mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 22:04:21 +00:00
1072 lines
37 KiB
C++
Vendored
1072 lines
37 KiB
C++
Vendored
//===----------------------------------------------------------------------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef _LIBCPP___LOCALE_DIR_NUM_H
|
|
#define _LIBCPP___LOCALE_DIR_NUM_H
|
|
|
|
#include <__algorithm/find.h>
|
|
#include <__algorithm/reverse.h>
|
|
#include <__charconv/to_chars_integral.h>
|
|
#include <__charconv/traits.h>
|
|
#include <__config>
|
|
#include <__iterator/istreambuf_iterator.h>
|
|
#include <__iterator/ostreambuf_iterator.h>
|
|
#include <__locale_dir/check_grouping.h>
|
|
#include <__locale_dir/get_c_locale.h>
|
|
#include <__locale_dir/pad_and_output.h>
|
|
#include <__locale_dir/scan_keyword.h>
|
|
#include <__memory/unique_ptr.h>
|
|
#include <__system_error/errc.h>
|
|
#include <cerrno>
|
|
#include <ios>
|
|
#include <streambuf>
|
|
|
|
#if _LIBCPP_HAS_LOCALIZATION
|
|
|
|
# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
|
# pragma GCC system_header
|
|
# endif
|
|
|
|
// TODO: Properly qualify calls now that the locale base API defines functions instead of macros
|
|
// NOLINTBEGIN(libcpp-robust-against-adl)
|
|
|
|
_LIBCPP_PUSH_MACROS
|
|
# include <__undef_macros>
|
|
|
|
_LIBCPP_BEGIN_NAMESPACE_STD
|
|
|
|
struct _LIBCPP_EXPORTED_FROM_ABI __num_get_base {
|
|
static const int __num_get_buf_sz = 40;
|
|
|
|
static int __get_base(ios_base&);
|
|
static const char __src[33]; // "0123456789abcdefABCDEFxX+-pPiInN"
|
|
// count of leading characters in __src used for parsing integers ("012..X+-")
|
|
static const size_t __int_chr_cnt = 26;
|
|
// count of leading characters in __src used for parsing floating-point values ("012..-pP")
|
|
static const size_t __fp_chr_cnt = 28;
|
|
};
|
|
|
|
template <class _CharT>
|
|
struct __num_get : protected __num_get_base {
|
|
static string __stage2_float_prep(ios_base& __iob, _CharT* __atoms, _CharT& __decimal_point, _CharT& __thousands_sep);
|
|
|
|
static int __stage2_float_loop(
|
|
_CharT __ct,
|
|
bool& __in_units,
|
|
char& __exp,
|
|
char* __a,
|
|
char*& __a_end,
|
|
_CharT __decimal_point,
|
|
_CharT __thousands_sep,
|
|
const string& __grouping,
|
|
unsigned* __g,
|
|
unsigned*& __g_end,
|
|
unsigned& __dc,
|
|
_CharT* __atoms);
|
|
|
|
[[__deprecated__("This exists only for ABI compatibility")]] static string
|
|
__stage2_int_prep(ios_base& __iob, _CharT* __atoms, _CharT& __thousands_sep);
|
|
static int __stage2_int_loop(
|
|
_CharT __ct,
|
|
int __base,
|
|
char* __a,
|
|
char*& __a_end,
|
|
unsigned& __dc,
|
|
_CharT __thousands_sep,
|
|
const string& __grouping,
|
|
unsigned* __g,
|
|
unsigned*& __g_end,
|
|
_CharT* __atoms);
|
|
|
|
_LIBCPP_HIDE_FROM_ABI static string __stage2_int_prep(ios_base& __iob, _CharT& __thousands_sep) {
|
|
locale __loc = __iob.getloc();
|
|
const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
|
|
__thousands_sep = __np.thousands_sep();
|
|
return __np.grouping();
|
|
}
|
|
|
|
_LIBCPP_HIDE_FROM_ABI const _CharT* __do_widen(ios_base& __iob, _CharT* __atoms) const {
|
|
return __do_widen_p(__iob, __atoms);
|
|
}
|
|
|
|
private:
|
|
template <typename _Tp>
|
|
_LIBCPP_HIDE_FROM_ABI const _Tp* __do_widen_p(ios_base& __iob, _Tp* __atoms) const {
|
|
locale __loc = __iob.getloc();
|
|
use_facet<ctype<_Tp> >(__loc).widen(__src, __src + __int_chr_cnt, __atoms);
|
|
return __atoms;
|
|
}
|
|
|
|
_LIBCPP_HIDE_FROM_ABI const char* __do_widen_p(ios_base& __iob, char* __atoms) const {
|
|
(void)__iob;
|
|
(void)__atoms;
|
|
return __src;
|
|
}
|
|
};
|
|
|
|
template <class _CharT>
|
|
string __num_get<_CharT>::__stage2_float_prep(
|
|
ios_base& __iob, _CharT* __atoms, _CharT& __decimal_point, _CharT& __thousands_sep) {
|
|
locale __loc = __iob.getloc();
|
|
std::use_facet<ctype<_CharT> >(__loc).widen(__src, __src + __fp_chr_cnt, __atoms);
|
|
const numpunct<_CharT>& __np = std::use_facet<numpunct<_CharT> >(__loc);
|
|
__decimal_point = __np.decimal_point();
|
|
__thousands_sep = __np.thousands_sep();
|
|
return __np.grouping();
|
|
}
|
|
|
|
template <class _CharT>
|
|
int __num_get<_CharT>::__stage2_int_loop(
|
|
_CharT __ct,
|
|
int __base,
|
|
char* __a,
|
|
char*& __a_end,
|
|
unsigned& __dc,
|
|
_CharT __thousands_sep,
|
|
const string& __grouping,
|
|
unsigned* __g,
|
|
unsigned*& __g_end,
|
|
_CharT* __atoms) {
|
|
if (__a_end == __a && (__ct == __atoms[24] || __ct == __atoms[25])) {
|
|
*__a_end++ = __ct == __atoms[24] ? '+' : '-';
|
|
__dc = 0;
|
|
return 0;
|
|
}
|
|
if (__grouping.size() != 0 && __ct == __thousands_sep) {
|
|
if (__g_end - __g < __num_get_buf_sz) {
|
|
*__g_end++ = __dc;
|
|
__dc = 0;
|
|
}
|
|
return 0;
|
|
}
|
|
ptrdiff_t __f = std::find(__atoms, __atoms + __int_chr_cnt, __ct) - __atoms;
|
|
if (__f >= 24)
|
|
return -1;
|
|
switch (__base) {
|
|
case 8:
|
|
case 10:
|
|
if (__f >= __base)
|
|
return -1;
|
|
break;
|
|
case 16:
|
|
if (__f < 22)
|
|
break;
|
|
if (__a_end != __a && __a_end - __a <= 2 && __a_end[-1] == '0') {
|
|
__dc = 0;
|
|
*__a_end++ = __src[__f];
|
|
return 0;
|
|
}
|
|
return -1;
|
|
}
|
|
*__a_end++ = __src[__f];
|
|
++__dc;
|
|
return 0;
|
|
}
|
|
|
|
template <class _CharT>
|
|
int __num_get<_CharT>::__stage2_float_loop(
|
|
_CharT __ct,
|
|
bool& __in_units,
|
|
char& __exp,
|
|
char* __a,
|
|
char*& __a_end,
|
|
_CharT __decimal_point,
|
|
_CharT __thousands_sep,
|
|
const string& __grouping,
|
|
unsigned* __g,
|
|
unsigned*& __g_end,
|
|
unsigned& __dc,
|
|
_CharT* __atoms) {
|
|
if (__ct == __decimal_point) {
|
|
if (!__in_units)
|
|
return -1;
|
|
__in_units = false;
|
|
*__a_end++ = '.';
|
|
if (__grouping.size() != 0 && __g_end - __g < __num_get_buf_sz)
|
|
*__g_end++ = __dc;
|
|
return 0;
|
|
}
|
|
if (__ct == __thousands_sep && __grouping.size() != 0) {
|
|
if (!__in_units)
|
|
return -1;
|
|
if (__g_end - __g < __num_get_buf_sz) {
|
|
*__g_end++ = __dc;
|
|
__dc = 0;
|
|
}
|
|
return 0;
|
|
}
|
|
ptrdiff_t __f = std::find(__atoms, __atoms + __num_get_base::__fp_chr_cnt, __ct) - __atoms;
|
|
if (__f >= static_cast<ptrdiff_t>(__num_get_base::__fp_chr_cnt))
|
|
return -1;
|
|
char __x = __src[__f];
|
|
if (__x == '-' || __x == '+') {
|
|
if (__a_end == __a || (std::toupper(__a_end[-1]) == std::toupper(__exp))) {
|
|
*__a_end++ = __x;
|
|
return 0;
|
|
}
|
|
return -1;
|
|
}
|
|
if (__x == 'x' || __x == 'X')
|
|
__exp = 'P';
|
|
else if (std::toupper(__x) == __exp) {
|
|
__exp = std::tolower(__exp);
|
|
if (__in_units) {
|
|
__in_units = false;
|
|
if (__grouping.size() != 0 && __g_end - __g < __num_get_buf_sz)
|
|
*__g_end++ = __dc;
|
|
}
|
|
}
|
|
*__a_end++ = __x;
|
|
if (__f >= 22)
|
|
return 0;
|
|
++__dc;
|
|
return 0;
|
|
}
|
|
|
|
extern template struct _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __num_get<char>;
|
|
# if _LIBCPP_HAS_WIDE_CHARACTERS
|
|
extern template struct _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __num_get<wchar_t>;
|
|
# endif
|
|
|
|
template <class _Tp>
|
|
_LIBCPP_HIDE_FROM_ABI _Tp __do_strtod(const char* __a, char** __p2);
|
|
|
|
template <>
|
|
inline _LIBCPP_HIDE_FROM_ABI float __do_strtod<float>(const char* __a, char** __p2) {
|
|
return __locale::__strtof(__a, __p2, _LIBCPP_GET_C_LOCALE);
|
|
}
|
|
|
|
template <>
|
|
inline _LIBCPP_HIDE_FROM_ABI double __do_strtod<double>(const char* __a, char** __p2) {
|
|
return __locale::__strtod(__a, __p2, _LIBCPP_GET_C_LOCALE);
|
|
}
|
|
|
|
template <>
|
|
inline _LIBCPP_HIDE_FROM_ABI long double __do_strtod<long double>(const char* __a, char** __p2) {
|
|
return __locale::__strtold(__a, __p2, _LIBCPP_GET_C_LOCALE);
|
|
}
|
|
|
|
template <class _Tp>
|
|
_LIBCPP_HIDE_FROM_ABI _Tp __num_get_float(const char* __a, const char* __a_end, ios_base::iostate& __err) {
|
|
if (__a != __a_end) {
|
|
__libcpp_remove_reference_t<decltype(errno)> __save_errno = errno;
|
|
errno = 0;
|
|
char* __p2;
|
|
_Tp __ld = std::__do_strtod<_Tp>(__a, &__p2);
|
|
__libcpp_remove_reference_t<decltype(errno)> __current_errno = errno;
|
|
if (__current_errno == 0)
|
|
errno = __save_errno;
|
|
if (__p2 != __a_end) {
|
|
__err = ios_base::failbit;
|
|
return 0;
|
|
} else if (__current_errno == ERANGE)
|
|
__err = ios_base::failbit;
|
|
return __ld;
|
|
}
|
|
__err = ios_base::failbit;
|
|
return 0;
|
|
}
|
|
|
|
template <class _Tp>
|
|
_LIBCPP_HIDE_FROM_ABI _Tp
|
|
__num_get_signed_integral(const char* __a, const char* __a_end, ios_base::iostate& __err, int __base) {
|
|
if (__a != __a_end) {
|
|
__libcpp_remove_reference_t<decltype(errno)> __save_errno = errno;
|
|
errno = 0;
|
|
char* __p2;
|
|
long long __ll = __locale::__strtoll(__a, &__p2, __base, _LIBCPP_GET_C_LOCALE);
|
|
__libcpp_remove_reference_t<decltype(errno)> __current_errno = errno;
|
|
if (__current_errno == 0)
|
|
errno = __save_errno;
|
|
if (__p2 != __a_end) {
|
|
__err = ios_base::failbit;
|
|
return 0;
|
|
} else if (__current_errno == ERANGE || __ll < numeric_limits<_Tp>::min() || numeric_limits<_Tp>::max() < __ll) {
|
|
__err = ios_base::failbit;
|
|
if (__ll > 0)
|
|
return numeric_limits<_Tp>::max();
|
|
else
|
|
return numeric_limits<_Tp>::min();
|
|
}
|
|
return static_cast<_Tp>(__ll);
|
|
}
|
|
__err = ios_base::failbit;
|
|
return 0;
|
|
}
|
|
|
|
template <class _Tp>
|
|
_LIBCPP_HIDE_FROM_ABI _Tp
|
|
__num_get_unsigned_integral(const char* __a, const char* __a_end, ios_base::iostate& __err, int __base) {
|
|
if (__a != __a_end) {
|
|
const bool __negate = *__a == '-';
|
|
if (__negate && ++__a == __a_end) {
|
|
__err = ios_base::failbit;
|
|
return 0;
|
|
}
|
|
__libcpp_remove_reference_t<decltype(errno)> __save_errno = errno;
|
|
errno = 0;
|
|
char* __p2;
|
|
unsigned long long __ll = __locale::__strtoull(__a, &__p2, __base, _LIBCPP_GET_C_LOCALE);
|
|
__libcpp_remove_reference_t<decltype(errno)> __current_errno = errno;
|
|
if (__current_errno == 0)
|
|
errno = __save_errno;
|
|
if (__p2 != __a_end) {
|
|
__err = ios_base::failbit;
|
|
return 0;
|
|
} else if (__current_errno == ERANGE || numeric_limits<_Tp>::max() < __ll) {
|
|
__err = ios_base::failbit;
|
|
return numeric_limits<_Tp>::max();
|
|
}
|
|
_Tp __res = static_cast<_Tp>(__ll);
|
|
if (__negate)
|
|
__res = -__res;
|
|
return __res;
|
|
}
|
|
__err = ios_base::failbit;
|
|
return 0;
|
|
}
|
|
|
|
template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> >
|
|
class num_get : public locale::facet, private __num_get<_CharT> {
|
|
public:
|
|
typedef _CharT char_type;
|
|
typedef _InputIterator iter_type;
|
|
|
|
_LIBCPP_HIDE_FROM_ABI explicit num_get(size_t __refs = 0) : locale::facet(__refs) {}
|
|
|
|
_LIBCPP_HIDE_FROM_ABI iter_type
|
|
get(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, bool& __v) const {
|
|
return do_get(__b, __e, __iob, __err, __v);
|
|
}
|
|
|
|
_LIBCPP_HIDE_FROM_ABI iter_type
|
|
get(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, long& __v) const {
|
|
return do_get(__b, __e, __iob, __err, __v);
|
|
}
|
|
|
|
_LIBCPP_HIDE_FROM_ABI iter_type
|
|
get(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, long long& __v) const {
|
|
return do_get(__b, __e, __iob, __err, __v);
|
|
}
|
|
|
|
_LIBCPP_HIDE_FROM_ABI iter_type
|
|
get(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, unsigned short& __v) const {
|
|
return do_get(__b, __e, __iob, __err, __v);
|
|
}
|
|
|
|
_LIBCPP_HIDE_FROM_ABI iter_type
|
|
get(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, unsigned int& __v) const {
|
|
return do_get(__b, __e, __iob, __err, __v);
|
|
}
|
|
|
|
_LIBCPP_HIDE_FROM_ABI iter_type
|
|
get(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, unsigned long& __v) const {
|
|
return do_get(__b, __e, __iob, __err, __v);
|
|
}
|
|
|
|
_LIBCPP_HIDE_FROM_ABI iter_type
|
|
get(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, unsigned long long& __v) const {
|
|
return do_get(__b, __e, __iob, __err, __v);
|
|
}
|
|
|
|
_LIBCPP_HIDE_FROM_ABI iter_type
|
|
get(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, float& __v) const {
|
|
return do_get(__b, __e, __iob, __err, __v);
|
|
}
|
|
|
|
_LIBCPP_HIDE_FROM_ABI iter_type
|
|
get(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, double& __v) const {
|
|
return do_get(__b, __e, __iob, __err, __v);
|
|
}
|
|
|
|
_LIBCPP_HIDE_FROM_ABI iter_type
|
|
get(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, long double& __v) const {
|
|
return do_get(__b, __e, __iob, __err, __v);
|
|
}
|
|
|
|
_LIBCPP_HIDE_FROM_ABI iter_type
|
|
get(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, void*& __v) const {
|
|
return do_get(__b, __e, __iob, __err, __v);
|
|
}
|
|
|
|
static locale::id id;
|
|
|
|
protected:
|
|
_LIBCPP_HIDE_FROM_ABI_VIRTUAL ~num_get() override {}
|
|
|
|
template <class _Fp>
|
|
_LIBCPP_HIDE_FROM_ABI iter_type
|
|
__do_get_floating_point(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, _Fp& __v) const {
|
|
// Stage 1, nothing to do
|
|
// Stage 2
|
|
char_type __atoms[__num_get_base::__fp_chr_cnt];
|
|
char_type __decimal_point;
|
|
char_type __thousands_sep;
|
|
string __grouping = this->__stage2_float_prep(__iob, __atoms, __decimal_point, __thousands_sep);
|
|
string __buf;
|
|
__buf.resize(__buf.capacity());
|
|
char* __a = &__buf[0];
|
|
char* __a_end = __a;
|
|
unsigned __g[__num_get_base::__num_get_buf_sz];
|
|
unsigned* __g_end = __g;
|
|
unsigned __dc = 0;
|
|
bool __in_units = true;
|
|
char __exp = 'E';
|
|
bool __is_leading_parsed = false;
|
|
for (; __b != __e; ++__b) {
|
|
if (__a_end == __a + __buf.size()) {
|
|
size_t __tmp = __buf.size();
|
|
__buf.resize(2 * __buf.size());
|
|
__buf.resize(__buf.capacity());
|
|
__a = &__buf[0];
|
|
__a_end = __a + __tmp;
|
|
}
|
|
if (this->__stage2_float_loop(
|
|
*__b,
|
|
__in_units,
|
|
__exp,
|
|
__a,
|
|
__a_end,
|
|
__decimal_point,
|
|
__thousands_sep,
|
|
__grouping,
|
|
__g,
|
|
__g_end,
|
|
__dc,
|
|
__atoms))
|
|
break;
|
|
|
|
// the leading character excluding the sign must be a decimal digit
|
|
if (!__is_leading_parsed) {
|
|
if (__a_end - __a >= 1 && __a[0] != '-' && __a[0] != '+') {
|
|
if (('0' <= __a[0] && __a[0] <= '9') || __a[0] == '.')
|
|
__is_leading_parsed = true;
|
|
else
|
|
break;
|
|
} else if (__a_end - __a >= 2 && (__a[0] == '-' || __a[0] == '+')) {
|
|
if (('0' <= __a[1] && __a[1] <= '9') || __a[1] == '.')
|
|
__is_leading_parsed = true;
|
|
else
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (__grouping.size() != 0 && __in_units && __g_end - __g < __num_get_base::__num_get_buf_sz)
|
|
*__g_end++ = __dc;
|
|
// Stage 3
|
|
__v = std::__num_get_float<_Fp>(__a, __a_end, __err);
|
|
// Digit grouping checked
|
|
__check_grouping(__grouping, __g, __g_end, __err);
|
|
// EOF checked
|
|
if (__b == __e)
|
|
__err |= ios_base::eofbit;
|
|
return __b;
|
|
}
|
|
|
|
template <class _Signed>
|
|
_LIBCPP_HIDE_FROM_ABI iter_type
|
|
__do_get_signed(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, _Signed& __v) const {
|
|
// Stage 1
|
|
int __base = this->__get_base(__iob);
|
|
// Stage 2
|
|
char_type __thousands_sep;
|
|
const int __atoms_size = __num_get_base::__int_chr_cnt;
|
|
char_type __atoms1[__atoms_size];
|
|
const char_type* __atoms = this->__do_widen(__iob, __atoms1);
|
|
string __grouping = this->__stage2_int_prep(__iob, __thousands_sep);
|
|
string __buf;
|
|
__buf.resize(__buf.capacity());
|
|
char* __a = &__buf[0];
|
|
char* __a_end = __a;
|
|
unsigned __g[__num_get_base::__num_get_buf_sz];
|
|
unsigned* __g_end = __g;
|
|
unsigned __dc = 0;
|
|
for (; __b != __e; ++__b) {
|
|
if (__a_end == __a + __buf.size()) {
|
|
size_t __tmp = __buf.size();
|
|
__buf.resize(2 * __buf.size());
|
|
__buf.resize(__buf.capacity());
|
|
__a = &__buf[0];
|
|
__a_end = __a + __tmp;
|
|
}
|
|
if (this->__stage2_int_loop(
|
|
*__b,
|
|
__base,
|
|
__a,
|
|
__a_end,
|
|
__dc,
|
|
__thousands_sep,
|
|
__grouping,
|
|
__g,
|
|
__g_end,
|
|
const_cast<char_type*>(__atoms)))
|
|
break;
|
|
}
|
|
if (__grouping.size() != 0 && __g_end - __g < __num_get_base::__num_get_buf_sz)
|
|
*__g_end++ = __dc;
|
|
// Stage 3
|
|
__v = std::__num_get_signed_integral<_Signed>(__a, __a_end, __err, __base);
|
|
// Digit grouping checked
|
|
__check_grouping(__grouping, __g, __g_end, __err);
|
|
// EOF checked
|
|
if (__b == __e)
|
|
__err |= ios_base::eofbit;
|
|
return __b;
|
|
}
|
|
|
|
template <class _Unsigned>
|
|
_LIBCPP_HIDE_FROM_ABI iter_type
|
|
__do_get_unsigned(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, _Unsigned& __v) const {
|
|
// Stage 1
|
|
int __base = this->__get_base(__iob);
|
|
// Stage 2
|
|
char_type __thousands_sep;
|
|
const int __atoms_size = __num_get_base::__int_chr_cnt;
|
|
char_type __atoms1[__atoms_size];
|
|
const char_type* __atoms = this->__do_widen(__iob, __atoms1);
|
|
string __grouping = this->__stage2_int_prep(__iob, __thousands_sep);
|
|
string __buf;
|
|
__buf.resize(__buf.capacity());
|
|
char* __a = &__buf[0];
|
|
char* __a_end = __a;
|
|
unsigned __g[__num_get_base::__num_get_buf_sz];
|
|
unsigned* __g_end = __g;
|
|
unsigned __dc = 0;
|
|
for (; __b != __e; ++__b) {
|
|
if (__a_end == __a + __buf.size()) {
|
|
size_t __tmp = __buf.size();
|
|
__buf.resize(2 * __buf.size());
|
|
__buf.resize(__buf.capacity());
|
|
__a = &__buf[0];
|
|
__a_end = __a + __tmp;
|
|
}
|
|
if (this->__stage2_int_loop(
|
|
*__b,
|
|
__base,
|
|
__a,
|
|
__a_end,
|
|
__dc,
|
|
__thousands_sep,
|
|
__grouping,
|
|
__g,
|
|
__g_end,
|
|
const_cast<char_type*>(__atoms)))
|
|
break;
|
|
}
|
|
if (__grouping.size() != 0 && __g_end - __g < __num_get_base::__num_get_buf_sz)
|
|
*__g_end++ = __dc;
|
|
// Stage 3
|
|
__v = std::__num_get_unsigned_integral<_Unsigned>(__a, __a_end, __err, __base);
|
|
// Digit grouping checked
|
|
__check_grouping(__grouping, __g, __g_end, __err);
|
|
// EOF checked
|
|
if (__b == __e)
|
|
__err |= ios_base::eofbit;
|
|
return __b;
|
|
}
|
|
|
|
virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, bool& __v) const;
|
|
|
|
virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, long& __v) const {
|
|
return this->__do_get_signed(__b, __e, __iob, __err, __v);
|
|
}
|
|
|
|
virtual iter_type
|
|
do_get(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, long long& __v) const {
|
|
return this->__do_get_signed(__b, __e, __iob, __err, __v);
|
|
}
|
|
|
|
virtual iter_type
|
|
do_get(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, unsigned short& __v) const {
|
|
return this->__do_get_unsigned(__b, __e, __iob, __err, __v);
|
|
}
|
|
|
|
virtual iter_type
|
|
do_get(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, unsigned int& __v) const {
|
|
return this->__do_get_unsigned(__b, __e, __iob, __err, __v);
|
|
}
|
|
|
|
virtual iter_type
|
|
do_get(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, unsigned long& __v) const {
|
|
return this->__do_get_unsigned(__b, __e, __iob, __err, __v);
|
|
}
|
|
|
|
virtual iter_type
|
|
do_get(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, unsigned long long& __v) const {
|
|
return this->__do_get_unsigned(__b, __e, __iob, __err, __v);
|
|
}
|
|
|
|
virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, float& __v) const {
|
|
return this->__do_get_floating_point(__b, __e, __iob, __err, __v);
|
|
}
|
|
|
|
virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, double& __v) const {
|
|
return this->__do_get_floating_point(__b, __e, __iob, __err, __v);
|
|
}
|
|
|
|
virtual iter_type
|
|
do_get(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, long double& __v) const {
|
|
return this->__do_get_floating_point(__b, __e, __iob, __err, __v);
|
|
}
|
|
|
|
virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, void*& __v) const;
|
|
};
|
|
|
|
template <class _CharT, class _InputIterator>
|
|
locale::id num_get<_CharT, _InputIterator>::id;
|
|
|
|
template <class _CharT, class _InputIterator>
|
|
_InputIterator num_get<_CharT, _InputIterator>::do_get(
|
|
iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, bool& __v) const {
|
|
if ((__iob.flags() & ios_base::boolalpha) == 0) {
|
|
long __lv = -1;
|
|
__b = do_get(__b, __e, __iob, __err, __lv);
|
|
switch (__lv) {
|
|
case 0:
|
|
__v = false;
|
|
break;
|
|
case 1:
|
|
__v = true;
|
|
break;
|
|
default:
|
|
__v = true;
|
|
__err = ios_base::failbit;
|
|
break;
|
|
}
|
|
return __b;
|
|
}
|
|
const ctype<_CharT>& __ct = std::use_facet<ctype<_CharT> >(__iob.getloc());
|
|
const numpunct<_CharT>& __np = std::use_facet<numpunct<_CharT> >(__iob.getloc());
|
|
typedef typename numpunct<_CharT>::string_type string_type;
|
|
const string_type __names[2] = {__np.truename(), __np.falsename()};
|
|
const string_type* __i = std::__scan_keyword(__b, __e, __names, __names + 2, __ct, __err);
|
|
__v = __i == __names;
|
|
return __b;
|
|
}
|
|
|
|
template <class _CharT, class _InputIterator>
|
|
_InputIterator num_get<_CharT, _InputIterator>::do_get(
|
|
iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, void*& __v) const {
|
|
// Stage 1
|
|
int __base = 16;
|
|
// Stage 2
|
|
char_type __atoms[__num_get_base::__int_chr_cnt];
|
|
char_type __thousands_sep = char_type();
|
|
string __grouping;
|
|
std::use_facet<ctype<_CharT> >(__iob.getloc())
|
|
.widen(__num_get_base::__src, __num_get_base::__src + __num_get_base::__int_chr_cnt, __atoms);
|
|
string __buf;
|
|
__buf.resize(__buf.capacity());
|
|
char* __a = &__buf[0];
|
|
char* __a_end = __a;
|
|
unsigned __g[__num_get_base::__num_get_buf_sz];
|
|
unsigned* __g_end = __g;
|
|
unsigned __dc = 0;
|
|
for (; __b != __e; ++__b) {
|
|
if (__a_end == __a + __buf.size()) {
|
|
size_t __tmp = __buf.size();
|
|
__buf.resize(2 * __buf.size());
|
|
__buf.resize(__buf.capacity());
|
|
__a = &__buf[0];
|
|
__a_end = __a + __tmp;
|
|
}
|
|
if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc, __thousands_sep, __grouping, __g, __g_end, __atoms))
|
|
break;
|
|
}
|
|
// Stage 3
|
|
__buf.resize(__a_end - __a);
|
|
if (__locale::__sscanf(__buf.c_str(), _LIBCPP_GET_C_LOCALE, "%p", &__v) != 1)
|
|
__err = ios_base::failbit;
|
|
// EOF checked
|
|
if (__b == __e)
|
|
__err |= ios_base::eofbit;
|
|
return __b;
|
|
}
|
|
|
|
extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS num_get<char>;
|
|
# if _LIBCPP_HAS_WIDE_CHARACTERS
|
|
extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS num_get<wchar_t>;
|
|
# endif
|
|
|
|
struct _LIBCPP_EXPORTED_FROM_ABI __num_put_base {
|
|
protected:
|
|
static void __format_int(char* __fmt, const char* __len, bool __signd, ios_base::fmtflags __flags);
|
|
static bool __format_float(char* __fmt, const char* __len, ios_base::fmtflags __flags);
|
|
static char* __identify_padding(char* __nb, char* __ne, const ios_base& __iob);
|
|
};
|
|
|
|
template <class _CharT>
|
|
struct __num_put : protected __num_put_base {
|
|
static void __widen_and_group_int(
|
|
char* __nb, char* __np, char* __ne, _CharT* __ob, _CharT*& __op, _CharT*& __oe, const locale& __loc);
|
|
static void __widen_and_group_float(
|
|
char* __nb, char* __np, char* __ne, _CharT* __ob, _CharT*& __op, _CharT*& __oe, const locale& __loc);
|
|
};
|
|
|
|
template <class _CharT>
|
|
void __num_put<_CharT>::__widen_and_group_int(
|
|
char* __nb, char* __np, char* __ne, _CharT* __ob, _CharT*& __op, _CharT*& __oe, const locale& __loc) {
|
|
const ctype<_CharT>& __ct = std::use_facet<ctype<_CharT> >(__loc);
|
|
const numpunct<_CharT>& __npt = std::use_facet<numpunct<_CharT> >(__loc);
|
|
string __grouping = __npt.grouping();
|
|
if (__grouping.empty()) {
|
|
__ct.widen(__nb, __ne, __ob);
|
|
__oe = __ob + (__ne - __nb);
|
|
} else {
|
|
__oe = __ob;
|
|
char* __nf = __nb;
|
|
if (*__nf == '-' || *__nf == '+')
|
|
*__oe++ = __ct.widen(*__nf++);
|
|
if (__ne - __nf >= 2 && __nf[0] == '0' && (__nf[1] == 'x' || __nf[1] == 'X')) {
|
|
*__oe++ = __ct.widen(*__nf++);
|
|
*__oe++ = __ct.widen(*__nf++);
|
|
}
|
|
std::reverse(__nf, __ne);
|
|
_CharT __thousands_sep = __npt.thousands_sep();
|
|
unsigned __dc = 0;
|
|
unsigned __dg = 0;
|
|
for (char* __p = __nf; __p < __ne; ++__p) {
|
|
if (static_cast<unsigned>(__grouping[__dg]) > 0 && __dc == static_cast<unsigned>(__grouping[__dg])) {
|
|
*__oe++ = __thousands_sep;
|
|
__dc = 0;
|
|
if (__dg < __grouping.size() - 1)
|
|
++__dg;
|
|
}
|
|
*__oe++ = __ct.widen(*__p);
|
|
++__dc;
|
|
}
|
|
std::reverse(__ob + (__nf - __nb), __oe);
|
|
}
|
|
if (__np == __ne)
|
|
__op = __oe;
|
|
else
|
|
__op = __ob + (__np - __nb);
|
|
}
|
|
|
|
template <class _CharT>
|
|
void __num_put<_CharT>::__widen_and_group_float(
|
|
char* __nb, char* __np, char* __ne, _CharT* __ob, _CharT*& __op, _CharT*& __oe, const locale& __loc) {
|
|
const ctype<_CharT>& __ct = std::use_facet<ctype<_CharT> >(__loc);
|
|
const numpunct<_CharT>& __npt = std::use_facet<numpunct<_CharT> >(__loc);
|
|
string __grouping = __npt.grouping();
|
|
__oe = __ob;
|
|
char* __nf = __nb;
|
|
if (*__nf == '-' || *__nf == '+')
|
|
*__oe++ = __ct.widen(*__nf++);
|
|
char* __ns;
|
|
if (__ne - __nf >= 2 && __nf[0] == '0' && (__nf[1] == 'x' || __nf[1] == 'X')) {
|
|
*__oe++ = __ct.widen(*__nf++);
|
|
*__oe++ = __ct.widen(*__nf++);
|
|
for (__ns = __nf; __ns < __ne; ++__ns)
|
|
if (!__locale::__isxdigit(*__ns, _LIBCPP_GET_C_LOCALE))
|
|
break;
|
|
} else {
|
|
for (__ns = __nf; __ns < __ne; ++__ns)
|
|
if (!__locale::__isdigit(*__ns, _LIBCPP_GET_C_LOCALE))
|
|
break;
|
|
}
|
|
if (__grouping.empty()) {
|
|
__ct.widen(__nf, __ns, __oe);
|
|
__oe += __ns - __nf;
|
|
} else {
|
|
std::reverse(__nf, __ns);
|
|
_CharT __thousands_sep = __npt.thousands_sep();
|
|
unsigned __dc = 0;
|
|
unsigned __dg = 0;
|
|
for (char* __p = __nf; __p < __ns; ++__p) {
|
|
if (__grouping[__dg] > 0 && __dc == static_cast<unsigned>(__grouping[__dg])) {
|
|
*__oe++ = __thousands_sep;
|
|
__dc = 0;
|
|
if (__dg < __grouping.size() - 1)
|
|
++__dg;
|
|
}
|
|
*__oe++ = __ct.widen(*__p);
|
|
++__dc;
|
|
}
|
|
std::reverse(__ob + (__nf - __nb), __oe);
|
|
}
|
|
for (__nf = __ns; __nf < __ne; ++__nf) {
|
|
if (*__nf == '.') {
|
|
*__oe++ = __npt.decimal_point();
|
|
++__nf;
|
|
break;
|
|
} else
|
|
*__oe++ = __ct.widen(*__nf);
|
|
}
|
|
__ct.widen(__nf, __ne, __oe);
|
|
__oe += __ne - __nf;
|
|
if (__np == __ne)
|
|
__op = __oe;
|
|
else
|
|
__op = __ob + (__np - __nb);
|
|
}
|
|
|
|
extern template struct _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __num_put<char>;
|
|
# if _LIBCPP_HAS_WIDE_CHARACTERS
|
|
extern template struct _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __num_put<wchar_t>;
|
|
# endif
|
|
|
|
template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> >
|
|
class num_put : public locale::facet, private __num_put<_CharT> {
|
|
public:
|
|
typedef _CharT char_type;
|
|
typedef _OutputIterator iter_type;
|
|
|
|
_LIBCPP_HIDE_FROM_ABI explicit num_put(size_t __refs = 0) : locale::facet(__refs) {}
|
|
|
|
_LIBCPP_HIDE_FROM_ABI iter_type put(iter_type __s, ios_base& __iob, char_type __fl, bool __v) const {
|
|
return do_put(__s, __iob, __fl, __v);
|
|
}
|
|
|
|
_LIBCPP_HIDE_FROM_ABI iter_type put(iter_type __s, ios_base& __iob, char_type __fl, long __v) const {
|
|
return do_put(__s, __iob, __fl, __v);
|
|
}
|
|
|
|
_LIBCPP_HIDE_FROM_ABI iter_type put(iter_type __s, ios_base& __iob, char_type __fl, long long __v) const {
|
|
return do_put(__s, __iob, __fl, __v);
|
|
}
|
|
|
|
_LIBCPP_HIDE_FROM_ABI iter_type put(iter_type __s, ios_base& __iob, char_type __fl, unsigned long __v) const {
|
|
return do_put(__s, __iob, __fl, __v);
|
|
}
|
|
|
|
_LIBCPP_HIDE_FROM_ABI iter_type put(iter_type __s, ios_base& __iob, char_type __fl, unsigned long long __v) const {
|
|
return do_put(__s, __iob, __fl, __v);
|
|
}
|
|
|
|
_LIBCPP_HIDE_FROM_ABI iter_type put(iter_type __s, ios_base& __iob, char_type __fl, double __v) const {
|
|
return do_put(__s, __iob, __fl, __v);
|
|
}
|
|
|
|
_LIBCPP_HIDE_FROM_ABI iter_type put(iter_type __s, ios_base& __iob, char_type __fl, long double __v) const {
|
|
return do_put(__s, __iob, __fl, __v);
|
|
}
|
|
|
|
_LIBCPP_HIDE_FROM_ABI iter_type put(iter_type __s, ios_base& __iob, char_type __fl, const void* __v) const {
|
|
return do_put(__s, __iob, __fl, __v);
|
|
}
|
|
|
|
static locale::id id;
|
|
|
|
protected:
|
|
_LIBCPP_HIDE_FROM_ABI_VIRTUAL ~num_put() override {}
|
|
|
|
virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl, bool __v) const;
|
|
virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl, long __v) const;
|
|
virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl, long long __v) const;
|
|
virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl, unsigned long) const;
|
|
virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl, unsigned long long) const;
|
|
virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl, double __v) const;
|
|
virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl, long double __v) const;
|
|
virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl, const void* __v) const;
|
|
|
|
template <class _Integral>
|
|
_LIBCPP_HIDE_FROM_ABI inline _OutputIterator
|
|
__do_put_integral(iter_type __s, ios_base& __iob, char_type __fl, _Integral __v) const;
|
|
|
|
template <class _Float>
|
|
_LIBCPP_HIDE_FROM_ABI inline _OutputIterator
|
|
__do_put_floating_point(iter_type __s, ios_base& __iob, char_type __fl, _Float __v, char const* __len) const;
|
|
};
|
|
|
|
template <class _CharT, class _OutputIterator>
|
|
locale::id num_put<_CharT, _OutputIterator>::id;
|
|
|
|
template <class _CharT, class _OutputIterator>
|
|
_OutputIterator
|
|
num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, char_type __fl, bool __v) const {
|
|
if ((__iob.flags() & ios_base::boolalpha) == 0)
|
|
return do_put(__s, __iob, __fl, (unsigned long)__v);
|
|
const numpunct<char_type>& __np = std::use_facet<numpunct<char_type> >(__iob.getloc());
|
|
typedef typename numpunct<char_type>::string_type string_type;
|
|
string_type __nm = __v ? __np.truename() : __np.falsename();
|
|
for (typename string_type::iterator __i = __nm.begin(); __i != __nm.end(); ++__i, ++__s)
|
|
*__s = *__i;
|
|
return __s;
|
|
}
|
|
|
|
template <class _CharT, class _OutputIterator>
|
|
template <class _Integral>
|
|
_LIBCPP_HIDE_FROM_ABI inline _OutputIterator num_put<_CharT, _OutputIterator>::__do_put_integral(
|
|
iter_type __s, ios_base& __iob, char_type __fl, _Integral __v) const {
|
|
// Stage 1 - Get number in narrow char
|
|
|
|
// Worst case is octal, with showbase enabled. Note that octal is always
|
|
// printed as an unsigned value.
|
|
using _Unsigned = typename make_unsigned<_Integral>::type;
|
|
_LIBCPP_CONSTEXPR const unsigned __buffer_size =
|
|
(numeric_limits<_Unsigned>::digits / 3) // 1 char per 3 bits
|
|
+ ((numeric_limits<_Unsigned>::digits % 3) != 0) // round up
|
|
+ 2; // base prefix + terminating null character
|
|
|
|
char __char_buffer[__buffer_size];
|
|
char* __buffer_ptr = __char_buffer;
|
|
|
|
auto __flags = __iob.flags();
|
|
|
|
auto __basefield = (__flags & ios_base::basefield);
|
|
|
|
// Extract base
|
|
int __base = 10;
|
|
if (__basefield == ios_base::oct)
|
|
__base = 8;
|
|
else if (__basefield == ios_base::hex)
|
|
__base = 16;
|
|
|
|
// Print '-' and make the argument unsigned
|
|
auto __uval = std::__to_unsigned_like(__v);
|
|
if (__basefield != ios_base::oct && __basefield != ios_base::hex && __v < 0) {
|
|
*__buffer_ptr++ = '-';
|
|
__uval = std::__complement(__uval);
|
|
}
|
|
|
|
// Maybe add '+' prefix
|
|
if (std::is_signed<_Integral>::value && (__flags & ios_base::showpos) && __basefield != ios_base::oct &&
|
|
__basefield != ios_base::hex && __v >= 0)
|
|
*__buffer_ptr++ = '+';
|
|
|
|
// Add base prefix
|
|
if (__v != 0 && __flags & ios_base::showbase) {
|
|
if (__basefield == ios_base::oct) {
|
|
*__buffer_ptr++ = '0';
|
|
} else if (__basefield == ios_base::hex) {
|
|
*__buffer_ptr++ = '0';
|
|
*__buffer_ptr++ = (__flags & ios_base::uppercase ? 'X' : 'x');
|
|
}
|
|
}
|
|
|
|
auto __res = std::__to_chars_integral(__buffer_ptr, __char_buffer + __buffer_size, __uval, __base);
|
|
_LIBCPP_ASSERT_INTERNAL(__res.__ec == std::errc(0), "to_chars: invalid maximum buffer size computed?");
|
|
|
|
// Make letters uppercase
|
|
if (__flags & ios_base::hex && __flags & ios_base::uppercase) {
|
|
for (; __buffer_ptr != __res.__ptr; ++__buffer_ptr)
|
|
*__buffer_ptr = std::__hex_to_upper(*__buffer_ptr);
|
|
}
|
|
|
|
char* __np = this->__identify_padding(__char_buffer, __res.__ptr, __iob);
|
|
// Stage 2 - Widen __nar while adding thousands separators
|
|
char_type __o[2 * (__buffer_size - 1) - 1];
|
|
char_type* __op; // pad here
|
|
char_type* __oe; // end of output
|
|
this->__widen_and_group_int(__char_buffer, __np, __res.__ptr, __o, __op, __oe, __iob.getloc());
|
|
// [__o, __oe) contains thousands_sep'd wide number
|
|
// Stage 3 & 4
|
|
return std::__pad_and_output(__s, __o, __op, __oe, __iob, __fl);
|
|
}
|
|
|
|
template <class _CharT, class _OutputIterator>
|
|
_OutputIterator
|
|
num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, char_type __fl, long __v) const {
|
|
return this->__do_put_integral(__s, __iob, __fl, __v);
|
|
}
|
|
|
|
template <class _CharT, class _OutputIterator>
|
|
_OutputIterator
|
|
num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, char_type __fl, long long __v) const {
|
|
return this->__do_put_integral(__s, __iob, __fl, __v);
|
|
}
|
|
|
|
template <class _CharT, class _OutputIterator>
|
|
_OutputIterator
|
|
num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, char_type __fl, unsigned long __v) const {
|
|
return this->__do_put_integral(__s, __iob, __fl, __v);
|
|
}
|
|
|
|
template <class _CharT, class _OutputIterator>
|
|
_OutputIterator
|
|
num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, char_type __fl, unsigned long long __v) const {
|
|
return this->__do_put_integral(__s, __iob, __fl, __v);
|
|
}
|
|
|
|
template <class _CharT, class _OutputIterator>
|
|
template <class _Float>
|
|
_LIBCPP_HIDE_FROM_ABI inline _OutputIterator num_put<_CharT, _OutputIterator>::__do_put_floating_point(
|
|
iter_type __s, ios_base& __iob, char_type __fl, _Float __v, char const* __len) const {
|
|
// Stage 1 - Get number in narrow char
|
|
char __fmt[8] = {'%', 0};
|
|
bool __specify_precision = this->__format_float(__fmt + 1, __len, __iob.flags());
|
|
const unsigned __nbuf = 30;
|
|
char __nar[__nbuf];
|
|
char* __nb = __nar;
|
|
int __nc;
|
|
_LIBCPP_DIAGNOSTIC_PUSH
|
|
_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wformat-nonliteral")
|
|
_LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wformat-nonliteral")
|
|
if (__specify_precision)
|
|
__nc = __locale::__snprintf(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v);
|
|
else
|
|
__nc = __locale::__snprintf(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, __v);
|
|
unique_ptr<char, void (*)(void*)> __nbh(nullptr, free);
|
|
if (__nc > static_cast<int>(__nbuf - 1)) {
|
|
if (__specify_precision)
|
|
__nc = __locale::__asprintf(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v);
|
|
else
|
|
__nc = __locale::__asprintf(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, __v);
|
|
if (__nc == -1)
|
|
std::__throw_bad_alloc();
|
|
__nbh.reset(__nb);
|
|
}
|
|
_LIBCPP_DIAGNOSTIC_POP
|
|
char* __ne = __nb + __nc;
|
|
char* __np = this->__identify_padding(__nb, __ne, __iob);
|
|
// Stage 2 - Widen __nar while adding thousands separators
|
|
char_type __o[2 * (__nbuf - 1) - 1];
|
|
char_type* __ob = __o;
|
|
unique_ptr<char_type, void (*)(void*)> __obh(0, free);
|
|
if (__nb != __nar) {
|
|
__ob = (char_type*)malloc(2 * static_cast<size_t>(__nc) * sizeof(char_type));
|
|
if (__ob == 0)
|
|
std::__throw_bad_alloc();
|
|
__obh.reset(__ob);
|
|
}
|
|
char_type* __op; // pad here
|
|
char_type* __oe; // end of output
|
|
this->__widen_and_group_float(__nb, __np, __ne, __ob, __op, __oe, __iob.getloc());
|
|
// [__o, __oe) contains thousands_sep'd wide number
|
|
// Stage 3 & 4
|
|
__s = std::__pad_and_output(__s, __ob, __op, __oe, __iob, __fl);
|
|
return __s;
|
|
}
|
|
|
|
template <class _CharT, class _OutputIterator>
|
|
_OutputIterator
|
|
num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, char_type __fl, double __v) const {
|
|
return this->__do_put_floating_point(__s, __iob, __fl, __v, "");
|
|
}
|
|
|
|
template <class _CharT, class _OutputIterator>
|
|
_OutputIterator
|
|
num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, char_type __fl, long double __v) const {
|
|
return this->__do_put_floating_point(__s, __iob, __fl, __v, "L");
|
|
}
|
|
|
|
template <class _CharT, class _OutputIterator>
|
|
_OutputIterator
|
|
num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, char_type __fl, const void* __v) const {
|
|
auto __flags = __iob.flags();
|
|
__iob.flags((__flags & ~ios_base::basefield & ~ios_base::uppercase) | ios_base::hex | ios_base::showbase);
|
|
auto __res = __do_put_integral(__s, __iob, __fl, reinterpret_cast<uintptr_t>(__v));
|
|
__iob.flags(__flags);
|
|
return __res;
|
|
}
|
|
|
|
extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS num_put<char>;
|
|
# if _LIBCPP_HAS_WIDE_CHARACTERS
|
|
extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS num_put<wchar_t>;
|
|
# endif
|
|
|
|
_LIBCPP_END_NAMESPACE_STD
|
|
|
|
_LIBCPP_POP_MACROS
|
|
|
|
// NOLINTEND(libcpp-robust-against-adl)
|
|
|
|
#endif // _LIBCPP_HAS_LOCALIZATION
|
|
|
|
#endif // _LIBCPP___LOCALE_DIR_NUM_H
|