OSDN Git Service

libstdc++/5432
[pf3gnuchains/gcc-fork.git] / libstdc++-v3 / src / locale.cc
index 0e899c1..5209182 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_cstring.h>
-#include <bits/std_cassert.h>
-#include <bits/std_cctype.h>
-#include <bits/std_limits.h>
+#include <clocale>
+#include <cstring>
+#include <cassert>
+#include <cctype>
+#include <limits>
 #include <exception>
-#include <bits/std_stdexcept.h>
-#include <bits/std_locale.h>
-#include <bits/std_istream.h>
-#include <bits/std_ostream.h>
-#include <bits/std_vector.h>
-#include <bits/std_memory.h>      // for auto_ptr
+#include <stdexcept>
+#include <locale>
+#include <istream>
+#include <ostream>
+#include <vector>
+#include <memory>      // for auto_ptr
 #ifdef _GLIBCPP_USE_WCHAR_T  
-# include <bits/std_cwctype.h>     // for towupper, etc.
+# include <cwctype>     // for towupper, etc.
 #endif
 
+#include <bits/atomicity.h>
+
 namespace std 
 {
   // Defined in globals.cc.
@@ -72,7 +74,7 @@ namespace std
 #endif
 
   // Definitions for static const data members of locale::id
-  size_t locale::id::_S_highwater;  // init'd to 0 by linker
+  _Atomic_word locale::id::_S_highwater;  // init'd to 0 by linker
 
   // Definitions for static const data members of locale::_Impl
   const locale::id* const
@@ -187,7 +189,7 @@ namespace std
   { 
     _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(); }
@@ -283,7 +285,9 @@ namespace std
   locale const&
   locale::classic()
   {
-    // XXX MT
+    static _STL_mutex_lock __lock __STL_MUTEX_INITIALIZER;
+    _STL_auto_lock __auto(__lock);
+
     if (!_S_classic)
       {
        try 
@@ -348,20 +352,29 @@ namespace std
     return __ret;
   }
 
+  __c_locale
+  locale::facet::_S_c_locale;
+  
+  locale::facet::
+  ~facet() { }
+
   locale::facet::
   facet(size_t __refs) throw() : _M_references(__refs) 
-  { }
+  { 
+    if (!_S_c_locale)
+      _S_create_c_locale(_S_c_locale, "C");
+  }
 
   void  
   locale::facet::
   _M_add_reference() throw()
-  { ++_M_references; }  // XXX MT
+  { __atomic_add(&_M_references, 1); }
 
   void  
   locale::facet::
   _M_remove_reference() throw()
   {
-    if (_M_references-- == 0)
+    if (__exchange_and_add(&_M_references, -1) == 0)
       {
         try 
          { delete this; }  
@@ -370,6 +383,8 @@ namespace std
       }
   }
   
+  locale::id::id() { }
+
   // Definitions for static const data members of ctype_base.
   const ctype_base::mask ctype_base::space;
   const ctype_base::mask ctype_base::print;
@@ -389,7 +404,12 @@ namespace std
   const size_t ctype<char>::table_size;
 
   ctype<char>::~ctype()
-  { if (_M_del) delete[] this->table(); }
+  { 
+    if (_M_c_locale_ctype)
+      _S_destroy_c_locale(_M_c_locale_ctype);
+    if (_M_del) 
+      delete[] this->table(); 
+  }
 
   // These are dummy placeholders as these virtual functions are never called.
   bool 
@@ -431,171 +451,26 @@ namespace std
     return __hi;
   }
 
-  template<>
-  ctype_byname<char>::ctype_byname(const char* /*__s*/, size_t __refs)
-  : ctype<char>(new mask[table_size], true, __refs)
-  { }
-
-#ifdef _GLIBCPP_USE_WCHAR_T  
-  ctype<wchar_t>::__wmask_type
-  ctype<wchar_t>::_M_convert_to_wmask(const mask __m) const
-  {
-    __wmask_type __ret;
-    switch (__m)
-      {
-      case space:
-       __ret = wctype("space");
-       break;
-      case print:
-       __ret = wctype("print");
-       break;
-      case cntrl:
-       __ret = wctype("cntrl");
-       break;
-      case upper:
-       __ret = wctype("upper");
-       break;
-      case lower:
-       __ret = wctype("lower");
-       break;
-      case alpha:
-       __ret = wctype("alpha");
-       break;
-      case digit:
-       __ret = wctype("digit");
-       break;
-      case punct:
-       __ret = wctype("punct");
-       break;
-      case xdigit:
-       __ret = wctype("xdigit");
-       break;
-      case alnum:
-       __ret = wctype("alnum");
-       break;
-      case graph:
-       __ret = wctype("graph");
-       break;
-      default:
-       __ret = 0;
-      }
-    return __ret;
-  };
-  
-  ctype<wchar_t>::~ctype() { }
-
-  // NB: These ctype<wchar_t> methods are not configuration-specific,
-  // unlike the ctype<char> bits.
+#ifdef _GLIBCPP_USE_WCHAR_T
   ctype<wchar_t>::ctype(size_t __refs) 
-  : __ctype_abstract_base<wchar_t>(__refs) { }
+  : __ctype_abstract_base<wchar_t>(__refs)
+  { _M_c_locale_ctype = _S_clone_c_locale(_S_c_locale); }
 
-  ctype<wchar_t>::ctype(__c_locale /*__cloc*/, size_t __refs) 
-  : __ctype_abstract_base<wchar_t>(__refs) { }
+  ctype<wchar_t>::ctype(__c_locale __cloc, size_t __refs) 
+  : __ctype_abstract_base<wchar_t>(__refs) 
+  { _M_c_locale_ctype = _S_clone_c_locale(__cloc); }
 
-  wchar_t
-  ctype<wchar_t>::do_toupper(wchar_t __c) const
-  { return towupper(__c); }
-
-  const wchar_t*
-  ctype<wchar_t>::do_toupper(wchar_t* __lo, const wchar_t* __hi) const
-  {
-    while (__lo < __hi)
-      {
-        *__lo = towupper(*__lo);
-        ++__lo;
-      }
-    return __hi;
-  }
-  
-  wchar_t
-  ctype<wchar_t>::do_tolower(wchar_t __c) const
-  { return towlower(__c); }
-  
-  const wchar_t*
-  ctype<wchar_t>::do_tolower(wchar_t* __lo, const wchar_t* __hi) const
-  {
-    while (__lo < __hi)
-      {
-        *__lo = towlower(*__lo);
-        ++__lo;
-      }
-    return __hi;
-  }
-
-  bool
-  ctype<wchar_t>::
-  do_is(mask __m, char_type __c) const
-  { return static_cast<bool>(iswctype(__c, _M_convert_to_wmask(__m))); }
-  
-  const wchar_t* 
-  ctype<wchar_t>::
-  do_is(const wchar_t* __lo, const wchar_t* __hi, mask* __m) const
-  {
-    while (__lo < __hi && !this->is(*__m, *__lo))
-      ++__lo;
-    return __lo;
-  }
-  
-  const wchar_t* 
-  ctype<wchar_t>::
-  do_scan_is(mask __m, const wchar_t* __lo, const wchar_t* __hi) const
-  {
-    while (__lo < __hi && !this->is(__m, *__lo))
-      ++__lo;
-    return __lo;
-  }
-
-  const wchar_t*
-  ctype<wchar_t>::
-  do_scan_not(mask __m, const char_type* __lo, const char_type* __hi) const
-  {
-    while (__lo < __hi && this->is(__m, *__lo) != 0)
-      ++__lo;
-    return __lo;
-  }
-
-  wchar_t
-  ctype<wchar_t>::
-  do_widen(char __c) const
-  { return btowc(__c); }
-  
-  const char* 
-  ctype<wchar_t>::
-  do_widen(const char* __lo, const char* __hi, wchar_t* __dest) const
-  {
-    mbstate_t __state;
-    memset(static_cast<void*>(&__state), 0, sizeof(mbstate_t));
-    mbsrtowcs(__dest, &__lo, __hi - __lo, &__state);
-    return __hi;
-  }
-
-  char
-  ctype<wchar_t>::
-  do_narrow(wchar_t __wc, char __dfault) const
-  { 
-    int __c = wctob(__wc);
-    return (__c == EOF ? __dfault : static_cast<char>(__c)); 
-  }
-
-  const wchar_t*
-  ctype<wchar_t>::
-  do_narrow(const wchar_t* __lo, const wchar_t* __hi, char __dfault, 
-           char* __dest) const
-  {
-    mbstate_t __state;
-    memset(static_cast<void*>(&__state), 0, sizeof(mbstate_t));
-    size_t __len = __hi - __lo;
-    size_t __conv = wcsrtombs(__dest, &__lo, __len, &__state);
-    if (__conv == __len)
-      *__dest = __dfault;
-    return __hi;
-  }
+  ctype<wchar_t>::~ctype() 
+  { _S_destroy_c_locale(_M_c_locale_ctype); }
 
   template<>
-  ctype_byname<wchar_t>::
-  ctype_byname(const char* /*__s*/, size_t __refs)
-  : ctype<wchar_t>(__refs) { }
-#endif //  _GLIBCPP_USE_WCHAR_T
+    ctype_byname<wchar_t>::ctype_byname(const char* __s, size_t __refs)
+    : ctype<wchar_t>(__refs) 
+    {  
+      _S_destroy_c_locale(_M_c_locale_ctype);
+      _S_create_c_locale(_M_c_locale_ctype, __s); 
+    }
+#endif
 
   // Definitions for static const data members of time_base
   template<> 
@@ -618,7 +493,7 @@ namespace std
 
   // Definitions for static const data members of money_base
   const money_base::pattern 
-  money_base::_S_default_pattern =  {{symbol, sign, none, value}};
+  money_base::_S_default_pattern =  { {symbol, sign, none, value} };
 
   template<>
     const ctype<char>&
@@ -708,12 +583,12 @@ namespace std
   }
   
   template<>
-    moneypunct_byname<char, false>::moneypunct_byname(const char* /*__s*/
+    moneypunct_byname<char, false>::moneypunct_byname(const char*, 
                                                      size_t __refs)
     : moneypunct<char, false>(__refs) { }
   
   template<>
-    moneypunct_byname<char, true>::moneypunct_byname(const char* /*__s*/
+    moneypunct_byname<char, true>::moneypunct_byname(const char*, 
                                                     size_t __refs)
     : moneypunct<char, true>(__refs) { }
 } // namespace std