]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - contrib/libstdc++/config/locale/gnu/monetary_members.cc
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / contrib / libstdc++ / config / locale / gnu / monetary_members.cc
1 // std::moneypunct implementation details, GNU version -*- C++ -*-
2
3 // Copyright (C) 2001, 2002, 2003, 2004, 2005 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
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
39 _GLIBCXX_BEGIN_NAMESPACE(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           for (size_t __i = 0; __i < money_base::_S_end; ++__i)
376             _M_data->_M_atoms[__i] =
377               static_cast<wchar_t>(money_base::_S_atoms[__i]);
378         }
379       else
380         {
381           // Named locale.
382 #if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
383           __c_locale __old = __uselocale(__cloc);
384 #else
385           // Switch to named locale so that mbsrtowcs will work.
386           char* __old = strdup(setlocale(LC_ALL, NULL));
387           setlocale(LC_ALL, __name);
388 #endif
389
390           union { char *__s; wchar_t __w; } __u;
391           __u.__s = __nl_langinfo_l(_NL_MONETARY_DECIMAL_POINT_WC, __cloc);
392           _M_data->_M_decimal_point = __u.__w;
393
394           __u.__s = __nl_langinfo_l(_NL_MONETARY_THOUSANDS_SEP_WC, __cloc);
395           _M_data->_M_thousands_sep = __u.__w;
396           _M_data->_M_grouping = __nl_langinfo_l(__MON_GROUPING, __cloc);
397           _M_data->_M_grouping_size = strlen(_M_data->_M_grouping);
398
399           const char* __cpossign = __nl_langinfo_l(__POSITIVE_SIGN, __cloc);
400           const char* __cnegsign = __nl_langinfo_l(__NEGATIVE_SIGN, __cloc);
401           const char* __ccurr = __nl_langinfo_l(__INT_CURR_SYMBOL, __cloc);
402
403           wchar_t* __wcs_ps = 0;
404           wchar_t* __wcs_ns = 0;
405           const char __nposn = *(__nl_langinfo_l(__INT_N_SIGN_POSN, __cloc));
406           try
407             {
408               mbstate_t __state;
409               size_t __len = strlen(__cpossign);
410               if (__len)
411                 {
412                   ++__len;
413                   memset(&__state, 0, sizeof(mbstate_t));
414                   __wcs_ps = new wchar_t[__len];
415                   mbsrtowcs(__wcs_ps, &__cpossign, __len, &__state);
416                   _M_data->_M_positive_sign = __wcs_ps;
417                 }
418               else
419                 _M_data->_M_positive_sign = L"";
420               _M_data->_M_positive_sign_size = wcslen(_M_data->_M_positive_sign);
421               
422               __len = strlen(__cnegsign);
423               if (!__nposn)
424                 _M_data->_M_negative_sign = L"()";
425               else if (__len)
426                 { 
427                   ++__len;
428                   memset(&__state, 0, sizeof(mbstate_t));
429                   __wcs_ns = new wchar_t[__len];
430                   mbsrtowcs(__wcs_ns, &__cnegsign, __len, &__state);
431                   _M_data->_M_negative_sign = __wcs_ns;
432                 }
433               else
434                 _M_data->_M_negative_sign = L"";
435               _M_data->_M_negative_sign_size = wcslen(_M_data->_M_negative_sign);
436               
437               // _Intl == true.
438               __len = strlen(__ccurr);
439               if (__len)
440                 {
441                   ++__len;
442                   memset(&__state, 0, sizeof(mbstate_t));
443                   wchar_t* __wcs = new wchar_t[__len];
444                   mbsrtowcs(__wcs, &__ccurr, __len, &__state);
445                   _M_data->_M_curr_symbol = __wcs;
446                 }
447               else
448                 _M_data->_M_curr_symbol = L"";
449               _M_data->_M_curr_symbol_size = wcslen(_M_data->_M_curr_symbol);
450             }
451           catch (...)
452             {
453               delete _M_data;
454               _M_data = 0;
455               delete __wcs_ps;
456               delete __wcs_ns;        
457 #if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
458               __uselocale(__old);
459 #else
460               setlocale(LC_ALL, __old);
461               free(__old);
462 #endif
463               __throw_exception_again;
464             } 
465           
466           _M_data->_M_frac_digits = *(__nl_langinfo_l(__INT_FRAC_DIGITS, 
467                                                       __cloc));
468           char __pprecedes = *(__nl_langinfo_l(__INT_P_CS_PRECEDES, __cloc));
469           char __pspace = *(__nl_langinfo_l(__INT_P_SEP_BY_SPACE, __cloc));
470           char __pposn = *(__nl_langinfo_l(__INT_P_SIGN_POSN, __cloc));
471           _M_data->_M_pos_format = _S_construct_pattern(__pprecedes, __pspace, 
472                                                         __pposn);
473           char __nprecedes = *(__nl_langinfo_l(__INT_N_CS_PRECEDES, __cloc));
474           char __nspace = *(__nl_langinfo_l(__INT_N_SEP_BY_SPACE, __cloc));
475           _M_data->_M_neg_format = _S_construct_pattern(__nprecedes, __nspace, 
476                                                         __nposn);
477
478 #if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
479           __uselocale(__old);
480 #else
481           setlocale(LC_ALL, __old);
482           free(__old);
483 #endif
484         }
485     }
486
487   template<> 
488   void
489   moneypunct<wchar_t, false>::_M_initialize_moneypunct(__c_locale __cloc,
490 #if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
491                                                        const char*)
492 #else
493                                                        const char* __name)
494 #endif
495   {
496     if (!_M_data)
497       _M_data = new __moneypunct_cache<wchar_t, false>;
498
499     if (!__cloc)
500         {
501           // "C" locale
502           _M_data->_M_decimal_point = L'.';
503           _M_data->_M_thousands_sep = L',';
504           _M_data->_M_grouping = "";
505           _M_data->_M_grouping_size = 0;
506           _M_data->_M_curr_symbol = L"";
507           _M_data->_M_curr_symbol_size = 0;
508           _M_data->_M_positive_sign = L"";
509           _M_data->_M_positive_sign_size = 0;
510           _M_data->_M_negative_sign = L"";
511           _M_data->_M_negative_sign_size = 0;
512           _M_data->_M_frac_digits = 0;
513           _M_data->_M_pos_format = money_base::_S_default_pattern;
514           _M_data->_M_neg_format = money_base::_S_default_pattern;
515
516           // Use ctype::widen code without the facet...
517           for (size_t __i = 0; __i < money_base::_S_end; ++__i)
518             _M_data->_M_atoms[__i] =
519               static_cast<wchar_t>(money_base::_S_atoms[__i]);
520         }
521       else
522         {
523           // Named locale.
524 #if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
525           __c_locale __old = __uselocale(__cloc);
526 #else
527           // Switch to named locale so that mbsrtowcs will work.
528           char* __old = strdup(setlocale(LC_ALL, NULL));
529           setlocale(LC_ALL, __name);
530 #endif
531
532           union { char *__s; wchar_t __w; } __u;
533           __u.__s = __nl_langinfo_l(_NL_MONETARY_DECIMAL_POINT_WC, __cloc);
534           _M_data->_M_decimal_point = __u.__w;
535
536           __u.__s = __nl_langinfo_l(_NL_MONETARY_THOUSANDS_SEP_WC, __cloc);
537           _M_data->_M_thousands_sep = __u.__w;
538           _M_data->_M_grouping = __nl_langinfo_l(__MON_GROUPING, __cloc);
539           _M_data->_M_grouping_size = strlen(_M_data->_M_grouping);
540
541           const char* __cpossign = __nl_langinfo_l(__POSITIVE_SIGN, __cloc);
542           const char* __cnegsign = __nl_langinfo_l(__NEGATIVE_SIGN, __cloc);
543           const char* __ccurr = __nl_langinfo_l(__CURRENCY_SYMBOL, __cloc);
544
545           wchar_t* __wcs_ps = 0;
546           wchar_t* __wcs_ns = 0;
547           const char __nposn = *(__nl_langinfo_l(__N_SIGN_POSN, __cloc));
548           try
549             {
550               mbstate_t __state;
551               size_t __len;
552               __len = strlen(__cpossign);
553               if (__len)
554                 {
555                   ++__len;
556                   memset(&__state, 0, sizeof(mbstate_t));
557                   __wcs_ps = new wchar_t[__len];
558                   mbsrtowcs(__wcs_ps, &__cpossign, __len, &__state);
559                   _M_data->_M_positive_sign = __wcs_ps;
560                 }
561               else
562                 _M_data->_M_positive_sign = L"";
563               _M_data->_M_positive_sign_size = wcslen(_M_data->_M_positive_sign);
564               
565               __len = strlen(__cnegsign);
566               if (!__nposn)
567                 _M_data->_M_negative_sign = L"()";
568               else if (__len)
569                 { 
570                   ++__len;
571                   memset(&__state, 0, sizeof(mbstate_t));
572                   __wcs_ns = new wchar_t[__len];
573                   mbsrtowcs(__wcs_ns, &__cnegsign, __len, &__state);
574                   _M_data->_M_negative_sign = __wcs_ns;
575                 }
576               else
577                 _M_data->_M_negative_sign = L"";
578               _M_data->_M_negative_sign_size = wcslen(_M_data->_M_negative_sign);
579
580               // _Intl == true.
581               __len = strlen(__ccurr);
582               if (__len)
583                 {
584                   ++__len;
585                   memset(&__state, 0, sizeof(mbstate_t));
586                   wchar_t* __wcs = new wchar_t[__len];
587                   mbsrtowcs(__wcs, &__ccurr, __len, &__state);
588                   _M_data->_M_curr_symbol = __wcs;
589                 }
590               else
591                 _M_data->_M_curr_symbol = L"";
592               _M_data->_M_curr_symbol_size = wcslen(_M_data->_M_curr_symbol);
593             }
594           catch (...)
595             {
596               delete _M_data;
597               _M_data = 0;
598               delete __wcs_ps;
599               delete __wcs_ns;        
600 #if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
601               __uselocale(__old);
602 #else
603               setlocale(LC_ALL, __old);
604               free(__old);
605 #endif
606               __throw_exception_again;
607             }
608
609           _M_data->_M_frac_digits = *(__nl_langinfo_l(__FRAC_DIGITS, __cloc));
610           char __pprecedes = *(__nl_langinfo_l(__P_CS_PRECEDES, __cloc));
611           char __pspace = *(__nl_langinfo_l(__P_SEP_BY_SPACE, __cloc));
612           char __pposn = *(__nl_langinfo_l(__P_SIGN_POSN, __cloc));
613           _M_data->_M_pos_format = _S_construct_pattern(__pprecedes, __pspace, 
614                                                         __pposn);
615           char __nprecedes = *(__nl_langinfo_l(__N_CS_PRECEDES, __cloc));
616           char __nspace = *(__nl_langinfo_l(__N_SEP_BY_SPACE, __cloc));
617           _M_data->_M_neg_format = _S_construct_pattern(__nprecedes, __nspace, 
618                                                         __nposn);
619
620 #if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
621           __uselocale(__old);
622 #else
623           setlocale(LC_ALL, __old);
624           free(__old);
625 #endif
626         }
627     }
628
629   template<> 
630     moneypunct<wchar_t, true>::~moneypunct()
631     {
632       if (_M_data->_M_positive_sign_size)
633         delete [] _M_data->_M_positive_sign;
634       if (_M_data->_M_negative_sign_size
635           && wcscmp(_M_data->_M_negative_sign, L"()") != 0)
636         delete [] _M_data->_M_negative_sign;
637       if (_M_data->_M_curr_symbol_size)
638         delete [] _M_data->_M_curr_symbol;
639       delete _M_data;
640     }
641
642   template<> 
643     moneypunct<wchar_t, false>::~moneypunct()
644     {
645       if (_M_data->_M_positive_sign_size)
646         delete [] _M_data->_M_positive_sign;
647       if (_M_data->_M_negative_sign_size
648           && wcscmp(_M_data->_M_negative_sign, L"()") != 0)
649         delete [] _M_data->_M_negative_sign;
650       if (_M_data->_M_curr_symbol_size)
651         delete [] _M_data->_M_curr_symbol;
652       delete _M_data;
653     }
654 #endif
655
656 _GLIBCXX_END_NAMESPACE