locale-inst.cc: Add time_put_byname and time_get_byname instantiations.
authorBenjamin Kosnik <bkoz@purist.soma.redhat.com>
Tue, 19 Sep 2000 06:47:52 +0000 (06:47 +0000)
committerBenjamin Kosnik <bkoz@gcc.gnu.org>
Tue, 19 Sep 2000 06:47:52 +0000 (06:47 +0000)
2000-09-18  Benjamin Kosnik  <bkoz@purist.soma.redhat.com>

* src/locale-inst.cc: Add time_put_byname and
time_get_byname instantiations.
* bits/locale_facets.h: Correct default, private derivation to
public derivation in _byname declarations.
* src/locale.cc (locale::classic()): Simplify.
* src/localename.cc (locale::_Impl:: _Impl(const _Impl& __other,
const string& __name, category __cat, size_t __refs): Re-work for
named locales.
(_M_normalize_category_names): Remove.

* testsuite/22_locale/global_templates.cc (test01): Tweaks.
* testsuite/22_locale/ctor_copy_dtor.cc (test01): More tests.

From-SVN: r36526

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

index 3c0e5015b135037593584d0625a784076e3065a9..6921b77769711058e14699054c35a26514036d95 100644 (file)
@@ -1,3 +1,18 @@
+2000-09-18  Benjamin Kosnik  <bkoz@purist.soma.redhat.com>
+
+       * src/locale-inst.cc: Add time_put_byname and
+       time_get_byname instantiations.
+       * bits/locale_facets.h: Correct default, private derivation to
+       public derivation in _byname declarations.
+       * src/locale.cc (locale::classic()): Simplify.
+       * src/localename.cc (locale::_Impl:: _Impl(const _Impl& __other,
+       const string& __name, category __cat, size_t __refs): Re-work for
+       named locales.
+       (_M_normalize_category_names): Remove.
+
+       * testsuite/22_locale/global_templates.cc (test01): Tweaks.
+       * testsuite/22_locale/ctor_copy_dtor.cc (test01): More tests.
+
 2000-09-18  Yuri V. Baskakov  <yuribsk@lab.sun.mcst.ru>
 
        * bits/std_bitset.h (operator>>): Change to char_type.
index 13def7d60538074a7d7c8c2b0094b9bc6f1dfb6a..732eafce4cad1682f968e245ee854102362fcd73 100644 (file)
@@ -682,6 +682,8 @@ namespace std
       typedef _InIter                          iter_type;
       typedef char_traits<_CharT>      __traits_type;
 
+      static locale::id id;
+
       explicit 
       num_get(size_t __refs = 0) : locale::facet(__refs) { }
 
@@ -756,8 +758,6 @@ namespace std
          ios_base::iostate& __err, void*& __v) const
       { return do_get(__in, __end, __io, __err, __v); }      
 
-      static locale::id id;
-
     protected:
       virtual ~num_get() { }
 
@@ -850,6 +850,8 @@ namespace std
       typedef _CharT       char_type;
       typedef _OutIter     iter_type;
 
+      static locale::id id;
+
       explicit 
       num_put(size_t __refs = 0) : locale::facet(__refs) { }
 
@@ -891,8 +893,6 @@ namespace std
          const void* __v) const
       { return do_put(__s, __f, __fill, __v); }
 
-      static locale::id id;
-
     protected:
       virtual 
       ~num_put() { };
@@ -1234,6 +1234,8 @@ namespace std
       typedef _CharT     char_type;
       typedef _InIter    iter_type;
 
+      static locale::id id;
+
       explicit 
       time_get(size_t __refs = 0) 
       : locale::facet (__refs), _M_daynames(0), _M_monthnames(0) { }
@@ -1267,8 +1269,6 @@ namespace std
               ios_base::iostate& __err, tm* __t) const
       { return do_get_year(__s,__end,__f,__err,__t); }
 
-      static locale::id id;
-
     protected:
       virtual 
       ~time_get() 
