OSDN Git Service

libstdc++/5432
[pf3gnuchains/gcc-fork.git] / libstdc++-v3 / src / localename.cc
index e4bc18f..816f758 100644 (file)
 // invalidate any other reasons why the executable file might be covered by
 // the GNU General Public License.
 
-#include <bits/std_clocale.h>
-#include <bits/std_locale.h>
-#include <bits/std_cstring.h>
-#include <bits/std_vector.h>
-#include <bits/std_stdexcept.h>
+#include <clocale>
+#include <cstring>
+#include <locale>
+#include <vector>
+#include <stdexcept>
 
 namespace std
 {
@@ -41,13 +41,12 @@ namespace std
       if (*it)
        (*it)->_M_remove_reference();
     delete _M_facets;
-    locale::facet::_S_destroy_c_locale(_M_c_locale);
   }
 
   // Clone existing _Impl object.
   locale::_Impl::
   _Impl(const _Impl& __imp, size_t __refs)
-  : _M_references(__refs - 1), _M_facets(0), _M_c_locale(0) // XXX
+  : _M_references(__refs), _M_facets(0) // XXX
   {
     try
       {  _M_facets = new __vec_facet(*(__imp._M_facets)); }
@@ -69,14 +68,18 @@ namespace std
   // Construct named _Impl, including the standard "C" locale.
   locale::_Impl::
   _Impl(string __str, size_t __refs)
-  : _M_references(__refs - 1), _M_facets(0)
+  : _M_references(__refs), _M_facets(0)
   {
     // Initialize the underlying locale model, which also checks to
     // see if the given name is valid.
+    __c_locale __cloc;
+    locale::facet::_S_create_c_locale(__cloc, __str.c_str());
+
+    // This is needed as presently "C" locales != required data in
+    // __timepunct, numpunct, and moneypunct.
+    __c_locale __cloc_c = NULL;
     if (__str != "C" && __str != "POSIX")
-      locale::facet::_S_create_c_locale(_M_c_locale, __str.c_str());
-    else
-      _M_c_locale = NULL;
+      __cloc_c = __cloc;
 
     // Allocate facet container.
     try
@@ -92,36 +95,38 @@ namespace std
       _M_names[i] = __str;
 
     // Construct all standard facets and add them to _M_facets.
-    // XXX Eventually, all should use __c_locale ctor like numpunct
-    _M_init_facet(new std::collate<char>);
-    _M_init_facet(new std::ctype<char>);
+    _M_init_facet(new std::collate<char>(__cloc));
+    _M_init_facet(new std::ctype<char>(__cloc));
     _M_init_facet(new codecvt<char, char, mbstate_t>);
-    _M_init_facet(new moneypunct<char, false>(_M_c_locale));
-    _M_init_facet(new moneypunct<char,true >);
+    _M_init_facet(new moneypunct<char, false>(__cloc_c));
+    _M_init_facet(new moneypunct<char, true>(__cloc_c));
     _M_init_facet(new money_get<char>);
     _M_init_facet(new money_put<char>);
-    _M_init_facet(new numpunct<char>(_M_c_locale));
+    _M_init_facet(new numpunct<char>(__cloc_c));
     _M_init_facet(new num_get<char>);
     _M_init_facet(new num_put<char>);
+    _M_init_facet(new __timepunct<char>(__cloc_c, __str.c_str()));
     _M_init_facet(new time_get<char>);
     _M_init_facet(new time_put<char>);
-    _M_init_facet(new std::messages<char>);
+    _M_init_facet(new std::messages<char>(__cloc, __str.c_str()));
     
 #ifdef  _GLIBCPP_USE_WCHAR_T
-    _M_init_facet(new std::collate<wchar_t>);
-    _M_init_facet(new std::ctype<wchar_t>);
+    _M_init_facet(new std::collate<wchar_t>(__cloc));
+    _M_init_facet(new std::ctype<wchar_t>(__cloc));
     _M_init_facet(new codecvt<wchar_t, char, mbstate_t>);
-    _M_init_facet(new moneypunct<wchar_t, false>(_M_c_locale));
-    _M_init_facet(new moneypunct<wchar_t,true >);
+    _M_init_facet(new moneypunct<wchar_t, false>(__cloc_c));
+    _M_init_facet(new moneypunct<wchar_t, true>(__cloc_c));
     _M_init_facet(new money_get<wchar_t>);
     _M_init_facet(new money_put<wchar_t>);
-    _M_init_facet(new numpunct<wchar_t>(_M_c_locale));
+    _M_init_facet(new numpunct<wchar_t>(__cloc_c));
     _M_init_facet(new num_get<wchar_t>);
     _M_init_facet(new num_put<wchar_t>);
+    _M_init_facet(new __timepunct<wchar_t>(__cloc_c, __str.c_str()));
     _M_init_facet(new time_get<wchar_t>);
     _M_init_facet(new time_put<wchar_t>);
-    _M_init_facet(new std::messages<wchar_t>);
+    _M_init_facet(new std::messages<wchar_t>(__cloc, __str.c_str()));
 #endif   
+    locale::facet::_S_destroy_c_locale(__cloc);
   }
   
   void
@@ -173,7 +178,7 @@ namespace std
       {
        size_t& __index = __idp->_M_index;
        if (!__index)
-         __index = ++locale::id::_S_highwater;  // XXX MT
+         __index = 1 + __exchange_and_add(&locale::id::_S_highwater, 1);
        
        if (__index >= _M_facets->size())
          _M_facets->resize(__index + 1, 0);  // might throw
@@ -184,8 +189,7 @@ namespace std
            // Replacing an existing facet.
            // Order matters, here:
            __fp->_M_add_reference();
-           if (__fpr) 
-             __fpr->_M_remove_reference();
+           __fpr->_M_remove_reference();
            __fpr = __fp;
          }
        else
@@ -198,4 +202,3 @@ namespace std
       }
   }
 } // namespace std
-