locale.cc (locale::name()): Implement.
authorBenjamin Kosnik <bkoz@purist.soma.redhat.com>
Fri, 15 Sep 2000 07:06:46 +0000 (07:06 +0000)
committerBenjamin Kosnik <bkoz@gcc.gnu.org>
Fri, 15 Sep 2000 07:06:46 +0000 (07:06 +0000)
2000-09-14  Benjamin Kosnik  <bkoz@purist.soma.redhat.com>

* src/locale.cc (locale::name()): Implement.
(_Impl(size_t __numfacets, size_t __refs, bool __namep = false,
string __name = "*")): Change signature.
(locale::classic): Initialize the "C" locale as a named locale.
* bits/localefwd.h (locale): Change _M_num_references to
_M_references. Eliminate _M_cached_name_ok. Rename _M_cached_name
to _M_name.
* bits/localefwd.h: Tweaks.
* src/localename.cc: Tweaks.
* testsuite/22_locale/ctor_copy_dtor.cc (test01): Add tests.
(test01): Fix.

* bits/basic_string.h: Consistency check, change _M_state ->
_M_references.

From-SVN: r36426

libstdc++-v3/ChangeLog
libstdc++-v3/bits/basic_string.h
libstdc++-v3/bits/localefwd.h
libstdc++-v3/src/locale.cc
libstdc++-v3/src/localename.cc
libstdc++-v3/testsuite/22_locale/ctor_copy_dtor.cc

index db6f542a081eee9d923a8e4a565606b6e932d46b..5547d6cc6406d84a0669c7f7d34c24968fe36003 100644 (file)
@@ -1,3 +1,20 @@
+2000-09-14  Benjamin Kosnik  <bkoz@purist.soma.redhat.com>
+
+       * src/locale.cc (locale::name()): Implement.
+       (_Impl(size_t __numfacets, size_t __refs, bool __namep = false,
+       string __name = "*")): Change signature.
+       (locale::classic): Initialize the "C" locale as a named locale.
+       * bits/localefwd.h (locale): Change _M_num_references to
+       _M_references. Eliminate _M_cached_name_ok. Rename _M_cached_name
+       to _M_name.
+       * bits/localefwd.h: Tweaks.
+       * src/localename.cc: Tweaks.
+       * testsuite/22_locale/ctor_copy_dtor.cc (test01): Add tests.
+       (test01): Fix.
+
+       * bits/basic_string.h: Consistency check, change _M_state ->
+       _M_references.
+
 2000-09-14  Brendan Kehoe  <brendan@zen.org>
 
         * bits/string.tcc (_Rep::_S_max_size): Use typename for its size_type
@@ -13,7 +30,7 @@
        * bits/std_ostream.h (ends(basic_ostream<_CharT, _Traits>& __os)):
        Change __eos to _S_eos.
        
-2000-09-13  Benjamin Kosnik  <bkoz@redhat.com>
+2000-09-13  Benjamin Kosnik  <bkoz@purist.soma.redhat.com>
 
        * testsuite/22_locale/static_members.cc: New file.
        * testsuite/22_locale/ctor_copy_dtor.cc: New file.