@@ -1330,6 +1330,8 @@ namespace std
       typedef _CharT     char_type;
       typedef _OutIter   iter_type;
 
+      static locale::id id;
+
       explicit 
       time_put(size_t __refs = 0) : locale::facet (__refs) { }
 
@@ -1345,8 +1347,6 @@ namespace std
          const tm* __tmb, char __format, char __modifier = 0) const
       { return do_put(__s, __f, __fill, __tmb, __format, __modifier); }
 
-      static locale::id id;
-
     protected:
       virtual 
       ~time_put() { }
@@ -1358,7 +1358,7 @@ namespace std
     };
 
   template<typename _CharT, typename _OutIter>
-    class time_put_byname : time_put<_CharT, _OutIter>
+    class time_put_byname : public time_put<_CharT, _OutIter>
     {
     public:
       typedef _CharT     char_type;
@@ -1367,6 +1367,7 @@ namespace std
       explicit 
       time_put_byname(const char*, size_t __refs = 0) 
       : time_put<_CharT, _OutIter> (__refs) { }
+
     protected:
       virtual 
       ~time_put_byname() { }
@@ -1381,6 +1382,8 @@ namespace std
       typedef _InIter       iter_type;
       typedef basic_string<_CharT> string_type;
 
+      static locale::id id;
+
       explicit 
       money_get(size_t __refs = 0) : locale::facet(__refs) { }
 
@@ -1394,8 +1397,6 @@ namespace std
           ios_base::iostate& __err, string_type& __digits) const
       { return do_get(__s, __end, __intl, __f, __err, __digits); }
 
-      static locale::id id;
-
     protected:
       virtual 
       ~money_get() { }
@@ -1421,6 +1422,8 @@ namespace std
       typedef _OutIter            iter_type;
       typedef basic_string<_CharT> string_type;
 
+      static locale::id id;
+
       explicit 
       money_put(size_t __refs = 0) : locale::facet(__refs) { }
 
@@ -1434,8 +1437,6 @@ namespace std
          char_type __fill, const string_type& __digits) const
       { return do_put(__s, __intl, __f, __fill, __digits); }
 
-      static locale::id id;
-
     protected:
       virtual 
       ~money_put() { }
@@ -1535,6 +1536,7 @@ namespace std
 
       explicit 
       moneypunct(size_t __refs = 0) : _Moneypunct<_CharT> (__refs) { }
+
     protected:
       virtual 
       ~moneypunct() { }
index a0b4a26d2680348572f1f1ee134a88e6887020d3..252f95dda740f371251117b4bf224654253f6e29 100644 (file)
@@ -443,7 +443,7 @@ namespace std
     facet(size_t __refs = 0) throw();
 
     virtual 
-    ~facet() {};
+    ~facet() { };
 
   private:
     size_t _M_references;
