1 // Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
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)
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,
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.
29 #include <bits/std_clocale.h>
30 #include <bits/std_locale.h>
31 #include <bits/std_cstring.h>
32 #include <bits/std_vector.h>
33 #include <bits/std_stdexcept.h>
40 std::vector<facet*>::iterator it = _M_facets->begin();
41 for (; it != _M_facets->end(); ++it)
42 (*it)->_M_remove_reference();
44 delete _M_category_names;
48 _Impl(const _Impl& __imp, size_t __refs)
49 : _M_references(__refs - 1), _M_facets(0), _M_category_names(0),
50 _M_has_name(__imp._M_has_name), _M_name(__imp._M_name)
53 { _M_facets = new __vec_facet(*(__imp._M_facets)); }
61 { _M_category_names = new __vec_string(*(__imp._M_category_names)); }
64 delete _M_category_names;
68 std::vector<facet*>::iterator __it = _M_facets->begin();
69 for (; __it != _M_facets->end(); ++__it)
70 (*__it)->_M_add_reference();
73 // This constructor is used to correctly initialize named locales,
74 // including the standard "C" locale.
76 _Impl(size_t __num, size_t __refs, bool __has_name, string __str)
77 : _M_references(__refs - 1), _M_facets(0), _M_category_names(0),
78 _M_has_name(__has_name), _M_name(__str)
81 { _M_facets = new __vec_facet(__num, NULL); }
89 { _M_category_names = new __vec_string(_S_categories_num, _M_name); }
92 delete _M_category_names;
97 // Construct specific categories, leaving unselected ones alone
99 _Impl(const _Impl& __imp, const string& __str, category __cat, size_t __refs)
100 : _M_references(__refs - 1)
102 __cat = _S_normalize_category(__cat); // might throw
105 { _M_facets = new __vec_facet(*(__imp._M_facets)); }
113 { _M_category_names = new __vec_string(*(__imp._M_category_names)); }
116 delete _M_category_names;
120 static void(_Impl::* ctors[]) (const char*) =
122 // NB: Order must match the decl order in class locale.
123 &locale::_Impl::_M_construct_ctype,
124 &locale::_Impl::_M_construct_numeric,
125 &locale::_Impl::_M_construct_collate,
126 &locale::_Impl::_M_construct_time,
127 &locale::_Impl::_M_construct_monetary,
128 &locale::_Impl::_M_construct_messages,
132 __vec_facet::iterator __it = _M_facets->begin();
133 for (; __it != _M_facets->end(); ++__it)
134 (*__it)->_M_add_reference();
138 unsigned mask = (locale::all & -(unsigned)locale::all);
139 for (unsigned ix = 0; (-mask & __cat) != 0; ++ix, (mask <<= 1))
145 _M_replace_category(_S_classic, _S_facet_categories[ix]);
147 (this->*ctors[ix])(__str.c_str());
152 __it = _M_facets->begin();
153 for (; __it != _M_facets->end(); ++__it)
154 (*__it)->_M_remove_reference();
158 // XXX May need to be adjusted
161 _M_has_name = __str != "*";
166 _M_replace_categories(const _Impl* __imp, category __cat)
168 category __mask = locale::all & -static_cast<unsigned int>(locale::all);
169 for (unsigned int __ix = 0; (-__mask & __cat) != 0; ++__ix, (__mask <<= 1))
173 _M_replace_category(__imp, _S_facet_categories[__ix]);
174 (*_M_category_names)[__ix] = (*(__imp->_M_category_names))[__ix];
181 _M_replace_category(const _Impl* __imp, const locale::id* const* __idpp)
183 for (; *__idpp; ++__idpp)
184 _M_replace_facet(__imp, *__idpp);
189 _M_replace_facet(const _Impl* __imp, const locale::id* __idp)
191 size_t __index = __idp->_M_index;
193 || __imp->_M_facets->size() <= __index
194 || (*(__imp->_M_facets))[__index] == 0)
195 throw runtime_error("no locale facet");
197 _M_install_facet(__idp, (*(__imp->_M_facets))[__index]);
202 _M_install_facet(const locale::id* __idp, facet* __fp)
207 size_t& __index = __idp->_M_index;
209 __index = ++locale::id::_S_highwater; // XXX MT
211 if (__index >= _M_facets->size())
212 _M_facets->resize(__index + 1, 0); // might throw
213 facet*& __fpr = (*_M_facets)[__index];
214 // Order matters, here:
215 __fp->_M_add_reference();
217 __fpr->_M_remove_reference();
222 locale::_Impl::_M_construct_collate(const char* __s)
224 _M_facet_init(new collate_byname<char>(__s, 0));
225 #ifdef _GLIBCPP_USE_WCHAR_T
226 _M_facet_init(new collate_byname<wchar_t>(__s, 0));
231 locale::_Impl::_M_construct_ctype(const char* __s)
233 _M_facet_init(new ctype_byname<char>(__s, 0));
234 _M_facet_init(new codecvt_byname<char, char, mbstate_t>(__s));
235 #ifdef _GLIBCPP_USE_WCHAR_T
236 _M_facet_init(new ctype_byname<wchar_t>(__s, 0));
237 _M_facet_init(new codecvt_byname<wchar_t, char, mbstate_t>(__s));
242 locale::_Impl::_M_construct_monetary(const char* __s)
244 _M_replace_facet(locale::_S_classic, &money_get<char>::id);
245 _M_replace_facet(locale::_S_classic, &money_put<char>::id);
246 _M_facet_init(new moneypunct_byname<char, false>(__s, 0));
247 _M_facet_init(new moneypunct_byname<char, true >(__s, 0));
248 #ifdef _GLIBCPP_USE_WCHAR_T
249 _M_replace_facet(locale::_S_classic, &money_get<wchar_t>::id);
250 _M_replace_facet(locale::_S_classic, &money_put<wchar_t>::id);
251 _M_facet_init(new moneypunct_byname<wchar_t, false>(__s, 0));
252 _M_facet_init(new moneypunct_byname<wchar_t, true >(__s, 0));
257 locale::_Impl::_M_construct_numeric(const char* __s)
259 _M_replace_facet(locale::_S_classic, &num_get<char>::id);
260 _M_replace_facet(locale::_S_classic, &num_put<char>::id);
261 _M_facet_init(new numpunct_byname<char>(__s, 0));
262 #ifdef _GLIBCPP_USE_WCHAR_T
263 _M_replace_facet(locale::_S_classic, &num_get<wchar_t>::id);
264 _M_replace_facet(locale::_S_classic, &num_put<wchar_t>::id);
265 _M_facet_init(new numpunct_byname<wchar_t>(__s, 0));
270 locale::_Impl::_M_construct_time(const char* __s)
272 _M_facet_init(new time_get_byname<char>(__s, 0));
273 _M_facet_init(new time_put_byname<char>(__s, 0));
274 #ifdef _GLIBCPP_USE_WCHAR_T
275 _M_facet_init(new time_get_byname<wchar_t>(__s, 0));
276 _M_facet_init(new time_put_byname<wchar_t>(__s, 0));
281 locale::_Impl::_M_construct_messages(const char* __s)
283 _M_facet_init(new messages_byname<char>(__s, 0));
284 #ifdef _GLIBCPP_USE_WCHAR_T
285 _M_facet_init(new messages_byname<wchar_t>(__s, 0));