1 // Wrapper for underlying C-language localization -*- C++ -*-
3 // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
4 // Free Software Foundation, Inc.
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)
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.
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,
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.
32 // ISO C++ 14882: 22.8 Standard locale categories.
35 // Written by Benjamin Kosnik <bkoz@redhat.com>
37 #include <cerrno> // For errno
38 #include <cmath> // For isinf, finite, finitef, fabs
39 #include <cstdlib> // For strof, strtold
46 #ifdef _GLIBCXX_HAVE_IEEEFP_H
50 _GLIBCXX_BEGIN_NAMESPACE(std)
54 __convert_to_v(const char* __s, float& __v, ios_base::iostate& __err,
57 // Assumes __s formatted for "C" locale.
58 char* __old = setlocale(LC_ALL, NULL);
59 const size_t __len = strlen(__old) + 1;
60 char* __sav = new char[__len];
61 memcpy(__sav, __old, __len);
62 setlocale(LC_ALL, "C");
64 bool __overflow = false;
66 #if !__FLT_HAS_INFINITY__
70 #ifdef _GLIBCXX_HAVE_STRTOF
71 __v = strtof(__s, &__sanity);
73 double __d = strtod(__s, &__sanity);
74 __v = static_cast<float>(__d);
75 #ifdef _GLIBCXX_HAVE_FINITEF
78 #elif defined (_GLIBCXX_HAVE_FINITE)
79 if (!finite (static_cast<double> (__v)))
81 #elif defined (_GLIBCXX_HAVE_ISINF)
82 if (isinf (static_cast<double> (__v)))
85 if (fabs(__d) > numeric_limits<float>::max())
88 #endif // _GLIBCXX_HAVE_STRTOF
90 // _GLIBCXX_RESOLVE_LIB_DEFECTS
91 // 23. Num_get overflow result.
92 if (__sanity == __s || *__sanity != '\0')
95 __err = ios_base::failbit;
98 #if __FLT_HAS_INFINITY__
99 || __v == numeric_limits<float>::infinity()
100 || __v == -numeric_limits<float>::infinity())
102 || ((__v > 1.0f || __v < -1.0f) && errno == ERANGE)
106 __v = numeric_limits<float>::max();
108 __v = -numeric_limits<float>::max();
109 __err = ios_base::failbit;
112 setlocale(LC_ALL, __sav);
118 __convert_to_v(const char* __s, double& __v, ios_base::iostate& __err,
121 // Assumes __s formatted for "C" locale.
122 char* __old = setlocale(LC_ALL, NULL);
123 const size_t __len = strlen(__old) + 1;
124 char* __sav = new char[__len];
125 memcpy(__sav, __old, __len);
126 setlocale(LC_ALL, "C");
129 #if !__DBL_HAS_INFINITY__
133 __v = strtod(__s, &__sanity);
135 // _GLIBCXX_RESOLVE_LIB_DEFECTS
136 // 23. Num_get overflow result.
137 if (__sanity == __s || *__sanity != '\0')
140 __err = ios_base::failbit;
143 #if __DBL_HAS_INFINITY__
144 __v == numeric_limits<double>::infinity()
145 || __v == -numeric_limits<double>::infinity())
147 (__v > 1.0 || __v < -1.0) && errno == ERANGE)
151 __v = numeric_limits<double>::max();
153 __v = -numeric_limits<double>::max();
154 __err = ios_base::failbit;
157 setlocale(LC_ALL, __sav);
163 __convert_to_v(const char* __s, long double& __v,
164 ios_base::iostate& __err, const __c_locale&)
166 // Assumes __s formatted for "C" locale.
167 char* __old = setlocale(LC_ALL, NULL);
168 const size_t __len = strlen(__old) + 1;
169 char* __sav = new char[__len];
170 memcpy(__sav, __old, __len);
171 setlocale(LC_ALL, "C");
173 #if !__LDBL_HAS_INFINITY__
177 #if defined(_GLIBCXX_HAVE_STRTOLD) && !defined(_GLIBCXX_HAVE_BROKEN_STRTOLD)
179 __v = strtold(__s, &__sanity);
181 // _GLIBCXX_RESOLVE_LIB_DEFECTS
182 // 23. Num_get overflow result.
183 if (__sanity == __s || *__sanity != '\0')
185 typedef char_traits<char>::int_type int_type;
186 int __p = sscanf(__s, "%Lf", &__v);
188 if (!__p || static_cast<int_type>(__p) == char_traits<char>::eof())
192 __err = ios_base::failbit;
195 #if __LDBL_HAS_INFINITY__
196 __v == numeric_limits<long double>::infinity()
197 || __v == -numeric_limits<long double>::infinity())
199 (__v > 1.0l || __v < -1.0l) && errno == ERANGE)
203 __v = numeric_limits<long double>::max();
205 __v = -numeric_limits<long double>::max();
206 __err = ios_base::failbit;
209 setlocale(LC_ALL, __sav);
214 locale::facet::_S_create_c_locale(__c_locale& __cloc, const char* __s,
217 // Currently, the generic model only supports the "C" locale.
218 // See http://gcc.gnu.org/ml/libstdc++/2003-02/msg00345.html
220 if (strcmp(__s, "C"))
221 __throw_runtime_error(__N("locale::facet::_S_create_c_locale "
226 locale::facet::_S_destroy_c_locale(__c_locale& __cloc)
230 locale::facet::_S_clone_c_locale(__c_locale&)
231 { return __c_locale(); }
233 _GLIBCXX_END_NAMESPACE
235 _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
237 const char* const category_names[6 + _GLIBCXX_NUM_CATEGORIES] =
247 _GLIBCXX_END_NAMESPACE
249 _GLIBCXX_BEGIN_NAMESPACE(std)
251 const char* const* const locale::_S_categories = __gnu_cxx::category_names;
253 _GLIBCXX_END_NAMESPACE
255 // XXX GLIBCXX_ABI Deprecated
256 #ifdef _GLIBCXX_LONG_DOUBLE_COMPAT
257 #define _GLIBCXX_LDBL_COMPAT(dbl, ldbl) \
258 extern "C" void ldbl (void) __attribute__ ((alias (#dbl)))
259 _GLIBCXX_LDBL_COMPAT(_ZSt14__convert_to_vIdEvPKcRT_RSt12_Ios_IostateRKPi, _ZSt14__convert_to_vIeEvPKcRT_RSt12_Ios_IostateRKPi);
260 #endif // _GLIBCXX_LONG_DOUBLE_COMPAT