// Locale support -*- C++ -*-
-// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
-// 2006, 2007, 2008
-// Free Software Foundation, Inc.
+// Copyright (C) 1997-2015 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
-// Free Software Foundation; either version 2, or (at your option)
+// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License along
-// with this library; see the file COPYING. If not, write to the Free
-// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
-// USA.
-
-// As a special exception, you may use this file as part of a free software
-// library without restriction. Specifically, if other files instantiate
-// templates or use macros or inline functions from this file, or you compile
-// this file and link it with other files to produce an executable, this
-// file does not by itself cause the resulting executable to be covered by
-// the GNU General Public License. This exception does not however
-// invalidate any other reasons why the executable file might be covered by
-// the GNU General Public License.
-
-/** @file locale_facets.tcc
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+// <http://www.gnu.org/licenses/>.
+
+/** @file bits/locale_facets.tcc
* This is an internal header file, included by other library headers.
- * You should not attempt to use it directly.
+ * Do not attempt to use it directly. @headername{locale}
*/
#ifndef _LOCALE_FACETS_TCC
#pragma GCC system_header
-_GLIBCXX_BEGIN_NAMESPACE(std)
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
// Routine to access a cache for the facet. If the cache didn't
// exist before, it gets constructed on the fly.
const locale::facet** __caches = __loc._M_impl->_M_caches;
if (!__caches[__i])
{
- __numpunct_cache<_CharT>* __tmp = NULL;
- try
+ __numpunct_cache<_CharT>* __tmp = 0;
+ __try
{
__tmp = new __numpunct_cache<_CharT>;
__tmp->_M_cache(__loc);
}
- catch(...)
+ __catch(...)
{
delete __tmp;
__throw_exception_again;
void
__numpunct_cache<_CharT>::_M_cache(const locale& __loc)
{
- _M_allocated = true;
-
const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
- _M_grouping_size = __np.grouping().size();
- char* __grouping = new char[_M_grouping_size];
- __np.grouping().copy(__grouping, _M_grouping_size);
- _M_grouping = __grouping;
- _M_use_grouping = (_M_grouping_size
- && static_cast<signed char>(__np.grouping()[0]) > 0);
-
- _M_truename_size = __np.truename().size();
- _CharT* __truename = new _CharT[_M_truename_size];
- __np.truename().copy(__truename, _M_truename_size);
- _M_truename = __truename;
-
- _M_falsename_size = __np.falsename().size();
- _CharT* __falsename = new _CharT[_M_falsename_size];
- __np.falsename().copy(__falsename, _M_falsename_size);
- _M_falsename = __falsename;
-
- _M_decimal_point = __np.decimal_point();
- _M_thousands_sep = __np.thousands_sep();
-
- const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__loc);
- __ct.widen(__num_base::_S_atoms_out,
- __num_base::_S_atoms_out + __num_base::_S_oend, _M_atoms_out);
- __ct.widen(__num_base::_S_atoms_in,
- __num_base::_S_atoms_in + __num_base::_S_iend, _M_atoms_in);
+ char* __grouping = 0;
+ _CharT* __truename = 0;
+ _CharT* __falsename = 0;
+ __try
+ {
+ const string& __g = __np.grouping();
+ _M_grouping_size = __g.size();
+ __grouping = new char[_M_grouping_size];
+ __g.copy(__grouping, _M_grouping_size);
+ _M_use_grouping = (_M_grouping_size
+ && static_cast<signed char>(__grouping[0]) > 0
+ && (__grouping[0]
+ != __gnu_cxx::__numeric_traits<char>::__max));
+
+ const basic_string<_CharT>& __tn = __np.truename();
+ _M_truename_size = __tn.size();
+ __truename = new _CharT[_M_truename_size];
+ __tn.copy(__truename, _M_truename_size);
+
+ const basic_string<_CharT>& __fn = __np.falsename();
+ _M_falsename_size = __fn.size();
+ __falsename = new _CharT[_M_falsename_size];
+ __fn.copy(__falsename, _M_falsename_size);
+
+ _M_decimal_point = __np.decimal_point();
+ _M_thousands_sep = __np.thousands_sep();
+
+ const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__loc);
+ __ct.widen(__num_base::_S_atoms_out,
+ __num_base::_S_atoms_out
+ + __num_base::_S_oend, _M_atoms_out);
+ __ct.widen(__num_base::_S_atoms_in,
+ __num_base::_S_atoms_in
+ + __num_base::_S_iend, _M_atoms_in);
+
+ _M_grouping = __grouping;
+ _M_truename = __truename;
+ _M_falsename = __falsename;
+ _M_allocated = true;
+ }
+ __catch(...)
+ {
+ delete [] __grouping;
+ delete [] __truename;
+ delete [] __falsename;
+ __throw_exception_again;
+ }
}
// Used by both numeric and monetary facets.
// 1,222,444 == __grouping_tmp of "\1\3\3"
// __grouping is parsed R to L
// 1,222,444 == __grouping of "\3" == "\3\3\3"
- bool
+ _GLIBCXX_PURE bool
__verify_grouping(const char* __grouping, size_t __grouping_size,
- const string& __grouping_tmp);
+ const string& __grouping_tmp) throw ();
-_GLIBCXX_BEGIN_LDBL_NAMESPACE
+_GLIBCXX_BEGIN_NAMESPACE_LDBL
template<typename _CharT, typename _InIter>
+ _GLIBCXX_DEFAULT_ABI_TAG
_InIter
num_get<_CharT, _InIter>::
_M_extract_float(_InIter __beg, _InIter __end, ios_base& __io,
template<typename _CharT, typename _InIter>
template<typename _ValueT>
+ _GLIBCXX_DEFAULT_ABI_TAG
_InIter
num_get<_CharT, _InIter>::
_M_extract_int(_InIter __beg, _InIter __end, ios_base& __io,
if (!__testeof)
{
__c = *__beg;
- if (__gnu_cxx::__numeric_traits<_ValueT>::__is_signed)
- __negative = __c == __lit[__num_base::_S_iminus];
+ __negative = __c == __lit[__num_base::_S_iminus];
if ((__negative || __c == __lit[__num_base::_S_iplus])
&& !(__lc->_M_use_grouping && __c == __lc->_M_thousands_sep)
&& !(__c == __lc->_M_decimal_point))
__found_grouping.reserve(32);
bool __testfail = false;
bool __testoverflow = false;
- const __unsigned_type __max = __negative
+ const __unsigned_type __max =
+ (__negative && __gnu_cxx::__numeric_traits<_ValueT>::__is_signed)
? -__gnu_cxx::__numeric_traits<_ValueT>::__min
: __gnu_cxx::__numeric_traits<_ValueT>::__max;
const __unsigned_type __smax = __max / __base;
}
else if (__testoverflow)
{
- if (__negative)
+ if (__negative
+ && __gnu_cxx::__numeric_traits<_ValueT>::__is_signed)
__v = __gnu_cxx::__numeric_traits<_ValueT>::__min;
else
__v = __gnu_cxx::__numeric_traits<_ValueT>::__max;
bool __testf = true;
bool __testt = true;
+ bool __donef = __lc->_M_falsename_size == 0;
+ bool __donet = __lc->_M_truename_size == 0;
bool __testeof = false;
- size_t __n;
- const size_t __lim = std::max(__lc->_M_falsename_size,
- __lc->_M_truename_size);
- for (__n = 0; __n < __lim; ++__n, ++__beg)
+ size_t __n = 0;
+ while (!__donef || !__donet)
{
if (__beg == __end)
{
const char_type __c = *__beg;
- if (__testf && __n < __lc->_M_falsename_size)
+ if (!__donef)
__testf = __c == __lc->_M_falsename[__n];
- if (__testt && __n < __lc->_M_truename_size)
+ if (!__testf && __donet)
+ break;
+
+ if (!__donet)
__testt = __c == __lc->_M_truename[__n];
- if (!__testt && !__testf)
+ if (!__testt && __donef)
break;
- if ((!__testt && __n >= __lc->_M_falsename_size)
- || (!__testf && __n >= __lc->_M_truename_size))
+ if (!__testt && !__testf)
break;
+
+ ++__n;
+ ++__beg;
+
+ __donef = !__testf || __n >= __lc->_M_falsename_size;
+ __donet = !__testt || __n >= __lc->_M_truename_size;
}
if (__testf && __n == __lc->_M_falsename_size && __n)
{
__len = static_cast<int>(__w);
}
-_GLIBCXX_END_LDBL_NAMESPACE
+_GLIBCXX_END_NAMESPACE_LDBL
template<typename _CharT, typename _ValueT>
int
return __bufend - __buf;
}
-_GLIBCXX_BEGIN_LDBL_NAMESPACE
+_GLIBCXX_BEGIN_NAMESPACE_LDBL
template<typename _CharT, typename _OutIter>
void
__num_base::_S_format_float(__io, __fbuf, __mod);
#ifdef _GLIBCXX_USE_C99
+ // Precision is always used except for hexfloat format.
+ const bool __use_prec =
+ (__io.flags() & ios_base::floatfield) != ios_base::floatfield;
+
// First try a buffer perhaps big enough (most probably sufficient
// for non-ios_base::fixed outputs)
int __cs_size = __max_digits * 3;
char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
- __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size,
- __fbuf, __prec, __v);
+ if (__use_prec)
+ __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size,
+ __fbuf, __prec, __v);
+ else
+ __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size,
+ __fbuf, __v);
// If the buffer was not large enough, try again with the correct size.
if (__len >= __cs_size)
{
__cs_size = __len + 1;
__cs = static_cast<char*>(__builtin_alloca(__cs_size));
- __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size,
- __fbuf, __prec, __v);
+ if (__use_prec)
+ __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size,
+ __fbuf, __prec, __v);
+ else
+ __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size,
+ __fbuf, __v);
}
#else
// Consider the possibility of long ios_base::fixed outputs
const streamsize __w = __io.width();
if (__w > static_cast<streamsize>(__len))
{
- _CharT* __cs
+ const streamsize __plen = __w - __len;
+ _CharT* __ps
= static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
- * __w));
- _M_pad(__fill, __w, __io, __cs, __name, __len);
- __name = __cs;
+ * __plen));
+
+ char_traits<_CharT>::assign(__ps, __plen, __fill);
+ __io.width(0);
+
+ if ((__flags & ios_base::adjustfield) == ios_base::left)
+ {
+ __s = std::__write(__s, __name, __len);
+ __s = std::__write(__s, __ps, __plen);
+ }
+ else
+ {
+ __s = std::__write(__s, __ps, __plen);
+ __s = std::__write(__s, __name, __len);
+ }
+ return __s;
}
__io.width(0);
__s = std::__write(__s, __name, __len);
{
const ios_base::fmtflags __flags = __io.flags();
const ios_base::fmtflags __fmt = ~(ios_base::basefield
- | ios_base::uppercase
- | ios_base::internal);
+ | ios_base::uppercase);
__io.flags((__flags & __fmt) | (ios_base::hex | ios_base::showbase));
typedef __gnu_cxx::__conditional_type<(sizeof(const void*)
return __s;
}
-_GLIBCXX_END_LDBL_NAMESPACE
+_GLIBCXX_END_NAMESPACE_LDBL
// Construct correctly padded string, as per 22.2.2.2.2
// Assumes
size_t __ctr = 0;
while (__last - __first > __gbeg[__idx]
- && static_cast<signed char>(__gbeg[__idx]) > 0)
+ && static_cast<signed char>(__gbeg[__idx]) > 0
+ && __gbeg[__idx] != __gnu_cxx::__numeric_traits<char>::__max)
{
__last -= __gbeg[__idx];
__idx < __gsize - 1 ? ++__idx : ++__ctr;
// Inhibit implicit instantiations for required instantiations,
// which are defined via explicit instantiations elsewhere.
- // NB: This syntax is a GNU extension.
#if _GLIBCXX_EXTERN_TEMPLATE
- extern template class numpunct<char>;
- extern template class numpunct_byname<char>;
- extern template class _GLIBCXX_LDBL_NAMESPACE num_get<char>;
- extern template class _GLIBCXX_LDBL_NAMESPACE num_put<char>;
+ extern template class _GLIBCXX_NAMESPACE_CXX11 numpunct<char>;
+ extern template class _GLIBCXX_NAMESPACE_CXX11 numpunct_byname<char>;
+ extern template class _GLIBCXX_NAMESPACE_LDBL num_get<char>;
+ extern template class _GLIBCXX_NAMESPACE_LDBL num_put<char>;
extern template class ctype_byname<char>;
extern template
has_facet<num_get<char> >(const locale&);
#ifdef _GLIBCXX_USE_WCHAR_T
- extern template class numpunct<wchar_t>;
- extern template class numpunct_byname<wchar_t>;
- extern template class _GLIBCXX_LDBL_NAMESPACE num_get<wchar_t>;
- extern template class _GLIBCXX_LDBL_NAMESPACE num_put<wchar_t>;
+ extern template class _GLIBCXX_NAMESPACE_CXX11 numpunct<wchar_t>;
+ extern template class _GLIBCXX_NAMESPACE_CXX11 numpunct_byname<wchar_t>;
+ extern template class _GLIBCXX_NAMESPACE_LDBL num_get<wchar_t>;
+ extern template class _GLIBCXX_NAMESPACE_LDBL num_put<wchar_t>;
extern template class ctype_byname<wchar_t>;
extern template
#endif
#endif
-_GLIBCXX_END_NAMESPACE
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace
#endif