locale_classes.h

00001 // Locale support -*- C++ -*-
00002 
00003 // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003
00004 // Free Software Foundation, Inc.
00005 //
00006 // This file is part of the GNU ISO C++ Library.  This library is free
00007 // software; you can redistribute it and/or modify it under the
00008 // terms of the GNU General Public License as published by the
00009 // Free Software Foundation; either version 2, or (at your option)
00010 // any later version.
00011 
00012 // This library is distributed in the hope that it will be useful,
00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 // GNU General Public License for more details.
00016 
00017 // You should have received a copy of the GNU General Public License along
00018 // with this library; see the file COPYING.  If not, write to the Free
00019 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
00020 // USA.
00021 
00022 // As a special exception, you may use this file as part of a free software
00023 // library without restriction.  Specifically, if other files instantiate
00024 // templates or use macros or inline functions from this file, or you compile
00025 // this file and link it with other files to produce an executable, this
00026 // file does not by itself cause the resulting executable to be covered by
00027 // the GNU General Public License.  This exception does not however
00028 // invalidate any other reasons why the executable file might be covered by
00029 // the GNU General Public License.
00030 
00031 //
00032 // ISO C++ 14882: 22.1  Locales
00033 //
00034 
00035 /** @file localefwd.h
00036  *  This is an internal header file, included by other library headers.
00037  *  You should not attempt to use it directly.
00038  */
00039 
00040 #ifndef _CPP_BITS_LOCALE_CLASSES_H
00041 #define _CPP_BITS_LOCALE_CLASSES_H  1
00042 
00043 #pragma GCC system_header
00044 
00045 #include <bits/localefwd.h>
00046 #include <cstring>      // For strcmp.
00047 #include <string>
00048 #include <bits/atomicity.h>
00049 
00050 namespace std
00051 {
00052   class __locale_cache_base;
00053   template<typename _Facet> class __locale_cache;
00054 
00055   // 22.1.1 Class locale
00056   class locale
00057   {
00058   public:
00059     // Types:
00060     typedef unsigned int    category;
00061 
00062     // Forward decls and friends:
00063     class facet;
00064     class id;
00065     class _Impl;
00066 
00067     friend class facet;
00068     friend class _Impl;
00069 
00070     template<typename _Facet>
00071       friend const _Facet& 
00072       use_facet(const locale&);
00073     
00074     template<typename _Facet>
00075       friend bool 
00076       has_facet(const locale&) throw();
00077  
00078     template<typename _Facet>
00079       friend const __locale_cache<_Facet>&
00080       __use_cache(const locale&);
00081 
00082     // Category values:
00083     // NB: Order must match _S_facet_categories definition in locale.cc
00084     static const category none      = 0;
00085     static const category ctype     = 1L << 0;
00086     static const category numeric   = 1L << 1;
00087     static const category collate   = 1L << 2;
00088     static const category time      = 1L << 3;
00089     static const category monetary  = 1L << 4;
00090     static const category messages  = 1L << 5;
00091     static const category all       = (ctype | numeric | collate |
00092                        time  | monetary | messages);
00093 
00094     // Construct/copy/destroy:
00095     locale() throw();
00096 
00097     locale(const locale& __other) throw();
00098 
00099     explicit  
00100     locale(const char* __s);
00101 
00102     locale(const locale& __base, const char* __s, category __cat);
00103 
00104     locale(const locale& __base, const locale& __add, category __cat);
00105 
00106     template<typename _Facet>
00107       locale(const locale& __other, _Facet* __f);
00108 
00109     ~locale() throw();
00110 
00111     const locale&  
00112     operator=(const locale& __other) throw();
00113 
00114     template<typename _Facet>
00115       locale  
00116       combine(const locale& __other) const;
00117 
00118     // Locale operations:
00119     string 
00120     name() const;
00121 
00122     bool 
00123     operator==(const locale& __other) const throw ();
00124 
00125     inline bool  
00126     operator!=(const locale& __other) const throw ()
00127     { return !(this->operator==(__other));  }
00128 
00129     template<typename _Char, typename _Traits, typename _Alloc>
00130       bool  
00131       operator()(const basic_string<_Char, _Traits, _Alloc>& __s1,
00132          const basic_string<_Char, _Traits, _Alloc>& __s2) const;
00133 
00134     // Global locale objects:
00135     static locale 
00136     global(const locale&);
00137 
00138     static const locale& 
00139     classic();
00140 
00141   private:
00142     // The (shared) implementation
00143     _Impl*      _M_impl;  
00144 
00145     // The "C" reference locale
00146     static _Impl*   _S_classic; 
00147 
00148     // Current global locale
00149     static _Impl*   _S_global;  
00150 
00151     // Number of standard categories. For C++, these categories are
00152     // collate, ctype, monetary, numeric, time, and messages. These
00153     // directly correspond to ISO C99 macros LC_COLLATE, LC_CTYPE,
00154     // LC_MONETARY, LC_NUMERIC, and LC_TIME. In addition, POSIX (IEEE
00155     // 1003.1-2001) specifies LC_MESSAGES.
00156     static const size_t _S_categories_size = 6;
00157 
00158     // In addition to the standard categories, the underlying
00159     // operating system is allowed to define extra LC_*
00160     // macros. For GNU systems, the following are also valid:
00161     // LC_PAPER, LC_NAME, LC_ADDRESS, LC_TELEPHONE, LC_MEASUREMENT,
00162     // and LC_IDENTIFICATION.
00163     static const size_t _S_extra_categories_size = _GLIBCPP_NUM_CATEGORIES;
00164 
00165     // Names of underlying locale categories.  
00166     // NB: locale::global() has to know how to modify all the
00167     // underlying categories, not just the ones required by the C++
00168     // standard.
00169     static const char*  _S_categories[_S_categories_size 
00170                       + _S_extra_categories_size];
00171 
00172     explicit 
00173     locale(_Impl*) throw();
00174 
00175     static inline void  
00176     _S_initialize()
00177     { 
00178       if (!_S_classic) 
00179     classic();  
00180     }
00181 
00182     static category  
00183     _S_normalize_category(category);
00184 
00185     void
00186     _M_coalesce(const locale& __base, const locale& __add, category __cat);
00187   };
00188 
00189 
00190   // Implementation object for locale 
00191   class locale::_Impl
00192   {
00193   public:
00194     // Friends.
00195     friend class locale;
00196     friend class locale::facet;
00197 
00198     template<typename _Facet>
00199       friend const _Facet&  
00200       use_facet(const locale&);
00201 
00202     template<typename _Facet>
00203       friend bool  
00204       has_facet(const locale&) throw();
00205 
00206     template<typename _Facet>
00207       friend const __locale_cache<_Facet>&
00208       __use_cache(const locale&);
00209 
00210   private:
00211     // Data Members.
00212     _Atomic_word            _M_references;
00213     facet**                 _M_facets;
00214     size_t              _M_facets_size;
00215 
00216     char*               _M_names[_S_categories_size
00217                          + _S_extra_categories_size];
00218     static const locale::id* const  _S_id_ctype[];
00219     static const locale::id* const  _S_id_numeric[];
00220     static const locale::id* const  _S_id_collate[];
00221     static const locale::id* const  _S_id_time[];
00222     static const locale::id* const  _S_id_monetary[];
00223     static const locale::id* const  _S_id_messages[];
00224     static const locale::id* const* const _S_facet_categories[];
00225 
00226     inline void 
00227     _M_add_reference() throw()
00228     { __atomic_add(&_M_references, 1); }
00229 
00230     inline void 
00231     _M_remove_reference() throw()
00232     {
00233       if (__exchange_and_add(&_M_references, -1) == 1)
00234     {
00235       try 
00236         { delete this; } 
00237       catch(...) 
00238         { }
00239     }
00240     }
00241 
00242     _Impl(const _Impl&, size_t);
00243     _Impl(const char*, size_t);
00244     _Impl(facet**, size_t, bool);
00245 
00246    ~_Impl() throw();
00247 
00248     _Impl(const _Impl&);  // Not defined.
00249 
00250     void 
00251     operator=(const _Impl&);  // Not defined.
00252 
00253     inline bool
00254     _M_check_same_name()
00255     {
00256       bool __ret = true;
00257       for (size_t __i = 0; 
00258        __ret && __i < _S_categories_size + _S_extra_categories_size - 1; 
00259        ++__i)
00260     __ret &= (strcmp(_M_names[__i], _M_names[__i + 1]) == 0);
00261       return __ret;
00262     }
00263 
00264     void 
00265     _M_replace_categories(const _Impl*, category);
00266 
00267     void 
00268     _M_replace_category(const _Impl*, const locale::id* const*);
00269 
00270     void 
00271     _M_replace_facet(const _Impl*, const locale::id*);
00272 
00273     void 
00274     _M_install_facet(const locale::id*, facet*);
00275 
00276     template<typename _Facet>
00277       inline void 
00278       _M_init_facet(_Facet* __facet)
00279       { _M_install_facet(&_Facet::id, __facet);  }
00280 
00281     // Retrieve the cache at __index.  0 is returned if the cache is
00282     // missing.  Cache is actually located at __index +
00283     // _M_facets_size.  __index must be < _M_facets_size.
00284     inline __locale_cache_base*
00285       _M_get_cache(size_t __index)
00286       {
00287     return (__locale_cache_base*)_M_facets[__index + _M_facets_size];
00288       }
00289 
00290     // Save the supplied cache at __id.  Assumes _M_get_cache has been
00291     // called.
00292     void
00293     _M_install_cache(__locale_cache_base* __cache, int __id)
00294     {
00295       _M_facets[__id + _M_facets_size] = 
00296     reinterpret_cast<locale::facet*>(__cache);
00297     }
00298       
00299   };
00300 
00301   template<typename _Facet>
00302     locale::locale(const locale& __other, _Facet* __f)
00303     {
00304       _M_impl = new _Impl(*__other._M_impl, 1);
00305       _M_impl->_M_install_facet(&_Facet::id, __f);
00306       for (size_t __i = 0; 
00307        __i < _S_categories_size + _S_extra_categories_size; ++__i)
00308     {
00309       delete [] _M_impl->_M_names[__i];
00310       char* __new = new char[2];
00311       strcpy(__new, "*");
00312       _M_impl->_M_names[__i] = __new;
00313     }
00314     }
00315 
00316 
00317   // 22.1.1.1.2  Class locale::facet
00318   class locale::facet
00319   {
00320   private:
00321     friend class locale;
00322     friend class locale::_Impl;
00323 
00324     _Atomic_word            _M_references;
00325 
00326   protected:
00327     // Contains data from the underlying "C" library for the classic locale.
00328     static __c_locale               _S_c_locale;
00329 
00330     // String literal for the name of the classic locale.
00331     static char             _S_c_name[2];
00332     
00333     explicit 
00334     facet(size_t __refs = 0) throw();
00335 
00336     virtual 
00337     ~facet();
00338 
00339     static void
00340     _S_create_c_locale(__c_locale& __cloc, const char* __s, 
00341                __c_locale __old = 0);
00342 
00343     static __c_locale
00344     _S_clone_c_locale(__c_locale& __cloc);
00345 
00346     static void
00347     _S_destroy_c_locale(__c_locale& __cloc);
00348 
00349   private:
00350     void 
00351     _M_add_reference() throw();
00352 
00353     void 
00354     _M_remove_reference() throw();
00355 
00356     facet(const facet&);  // Not defined.
00357 
00358     void 
00359     operator=(const facet&);  // Not defined.
00360   };
00361 
00362 
00363   // 22.1.1.1.3 Class locale::id
00364   class locale::id
00365   {
00366   private:
00367     friend class locale;
00368     friend class locale::_Impl;
00369     template<typename _Facet>
00370       friend const _Facet&  
00371       use_facet(const locale&);
00372     template<typename _Facet>
00373       friend bool           
00374       has_facet(const locale&) throw ();
00375 
00376     // NB: There is no accessor for _M_index because it may be used
00377     // before the constructor is run; the effect of calling a member
00378     // function (even an inline) would be undefined.
00379     mutable size_t      _M_index;
00380 
00381     // Last id number assigned.
00382     static _Atomic_word     _S_highwater;   
00383 
00384     void 
00385     operator=(const id&);  // Not defined.
00386 
00387     id(const id&);  // Not defined.
00388 
00389   public:
00390     // NB: This class is always a static data member, and thus can be
00391     // counted on to be zero-initialized.
00392     id();
00393 
00394     inline size_t
00395     _M_id() const
00396     {
00397       if (!_M_index)
00398     _M_index = 1 + __exchange_and_add(&_S_highwater, 1);
00399       return _M_index - 1;
00400     }
00401   };
00402 } // namespace std
00403 
00404 #endif

Generated on Sat Jan 10 15:26:32 2004 for libstdc++-v3 Source by doxygen 1.3.4