# Boost C++ Libraries

...one of the most highly regarded and expertly designed C++ library projects in the world. — Herb Sutter and Andrei Alexandrescu, C++ Coding Standards

- Main Page
- Modules
- Namespaces
- Classes
- Files
- Examples

- File List

# boost/locale/message.hpp

    00001 //
    00002 //  Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
    00003 //
    00004 //  Distributed under the Boost Software License, Version 1.0. (See
    00005 //  accompanying file LICENSE_1_0.txt or copy at
    00006 //  http://www.boost.org/LICENSE_1_0.txt)
    00007 //
    00008 #ifndef BOOST_LOCALE_MESSAGE_HPP_INCLUDED
    00009 #define BOOST_LOCALE_MESSAGE_HPP_INCLUDED
    00010
    00011 #include <boost/locale/config.hpp>
    00012 #ifdef BOOST_MSVC
    00013 #  pragma warning(push)
    00014 #  pragma warning(disable : 4275 4251 4231 4660)
    00015 #endif
    00016 #include <locale>
    00017 #include <string>
    00018 #include <vector>
    00019 #include <set>
    00020 #include <memory>
    00021 #include <boost/locale/formatting.hpp>
    00022
    00023
    00024 namespace boost {
    00025     namespace locale {
    00033
    00035
    00036         template<typename CharType>
    00037         struct base_message_format: public std::locale::facet
    00038         {
    00039         };
    00040
    00042
    00046         template<typename CharType>
    00047         class message_format : public base_message_format<CharType>
    00048         {
    00049         public:
    00050
    00054             typedef CharType char_type;
    00058             typedef std::basic_string<CharType> string_type;
    00059
    00063             message_format(size_t refs = 0) :
    00064                 base_message_format<CharType>(refs)
    00065             {
    00066             }
    00067
    00078             virtual char_type const *get(int domain_id,char_type const *context,char_type const *id) const = 0;
    00092             virtual char_type const *get(int domain_id,char_type const *context,char_type const *single_id,int n) const = 0;
    00093
    00097             virtual int domain(std::string const &domain) const = 0;
    00098
    00107             virtual char_type const *convert(char_type const *msg,string_type &buffer) const = 0;
    00108
    00109 #if defined (__SUNPRO_CC) && defined (_RWSTD_VER)
    00110             std::locale::id& __get_id (void) const { return id; }
    00111 #endif
    00112         protected:
    00113             virtual ~message_format()
    00114             {
    00115             }
    00116
    00117         };
    00118
    00120
    00121         namespace details {
    00122             inline bool is_us_ascii_char(char c)
    00123             {
    00124                 // works for null terminated strings regardless char "signness"
    00125                 return 0<c && c<0x7F;
    00126             }
    00127             inline bool is_us_ascii_string(char const *msg)
    00128             {
    00129                 while(*msg) {
    00130                     if(!is_us_ascii_char(*msg++))
    00131                         return false;
    00132                 }
    00133                 return true;
    00134             }
    00135
    00136             template<typename CharType>
    00137             struct string_cast_traits {
    00138                 static CharType const *cast(CharType const *msg,std::basic_string<CharType> &/*unused*/)
    00139                 {
    00140                     return msg;
    00141                 }
    00142             };
    00143
    00144             template<>
    00145             struct string_cast_traits<char> {
    00146                 static char const *cast(char const *msg,std::string &buffer)
    00147                 {
    00148                     if(is_us_ascii_string(msg))
    00149                         return msg;
    00150                     buffer.reserve(strlen(msg));
    00151                     char c;
    00152                     while((c=*msg++)!=0) {
    00153                         if(is_us_ascii_char(c))
    00154                             buffer+=c;
    00155                     }
    00156                     return buffer.c_str();
    00157                 }
    00158             };
    00159         } // details
    00160
    00162
    00170         template<typename CharType>
    00171         class basic_message {
    00172         public:
    00173
    00174             typedef CharType char_type;
    00175             typedef std::basic_string<char_type> string_type;
    00176             typedef message_format<char_type> facet_type;
    00177
    00181             basic_message() :
    00182                 n_(0),
    00183                 c_id_(0),
    00184                 c_context_(0),
    00185                 c_plural_(0)
    00186             {
    00187             }
    00188
    00193             explicit basic_message(char_type const *id) :
    00194                 n_(0),
    00195                 c_id_(id),
    00196                 c_context_(0),
    00197                 c_plural_(0)
    00198             {
    00199             }
    00200
    00207             explicit basic_message(char_type const *single,char_type const *plural,int n) :
    00208                 n_(n),
    00209                 c_id_(single),
    00210                 c_context_(0),
    00211                 c_plural_(plural)
    00212             {
    00213             }
    00214
    00220             explicit basic_message(char_type const *context,char_type const *id) :
    00221                 n_(0),
    00222                 c_id_(id),
    00223                 c_context_(context),
    00224                 c_plural_(0)
    00225             {
    00226             }
    00227
    00234             explicit basic_message(char_type const *context,char_type const *single,char_type const *plural,int n) :
    00235                 n_(n),
    00236                 c_id_(single),
    00237                 c_context_(context),
    00238                 c_plural_(plural)
    00239             {
    00240             }
    00241
    00242
    00246             explicit basic_message(string_type const &id) :
    00247                 n_(0),
    00248                 c_id_(0),
    00249                 c_context_(0),
    00250                 c_plural_(0),
    00251                 id_(id)
    00252             {
    00253             }
    00254
    00260             explicit basic_message(string_type const &single,string_type const &plural,int number) :
    00261                 n_(number),
    00262                 c_id_(0),
    00263                 c_context_(0),
    00264                 c_plural_(0),
    00265                 id_(single),
    00266                 plural_(plural)
    00267             {
    00268             }
    00269
    00273             explicit basic_message(string_type const &context,string_type const &id) :
    00274                 n_(0),
    00275                 c_id_(0),
    00276                 c_context_(0),
    00277                 c_plural_(0),
    00278                 id_(id),
    00279                 context_(context)
    00280             {
    00281             }
    00282
    00288             explicit basic_message(string_type const &context,string_type const &single,string_type const &plural,int number) :
    00289                 n_(number),
    00290                 c_id_(0),
    00291                 c_context_(0),
    00292                 c_plural_(0),
    00293                 id_(single),
    00294                 context_(context),
    00295                 plural_(plural)
    00296             {
    00297             }
    00298
    00302             basic_message(basic_message const &other) :
    00303                 n_(other.n_),
    00304                 c_id_(other.c_id_),
    00305                 c_context_(other.c_context_),
    00306                 c_plural_(other.c_plural_),
    00307                 id_(other.id_),
    00308                 context_(other.context_),
    00309                 plural_(other.plural_)
    00310             {
    00311             }
    00312
    00316             basic_message const &operator=(basic_message const &other)
    00317             {
    00318                 if(this==&other) {
    00319                     return *this;
    00320                 }
    00321                 basic_message tmp(other);
    00322                 swap(tmp);
    00323                 return *this;
    00324             }
    00325
    00329             void swap(basic_message &other)
    00330             {
    00331                 std::swap(n_,other.n_);
    00332                 std::swap(c_id_,other.c_id_);
    00333                 std::swap(c_context_,other.c_context_);
    00334                 std::swap(c_plural_,other.c_plural_);
    00335
    00336                 id_.swap(other.id_);
    00337                 context_.swap(other.context_);
    00338                 plural_.swap(other.plural_);
    00339             }
    00340
    00344
    00345             operator string_type () const
    00346             {
    00347                 return str();
    00348             }
    00349
    00353             string_type str() const
    00354             {
    00355                 std::locale loc;
    00356                 return str(loc,0);
    00357             }
    00358
    00362             string_type str(std::locale const &locale) const
    00363             {
    00364                 return str(locale,0);
    00365             }
    00366
    00370             string_type str(std::locale const &locale,std::string const &domain_id) const
    00371             {
    00372                 int id=0;
    00373                 if(std::has_facet<facet_type>(locale))
    00374                     id=std::use_facet<facet_type>(locale).domain(domain_id);
    00375                 return str(locale,id);
    00376             }
    00377
    00381             string_type str(std::string const &domain_id) const
    00382             {
    00383                 int id=0;
    00384                 std::locale loc;
    00385                 if(std::has_facet<facet_type>(loc))
    00386                     id=std::use_facet<facet_type>(loc).domain(domain_id);
    00387                 return str(loc,id);
    00388             }
    00389
    00390
    00394             string_type str(std::locale const &loc,int id) const
    00395             {
    00396                 string_type buffer;
    00397                 char_type const *ptr = write(loc,id,buffer);
    00398                 if(ptr == buffer.c_str())
    00399                     return buffer;
    00400                 else
    00401                     buffer = ptr;
    00402                 return buffer;
    00403             }
    00404
    00405
    00410             void write(std::basic_ostream<char_type> &out) const
    00411             {
    00412                 std::locale const &loc = out.getloc();
    00413                 int id = ios_info::get(out).domain_id();
    00414                 string_type buffer;
    00415                 out << write(loc,id,buffer);
    00416             }
    00417
    00418         private:
    00419             char_type const *plural() const
    00420             {
    00421                 if(c_plural_)
    00422                     return c_plural_;
    00423                 if(plural_.empty())
    00424                     return 0;
    00425                 return plural_.c_str();
    00426             }
    00427             char_type const *context() const
    00428             {
    00429                 if(c_context_)
    00430                     return c_context_;
    00431                 if(context_.empty())
    00432                     return 0;
    00433                 return context_.c_str();
    00434             }
    00435
    00436             char_type const *id() const
    00437             {
    00438                 return c_id_ ? c_id_ : id_.c_str();
    00439             }
    00440
    00441             char_type const *write(std::locale const &loc,int domain_id,string_type &buffer) const
    00442             {
    00443                 char_type const *translated = 0;
    00444                 static const char_type empty_string[1] = {0};
    00445
    00446                 char_type const *id = this->id();
    00447                 char_type const *context = this->context();
    00448                 char_type const *plural = this->plural();
    00449
    00450                 if(*id == 0)
    00451                     return empty_string;
    00452
    00453                 facet_type const *facet = 0;
    00454                 if(std::has_facet<facet_type>(loc))
    00455                     facet = &std::use_facet<facet_type>(loc);
    00456
    00457                 if(facet) {
    00458                     if(!plural) {
    00459                         translated = facet->get(domain_id,context,id);
    00460                     }
    00461                     else {
    00462                         translated = facet->get(domain_id,context,id,n_);
    00463                     }
    00464                 }
    00465
    00466                 if(!translated) {
    00467                     char_type const *msg = plural ? ( n_ == 1 ? id : plural) : id;
    00468
    00469                     if(facet) {
    00470                         translated = facet->convert(msg,buffer);
    00471                     }
    00472                     else {
    00473                         translated = details::string_cast_traits<char_type>::cast(msg,buffer);
    00474                     }
    00475                 }
    00476                 return translated;
    00477             }
    00478
    00480
    00481             int n_;
    00482             char_type const *c_id_;
    00483             char_type const *c_context_;
    00484             char_type const *c_plural_;
    00485             string_type id_;
    00486             string_type context_;
    00487             string_type plural_;
    00488         };
    00489
    00490
    00494         typedef basic_message<char> message;
    00498         typedef basic_message<wchar_t> wmessage;
    00499         #ifdef BOOST_HAS_CHAR16_T
    00500
    00501
    00502
    00503         typedef basic_message<char16_t> u16message;
    00504         #endif
    00505         #ifdef BOOST_HAS_CHAR32_T
    00506
    00507
    00508
    00509         typedef basic_message<char32_t> u32message;
    00510         #endif
    00511
    00515         template<typename CharType>
    00516         std::basic_ostream<CharType> &operator<<(std::basic_ostream<CharType> &out,basic_message<CharType> const &msg)
    00517         {
    00518             msg.write(out);
    00519             return out;
    00520         }
    00521
    00525
    00529         template<typename CharType>
    00530         inline basic_message<CharType> translate(CharType const *msg)
    00531         {
    00532             return basic_message<CharType>(msg);
    00533         }
    00537         template<typename CharType>
    00538         inline basic_message<CharType> translate(   CharType const *context,
    00539                                                     CharType const *msg)
    00540         {
    00541             return basic_message<CharType>(context,msg);
    00542         }
    00546         template<typename CharType>
    00547         inline basic_message<CharType> translate(   CharType const *single,
    00548                                                     CharType const *plural,
    00549                                                     int n)
    00550         {
    00551             return basic_message<CharType>(single,plural,n);
    00552         }
    00556         template<typename CharType>
    00557         inline basic_message<CharType> translate(   CharType const *context,
    00558                                                     CharType const *single,
    00559                                                     CharType const *plural,
    00560                                                     int n)
    00561         {
    00562             return basic_message<CharType>(context,single,plural,n);
    00563         }
    00564
    00568         template<typename CharType>
    00569         inline basic_message<CharType> translate(std::basic_string<CharType> const &msg)
    00570         {
    00571             return basic_message<CharType>(msg);
    00572         }
    00573
    00577         template<typename CharType>
    00578         inline basic_message<CharType> translate(   std::basic_string<CharType> const &context,
    00579                                                     std::basic_string<CharType> const &msg)
    00580         {
    00581             return basic_message<CharType>(context,msg);
    00582         }
    00586         template<typename CharType>
    00587         inline basic_message<CharType> translate(   std::basic_string<CharType> const &context,
    00588                                                     std::basic_string<CharType> const &single,
    00589                                                     std::basic_string<CharType> const &plural,
    00590                                                     int n)
    00591         {
    00592             return basic_message<CharType>(context,single,plural,n);
    00593         }
    00594
    00598
    00599         template<typename CharType>
    00600         inline basic_message<CharType> translate(   std::basic_string<CharType> const &single,
    00601                                                     std::basic_string<CharType> const &plural,
    00602                                                     int n)
    00603         {
    00604             return basic_message<CharType>(single,plural,n);
    00605         }
    00606
    00608
    00612
    00616         template<typename CharType>
    00617         std::basic_string<CharType> gettext(CharType const *id,
    00618                                             std::locale const &loc=std::locale())
    00619         {
    00620             return basic_message<CharType>(id).str(loc);
    00621         }
    00625         template<typename CharType>
    00626         std::basic_string<CharType> ngettext(   CharType const *s,
    00627                                                 CharType const *p,
    00628                                                 int n,
    00629                                                 std::locale const &loc=std::locale())
    00630         {
    00631             return basic_message<CharType>(s,p,n).str(loc);
    00632         }
    00636         template<typename CharType>
    00637         std::basic_string<CharType>  dgettext(  char const *domain,
    00638                                                 CharType const *id,
    00639                                                 std::locale const &loc=std::locale())
    00640         {
    00641             return basic_message<CharType>(id).str(loc,domain);
    00642         }
    00643
    00647         template<typename CharType>
    00648         std::basic_string<CharType>  dngettext( char const *domain,
    00649                                                 CharType const *s,
    00650                                                 CharType const *p,
    00651                                                 int n,
    00652                                                 std::locale const &loc=std::locale())
    00653         {
    00654             return basic_message<CharType>(s,p,n).str(loc,domain);
    00655         }
    00659         template<typename CharType>
    00660         std::basic_string<CharType>  pgettext(  CharType const *context,
    00661                                                 CharType const *id,
    00662                                                 std::locale const &loc=std::locale())
    00663         {
    00664             return basic_message<CharType>(context,id).str(loc);
    00665         }
    00669         template<typename CharType>
    00670         std::basic_string<CharType>  npgettext( CharType const *context,
    00671                                                 CharType const *s,
    00672                                                 CharType const *p,
    00673                                                 int n,
    00674                                                 std::locale const &loc=std::locale())
    00675         {
    00676             return basic_message<CharType>(context,s,p,n).str(loc);
    00677         }
    00681         template<typename CharType>
    00682         std::basic_string<CharType>  dpgettext( char const *domain,
    00683                                                 CharType const *context,
    00684                                                 CharType const *id,
    00685                                                 std::locale const &loc=std::locale())
    00686         {
    00687             return basic_message<CharType>(context,id).str(loc,domain);
    00688         }
    00692         template<typename CharType>
    00693         std::basic_string<CharType>  dnpgettext(char const *domain,
    00694                                                 CharType const *context,
    00695                                                 CharType const *s,
    00696                                                 CharType const *p,
    00697                                                 int n,
    00698                                                 std::locale const &loc=std::locale())
    00699         {
    00700             return basic_message<CharType>(context,s,p,n).str(loc,domain);
    00701         }
    00702
    00706
    00707         template<>
    00708         struct BOOST_LOCALE_DECL base_message_format<char> : public std::locale::facet
    00709         {
    00710             base_message_format(size_t refs = 0) : std::locale::facet(refs)
    00711             {
    00712             }
    00713             static std::locale::id id;
    00714         };
    00715
    00716         template<>
    00717         struct BOOST_LOCALE_DECL base_message_format<wchar_t> : public std::locale::facet
    00718         {
    00719             base_message_format(size_t refs = 0) : std::locale::facet(refs)
    00720             {
    00721             }
    00722             static std::locale::id id;
    00723         };
    00724
    00725         #ifdef BOOST_HAS_CHAR16_T
    00726
    00727         template<>
    00728         struct BOOST_LOCALE_DECL base_message_format<char16_t> : public std::locale::facet
    00729         {
    00730             base_message_format(size_t refs = 0) : std::locale::facet(refs)
    00731             {
    00732             }
    00733             static std::locale::id id;
    00734         };
    00735
    00736         #endif
    00737
    00738         #ifdef BOOST_HAS_CHAR32_T
    00739
    00740         template<>
    00741         struct BOOST_LOCALE_DECL base_message_format<char32_t> : public std::locale::facet
    00742         {
    00743             base_message_format(size_t refs = 0) : std::locale::facet(refs)
    00744             {
    00745             }
    00746             static std::locale::id id;
    00747         };
    00748
    00749         #endif
    00750
    00752
    00756
    00757         namespace as {
    00759             namespace details {
    00760                 struct set_domain {
    00761                     std::string domain_id;
    00762                 };
    00763                 template<typename CharType>
    00764                 std::basic_ostream<CharType> &operator<<(std::basic_ostream<CharType> &out, set_domain const &dom)
    00765                 {
    00766                     int id = std::use_facet<message_format<CharType> >(out.getloc()).domain(dom.domain_id);
    00767                     ios_info::get(out).domain_id(id);
    00768                     return out;
    00769                 }
    00770             } // details
    00772
    00777
    00783             inline
    00784             #ifdef BOOST_LOCALE_DOXYGEN
    00785             unspecified_type
    00786             #else
    00787             details::set_domain
    00788             #endif
    00789             domain(std::string const &id)
    00790             {
    00791                 details::set_domain tmp = { id };
    00792                 return tmp;
    00793             }
    00795         } // as
    00796     } // locale
    00797 } // boost
    00798
    00799 #ifdef BOOST_MSVC
    00800 #pragma warning(pop)
    00801 #endif
    00802
    00803
    00804 #endif
    00805
    00806 // vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
    00807