OSDN Git Service

libstdc++/5432
[pf3gnuchains/gcc-fork.git] / libstdc++-v3 / include / bits / localefwd.h
index be2908c..bcb60b7 100644 (file)
@@ -1,6 +1,7 @@
 // Locale support -*- C++ -*-
 
-// Copyright (C) 1997-2000 Free Software Foundation, Inc.
+// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002
+// Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
 // software; you can redistribute it and/or modify it under the
 // ISO C++ 14882: 22.1  Locales
 //
 
+/** @file localefwd.h
+ *  This is an internal header file, included by other library headers.
+ *  You should not attempt to use it directly.
+ */
+
 #ifndef _CPP_BITS_LOCCORE_H
 #define _CPP_BITS_LOCCORE_H    1
 
+#pragma GCC system_header
+
 #include <bits/c++config.h>
-#include <bits/std_climits.h>  // For CHAR_BIT
-#include <bits/std_string.h>   // For string
-#include <bits/std_cctype.h>   // For isspace, etc.
+#include <bits/c++locale.h>     // Defines __c_locale, config-specific includes
+#include <climits>             // For CHAR_BIT
+#include <cctype>              // For isspace, etc.
+#include <string>              // For string
+#include <bits/functexcept.h>
+
+#include <bits/atomicity.h>
 
 namespace std
 {
-
-  // _Count_ones: compile-time computation of number of 1-bits in a value N
-  // This takes only 5 (or 6) instantiations, doing recursive descent
-  // in parallel -- ncm
-  template<unsigned int _Num, int _Shift = (sizeof(unsigned) * CHAR_BIT)/2,
-           unsigned int _Mask = (~0u >> _Shift) >
-    struct _Count_ones;
-
-  // It is preferable to use enumerators instead of integral static data
-  // members to avoid emission of superflous variables -- gdr.
-  template<unsigned int _Num, unsigned int _Mask>
-    struct _Count_ones<_Num, 0, _Mask> 
-    {
-      enum
-      {
-        _S_count = _Num
-      };
-    };
-
-  template<unsigned int _Num, int _Shift, unsigned int _Mask>
-    struct _Count_ones 
-    {
-      enum
-      {
-        _S_halfcount = _Count_ones<_Num, _Shift/2,
-                                   (_Mask^((~_Mask)>>(_Shift/2))) >::_S_count,
-        _S_count = (_S_halfcount&_Mask) + ((_S_halfcount>>_Shift)&_Mask)
-      };
-    };
+  // NB: Don't instantiate required wchar_t facets if no wchar_t support.
+#ifdef _GLIBCPP_USE_WCHAR_T
+# define  _GLIBCPP_NUM_FACETS 28
+#else
+# define  _GLIBCPP_NUM_FACETS 14
+#endif
 
   // 22.1.1 Locale
-  template<typename _Tp> class allocator;
-  template<typename _Tp, typename _Alloc> class vector;
+  template<typename _Tp, typename _Alloc> 
+    class vector;
   class locale;
 
   // 22.1.3 Convenience interfaces
@@ -138,19 +127,18 @@ namespace std
 #ifdef _GLIBCPP_USE_WCHAR_T
   template<> class ctype<wchar_t>;
 #endif
-
   template<typename _CharT> 
     class ctype_byname;
   // NB: Specialized for char and wchar_t in locale_facets.h.
 
   class codecvt_base;
+  class __enc_traits;
   template<typename _InternT, typename _ExternT, typename _StateT>
     class codecvt;
   template<> class codecvt<char, char, mbstate_t>;
 #ifdef _GLIBCPP_USE_WCHAR_T
   template<> class codecvt<wchar_t, char, mbstate_t>;
 #endif
-
   template<typename _InternT, typename _ExternT, typename _StateT>
     class codecvt_byname;
 
@@ -165,10 +153,6 @@ namespace std
   // 22.2.4 collation
   template<typename _CharT> 
     class collate;
-  template<> class collate<char>;
-#ifdef _GLIBCPP_USE_WCHAR_T
-  template<> class collate<wchar_t>;
-#endif
   template<typename _CharT> class 
     collate_byname;
 
@@ -201,19 +185,19 @@ namespace std
   template<typename _CharT> 
     class messages_byname;
 
-
   // 22.1.1 Class locale
   class locale
   {
   public:
     // Types:
-    typedef int category;
+    typedef unsigned int       category;
 
     // Forward decls and friends:
     class facet;
     class id;
     class _Impl;
 
+    friend class facet;
     friend class _Impl;
 
     template<typename _Facet>
@@ -225,35 +209,32 @@ namespace std
       has_facet(const locale&) throw();
  
     // Category values:
-    // NB much depends on the order in which these appear:
+    // NB: Order must match _S_facet_categories definition in locale.cc
     static const category none         = 0;
-    static const category collate      = 0x0100;
-    static const category ctype        = 0x0200;
-    static const category monetary     = 0x0400;
-    static const category numeric      = 0x0800;
-    static const category time                 = 0x1000;
-    static const category messages     = 0x2000;
+    static const category ctype        = 1L << 0;
+    static const category numeric      = 1L << 1;
+    static const category collate      = 1L << 2;
+    static const category time                 = 1L << 3;
+    static const category monetary     = 1L << 4;
+    static const category messages     = 1L << 5;
     static const category all          = (collate | ctype | monetary |
                                           numeric | time  | messages);
 
     // Construct/copy/destroy:
-    inline  
     locale() throw();
 
-    inline  
     locale(const locale& __other) throw();
 
     explicit  
     locale(const char* __std_name);
 
-    locale(const locale& __other, const char* __std_name, category __cat);
+    locale(const locale& __base, const char* __s, category __cat);
 
-    locale(const locale& __other, const locale& __one, category __cat);
+    locale(const locale& __base, const locale& __add, category __cat);
 
     template<typename _Facet>
       locale(const locale& __other, _Facet* __f);
 
-    inline  
     ~locale() throw();
 
     const locale&  
@@ -261,7 +242,7 @@ namespace std
 
     template<typename _Facet>
       locale  
-      combine(const locale& __other);
+      combine(const locale& __other) const;
 
     // Locale operations:
     string 
@@ -272,7 +253,7 @@ namespace std
 
     inline bool  
     operator!=(const locale& __other) const throw ()
-    { return !(operator==(__other));  }
+    { return !(this->operator==(__other));  }
 
     template<typename _Char, typename _Traits, typename _Alloc>
       bool  
@@ -296,28 +277,33 @@ namespace std
     // Current global reference locale
     static _Impl*      _S_global;  
 
-    static const int   _S_categories_num = _Count_ones<all>::_S_count;
-    static const int   _S_facets_num = 26;
+    static const size_t        _S_num_categories = 6;
+    static const size_t _S_num_facets = _GLIBCPP_NUM_FACETS;
 
     explicit 
     locale(_Impl*) throw();
 
     static inline void  
     _S_initialize()
-    { if (!_S_classic) classic();  }
+    { 
+      if (!_S_classic) 
+       classic();  
+    }
 
-    static int  
-    _S_normalize_category(int);
+    static category  
+    _S_normalize_category(category);
+
+    void
+    _M_coalesce(const locale& __base, const locale& __add, category __cat);
   };
 
 
-  // locale implementation object
+  // Implementation object for locale 
   class locale::_Impl
   {
   public:
     // Types.
-    typedef vector<facet*, allocator<facet*> > __vec_facet;
-    typedef vector<string, allocator<string> > __vec_string;
+    typedef vector<facet*, allocator<facet*> >         __vec_facet;
 
     // Friends.
     friend class locale;
@@ -333,42 +319,46 @@ namespace std
 
   private:
     // Data Members.
-    size_t                             _M_references;
+    _Atomic_word                       _M_references;
     __vec_facet*                       _M_facets;
-    __vec_string*                      _M_category_names;
-    bool                               _M_has_name;
-    string                             _M_name;
-    static const locale::id* const     _S_id_collate[];
+    string                             _M_names[_S_num_categories];
     static const locale::id* const     _S_id_ctype[];
-    static const locale::id* const     _S_id_monetary[];
     static const locale::id* const     _S_id_numeric[];
+    static const locale::id* const     _S_id_collate[];
     static const locale::id* const     _S_id_time[];
+    static const locale::id* const     _S_id_monetary[];
     static const locale::id* const     _S_id_messages[];
     static const locale::id* const* const _S_facet_categories[];
 
     inline void 
     _M_add_reference() throw()
-    { ++_M_references; }  // XXX MT
+    { __atomic_add(&_M_references, 1); }
 
     inline void 
     _M_remove_reference() throw()
     {
-      if (_M_references-- == 0)  // XXX MT
+      if (__exchange_and_add(&_M_references, -1) == 1)
        {
-         try { 
-           delete this; 
-         } 
-         catch(...) { 
-         }
+         try 
+           { delete this; } 
+         catch(...) 
+           { }
        }
     }
 
-    _Impl(const _Impl&, size_t __refs);
-    _Impl(const _Impl&, const string&, category, size_t __refs);
-    _Impl(size_t __facets, size_t __refs, bool __has_name, 
-         string __name = "*");
+    _Impl(const _Impl&, size_t);
+    _Impl(string __name, size_t);
    ~_Impl() throw();
 
+    inline bool
+    _M_check_same_name()
+    {
+      bool __ret = true;
+      for (size_t i = 0; i < _S_num_categories - 1; ++i)
+       __ret &= _M_names[i] == _M_names[i + 1];
+      return __ret;
+    }
+
     void 
     _M_replace_categories(const _Impl*, category);
 
@@ -383,85 +373,67 @@ namespace std
 
     template<typename _Facet>
       inline void 
-      _M_facet_init(_Facet* __facet)
+      _M_init_facet(_Facet* __facet)
       { _M_install_facet(&_Facet::id, __facet);  }
-
-    void 
-    _M_construct_collate(const char*);
-
-    void 
-    _M_construct_ctype(const char*);
-
-    void 
-    _M_construct_monetary(const char*);
-
-    void 
-    _M_construct_numeric(const char*);
-
-    void 
-    _M_construct_time(const char*);
-
-    void 
-    _M_construct_messages(const char*);
-
-    category 
-    _M_normalize_category_names(const string&, category __cat);
   };
 
-  // class locale inlines, that need declaration of locale::_Imp
-  locale::locale() throw()
-  { 
-    _S_initialize(); 
-    (_M_impl = _S_global)->_M_add_reference(); 
-  } // XXX MT
-
-  locale::locale(const locale& __other) throw()
-  { (_M_impl = __other._M_impl)->_M_add_reference(); }
-
   template<typename _Facet>
     locale::locale(const locale& __other, _Facet* __f)
     {
       _M_impl = new _Impl(*__other._M_impl, 1);
       _M_impl->_M_install_facet(&_Facet::id, __f);
-      _M_impl->_M_has_name = false;
-      _M_impl->_M_name = "*";
+      for (size_t __i = 0; __i < _S_num_categories; ++__i)
+       _M_impl->_M_names[__i] = "*";
     }
 
-  locale::~locale() throw()
-  { _M_impl->_M_remove_reference(); }
-
   // 22.1.1.1.2  Class locale::facet
   class locale::facet
   {
     friend class locale;
     friend class locale::_Impl;
+    friend class __enc_traits;
+
+  private:
+    _Atomic_word _M_references;
 
   protected:
+    // Contains data from the underlying "C" library for default "C"
+    // or "POSIX" locale.
+    static __c_locale               _S_c_locale;
+    
     explicit 
     facet(size_t __refs = 0) throw();
 
     virtual 
-    ~facet() { };
+    ~facet();
 
-  private:
-    size_t _M_references;
+    static void
+    _S_create_c_locale(__c_locale& __cloc, const char* __s);
 
+    static __c_locale
+    _S_clone_c_locale(__c_locale& __cloc);
+
+    static void
+    _S_destroy_c_locale(__c_locale& __cloc);
+
+  private:
     void 
     _M_add_reference() throw();
 
     void 
     _M_remove_reference() throw();
 
-    facet(const facet&);  // not defined
+    facet(const facet&);  // Not defined.
 
     void 
-    operator=(const facet&);  // not defined
+    operator=(const facet&);  // Not defined.
   };
 
 
   // 22.1.1.1.3 Class locale::id
   class locale::id
   {
+  private:
     friend class locale;
     friend class locale::_Impl;
     template<typename _Facet>
@@ -470,21 +442,24 @@ namespace std
     template<typename _Facet>
       friend bool           
       has_facet(const locale&) throw ();
-  public:
-    id() {};
-  private:
+
     // NB: There is no accessor for _M_index because it may be used
     // before the constructor is run; the effect of calling a member
     // function (even an inline) would be undefined.
     mutable size_t     _M_index;
 
     // Last id number assigned
-    static size_t      _S_highwater;   
+    static _Atomic_word        _S_highwater;   
 
     void 
     operator=(const id&);  // not defined
 
     id(const id&);  // not defined
+
+  public:
+    // NB: This class is always a static data member, and thus can be
+    // counted on to be zero-initialized.
+    id();
   };
 
   template<typename _Facet>
@@ -494,12 +469,6 @@ namespace std
   template<typename _Facet>
     bool
     has_facet(const locale& __loc) throw();
-
 } // namespace std
 
-#endif /* _CPP_BITS_LOCCORE_H */
-
-// Local Variables:
-// mode:c++
-// End:
-
+#endif