2002-01-04 Benjamin Kosnik <bkoz@redhat.com>
[official-gcc.git] / libstdc++-v3 / src / localename.cc
blob45c4732d007fe1dbfff8fbefacab771961698b17
1 // Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
2 //
3 // This file is part of the GNU ISO C++ Library. This library is free
4 // software; you can redistribute it and/or modify it under the
5 // terms of the GNU General Public License as published by the
6 // Free Software Foundation; either version 2, or (at your option)
7 // any later version.
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // You should have received a copy of the GNU General Public License along
15 // with this library; see the file COPYING. If not, write to the Free
16 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
17 // USA.
19 // As a special exception, you may use this file as part of a free software
20 // library without restriction. Specifically, if other files instantiate
21 // templates or use macros or inline functions from this file, or you compile
22 // this file and link it with other files to produce an executable, this
23 // file does not by itself cause the resulting executable to be covered by
24 // the GNU General Public License. This exception does not however
25 // invalidate any other reasons why the executable file might be covered by
26 // the GNU General Public License.
28 #include <clocale>
29 #include <cstring>
30 #include <locale>
31 #include <vector>
32 #include <stdexcept>
34 namespace std
36 locale::_Impl::
37 ~_Impl() throw()
39 __vec_facet::iterator it = _M_facets->begin();
40 for (; it != _M_facets->end(); ++it)
41 if (*it)
42 (*it)->_M_remove_reference();
43 delete _M_facets;
46 // Clone existing _Impl object.
47 locale::_Impl::
48 _Impl(const _Impl& __imp, size_t __refs)
49 : _M_references(__refs), _M_facets(0) // XXX
51 try
52 { _M_facets = new __vec_facet(*(__imp._M_facets)); }
53 catch(...)
55 delete _M_facets;
56 __throw_exception_again;
59 for (size_t i = 0; i < _S_num_categories; ++i)
60 _M_names[i] = __imp._M_names[i];
62 __vec_facet::iterator __it = _M_facets->begin();
63 for (; __it != _M_facets->end(); ++__it)
64 if (*__it)
65 (*__it)->_M_add_reference();
68 // Construct named _Impl, including the standard "C" locale.
69 locale::_Impl::
70 _Impl(string __str, size_t __refs)
71 : _M_references(__refs), _M_facets(0)
73 // Initialize the underlying locale model, which also checks to
74 // see if the given name is valid.
75 __c_locale __cloc;
76 locale::facet::_S_create_c_locale(__cloc, __str.c_str());
78 // This is needed as presently "C" locales != required data in
79 // __timepunct, numpunct, and moneypunct.
80 __c_locale __cloc_c = NULL;
81 if (__str != "C" && __str != "POSIX")
82 __cloc_c = __cloc;
84 // Allocate facet container.
85 try
86 { _M_facets = new __vec_facet(_S_num_facets, NULL); }
87 catch(...)
89 delete _M_facets;
90 __throw_exception_again;
93 // Name all the categories.
94 for (size_t i = 0; i < _S_num_categories; ++i)
95 _M_names[i] = __str;
97 // Construct all standard facets and add them to _M_facets.
98 _M_init_facet(new std::collate<char>(__cloc));
99 _M_init_facet(new std::ctype<char>(__cloc));
100 _M_init_facet(new codecvt<char, char, mbstate_t>);
101 _M_init_facet(new moneypunct<char, false>(__cloc_c));
102 _M_init_facet(new moneypunct<char, true>(__cloc_c));
103 _M_init_facet(new money_get<char>);
104 _M_init_facet(new money_put<char>);
105 _M_init_facet(new numpunct<char>(__cloc_c));
106 _M_init_facet(new num_get<char>);
107 _M_init_facet(new num_put<char>);
108 _M_init_facet(new __timepunct<char>(__cloc_c, __str.c_str()));
109 _M_init_facet(new time_get<char>);
110 _M_init_facet(new time_put<char>);
111 _M_init_facet(new std::messages<char>(__cloc, __str.c_str()));
113 #ifdef _GLIBCPP_USE_WCHAR_T
114 _M_init_facet(new std::collate<wchar_t>(__cloc));
115 _M_init_facet(new std::ctype<wchar_t>(__cloc));
116 _M_init_facet(new codecvt<wchar_t, char, mbstate_t>);
117 _M_init_facet(new moneypunct<wchar_t, false>(__cloc_c));
118 _M_init_facet(new moneypunct<wchar_t, true>(__cloc_c));
119 _M_init_facet(new money_get<wchar_t>);
120 _M_init_facet(new money_put<wchar_t>);
121 _M_init_facet(new numpunct<wchar_t>(__cloc_c));
122 _M_init_facet(new num_get<wchar_t>);
123 _M_init_facet(new num_put<wchar_t>);
124 _M_init_facet(new __timepunct<wchar_t>(__cloc_c, __str.c_str()));
125 _M_init_facet(new time_get<wchar_t>);
126 _M_init_facet(new time_put<wchar_t>);
127 _M_init_facet(new std::messages<wchar_t>(__cloc, __str.c_str()));
128 #endif
129 locale::facet::_S_destroy_c_locale(__cloc);
132 void
133 locale::_Impl::
134 _M_replace_categories(const _Impl* __imp, category __cat)
136 const string __none("*");
137 category __mask;
138 for (unsigned int __ix = 0; __ix < _S_num_categories; ++__ix)
140 __mask = 1 << __ix;
141 if (__mask & __cat)
143 // Need to replace entry in _M_facets with other locale's info.
144 _M_replace_category(__imp, _S_facet_categories[__ix]);
145 // If both have names, go ahead and mangle.
146 if (_M_names[__ix] != __none && __imp->_M_names[__ix] != __none)
147 _M_names[__ix] = __imp->_M_names[__ix];
152 void
153 locale::_Impl::
154 _M_replace_category(const _Impl* __imp, const locale::id* const* __idpp)
156 for (; *__idpp; ++__idpp)
157 _M_replace_facet(__imp, *__idpp);
160 void
161 locale::_Impl::
162 _M_replace_facet(const _Impl* __imp, const locale::id* __idp)
164 size_t __index = __idp->_M_index;
165 if (__index == 0
166 || __imp->_M_facets->size() <= __index
167 || (*(__imp->_M_facets))[__index] == 0)
168 __throw_runtime_error("no locale facet");
170 _M_install_facet(__idp, (*(__imp->_M_facets))[__index]);
173 void
174 locale::_Impl::
175 _M_install_facet(const locale::id* __idp, facet* __fp)
177 if (__fp)
179 size_t& __index = __idp->_M_index;
180 if (!__index)
181 __index = ++locale::id::_S_highwater; // XXX MT
183 if (__index >= _M_facets->size())
184 _M_facets->resize(__index + 1, 0); // might throw
186 facet*& __fpr = (*_M_facets)[__index];
187 if (__fpr)
189 // Replacing an existing facet.
190 // Order matters, here:
191 __fp->_M_add_reference();
192 __fpr->_M_remove_reference();
193 __fpr = __fp;
195 else
197 // Installing a newly created facet into an empty
198 // _M_facets container, say a newly-constructed,
199 // swanky-fresh _Impl.
200 (*_M_facets)[__index] = __fp;
204 } // namespace std