00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00040 #ifndef _CPP_BITS_LOCCORE_H
00041 #define _CPP_BITS_LOCCORE_H 1
00042 
00043 #pragma GCC system_header
00044 
00045 #include <bits/c++config.h>
00046 #include <bits/c++locale.h>     
00047 #include <climits>      
00048 #include <cctype>       
00049 #include <string>       
00050 #include <bits/functexcept.h>
00051 #include <bits/atomicity.h>
00052 
00053 namespace std
00054 {
00055   
00056   class locale;
00057 
00058   
00059   template<typename _CharT> 
00060     inline bool 
00061     isspace(_CharT, const locale&);
00062 
00063   template<typename _CharT> 
00064     inline bool 
00065     isprint(_CharT, const locale&);
00066 
00067   template<typename _CharT> 
00068     inline bool 
00069     iscntrl(_CharT, const locale&);
00070 
00071   template<typename _CharT> 
00072     inline bool 
00073     isupper(_CharT, const locale&);
00074 
00075   template<typename _CharT> 
00076     inline bool 
00077     islower(_CharT, const locale&);
00078 
00079   template<typename _CharT> 
00080     inline bool 
00081     isalpha(_CharT, const locale&);
00082 
00083   template<typename _CharT> 
00084     inline bool 
00085     isdigit(_CharT, const locale&);
00086 
00087   template<typename _CharT> 
00088     inline bool 
00089     ispunct(_CharT, const locale&);
00090 
00091   template<typename _CharT> 
00092     inline bool 
00093     isxdigit(_CharT, const locale&);
00094 
00095   template<typename _CharT> 
00096     inline bool 
00097     isalnum(_CharT, const locale&);
00098 
00099   template<typename _CharT> 
00100     inline bool 
00101     isgraph(_CharT, const locale&);
00102 
00103   template<typename _CharT> 
00104     inline _CharT 
00105     toupper(_CharT, const locale&);
00106 
00107   template<typename _CharT> 
00108     inline _CharT 
00109     tolower(_CharT, const locale&);
00110 
00111 
00112   
00113   class ctype_base;
00114   template<typename _CharT> 
00115     class ctype;
00116   template<> class ctype<char>;
00117 #ifdef _GLIBCPP_USE_WCHAR_T
00118   template<> class ctype<wchar_t>;
00119 #endif
00120   template<typename _CharT> 
00121     class ctype_byname;
00122   
00123 
00124   class codecvt_base;
00125   class __enc_traits;
00126   template<typename _InternT, typename _ExternT, typename _StateT>
00127     class codecvt;
00128   template<> class codecvt<char, char, mbstate_t>;
00129 #ifdef _GLIBCPP_USE_WCHAR_T
00130   template<> class codecvt<wchar_t, char, mbstate_t>;
00131 #endif
00132   template<typename _InternT, typename _ExternT, typename _StateT>
00133     class codecvt_byname;
00134 
00135   
00136   template<typename _CharT, typename _InIter = istreambuf_iterator<_CharT> >
00137     class num_get;
00138   template<typename _CharT, typename _OutIter = ostreambuf_iterator<_CharT> >
00139     class num_put;
00140   template<typename _CharT> class numpunct;
00141   template<typename _CharT> class numpunct_byname;
00142 
00143   
00144   template<typename _CharT> 
00145     class collate;
00146   template<typename _CharT> class 
00147     collate_byname;
00148 
00149   
00150   class time_base;
00151   template<typename _CharT, typename _InIter =  istreambuf_iterator<_CharT> >
00152     class time_get;
00153   template<typename _CharT, typename _InIter =  istreambuf_iterator<_CharT> >
00154     class time_get_byname;
00155   template<typename _CharT, typename _OutIter = ostreambuf_iterator<_CharT> >
00156     class time_put;
00157   template<typename _CharT, typename _OutIter = ostreambuf_iterator<_CharT> >
00158     class time_put_byname;
00159 
00160   
00161   class money_base;
00162   template<typename _CharT, typename _InIter =  istreambuf_iterator<_CharT> >
00163     class money_get;
00164   template<typename _CharT, typename _OutIter = ostreambuf_iterator<_CharT> >
00165     class money_put;
00166   template<typename _CharT, bool _Intl = false> 
00167     class moneypunct;
00168   template<typename _CharT, bool _Intl = false> 
00169     class moneypunct_byname;
00170 
00171   
00172   class messages_base;
00173   template<typename _CharT> 
00174     class messages;
00175   template<typename _CharT> 
00176     class messages_byname;
00177 
00178   
00179   class locale
00180   {
00181   public:
00182     
00183     typedef unsigned int    category;
00184 
00185     
00186     class facet;
00187     class id;
00188     class _Impl;
00189 
00190     friend class facet;
00191     friend class _Impl;
00192 
00193     template<typename _Facet>
00194       friend const _Facet& 
00195       use_facet(const locale&);
00196     
00197     template<typename _Facet>
00198       friend bool 
00199       has_facet(const locale&) throw();
00200  
00201     
00202     
00203     static const category none      = 0;
00204     static const category ctype     = 1L << 0;
00205     static const category numeric   = 1L << 1;
00206     static const category collate   = 1L << 2;
00207     static const category time      = 1L << 3;
00208     static const category monetary  = 1L << 4;
00209     static const category messages  = 1L << 5;
00210     static const category all       = (collate | ctype | monetary |
00211                        numeric | time  | messages);
00212 
00213     
00214     locale() throw();
00215 
00216     locale(const locale& __other) throw();
00217 
00218     explicit  
00219     locale(const char* __s);
00220 
00221     locale(const locale& __base, const char* __s, category __cat);
00222 
00223     locale(const locale& __base, const locale& __add, category __cat);
00224 
00225     template<typename _Facet>
00226       locale(const locale& __other, _Facet* __f);
00227 
00228     ~locale() throw();
00229 
00230     const locale&  
00231     operator=(const locale& __other) throw();
00232 
00233     template<typename _Facet>
00234       locale  
00235       combine(const locale& __other) const;
00236 
00237     
00238     string 
00239     name() const;
00240 
00241     bool 
00242     operator==(const locale& __other) const throw ();
00243 
00244     inline bool  
00245     operator!=(const locale& __other) const throw ()
00246     { return !(this->operator==(__other));  }
00247 
00248     template<typename _Char, typename _Traits, typename _Alloc>
00249       bool  
00250       operator()(const basic_string<_Char, _Traits, _Alloc>& __s1,
00251          const basic_string<_Char, _Traits, _Alloc>& __s2) const;
00252 
00253     
00254     static locale 
00255     global(const locale&);
00256 
00257     static const locale& 
00258     classic();
00259 
00260   private:
00261     
00262     _Impl*      _M_impl;  
00263 
00264     
00265     static _Impl*   _S_classic; 
00266 
00267     
00268     static _Impl*   _S_global;  
00269 
00270     static const size_t _S_num_categories = 6;
00271 
00272     explicit 
00273     locale(_Impl*) throw();
00274 
00275     static inline void  
00276     _S_initialize()
00277     { 
00278       if (!_S_classic) 
00279     classic();  
00280     }
00281 
00282     static category  
00283     _S_normalize_category(category);
00284 
00285     void
00286     _M_coalesce(const locale& __base, const locale& __add, category __cat);
00287   };
00288 
00289 
00290   
00291   class locale::_Impl
00292   {
00293   public:
00294     
00295     friend class locale;
00296     friend class locale::facet;
00297 
00298     template<typename _Facet>
00299       friend const _Facet&  
00300       use_facet(const locale&);
00301 
00302     template<typename _Facet>
00303       friend bool  
00304       has_facet(const locale&) throw();
00305 
00306   private:
00307     
00308     _Atomic_word            _M_references;
00309     facet**                 _M_facets;
00310     size_t              _M_facets_size;
00311     const char*             _M_names[_S_num_categories];
00312     static const locale::id* const  _S_id_ctype[];
00313     static const locale::id* const  _S_id_numeric[];
00314     static const locale::id* const  _S_id_collate[];
00315     static const locale::id* const  _S_id_time[];
00316     static const locale::id* const  _S_id_monetary[];
00317     static const locale::id* const  _S_id_messages[];
00318     static const locale::id* const* const _S_facet_categories[];
00319 
00320     inline void 
00321     _M_add_reference() throw()
00322     { __atomic_add(&_M_references, 1); }
00323 
00324     inline void 
00325     _M_remove_reference() throw()
00326     {
00327       if (__exchange_and_add(&_M_references, -1) == 1)
00328     {
00329       try 
00330         { delete this; } 
00331       catch(...) 
00332         { }
00333     }
00334     }
00335 
00336     _Impl(const _Impl&, size_t);
00337     _Impl(const char*, size_t);
00338     _Impl(facet**, size_t, bool);
00339 
00340    ~_Impl() throw();
00341 
00342     _Impl(const _Impl&);  
00343 
00344     void 
00345     operator=(const _Impl&);  
00346 
00347     inline bool
00348     _M_check_same_name()
00349     {
00350       bool __ret = true;
00351       for (size_t i = 0; __ret && i < _S_num_categories - 1; ++i)
00352     __ret &= (strcmp(_M_names[i], _M_names[i + 1]) == 0);
00353       return __ret;
00354     }
00355 
00356     void 
00357     _M_replace_categories(const _Impl*, category);
00358 
00359     void 
00360     _M_replace_category(const _Impl*, const locale::id* const*);
00361 
00362     void 
00363     _M_replace_facet(const _Impl*, const locale::id*);
00364 
00365     void 
00366     _M_install_facet(const locale::id*, facet*);
00367 
00368     template<typename _Facet>
00369       inline void 
00370       _M_init_facet(_Facet* __facet)
00371       { _M_install_facet(&_Facet::id, __facet);  }
00372   };
00373 
00374   template<typename _Facet>
00375     locale::locale(const locale& __other, _Facet* __f)
00376     {
00377       _M_impl = new _Impl(*__other._M_impl, 1);
00378       _M_impl->_M_install_facet(&_Facet::id, __f);
00379       for (size_t __i = 0; __i < _S_num_categories; ++__i)
00380     _M_impl->_M_names[__i] = "*";
00381     }
00382 
00383   
00384   class locale::facet
00385   {
00386   private:
00387     friend class locale;
00388     friend class locale::_Impl;
00389 
00390     _Atomic_word _M_references;
00391 
00392   protected:
00393     
00394     
00395     static __c_locale            _S_c_locale;
00396     
00397     explicit 
00398     facet(size_t __refs = 0) throw();
00399 
00400     virtual 
00401     ~facet();
00402 
00403     static void
00404     _S_create_c_locale(__c_locale& __cloc, const char* __s, 
00405                __c_locale __old = 0);
00406 
00407     static __c_locale
00408     _S_clone_c_locale(__c_locale& __cloc);
00409 
00410     static void
00411     _S_destroy_c_locale(__c_locale& __cloc);
00412 
00413   private:
00414     void 
00415     _M_add_reference() throw();
00416 
00417     void 
00418     _M_remove_reference() throw();
00419 
00420     facet(const facet&);  
00421 
00422     void 
00423     operator=(const facet&);  
00424   };
00425 
00426 
00427   
00428   class locale::id
00429   {
00430   private:
00431     friend class locale;
00432     friend class locale::_Impl;
00433     template<typename _Facet>
00434       friend const _Facet&  
00435       use_facet(const locale&);
00436     template<typename _Facet>
00437       friend bool           
00438       has_facet(const locale&) throw ();
00439 
00440     
00441     
00442     
00443     mutable size_t      _M_index;
00444 
00445     
00446     static _Atomic_word     _S_highwater;   
00447 
00448     void 
00449     operator=(const id&);  
00450 
00451     id(const id&);  
00452 
00453   public:
00454     
00455     
00456     id();
00457 
00458     inline size_t
00459     _M_id() const
00460     {
00461       if (!_M_index)
00462     _M_index = 1 + __exchange_and_add(&_S_highwater, 1);
00463       return _M_index - 1;
00464     }
00465   };
00466 
00467   template<typename _Facet>
00468     const _Facet&
00469     use_facet(const locale& __loc);
00470 
00471   template<typename _Facet>
00472     bool
00473     has_facet(const locale& __loc) throw();
00474 } 
00475 
00476 #endif