index c857790625ecdea85833d6c9edfaaa7ebeb75c0b..60795f7b72e5354bfbe232009a5b36aae093d201 100644 (file)
@@ -105,7 +105,7 @@ namespace std {
       //      _CharT() where the interface does not require it.
       //   2. _M_capacity >= _M_length
       //      Allocated memory is always _M_capacity + (1 * sizeof(_CharT)).
-      //   3. _M_state has three states:
+      //   3. _M_references has three states:
       //      -1: leaked, one reference, no ref-copies allowed, non-const.
       //       0: one reference, non-const.
       //     n>0: n + 1 references, operations require a lock, const.
@@ -136,23 +136,23 @@ namespace std {
 
        size_type               _M_length;
        size_type               _M_capacity;
-       _Atomic_word            _M_state;
+       _Atomic_word            _M_references;
        
         bool
        _M_is_leaked() const
-        { return _M_state < 0; }
+        { return _M_references < 0; }
 
         bool
        _M_is_shared() const
-        { return _M_state > 0; }
+        { return _M_references > 0; }
 
         void
        _M_set_leaked() 
-        { _M_state = -1; }
+        { _M_references = -1; }
 
         void
        _M_set_sharable() 
-        { _M_state = 0; }
+        { _M_references = 0; }
 
        _CharT* 
        _M_refdata() throw()
@@ -174,7 +174,7 @@ namespace std {
        void 
        _M_dispose(const _Alloc& __a)
        { 
-         if (__exchange_and_add(&_M_state, -1) <= 0)  
+         if (__exchange_and_add(&_M_references, -1) <= 0)  
            _M_destroy(__a); 
        }  // XXX MT
 
@@ -184,7 +184,7 @@ namespace std {
        _CharT* 
        _M_refcopy() throw()
        { 
-         __atomic_add(&_M_state, 1); 
+         __atomic_add(&_M_references, 1); 
          return _M_refdata(); 
        }  // XXX MT
 
index f30dd40c8da1c638671346fa12d84ab514ea6581..a0b4a26d2680348572f1f1ee134a88e6887020d3 100644 (file)
@@ -250,9 +250,9 @@ namespace std
     explicit  
     locale(const char* __std_name);
 
-    locale(const locale& __other, const char* __std_name, category __cats);
+    locale(const locale& __other, const char* __std_name, category __cat);
 
-    locale(const locale& __other, const locale& __one, category __cats);
+    locale(const locale& __other, const locale& __one, category __cat);
 
     template<typename _Facet>
       locale(const locale& __other, _Facet* __f);
@@ -300,6 +300,8 @@ namespace std
     // Current global reference locale
     static _Impl*      _S_global;  
 
+    static const int   _S_num_categories = _Count_ones<all>::_S_count;
+
     explicit 
     locale(_Impl*) throw();
 
@@ -309,9 +311,6 @@ namespace std
 
     static int  
     _S_normalize_category(int);
-
-    static const int 
-    _S_num_categories = _Count_ones<all>::_S_count;
   };
 
 
@@ -337,12 +336,11 @@ namespace std
 
   private:
     // Data Members.
-    size_t                             _M_num_references;
+    size_t                             _M_references;
     __vec_facet*                       _M_facets;
     __vec_string*                      _M_category_names;
     bool                               _M_has_name;
-    bool                               _M_cached_name_ok;
-    string                             _M_cached_name;
+    string                             _M_name;
     static const locale::id* const     _S_id_collate[];
     static const locale::id* const     _S_id_ctype[];
     static const locale::id* const     _S_id_monetary[];
@@ -353,12 +351,12 @@ namespace std
 
     inline void 
     _M_add_reference() throw()
-    { ++_M_num_references; }  // XXX MT
+    { ++_M_references; }  // XXX MT
 
     inline void 
     _M_remove_reference() throw()
     {
-      if (_M_num_references-- == 0)  // XXX MT
+      if (_M_references-- == 0)  // XXX MT
        {
          try { 
            delete this; 
@@ -370,7 +368,7 @@ namespace std
 
     _Impl(const _Impl&, size_t __refs);
     _Impl(const _Impl&, const string&, category, size_t __refs);
-    _Impl(size_t __facets, size_t __refs);
+    _Impl(size_t __facets, size_t __refs, bool __has_name, string __name);
    ~_Impl() throw();
 
     void 
@@ -409,7 +407,7 @@ namespace std
     _M_construct_messages(const char*);
 
     category 
-    _M_normalize_category_names(const string&, category __cats);
+    _M_normalize_category_names(const string&, category __cat);
   };
 
   // class locale inlines, that need declaration of locale::_Imp
@@ -428,6 +426,7 @@ namespace std
       _M_impl = new _Impl(*__other._M_impl, 0);
       _M_impl->_M_install_facet(&_Facet::id, __f);
       _M_impl->_M_has_name = false;
+      _M_impl->_M_name = "*";
     }
 
   locale::~locale() throw()
@@ -447,7 +446,7 @@ namespace std
     ~facet() {};
 
   private:
-    size_t _M_num_references;
+    size_t _M_references;
 
     void 
     _M_add_reference() throw();
index 58e55a36d0a803a98d39fb2b33b864a09d3e3469..c5f4fcf789f26b3ec07042ed39f5e4dd8fbf0bdb 100644 (file)
@@ -40,6 +40,7 @@
 #ifdef _GLIBCPP_USE_WCHAR_T  
   #include <bits/std_cwctype.h>     // for towupper, etc.
 #endif
+
 namespace std {
 
   // Definitions for static const data members of locale.
@@ -550,134 +551,50 @@ namespace std {
     return __incl_prec;
   }
 
-  // locale::_Impl
-  locale::_Impl::
-  ~_Impl() throw()
-  {
-    std::vector<facet*>::iterator it = _M_facets->begin();
-    for (; it != _M_facets->end(); ++it)
-      (*it)->_M_remove_reference();
-    delete _M_facets;
-    delete _M_category_names;
-  }
 
-  locale::_Impl::
-  _Impl(size_t __numfacets, size_t __refs)
-  : _M_num_references(__refs - 1), _M_facets(0), _M_category_names(0), 
-    _M_has_name(false), _M_cached_name_ok(false), _M_cached_name(string ("*"))
-  { 
-    typedef vector<facet*, allocator<facet*> > __vec_facet;
-    typedef vector<string, allocator<string> > __vec_string;
-
-    auto_ptr<__vec_facet> __pvf(new __vec_facet(__numfacets, (facet*)0));
-    auto_ptr<__vec_string> __pcn(new __vec_string(_S_num_categories, 
-                                                 string("*")));
-    _M_facets = __pvf.release();
-    _M_category_names = __pcn.release();
-  }
-  
-  locale::_Impl::
-  _Impl(const _Impl& __other, size_t __refs)
-  : _M_num_references(__refs), _M_facets(0), _M_category_names(0), 
-    _M_has_name(__other._M_has_name), 
-    _M_cached_name_ok(__other._M_cached_name_ok), 
-    _M_cached_name(__other._M_cached_name)
+  locale::locale(const char* __name)
   {
-    typedef vector<facet*, allocator<facet*> > __vec_facet;
-    typedef vector<string, allocator<string> > __vec_string;
-
-    auto_ptr<__vec_facet> __pvf(new __vec_facet(*(__other._M_facets)));
-    auto_ptr<__vec_string> 
-      __pcn(new __vec_string(*(__other._M_category_names)));
-
-    std::vector<facet*>::iterator __it = __pvf->begin();
-    for (; __it != __pvf->end(); ++__it)
-      (*__it)->_M_add_reference();
-
-    // These must be last since in the presence of an exception, the 
-    // destructor for 'this' won't run until AFTER execution has passed  
-    // the closing brace of the constructor.
-    _M_facets = __pvf.release();
-    _M_category_names = __pcn.release();
-  }
-  
-  void
-  locale::_Impl::
-  _M_replace_categories(const _Impl* __other, category __cats)
-  {
-    assert((__cats & locale::all) && !(__cats & ~locale::all));
-    
-    unsigned mask = (locale::all & -(unsigned)locale::all);
-    for (unsigned ix = 0; (-mask & __cats) != 0; ++ix, (mask <<= 1))
+    _S_initialize();
+    if (strcmp(__name, "C") == 0 || strcmp(__name, "POSIX") == 0)
+      (_M_impl = _S_classic)->_M_add_reference();
+    else
       {
-       if (mask & __cats)
-         {
-           _M_replace_category(__other, _S_facet_categories[ix]);
-           (*_M_category_names)[ix] = (*(__other->_M_category_names))[ix];
-         }
+       // Might throw:
+       _M_impl = new _Impl(*_S_classic, __name, all, 1);
+        _M_impl->_M_has_name = true;
       }
   }
 
-  void
-  locale::_Impl::
-  _M_replace_category(const _Impl* __other, const locale::id* const* __idpp)
-  {
-    for (; *__idpp; ++__idpp)
-      _M_replace_facet(__other, *__idpp);
-  }
-  
-  void
-  locale::_Impl::
-  _M_replace_facet(const _Impl* __other, const locale::id* __idp)
-  {
-    size_t __index = __idp->_M_index;
-    if (__index == 0 
-       || __other->_M_facets->size() <= __index 
-       || (*(__other->_M_facets))[__index] == 0)
-      throw runtime_error("no locale facet");
-       
-    _M_install_facet(__idp, (*(__other->_M_facets))[__index]); 
-  }
+  locale::locale(const locale& __other, const char* __name, category __cat)
+  : _M_impl(new _Impl(*__other._M_impl, __name, _S_normalize_category(__cat), 1))
+  { }
 
-  void
-  locale::_Impl::
-  _M_install_facet(const locale::id* __idp, facet* __fp)
+  bool
+  locale::operator==(const locale& __rhs) const throw()
   {
-    if (__fp == 0)
-      return;
-
-    size_t& __index = __idp->_M_index;
-    if (!__index)
-      __index = ++locale::id::_S_highwater;  // XXX MT
-
-    if (__index >= _M_facets->size())
-      _M_facets->resize(__index + 1, 0);  // might throw
-    facet*& __fpr = (*_M_facets)[__index];
-    // Order matters, here:
-    __fp->_M_add_reference();
-    if (__fpr) 
-      __fpr->_M_remove_reference();
-    __fpr = __fp;
+    return((this->name() != "*" && this->name() == __rhs.name())
+          || _M_impl == __rhs._M_impl);
   }
+
   locale::locale(_Impl* __ip) throw()
   : _M_impl(__ip)
   { __ip->_M_add_reference(); }
 
-  locale::locale(const locale& __other, const locale& __one, category __cats)
+  locale::locale(const locale& __other, const locale& __one, category __cat)
   {
-    __cats = _S_normalize_category(__cats);    // might throw
+    __cat = _S_normalize_category(__cat);    // might throw
     _M_impl = new _Impl(*__other._M_impl, 1);  // might throw
 
     try { 
-      _M_impl->_M_replace_categories(__one._M_impl, __cats); 
+      _M_impl->_M_replace_categories(__one._M_impl, __cat); 
     }
     catch (...) { 
       _M_impl->_M_remove_reference(); 
       throw; 
     }
 
-    _M_impl->_M_cached_name_ok = false;
+    // XXX
+    //    _M_impl->_M_cached_name_ok = false;
     if (!__other._M_impl->_M_has_name)
       _M_impl->_M_has_name = false;
   }
@@ -707,10 +624,7 @@ namespace std {
 
   string
   locale::name() const
-  {
-    // XXX not done
-    return "*";
-  }
+  { return _M_impl->_M_name; }
 
   locale const&
   locale::classic()
@@ -722,7 +636,8 @@ namespace std {
        try {
          // 26 Standard facets, 2 references.
          // One reference for _M_classic, one for _M_global
-         _S_classic = _S_global = new _Impl(26, 2);
+         _S_classic = new _Impl(26, 2, true, "C");
+         _S_global = _S_classic; 
 
          // collate category
          _S_classic->_M_facet_init(new std::collate<char>);
@@ -784,33 +699,49 @@ namespace std {
   }
 
   int
-  locale::_S_normalize_category(int __cats
+  locale::_S_normalize_category(int __cat) 
   {
-    if ((__cats & all) && !(__cats & ~all))
-      return __cats;
-
-    // NB: May be a C-style "LC_ALL" category; convert.
-    switch (__cats)
+    int __ret;
+    if ((__cat & all) && !(__cat & ~all))
+      __ret = __cat;
+    else
       {
-      case LC_COLLATE:  return collate; 
-      case LC_CTYPE:    return ctype;
-      case LC_MONETARY: return monetary;
-      case LC_NUMERIC:  return numeric;
-      case LC_TIME:     return time; 
+       // NB: May be a C-style "LC_ALL" category; convert.
+       switch (__cat)
+         {
+         case LC_COLLATE:  
+           __ret = collate; 
+           break;
+         case LC_CTYPE:    
+           __ret = ctype;
+           break;
+         case LC_MONETARY: 
+           __ret = monetary;
+           break;
+         case LC_NUMERIC:  
+           __ret = numeric;
+           break;
+         case LC_TIME:     
+           __ret = time; 
+           break;
 #ifdef _GLIBCPP_HAVE_LC_MESSAGES
-      case LC_MESSAGES: return messages;
+         case LC_MESSAGES: 
+           __ret = messages;
+           break;
 #endif 
-      case LC_ALL:      return all;
+         case LC_ALL:      
+           __ret = all;
+           break;
+         default:
+           throw runtime_error("bad locale category");
+         }
       }
-    
-    // XXX Should throw derived class here
-    throw runtime_error("bad locale category");
-    /* NOTREACHED */
+    return __ret;
   }
 
   locale::facet::
   facet(size_t __refs) throw()
-  : _M_num_references(__refs - 1) 
+  : _M_references(__refs - 1) 
   { }
 
   void  
@@ -818,14 +749,14 @@ namespace std {
   _M_add_reference() throw()
   { 
     if (this) 
-      ++_M_num_references; 
+      ++_M_references; 
   }                     // XXX MT
 
   void  
   locale::facet::
   _M_remove_reference() throw()
   {
-    if (this && _M_num_references-- == 0)
+    if (this && _M_references-- == 0)
       {
         try { 
          delete this; 
index 200346930c9c303c570860a4cefd5793e28bd7ef..baa3bee7799b4090b12f3fcb531a9736969f2a90 100644 (file)
@@ -1,5 +1,4 @@
-
-// Copyright (C) 1997-1999 Free Software Foundation, Inc.
+// Copyright (C) 1997, 1998, 1999, 2000 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
 #include <bits/std_cstring.h>
 #include <bits/std_cassert.h>
 #include <bits/std_vector.h>
+#include <bits/std_stdexcept.h>
 
 namespace std {
 
-/////////////////////////////
-// locale::_Impl constructors
-/////////////////////////////
+  locale::_Impl::
+  ~_Impl() throw()
+  {
+    std::vector<facet*>::iterator it = _M_facets->begin();
+    for (; it != _M_facets->end(); ++it)
+      (*it)->_M_remove_reference();
+    delete _M_facets;
+    delete _M_category_names;
+  }
 
-  // construct specific categories, leaving unselected ones alone
-  //////////
-  locale::_Impl::_Impl(const _Impl& other,const string& name, category cats,
-                      size_t refs)
-  : _M_num_references(refs)
+  // This constructor is used to correctly initialize the standard,
+  // required facets.
+  locale::_Impl::
+  _Impl(size_t __numfacets, size_t __refs, bool __has_name = false, 
+       string __name = "*")
+  : _M_references(__refs - 1), _M_facets(0), _M_category_names(0), 
+    _M_has_name(__has_name), _M_name(__name)
+  { 
+    typedef vector<facet*, allocator<facet*> > __vec_facet;
+    typedef vector<string, allocator<string> > __vec_string;
+
+    auto_ptr<__vec_facet> __pvf(new __vec_facet(__numfacets, (facet*)0));
+    auto_ptr<__vec_string> __pcn(new __vec_string(_S_num_categories, _M_name));
+    _M_facets = __pvf.release();
+    _M_category_names = __pcn.release();
+  }
+  
+  locale::_Impl::
+  _Impl(const _Impl& __other, size_t __refs)
+  : _M_references(__refs - 1), _M_facets(0), _M_category_names(0), 
+    _M_has_name(__other._M_has_name), _M_name(__other._M_name)
+  {
+    typedef vector<facet*, allocator<facet*> > __vec_facet;
+    typedef vector<string, allocator<string> > __vec_string;
+
+    auto_ptr<__vec_facet> __pvf(new __vec_facet(*(__other._M_facets)));
+    auto_ptr<__vec_string> 
+      __pcn(new __vec_string(*(__other._M_category_names)));
+
+    std::vector<facet*>::iterator __it = __pvf->begin();
+    for (; __it != __pvf->end(); ++__it)
+      (*__it)->_M_add_reference();
+
+    // These must be last since in the presence of an exception, the 
+    // destructor for 'this' won't run until AFTER execution has passed  
+    // the closing brace of the constructor.
+    _M_facets = __pvf.release();
+    _M_category_names = __pcn.release();
+  }
+
+  // Construct specific categories, leaving unselected ones alone
+  locale::_Impl::
+  _Impl(const _Impl& __other, const string& __name, category __cat, 
+       size_t __refs)
+    : _M_references(__refs - 1)
     //  , _M_facets(other._M_facets)
     //  , _M_category_names(other._M_category_names)
-    , _M_has_name(other._M_has_name), _M_cached_name_ok(false)
+    , _M_has_name(__other._M_has_name), _M_name(__other._M_name)
   {
 #if 1
     typedef vector<facet*, allocator<facet*> > __vec_facet;
     typedef vector<string, allocator<string> > __vec_string;
     try {
-      _M_facets = new __vec_facet(*(other._M_facets));
+      _M_facets = new __vec_facet(*(__other._M_facets));
     }
     catch (...) {
       delete _M_facets;
       throw;
     }
     try {
-       _M_category_names = new __vec_string(*(other._M_category_names));
+       _M_category_names = new __vec_string(*(__other._M_category_names));
     }
     catch (...) {
       delete _M_category_names;
@@ -70,7 +116,7 @@ namespace std {
     // static void(_Impl::* const ctors[]) (const char*) = 
     static void(_Impl::* ctors[]) (const char*) = 
     {
-      //  NB: order must match the decl order in class locale.
+      //  NB: Order must match the decl order in class locale.
       &locale::_Impl::_M_construct_collate,
       &locale::_Impl::_M_construct_ctype,
       &locale::_Impl::_M_construct_monetary,
@@ -81,111 +127,167 @@ namespace std {
     };
     
     _S_initialize();
-    std::vector<facet*>::iterator it = _M_facets->begin();
-    for (; it != _M_facets->end(); ++it)
-      (*it)->_M_add_reference();
+    std::vector<facet*>::iterator __it = _M_facets->begin();
+    for (; __it != _M_facets->end(); ++__it)
+      (*__it)->_M_add_reference();
 
     try {
-      category classix = _S_normalize_category(cats);  // might throw
-      _M_normalize_category_names(name, classix);
+      category __ccategory = _S_normalize_category(__cat);  // might throw
+      _M_normalize_category_names(__name, __ccategory);
        
       unsigned mask = (locale::all & -(unsigned)locale::all);
-      for (unsigned ix = 0; (-mask & cats) != 0; ++ix, (mask <<= 1))
+      for (unsigned ix = 0; (-mask & __cat) != 0; ++ix, (mask <<= 1))
        {
-         if (!(mask & cats))
+         if (!(mask & __cat))
            continue;
          
-         if (mask & classix)
+         if (mask & __ccategory)
            _M_replace_category(_S_classic, _S_facet_categories[ix]);
          else
-           (this->*ctors[ix]) (name.c_str());
+           (this->*ctors[ix]) (__name.c_str());
        }
     }
     catch (...) {
-      it = _M_facets->begin();
-      for (; it != _M_facets->end(); ++it)
-       (*it)->_M_remove_reference();
+      __it = _M_facets->begin();
+      for (; __it != _M_facets->end(); ++__it)
+       (*__it)->_M_remove_reference();
       throw;
     }
   }
+  
+  void
+  locale::_Impl::
+  _M_replace_categories(const _Impl* __other, category __cat)
+  {
+    assert((__cat & locale::all) && !(__cat & ~locale::all));
+    
+    unsigned int __mask = locale::all & -static_cast<unsigned int>(locale::all);
+    for (unsigned int __ix = 0; (-__mask & __cat) != 0; ++__ix, (__mask <<= 1))
+      {
+       if (__mask & __cat)
+         {
+           _M_replace_category(__other, _S_facet_categories[__ix]);
+           (*_M_category_names)[__ix] = (*(__other->_M_category_names))[__ix];
+         }
+      }
+  }
+
+  void
+  locale::_Impl::
+  _M_replace_category(const _Impl* __other, const locale::id* const* __idpp)
+  {
+    for (; *__idpp; ++__idpp)
+      _M_replace_facet(__other, *__idpp);
+  }
+  
+  void
+  locale::_Impl::
+  _M_replace_facet(const _Impl* __other, const locale::id* __idp)
+  {
+    size_t __index = __idp->_M_index;
+    if (__index == 0 
+       || __other->_M_facets->size() <= __index 
+       || (*(__other->_M_facets))[__index] == 0)
+      throw runtime_error("no locale facet");
+       
+    _M_install_facet(__idp, (*(__other->_M_facets))[__index]); 
+  }
+
+  void
+  locale::_Impl::
+  _M_install_facet(const locale::id* __idp, facet* __fp)
+  {
+    if (__fp == 0)
+      return;
+
+    size_t& __index = __idp->_M_index;
+    if (!__index)
+      __index = ++locale::id::_S_highwater;  // XXX MT
 
-  //////////
+    if (__index >= _M_facets->size())
+      _M_facets->resize(__index + 1, 0);  // might throw
+    facet*& __fpr = (*_M_facets)[__index];
+    // Order matters, here:
+    __fp->_M_add_reference();
+    if (__fpr) 
+      __fpr->_M_remove_reference();
+    __fpr = __fp;
+  }
   locale::category
   locale::_Impl::_M_normalize_category_names(const string&, 
-                                            locale::category cats)
+                                            locale::category __cat)
   {
-
     // The problem to be solved here is that locale names
-    //   generally have one of two forms: they might have
-    //   only one component, such as "en_US"; or they might
-    //   have six, such as "en_US fr_FR en_US C C C", where
-    //   each component names a category.  Each vendor has
-    //   a different order of categories.  Each vendor uses
-    //   a different format:
-    //      AIX uses "C C C C C C"
-    //      Sun uses "/C/C/C/C/C/C"
-    //      HP uses  "/0:C;1:C;2:C;3:C;4:C;5:C;6:C;/"
-    //        (where the 0th element is for LC_ALL.)
-    //   Most systems (except AIX) permit the long form only for
-    //   setlocale(LC_ALL,...), and require the short form for
-    //   other calls.  All this matters because locale names are
-    //   supposed to be compatible between locale("") and
-    //   setlocale(..., "") constructors.
+    // generally have one of two forms: they might have
+    // only one component, such as "en_US"; or they might
+    // have six, such as "en_US fr_FR en_US C C C", where
+    // each component names a category.  Each vendor has
+    // a different order of categories.  Each vendor uses
+    // a different format:
+    //    AIX uses "C C C C C C"
+    //    Sun uses "/C/C/C/C/C/C"
+    //    HP uses  "/0:C;1:C;2:C;3:C;4:C;5:C;6:C;/"
+    //    (where the 0th element is for LC_ALL.)
+    // Most systems (except AIX) permit the long form only for
+    // setlocale(LC_ALL,...), and require the short form for
+    // other calls.  All this matters because locale names are
+    // supposed to be compatible between locale("") and
+    // setlocale(..., "") constructors.
     
-    return cats;
+    return __cat;
 #if 0 /* XXX not done */
     unsigned mask = (locale::all & -(unsigned)locale::all);
-    for (unsigned ix = 0; (-mask & cats) != 0; ++ix, (mask <<= 1))
+    for (unsigned ix = 0; (-mask & __cat) != 0; ++ix, (mask <<= 1))
       {
        
       }
 #endif
   }
 
-  //////////
   void 
-  locale::_Impl::_M_construct_collate(const char* /*name*/)
+  locale::_Impl::_M_construct_collate(const char* /*__name*/)
   {
 #if 0
-    _M_facet_init(new std::collate_byname<char>(name));
-    _M_facet_init(new std::collate_byname<wchar_t>(name));
+    _M_facet_init(new std::collate_byname<char>(__name));
+    _M_facet_init(new std::collate_byname<wchar_t>(__name));
 #endif
   }
 
   void 
-  locale::_Impl::_M_construct_ctype(const char* /*name*/)
+  locale::_Impl::_M_construct_ctype(const char* /*__name*/)
   {
 #if 0
-    _M_facet_init(new std::ctype_byname<char>(name));
-    _M_facet_init(new std::ctype_byname<wchar_t>(name));
-    _M_facet_init(new std::codecvt_byname<char,char,mbstate_t>(name));
-    _M_facet_init(new std::codecvt_byname<wchar_t,char,mbstate_t>(name));
+    _M_facet_init(new std::ctype_byname<char>(__name));
+    _M_facet_init(new std::ctype_byname<wchar_t>(__name));
+    _M_facet_init(new std::codecvt_byname<char, char, mbstate_t>(__name));
+    _M_facet_init(new std::codecvt_byname<wchar_t, char, mbstate_t>(__name));
 #endif
   }
     
   void 
-  locale::_Impl::_M_construct_monetary(const char* /*name*/)
+  locale::_Impl::_M_construct_monetary(const char* /*__name*/)
   {
 #if 0
-    _M_facet_init(new std::moneypunct_byname<char,false>(name));
-    _M_facet_init(new std::moneypunct_byname<wchar_t,false>(name));
-    _M_facet_init(new std::moneypunct_byname<char,true >(name));
-    _M_facet_init(new std::moneypunct_byname<wchar_t,true >(name));
+    _M_facet_init(new std::moneypunct_byname<char, false>(__name));
+    _M_facet_init(new std::moneypunct_byname<wchar_t, false>(__name));
+    _M_facet_init(new std::moneypunct_byname<char, true >(__name));
+    _M_facet_init(new std::moneypunct_byname<wchar_t, true >(__name));
 
     locale::_M_initialize();
-    _M_replace_facet(locale::_S_classic, &std::money_get<char>(name)::id);
-    _M_replace_facet(locale::_S_classic, &std::money_get<wchar_t>(name)::id);
-    _M_replace_facet(locale::_S_classic, &std::money_put<char>(name)::id);
-    _M_replace_facet(locale::_S_classic, &std::money_put<wchar_t>(name)::id);
+    _M_replace_facet(locale::_S_classic, &std::money_get<char>(__name)::id);
+    _M_replace_facet(locale::_S_classic, &std::money_get<wchar_t>(__name)::id);
+    _M_replace_facet(locale::_S_classic, &std::money_put<char>(__name)::id);
+    _M_replace_facet(locale::_S_classic, &std::money_put<wchar_t>(__name)::id);
 #endif
   }
     
   void 
-  locale::_Impl::_M_construct_numeric(const char* /*name*/)
+  locale::_Impl::_M_construct_numeric(const char* /*__name*/)
   {
 #if 0
-    _M_facet_init(new std::numpunct_byname<char>(name));
-    _M_facet_init(new std::numpunct_byname<wchar_t>(name));
+    _M_facet_init(new std::numpunct_byname<char>(__name));
+    _M_facet_init(new std::numpunct_byname<wchar_t>(__name));
 
     locale::_M_initialize();
     _M_replace_facet(locale::_S_classic, &std::num_get<char>::id);
@@ -196,55 +298,25 @@ namespace std {
   }
     
   void 
-  locale::_Impl::_M_construct_time(const char* /*name*/)
+  locale::_Impl::_M_construct_time(const char* /*__name*/)
   {
 #if 0
-    _M_facet_init(new std::time_get_byname<char>(name));
-    _M_facet_init(new std::time_get_byname<wchar_t>(name));
-    _M_facet_init(new std::time_put_byname<char>(name));
-    _M_facet_init(new std::time_put_byname<wchar_t>(name));
+    _M_facet_init(new std::time_get_byname<char>(__name));
+    _M_facet_init(new std::time_get_byname<wchar_t>(__name));
+    _M_facet_init(new std::time_put_byname<char>(__name));
+    _M_facet_init(new std::time_put_byname<wchar_t>(__name));
 #endif
   }
     
   void 
-  locale::_Impl::_M_construct_messages(const char* /*name*/)
+  locale::_Impl::_M_construct_messages(const char* /*__name*/)
   {
 #if 0
-    _M_facet_init(new std::messages_byname<char>(name));
-    _M_facet_init(new std::messages_byname<wchar_t>(name));
+    _M_facet_init(new std::messages_byname<char>(__name));
+    _M_facet_init(new std::messages_byname<wchar_t>(__name));
 #endif
   }
+}
 
-  //////////////////////
-  // locale constructors
-  //////////////////////
-  
-  ////////
-  locale::locale(const char* std_name)
-  {
-    _S_initialize();
-    if (strcmp(std_name, "C") == 0 || strcmp(std_name, "POSIX"))
-      (_M_impl = _S_classic)->_M_add_reference();
-    else
-      {
-       // might throw:
-       _M_impl = new _Impl(*_S_classic, string(std_name), all, 1);
-        _M_impl->_M_has_name = true;
-      }
-  }
-
-  /////////
-  locale::locale(const locale& other, const char* std_name, category cats)
-  : _M_impl(new _Impl(*other._M_impl, string(std_name),
-                     _S_normalize_category(cats), 1))  // might throw
-  { }
 
-  ///////
-  bool
-  locale::operator==(const locale& __rhs) const throw()
-  {
-    return(_M_impl == __rhs._M_impl 
-          || (this->name() != "*" && this->name() == __rhs.name()));
-  }
 
-}
index ddc2a6a193152778f56b58de8ff9b01488a512ac..d276dc875ea1e7d113ac26ce459c5acae6787c42 100644 (file)
@@ -21,6 +21,7 @@
 // 22.1.1.2 locale constructors and destructors [lib.locale.cons]
 
 #include <locale>
+#include <stdexcept>
 #include <debug_assert.h>
 
 typedef std::codecvt<char, char, mbstate_t> ccodecvt;
@@ -35,25 +36,46 @@ void test01()
 
   // construct a locale object with the C facet
   const locale&        loc01 = locale::classic();
-  // construct a locale object with the specialized facet.
-  locale                loc02(locale::classic(), new gnu_codecvt);
-  VERIFY ( loc01 != loc02 );
-  VERIFY ( !(loc01 == loc02) );
 
   // 1
+  // template <class Facet> locale(const locale& other, Facet* f)
+  // construct a locale object with the specialized facet.
+  locale loc02(locale::classic(), new gnu_codecvt);
+  VERIFY (loc01 != loc02);
+  VERIFY (loc02.name() == "*");
+
+  // 2
   // locale() throw()
   locale loc03;
-  VERIFY ( loc03 == loc01);
-  locale loc04 = global(loc02);
+  VERIFY (loc03 == loc01);
+  VERIFY (loc03.name() == "C");
+  locale loc04 = locale::global(loc02);
   locale loc05;
   VERIFY (loc05 != loc03);
   VERIFY (loc05 == loc02);
 
-#if  0
-  str1 = cloc.name();
-  str2 = loc.name();  
-  VERIFY( loc(str1, str2) == false );
- #endif
+  // 3
+  // explicit locale(const char* std_name)
+  locale loc06("fr_FR");
+  VERIFY (loc06 != loc01);  
+  VERIFY (loc06 != loc02);  
+  VERIFY (loc06.name() == "fr_FR");
+  locale loc07("");
+  VERIFY (loc07 != loc01);  
+  VERIFY (loc07 != loc02);  
+  VERIFY (loc06.name() == "");
+  try
+    { locale loc08(static_cast<const char*>(NULL)); }
+  catch(runtime_error& obj)
+    { VERIFY (true); }
+  catch(...)
+    { VERIFY (false); }
+
+  // 4
+  // locale(const locale& other, const char* std_name, category)
+  
+
+
 }
 
 int main ()