]> gcc.gnu.org Git - gcc.git/blob - libstdc++-v3/src/localename.cc
7d6f259acce0dfeae9cd86f7b76afa03fb2493ff
[gcc.git] / libstdc++-v3 / src / localename.cc
1 // Copyright (C) 1997, 1998, 1999, 2000 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.
8
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.
13
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.
18
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.
27
28
29 #include <bits/std_clocale.h>
30 #include <bits/std_locale.h>
31 #include <bits/std_cstring.h>
32 #include <bits/std_cassert.h>
33 #include <bits/std_vector.h>
34 #include <bits/std_stdexcept.h>
35
36 namespace std {
37
38 locale::_Impl::
39 ~_Impl() throw()
40 {
41 std::vector<facet*>::iterator it = _M_facets->begin();
42 for (; it != _M_facets->end(); ++it)
43 (*it)->_M_remove_reference();
44 delete _M_facets;
45 delete _M_category_names;
46 }
47
48 locale::_Impl::
49 _Impl(const _Impl& __other, size_t __refs)
50 : _M_references(__refs - 1), _M_facets(0), _M_category_names(0),
51 _M_has_name(__other._M_has_name), _M_name(__other._M_name)
52 {
53 try
54 { _M_facets = new __vec_facet(*(__other._M_facets)); }
55 catch(...)
56 {
57 delete _M_facets;
58 throw;
59 }
60
61 try
62 { _M_category_names = new __vec_string(*(__other._M_category_names)); }
63 catch(...)
64 {
65 delete _M_category_names;
66 throw;
67 }
68
69 std::vector<facet*>::iterator __it = _M_facets->begin();
70 for (; __it != _M_facets->end(); ++__it)
71 (*__it)->_M_add_reference();
72 }
73
74 // This constructor is used to correctly initialize named locales,
75 // including the standard "C" locale.
76 locale::_Impl::
77 _Impl(size_t __numfacets, size_t __refs, bool __has_name = false,
78 string __name = "*")
79 : _M_references(__refs - 1), _M_facets(0), _M_category_names(0),
80 _M_has_name(__has_name), _M_name(__name)
81 {
82 try
83 { _M_facets = new __vec_facet(__numfacets, NULL); }
84 catch(...)
85 {
86 delete _M_facets;
87 throw;
88 }
89
90 try
91 { _M_category_names = new __vec_string(_S_categories_num, _M_name); }
92 catch(...)
93 {
94 delete _M_category_names;
95 throw;
96 }
97 }
98
99 // Construct specific categories, leaving unselected ones alone
100 locale::_Impl::
101 _Impl(const _Impl& __other, const string& __name, category __cat,
102 size_t __refs)
103 : _M_references(__refs - 1), _M_has_name(__other._M_name != "*")
104 {
105 __cat = _S_normalize_category(__cat); // might throw
106
107 try
108 { _M_facets = new __vec_facet(*(__other._M_facets)); }
109 catch(...)
110 {
111 delete _M_facets;
112 throw;
113 }
114
115 try
116 { _M_category_names = new __vec_string(*(__other._M_category_names)); }
117 catch(...)
118 {
119 delete _M_category_names;
120 throw;
121 }
122
123 static void(_Impl::* ctors[]) (const char*) =
124 {
125 // NB: Order must match the decl order in class locale.
126 &locale::_Impl::_M_construct_collate,
127 &locale::_Impl::_M_construct_ctype,
128 &locale::_Impl::_M_construct_monetary,
129 &locale::_Impl::_M_construct_numeric,
130 &locale::_Impl::_M_construct_time,
131 &locale::_Impl::_M_construct_messages,
132 0
133 };
134
135 __vec_facet::iterator __it = _M_facets->begin();
136 for (; __it != _M_facets->end(); ++__it)
137 (*__it)->_M_add_reference();
138
139 try
140 {
141 unsigned mask = (locale::all & -(unsigned)locale::all);
142 for (unsigned ix = 0; (-mask & __cat) != 0; ++ix, (mask <<= 1))
143 {
144 if (!(mask & __cat))
145 continue;
146
147 if (mask & __cat)
148 _M_replace_category(_S_classic, _S_facet_categories[ix]);
149 else
150 (this->*ctors[ix])(__name.c_str());
151 }
152 }
153 catch(...)
154 {
155 __it = _M_facets->begin();
156 for (; __it != _M_facets->end(); ++__it)
157 (*__it)->_M_remove_reference();
158 throw;
159 }
160
161 // XXX May need to be adjusted
162 if (__cat == all)
163 _M_name = __name;
164 }
165
166 void
167 locale::_Impl::
168 _M_replace_categories(const _Impl* __other, category __cat)
169 {
170 assert((__cat & locale::all) && !(__cat & ~locale::all));
171
172 unsigned int __mask = locale::all & -static_cast<unsigned int>(locale::all);
173 for (unsigned int __ix = 0; (-__mask & __cat) != 0; ++__ix, (__mask <<= 1))
174 {
175 if (__mask & __cat)
176 {
177 _M_replace_category(__other, _S_facet_categories[__ix]);
178 (*_M_category_names)[__ix] = (*(__other->_M_category_names))[__ix];
179 }
180 }
181 }
182
183 void
184 locale::_Impl::
185 _M_replace_category(const _Impl* __other, const locale::id* const* __idpp)
186 {
187 for (; *__idpp; ++__idpp)
188 _M_replace_facet(__other, *__idpp);
189 }
190
191 void
192 locale::_Impl::
193 _M_replace_facet(const _Impl* __other, const locale::id* __idp)
194 {
195 size_t __index = __idp->_M_index;
196 if (__index == 0
197 || __other->_M_facets->size() <= __index
198 || (*(__other->_M_facets))[__index] == 0)
199 throw runtime_error("no locale facet");
200
201 _M_install_facet(__idp, (*(__other->_M_facets))[__index]);
202 }
203
204 void
205 locale::_Impl::
206 _M_install_facet(const locale::id* __idp, facet* __fp)
207 {
208 if (__fp == 0)
209 return;
210
211 size_t& __index = __idp->_M_index;
212 if (!__index)
213 __index = ++locale::id::_S_highwater; // XXX MT
214
215 if (__index >= _M_facets->size())
216 _M_facets->resize(__index + 1, 0); // might throw
217 facet*& __fpr = (*_M_facets)[__index];
218 // Order matters, here:
219 __fp->_M_add_reference();
220 if (__fpr)
221 __fpr->_M_remove_reference();
222 __fpr = __fp;
223 }
224
225 void
226 locale::_Impl::_M_construct_collate(const char* __name)
227 {
228 _M_facet_init(new collate_byname<char>(__name, 0));
229 _M_facet_init(new collate_byname<wchar_t>(__name, 0));
230 }
231
232 void
233 locale::_Impl::_M_construct_ctype(const char* __name)
234 {
235 _M_facet_init(new ctype_byname<char>(__name, 0));
236 _M_facet_init(new ctype_byname<wchar_t>(__name, 0));
237 _M_facet_init(new codecvt_byname<char, char, mbstate_t>(__name));
238 _M_facet_init(new codecvt_byname<wchar_t, char, mbstate_t>(__name));
239 }
240
241 void
242 locale::_Impl::_M_construct_monetary(const char* __name)
243 {
244 _M_facet_init(new moneypunct_byname<char, false>(__name, 0));
245 _M_facet_init(new moneypunct_byname<wchar_t, false>(__name, 0));
246 _M_facet_init(new moneypunct_byname<char, true >(__name, 0));
247 _M_facet_init(new moneypunct_byname<wchar_t, true >(__name, 0));
248
249 _M_replace_facet(locale::_S_classic, &money_get<char>::id);
250 _M_replace_facet(locale::_S_classic, &money_get<wchar_t>::id);
251 _M_replace_facet(locale::_S_classic, &money_put<char>::id);
252 _M_replace_facet(locale::_S_classic, &money_put<wchar_t>::id);
253 }
254
255 void
256 locale::_Impl::_M_construct_numeric(const char* __name)
257 {
258 _M_facet_init(new numpunct_byname<char>(__name, 0));
259 _M_facet_init(new numpunct_byname<wchar_t>(__name, 0));
260
261 _M_replace_facet(locale::_S_classic, &num_get<char>::id);
262 _M_replace_facet(locale::_S_classic, &num_get<wchar_t>::id);
263 _M_replace_facet(locale::_S_classic, &num_put<char>::id);
264 _M_replace_facet(locale::_S_classic, &num_put<wchar_t>::id);
265 }
266
267 void
268 locale::_Impl::_M_construct_time(const char* __name)
269 {
270 _M_facet_init(new time_get_byname<char>(__name, 0));
271 _M_facet_init(new time_get_byname<wchar_t>(__name, 0));
272 _M_facet_init(new time_put_byname<char>(__name, 0));
273 _M_facet_init(new time_put_byname<wchar_t>(__name, 0));
274 }
275
276 void
277 locale::_Impl::_M_construct_messages(const char* __name)
278 {
279 _M_facet_init(new messages_byname<char>(__name, 0));
280 _M_facet_init(new messages_byname<wchar_t>(__name, 0));
281 }
282 }
283
284
285
This page took 0.062687 seconds and 5 git commands to generate.