index 3b8b9819a21fac78416733cc2f0c6ea23d7621ea..0a2348f5825ae4e32183f07b5164bed57eec8a13 100644 (file)
@@ -95,15 +95,16 @@ namespace std {
 #endif
   
   // time_get and time_put
-  //template class time_get<char, obuf_iterator>;
   template class time_put<char, obuf_iterator>;
+  template class time_put_byname<char, obuf_iterator>;
   template class time_get<char, ibuf_iterator>;
-  template class time_put<char, ibuf_iterator>;
+  template class time_get_byname<char, ibuf_iterator>;
+
 #ifdef _GLIBCPP_USE_WCHAR_T
-  //template class time_get<wchar_t, wobuf_iterator>;
   template class time_put<wchar_t, wobuf_iterator>;
+  template class time_put_byname<wchar_t, wobuf_iterator>;
   template class time_get<wchar_t, wibuf_iterator>;
-  template class time_put<wchar_t, wibuf_iterator>;
+  template class time_get_byname<wchar_t, wibuf_iterator>;
 #endif
 
   // messages
index f3966ab2497eed513876078b976903c60b390fe2..de57040f9acc5f2262e4e029486e1053bdd0d541 100644 (file)
@@ -574,8 +574,7 @@ namespace std {
          (_M_impl = __other._M_impl)->_M_add_reference();
        // Might throw:
        else
-         _M_impl = new _Impl(*__other._M_impl, __name,
-                             _S_normalize_category(__cat), 1);
+         _M_impl = new _Impl(*__other._M_impl, __name, __cat, 1);
       }
     else
       throw runtime_error("attempt to create locale from NULL named locale");
@@ -651,29 +650,18 @@ namespace std {
          _S_classic = new _Impl(26, 2, true, "C");
          _S_global = _S_classic; 
 
-         // collate category
          _S_classic->_M_facet_init(new std::collate<char>);
-         
-         // ctype category
          _S_classic->_M_facet_init(new std::ctype<char>);
          _S_classic->_M_facet_init(new codecvt<char, char, mbstate_t>);
-
-         // monetary category
          _S_classic->_M_facet_init(new moneypunct<char, false>);
          _S_classic->_M_facet_init(new moneypunct<char,true >);
          _S_classic->_M_facet_init(new money_get<char>);
          _S_classic->_M_facet_init(new money_put<char>);
-         
-         // numeric category
          _S_classic->_M_facet_init(new numpunct<char>);
          _S_classic->_M_facet_init(new num_get<char>);
          _S_classic->_M_facet_init(new num_put<char>);
-         
-         // time category
          _S_classic->_M_facet_init(new time_get<char>);
          _S_classic->_M_facet_init(new time_put<char>);
-         
-         // messages category
          _S_classic->_M_facet_init(new std::messages<char>);
 
 #ifdef  _GLIBCPP_USE_WCHAR_T
index 51872d8a1549e79de297d2b7bab9594438fc2459..1b231c02bcda30bd0b720a074f031ac3590a3522 100644 (file)
@@ -89,31 +89,27 @@ namespace std {
   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(__name != "*"), _M_name(__name)
+    : _M_references(__refs - 1), _M_has_name(__other._M_name != "*")
   {
-#if 1
     typedef vector<facet*, allocator<facet*> > __vec_facet;
     typedef vector<string, allocator<string> > __vec_string;
+
+    __cat = _S_normalize_category(__cat);  // might throw
     try {
       _M_facets = new __vec_facet(*(__other._M_facets));
     }
-    catch (...) {
+    catch(...) {
       delete _M_facets;
       throw;
     }
     try {
        _M_category_names = new __vec_string(*(__other._M_category_names));
     }
-    catch (...) {
+    catch(...) {
       delete _M_category_names;
       throw;
     }
-#endif
-    // XXX Nathan what are you doing here? Is this supposed to be const?
-    // static void(_Impl::* const ctors[]) (const char*) = 
+
     static void(_Impl::* ctors[]) (const char*) = 
     {
       //  NB: Order must match the decl order in class locale.
@@ -126,33 +122,35 @@ namespace std {
       0
     };
     
-    _S_initialize();
-    std::vector<facet*>::iterator __it = _M_facets->begin();
+    __vec_facet::iterator __it = _M_facets->begin();
     for (; __it != _M_facets->end(); ++__it)
       (*__it)->_M_add_reference();
 
-    try {
-      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 & __cat) != 0; ++ix, (mask <<= 1))
-       {
-         if (!(mask & __cat))
-           continue;
-         
-         if (mask & __ccategory)
-           _M_replace_category(_S_classic, _S_facet_categories[ix]);
-         else
-           (this->*ctors[ix]) (__name.c_str());
-       }
-    }
-    catch (...) {
-      __it = _M_facets->begin();
-      for (; __it != _M_facets->end(); ++__it)
-       (*__it)->_M_remove_reference();
-      throw;
-    }
+    try 
+      {
+       unsigned mask = (locale::all & -(unsigned)locale::all);
+       for (unsigned ix = 0; (-mask & __cat) != 0; ++ix, (mask <<= 1))
+         {
+           if (!(mask & __cat))
+             continue;
+           
+           if (mask & __cat)
+             _M_replace_category(_S_classic, _S_facet_categories[ix]);
+           else
+             (this->*ctors[ix])(__name.c_str());
+         }
+      }
+    catch(...) 
+      {
+       __it = _M_facets->begin();
+       for (; __it != _M_facets->end(); ++__it)
+         (*__it)->_M_remove_reference();
+       throw;
+      }
+
+    // XXX May need to be adjusted
+    if (__cat == all)
+      _M_name = __name;
   }
   
   void
@@ -214,107 +212,62 @@ namespace std {
     __fpr = __fp;
   }
  
-  locale::category
-  locale::_Impl::_M_normalize_category_names(const string&, 
-                                            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.
-    
-    return __cat;
-#if 0 /* XXX not done */
-    unsigned mask = (locale::all & -(unsigned)locale::all);
-    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));
-#endif
+    _M_facet_init(new collate_byname<char>(__name, 0));
+    _M_facet_init(new collate_byname<wchar_t>(__name, 0));
   }
 
   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));
