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