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 _LOCALE_CLASSES_H
00041 #define _LOCALE_CLASSES_H 1
00042 
00043 #pragma GCC system_header
00044 
00045 #include <bits/localefwd.h>
00046 #include <cstring>      
00047 #include <string>
00048 #include <bits/atomicity.h>
00049 #include <bits/gthr.h>
00050 
00051 namespace std
00052 {
00053   
00067   class locale
00068   {
00069   public:
00070     
00072     typedef int category;
00073 
00074     
00075     class facet;
00076     class id;
00077     class _Impl;
00078 
00079     friend class facet;
00080     friend class _Impl;
00081 
00082     template<typename _Facet>
00083       friend bool
00084       has_facet(const locale&) throw();
00085 
00086     template<typename _Facet>
00087       friend const _Facet&
00088       use_facet(const locale&);
00089 
00090     template<typename _Cache>
00091       friend struct __use_cache;
00092 
00094 
00105     static const category none      = 0;
00106     static const category ctype     = 1L << 0;
00107     static const category numeric   = 1L << 1;
00108     static const category collate   = 1L << 2;
00109     static const category time      = 1L << 3;
00110     static const category monetary  = 1L << 4;
00111     static const category messages  = 1L << 5;
00112     static const category all       = (ctype | numeric | collate |
00113                        time  | monetary | messages);
00115 
00116     
00117 
00124     locale() throw();
00125 
00133     locale(const locale& __other) throw();
00134 
00143     explicit
00144     locale(const char* __s);
00145 
00158     locale(const locale& __base, const char* __s, category __cat);
00159 
00171     locale(const locale& __base, const locale& __add, category __cat);
00172 
00183     template<typename _Facet>
00184       locale(const locale& __other, _Facet* __f);
00185 
00187     ~locale() throw();
00188 
00197     const locale&
00198     operator=(const locale& __other) throw();
00199 
00212     template<typename _Facet>
00213       locale
00214       combine(const locale& __other) const;
00215 
00216     
00221     string
00222     name() const;
00223 
00231     bool
00232     operator==(const locale& __other) const throw ();
00233 
00240     inline bool
00241     operator!=(const locale& __other) const throw ()
00242     { return !(this->operator==(__other));  }
00243 
00259     template<typename _Char, typename _Traits, typename _Alloc>
00260       bool
00261       operator()(const basic_string<_Char, _Traits, _Alloc>& __s1,
00262          const basic_string<_Char, _Traits, _Alloc>& __s2) const;
00263 
00264     
00275     static locale
00276     global(const locale&);
00277 
00281     static const locale&
00282     classic();
00283 
00284   private:
00285     
00286     _Impl*      _M_impl;
00287 
00288     
00289     static _Impl*       _S_classic;
00290 
00291     
00292     static _Impl*   _S_global;
00293 
00294     
00295     
00296     
00297     
00298     static const char* const* const _S_categories;
00299 
00300     
00301     
00302     
00303     
00304     
00305     
00306     
00307     
00308     
00309     
00310     enum { _S_categories_size = 6 + _GLIBCXX_NUM_CATEGORIES };
00311 
00312 #ifdef __GTHREADS
00313     static __gthread_once_t _S_once;
00314 #endif
00315 
00316     explicit
00317     locale(_Impl*) throw();
00318 
00319     static void
00320     _S_initialize();
00321 
00322     static void
00323     _S_initialize_once();
00324 
00325     static category
00326     _S_normalize_category(category);
00327 
00328     void
00329     _M_coalesce(const locale& __base, const locale& __add, category __cat);
00330   };
00331 
00332 
00333   
00343   class locale::facet
00344   {
00345   private:
00346     friend class locale;
00347     friend class locale::_Impl;
00348 
00349     mutable _Atomic_word        _M_refcount;
00350 
00351     
00352     static __c_locale                   _S_c_locale;
00353 
00354     
00355     static const char           _S_c_name[2];
00356 
00357 #ifdef __GTHREADS
00358     static __gthread_once_t     _S_once;
00359 #endif
00360 
00361     static void
00362     _S_initialize_once();
00363 
00364   protected:
00374     explicit
00375     facet(size_t __refs = 0) throw() : _M_refcount(__refs ? 1 : 0)
00376     { }
00377 
00379     virtual
00380     ~facet();
00381 
00382     static void
00383     _S_create_c_locale(__c_locale& __cloc, const char* __s,
00384                __c_locale __old = 0);
00385 
00386     static __c_locale
00387     _S_clone_c_locale(__c_locale& __cloc);
00388 
00389     static void
00390     _S_destroy_c_locale(__c_locale& __cloc);
00391 
00392     
00393     
00394     static __c_locale
00395     _S_get_c_locale();
00396 
00397     static const char*
00398     _S_get_c_name();
00399 
00400   private:
00401     inline void
00402     _M_add_reference() const throw()
00403     { __gnu_cxx::__atomic_add(&_M_refcount, 1); }
00404 
00405     inline void
00406     _M_remove_reference() const throw()
00407     {
00408       if (__gnu_cxx::__exchange_and_add(&_M_refcount, -1) == 1)
00409     {
00410       try
00411         { delete this; }
00412       catch (...)
00413         { }
00414     }
00415     }
00416 
00417     facet(const facet&);  
00418 
00419     facet&
00420     operator=(const facet&);  
00421   };
00422 
00423 
00424   
00434   class locale::id
00435   {
00436   private:
00437     friend class locale;
00438     friend class locale::_Impl;
00439 
00440     template<typename _Facet>
00441       friend const _Facet&
00442       use_facet(const locale&);
00443 
00444     template<typename _Facet>
00445       friend bool
00446       has_facet(const locale&) throw ();
00447 
00448     
00449     
00450     
00451     mutable size_t      _M_index;
00452 
00453     
00454     static _Atomic_word     _S_refcount;
00455 
00456     void
00457     operator=(const id&);  
00458 
00459     id(const id&);  
00460 
00461   public:
00462     
00463     
00465     id() { }
00466 
00467     size_t
00468     _M_id() const;
00469   };
00470 
00471 
00472   
00473   class locale::_Impl
00474   {
00475   public:
00476     
00477     friend class locale;
00478     friend class locale::facet;
00479 
00480     template<typename _Facet>
00481       friend bool
00482       has_facet(const locale&) throw();
00483 
00484     template<typename _Facet>
00485       friend const _Facet&
00486       use_facet(const locale&);
00487 
00488     template<typename _Cache>
00489       friend struct __use_cache;
00490 
00491   private:
00492     
00493     _Atomic_word            _M_refcount;
00494     const facet**           _M_facets;
00495     size_t              _M_facets_size;
00496     const facet**           _M_caches;
00497     char**              _M_names;
00498     static const locale::id* const  _S_id_ctype[];
00499     static const locale::id* const  _S_id_numeric[];
00500     static const locale::id* const  _S_id_collate[];
00501     static const locale::id* const  _S_id_time[];
00502     static const locale::id* const  _S_id_monetary[];
00503     static const locale::id* const  _S_id_messages[];
00504     static const locale::id* const* const _S_facet_categories[];
00505 
00506     inline void
00507     _M_add_reference() throw()
00508     { __gnu_cxx::__atomic_add(&_M_refcount, 1); }
00509 
00510     inline void
00511     _M_remove_reference() throw()
00512     {
00513       if (__gnu_cxx::__exchange_and_add(&_M_refcount, -1) == 1)
00514     {
00515       try
00516         { delete this; }
00517       catch(...)
00518         { }
00519     }
00520     }
00521 
00522     _Impl(const _Impl&, size_t);
00523     _Impl(const char*, size_t);
00524     _Impl(size_t) throw();
00525 
00526    ~_Impl() throw();
00527 
00528     _Impl(const _Impl&);  
00529 
00530     void
00531     operator=(const _Impl&);  
00532 
00533     inline bool
00534     _M_check_same_name()
00535     {
00536       bool __ret = true;
00537       if (_M_names[1])
00538     
00539     for (size_t __i = 0; __ret && __i < _S_categories_size - 1; ++__i)
00540       __ret = std::strcmp(_M_names[__i], _M_names[__i + 1]) == 0;
00541       return __ret;
00542     }
00543 
00544     void
00545     _M_replace_categories(const _Impl*, category);
00546 
00547     void
00548     _M_replace_category(const _Impl*, const locale::id* const*);
00549 
00550     void
00551     _M_replace_facet(const _Impl*, const locale::id*);
00552 
00553     void
00554     _M_install_facet(const locale::id*, const facet*);
00555 
00556     template<typename _Facet>
00557       inline void
00558       _M_init_facet(_Facet* __facet)
00559       { _M_install_facet(&_Facet::id, __facet); }
00560 
00561     void
00562     _M_install_cache(const facet*, size_t);
00563   };
00564 
00565   template<typename _Facet>
00566     locale::locale(const locale& __other, _Facet* __f)
00567     {
00568       _M_impl = new _Impl(*__other._M_impl, 1);
00569 
00570       try
00571     { _M_impl->_M_install_facet(&_Facet::id, __f); }
00572       catch(...)
00573     {
00574       _M_impl->_M_remove_reference();
00575       __throw_exception_again;
00576     }
00577       delete [] _M_impl->_M_names[0];
00578       _M_impl->_M_names[0] = 0;   
00579     }
00580 } 
00581 
00582 #endif