monetary_members.cc revision 146897
1// std::moneypunct implementation details, GNU version -*- C++ -*- 2 3// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. 4// 5// This file is part of the GNU ISO C++ Library. This library is free 6// software; you can redistribute it and/or modify it under the 7// terms of the GNU General Public License as published by the 8// Free Software Foundation; either version 2, or (at your option) 9// any later version. 10 11// This library is distributed in the hope that it will be useful, 12// but WITHOUT ANY WARRANTY; without even the implied warranty of 13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14// GNU General Public License for more details. 15 16// You should have received a copy of the GNU General Public License along 17// with this library; see the file COPYING. If not, write to the Free 18// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 19// USA. 20 21// As a special exception, you may use this file as part of a free software 22// library without restriction. Specifically, if other files instantiate 23// templates or use macros or inline functions from this file, or you compile 24// this file and link it with other files to produce an executable, this 25// file does not by itself cause the resulting executable to be covered by 26// the GNU General Public License. This exception does not however 27// invalidate any other reasons why the executable file might be covered by 28// the GNU General Public License. 29 30// 31// ISO C++ 14882: 22.2.6.3.2 moneypunct virtual functions 32// 33 34// Written by Benjamin Kosnik <bkoz@redhat.com> 35 36#include <locale> 37#include <bits/c++locale_internal.h> 38 39namespace std 40{ 41 // Construct and return valid pattern consisting of some combination of: 42 // space none symbol sign value 43 money_base::pattern 44 money_base::_S_construct_pattern(char __precedes, char __space, char __posn) 45 { 46 pattern __ret; 47 48 // This insanely complicated routine attempts to construct a valid 49 // pattern for use with monyepunct. A couple of invariants: 50 51 // if (__precedes) symbol -> value 52 // else value -> symbol 53 54 // if (__space) space 55 // else none 56 57 // none == never first 58 // space never first or last 59 60 // Any elegant implementations of this are welcome. 61 switch (__posn) 62 { 63 case 0: 64 case 1: 65 // 1 The sign precedes the value and symbol. 66 __ret.field[0] = sign; 67 if (__space) 68 { 69 // Pattern starts with sign. 70 if (__precedes) 71 { 72 __ret.field[1] = symbol; 73 __ret.field[3] = value; 74 } 75 else 76 { 77 __ret.field[1] = value; 78 __ret.field[3] = symbol; 79 } 80 __ret.field[2] = space; 81 } 82 else 83 { 84 // Pattern starts with sign and ends with none. 85 if (__precedes) 86 { 87 __ret.field[1] = symbol; 88 __ret.field[2] = value; 89 } 90 else 91 { 92 __ret.field[1] = value; 93 __ret.field[2] = symbol; 94 } 95 __ret.field[3] = none; 96 } 97 break; 98 case 2: 99 // 2 The sign follows the value and symbol. 100 if (__space) 101 { 102 // Pattern either ends with sign. 103 if (__precedes) 104 { 105 __ret.field[0] = symbol; 106 __ret.field[2] = value; 107 } 108 else 109 { 110 __ret.field[0] = value; 111 __ret.field[2] = symbol; 112 } 113 __ret.field[1] = space; 114 __ret.field[3] = sign; 115 } 116 else 117 { 118 // Pattern ends with sign then none. 119 if (__precedes) 120 { 121 __ret.field[0] = symbol; 122 __ret.field[1] = value; 123 } 124 else 125 { 126 __ret.field[0] = value; 127 __ret.field[1] = symbol; 128 } 129 __ret.field[2] = sign; 130 __ret.field[3] = none; 131 } 132 break; 133 case 3: 134 // 3 The sign immediately precedes the symbol. 135 if (__precedes) 136 { 137 __ret.field[0] = sign; 138 __ret.field[1] = symbol; 139 if (__space) 140 { 141 __ret.field[2] = space; 142 __ret.field[3] = value; 143 } 144 else 145 { 146 __ret.field[2] = value; 147 __ret.field[3] = none; 148 } 149 } 150 else 151 { 152 __ret.field[0] = value; 153 if (__space) 154 { 155 __ret.field[1] = space; 156 __ret.field[2] = sign; 157 __ret.field[3] = symbol; 158 } 159 else 160 { 161 __ret.field[1] = sign; 162 __ret.field[2] = symbol; 163 __ret.field[3] = none; 164 } 165 } 166 break; 167 case 4: 168 // 4 The sign immediately follows the symbol. 169 if (__precedes) 170 { 171 __ret.field[0] = symbol; 172 __ret.field[1] = sign; 173 if (__space) 174 { 175 __ret.field[2] = space; 176 __ret.field[3] = value; 177 } 178 else 179 { 180 __ret.field[2] = value; 181 __ret.field[3] = none; 182 } 183 } 184 else 185 { 186 __ret.field[0] = value; 187 if (__space) 188 { 189 __ret.field[1] = space; 190 __ret.field[2] = symbol; 191 __ret.field[3] = sign; 192 } 193 else 194 { 195 __ret.field[1] = symbol; 196 __ret.field[2] = sign; 197 __ret.field[3] = none; 198 } 199 } 200 break; 201 default: 202 __ret = pattern(); 203 } 204 return __ret; 205 } 206 207 template<> 208 void 209 moneypunct<char, true>::_M_initialize_moneypunct(__c_locale __cloc, 210 const char*) 211 { 212 if (!_M_data) 213 _M_data = new __moneypunct_cache<char, true>; 214 215 if (!__cloc) 216 { 217 // "C" locale 218 _M_data->_M_decimal_point = '.'; 219 _M_data->_M_thousands_sep = ','; 220 _M_data->_M_grouping = ""; 221 _M_data->_M_grouping_size = 0; 222 _M_data->_M_curr_symbol = ""; 223 _M_data->_M_curr_symbol_size = 0; 224 _M_data->_M_positive_sign = ""; 225 _M_data->_M_positive_sign_size = 0; 226 _M_data->_M_negative_sign = ""; 227 _M_data->_M_negative_sign_size = 0; 228 _M_data->_M_frac_digits = 0; 229 _M_data->_M_pos_format = money_base::_S_default_pattern; 230 _M_data->_M_neg_format = money_base::_S_default_pattern; 231 232 for (size_t __i = 0; __i < money_base::_S_end; ++__i) 233 _M_data->_M_atoms[__i] = money_base::_S_atoms[__i]; 234 } 235 else 236 { 237 // Named locale. 238 _M_data->_M_decimal_point = *(__nl_langinfo_l(__MON_DECIMAL_POINT, 239 __cloc)); 240 _M_data->_M_thousands_sep = *(__nl_langinfo_l(__MON_THOUSANDS_SEP, 241 __cloc)); 242 _M_data->_M_grouping = __nl_langinfo_l(__MON_GROUPING, __cloc); 243 _M_data->_M_grouping_size = strlen(_M_data->_M_grouping); 244 _M_data->_M_positive_sign = __nl_langinfo_l(__POSITIVE_SIGN, __cloc); 245 _M_data->_M_positive_sign_size = strlen(_M_data->_M_positive_sign); 246 247 char __nposn = *(__nl_langinfo_l(__INT_N_SIGN_POSN, __cloc)); 248 if (!__nposn) 249 _M_data->_M_negative_sign = "()"; 250 else 251 _M_data->_M_negative_sign = __nl_langinfo_l(__NEGATIVE_SIGN, 252 __cloc); 253 _M_data->_M_negative_sign_size = strlen(_M_data->_M_negative_sign); 254 255 // _Intl == true 256 _M_data->_M_curr_symbol = __nl_langinfo_l(__INT_CURR_SYMBOL, __cloc); 257 _M_data->_M_curr_symbol_size = strlen(_M_data->_M_curr_symbol); 258 _M_data->_M_frac_digits = *(__nl_langinfo_l(__INT_FRAC_DIGITS, 259 __cloc)); 260 char __pprecedes = *(__nl_langinfo_l(__INT_P_CS_PRECEDES, __cloc)); 261 char __pspace = *(__nl_langinfo_l(__INT_P_SEP_BY_SPACE, __cloc)); 262 char __pposn = *(__nl_langinfo_l(__INT_P_SIGN_POSN, __cloc)); 263 _M_data->_M_pos_format = _S_construct_pattern(__pprecedes, __pspace, 264 __pposn); 265 char __nprecedes = *(__nl_langinfo_l(__INT_N_CS_PRECEDES, __cloc)); 266 char __nspace = *(__nl_langinfo_l(__INT_N_SEP_BY_SPACE, __cloc)); 267 _M_data->_M_neg_format = _S_construct_pattern(__nprecedes, __nspace, 268 __nposn); 269 } 270 } 271 272 template<> 273 void 274 moneypunct<char, false>::_M_initialize_moneypunct(__c_locale __cloc, 275 const char*) 276 { 277 if (!_M_data) 278 _M_data = new __moneypunct_cache<char, false>; 279 280 if (!__cloc) 281 { 282 // "C" locale 283 _M_data->_M_decimal_point = '.'; 284 _M_data->_M_thousands_sep = ','; 285 _M_data->_M_grouping = ""; 286 _M_data->_M_grouping_size = 0; 287 _M_data->_M_curr_symbol = ""; 288 _M_data->_M_curr_symbol_size = 0; 289 _M_data->_M_positive_sign = ""; 290 _M_data->_M_positive_sign_size = 0; 291 _M_data->_M_negative_sign = ""; 292 _M_data->_M_negative_sign_size = 0; 293 _M_data->_M_frac_digits = 0; 294 _M_data->_M_pos_format = money_base::_S_default_pattern; 295 _M_data->_M_neg_format = money_base::_S_default_pattern; 296 297 for (size_t __i = 0; __i < money_base::_S_end; ++__i) 298 _M_data->_M_atoms[__i] = money_base::_S_atoms[__i]; 299 } 300 else 301 { 302 // Named locale. 303 _M_data->_M_decimal_point = *(__nl_langinfo_l(__MON_DECIMAL_POINT, 304 __cloc)); 305 _M_data->_M_thousands_sep = *(__nl_langinfo_l(__MON_THOUSANDS_SEP, 306 __cloc)); 307 _M_data->_M_grouping = __nl_langinfo_l(__MON_GROUPING, __cloc); 308 _M_data->_M_grouping_size = strlen(_M_data->_M_grouping); 309 _M_data->_M_positive_sign = __nl_langinfo_l(__POSITIVE_SIGN, __cloc); 310 _M_data->_M_positive_sign_size = strlen(_M_data->_M_positive_sign); 311 312 char __nposn = *(__nl_langinfo_l(__N_SIGN_POSN, __cloc)); 313 if (!__nposn) 314 _M_data->_M_negative_sign = "()"; 315 else 316 _M_data->_M_negative_sign = __nl_langinfo_l(__NEGATIVE_SIGN, 317 __cloc); 318 _M_data->_M_negative_sign_size = strlen(_M_data->_M_negative_sign); 319 320 // _Intl == false 321 _M_data->_M_curr_symbol = __nl_langinfo_l(__CURRENCY_SYMBOL, __cloc); 322 _M_data->_M_curr_symbol_size = strlen(_M_data->_M_curr_symbol); 323 _M_data->_M_frac_digits = *(__nl_langinfo_l(__FRAC_DIGITS, __cloc)); 324 char __pprecedes = *(__nl_langinfo_l(__P_CS_PRECEDES, __cloc)); 325 char __pspace = *(__nl_langinfo_l(__P_SEP_BY_SPACE, __cloc)); 326 char __pposn = *(__nl_langinfo_l(__P_SIGN_POSN, __cloc)); 327 _M_data->_M_pos_format = _S_construct_pattern(__pprecedes, __pspace, 328 __pposn); 329 char __nprecedes = *(__nl_langinfo_l(__N_CS_PRECEDES, __cloc)); 330 char __nspace = *(__nl_langinfo_l(__N_SEP_BY_SPACE, __cloc)); 331 _M_data->_M_neg_format = _S_construct_pattern(__nprecedes, __nspace, 332 __nposn); 333 } 334 } 335 336 template<> 337 moneypunct<char, true>::~moneypunct() 338 { delete _M_data; } 339 340 template<> 341 moneypunct<char, false>::~moneypunct() 342 { delete _M_data; } 343 344#ifdef _GLIBCXX_USE_WCHAR_T 345 template<> 346 void 347 moneypunct<wchar_t, true>::_M_initialize_moneypunct(__c_locale __cloc, 348#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2) 349 const char*) 350#else 351 const char* __name) 352#endif 353 { 354 if (!_M_data) 355 _M_data = new __moneypunct_cache<wchar_t, true>; 356 357 if (!__cloc) 358 { 359 // "C" locale 360 _M_data->_M_decimal_point = L'.'; 361 _M_data->_M_thousands_sep = L','; 362 _M_data->_M_grouping = ""; 363 _M_data->_M_grouping_size = 0; 364 _M_data->_M_curr_symbol = L""; 365 _M_data->_M_curr_symbol_size = 0; 366 _M_data->_M_positive_sign = L""; 367 _M_data->_M_positive_sign_size = 0; 368 _M_data->_M_negative_sign = L""; 369 _M_data->_M_negative_sign_size = 0; 370 _M_data->_M_frac_digits = 0; 371 _M_data->_M_pos_format = money_base::_S_default_pattern; 372 _M_data->_M_neg_format = money_base::_S_default_pattern; 373 374 // Use ctype::widen code without the facet... 375 unsigned char uc; 376 for (size_t __i = 0; __i < money_base::_S_end; ++__i) 377 { 378 uc = static_cast<unsigned char>(money_base::_S_atoms[__i]); 379 _M_data->_M_atoms[__i] = btowc(uc); 380 } 381 } 382 else 383 { 384 // Named locale. 385#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2) 386 __c_locale __old = __uselocale(__cloc); 387#else 388 // Switch to named locale so that mbsrtowcs will work. 389 char* __old = strdup(setlocale(LC_ALL, NULL)); 390 setlocale(LC_ALL, __name); 391#endif 392 393 union __s_and_w { const char *__s; unsigned int __w; } __u; 394 __u.__s = __nl_langinfo_l(_NL_MONETARY_DECIMAL_POINT_WC, __cloc); 395 _M_data->_M_decimal_point = static_cast<wchar_t>(__u.__w); 396 397 __u.__s = __nl_langinfo_l(_NL_MONETARY_THOUSANDS_SEP_WC, __cloc); 398 _M_data->_M_thousands_sep = static_cast<wchar_t>(__u.__w); 399 _M_data->_M_grouping = __nl_langinfo_l(__MON_GROUPING, __cloc); 400 _M_data->_M_grouping_size = strlen(_M_data->_M_grouping); 401 402 const char* __cpossign = __nl_langinfo_l(__POSITIVE_SIGN, __cloc); 403 const char* __cnegsign = __nl_langinfo_l(__NEGATIVE_SIGN, __cloc); 404 const char* __ccurr = __nl_langinfo_l(__INT_CURR_SYMBOL, __cloc); 405 406 wchar_t* __wcs_ps = 0; 407 wchar_t* __wcs_ns = 0; 408 const char __nposn = *(__nl_langinfo_l(__INT_N_SIGN_POSN, __cloc)); 409 try 410 { 411 mbstate_t __state; 412 size_t __len = strlen(__cpossign); 413 if (__len) 414 { 415 ++__len; 416 memset(&__state, 0, sizeof(mbstate_t)); 417 __wcs_ps = new wchar_t[__len]; 418 mbsrtowcs(__wcs_ps, &__cpossign, __len, &__state); 419 _M_data->_M_positive_sign = __wcs_ps; 420 } 421 else 422 _M_data->_M_positive_sign = L""; 423 _M_data->_M_positive_sign_size = wcslen(_M_data->_M_positive_sign); 424 425 __len = strlen(__cnegsign); 426 if (!__nposn) 427 _M_data->_M_negative_sign = L"()"; 428 else if (__len) 429 { 430 ++__len; 431 memset(&__state, 0, sizeof(mbstate_t)); 432 __wcs_ns = new wchar_t[__len]; 433 mbsrtowcs(__wcs_ns, &__cnegsign, __len, &__state); 434 _M_data->_M_negative_sign = __wcs_ns; 435 } 436 else 437 _M_data->_M_negative_sign = L""; 438 _M_data->_M_negative_sign_size = wcslen(_M_data->_M_negative_sign); 439 440 // _Intl == true. 441 __len = strlen(__ccurr); 442 if (__len) 443 { 444 ++__len; 445 memset(&__state, 0, sizeof(mbstate_t)); 446 wchar_t* __wcs = new wchar_t[__len]; 447 mbsrtowcs(__wcs, &__ccurr, __len, &__state); 448 _M_data->_M_curr_symbol = __wcs; 449 } 450 else 451 _M_data->_M_curr_symbol = L""; 452 _M_data->_M_curr_symbol_size = wcslen(_M_data->_M_curr_symbol); 453 } 454 catch (...) 455 { 456 delete _M_data; 457 _M_data = 0; 458 delete __wcs_ps; 459 delete __wcs_ns; 460#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2) 461 __uselocale(__old); 462#else 463 setlocale(LC_ALL, __old); 464 free(__old); 465#endif 466 __throw_exception_again; 467 } 468 469 _M_data->_M_frac_digits = *(__nl_langinfo_l(__INT_FRAC_DIGITS, 470 __cloc)); 471 char __pprecedes = *(__nl_langinfo_l(__INT_P_CS_PRECEDES, __cloc)); 472 char __pspace = *(__nl_langinfo_l(__INT_P_SEP_BY_SPACE, __cloc)); 473 char __pposn = *(__nl_langinfo_l(__INT_P_SIGN_POSN, __cloc)); 474 _M_data->_M_pos_format = _S_construct_pattern(__pprecedes, __pspace, 475 __pposn); 476 char __nprecedes = *(__nl_langinfo_l(__INT_N_CS_PRECEDES, __cloc)); 477 char __nspace = *(__nl_langinfo_l(__INT_N_SEP_BY_SPACE, __cloc)); 478 _M_data->_M_neg_format = _S_construct_pattern(__nprecedes, __nspace, 479 __nposn); 480 481#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2) 482 __uselocale(__old); 483#else 484 setlocale(LC_ALL, __old); 485 free(__old); 486#endif 487 } 488 } 489 490 template<> 491 void 492 moneypunct<wchar_t, false>::_M_initialize_moneypunct(__c_locale __cloc, 493#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2) 494 const char*) 495#else 496 const char* __name) 497#endif 498 { 499 if (!_M_data) 500 _M_data = new __moneypunct_cache<wchar_t, false>; 501 502 if (!__cloc) 503 { 504 // "C" locale 505 _M_data->_M_decimal_point = L'.'; 506 _M_data->_M_thousands_sep = L','; 507 _M_data->_M_grouping = ""; 508 _M_data->_M_grouping_size = 0; 509 _M_data->_M_curr_symbol = L""; 510 _M_data->_M_curr_symbol_size = 0; 511 _M_data->_M_positive_sign = L""; 512 _M_data->_M_positive_sign_size = 0; 513 _M_data->_M_negative_sign = L""; 514 _M_data->_M_negative_sign_size = 0; 515 _M_data->_M_frac_digits = 0; 516 _M_data->_M_pos_format = money_base::_S_default_pattern; 517 _M_data->_M_neg_format = money_base::_S_default_pattern; 518 519 // Use ctype::widen code without the facet... 520 unsigned char uc; 521 for (size_t __i = 0; __i < money_base::_S_end; ++__i) 522 { 523 uc = static_cast<unsigned char>(money_base::_S_atoms[__i]); 524 _M_data->_M_atoms[__i] = btowc(uc); 525 } 526 } 527 else 528 { 529 // Named locale. 530#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2) 531 __c_locale __old = __uselocale(__cloc); 532#else 533 // Switch to named locale so that mbsrtowcs will work. 534 char* __old = strdup(setlocale(LC_ALL, NULL)); 535 setlocale(LC_ALL, __name); 536#endif 537 538 union __s_and_w { const char *__s; unsigned int __w; } __u; 539 __u.__s = __nl_langinfo_l(_NL_MONETARY_DECIMAL_POINT_WC, __cloc); 540 _M_data->_M_decimal_point = static_cast<wchar_t>(__u.__w); 541 542 __u.__s = __nl_langinfo_l(_NL_MONETARY_THOUSANDS_SEP_WC, __cloc); 543 _M_data->_M_thousands_sep = static_cast<wchar_t>(__u.__w); 544 _M_data->_M_grouping = __nl_langinfo_l(__MON_GROUPING, __cloc); 545 _M_data->_M_grouping_size = strlen(_M_data->_M_grouping); 546 547 const char* __cpossign = __nl_langinfo_l(__POSITIVE_SIGN, __cloc); 548 const char* __cnegsign = __nl_langinfo_l(__NEGATIVE_SIGN, __cloc); 549 const char* __ccurr = __nl_langinfo_l(__CURRENCY_SYMBOL, __cloc); 550 551 wchar_t* __wcs_ps = 0; 552 wchar_t* __wcs_ns = 0; 553 const char __nposn = *(__nl_langinfo_l(__N_SIGN_POSN, __cloc)); 554 try 555 { 556 mbstate_t __state; 557 size_t __len; 558 __len = strlen(__cpossign); 559 if (__len) 560 { 561 ++__len; 562 memset(&__state, 0, sizeof(mbstate_t)); 563 __wcs_ps = new wchar_t[__len]; 564 mbsrtowcs(__wcs_ps, &__cpossign, __len, &__state); 565 _M_data->_M_positive_sign = __wcs_ps; 566 } 567 else 568 _M_data->_M_positive_sign = L""; 569 _M_data->_M_positive_sign_size = wcslen(_M_data->_M_positive_sign); 570 571 __len = strlen(__cnegsign); 572 if (!__nposn) 573 _M_data->_M_negative_sign = L"()"; 574 else if (__len) 575 { 576 ++__len; 577 memset(&__state, 0, sizeof(mbstate_t)); 578 __wcs_ns = new wchar_t[__len]; 579 mbsrtowcs(__wcs_ns, &__cnegsign, __len, &__state); 580 _M_data->_M_negative_sign = __wcs_ns; 581 } 582 else 583 _M_data->_M_negative_sign = L""; 584 _M_data->_M_negative_sign_size = wcslen(_M_data->_M_negative_sign); 585 586 // _Intl == true. 587 __len = strlen(__ccurr); 588 if (__len) 589 { 590 ++__len; 591 memset(&__state, 0, sizeof(mbstate_t)); 592 wchar_t* __wcs = new wchar_t[__len]; 593 mbsrtowcs(__wcs, &__ccurr, __len, &__state); 594 _M_data->_M_curr_symbol = __wcs; 595 } 596 else 597 _M_data->_M_curr_symbol = L""; 598 _M_data->_M_curr_symbol_size = wcslen(_M_data->_M_curr_symbol); 599 } 600 catch (...) 601 { 602 delete _M_data; 603 _M_data = 0; 604 delete __wcs_ps; 605 delete __wcs_ns; 606#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2) 607 __uselocale(__old); 608#else 609 setlocale(LC_ALL, __old); 610 free(__old); 611#endif 612 __throw_exception_again; 613 } 614 615 _M_data->_M_frac_digits = *(__nl_langinfo_l(__FRAC_DIGITS, __cloc)); 616 char __pprecedes = *(__nl_langinfo_l(__P_CS_PRECEDES, __cloc)); 617 char __pspace = *(__nl_langinfo_l(__P_SEP_BY_SPACE, __cloc)); 618 char __pposn = *(__nl_langinfo_l(__P_SIGN_POSN, __cloc)); 619 _M_data->_M_pos_format = _S_construct_pattern(__pprecedes, __pspace, 620 __pposn); 621 char __nprecedes = *(__nl_langinfo_l(__N_CS_PRECEDES, __cloc)); 622 char __nspace = *(__nl_langinfo_l(__N_SEP_BY_SPACE, __cloc)); 623 _M_data->_M_neg_format = _S_construct_pattern(__nprecedes, __nspace, 624 __nposn); 625 626#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2) 627 __uselocale(__old); 628#else 629 setlocale(LC_ALL, __old); 630 free(__old); 631#endif 632 } 633 } 634 635 template<> 636 moneypunct<wchar_t, true>::~moneypunct() 637 { 638 if (_M_data->_M_positive_sign_size) 639 delete [] _M_data->_M_positive_sign; 640 if (_M_data->_M_negative_sign_size 641 && wcscmp(_M_data->_M_negative_sign, L"()") != 0) 642 delete [] _M_data->_M_negative_sign; 643 if (_M_data->_M_curr_symbol_size) 644 delete [] _M_data->_M_curr_symbol; 645 delete _M_data; 646 } 647 648 template<> 649 moneypunct<wchar_t, false>::~moneypunct() 650 { 651 if (_M_data->_M_positive_sign_size) 652 delete [] _M_data->_M_positive_sign; 653 if (_M_data->_M_negative_sign_size 654 && wcscmp(_M_data->_M_negative_sign, L"()") != 0) 655 delete [] _M_data->_M_negative_sign; 656 if (_M_data->_M_curr_symbol_size) 657 delete [] _M_data->_M_curr_symbol; 658 delete _M_data; 659 } 660#endif 661} 662