197403Sobrien// std::numpunct implementation details, GNU version -*- C++ -*-
297403Sobrien
3169691Skan// Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
497403Sobrien//
597403Sobrien// This file is part of the GNU ISO C++ Library.  This library is free
697403Sobrien// software; you can redistribute it and/or modify it under the
797403Sobrien// terms of the GNU General Public License as published by the
897403Sobrien// Free Software Foundation; either version 2, or (at your option)
997403Sobrien// any later version.
1097403Sobrien
1197403Sobrien// This library is distributed in the hope that it will be useful,
1297403Sobrien// but WITHOUT ANY WARRANTY; without even the implied warranty of
1397403Sobrien// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1497403Sobrien// GNU General Public License for more details.
1597403Sobrien
1697403Sobrien// You should have received a copy of the GNU General Public License along
1797403Sobrien// with this library; see the file COPYING.  If not, write to the Free
18169691Skan// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
1997403Sobrien// USA.
2097403Sobrien
2197403Sobrien// As a special exception, you may use this file as part of a free software
2297403Sobrien// library without restriction.  Specifically, if other files instantiate
2397403Sobrien// templates or use macros or inline functions from this file, or you compile
2497403Sobrien// this file and link it with other files to produce an executable, this
2597403Sobrien// file does not by itself cause the resulting executable to be covered by
2697403Sobrien// the GNU General Public License.  This exception does not however
2797403Sobrien// invalidate any other reasons why the executable file might be covered by
2897403Sobrien// the GNU General Public License.
2997403Sobrien
3097403Sobrien//
3197403Sobrien// ISO C++ 14882: 22.2.3.1.2  numpunct virtual functions
3297403Sobrien//
3397403Sobrien
3497403Sobrien// Written by Benjamin Kosnik <bkoz@redhat.com>
3597403Sobrien
3697403Sobrien#include <locale>
37117397Skan#include <bits/c++locale_internal.h>
3897403Sobrien
39169691Skan_GLIBCXX_BEGIN_NAMESPACE(std)
40169691Skan
4197403Sobrien  template<>
4297403Sobrien    void
4397403Sobrien    numpunct<char>::_M_initialize_numpunct(__c_locale __cloc)
4497403Sobrien    {
45132720Skan      if (!_M_data)
46132720Skan	_M_data = new __numpunct_cache<char>;
47132720Skan
48107606Sobrien      if (!__cloc)
4997403Sobrien	{
5097403Sobrien	  // "C" locale
51132720Skan	  _M_data->_M_grouping = "";
52132720Skan	  _M_data->_M_grouping_size = 0;
53132720Skan	  _M_data->_M_use_grouping = false;
54132720Skan
55132720Skan	  _M_data->_M_decimal_point = '.';
56132720Skan	  _M_data->_M_thousands_sep = ',';
57132720Skan
58132720Skan	  for (size_t __i = 0; __i < __num_base::_S_oend; ++__i)
59132720Skan	    _M_data->_M_atoms_out[__i] = __num_base::_S_atoms_out[__i];
60132720Skan
61132720Skan	  for (size_t __j = 0; __j < __num_base::_S_iend; ++__j)
62132720Skan	    _M_data->_M_atoms_in[__j] = __num_base::_S_atoms_in[__j];
6397403Sobrien	}
6497403Sobrien      else
6597403Sobrien	{
6697403Sobrien	  // Named locale.
67132720Skan	  _M_data->_M_decimal_point = *(__nl_langinfo_l(DECIMAL_POINT,
68132720Skan							__cloc));
69132720Skan	  _M_data->_M_thousands_sep = *(__nl_langinfo_l(THOUSANDS_SEP,
70132720Skan							__cloc));
71132720Skan
72132720Skan	  // Check for NULL, which implies no grouping.
73132720Skan	  if (_M_data->_M_thousands_sep == '\0')
74132720Skan	    _M_data->_M_grouping = "";
7597403Sobrien	  else
76132720Skan	    _M_data->_M_grouping = __nl_langinfo_l(GROUPING, __cloc);
77132720Skan	  _M_data->_M_grouping_size = strlen(_M_data->_M_grouping);
7897403Sobrien	}
79132720Skan
8097403Sobrien      // NB: There is no way to extact this info from posix locales.
8197403Sobrien      // _M_truename = __nl_langinfo_l(YESSTR, __cloc);
82132720Skan      _M_data->_M_truename = "true";
83169691Skan      _M_data->_M_truename_size = 4;
8497403Sobrien      // _M_falsename = __nl_langinfo_l(NOSTR, __cloc);
85132720Skan      _M_data->_M_falsename = "false";
86169691Skan      _M_data->_M_falsename_size = 5;
8797403Sobrien    }
8897403Sobrien
8997403Sobrien  template<>
9097403Sobrien    numpunct<char>::~numpunct()
91132720Skan    { delete _M_data; }
9297403Sobrien
93132720Skan#ifdef _GLIBCXX_USE_WCHAR_T
9497403Sobrien  template<>
9597403Sobrien    void
9697403Sobrien    numpunct<wchar_t>::_M_initialize_numpunct(__c_locale __cloc)
9797403Sobrien    {
98132720Skan      if (!_M_data)
99132720Skan	_M_data = new __numpunct_cache<wchar_t>;
100132720Skan
101107606Sobrien      if (!__cloc)
10297403Sobrien	{
10397403Sobrien	  // "C" locale
104132720Skan	  _M_data->_M_grouping = "";
105132720Skan	  _M_data->_M_grouping_size = 0;
106132720Skan	  _M_data->_M_use_grouping = false;
107132720Skan
108132720Skan	  _M_data->_M_decimal_point = L'.';
109132720Skan	  _M_data->_M_thousands_sep = L',';
110132720Skan
111132720Skan	  // Use ctype::widen code without the facet...
112132720Skan	  for (size_t __i = 0; __i < __num_base::_S_oend; ++__i)
113169691Skan	    _M_data->_M_atoms_out[__i] =
114169691Skan	      static_cast<wchar_t>(__num_base::_S_atoms_out[__i]);
115132720Skan
116132720Skan	  for (size_t __j = 0; __j < __num_base::_S_iend; ++__j)
117169691Skan	    _M_data->_M_atoms_in[__j] =
118169691Skan	      static_cast<wchar_t>(__num_base::_S_atoms_in[__j]);
11997403Sobrien	}
12097403Sobrien      else
12197403Sobrien	{
12297403Sobrien	  // Named locale.
123169691Skan	  // NB: In the GNU model wchar_t is always 32 bit wide.
124169691Skan	  union { char *__s; wchar_t __w; } __u;
125132720Skan	  __u.__s = __nl_langinfo_l(_NL_NUMERIC_DECIMAL_POINT_WC, __cloc);
126169691Skan	  _M_data->_M_decimal_point = __u.__w;
127132720Skan
128132720Skan	  __u.__s = __nl_langinfo_l(_NL_NUMERIC_THOUSANDS_SEP_WC, __cloc);
129169691Skan	  _M_data->_M_thousands_sep = __u.__w;
130132720Skan
131132720Skan	  if (_M_data->_M_thousands_sep == L'\0')
132132720Skan	    _M_data->_M_grouping = "";
13397403Sobrien	  else
134132720Skan	    _M_data->_M_grouping = __nl_langinfo_l(GROUPING, __cloc);
135132720Skan	  _M_data->_M_grouping_size = strlen(_M_data->_M_grouping);
13697403Sobrien	}
137132720Skan
13897403Sobrien      // NB: There is no way to extact this info from posix locales.
13997403Sobrien      // _M_truename = __nl_langinfo_l(YESSTR, __cloc);
140132720Skan      _M_data->_M_truename = L"true";
141169691Skan      _M_data->_M_truename_size = 4;
14297403Sobrien      // _M_falsename = __nl_langinfo_l(NOSTR, __cloc);
143132720Skan      _M_data->_M_falsename = L"false";
144169691Skan      _M_data->_M_falsename_size = 5;
14597403Sobrien    }
14697403Sobrien
14797403Sobrien  template<>
14897403Sobrien    numpunct<wchar_t>::~numpunct()
149132720Skan    { delete _M_data; }
15097403Sobrien #endif
151169691Skan
152169691Skan_GLIBCXX_END_NAMESPACE
153