-#endif
+    _M_facet_init(new ctype_byname<char>(__name, 0));
+    _M_facet_init(new ctype_byname<wchar_t>(__name, 0));
+    _M_facet_init(new codecvt_byname<char, char, mbstate_t>(__name));
+    _M_facet_init(new codecvt_byname<wchar_t, char, mbstate_t>(__name));
   }
     
   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 moneypunct_byname<char, false>(__name, 0));
+    _M_facet_init(new moneypunct_byname<wchar_t, false>(__name, 0));
+    _M_facet_init(new moneypunct_byname<char, true >(__name, 0));
+    _M_facet_init(new moneypunct_byname<wchar_t, true >(__name, 0));
 
-    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);
-#endif
+    _M_replace_facet(locale::_S_classic, &money_get<char>::id);
+    _M_replace_facet(locale::_S_classic, &money_get<wchar_t>::id);
+    _M_replace_facet(locale::_S_classic, &money_put<char>::id);
+    _M_replace_facet(locale::_S_classic, &money_put<wchar_t>::id);
   }
     
   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 numpunct_byname<char>(__name, 0));
+    _M_facet_init(new numpunct_byname<wchar_t>(__name, 0));
 
-    locale::_M_initialize();
-    _M_replace_facet(locale::_S_classic, &std::num_get<char>::id);
-    _M_replace_facet(locale::_S_classic, &std::num_get<wchar_t>::id);
-    _M_replace_facet(locale::_S_classic, &std::num_put<char>::id);
-    _M_replace_facet(locale::_S_classic, &std::num_put<wchar_t>::id);
-#endif
+    _M_replace_facet(locale::_S_classic, &num_get<char>::id);
+    _M_replace_facet(locale::_S_classic, &num_get<wchar_t>::id);
+    _M_replace_facet(locale::_S_classic, &num_put<char>::id);
+    _M_replace_facet(locale::_S_classic, &num_put<wchar_t>::id);
   }
     
   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));
-#endif
+    _M_facet_init(new time_get_byname<char>(__name, 0));
+    _M_facet_init(new time_get_byname<wchar_t>(__name, 0));
+    _M_facet_init(new time_put_byname<char>(__name, 0));
+    _M_facet_init(new time_put_byname<wchar_t>(__name, 0));
   }
     
   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));
-#endif
+    _M_facet_init(new messages_byname<char>(__name, 0));
+    _M_facet_init(new messages_byname<wchar_t>(__name, 0));
   }
 }
 
index 5a9a42acd02e4b3384868b9efc352a6839ffbbfd..983a28f5aa3210b3f4be136375863f6fa57cb1fc 100644 (file)
 #include <stdexcept>
 #include <debug_assert.h>
 
