Added boost header
This commit is contained in:
515
test/external/boost/locale/format.hpp
vendored
Normal file
515
test/external/boost/locale/format.hpp
vendored
Normal file
@@ -0,0 +1,515 @@
|
||||
//
|
||||
// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#ifndef BOOST_LOCALE_FORMAT_HPP_INCLUDED
|
||||
#define BOOST_LOCALE_FORMAT_HPP_INCLUDED
|
||||
|
||||
#include <boost/locale/config.hpp>
|
||||
#ifdef BOOST_MSVC
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable : 4275 4251 4231 4660)
|
||||
#endif
|
||||
#include <boost/locale/message.hpp>
|
||||
#include <boost/locale/formatting.hpp>
|
||||
|
||||
#include <sstream>
|
||||
|
||||
|
||||
namespace boost {
|
||||
namespace locale {
|
||||
|
||||
///
|
||||
/// \defgroup format Format
|
||||
///
|
||||
/// This module provides printf like functionality integrated into iostreams and suitable for localization
|
||||
///
|
||||
/// @{
|
||||
///
|
||||
|
||||
/// \cond INTERNAL
|
||||
namespace details {
|
||||
|
||||
template<typename CharType>
|
||||
struct formattible {
|
||||
typedef std::basic_ostream<CharType> stream_type;
|
||||
typedef void (*writer_type)(stream_type &output,void const *ptr);
|
||||
|
||||
formattible() :
|
||||
pointer_(0),
|
||||
writer_(&formattible::void_write)
|
||||
{
|
||||
}
|
||||
|
||||
formattible(formattible const &other) :
|
||||
pointer_(other.pointer_),
|
||||
writer_(other.writer_)
|
||||
{
|
||||
}
|
||||
|
||||
formattible const &operator=(formattible const &other)
|
||||
{
|
||||
if(this != &other) {
|
||||
pointer_=other.pointer_;
|
||||
writer_=other.writer_;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename Type>
|
||||
formattible(Type const &value)
|
||||
{
|
||||
pointer_ = static_cast<void const *>(&value);
|
||||
writer_ = &write<Type>;
|
||||
}
|
||||
|
||||
template<typename Type>
|
||||
formattible const &operator=(Type const &other)
|
||||
{
|
||||
*this = formattible(other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
friend stream_type &operator<<(stream_type &out,formattible const &fmt)
|
||||
{
|
||||
fmt.writer_(out,fmt.pointer_);
|
||||
return out;
|
||||
}
|
||||
|
||||
private:
|
||||
static void void_write(stream_type &output,void const * /*ptr*/)
|
||||
{
|
||||
CharType empty_string[1]={0};
|
||||
output<<empty_string;
|
||||
}
|
||||
|
||||
template<typename Type>
|
||||
static void write(stream_type &output,void const *ptr)
|
||||
{
|
||||
output << *static_cast<Type const *>(ptr);
|
||||
}
|
||||
|
||||
void const *pointer_;
|
||||
writer_type writer_;
|
||||
}; // formattible
|
||||
|
||||
class BOOST_LOCALE_DECL format_parser {
|
||||
public:
|
||||
format_parser(std::ios_base &ios,void *,void (*imbuer)(void *,std::locale const &));
|
||||
~format_parser();
|
||||
|
||||
unsigned get_position();
|
||||
|
||||
void set_one_flag(std::string const &key,std::string const &value);
|
||||
|
||||
template<typename CharType>
|
||||
void set_flag_with_str(std::string const &key,std::basic_string<CharType> const &value)
|
||||
{
|
||||
if(key=="ftime" || key=="strftime") {
|
||||
as::strftime(ios_);
|
||||
ios_info::get(ios_).date_time_pattern(value);
|
||||
}
|
||||
}
|
||||
void restore();
|
||||
private:
|
||||
void imbue(std::locale const &);
|
||||
format_parser(format_parser const &);
|
||||
void operator=(format_parser const &);
|
||||
|
||||
std::ios_base &ios_;
|
||||
struct data;
|
||||
std::auto_ptr<data> d;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
/// \endcond
|
||||
|
||||
///
|
||||
/// \brief a printf like class that allows type-safe and locale aware message formatting
|
||||
///
|
||||
/// This class creates a formatted message similar to printf or boost::format and receives
|
||||
/// formatted entries via operator %.
|
||||
///
|
||||
/// For example
|
||||
/// \code
|
||||
/// cout << format("Hello {1}, you are {2} years old") % name % age << endl;
|
||||
/// \endcode
|
||||
///
|
||||
/// Formatting is enclosed between curly brackets \c { \c } and defined by a comma separated list of flags in the format key[=value]
|
||||
/// value may also be text included between single quotes \c ' that is used for special purposes where inclusion of non-ASCII
|
||||
/// text is allowed
|
||||
///
|
||||
/// Including of literal \c { and \c } is possible by specifying double brackets \c {{ and \c }} accordingly.
|
||||
///
|
||||
///
|
||||
/// For example:
|
||||
///
|
||||
/// \code
|
||||
/// cout << format("The height of water at {1,time} is {2,num=fixed,precision=3}") % time % height;
|
||||
/// \endcode
|
||||
///
|
||||
/// The special key -- a number without a value defines the position of an input parameter.
|
||||
/// List of keys:
|
||||
/// - \c [0-9]+ -- digits, the index of a formatted parameter -- mandatory key.
|
||||
/// - \c num or \c number -- format a number. Optional values are:
|
||||
/// - \c hex -- display hexadecimal number
|
||||
/// - \c oct -- display in octal format
|
||||
/// - \c sci or \c scientific -- display in scientific format
|
||||
/// - \c fix or \c fixed -- display in fixed format
|
||||
/// .
|
||||
/// For example \c number=sci
|
||||
/// - \c cur or \c currency -- format currency. Optional values are:
|
||||
///
|
||||
/// - \c iso -- display using ISO currency symbol.
|
||||
/// - \c nat or \c national -- display using national currency symbol.
|
||||
/// .
|
||||
/// - \c per or \c percent -- format percent value.
|
||||
/// - \c date, \c time , \c datetime or \c dt -- format date, time or date and time. Optional values are:
|
||||
/// - \c s or \c short -- display in short format
|
||||
/// - \c m or \c medium -- display in medium format.
|
||||
/// - \c l or \c long -- display in long format.
|
||||
/// - \c f or \c full -- display in full format.
|
||||
/// .
|
||||
/// - \c ftime with string (quoted) parameter -- display as with \c strftime see, \c as::ftime manipulator
|
||||
/// - \c spell or \c spellout -- spell the number.
|
||||
/// - \c ord or \c ordinal -- format ordinal number (1st, 2nd... etc)
|
||||
/// - \c left or \c < -- align to left.
|
||||
/// - \c right or \c > -- align to right.
|
||||
/// - \c width or \c w -- set field width (requires parameter).
|
||||
/// - \c precision or \c p -- set precision (requires parameter).
|
||||
/// - \c locale -- with parameter -- switch locale for current operation. This command generates locale
|
||||
/// with formatting facets giving more fine grained control of formatting. For example:
|
||||
/// \code
|
||||
/// cout << format("Today {1,date} ({1,date,locale=he_IL.UTF-8@calendar=hebrew,date} Hebrew Date)") % date;
|
||||
/// \endcode
|
||||
/// - \c timezone or \c tz -- the name of the timezone to display the time in. For example:\n
|
||||
/// \code
|
||||
/// cout << format("Time is: Local {1,time}, ({1,time,tz=EET} Eastern European Time)") % date;
|
||||
/// \endcode
|
||||
/// - \c local - display the time in local time
|
||||
/// - \c gmt - display the time in UTC time scale
|
||||
/// \code
|
||||
/// cout << format("Local time is: {1,time,local}, universal time is {1,time,gmt}") % time;
|
||||
/// \endcode
|
||||
///
|
||||
///
|
||||
/// Invalid formatting strings are slightly ignored. This would prevent from translator
|
||||
/// to crash the program in unexpected location.
|
||||
///
|
||||
template<typename CharType>
|
||||
class basic_format {
|
||||
public:
|
||||
typedef CharType char_type; ///< Underlying character type
|
||||
typedef basic_message<char_type> message_type; ///< The translation message type
|
||||
/// \cond INTERNAL
|
||||
typedef details::formattible<CharType> formattible_type;
|
||||
/// \endcond
|
||||
|
||||
typedef std::basic_string<CharType> string_type; ///< string type for this type of character
|
||||
typedef std::basic_ostream<CharType> stream_type; ///< output stream type for this type of character
|
||||
|
||||
|
||||
///
|
||||
/// Create a format class for \a format_string
|
||||
///
|
||||
basic_format(string_type format_string) :
|
||||
format_(format_string),
|
||||
translate_(false),
|
||||
parameters_count_(0)
|
||||
{
|
||||
}
|
||||
///
|
||||
/// Create a format class using message \a trans. The message if translated first according
|
||||
/// to the rules of target locale and then interpreted as format string
|
||||
///
|
||||
basic_format(message_type const &trans) :
|
||||
message_(trans),
|
||||
translate_(true),
|
||||
parameters_count_(0)
|
||||
{
|
||||
}
|
||||
|
||||
///
|
||||
/// Add new parameter to format list. The object should be a type
|
||||
/// with defined expression out << object where \c out is \c std::basic_ostream.
|
||||
///
|
||||
template<typename Formattible>
|
||||
basic_format &operator % (Formattible const &object)
|
||||
{
|
||||
add(formattible_type(object));
|
||||
return *this;
|
||||
}
|
||||
|
||||
///
|
||||
/// Format a string using a locale \a loc
|
||||
///
|
||||
string_type str(std::locale const &loc = std::locale()) const
|
||||
{
|
||||
std::basic_ostringstream<CharType> buffer;
|
||||
buffer.imbue(loc);
|
||||
write(buffer);
|
||||
return buffer.str();
|
||||
}
|
||||
|
||||
///
|
||||
/// write a formatted string to output stream \a out using out's locale
|
||||
///
|
||||
void write(stream_type &out) const
|
||||
{
|
||||
string_type format;
|
||||
if(translate_)
|
||||
format = message_.str(out.getloc(),ios_info::get(out).domain_id());
|
||||
else
|
||||
format = format_;
|
||||
|
||||
format_output(out,format);
|
||||
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
|
||||
class format_guard {
|
||||
public:
|
||||
format_guard(details::format_parser &fmt) :
|
||||
fmt_(&fmt),
|
||||
restored_(false)
|
||||
{
|
||||
}
|
||||
void restore()
|
||||
{
|
||||
if(restored_)
|
||||
return;
|
||||
fmt_->restore();
|
||||
restored_ = true;
|
||||
}
|
||||
~format_guard()
|
||||
{
|
||||
try {
|
||||
restore();
|
||||
}
|
||||
catch(...) {
|
||||
}
|
||||
}
|
||||
private:
|
||||
details::format_parser *fmt_;
|
||||
bool restored_;
|
||||
};
|
||||
|
||||
void format_output(stream_type &out,string_type const &sformat) const
|
||||
{
|
||||
char_type obrk='{';
|
||||
char_type cbrk='}';
|
||||
char_type eq='=';
|
||||
char_type comma=',';
|
||||
char_type quote='\'';
|
||||
|
||||
size_t pos = 0;
|
||||
size_t size=sformat.size();
|
||||
CharType const *format=sformat.c_str();
|
||||
while(format[pos]!=0) {
|
||||
if(format[pos] != obrk) {
|
||||
if(format[pos]==cbrk && format[pos+1]==cbrk) {
|
||||
out << cbrk;
|
||||
pos+=2;
|
||||
}
|
||||
else {
|
||||
out<<format[pos];
|
||||
pos++;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if(pos+1 < size && format[pos+1]==obrk) {
|
||||
out << obrk;
|
||||
pos+=2;
|
||||
continue;
|
||||
}
|
||||
pos++;
|
||||
|
||||
details::format_parser fmt(out,static_cast<void *>(&out),&basic_format::imbue_locale);
|
||||
|
||||
format_guard guard(fmt);
|
||||
|
||||
while(pos < size) {
|
||||
std::string key;
|
||||
std::string svalue;
|
||||
string_type value;
|
||||
bool use_svalue = true;
|
||||
for(;format[pos];pos++) {
|
||||
char_type c=format[pos];
|
||||
if(c==comma || c==eq || c==cbrk)
|
||||
break;
|
||||
else {
|
||||
key+=static_cast<char>(c);
|
||||
}
|
||||
}
|
||||
|
||||
if(format[pos]==eq) {
|
||||
pos++;
|
||||
if(format[pos]==quote) {
|
||||
pos++;
|
||||
use_svalue = false;
|
||||
while(format[pos]) {
|
||||
if(format[pos]==quote) {
|
||||
if(format[pos+1]==quote) {
|
||||
value+=quote;
|
||||
pos+=2;
|
||||
}
|
||||
else {
|
||||
pos++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
value+=format[pos];
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
char_type c;
|
||||
while((c=format[pos])!=0 && c!=comma && c!=cbrk) {
|
||||
svalue+=static_cast<char>(c);
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(use_svalue) {
|
||||
fmt.set_one_flag(key,svalue);
|
||||
}
|
||||
else
|
||||
fmt.set_flag_with_str(key,value);
|
||||
|
||||
if(format[pos]==comma) {
|
||||
pos++;
|
||||
continue;
|
||||
}
|
||||
else if(format[pos]==cbrk) {
|
||||
unsigned position = fmt.get_position();
|
||||
out << get(position);
|
||||
guard.restore();
|
||||
pos++;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
guard.restore();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Non-copyable
|
||||
//
|
||||
basic_format(basic_format const &other);
|
||||
void operator=(basic_format const &other);
|
||||
|
||||
void add(formattible_type const ¶m)
|
||||
{
|
||||
if(parameters_count_ >= base_params_)
|
||||
ext_params_.push_back(param);
|
||||
else
|
||||
parameters_[parameters_count_] = param;
|
||||
parameters_count_++;
|
||||
}
|
||||
|
||||
formattible_type get(unsigned id) const
|
||||
{
|
||||
if(id >= parameters_count_)
|
||||
return formattible_type();
|
||||
else if(id >= base_params_)
|
||||
return ext_params_[id - base_params_];
|
||||
else
|
||||
return parameters_[id];
|
||||
}
|
||||
|
||||
static void imbue_locale(void *ptr,std::locale const &l)
|
||||
{
|
||||
reinterpret_cast<stream_type *>(ptr)->imbue(l);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static unsigned const base_params_ = 8;
|
||||
|
||||
message_type message_;
|
||||
string_type format_;
|
||||
bool translate_;
|
||||
|
||||
|
||||
formattible_type parameters_[base_params_];
|
||||
unsigned parameters_count_;
|
||||
std::vector<formattible_type> ext_params_;
|
||||
};
|
||||
|
||||
///
|
||||
/// Write formatted message to stream.
|
||||
///
|
||||
/// This operator actually causes actual text formatting. It uses the locale of \a out stream
|
||||
///
|
||||
template<typename CharType>
|
||||
std::basic_ostream<CharType> &operator<<(std::basic_ostream<CharType> &out,basic_format<CharType> const &fmt)
|
||||
{
|
||||
fmt.write(out);
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
///
|
||||
/// Definition of char based format
|
||||
///
|
||||
typedef basic_format<char> format;
|
||||
|
||||
///
|
||||
/// Definition of wchar_t based format
|
||||
///
|
||||
typedef basic_format<wchar_t> wformat;
|
||||
|
||||
#ifdef BOOST_HAS_CHAR16_T
|
||||
///
|
||||
/// Definition of char16_t based format
|
||||
///
|
||||
typedef basic_format<char16_t> u16format;
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_HAS_CHAR32_T
|
||||
///
|
||||
/// Definition of char32_t based format
|
||||
///
|
||||
typedef basic_format<char32_t> u32format;
|
||||
#endif
|
||||
|
||||
///
|
||||
/// @}
|
||||
///
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
///
|
||||
/// \example hello.cpp
|
||||
///
|
||||
/// Basic example of using various functions provided by this library
|
||||
///
|
||||
/// \example whello.cpp
|
||||
///
|
||||
/// Basic example of using various functions with wide strings provided by this library
|
||||
///
|
||||
///
|
||||
|
||||
// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
|
||||
|
||||
Reference in New Issue
Block a user