]> git.ipfire.org Git - thirdparty/gcc.git/blame - libstdc++-v3/src/localename.cc
builtins.c (expand_builtin_memcmp): Mark parameter with ATTRIBUTE_UNUSED.
[thirdparty/gcc.git] / libstdc++-v3 / src / localename.cc
CommitLineData
d358ecd0 1// Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
b2dad0e3
BK
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
b2dad0e3
BK
28#include <bits/std_clocale.h>
29#include <bits/std_locale.h>
30#include <bits/std_cstring.h>
b2dad0e3 31#include <bits/std_vector.h>
e4cc8659 32#include <bits/std_stdexcept.h>
b2dad0e3 33
d53d7f6e
PE
34namespace std
35{
e4cc8659
BK
36 locale::_Impl::
37 ~_Impl() throw()
38 {
0214010c 39 __vec_facet::iterator it = _M_facets->begin();
e4cc8659 40 for (; it != _M_facets->end(); ++it)
0214010c
BK
41 if (*it)
42 (*it)->_M_remove_reference();
e4cc8659 43 delete _M_facets;
e4cc8659 44 }
b2dad0e3 45
0214010c 46 // Clone existing _Impl object.
e4cc8659 47 locale::_Impl::
d358ecd0 48 _Impl(const _Impl& __imp, size_t __refs)
33590f13 49 : _M_references(__refs), _M_facets(0) // XXX
e4cc8659 50 {
22b9554c 51 try
d358ecd0 52 { _M_facets = new __vec_facet(*(__imp._M_facets)); }
22b9554c
BK
53 catch(...)
54 {
55 delete _M_facets;
e2c09482 56 __throw_exception_again;
22b9554c 57 }
e4cc8659 58
0214010c
BK
59 for (size_t i = 0; i < _S_num_categories; ++i)
60 _M_names[i] = __imp._M_names[i];
e4cc8659 61
0214010c 62 __vec_facet::iterator __it = _M_facets->begin();
22b9554c 63 for (; __it != _M_facets->end(); ++__it)
0214010c
BK
64 if (*__it)
65 (*__it)->_M_add_reference();
e4cc8659
BK
66 }
67
0214010c 68 // Construct named _Impl, including the standard "C" locale.
22b9554c 69 locale::_Impl::
0214010c 70 _Impl(string __str, size_t __refs)
13f83598 71 : _M_references(__refs), _M_facets(0)
7dc08a20 72 {
0214010c
BK
73 // Initialize the underlying locale model, which also checks to
74 // see if the given name is valid.
33590f13 75 __c_locale __cloc = NULL;
0214010c 76 if (__str != "C" && __str != "POSIX")
33590f13 77 locale::facet::_S_create_c_locale(__cloc, __str.c_str());
0214010c
BK
78
79 // Allocate facet container.
22b9554c 80 try
0214010c 81 { _M_facets = new __vec_facet(_S_num_facets, NULL); }
22b9554c
BK
82 catch(...)
83 {
84 delete _M_facets;
e2c09482 85 __throw_exception_again;
22b9554c
BK
86 }
87
0214010c
BK
88 // Name all the categories.
89 for (size_t i = 0; i < _S_num_categories; ++i)
90 _M_names[i] = __str;
91
92 // Construct all standard facets and add them to _M_facets.
e08138aa 93 // XXX How to deal cleanly, consistently with null ("C") __cloc?
ea0c0b6e 94 _M_init_facet(new std::collate<char>(__cloc));
9e5c7dba 95 _M_init_facet(new std::ctype<char>(__cloc));
0214010c 96 _M_init_facet(new codecvt<char, char, mbstate_t>);
33590f13 97 _M_init_facet(new moneypunct<char, false>(__cloc));
69971cd8 98 _M_init_facet(new moneypunct<char, true>(__cloc));
0214010c
BK
99 _M_init_facet(new money_get<char>);
100 _M_init_facet(new money_put<char>);
33590f13 101 _M_init_facet(new numpunct<char>(__cloc));
0214010c
BK
102 _M_init_facet(new num_get<char>);
103 _M_init_facet(new num_put<char>);
e08138aa 104 _M_init_facet(new __timepunct<char>(__cloc, __str.c_str()));
0214010c
BK
105 _M_init_facet(new time_get<char>);
106 _M_init_facet(new time_put<char>);
33590f13 107 _M_init_facet(new std::messages<char>(__cloc, __str.c_str()));
b2dad0e3 108
0214010c 109#ifdef _GLIBCPP_USE_WCHAR_T
ea0c0b6e 110 _M_init_facet(new std::collate<wchar_t>(__cloc));
9e5c7dba 111 _M_init_facet(new std::ctype<wchar_t>(__cloc));
0214010c 112 _M_init_facet(new codecvt<wchar_t, char, mbstate_t>);
33590f13 113 _M_init_facet(new moneypunct<wchar_t, false>(__cloc));
69971cd8 114 _M_init_facet(new moneypunct<wchar_t, true>(__cloc));
0214010c
BK
115 _M_init_facet(new money_get<wchar_t>);
116 _M_init_facet(new money_put<wchar_t>);
33590f13 117 _M_init_facet(new numpunct<wchar_t>(__cloc));
0214010c
BK
118 _M_init_facet(new num_get<wchar_t>);
119 _M_init_facet(new num_put<wchar_t>);
e08138aa 120 _M_init_facet(new __timepunct<wchar_t>(__cloc, __str.c_str()));
0214010c
BK
121 _M_init_facet(new time_get<wchar_t>);
122 _M_init_facet(new time_put<wchar_t>);
33590f13 123 _M_init_facet(new std::messages<wchar_t>(__cloc, __str.c_str()));
0214010c 124#endif
33590f13 125 locale::facet::_S_destroy_c_locale(__cloc);
b2dad0e3 126 }
e4cc8659
BK
127
128 void
129 locale::_Impl::
d358ecd0 130 _M_replace_categories(const _Impl* __imp, category __cat)
e4cc8659 131 {
0214010c
BK
132 const string __none("*");
133 category __mask;
134 for (unsigned int __ix = 0; __ix < _S_num_categories; ++__ix)
e4cc8659 135 {
0214010c 136 __mask = 1 << __ix;
e4cc8659
BK
137 if (__mask & __cat)
138 {
0214010c 139 // Need to replace entry in _M_facets with other locale's info.
d358ecd0 140 _M_replace_category(__imp, _S_facet_categories[__ix]);
0214010c
BK
141 // If both have names, go ahead and mangle.
142 if (_M_names[__ix] != __none && __imp->_M_names[__ix] != __none)
143 _M_names[__ix] = __imp->_M_names[__ix];
e4cc8659
BK
144 }
145 }
146 }
147
148 void
149 locale::_Impl::
d358ecd0 150 _M_replace_category(const _Impl* __imp, const locale::id* const* __idpp)
e4cc8659
BK
151 {
152 for (; *__idpp; ++__idpp)
d358ecd0 153 _M_replace_facet(__imp, *__idpp);
e4cc8659
BK
154 }
155
156 void
157 locale::_Impl::
d358ecd0 158 _M_replace_facet(const _Impl* __imp, const locale::id* __idp)
e4cc8659
BK
159 {
160 size_t __index = __idp->_M_index;
161 if (__index == 0
d358ecd0
BK
162 || __imp->_M_facets->size() <= __index
163 || (*(__imp->_M_facets))[__index] == 0)
e2c09482 164 __throw_runtime_error("no locale facet");
e4cc8659 165
d358ecd0 166 _M_install_facet(__idp, (*(__imp->_M_facets))[__index]);
e4cc8659
BK
167 }
168
169 void
170 locale::_Impl::
171 _M_install_facet(const locale::id* __idp, facet* __fp)
172 {
0214010c
BK
173 if (__fp)
174 {
175 size_t& __index = __idp->_M_index;
176 if (!__index)
177 __index = ++locale::id::_S_highwater; // XXX MT
178
179 if (__index >= _M_facets->size())
180 _M_facets->resize(__index + 1, 0); // might throw
b2dad0e3 181
0214010c
BK
182 facet*& __fpr = (*_M_facets)[__index];
183 if (__fpr)
184 {
185 // Replacing an existing facet.
186 // Order matters, here:
187 __fp->_M_add_reference();
13f83598 188 __fpr->_M_remove_reference();
0214010c
BK
189 __fpr = __fp;
190 }
191 else
192 {
193 // Installing a newly created facet into an empty
194 // _M_facets container, say a newly-constructed,
195 // swanky-fresh _Impl.
196 (*_M_facets)[__index] = __fp;
197 }
198 }
b2dad0e3 199 }
d53d7f6e 200} // namespace std