-typedef std::codecvt<char, char, mbstate_t> ccodecvt;
-class gnu_codecvt: public ccodecvt { }; 
+typedef std::codecvt<char, char, mbstate_t>            c_codecvt;
+typedef std::codecvt_byname<char, char, mbstate_t>     c_codecvt_byname;
+typedef std::codecvt<wchar_t, char, mbstate_t>         w_codecvt;
+typedef std::codecvt_byname<wchar_t, char, mbstate_t>  w_codecvt_byname;
+
+class gnu_codecvt: public c_codecvt { }; 
 
 void test01()
 {
   using namespace std;
 
+  typedef unsigned short                       unicode_t;
+  typedef unicode_t                            int_type;
+  typedef char                                 ext_type;
+  typedef __enc_traits                         enc_type;
+  typedef codecvt<int_type, ext_type, enc_type>        unicode_codecvt;
+
   bool test = true;
   string str1, str2;
 
@@ -43,6 +53,55 @@ void test01()
   locale loc02(locale::classic(), new gnu_codecvt);
   VERIFY (loc01 != loc02);
   VERIFY (loc02.name() == "*");
+  try
+    {
+      VERIFY (has_facet<gnu_codecvt>(loc02));
+      VERIFY (has_facet<c_codecvt>(loc02));
+      VERIFY (has_facet<w_codecvt>(loc02));
+    }
+  catch(...)
+    { VERIFY( false ); }
+
+  try 
+    {  VERIFY (has_facet<c_codecvt_byname>(loc02)); }
+  catch(bad_cast& obj)
+    { VERIFY( true ); }
+  catch(...)
+    { VERIFY( false ); }
+
+  try 
+    {  VERIFY (has_facet<w_codecvt_byname>(loc02)); }
+  catch(bad_cast& obj)
+    { VERIFY( true ); }
+  catch(...)
+    { VERIFY( false ); }
+
+  // unicode_codecvt
+  locale loc13(locale::classic(), new unicode_codecvt);  
+  VERIFY (loc01 != loc13);
+  VERIFY (loc13.name() == "*");
+  try 
+    {
+      VERIFY (has_facet<c_codecvt>(loc13));
+      VERIFY (has_facet<w_codecvt>(loc13));
+      VERIFY (has_facet<unicode_codecvt>(loc13));
+    }
+  catch(...)
+    { VERIFY( false ); }
+
+  try 
+    {  VERIFY (has_facet<c_codecvt_byname>(loc13)); }
+  catch(bad_cast& obj)
+    { VERIFY( true ); }
+  catch(...)
+    { VERIFY( false ); }
+
+  try 
+    {  VERIFY (has_facet<w_codecvt_byname>(loc13)); }
+  catch(bad_cast& obj)
+    { VERIFY( true ); }
+  catch(...)
+    { VERIFY( false ); }
 
   // 2
   // locale() throw()
@@ -74,7 +133,8 @@ void test01()
   // 4
   // locale(const locale& other, const char* std_name, category)
   locale loc09(loc06, "C", locale::ctype);
-  VERIFY (loc09.name() == "fr_FR");
+  VERIFY (loc09.name() != "fr_FR");
+  VERIFY (loc09.name() != "C");
   VERIFY (loc09 != loc01);  
   VERIFY (loc09 != loc06);  
   // XXX somehow check that the ctype, codecvt facets have "C" locale bits...
@@ -98,7 +158,6 @@ void test01()
     { VERIFY (false); }
   
 
-
 }
 
 int main ()
index c207ccde3dd4565359058f4973523aea9ea45954..74661048222b686193428e723c1c5b877231a077 100644 (file)
@@ -57,7 +57,7 @@ void test01()
     { const ccodecvt& cvt03 = use_facet<gnu_codecvt>(cloc); }
   catch(bad_cast& obj)
     { VERIFY( true ); }
-    catch(...)
+  catch(...)
     { VERIFY( false ); }
 }