00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include <clocale>
00030 #include <cstring>
00031 #include <cstdlib>
00032 #include <cctype>
00033 #include <cwctype>
00034 #include <locale>
00035 #include <bits/atomicity.h>
00036 #include <bits/concurrence.h>
00037
00038 namespace __gnu_internal
00039 {
00040
00041 extern std::locale c_locale;
00042 extern std::locale::_Impl c_locale_impl;
00043
00044 extern std::locale::facet* facet_vec[_GLIBCXX_NUM_FACETS];
00045 extern char* name_vec[6 + _GLIBCXX_NUM_CATEGORIES];
00046 extern char name_c[6 + _GLIBCXX_NUM_CATEGORIES][2];
00047
00048 extern std::ctype<char> ctype_c;
00049 extern std::collate<char> collate_c;
00050 extern std::numpunct<char> numpunct_c;
00051 extern std::num_get<char> num_get_c;
00052 extern std::num_put<char> num_put_c;
00053 extern std::codecvt<char, char, mbstate_t> codecvt_c;
00054 extern std::moneypunct<char, false> moneypunct_cf;
00055 extern std::moneypunct<char, true> moneypunct_ct;
00056 extern std::money_get<char> money_get_c;
00057 extern std::money_put<char> money_put_c;
00058 extern std::__timepunct<char> timepunct_c;
00059 extern std::time_get<char> time_get_c;
00060 extern std::time_put<char> time_put_c;
00061 extern std::messages<char> messages_c;
00062 #ifdef _GLIBCXX_USE_WCHAR_T
00063 extern std::ctype<wchar_t> ctype_w;
00064 extern std::collate<wchar_t> collate_w;
00065 extern std::numpunct<wchar_t> numpunct_w;
00066 extern std::num_get<wchar_t> num_get_w;
00067 extern std::num_put<wchar_t> num_put_w;
00068 extern std::codecvt<wchar_t, char, mbstate_t> codecvt_w;
00069 extern std::moneypunct<wchar_t, false> moneypunct_wf;
00070 extern std::moneypunct<wchar_t, true> moneypunct_wt;
00071 extern std::money_get<wchar_t> money_get_w;
00072 extern std::money_put<wchar_t> money_put_w;
00073 extern std::__timepunct<wchar_t> timepunct_w;
00074 extern std::time_get<wchar_t> time_get_w;
00075 extern std::time_put<wchar_t> time_put_w;
00076 extern std::messages<wchar_t> messages_w;
00077 #endif
00078
00079
00080 extern std::locale::facet* cache_vec[_GLIBCXX_NUM_FACETS];
00081 extern std::__numpunct_cache<char> numpunct_cache_c;
00082 extern std::__moneypunct_cache<char, false> moneypunct_cache_cf;
00083 extern std::__moneypunct_cache<char, true> moneypunct_cache_ct;
00084 extern std::__timepunct_cache<char> timepunct_cache_c;
00085 #ifdef _GLIBCXX_USE_WCHAR_T
00086 extern std::__numpunct_cache<wchar_t> numpunct_cache_w;
00087 extern std::__moneypunct_cache<wchar_t, false> moneypunct_cache_wf;
00088 extern std::__moneypunct_cache<wchar_t, true> moneypunct_cache_wt;
00089 extern std::__timepunct_cache<wchar_t> timepunct_cache_w;
00090 #endif
00091
00092
00093 __glibcxx_mutex_define_initialized(locale_mutex);
00094 }
00095
00096 namespace std
00097 {
00098 using namespace __gnu_internal;
00099
00100 locale::locale() throw() : _M_impl(0)
00101 {
00102 _S_initialize();
00103 __gnu_cxx::lock sentry(__gnu_internal::locale_mutex);
00104 _S_global->_M_add_reference();
00105 _M_impl = _S_global;
00106 }
00107
00108 locale
00109 locale::global(const locale& __other)
00110 {
00111 _S_initialize();
00112 _Impl* __old;
00113 {
00114 __gnu_cxx::lock sentry(__gnu_internal::locale_mutex);
00115 __old = _S_global;
00116 __other._M_impl->_M_add_reference();
00117 _S_global = __other._M_impl;
00118 if (__other.name() != "*")
00119 setlocale(LC_ALL, __other.name().c_str());
00120 }
00121
00122
00123
00124
00125
00126
00127 return locale(__old);
00128 }
00129
00130 const locale&
00131 locale::classic()
00132 {
00133 _S_initialize();
00134 return c_locale;
00135 }
00136
00137 void
00138 locale::_S_initialize_once()
00139 {
00140
00141
00142 _S_classic = new (&c_locale_impl) _Impl(2);
00143 _S_global = _S_classic;
00144 new (&c_locale) locale(_S_classic);
00145 }
00146
00147 void
00148 locale::_S_initialize()
00149 {
00150 #ifdef __GTHREADS
00151 if (__gthread_active_p())
00152 __gthread_once(&_S_once, _S_initialize_once);
00153 #endif
00154 if (!_S_classic)
00155 _S_initialize_once();
00156 }
00157
00158
00159 const locale::id* const
00160 locale::_Impl::_S_id_ctype[] =
00161 {
00162 &std::ctype<char>::id,
00163 &codecvt<char, char, mbstate_t>::id,
00164 #ifdef _GLIBCXX_USE_WCHAR_T
00165 &std::ctype<wchar_t>::id,
00166 &codecvt<wchar_t, char, mbstate_t>::id,
00167 #endif
00168 0
00169 };
00170
00171 const locale::id* const
00172 locale::_Impl::_S_id_numeric[] =
00173 {
00174 &num_get<char>::id,
00175 &num_put<char>::id,
00176 &numpunct<char>::id,
00177 #ifdef _GLIBCXX_USE_WCHAR_T
00178 &num_get<wchar_t>::id,
00179 &num_put<wchar_t>::id,
00180 &numpunct<wchar_t>::id,
00181 #endif
00182 0
00183 };
00184
00185 const locale::id* const
00186 locale::_Impl::_S_id_collate[] =
00187 {
00188 &std::collate<char>::id,
00189 #ifdef _GLIBCXX_USE_WCHAR_T
00190 &std::collate<wchar_t>::id,
00191 #endif
00192 0
00193 };
00194
00195 const locale::id* const
00196 locale::_Impl::_S_id_time[] =
00197 {
00198 &__timepunct<char>::id,
00199 &time_get<char>::id,
00200 &time_put<char>::id,
00201 #ifdef _GLIBCXX_USE_WCHAR_T
00202 &__timepunct<wchar_t>::id,
00203 &time_get<wchar_t>::id,
00204 &time_put<wchar_t>::id,
00205 #endif
00206 0
00207 };
00208
00209 const locale::id* const
00210 locale::_Impl::_S_id_monetary[] =
00211 {
00212 &money_get<char>::id,
00213 &money_put<char>::id,
00214 &moneypunct<char, false>::id,
00215 &moneypunct<char, true >::id,
00216 #ifdef _GLIBCXX_USE_WCHAR_T
00217 &money_get<wchar_t>::id,
00218 &money_put<wchar_t>::id,
00219 &moneypunct<wchar_t, false>::id,
00220 &moneypunct<wchar_t, true >::id,
00221 #endif
00222 0
00223 };
00224
00225 const locale::id* const
00226 locale::_Impl::_S_id_messages[] =
00227 {
00228 &std::messages<char>::id,
00229 #ifdef _GLIBCXX_USE_WCHAR_T
00230 &std::messages<wchar_t>::id,
00231 #endif
00232 0
00233 };
00234
00235 const locale::id* const* const
00236 locale::_Impl::_S_facet_categories[] =
00237 {
00238
00239 locale::_Impl::_S_id_ctype,
00240 locale::_Impl::_S_id_numeric,
00241 locale::_Impl::_S_id_collate,
00242 locale::_Impl::_S_id_time,
00243 locale::_Impl::_S_id_monetary,
00244 locale::_Impl::_S_id_messages,
00245 0
00246 };
00247
00248
00249 locale::_Impl::
00250 _Impl(size_t __refs) throw()
00251 : _M_refcount(__refs), _M_facets(0), _M_facets_size(_GLIBCXX_NUM_FACETS),
00252 _M_caches(0), _M_names(0)
00253 {
00254 _M_facets = new (&facet_vec) const facet*[_M_facets_size];
00255 _M_caches = new (&cache_vec) const facet*[_M_facets_size];
00256 for (size_t __i = 0; __i < _M_facets_size; ++__i)
00257 _M_facets[__i] = _M_caches[__i] = 0;
00258
00259
00260 _M_names = new (&name_vec) char*[_S_categories_size];
00261 for (size_t __j = 0; __j < _S_categories_size; ++__j)
00262 {
00263 _M_names[__j] = new (&name_c[__j]) char[2];
00264 std::strcpy(_M_names[__j], locale::facet::_S_get_c_name());
00265 }
00266
00267
00268
00269
00270
00271
00272
00273
00274 _M_init_facet(new (&ctype_c) std::ctype<char>(0, false, 1));
00275 _M_init_facet(new (&codecvt_c) codecvt<char, char, mbstate_t>(1));
00276
00277 typedef __numpunct_cache<char> num_cache_c;
00278 num_cache_c* __npc = new (&numpunct_cache_c) num_cache_c(2);
00279 _M_init_facet(new (&numpunct_c) numpunct<char>(__npc, 1));
00280
00281 _M_init_facet(new (&num_get_c) num_get<char>(1));
00282 _M_init_facet(new (&num_put_c) num_put<char>(1));
00283 _M_init_facet(new (&collate_c) std::collate<char>(1));
00284
00285 typedef __moneypunct_cache<char, false> money_cache_cf;
00286 typedef __moneypunct_cache<char, true> money_cache_ct;
00287 money_cache_cf* __mpcf = new (&moneypunct_cache_cf) money_cache_cf(2);
00288 _M_init_facet(new (&moneypunct_cf) moneypunct<char, false>(__mpcf, 1));
00289 money_cache_ct* __mpct = new (&moneypunct_cache_ct) money_cache_ct(2);
00290 _M_init_facet(new (&moneypunct_ct) moneypunct<char, true>(__mpct, 1));
00291
00292 _M_init_facet(new (&money_get_c) money_get<char>(1));
00293 _M_init_facet(new (&money_put_c) money_put<char>(1));
00294
00295 typedef __timepunct_cache<char> time_cache_c;
00296 time_cache_c* __tpc = new (&timepunct_cache_c) time_cache_c(2);
00297 _M_init_facet(new (&timepunct_c) __timepunct<char>(__tpc, 1));
00298
00299 _M_init_facet(new (&time_get_c) time_get<char>(1));
00300 _M_init_facet(new (&time_put_c) time_put<char>(1));
00301 _M_init_facet(new (&messages_c) std::messages<char>(1));
00302
00303 #ifdef _GLIBCXX_USE_WCHAR_T
00304 _M_init_facet(new (&ctype_w) std::ctype<wchar_t>(1));
00305 _M_init_facet(new (&codecvt_w) codecvt<wchar_t, char, mbstate_t>(1));
00306
00307 typedef __numpunct_cache<wchar_t> num_cache_w;
00308 num_cache_w* __npw = new (&numpunct_cache_w) num_cache_w(2);
00309 _M_init_facet(new (&numpunct_w) numpunct<wchar_t>(__npw, 1));
00310
00311 _M_init_facet(new (&num_get_w) num_get<wchar_t>(1));
00312 _M_init_facet(new (&num_put_w) num_put<wchar_t>(1));
00313 _M_init_facet(new (&collate_w) std::collate<wchar_t>(1));
00314
00315 typedef __moneypunct_cache<wchar_t, false> money_cache_wf;
00316 typedef __moneypunct_cache<wchar_t, true> money_cache_wt;
00317 money_cache_wf* __mpwf = new (&moneypunct_cache_wf) money_cache_wf(2);
00318 _M_init_facet(new (&moneypunct_wf) moneypunct<wchar_t, false>(__mpwf, 1));
00319 money_cache_wt* __mpwt = new (&moneypunct_cache_wt) money_cache_wt(2);
00320 _M_init_facet(new (&moneypunct_wt) moneypunct<wchar_t, true>(__mpwt, 1));
00321
00322 _M_init_facet(new (&money_get_w) money_get<wchar_t>(1));
00323 _M_init_facet(new (&money_put_w) money_put<wchar_t>(1));
00324
00325 typedef __timepunct_cache<wchar_t> time_cache_w;
00326 time_cache_w* __tpw = new (&timepunct_cache_w) time_cache_w(2);
00327 _M_init_facet(new (&timepunct_w) __timepunct<wchar_t>(__tpw, 1));
00328
00329 _M_init_facet(new (&time_get_w) time_get<wchar_t>(1));
00330 _M_init_facet(new (&time_put_w) time_put<wchar_t>(1));
00331 _M_init_facet(new (&messages_w) std::messages<wchar_t>(1));
00332 #endif
00333
00334
00335
00336 _M_caches[numpunct<char>::id._M_id()] = __npc;
00337 _M_caches[moneypunct<char, false>::id._M_id()] = __mpcf;
00338 _M_caches[moneypunct<char, true>::id._M_id()] = __mpct;
00339 _M_caches[__timepunct<char>::id._M_id()] = __tpc;
00340 #ifdef _GLIBCXX_USE_WCHAR_T
00341 _M_caches[numpunct<wchar_t>::id._M_id()] = __npw;
00342 _M_caches[moneypunct<wchar_t, false>::id._M_id()] = __mpwf;
00343 _M_caches[moneypunct<wchar_t, true>::id._M_id()] = __mpwt;
00344 _M_caches[__timepunct<wchar_t>::id._M_id()] = __tpw;
00345 #endif
00346 }
00347 }