[libc++] Granularize <locale> (#146650)

This commit is contained in:
Nikolas Klauser
2025-07-05 18:11:58 +02:00
committed by GitHub
parent 1121d64ba9
commit ca697096aa
43 changed files with 3864 additions and 3532 deletions

View File

@@ -511,13 +511,19 @@ set(files
__iterator/unreachable_sentinel.h
__iterator/wrap_iter.h
__locale
__locale_dir/check_grouping.h
__locale_dir/get_c_locale.h
__locale_dir/locale_base_api.h
__locale_dir/locale_base_api/android.h
__locale_dir/locale_base_api/bsd_locale_fallbacks.h
__locale_dir/locale_base_api/ibm.h
__locale_dir/locale_base_api/musl.h
__locale_dir/locale_base_api/openbsd.h
__locale_dir/messages.h
__locale_dir/money.h
__locale_dir/num.h
__locale_dir/pad_and_output.h
__locale_dir/scan_keyword.h
__locale_dir/support/apple.h
__locale_dir/support/bsd_like.h
__locale_dir/support/freebsd.h
@@ -526,6 +532,9 @@ set(files
__locale_dir/support/no_locale/characters.h
__locale_dir/support/no_locale/strtonum.h
__locale_dir/support/windows.h
__locale_dir/time.h
__locale_dir/wbuffer_convert.h
__locale_dir/wstring_convert.h
__math/abs.h
__math/copysign.h
__math/error_functions.h

View File

@@ -50,12 +50,14 @@
# include <__format/formatter.h>
# include <__format/parser_std_format_spec.h>
# include <__format/write_escaped.h>
# include <__iterator/istreambuf_iterator.h>
# include <__iterator/ostreambuf_iterator.h>
# include <__locale_dir/time.h>
# include <__memory/addressof.h>
# include <__type_traits/is_specialization.h>
# include <cmath>
# include <ctime>
# include <limits>
# include <locale>
# include <sstream>
# include <string_view>

View File

@@ -29,7 +29,6 @@
#if _LIBCPP_HAS_LOCALIZATION
# include <iomanip> // for quoted
# include <locale>
#endif
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)

View File

@@ -13,14 +13,9 @@
#include <__algorithm/unwrap_iter.h>
#include <__config>
#include <__filesystem/path.h>
#include <__locale>
#include <string>
// Only required on Windows for __widen_from_utf8, and included conservatively
// because it requires support for localization.
#if defined(_LIBCPP_WIN32API)
# include <locale>
#endif
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif

View File

@@ -0,0 +1,31 @@
//===----------------------------------------------------------------------===//
//
// 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_CHECK_GROUPING_H
#define _LIBCPP___LOCALE_DIR_CHECK_GROUPING_H
#include <__config>
#include <__fwd/string.h>
#include <ios>
#if _LIBCPP_HAS_LOCALIZATION
# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
# endif
_LIBCPP_BEGIN_NAMESPACE_STD
_LIBCPP_EXPORTED_FROM_ABI void
__check_grouping(const string& __grouping, unsigned* __g, unsigned* __g_end, ios_base::iostate& __err);
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP_HAS_LOCALIZATION
#endif // _LIBCPP___LOCALE_DIR_CHECK_GROUPING_H

View File

@@ -0,0 +1,40 @@
//===----------------------------------------------------------------------===//
//
// 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_GET_C_LOCALE_H
#define _LIBCPP___LOCALE_DIR_GET_C_LOCALE_H
#include <__config>
#include <__locale_dir/locale_base_api.h>
#if _LIBCPP_HAS_LOCALIZATION
# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
# endif
_LIBCPP_BEGIN_NAMESPACE_STD
// FIXME: This should really be part of the locale base API
# if defined(__APPLE__) || defined(__FreeBSD__)
# define _LIBCPP_GET_C_LOCALE 0
# elif defined(__NetBSD__)
# define _LIBCPP_GET_C_LOCALE LC_C_LOCALE
# else
# define _LIBCPP_GET_C_LOCALE __cloc()
// Get the C locale object
_LIBCPP_EXPORTED_FROM_ABI __locale::__locale_t __cloc();
# define __cloc_defined
# endif
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP_HAS_LOCALIZATION
#endif // _LIBCPP___LOCALE_DIR_GET_C_LOCALE_H

View File

@@ -0,0 +1,143 @@
//===----------------------------------------------------------------------===//
//
// 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_MESSAGES_H
#define _LIBCPP___LOCALE_DIR_MESSAGES_H
#include <__config>
#include <__iterator/back_insert_iterator.h>
#include <__locale>
#include <string>
#if _LIBCPP_HAS_LOCALIZATION
# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
# endif
# if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
// Most unix variants have catopen. These are the specific ones that don't.
# if !defined(__BIONIC__) && !defined(_NEWLIB_VERSION) && !defined(__EMSCRIPTEN__)
# define _LIBCPP_HAS_CATOPEN 1
# include <nl_types.h>
# else
# define _LIBCPP_HAS_CATOPEN 0
# endif
# else
# define _LIBCPP_HAS_CATOPEN 0
# endif
_LIBCPP_BEGIN_NAMESPACE_STD
class _LIBCPP_EXPORTED_FROM_ABI messages_base {
public:
typedef intptr_t catalog;
_LIBCPP_HIDE_FROM_ABI messages_base() {}
};
template <class _CharT>
class messages : public locale::facet, public messages_base {
public:
typedef _CharT char_type;
typedef basic_string<_CharT> string_type;
_LIBCPP_HIDE_FROM_ABI explicit messages(size_t __refs = 0) : locale::facet(__refs) {}
_LIBCPP_HIDE_FROM_ABI catalog open(const basic_string<char>& __nm, const locale& __loc) const {
return do_open(__nm, __loc);
}
_LIBCPP_HIDE_FROM_ABI string_type get(catalog __c, int __set, int __msgid, const string_type& __dflt) const {
return do_get(__c, __set, __msgid, __dflt);
}
_LIBCPP_HIDE_FROM_ABI void close(catalog __c) const { do_close(__c); }
static locale::id id;
protected:
_LIBCPP_HIDE_FROM_ABI_VIRTUAL ~messages() override {}
virtual catalog do_open(const basic_string<char>&, const locale&) const;
virtual string_type do_get(catalog, int __set, int __msgid, const string_type& __dflt) const;
virtual void do_close(catalog) const;
};
template <class _CharT>
locale::id messages<_CharT>::id;
template <class _CharT>
typename messages<_CharT>::catalog messages<_CharT>::do_open(const basic_string<char>& __nm, const locale&) const {
# if _LIBCPP_HAS_CATOPEN
return (catalog)catopen(__nm.c_str(), NL_CAT_LOCALE);
# else // !_LIBCPP_HAS_CATOPEN
(void)__nm;
return -1;
# endif // _LIBCPP_HAS_CATOPEN
}
template <class _CharT>
typename messages<_CharT>::string_type
messages<_CharT>::do_get(catalog __c, int __set, int __msgid, const string_type& __dflt) const {
# if _LIBCPP_HAS_CATOPEN
string __ndflt;
__narrow_to_utf8<sizeof(char_type) * __CHAR_BIT__>()(
std::back_inserter(__ndflt), __dflt.c_str(), __dflt.c_str() + __dflt.size());
nl_catd __cat = (nl_catd)__c;
static_assert(sizeof(catalog) >= sizeof(nl_catd), "Unexpected nl_catd type");
char* __n = catgets(__cat, __set, __msgid, __ndflt.c_str());
string_type __w;
__widen_from_utf8<sizeof(char_type) * __CHAR_BIT__>()(std::back_inserter(__w), __n, __n + std::strlen(__n));
return __w;
# else // !_LIBCPP_HAS_CATOPEN
(void)__c;
(void)__set;
(void)__msgid;
return __dflt;
# endif // _LIBCPP_HAS_CATOPEN
}
template <class _CharT>
void messages<_CharT>::do_close(catalog __c) const {
# if _LIBCPP_HAS_CATOPEN
catclose((nl_catd)__c);
# else // !_LIBCPP_HAS_CATOPEN
(void)__c;
# endif // _LIBCPP_HAS_CATOPEN
}
extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS messages<char>;
# if _LIBCPP_HAS_WIDE_CHARACTERS
extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS messages<wchar_t>;
# endif
template <class _CharT>
class messages_byname : public messages<_CharT> {
public:
typedef messages_base::catalog catalog;
typedef basic_string<_CharT> string_type;
_LIBCPP_HIDE_FROM_ABI explicit messages_byname(const char*, size_t __refs = 0) : messages<_CharT>(__refs) {}
_LIBCPP_HIDE_FROM_ABI explicit messages_byname(const string&, size_t __refs = 0) : messages<_CharT>(__refs) {}
protected:
_LIBCPP_HIDE_FROM_ABI_VIRTUAL ~messages_byname() override {}
};
extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS messages_byname<char>;
# if _LIBCPP_HAS_WIDE_CHARACTERS
extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS messages_byname<wchar_t>;
# endif
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP_HAS_LOCALIZATION
#endif // _LIBCPP___LOCALE_DIR_MESSAGES_H

View File

@@ -0,0 +1,873 @@
//===----------------------------------------------------------------------===//
//
// 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_MONEY_H
#define _LIBCPP___LOCALE_DIR_MONEY_H
#include <__algorithm/copy.h>
#include <__algorithm/equal.h>
#include <__algorithm/find.h>
#include <__algorithm/reverse.h>
#include <__config>
#include <__locale>
#include <__locale_dir/check_grouping.h>
#include <__locale_dir/get_c_locale.h>
#include <__locale_dir/pad_and_output.h>
#include <__memory/unique_ptr.h>
#include <ios>
#include <string>
#if _LIBCPP_HAS_LOCALIZATION
# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
# endif
_LIBCPP_PUSH_MACROS
# include <__undef_macros>
_LIBCPP_BEGIN_NAMESPACE_STD
// money_base
class _LIBCPP_EXPORTED_FROM_ABI money_base {
public:
enum part { none, space, symbol, sign, value };
struct pattern {
char field[4];
};
_LIBCPP_HIDE_FROM_ABI money_base() {}
};
// moneypunct
template <class _CharT, bool _International = false>
class moneypunct : public locale::facet, public money_base {
public:
typedef _CharT char_type;
typedef basic_string<char_type> string_type;
_LIBCPP_HIDE_FROM_ABI explicit moneypunct(size_t __refs = 0) : locale::facet(__refs) {}
_LIBCPP_HIDE_FROM_ABI char_type decimal_point() const { return do_decimal_point(); }
_LIBCPP_HIDE_FROM_ABI char_type thousands_sep() const { return do_thousands_sep(); }
_LIBCPP_HIDE_FROM_ABI string grouping() const { return do_grouping(); }
_LIBCPP_HIDE_FROM_ABI string_type curr_symbol() const { return do_curr_symbol(); }
_LIBCPP_HIDE_FROM_ABI string_type positive_sign() const { return do_positive_sign(); }
_LIBCPP_HIDE_FROM_ABI string_type negative_sign() const { return do_negative_sign(); }
_LIBCPP_HIDE_FROM_ABI int frac_digits() const { return do_frac_digits(); }
_LIBCPP_HIDE_FROM_ABI pattern pos_format() const { return do_pos_format(); }
_LIBCPP_HIDE_FROM_ABI pattern neg_format() const { return do_neg_format(); }
static locale::id id;
static const bool intl = _International;
protected:
_LIBCPP_HIDE_FROM_ABI_VIRTUAL ~moneypunct() override {}
virtual char_type do_decimal_point() const { return numeric_limits<char_type>::max(); }
virtual char_type do_thousands_sep() const { return numeric_limits<char_type>::max(); }
virtual string do_grouping() const { return string(); }
virtual string_type do_curr_symbol() const { return string_type(); }
virtual string_type do_positive_sign() const { return string_type(); }
virtual string_type do_negative_sign() const { return string_type(1, '-'); }
virtual int do_frac_digits() const { return 0; }
virtual pattern do_pos_format() const {
pattern __p = {{symbol, sign, none, value}};
return __p;
}
virtual pattern do_neg_format() const {
pattern __p = {{symbol, sign, none, value}};
return __p;
}
};
template <class _CharT, bool _International>
locale::id moneypunct<_CharT, _International>::id;
template <class _CharT, bool _International>
const bool moneypunct<_CharT, _International>::intl;
extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct<char, false>;
extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct<char, true>;
# if _LIBCPP_HAS_WIDE_CHARACTERS
extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct<wchar_t, false>;
extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct<wchar_t, true>;
# endif
// moneypunct_byname
template <class _CharT, bool _International = false>
class moneypunct_byname : public moneypunct<_CharT, _International> {
public:
typedef money_base::pattern pattern;
typedef _CharT char_type;
typedef basic_string<char_type> string_type;
_LIBCPP_HIDE_FROM_ABI explicit moneypunct_byname(const char* __nm, size_t __refs = 0)
: moneypunct<_CharT, _International>(__refs) {
init(__nm);
}
_LIBCPP_HIDE_FROM_ABI explicit moneypunct_byname(const string& __nm, size_t __refs = 0)
: moneypunct<_CharT, _International>(__refs) {
init(__nm.c_str());
}
protected:
_LIBCPP_HIDE_FROM_ABI_VIRTUAL ~moneypunct_byname() override {}
char_type do_decimal_point() const override { return __decimal_point_; }
char_type do_thousands_sep() const override { return __thousands_sep_; }
string do_grouping() const override { return __grouping_; }
string_type do_curr_symbol() const override { return __curr_symbol_; }
string_type do_positive_sign() const override { return __positive_sign_; }
string_type do_negative_sign() const override { return __negative_sign_; }
int do_frac_digits() const override { return __frac_digits_; }
pattern do_pos_format() const override { return __pos_format_; }
pattern do_neg_format() const override { return __neg_format_; }
private:
char_type __decimal_point_;
char_type __thousands_sep_;
string __grouping_;
string_type __curr_symbol_;
string_type __positive_sign_;
string_type __negative_sign_;
int __frac_digits_;
pattern __pos_format_;
pattern __neg_format_;
void init(const char*);
};
template <>
_LIBCPP_EXPORTED_FROM_ABI void moneypunct_byname<char, false>::init(const char*);
template <>
_LIBCPP_EXPORTED_FROM_ABI void moneypunct_byname<char, true>::init(const char*);
extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct_byname<char, false>;
extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct_byname<char, true>;
# if _LIBCPP_HAS_WIDE_CHARACTERS
template <>
_LIBCPP_EXPORTED_FROM_ABI void moneypunct_byname<wchar_t, false>::init(const char*);
template <>
_LIBCPP_EXPORTED_FROM_ABI void moneypunct_byname<wchar_t, true>::init(const char*);
extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct_byname<wchar_t, false>;
extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct_byname<wchar_t, true>;
# endif
// money_get
template <class _CharT>
class __money_get {
protected:
typedef _CharT char_type;
typedef basic_string<char_type> string_type;
_LIBCPP_HIDE_FROM_ABI __money_get() {}
static void __gather_info(
bool __intl,
const locale& __loc,
money_base::pattern& __pat,
char_type& __dp,
char_type& __ts,
string& __grp,
string_type& __sym,
string_type& __psn,
string_type& __nsn,
int& __fd);
};
template <class _CharT>
void __money_get<_CharT>::__gather_info(
bool __intl,
const locale& __loc,
money_base::pattern& __pat,
char_type& __dp,
char_type& __ts,
string& __grp,
string_type& __sym,
string_type& __psn,
string_type& __nsn,
int& __fd) {
if (__intl) {
const moneypunct<char_type, true>& __mp = std::use_facet<moneypunct<char_type, true> >(__loc);
__pat = __mp.neg_format();
__nsn = __mp.negative_sign();
__psn = __mp.positive_sign();
__dp = __mp.decimal_point();
__ts = __mp.thousands_sep();
__grp = __mp.grouping();
__sym = __mp.curr_symbol();
__fd = __mp.frac_digits();
} else {
const moneypunct<char_type, false>& __mp = std::use_facet<moneypunct<char_type, false> >(__loc);
__pat = __mp.neg_format();
__nsn = __mp.negative_sign();
__psn = __mp.positive_sign();
__dp = __mp.decimal_point();
__ts = __mp.thousands_sep();
__grp = __mp.grouping();
__sym = __mp.curr_symbol();
__fd = __mp.frac_digits();
}
}
extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __money_get<char>;
# if _LIBCPP_HAS_WIDE_CHARACTERS
extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __money_get<wchar_t>;
# endif
template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> >
class money_get : public locale::facet, private __money_get<_CharT> {
public:
typedef _CharT char_type;
typedef _InputIterator iter_type;
typedef basic_string<char_type> string_type;
_LIBCPP_HIDE_FROM_ABI explicit money_get(size_t __refs = 0) : locale::facet(__refs) {}
_LIBCPP_HIDE_FROM_ABI iter_type
get(iter_type __b, iter_type __e, bool __intl, ios_base& __iob, ios_base::iostate& __err, long double& __v) const {
return do_get(__b, __e, __intl, __iob, __err, __v);
}
_LIBCPP_HIDE_FROM_ABI iter_type
get(iter_type __b, iter_type __e, bool __intl, ios_base& __iob, ios_base::iostate& __err, string_type& __v) const {
return do_get(__b, __e, __intl, __iob, __err, __v);
}
static locale::id id;
protected:
_LIBCPP_HIDE_FROM_ABI_VIRTUAL ~money_get() override {}
virtual iter_type
do_get(iter_type __b, iter_type __e, bool __intl, ios_base& __iob, ios_base::iostate& __err, long double& __v) const;
virtual iter_type
do_get(iter_type __b, iter_type __e, bool __intl, ios_base& __iob, ios_base::iostate& __err, string_type& __v) const;
private:
static bool __do_get(
iter_type& __b,
iter_type __e,
bool __intl,
const locale& __loc,
ios_base::fmtflags __flags,
ios_base::iostate& __err,
bool& __neg,
const ctype<char_type>& __ct,
unique_ptr<char_type, void (*)(void*)>& __wb,
char_type*& __wn,
char_type* __we);
};
template <class _CharT, class _InputIterator>
locale::id money_get<_CharT, _InputIterator>::id;
_LIBCPP_EXPORTED_FROM_ABI void __do_nothing(void*);
template <class _Tp>
_LIBCPP_HIDE_FROM_ABI void __double_or_nothing(unique_ptr<_Tp, void (*)(void*)>& __b, _Tp*& __n, _Tp*& __e) {
bool __owns = __b.get_deleter() != __do_nothing;
size_t __cur_cap = static_cast<size_t>(__e - __b.get()) * sizeof(_Tp);
size_t __new_cap = __cur_cap < numeric_limits<size_t>::max() / 2 ? 2 * __cur_cap : numeric_limits<size_t>::max();
if (__new_cap == 0)
__new_cap = sizeof(_Tp);
size_t __n_off = static_cast<size_t>(__n - __b.get());
_Tp* __t = (_Tp*)std::realloc(__owns ? __b.get() : 0, __new_cap);
if (__t == 0)
std::__throw_bad_alloc();
if (__owns)
__b.release();
else
std::memcpy(__t, __b.get(), __cur_cap);
__b = unique_ptr<_Tp, void (*)(void*)>(__t, free);
__new_cap /= sizeof(_Tp);
__n = __b.get() + __n_off;
__e = __b.get() + __new_cap;
}
// true == success
template <class _CharT, class _InputIterator>
bool money_get<_CharT, _InputIterator>::__do_get(
iter_type& __b,
iter_type __e,
bool __intl,
const locale& __loc,
ios_base::fmtflags __flags,
ios_base::iostate& __err,
bool& __neg,
const ctype<char_type>& __ct,
unique_ptr<char_type, void (*)(void*)>& __wb,
char_type*& __wn,
char_type* __we) {
if (__b == __e) {
__err |= ios_base::failbit;
return false;
}
const unsigned __bz = 100;
unsigned __gbuf[__bz];
unique_ptr<unsigned, void (*)(void*)> __gb(__gbuf, __do_nothing);
unsigned* __gn = __gb.get();
unsigned* __ge = __gn + __bz;
money_base::pattern __pat;
char_type __dp;
char_type __ts;
string __grp;
string_type __sym;
string_type __psn;
string_type __nsn;
// Capture the spaces read into money_base::{space,none} so they
// can be compared to initial spaces in __sym.
string_type __spaces;
int __fd;
__money_get<_CharT>::__gather_info(__intl, __loc, __pat, __dp, __ts, __grp, __sym, __psn, __nsn, __fd);
const string_type* __trailing_sign = 0;
__wn = __wb.get();
for (unsigned __p = 0; __p < 4 && __b != __e; ++__p) {
switch (__pat.field[__p]) {
case money_base::space:
if (__p != 3) {
if (__ct.is(ctype_base::space, *__b))
__spaces.push_back(*__b++);
else {
__err |= ios_base::failbit;
return false;
}
}
[[__fallthrough__]];
case money_base::none:
if (__p != 3) {
while (__b != __e && __ct.is(ctype_base::space, *__b))
__spaces.push_back(*__b++);
}
break;
case money_base::sign:
if (__psn.size() > 0 && *__b == __psn[0]) {
++__b;
__neg = false;
if (__psn.size() > 1)
__trailing_sign = std::addressof(__psn);
break;
}
if (__nsn.size() > 0 && *__b == __nsn[0]) {
++__b;
__neg = true;
if (__nsn.size() > 1)
__trailing_sign = std::addressof(__nsn);
break;
}
if (__psn.size() > 0 && __nsn.size() > 0) { // sign is required
__err |= ios_base::failbit;
return false;
}
if (__psn.size() == 0 && __nsn.size() == 0)
// locale has no way of specifying a sign. Use the initial value of __neg as a default
break;
__neg = (__nsn.size() == 0);
break;
case money_base::symbol: {
bool __more_needed =
__trailing_sign || (__p < 2) || (__p == 2 && __pat.field[3] != static_cast<char>(money_base::none));
bool __sb = (__flags & ios_base::showbase) != 0;
if (__sb || __more_needed) {
typename string_type::const_iterator __sym_space_end = __sym.begin();
if (__p > 0 && (__pat.field[__p - 1] == money_base::none || __pat.field[__p - 1] == money_base::space)) {
// Match spaces we've already read against spaces at
// the beginning of __sym.
while (__sym_space_end != __sym.end() && __ct.is(ctype_base::space, *__sym_space_end))
++__sym_space_end;
const size_t __num_spaces = __sym_space_end - __sym.begin();
if (__num_spaces > __spaces.size() ||
!std::equal(__spaces.end() - __num_spaces, __spaces.end(), __sym.begin())) {
// No match. Put __sym_space_end back at the
// beginning of __sym, which will prevent a
// match in the next loop.
__sym_space_end = __sym.begin();
}
}
typename string_type::const_iterator __sym_curr_char = __sym_space_end;
while (__sym_curr_char != __sym.end() && __b != __e && *__b == *__sym_curr_char) {
++__b;
++__sym_curr_char;
}
if (__sb && __sym_curr_char != __sym.end()) {
__err |= ios_base::failbit;
return false;
}
}
} break;
case money_base::value: {
unsigned __ng = 0;
for (; __b != __e; ++__b) {
char_type __c = *__b;
if (__ct.is(ctype_base::digit, __c)) {
if (__wn == __we)
std::__double_or_nothing(__wb, __wn, __we);
*__wn++ = __c;
++__ng;
} else if (__grp.size() > 0 && __ng > 0 && __c == __ts) {
if (__gn == __ge)
std::__double_or_nothing(__gb, __gn, __ge);
*__gn++ = __ng;
__ng = 0;
} else
break;
}
if (__gb.get() != __gn && __ng > 0) {
if (__gn == __ge)
std::__double_or_nothing(__gb, __gn, __ge);
*__gn++ = __ng;
}
if (__fd > 0) {
if (__b == __e || *__b != __dp) {
__err |= ios_base::failbit;
return false;
}
for (++__b; __fd > 0; --__fd, ++__b) {
if (__b == __e || !__ct.is(ctype_base::digit, *__b)) {
__err |= ios_base::failbit;
return false;
}
if (__wn == __we)
std::__double_or_nothing(__wb, __wn, __we);
*__wn++ = *__b;
}
}
if (__wn == __wb.get()) {
__err |= ios_base::failbit;
return false;
}
} break;
}
}
if (__trailing_sign) {
for (unsigned __i = 1; __i < __trailing_sign->size(); ++__i, ++__b) {
if (__b == __e || *__b != (*__trailing_sign)[__i]) {
__err |= ios_base::failbit;
return false;
}
}
}
if (__gb.get() != __gn) {
ios_base::iostate __et = ios_base::goodbit;
__check_grouping(__grp, __gb.get(), __gn, __et);
if (__et) {
__err |= ios_base::failbit;
return false;
}
}
return true;
}
template <class _CharT, class _InputIterator>
_InputIterator money_get<_CharT, _InputIterator>::do_get(
iter_type __b, iter_type __e, bool __intl, ios_base& __iob, ios_base::iostate& __err, long double& __v) const {
const int __bz = 100;
char_type __wbuf[__bz];
unique_ptr<char_type, void (*)(void*)> __wb(__wbuf, __do_nothing);
char_type* __wn;
char_type* __we = __wbuf + __bz;
locale __loc = __iob.getloc();
const ctype<char_type>& __ct = std::use_facet<ctype<char_type> >(__loc);
bool __neg = false;
if (__do_get(__b, __e, __intl, __loc, __iob.flags(), __err, __neg, __ct, __wb, __wn, __we)) {
const char __src[] = "0123456789";
char_type __atoms[sizeof(__src) - 1];
__ct.widen(__src, __src + (sizeof(__src) - 1), __atoms);
char __nbuf[__bz];
char* __nc = __nbuf;
const char* __nc_in = __nc;
unique_ptr<char, void (*)(void*)> __h(nullptr, free);
if (__wn - __wb.get() > __bz - 2) {
__h.reset((char*)malloc(static_cast<size_t>(__wn - __wb.get() + 2)));
if (__h.get() == nullptr)
std::__throw_bad_alloc();
__nc = __h.get();
__nc_in = __nc;
}
if (__neg)
*__nc++ = '-';
for (const char_type* __w = __wb.get(); __w < __wn; ++__w, ++__nc)
*__nc = __src[std::find(__atoms, std::end(__atoms), *__w) - __atoms];
*__nc = char();
if (sscanf(__nc_in, "%Lf", &__v) != 1)
std::__throw_runtime_error("money_get error");
}
if (__b == __e)
__err |= ios_base::eofbit;
return __b;
}
template <class _CharT, class _InputIterator>
_InputIterator money_get<_CharT, _InputIterator>::do_get(
iter_type __b, iter_type __e, bool __intl, ios_base& __iob, ios_base::iostate& __err, string_type& __v) const {
const int __bz = 100;
char_type __wbuf[__bz];
unique_ptr<char_type, void (*)(void*)> __wb(__wbuf, __do_nothing);
char_type* __wn;
char_type* __we = __wbuf + __bz;
locale __loc = __iob.getloc();
const ctype<char_type>& __ct = std::use_facet<ctype<char_type> >(__loc);
bool __neg = false;
if (__do_get(__b, __e, __intl, __loc, __iob.flags(), __err, __neg, __ct, __wb, __wn, __we)) {
__v.clear();
if (__neg)
__v.push_back(__ct.widen('-'));
char_type __z = __ct.widen('0');
char_type* __w;
for (__w = __wb.get(); __w < __wn - 1; ++__w)
if (*__w != __z)
break;
__v.append(__w, __wn);
}
if (__b == __e)
__err |= ios_base::eofbit;
return __b;
}
extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS money_get<char>;
# if _LIBCPP_HAS_WIDE_CHARACTERS
extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS money_get<wchar_t>;
# endif
// money_put
template <class _CharT>
class __money_put {
protected:
typedef _CharT char_type;
typedef basic_string<char_type> string_type;
_LIBCPP_HIDE_FROM_ABI __money_put() {}
static void __gather_info(
bool __intl,
bool __neg,
const locale& __loc,
money_base::pattern& __pat,
char_type& __dp,
char_type& __ts,
string& __grp,
string_type& __sym,
string_type& __sn,
int& __fd);
static void __format(
char_type* __mb,
char_type*& __mi,
char_type*& __me,
ios_base::fmtflags __flags,
const char_type* __db,
const char_type* __de,
const ctype<char_type>& __ct,
bool __neg,
const money_base::pattern& __pat,
char_type __dp,
char_type __ts,
const string& __grp,
const string_type& __sym,
const string_type& __sn,
int __fd);
};
template <class _CharT>
void __money_put<_CharT>::__gather_info(
bool __intl,
bool __neg,
const locale& __loc,
money_base::pattern& __pat,
char_type& __dp,
char_type& __ts,
string& __grp,
string_type& __sym,
string_type& __sn,
int& __fd) {
if (__intl) {
const moneypunct<char_type, true>& __mp = std::use_facet<moneypunct<char_type, true> >(__loc);
if (__neg) {
__pat = __mp.neg_format();
__sn = __mp.negative_sign();
} else {
__pat = __mp.pos_format();
__sn = __mp.positive_sign();
}
__dp = __mp.decimal_point();
__ts = __mp.thousands_sep();
__grp = __mp.grouping();
__sym = __mp.curr_symbol();
__fd = __mp.frac_digits();
} else {
const moneypunct<char_type, false>& __mp = std::use_facet<moneypunct<char_type, false> >(__loc);
if (__neg) {
__pat = __mp.neg_format();
__sn = __mp.negative_sign();
} else {
__pat = __mp.pos_format();
__sn = __mp.positive_sign();
}
__dp = __mp.decimal_point();
__ts = __mp.thousands_sep();
__grp = __mp.grouping();
__sym = __mp.curr_symbol();
__fd = __mp.frac_digits();
}
}
template <class _CharT>
void __money_put<_CharT>::__format(
char_type* __mb,
char_type*& __mi,
char_type*& __me,
ios_base::fmtflags __flags,
const char_type* __db,
const char_type* __de,
const ctype<char_type>& __ct,
bool __neg,
const money_base::pattern& __pat,
char_type __dp,
char_type __ts,
const string& __grp,
const string_type& __sym,
const string_type& __sn,
int __fd) {
__me = __mb;
for (char __p : __pat.field) {
switch (__p) {
case money_base::none:
__mi = __me;
break;
case money_base::space:
__mi = __me;
*__me++ = __ct.widen(' ');
break;
case money_base::sign:
if (!__sn.empty())
*__me++ = __sn[0];
break;
case money_base::symbol:
if (!__sym.empty() && (__flags & ios_base::showbase))
__me = std::copy(__sym.begin(), __sym.end(), __me);
break;
case money_base::value: {
// remember start of value so we can reverse it
char_type* __t = __me;
// find beginning of digits
if (__neg)
++__db;
// find end of digits
const char_type* __d;
for (__d = __db; __d < __de; ++__d)
if (!__ct.is(ctype_base::digit, *__d))
break;
// print fractional part
if (__fd > 0) {
int __f;
for (__f = __fd; __d > __db && __f > 0; --__f)
*__me++ = *--__d;
char_type __z = __f > 0 ? __ct.widen('0') : char_type();
for (; __f > 0; --__f)
*__me++ = __z;
*__me++ = __dp;
}
// print units part
if (__d == __db) {
*__me++ = __ct.widen('0');
} else {
unsigned __ng = 0;
unsigned __ig = 0;
unsigned __gl = __grp.empty() ? numeric_limits<unsigned>::max() : static_cast<unsigned>(__grp[__ig]);
while (__d != __db) {
if (__ng == __gl) {
*__me++ = __ts;
__ng = 0;
if (++__ig < __grp.size())
__gl = __grp[__ig] == numeric_limits<char>::max()
? numeric_limits<unsigned>::max()
: static_cast<unsigned>(__grp[__ig]);
}
*__me++ = *--__d;
++__ng;
}
}
// reverse it
std::reverse(__t, __me);
} break;
}
}
// print rest of sign, if any
if (__sn.size() > 1)
__me = std::copy(__sn.begin() + 1, __sn.end(), __me);
// set alignment
if ((__flags & ios_base::adjustfield) == ios_base::left)
__mi = __me;
else if ((__flags & ios_base::adjustfield) != ios_base::internal)
__mi = __mb;
}
extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __money_put<char>;
# if _LIBCPP_HAS_WIDE_CHARACTERS
extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __money_put<wchar_t>;
# endif
template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> >
class money_put : public locale::facet, private __money_put<_CharT> {
public:
typedef _CharT char_type;
typedef _OutputIterator iter_type;
typedef basic_string<char_type> string_type;
_LIBCPP_HIDE_FROM_ABI explicit money_put(size_t __refs = 0) : locale::facet(__refs) {}
_LIBCPP_HIDE_FROM_ABI iter_type
put(iter_type __s, bool __intl, ios_base& __iob, char_type __fl, long double __units) const {
return do_put(__s, __intl, __iob, __fl, __units);
}
_LIBCPP_HIDE_FROM_ABI iter_type
put(iter_type __s, bool __intl, ios_base& __iob, char_type __fl, const string_type& __digits) const {
return do_put(__s, __intl, __iob, __fl, __digits);
}
static locale::id id;
protected:
_LIBCPP_HIDE_FROM_ABI_VIRTUAL ~money_put() override {}
virtual iter_type do_put(iter_type __s, bool __intl, ios_base& __iob, char_type __fl, long double __units) const;
virtual iter_type
do_put(iter_type __s, bool __intl, ios_base& __iob, char_type __fl, const string_type& __digits) const;
};
template <class _CharT, class _OutputIterator>
locale::id money_put<_CharT, _OutputIterator>::id;
template <class _CharT, class _OutputIterator>
_OutputIterator money_put<_CharT, _OutputIterator>::do_put(
iter_type __s, bool __intl, ios_base& __iob, char_type __fl, long double __units) const {
// convert to char
const size_t __bs = 100;
char __buf[__bs];
char* __bb = __buf;
char_type __digits[__bs];
char_type* __db = __digits;
int __n = snprintf(__bb, __bs, "%.0Lf", __units);
unique_ptr<char, void (*)(void*)> __hn(nullptr, free);
unique_ptr<char_type, void (*)(void*)> __hd(0, free);
// secure memory for digit storage
if (static_cast<size_t>(__n) > __bs - 1) {
__n = __locale::__asprintf(&__bb, _LIBCPP_GET_C_LOCALE, "%.0Lf", __units);
if (__n == -1)
std::__throw_bad_alloc();
__hn.reset(__bb);
__hd.reset((char_type*)malloc(static_cast<size_t>(__n) * sizeof(char_type)));
if (__hd == nullptr)
std::__throw_bad_alloc();
__db = __hd.get();
}
// gather info
locale __loc = __iob.getloc();
const ctype<char_type>& __ct = std::use_facet<ctype<char_type> >(__loc);
__ct.widen(__bb, __bb + __n, __db);
bool __neg = __n > 0 && __bb[0] == '-';
money_base::pattern __pat;
char_type __dp;
char_type __ts;
string __grp;
string_type __sym;
string_type __sn;
int __fd;
this->__gather_info(__intl, __neg, __loc, __pat, __dp, __ts, __grp, __sym, __sn, __fd);
// secure memory for formatting
char_type __mbuf[__bs];
char_type* __mb = __mbuf;
unique_ptr<char_type, void (*)(void*)> __hw(0, free);
size_t __exn = __n > __fd ? (static_cast<size_t>(__n) - static_cast<size_t>(__fd)) * 2 + __sn.size() + __sym.size() +
static_cast<size_t>(__fd) + 1
: __sn.size() + __sym.size() + static_cast<size_t>(__fd) + 2;
if (__exn > __bs) {
__hw.reset((char_type*)malloc(__exn * sizeof(char_type)));
__mb = __hw.get();
if (__mb == 0)
std::__throw_bad_alloc();
}
// format
char_type* __mi;
char_type* __me;
this->__format(
__mb, __mi, __me, __iob.flags(), __db, __db + __n, __ct, __neg, __pat, __dp, __ts, __grp, __sym, __sn, __fd);
return std::__pad_and_output(__s, __mb, __mi, __me, __iob, __fl);
}
template <class _CharT, class _OutputIterator>
_OutputIterator money_put<_CharT, _OutputIterator>::do_put(
iter_type __s, bool __intl, ios_base& __iob, char_type __fl, const string_type& __digits) const {
// gather info
locale __loc = __iob.getloc();
const ctype<char_type>& __ct = std::use_facet<ctype<char_type> >(__loc);
bool __neg = __digits.size() > 0 && __digits[0] == __ct.widen('-');
money_base::pattern __pat;
char_type __dp;
char_type __ts;
string __grp;
string_type __sym;
string_type __sn;
int __fd;
this->__gather_info(__intl, __neg, __loc, __pat, __dp, __ts, __grp, __sym, __sn, __fd);
// secure memory for formatting
char_type __mbuf[100];
char_type* __mb = __mbuf;
unique_ptr<char_type, void (*)(void*)> __h(0, free);
size_t __exn =
static_cast<int>(__digits.size()) > __fd
? (__digits.size() - static_cast<size_t>(__fd)) * 2 + __sn.size() + __sym.size() + static_cast<size_t>(__fd) +
1
: __sn.size() + __sym.size() + static_cast<size_t>(__fd) + 2;
if (__exn > 100) {
__h.reset((char_type*)malloc(__exn * sizeof(char_type)));
__mb = __h.get();
if (__mb == 0)
std::__throw_bad_alloc();
}
// format
char_type* __mi;
char_type* __me;
this->__format(
__mb,
__mi,
__me,
__iob.flags(),
__digits.data(),
__digits.data() + __digits.size(),
__ct,
__neg,
__pat,
__dp,
__ts,
__grp,
__sym,
__sn,
__fd);
return std::__pad_and_output(__s, __mb, __mi, __me, __iob, __fl);
}
extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS money_put<char>;
# if _LIBCPP_HAS_WIDE_CHARACTERS
extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS money_put<wchar_t>;
# endif
_LIBCPP_END_NAMESPACE_STD
_LIBCPP_POP_MACROS
#endif // _LIBCPP_HAS_LOCALIZATION
#endif // _LIBCPP___LOCALE_DIR_MONEY_H

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,143 @@
//===----------------------------------------------------------------------===//
//
// 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_SCAN_KEYWORD_H
#define _LIBCPP___LOCALE_DIR_SCAN_KEYWORD_H
#include <__config>
#include <__memory/unique_ptr.h>
#include <ios>
#if _LIBCPP_HAS_LOCALIZATION
# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
# endif
_LIBCPP_BEGIN_NAMESPACE_STD
// __scan_keyword
// Scans [__b, __e) until a match is found in the basic_strings range
// [__kb, __ke) or until it can be shown that there is no match in [__kb, __ke).
// __b will be incremented (visibly), consuming CharT until a match is found
// or proved to not exist. A keyword may be "", in which will match anything.
// If one keyword is a prefix of another, and the next CharT in the input
// might match another keyword, the algorithm will attempt to find the longest
// matching keyword. If the longer matching keyword ends up not matching, then
// no keyword match is found. If no keyword match is found, __ke is returned
// and failbit is set in __err.
// Else an iterator pointing to the matching keyword is found. If more than
// one keyword matches, an iterator to the first matching keyword is returned.
// If on exit __b == __e, eofbit is set in __err. If __case_sensitive is false,
// __ct is used to force to lower case before comparing characters.
// Examples:
// Keywords: "a", "abb"
// If the input is "a", the first keyword matches and eofbit is set.
// If the input is "abc", no match is found and "ab" are consumed.
template <class _InputIterator, class _ForwardIterator, class _Ctype>
_LIBCPP_HIDE_FROM_ABI _ForwardIterator __scan_keyword(
_InputIterator& __b,
_InputIterator __e,
_ForwardIterator __kb,
_ForwardIterator __ke,
const _Ctype& __ct,
ios_base::iostate& __err,
bool __case_sensitive = true) {
typedef typename iterator_traits<_InputIterator>::value_type _CharT;
size_t __nkw = static_cast<size_t>(std::distance(__kb, __ke));
const unsigned char __doesnt_match = '\0';
const unsigned char __might_match = '\1';
const unsigned char __does_match = '\2';
unsigned char __statbuf[100];
unsigned char* __status = __statbuf;
unique_ptr<unsigned char, void (*)(void*)> __stat_hold(nullptr, free);
if (__nkw > sizeof(__statbuf)) {
__status = (unsigned char*)malloc(__nkw);
if (__status == nullptr)
std::__throw_bad_alloc();
__stat_hold.reset(__status);
}
size_t __n_might_match = __nkw; // At this point, any keyword might match
size_t __n_does_match = 0; // but none of them definitely do
// Initialize all statuses to __might_match, except for "" keywords are __does_match
unsigned char* __st = __status;
for (_ForwardIterator __ky = __kb; __ky != __ke; ++__ky, (void)++__st) {
if (!__ky->empty())
*__st = __might_match;
else {
*__st = __does_match;
--__n_might_match;
++__n_does_match;
}
}
// While there might be a match, test keywords against the next CharT
for (size_t __indx = 0; __b != __e && __n_might_match > 0; ++__indx) {
// Peek at the next CharT but don't consume it
_CharT __c = *__b;
if (!__case_sensitive)
__c = __ct.toupper(__c);
bool __consume = false;
// For each keyword which might match, see if the __indx character is __c
// If a match if found, consume __c
// If a match is found, and that is the last character in the keyword,
// then that keyword matches.
// If the keyword doesn't match this character, then change the keyword
// to doesn't match
__st = __status;
for (_ForwardIterator __ky = __kb; __ky != __ke; ++__ky, (void)++__st) {
if (*__st == __might_match) {
_CharT __kc = (*__ky)[__indx];
if (!__case_sensitive)
__kc = __ct.toupper(__kc);
if (__c == __kc) {
__consume = true;
if (__ky->size() == __indx + 1) {
*__st = __does_match;
--__n_might_match;
++__n_does_match;
}
} else {
*__st = __doesnt_match;
--__n_might_match;
}
}
}
// consume if we matched a character
if (__consume) {
++__b;
// If we consumed a character and there might be a matched keyword that
// was marked matched on a previous iteration, then such keywords
// which are now marked as not matching.
if (__n_might_match + __n_does_match > 1) {
__st = __status;
for (_ForwardIterator __ky = __kb; __ky != __ke; ++__ky, (void)++__st) {
if (*__st == __does_match && __ky->size() != __indx + 1) {
*__st = __doesnt_match;
--__n_does_match;
}
}
}
}
}
// We've exited the loop because we hit eof and/or we have no more "might matches".
if (__b == __e)
__err |= ios_base::eofbit;
// Return the first matching result
for (__st = __status; __kb != __ke; ++__kb, (void)++__st)
if (*__st == __does_match)
break;
if (__kb == __ke)
__err |= ios_base::failbit;
return __kb;
}
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP_HAS_LOCALIZATION
#endif // _LIBCPP___LOCALE_DIR_SCAN_KEYWORD_H

View File

@@ -0,0 +1,766 @@
//===----------------------------------------------------------------------===//
//
// 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_TIME_H
#define _LIBCPP___LOCALE_DIR_TIME_H
#include <__algorithm/copy.h>
#include <__config>
#include <__locale_dir/get_c_locale.h>
#include <__locale_dir/scan_keyword.h>
#include <ios>
#if _LIBCPP_HAS_LOCALIZATION
# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
# endif
_LIBCPP_BEGIN_NAMESPACE_STD
template <class _CharT, class _InputIterator>
_LIBCPP_HIDE_FROM_ABI int __get_up_to_n_digits(
_InputIterator& __b, _InputIterator __e, ios_base::iostate& __err, const ctype<_CharT>& __ct, int __n) {
// Precondition: __n >= 1
if (__b == __e) {
__err |= ios_base::eofbit | ios_base::failbit;
return 0;
}
// get first digit
_CharT __c = *__b;
if (!__ct.is(ctype_base::digit, __c)) {
__err |= ios_base::failbit;
return 0;
}
int __r = __ct.narrow(__c, 0) - '0';
for (++__b, (void)--__n; __b != __e && __n > 0; ++__b, (void)--__n) {
// get next digit
__c = *__b;
if (!__ct.is(ctype_base::digit, __c))
return __r;
__r = __r * 10 + __ct.narrow(__c, 0) - '0';
}
if (__b == __e)
__err |= ios_base::eofbit;
return __r;
}
class _LIBCPP_EXPORTED_FROM_ABI time_base {
public:
enum dateorder { no_order, dmy, mdy, ymd, ydm };
};
template <class _CharT>
class __time_get_c_storage {
protected:
typedef basic_string<_CharT> string_type;
virtual const string_type* __weeks() const;
virtual const string_type* __months() const;
virtual const string_type* __am_pm() const;
virtual const string_type& __c() const;
virtual const string_type& __r() const;
virtual const string_type& __x() const;
virtual const string_type& __X() const;
_LIBCPP_HIDE_FROM_ABI ~__time_get_c_storage() {}
};
template <>
_LIBCPP_EXPORTED_FROM_ABI const string* __time_get_c_storage<char>::__weeks() const;
template <>
_LIBCPP_EXPORTED_FROM_ABI const string* __time_get_c_storage<char>::__months() const;
template <>
_LIBCPP_EXPORTED_FROM_ABI const string* __time_get_c_storage<char>::__am_pm() const;
template <>
_LIBCPP_EXPORTED_FROM_ABI const string& __time_get_c_storage<char>::__c() const;
template <>
_LIBCPP_EXPORTED_FROM_ABI const string& __time_get_c_storage<char>::__r() const;
template <>
_LIBCPP_EXPORTED_FROM_ABI const string& __time_get_c_storage<char>::__x() const;
template <>
_LIBCPP_EXPORTED_FROM_ABI const string& __time_get_c_storage<char>::__X() const;
# if _LIBCPP_HAS_WIDE_CHARACTERS
template <>
_LIBCPP_EXPORTED_FROM_ABI const wstring* __time_get_c_storage<wchar_t>::__weeks() const;
template <>
_LIBCPP_EXPORTED_FROM_ABI const wstring* __time_get_c_storage<wchar_t>::__months() const;
template <>
_LIBCPP_EXPORTED_FROM_ABI const wstring* __time_get_c_storage<wchar_t>::__am_pm() const;
template <>
_LIBCPP_EXPORTED_FROM_ABI const wstring& __time_get_c_storage<wchar_t>::__c() const;
template <>
_LIBCPP_EXPORTED_FROM_ABI const wstring& __time_get_c_storage<wchar_t>::__r() const;
template <>
_LIBCPP_EXPORTED_FROM_ABI const wstring& __time_get_c_storage<wchar_t>::__x() const;
template <>
_LIBCPP_EXPORTED_FROM_ABI const wstring& __time_get_c_storage<wchar_t>::__X() const;
# endif
template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> >
class time_get : public locale::facet, public time_base, private __time_get_c_storage<_CharT> {
public:
typedef _CharT char_type;
typedef _InputIterator iter_type;
typedef time_base::dateorder dateorder;
typedef basic_string<char_type> string_type;
_LIBCPP_HIDE_FROM_ABI explicit time_get(size_t __refs = 0) : locale::facet(__refs) {}
_LIBCPP_HIDE_FROM_ABI dateorder date_order() const { return this->do_date_order(); }
_LIBCPP_HIDE_FROM_ABI iter_type
get_time(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, tm* __tm) const {
return do_get_time(__b, __e, __iob, __err, __tm);
}
_LIBCPP_HIDE_FROM_ABI iter_type
get_date(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, tm* __tm) const {
return do_get_date(__b, __e, __iob, __err, __tm);
}
_LIBCPP_HIDE_FROM_ABI iter_type
get_weekday(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, tm* __tm) const {
return do_get_weekday(__b, __e, __iob, __err, __tm);
}
_LIBCPP_HIDE_FROM_ABI iter_type
get_monthname(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, tm* __tm) const {
return do_get_monthname(__b, __e, __iob, __err, __tm);
}
_LIBCPP_HIDE_FROM_ABI iter_type
get_year(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, tm* __tm) const {
return do_get_year(__b, __e, __iob, __err, __tm);
}
_LIBCPP_HIDE_FROM_ABI iter_type
get(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, tm* __tm, char __fmt, char __mod = 0)
const {
return do_get(__b, __e, __iob, __err, __tm, __fmt, __mod);
}
iter_type
get(iter_type __b,
iter_type __e,
ios_base& __iob,
ios_base::iostate& __err,
tm* __tm,
const char_type* __fmtb,
const char_type* __fmte) const;
static locale::id id;
protected:
_LIBCPP_HIDE_FROM_ABI_VIRTUAL ~time_get() override {}
virtual dateorder do_date_order() const;
virtual iter_type
do_get_time(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, tm* __tm) const;
virtual iter_type
do_get_date(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, tm* __tm) const;
virtual iter_type
do_get_weekday(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, tm* __tm) const;
virtual iter_type
do_get_monthname(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, tm* __tm) const;
virtual iter_type
do_get_year(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, tm* __tm) const;
virtual iter_type do_get(
iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, tm* __tm, char __fmt, char __mod) const;
private:
void __get_white_space(iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const;
void __get_percent(iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const;
void __get_weekdayname(
int& __m, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const;
void __get_monthname(
int& __m, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const;
void __get_day(int& __d, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const;
void
__get_month(int& __m, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const;
void
__get_year(int& __y, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const;
void
__get_year4(int& __y, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const;
void
__get_hour(int& __d, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const;
void
__get_12_hour(int& __h, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const;
void
__get_am_pm(int& __h, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const;
void
__get_minute(int& __m, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const;
void
__get_second(int& __s, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const;
void
__get_weekday(int& __w, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const;
void __get_day_year_num(
int& __w, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const;
};
template <class _CharT, class _InputIterator>
locale::id time_get<_CharT, _InputIterator>::id;
// time_get primitives
template <class _CharT, class _InputIterator>
void time_get<_CharT, _InputIterator>::__get_weekdayname(
int& __w, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const {
// Note: ignoring case comes from the POSIX strptime spec
const string_type* __wk = this->__weeks();
ptrdiff_t __i = std::__scan_keyword(__b, __e, __wk, __wk + 14, __ct, __err, false) - __wk;
if (__i < 14)
__w = __i % 7;
}
template <class _CharT, class _InputIterator>
void time_get<_CharT, _InputIterator>::__get_monthname(
int& __m, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const {
// Note: ignoring case comes from the POSIX strptime spec
const string_type* __month = this->__months();
ptrdiff_t __i = std::__scan_keyword(__b, __e, __month, __month + 24, __ct, __err, false) - __month;
if (__i < 24)
__m = __i % 12;
}
template <class _CharT, class _InputIterator>
void time_get<_CharT, _InputIterator>::__get_day(
int& __d, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const {
int __t = std::__get_up_to_n_digits(__b, __e, __err, __ct, 2);
if (!(__err & ios_base::failbit) && 1 <= __t && __t <= 31)
__d = __t;
else
__err |= ios_base::failbit;
}
template <class _CharT, class _InputIterator>
void time_get<_CharT, _InputIterator>::__get_month(
int& __m, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const {
int __t = std::__get_up_to_n_digits(__b, __e, __err, __ct, 2) - 1;
if (!(__err & ios_base::failbit) && 0 <= __t && __t <= 11)
__m = __t;
else
__err |= ios_base::failbit;
}
template <class _CharT, class _InputIterator>
void time_get<_CharT, _InputIterator>::__get_year(
int& __y, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const {
int __t = std::__get_up_to_n_digits(__b, __e, __err, __ct, 4);
if (!(__err & ios_base::failbit)) {
if (__t < 69)
__t += 2000;
else if (69 <= __t && __t <= 99)
__t += 1900;
__y = __t - 1900;
}
}
template <class _CharT, class _InputIterator>
void time_get<_CharT, _InputIterator>::__get_year4(
int& __y, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const {
int __t = std::__get_up_to_n_digits(__b, __e, __err, __ct, 4);
if (!(__err & ios_base::failbit))
__y = __t - 1900;
}
template <class _CharT, class _InputIterator>
void time_get<_CharT, _InputIterator>::__get_hour(
int& __h, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const {
int __t = std::__get_up_to_n_digits(__b, __e, __err, __ct, 2);
if (!(__err & ios_base::failbit) && __t <= 23)
__h = __t;
else
__err |= ios_base::failbit;
}
template <class _CharT, class _InputIterator>
void time_get<_CharT, _InputIterator>::__get_12_hour(
int& __h, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const {
int __t = std::__get_up_to_n_digits(__b, __e, __err, __ct, 2);
if (!(__err & ios_base::failbit) && 1 <= __t && __t <= 12)
__h = __t;
else
__err |= ios_base::failbit;
}
template <class _CharT, class _InputIterator>
void time_get<_CharT, _InputIterator>::__get_minute(
int& __m, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const {
int __t = std::__get_up_to_n_digits(__b, __e, __err, __ct, 2);
if (!(__err & ios_base::failbit) && __t <= 59)
__m = __t;
else
__err |= ios_base::failbit;
}
template <class _CharT, class _InputIterator>
void time_get<_CharT, _InputIterator>::__get_second(
int& __s, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const {
int __t = std::__get_up_to_n_digits(__b, __e, __err, __ct, 2);
if (!(__err & ios_base::failbit) && __t <= 60)
__s = __t;
else
__err |= ios_base::failbit;
}
template <class _CharT, class _InputIterator>
void time_get<_CharT, _InputIterator>::__get_weekday(
int& __w, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const {
int __t = std::__get_up_to_n_digits(__b, __e, __err, __ct, 1);
if (!(__err & ios_base::failbit) && __t <= 6)
__w = __t;
else
__err |= ios_base::failbit;
}
template <class _CharT, class _InputIterator>
void time_get<_CharT, _InputIterator>::__get_day_year_num(
int& __d, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const {
int __t = std::__get_up_to_n_digits(__b, __e, __err, __ct, 3);
if (!(__err & ios_base::failbit) && __t <= 365)
__d = __t;
else
__err |= ios_base::failbit;
}
template <class _CharT, class _InputIterator>
void time_get<_CharT, _InputIterator>::__get_white_space(
iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const {
for (; __b != __e && __ct.is(ctype_base::space, *__b); ++__b)
;
if (__b == __e)
__err |= ios_base::eofbit;
}
template <class _CharT, class _InputIterator>
void time_get<_CharT, _InputIterator>::__get_am_pm(
int& __h, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const {
const string_type* __ap = this->__am_pm();
if (__ap[0].size() + __ap[1].size() == 0) {
__err |= ios_base::failbit;
return;
}
ptrdiff_t __i = std::__scan_keyword(__b, __e, __ap, __ap + 2, __ct, __err, false) - __ap;
if (__i == 0 && __h == 12)
__h = 0;
else if (__i == 1 && __h < 12)
__h += 12;
}
template <class _CharT, class _InputIterator>
void time_get<_CharT, _InputIterator>::__get_percent(
iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const {
if (__b == __e) {
__err |= ios_base::eofbit | ios_base::failbit;
return;
}
if (__ct.narrow(*__b, 0) != '%')
__err |= ios_base::failbit;
else if (++__b == __e)
__err |= ios_base::eofbit;
}
// time_get end primitives
template <class _CharT, class _InputIterator>
_InputIterator time_get<_CharT, _InputIterator>::get(
iter_type __b,
iter_type __e,
ios_base& __iob,
ios_base::iostate& __err,
tm* __tm,
const char_type* __fmtb,
const char_type* __fmte) const {
const ctype<char_type>& __ct = std::use_facet<ctype<char_type> >(__iob.getloc());
__err = ios_base::goodbit;
while (__fmtb != __fmte && __err == ios_base::goodbit) {
if (__b == __e) {
__err = ios_base::failbit;
break;
}
if (__ct.narrow(*__fmtb, 0) == '%') {
if (++__fmtb == __fmte) {
__err = ios_base::failbit;
break;
}
char __cmd = __ct.narrow(*__fmtb, 0);
char __opt = '\0';
if (__cmd == 'E' || __cmd == '0') {
if (++__fmtb == __fmte) {
__err = ios_base::failbit;
break;
}
__opt = __cmd;
__cmd = __ct.narrow(*__fmtb, 0);
}
__b = do_get(__b, __e, __iob, __err, __tm, __cmd, __opt);
++__fmtb;
} else if (__ct.is(ctype_base::space, *__fmtb)) {
for (++__fmtb; __fmtb != __fmte && __ct.is(ctype_base::space, *__fmtb); ++__fmtb)
;
for (; __b != __e && __ct.is(ctype_base::space, *__b); ++__b)
;
} else if (__ct.toupper(*__b) == __ct.toupper(*__fmtb)) {
++__b;
++__fmtb;
} else
__err = ios_base::failbit;
}
if (__b == __e)
__err |= ios_base::eofbit;
return __b;
}
template <class _CharT, class _InputIterator>
typename time_get<_CharT, _InputIterator>::dateorder time_get<_CharT, _InputIterator>::do_date_order() const {
return mdy;
}
template <class _CharT, class _InputIterator>
_InputIterator time_get<_CharT, _InputIterator>::do_get_time(
iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, tm* __tm) const {
const char_type __fmt[] = {'%', 'H', ':', '%', 'M', ':', '%', 'S'};
return get(__b, __e, __iob, __err, __tm, __fmt, __fmt + sizeof(__fmt) / sizeof(__fmt[0]));
}
template <class _CharT, class _InputIterator>
_InputIterator time_get<_CharT, _InputIterator>::do_get_date(
iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, tm* __tm) const {
const string_type& __fmt = this->__x();
return get(__b, __e, __iob, __err, __tm, __fmt.data(), __fmt.data() + __fmt.size());
}
template <class _CharT, class _InputIterator>
_InputIterator time_get<_CharT, _InputIterator>::do_get_weekday(
iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, tm* __tm) const {
const ctype<char_type>& __ct = std::use_facet<ctype<char_type> >(__iob.getloc());
__get_weekdayname(__tm->tm_wday, __b, __e, __err, __ct);
return __b;
}
template <class _CharT, class _InputIterator>
_InputIterator time_get<_CharT, _InputIterator>::do_get_monthname(
iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, tm* __tm) const {
const ctype<char_type>& __ct = std::use_facet<ctype<char_type> >(__iob.getloc());
__get_monthname(__tm->tm_mon, __b, __e, __err, __ct);
return __b;
}
template <class _CharT, class _InputIterator>
_InputIterator time_get<_CharT, _InputIterator>::do_get_year(
iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, tm* __tm) const {
const ctype<char_type>& __ct = std::use_facet<ctype<char_type> >(__iob.getloc());
__get_year(__tm->tm_year, __b, __e, __err, __ct);
return __b;
}
template <class _CharT, class _InputIterator>
_InputIterator time_get<_CharT, _InputIterator>::do_get(
iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, tm* __tm, char __fmt, char) const {
__err = ios_base::goodbit;
const ctype<char_type>& __ct = std::use_facet<ctype<char_type> >(__iob.getloc());
switch (__fmt) {
case 'a':
case 'A':
__get_weekdayname(__tm->tm_wday, __b, __e, __err, __ct);
break;
case 'b':
case 'B':
case 'h':
__get_monthname(__tm->tm_mon, __b, __e, __err, __ct);
break;
case 'c': {
const string_type& __fm = this->__c();
__b = get(__b, __e, __iob, __err, __tm, __fm.data(), __fm.data() + __fm.size());
} break;
case 'd':
case 'e':
__get_day(__tm->tm_mday, __b, __e, __err, __ct);
break;
case 'D': {
const char_type __fm[] = {'%', 'm', '/', '%', 'd', '/', '%', 'y'};
__b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm) / sizeof(__fm[0]));
} break;
case 'F': {
const char_type __fm[] = {'%', 'Y', '-', '%', 'm', '-', '%', 'd'};
__b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm) / sizeof(__fm[0]));
} break;
case 'H':
__get_hour(__tm->tm_hour, __b, __e, __err, __ct);
break;
case 'I':
__get_12_hour(__tm->tm_hour, __b, __e, __err, __ct);
break;
case 'j':
__get_day_year_num(__tm->tm_yday, __b, __e, __err, __ct);
break;
case 'm':
__get_month(__tm->tm_mon, __b, __e, __err, __ct);
break;
case 'M':
__get_minute(__tm->tm_min, __b, __e, __err, __ct);
break;
case 'n':
case 't':
__get_white_space(__b, __e, __err, __ct);
break;
case 'p':
__get_am_pm(__tm->tm_hour, __b, __e, __err, __ct);
break;
case 'r': {
const char_type __fm[] = {'%', 'I', ':', '%', 'M', ':', '%', 'S', ' ', '%', 'p'};
__b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm) / sizeof(__fm[0]));
} break;
case 'R': {
const char_type __fm[] = {'%', 'H', ':', '%', 'M'};
__b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm) / sizeof(__fm[0]));
} break;
case 'S':
__get_second(__tm->tm_sec, __b, __e, __err, __ct);
break;
case 'T': {
const char_type __fm[] = {'%', 'H', ':', '%', 'M', ':', '%', 'S'};
__b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm) / sizeof(__fm[0]));
} break;
case 'w':
__get_weekday(__tm->tm_wday, __b, __e, __err, __ct);
break;
case 'x':
return do_get_date(__b, __e, __iob, __err, __tm);
case 'X': {
const string_type& __fm = this->__X();
__b = get(__b, __e, __iob, __err, __tm, __fm.data(), __fm.data() + __fm.size());
} break;
case 'y':
__get_year(__tm->tm_year, __b, __e, __err, __ct);
break;
case 'Y':
__get_year4(__tm->tm_year, __b, __e, __err, __ct);
break;
case '%':
__get_percent(__b, __e, __err, __ct);
break;
default:
__err |= ios_base::failbit;
}
return __b;
}
extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_get<char>;
# if _LIBCPP_HAS_WIDE_CHARACTERS
extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_get<wchar_t>;
# endif
class _LIBCPP_EXPORTED_FROM_ABI __time_get {
protected:
__locale::__locale_t __loc_;
__time_get(const char* __nm);
__time_get(const string& __nm);
~__time_get();
};
template <class _CharT>
class __time_get_storage : public __time_get {
protected:
typedef basic_string<_CharT> string_type;
string_type __weeks_[14];
string_type __months_[24];
string_type __am_pm_[2];
string_type __c_;
string_type __r_;
string_type __x_;
string_type __X_;
explicit __time_get_storage(const char* __nm);
explicit __time_get_storage(const string& __nm);
_LIBCPP_HIDE_FROM_ABI ~__time_get_storage() {}
time_base::dateorder __do_date_order() const;
private:
void init(const ctype<_CharT>&);
string_type __analyze(char __fmt, const ctype<_CharT>&);
};
# define _LIBCPP_TIME_GET_STORAGE_EXPLICIT_INSTANTIATION(_CharT) \
template <> \
_LIBCPP_EXPORTED_FROM_ABI time_base::dateorder __time_get_storage<_CharT>::__do_date_order() const; \
template <> \
_LIBCPP_EXPORTED_FROM_ABI __time_get_storage<_CharT>::__time_get_storage(const char*); \
template <> \
_LIBCPP_EXPORTED_FROM_ABI __time_get_storage<_CharT>::__time_get_storage(const string&); \
template <> \
_LIBCPP_EXPORTED_FROM_ABI void __time_get_storage<_CharT>::init(const ctype<_CharT>&); \
template <> \
_LIBCPP_EXPORTED_FROM_ABI __time_get_storage<_CharT>::string_type __time_get_storage<_CharT>::__analyze( \
char, const ctype<_CharT>&); \
extern template _LIBCPP_EXPORTED_FROM_ABI time_base::dateorder __time_get_storage<_CharT>::__do_date_order() \
const; \
extern template _LIBCPP_EXPORTED_FROM_ABI __time_get_storage<_CharT>::__time_get_storage(const char*); \
extern template _LIBCPP_EXPORTED_FROM_ABI __time_get_storage<_CharT>::__time_get_storage(const string&); \
extern template _LIBCPP_EXPORTED_FROM_ABI void __time_get_storage<_CharT>::init(const ctype<_CharT>&); \
extern template _LIBCPP_EXPORTED_FROM_ABI __time_get_storage<_CharT>::string_type \
__time_get_storage<_CharT>::__analyze(char, const ctype<_CharT>&);
_LIBCPP_TIME_GET_STORAGE_EXPLICIT_INSTANTIATION(char)
# if _LIBCPP_HAS_WIDE_CHARACTERS
_LIBCPP_TIME_GET_STORAGE_EXPLICIT_INSTANTIATION(wchar_t)
# endif
# undef _LIBCPP_TIME_GET_STORAGE_EXPLICIT_INSTANTIATION
template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> >
class time_get_byname : public time_get<_CharT, _InputIterator>, private __time_get_storage<_CharT> {
public:
typedef time_base::dateorder dateorder;
typedef _InputIterator iter_type;
typedef _CharT char_type;
typedef basic_string<char_type> string_type;
_LIBCPP_HIDE_FROM_ABI explicit time_get_byname(const char* __nm, size_t __refs = 0)
: time_get<_CharT, _InputIterator>(__refs), __time_get_storage<_CharT>(__nm) {}
_LIBCPP_HIDE_FROM_ABI explicit time_get_byname(const string& __nm, size_t __refs = 0)
: time_get<_CharT, _InputIterator>(__refs), __time_get_storage<_CharT>(__nm) {}
protected:
_LIBCPP_HIDE_FROM_ABI_VIRTUAL ~time_get_byname() override {}
_LIBCPP_HIDE_FROM_ABI_VIRTUAL dateorder do_date_order() const override { return this->__do_date_order(); }
private:
_LIBCPP_HIDE_FROM_ABI_VIRTUAL const string_type* __weeks() const override { return this->__weeks_; }
_LIBCPP_HIDE_FROM_ABI_VIRTUAL const string_type* __months() const override { return this->__months_; }
_LIBCPP_HIDE_FROM_ABI_VIRTUAL const string_type* __am_pm() const override { return this->__am_pm_; }
_LIBCPP_HIDE_FROM_ABI_VIRTUAL const string_type& __c() const override { return this->__c_; }
_LIBCPP_HIDE_FROM_ABI_VIRTUAL const string_type& __r() const override { return this->__r_; }
_LIBCPP_HIDE_FROM_ABI_VIRTUAL const string_type& __x() const override { return this->__x_; }
_LIBCPP_HIDE_FROM_ABI_VIRTUAL const string_type& __X() const override { return this->__X_; }
};
extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_get_byname<char>;
# if _LIBCPP_HAS_WIDE_CHARACTERS
extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_get_byname<wchar_t>;
# endif
class _LIBCPP_EXPORTED_FROM_ABI __time_put {
__locale::__locale_t __loc_;
protected:
_LIBCPP_HIDE_FROM_ABI __time_put() : __loc_(_LIBCPP_GET_C_LOCALE) {}
__time_put(const char* __nm);
__time_put(const string& __nm);
~__time_put();
void __do_put(char* __nb, char*& __ne, const tm* __tm, char __fmt, char __mod) const;
# if _LIBCPP_HAS_WIDE_CHARACTERS
void __do_put(wchar_t* __wb, wchar_t*& __we, const tm* __tm, char __fmt, char __mod) const;
# endif
};
template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> >
class time_put : public locale::facet, private __time_put {
public:
typedef _CharT char_type;
typedef _OutputIterator iter_type;
_LIBCPP_HIDE_FROM_ABI explicit time_put(size_t __refs = 0) : locale::facet(__refs) {}
iter_type
put(iter_type __s, ios_base& __iob, char_type __fl, const tm* __tm, const char_type* __pb, const char_type* __pe)
const;
_LIBCPP_HIDE_FROM_ABI iter_type
put(iter_type __s, ios_base& __iob, char_type __fl, const tm* __tm, char __fmt, char __mod = 0) const {
return do_put(__s, __iob, __fl, __tm, __fmt, __mod);
}
static locale::id id;
protected:
_LIBCPP_HIDE_FROM_ABI_VIRTUAL ~time_put() override {}
virtual iter_type do_put(iter_type __s, ios_base&, char_type, const tm* __tm, char __fmt, char __mod) const;
_LIBCPP_HIDE_FROM_ABI explicit time_put(const char* __nm, size_t __refs) : locale::facet(__refs), __time_put(__nm) {}
_LIBCPP_HIDE_FROM_ABI explicit time_put(const string& __nm, size_t __refs)
: locale::facet(__refs), __time_put(__nm) {}
};
template <class _CharT, class _OutputIterator>
locale::id time_put<_CharT, _OutputIterator>::id;
template <class _CharT, class _OutputIterator>
_OutputIterator time_put<_CharT, _OutputIterator>::put(
iter_type __s, ios_base& __iob, char_type __fl, const tm* __tm, const char_type* __pb, const char_type* __pe)
const {
const ctype<char_type>& __ct = std::use_facet<ctype<char_type> >(__iob.getloc());
for (; __pb != __pe; ++__pb) {
if (__ct.narrow(*__pb, 0) == '%') {
if (++__pb == __pe) {
*__s++ = __pb[-1];
break;
}
char __mod = 0;
char __fmt = __ct.narrow(*__pb, 0);
if (__fmt == 'E' || __fmt == 'O') {
if (++__pb == __pe) {
*__s++ = __pb[-2];
*__s++ = __pb[-1];
break;
}
__mod = __fmt;
__fmt = __ct.narrow(*__pb, 0);
}
__s = do_put(__s, __iob, __fl, __tm, __fmt, __mod);
} else
*__s++ = *__pb;
}
return __s;
}
template <class _CharT, class _OutputIterator>
_OutputIterator time_put<_CharT, _OutputIterator>::do_put(
iter_type __s, ios_base&, char_type, const tm* __tm, char __fmt, char __mod) const {
char_type __nar[100];
char_type* __nb = __nar;
char_type* __ne = __nb + 100;
__do_put(__nb, __ne, __tm, __fmt, __mod);
return std::copy(__nb, __ne, __s);
}
extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_put<char>;
# if _LIBCPP_HAS_WIDE_CHARACTERS
extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_put<wchar_t>;
# endif
template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> >
class time_put_byname : public time_put<_CharT, _OutputIterator> {
public:
_LIBCPP_HIDE_FROM_ABI explicit time_put_byname(const char* __nm, size_t __refs = 0)
: time_put<_CharT, _OutputIterator>(__nm, __refs) {}
_LIBCPP_HIDE_FROM_ABI explicit time_put_byname(const string& __nm, size_t __refs = 0)
: time_put<_CharT, _OutputIterator>(__nm, __refs) {}
protected:
_LIBCPP_HIDE_FROM_ABI_VIRTUAL ~time_put_byname() override {}
};
extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_put_byname<char>;
# if _LIBCPP_HAS_WIDE_CHARACTERS
extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_put_byname<wchar_t>;
# endif
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP_HAS_LOCALIZATION
#endif // _LIBCPP___LOCALE_DIR_TIME_H

View File

@@ -0,0 +1,430 @@
//===----------------------------------------------------------------------===//
//
// 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_WBUFFER_CONVERT_H
#define _LIBCPP___LOCALE_DIR_WBUFFER_CONVERT_H
#include <__algorithm/reverse.h>
#include <__config>
#include <__string/char_traits.h>
#include <ios>
#include <streambuf>
#if _LIBCPP_HAS_LOCALIZATION
# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
# endif
# if _LIBCPP_STD_VER < 26 || defined(_LIBCPP_ENABLE_CXX26_REMOVED_WSTRING_CONVERT)
_LIBCPP_PUSH_MACROS
# include <__undef_macros>
_LIBCPP_BEGIN_NAMESPACE_STD
template <class _Codecvt, class _Elem = wchar_t, class _Tr = char_traits<_Elem> >
class _LIBCPP_DEPRECATED_IN_CXX17 wbuffer_convert : public basic_streambuf<_Elem, _Tr> {
public:
// types:
typedef _Elem char_type;
typedef _Tr traits_type;
typedef typename traits_type::int_type int_type;
typedef typename traits_type::pos_type pos_type;
typedef typename traits_type::off_type off_type;
typedef typename _Codecvt::state_type state_type;
private:
char* __extbuf_;
const char* __extbufnext_;
const char* __extbufend_;
char __extbuf_min_[8];
size_t __ebs_;
char_type* __intbuf_;
size_t __ibs_;
streambuf* __bufptr_;
_Codecvt* __cv_;
state_type __st_;
ios_base::openmode __cm_;
bool __owns_eb_;
bool __owns_ib_;
bool __always_noconv_;
public:
# ifndef _LIBCPP_CXX03_LANG
_LIBCPP_HIDE_FROM_ABI wbuffer_convert() : wbuffer_convert(nullptr) {}
explicit _LIBCPP_HIDE_FROM_ABI
wbuffer_convert(streambuf* __bytebuf, _Codecvt* __pcvt = new _Codecvt, state_type __state = state_type());
# else
_LIBCPP_EXPLICIT_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI
wbuffer_convert(streambuf* __bytebuf = nullptr, _Codecvt* __pcvt = new _Codecvt, state_type __state = state_type());
# endif
_LIBCPP_HIDE_FROM_ABI ~wbuffer_convert();
_LIBCPP_HIDE_FROM_ABI streambuf* rdbuf() const { return __bufptr_; }
_LIBCPP_HIDE_FROM_ABI streambuf* rdbuf(streambuf* __bytebuf) {
streambuf* __r = __bufptr_;
__bufptr_ = __bytebuf;
return __r;
}
wbuffer_convert(const wbuffer_convert&) = delete;
wbuffer_convert& operator=(const wbuffer_convert&) = delete;
_LIBCPP_HIDE_FROM_ABI state_type state() const { return __st_; }
protected:
_LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual int_type underflow();
_LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual int_type pbackfail(int_type __c = traits_type::eof());
_LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual int_type overflow(int_type __c = traits_type::eof());
_LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual basic_streambuf<char_type, traits_type>* setbuf(char_type* __s, streamsize __n);
_LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual pos_type
seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode __wch = ios_base::in | ios_base::out);
_LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual pos_type
seekpos(pos_type __sp, ios_base::openmode __wch = ios_base::in | ios_base::out);
_LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual int sync();
private:
_LIBCPP_HIDE_FROM_ABI_VIRTUAL bool __read_mode();
_LIBCPP_HIDE_FROM_ABI_VIRTUAL void __write_mode();
_LIBCPP_HIDE_FROM_ABI_VIRTUAL wbuffer_convert* __close();
};
_LIBCPP_SUPPRESS_DEPRECATED_PUSH
template <class _Codecvt, class _Elem, class _Tr>
wbuffer_convert<_Codecvt, _Elem, _Tr>::wbuffer_convert(streambuf* __bytebuf, _Codecvt* __pcvt, state_type __state)
: __extbuf_(nullptr),
__extbufnext_(nullptr),
__extbufend_(nullptr),
__ebs_(0),
__intbuf_(0),
__ibs_(0),
__bufptr_(__bytebuf),
__cv_(__pcvt),
__st_(__state),
__cm_(0),
__owns_eb_(false),
__owns_ib_(false),
__always_noconv_(__cv_ ? __cv_->always_noconv() : false) {
setbuf(0, 4096);
}
template <class _Codecvt, class _Elem, class _Tr>
wbuffer_convert<_Codecvt, _Elem, _Tr>::~wbuffer_convert() {
__close();
delete __cv_;
if (__owns_eb_)
delete[] __extbuf_;
if (__owns_ib_)
delete[] __intbuf_;
}
template <class _Codecvt, class _Elem, class _Tr>
typename wbuffer_convert<_Codecvt, _Elem, _Tr>::int_type wbuffer_convert<_Codecvt, _Elem, _Tr>::underflow() {
_LIBCPP_SUPPRESS_DEPRECATED_POP
if (__cv_ == 0 || __bufptr_ == nullptr)
return traits_type::eof();
bool __initial = __read_mode();
char_type __1buf;
if (this->gptr() == 0)
this->setg(std::addressof(__1buf), std::addressof(__1buf) + 1, std::addressof(__1buf) + 1);
const size_t __unget_sz = __initial ? 0 : std::min<size_t>((this->egptr() - this->eback()) / 2, 4);
int_type __c = traits_type::eof();
if (this->gptr() == this->egptr()) {
std::memmove(this->eback(), this->egptr() - __unget_sz, __unget_sz * sizeof(char_type));
if (__always_noconv_) {
streamsize __nmemb = static_cast<streamsize>(this->egptr() - this->eback() - __unget_sz);
__nmemb = __bufptr_->sgetn((char*)this->eback() + __unget_sz, __nmemb);
if (__nmemb != 0) {
this->setg(this->eback(), this->eback() + __unget_sz, this->eback() + __unget_sz + __nmemb);
__c = *this->gptr();
}
} else {
if (__extbufend_ != __extbufnext_) {
_LIBCPP_ASSERT_NON_NULL(__extbufnext_ != nullptr, "underflow moving from nullptr");
_LIBCPP_ASSERT_NON_NULL(__extbuf_ != nullptr, "underflow moving into nullptr");
std::memmove(__extbuf_, __extbufnext_, __extbufend_ - __extbufnext_);
}
__extbufnext_ = __extbuf_ + (__extbufend_ - __extbufnext_);
__extbufend_ = __extbuf_ + (__extbuf_ == __extbuf_min_ ? sizeof(__extbuf_min_) : __ebs_);
streamsize __nmemb = std::min(static_cast<streamsize>(this->egptr() - this->eback() - __unget_sz),
static_cast<streamsize>(__extbufend_ - __extbufnext_));
codecvt_base::result __r;
// FIXME: Do we ever need to restore the state here?
// state_type __svs = __st_;
streamsize __nr = __bufptr_->sgetn(const_cast<char*>(__extbufnext_), __nmemb);
if (__nr != 0) {
__extbufend_ = __extbufnext_ + __nr;
char_type* __inext;
__r = __cv_->in(
__st_, __extbuf_, __extbufend_, __extbufnext_, this->eback() + __unget_sz, this->egptr(), __inext);
if (__r == codecvt_base::noconv) {
this->setg((char_type*)__extbuf_, (char_type*)__extbuf_, (char_type*)const_cast<char*>(__extbufend_));
__c = *this->gptr();
} else if (__inext != this->eback() + __unget_sz) {
this->setg(this->eback(), this->eback() + __unget_sz, __inext);
__c = *this->gptr();
}
}
}
} else
__c = *this->gptr();
if (this->eback() == std::addressof(__1buf))
this->setg(0, 0, 0);
return __c;
}
_LIBCPP_SUPPRESS_DEPRECATED_PUSH
template <class _Codecvt, class _Elem, class _Tr>
typename wbuffer_convert<_Codecvt, _Elem, _Tr>::int_type
wbuffer_convert<_Codecvt, _Elem, _Tr>::pbackfail(int_type __c) {
_LIBCPP_SUPPRESS_DEPRECATED_POP
if (__cv_ != 0 && __bufptr_ && this->eback() < this->gptr()) {
if (traits_type::eq_int_type(__c, traits_type::eof())) {
this->gbump(-1);
return traits_type::not_eof(__c);
}
if (traits_type::eq(traits_type::to_char_type(__c), this->gptr()[-1])) {
this->gbump(-1);
*this->gptr() = traits_type::to_char_type(__c);
return __c;
}
}
return traits_type::eof();
}
_LIBCPP_SUPPRESS_DEPRECATED_PUSH
template <class _Codecvt, class _Elem, class _Tr>
typename wbuffer_convert<_Codecvt, _Elem, _Tr>::int_type wbuffer_convert<_Codecvt, _Elem, _Tr>::overflow(int_type __c) {
_LIBCPP_SUPPRESS_DEPRECATED_POP
if (__cv_ == 0 || !__bufptr_)
return traits_type::eof();
__write_mode();
char_type __1buf;
char_type* __pb_save = this->pbase();
char_type* __epb_save = this->epptr();
if (!traits_type::eq_int_type(__c, traits_type::eof())) {
if (this->pptr() == 0)
this->setp(std::addressof(__1buf), std::addressof(__1buf) + 1);
*this->pptr() = traits_type::to_char_type(__c);
this->pbump(1);
}
if (this->pptr() != this->pbase()) {
if (__always_noconv_) {
streamsize __nmemb = static_cast<streamsize>(this->pptr() - this->pbase());
if (__bufptr_->sputn((const char*)this->pbase(), __nmemb) != __nmemb)
return traits_type::eof();
} else {
char* __extbe = __extbuf_;
codecvt_base::result __r;
do {
const char_type* __e;
__r = __cv_->out(__st_, this->pbase(), this->pptr(), __e, __extbuf_, __extbuf_ + __ebs_, __extbe);
if (__e == this->pbase())
return traits_type::eof();
if (__r == codecvt_base::noconv) {
streamsize __nmemb = static_cast<size_t>(this->pptr() - this->pbase());
if (__bufptr_->sputn((const char*)this->pbase(), __nmemb) != __nmemb)
return traits_type::eof();
} else if (__r == codecvt_base::ok || __r == codecvt_base::partial) {
streamsize __nmemb = static_cast<size_t>(__extbe - __extbuf_);
if (__bufptr_->sputn(__extbuf_, __nmemb) != __nmemb)
return traits_type::eof();
if (__r == codecvt_base::partial) {
this->setp(const_cast<char_type*>(__e), this->pptr());
this->__pbump(this->epptr() - this->pbase());
}
} else
return traits_type::eof();
} while (__r == codecvt_base::partial);
}
this->setp(__pb_save, __epb_save);
}
return traits_type::not_eof(__c);
}
_LIBCPP_SUPPRESS_DEPRECATED_PUSH
template <class _Codecvt, class _Elem, class _Tr>
basic_streambuf<_Elem, _Tr>* wbuffer_convert<_Codecvt, _Elem, _Tr>::setbuf(char_type* __s, streamsize __n) {
_LIBCPP_SUPPRESS_DEPRECATED_POP
this->setg(0, 0, 0);
this->setp(0, 0);
if (__owns_eb_)
delete[] __extbuf_;
if (__owns_ib_)
delete[] __intbuf_;
__ebs_ = __n;
if (__ebs_ > sizeof(__extbuf_min_)) {
if (__always_noconv_ && __s) {
__extbuf_ = (char*)__s;
__owns_eb_ = false;
} else {
__extbuf_ = new char[__ebs_];
__owns_eb_ = true;
}
} else {
__extbuf_ = __extbuf_min_;
__ebs_ = sizeof(__extbuf_min_);
__owns_eb_ = false;
}
if (!__always_noconv_) {
__ibs_ = max<streamsize>(__n, sizeof(__extbuf_min_));
if (__s && __ibs_ >= sizeof(__extbuf_min_)) {
__intbuf_ = __s;
__owns_ib_ = false;
} else {
__intbuf_ = new char_type[__ibs_];
__owns_ib_ = true;
}
} else {
__ibs_ = 0;
__intbuf_ = 0;
__owns_ib_ = false;
}
return this;
}
_LIBCPP_SUPPRESS_DEPRECATED_PUSH
template <class _Codecvt, class _Elem, class _Tr>
typename wbuffer_convert<_Codecvt, _Elem, _Tr>::pos_type
wbuffer_convert<_Codecvt, _Elem, _Tr>::seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode __om) {
int __width = __cv_->encoding();
if (__cv_ == 0 || !__bufptr_ || (__width <= 0 && __off != 0) || sync())
return pos_type(off_type(-1));
// __width > 0 || __off == 0, now check __way
if (__way != ios_base::beg && __way != ios_base::cur && __way != ios_base::end)
return pos_type(off_type(-1));
pos_type __r = __bufptr_->pubseekoff(__width * __off, __way, __om);
__r.state(__st_);
return __r;
}
template <class _Codecvt, class _Elem, class _Tr>
typename wbuffer_convert<_Codecvt, _Elem, _Tr>::pos_type
wbuffer_convert<_Codecvt, _Elem, _Tr>::seekpos(pos_type __sp, ios_base::openmode __wch) {
if (__cv_ == 0 || !__bufptr_ || sync())
return pos_type(off_type(-1));
if (__bufptr_->pubseekpos(__sp, __wch) == pos_type(off_type(-1)))
return pos_type(off_type(-1));
return __sp;
}
template <class _Codecvt, class _Elem, class _Tr>
int wbuffer_convert<_Codecvt, _Elem, _Tr>::sync() {
_LIBCPP_SUPPRESS_DEPRECATED_POP
if (__cv_ == 0 || !__bufptr_)
return 0;
if (__cm_ & ios_base::out) {
if (this->pptr() != this->pbase())
if (overflow() == traits_type::eof())
return -1;
codecvt_base::result __r;
do {
char* __extbe;
__r = __cv_->unshift(__st_, __extbuf_, __extbuf_ + __ebs_, __extbe);
streamsize __nmemb = static_cast<streamsize>(__extbe - __extbuf_);
if (__bufptr_->sputn(__extbuf_, __nmemb) != __nmemb)
return -1;
} while (__r == codecvt_base::partial);
if (__r == codecvt_base::error)
return -1;
if (__bufptr_->pubsync())
return -1;
} else if (__cm_ & ios_base::in) {
off_type __c;
if (__always_noconv_)
__c = this->egptr() - this->gptr();
else {
int __width = __cv_->encoding();
__c = __extbufend_ - __extbufnext_;
if (__width > 0)
__c += __width * (this->egptr() - this->gptr());
else {
if (this->gptr() != this->egptr()) {
std::reverse(this->gptr(), this->egptr());
codecvt_base::result __r;
const char_type* __e = this->gptr();
char* __extbe;
do {
__r = __cv_->out(__st_, __e, this->egptr(), __e, __extbuf_, __extbuf_ + __ebs_, __extbe);
switch (__r) {
case codecvt_base::noconv:
__c += this->egptr() - this->gptr();
break;
case codecvt_base::ok:
case codecvt_base::partial:
__c += __extbe - __extbuf_;
break;
default:
return -1;
}
} while (__r == codecvt_base::partial);
}
}
}
if (__bufptr_->pubseekoff(-__c, ios_base::cur, __cm_) == pos_type(off_type(-1)))
return -1;
this->setg(0, 0, 0);
__cm_ = 0;
}
return 0;
}
_LIBCPP_SUPPRESS_DEPRECATED_PUSH
template <class _Codecvt, class _Elem, class _Tr>
bool wbuffer_convert<_Codecvt, _Elem, _Tr>::__read_mode() {
if (!(__cm_ & ios_base::in)) {
this->setp(0, 0);
if (__always_noconv_)
this->setg((char_type*)__extbuf_, (char_type*)__extbuf_ + __ebs_, (char_type*)__extbuf_ + __ebs_);
else
this->setg(__intbuf_, __intbuf_ + __ibs_, __intbuf_ + __ibs_);
__cm_ = ios_base::in;
return true;
}
return false;
}
template <class _Codecvt, class _Elem, class _Tr>
void wbuffer_convert<_Codecvt, _Elem, _Tr>::__write_mode() {
if (!(__cm_ & ios_base::out)) {
this->setg(0, 0, 0);
if (__ebs_ > sizeof(__extbuf_min_)) {
if (__always_noconv_)
this->setp((char_type*)__extbuf_, (char_type*)__extbuf_ + (__ebs_ - 1));
else
this->setp(__intbuf_, __intbuf_ + (__ibs_ - 1));
} else
this->setp(0, 0);
__cm_ = ios_base::out;
}
}
template <class _Codecvt, class _Elem, class _Tr>
wbuffer_convert<_Codecvt, _Elem, _Tr>* wbuffer_convert<_Codecvt, _Elem, _Tr>::__close() {
wbuffer_convert* __rt = nullptr;
if (__cv_ != nullptr && __bufptr_ != nullptr) {
__rt = this;
if ((__cm_ & ios_base::out) && sync())
__rt = nullptr;
}
return __rt;
}
_LIBCPP_SUPPRESS_DEPRECATED_POP
_LIBCPP_END_NAMESPACE_STD
_LIBCPP_POP_MACROS
# endif // _LIBCPP_STD_VER < 26 || defined(_LIBCPP_ENABLE_CXX26_REMOVED_WSTRING_CONVERT)
#endif // _LIBCPP_HAS_LOCALIZATION
#endif // _LIBCPP___LOCALE_DIR_WBUFFER_CONVERT_H

View File

@@ -0,0 +1,254 @@
//===----------------------------------------------------------------------===//
//
// 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_WSTRING_CONVERT_H
#define _LIBCPP___LOCALE_DIR_WSTRING_CONVERT_H
#include <__config>
#include <__locale>
#include <__memory/allocator.h>
#include <string>
#if _LIBCPP_HAS_LOCALIZATION
# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
# endif
# if _LIBCPP_STD_VER < 26 || defined(_LIBCPP_ENABLE_CXX26_REMOVED_WSTRING_CONVERT)
_LIBCPP_PUSH_MACROS
# include <__undef_macros>
_LIBCPP_BEGIN_NAMESPACE_STD
template <class _Codecvt,
class _Elem = wchar_t,
class _WideAlloc = allocator<_Elem>,
class _ByteAlloc = allocator<char> >
class _LIBCPP_DEPRECATED_IN_CXX17 wstring_convert {
public:
typedef basic_string<char, char_traits<char>, _ByteAlloc> byte_string;
typedef basic_string<_Elem, char_traits<_Elem>, _WideAlloc> wide_string;
typedef typename _Codecvt::state_type state_type;
typedef typename wide_string::traits_type::int_type int_type;
private:
byte_string __byte_err_string_;
wide_string __wide_err_string_;
_Codecvt* __cvtptr_;
state_type __cvtstate_;
size_t __cvtcount_;
public:
# ifndef _LIBCPP_CXX03_LANG
_LIBCPP_HIDE_FROM_ABI wstring_convert() : wstring_convert(new _Codecvt) {}
_LIBCPP_HIDE_FROM_ABI explicit wstring_convert(_Codecvt* __pcvt);
# else
_LIBCPP_HIDE_FROM_ABI _LIBCPP_EXPLICIT_SINCE_CXX14 wstring_convert(_Codecvt* __pcvt = new _Codecvt);
# endif
_LIBCPP_HIDE_FROM_ABI wstring_convert(_Codecvt* __pcvt, state_type __state);
_LIBCPP_EXPLICIT_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI
wstring_convert(const byte_string& __byte_err, const wide_string& __wide_err = wide_string());
# ifndef _LIBCPP_CXX03_LANG
_LIBCPP_HIDE_FROM_ABI wstring_convert(wstring_convert&& __wc);
# endif
_LIBCPP_HIDE_FROM_ABI ~wstring_convert();
wstring_convert(const wstring_convert& __wc) = delete;
wstring_convert& operator=(const wstring_convert& __wc) = delete;
_LIBCPP_HIDE_FROM_ABI wide_string from_bytes(char __byte) { return from_bytes(&__byte, &__byte + 1); }
_LIBCPP_HIDE_FROM_ABI wide_string from_bytes(const char* __ptr) {
return from_bytes(__ptr, __ptr + char_traits<char>::length(__ptr));
}
_LIBCPP_HIDE_FROM_ABI wide_string from_bytes(const byte_string& __str) {
return from_bytes(__str.data(), __str.data() + __str.size());
}
_LIBCPP_HIDE_FROM_ABI wide_string from_bytes(const char* __first, const char* __last);
_LIBCPP_HIDE_FROM_ABI byte_string to_bytes(_Elem __wchar) {
return to_bytes(std::addressof(__wchar), std::addressof(__wchar) + 1);
}
_LIBCPP_HIDE_FROM_ABI byte_string to_bytes(const _Elem* __wptr) {
return to_bytes(__wptr, __wptr + char_traits<_Elem>::length(__wptr));
}
_LIBCPP_HIDE_FROM_ABI byte_string to_bytes(const wide_string& __wstr) {
return to_bytes(__wstr.data(), __wstr.data() + __wstr.size());
}
_LIBCPP_HIDE_FROM_ABI byte_string to_bytes(const _Elem* __first, const _Elem* __last);
_LIBCPP_HIDE_FROM_ABI size_t converted() const _NOEXCEPT { return __cvtcount_; }
_LIBCPP_HIDE_FROM_ABI state_type state() const { return __cvtstate_; }
};
_LIBCPP_SUPPRESS_DEPRECATED_PUSH
template <class _Codecvt, class _Elem, class _WideAlloc, class _ByteAlloc>
inline wstring_convert<_Codecvt, _Elem, _WideAlloc, _ByteAlloc>::wstring_convert(_Codecvt* __pcvt)
: __cvtptr_(__pcvt), __cvtstate_(), __cvtcount_(0) {}
_LIBCPP_SUPPRESS_DEPRECATED_POP
template <class _Codecvt, class _Elem, class _WideAlloc, class _ByteAlloc>
inline wstring_convert<_Codecvt, _Elem, _WideAlloc, _ByteAlloc>::wstring_convert(_Codecvt* __pcvt, state_type __state)
: __cvtptr_(__pcvt), __cvtstate_(__state), __cvtcount_(0) {}
template <class _Codecvt, class _Elem, class _WideAlloc, class _ByteAlloc>
wstring_convert<_Codecvt, _Elem, _WideAlloc, _ByteAlloc>::wstring_convert(
const byte_string& __byte_err, const wide_string& __wide_err)
: __byte_err_string_(__byte_err), __wide_err_string_(__wide_err), __cvtstate_(), __cvtcount_(0) {
__cvtptr_ = new _Codecvt;
}
# ifndef _LIBCPP_CXX03_LANG
template <class _Codecvt, class _Elem, class _WideAlloc, class _ByteAlloc>
inline wstring_convert<_Codecvt, _Elem, _WideAlloc, _ByteAlloc>::wstring_convert(wstring_convert&& __wc)
: __byte_err_string_(std::move(__wc.__byte_err_string_)),
__wide_err_string_(std::move(__wc.__wide_err_string_)),
__cvtptr_(__wc.__cvtptr_),
__cvtstate_(__wc.__cvtstate_),
__cvtcount_(__wc.__cvtcount_) {
__wc.__cvtptr_ = nullptr;
}
# endif // _LIBCPP_CXX03_LANG
_LIBCPP_SUPPRESS_DEPRECATED_PUSH
template <class _Codecvt, class _Elem, class _WideAlloc, class _ByteAlloc>
wstring_convert<_Codecvt, _Elem, _WideAlloc, _ByteAlloc>::~wstring_convert() {
delete __cvtptr_;
}
template <class _Codecvt, class _Elem, class _WideAlloc, class _ByteAlloc>
typename wstring_convert<_Codecvt, _Elem, _WideAlloc, _ByteAlloc>::wide_string
wstring_convert<_Codecvt, _Elem, _WideAlloc, _ByteAlloc>::from_bytes(const char* __frm, const char* __frm_end) {
_LIBCPP_SUPPRESS_DEPRECATED_POP
__cvtcount_ = 0;
if (__cvtptr_ != nullptr) {
wide_string __ws(2 * (__frm_end - __frm), _Elem());
if (__frm != __frm_end)
__ws.resize(__ws.capacity());
codecvt_base::result __r = codecvt_base::ok;
state_type __st = __cvtstate_;
if (__frm != __frm_end) {
_Elem* __to = std::addressof(__ws[0]);
_Elem* __to_end = __to + __ws.size();
const char* __frm_nxt;
do {
_Elem* __to_nxt;
__r = __cvtptr_->in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
__cvtcount_ += __frm_nxt - __frm;
if (__frm_nxt == __frm) {
__r = codecvt_base::error;
} else if (__r == codecvt_base::noconv) {
__ws.resize(__to - std::addressof(__ws[0]));
// This only gets executed if _Elem is char
__ws.append((const _Elem*)__frm, (const _Elem*)__frm_end);
__frm = __frm_nxt;
__r = codecvt_base::ok;
} else if (__r == codecvt_base::ok) {
__ws.resize(__to_nxt - std::addressof(__ws[0]));
__frm = __frm_nxt;
} else if (__r == codecvt_base::partial) {
ptrdiff_t __s = __to_nxt - std::addressof(__ws[0]);
__ws.resize(2 * __s);
__to = std::addressof(__ws[0]) + __s;
__to_end = std::addressof(__ws[0]) + __ws.size();
__frm = __frm_nxt;
}
} while (__r == codecvt_base::partial && __frm_nxt < __frm_end);
}
if (__r == codecvt_base::ok)
return __ws;
}
if (__wide_err_string_.empty())
std::__throw_range_error("wstring_convert: from_bytes error");
return __wide_err_string_;
}
template <class _Codecvt, class _Elem, class _WideAlloc, class _ByteAlloc>
typename wstring_convert<_Codecvt, _Elem, _WideAlloc, _ByteAlloc>::byte_string
wstring_convert<_Codecvt, _Elem, _WideAlloc, _ByteAlloc>::to_bytes(const _Elem* __frm, const _Elem* __frm_end) {
__cvtcount_ = 0;
if (__cvtptr_ != nullptr) {
byte_string __bs(2 * (__frm_end - __frm), char());
if (__frm != __frm_end)
__bs.resize(__bs.capacity());
codecvt_base::result __r = codecvt_base::ok;
state_type __st = __cvtstate_;
if (__frm != __frm_end) {
char* __to = std::addressof(__bs[0]);
char* __to_end = __to + __bs.size();
const _Elem* __frm_nxt;
do {
char* __to_nxt;
__r = __cvtptr_->out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
__cvtcount_ += __frm_nxt - __frm;
if (__frm_nxt == __frm) {
__r = codecvt_base::error;
} else if (__r == codecvt_base::noconv) {
__bs.resize(__to - std::addressof(__bs[0]));
// This only gets executed if _Elem is char
__bs.append((const char*)__frm, (const char*)__frm_end);
__frm = __frm_nxt;
__r = codecvt_base::ok;
} else if (__r == codecvt_base::ok) {
__bs.resize(__to_nxt - std::addressof(__bs[0]));
__frm = __frm_nxt;
} else if (__r == codecvt_base::partial) {
ptrdiff_t __s = __to_nxt - std::addressof(__bs[0]);
__bs.resize(2 * __s);
__to = std::addressof(__bs[0]) + __s;
__to_end = std::addressof(__bs[0]) + __bs.size();
__frm = __frm_nxt;
}
} while (__r == codecvt_base::partial && __frm_nxt < __frm_end);
}
if (__r == codecvt_base::ok) {
size_t __s = __bs.size();
__bs.resize(__bs.capacity());
char* __to = std::addressof(__bs[0]) + __s;
char* __to_end = __to + __bs.size();
do {
char* __to_nxt;
__r = __cvtptr_->unshift(__st, __to, __to_end, __to_nxt);
if (__r == codecvt_base::noconv) {
__bs.resize(__to - std::addressof(__bs[0]));
__r = codecvt_base::ok;
} else if (__r == codecvt_base::ok) {
__bs.resize(__to_nxt - std::addressof(__bs[0]));
} else if (__r == codecvt_base::partial) {
ptrdiff_t __sp = __to_nxt - std::addressof(__bs[0]);
__bs.resize(2 * __sp);
__to = std::addressof(__bs[0]) + __sp;
__to_end = std::addressof(__bs[0]) + __bs.size();
}
} while (__r == codecvt_base::partial);
if (__r == codecvt_base::ok)
return __bs;
}
}
if (__byte_err_string_.empty())
std::__throw_range_error("wstring_convert: to_bytes error");
return __byte_err_string_;
}
_LIBCPP_END_NAMESPACE_STD
_LIBCPP_POP_MACROS
# endif // _LIBCPP_STD_VER < 26 || defined(_LIBCPP_ENABLE_CXX26_REMOVED_WSTRING_CONVERT)
#endif // _LIBCPP_HAS_LOCALIZATION
#endif // _LIBCPP___LOCALE_DIR_WSTRING_CONVERT_H

View File

@@ -15,6 +15,9 @@
# include <__exception/operations.h>
# include <__fwd/memory.h>
# include <__iterator/ostreambuf_iterator.h>
# include <__locale_dir/num.h>
# include <__locale_dir/pad_and_output.h>
# include <__memory/addressof.h>
# include <__memory/unique_ptr.h>
# include <__new/exceptions.h>
@@ -27,7 +30,6 @@
# include <__utility/declval.h>
# include <bitset>
# include <ios>
# include <locale>
# include <streambuf>
# include <string_view>

View File

@@ -18,8 +18,8 @@
# include <__ostream/basic_ostream.h>
# include <format>
# include <ios>
# include <locale>
# include <print>
# include <streambuf>
# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header

View File

@@ -16,6 +16,7 @@
#include <__exception/terminate.h>
#include <__functional/hash.h>
#include <__functional/unary_function.h>
#include <__locale>
#include <__memory/addressof.h>
#include <__memory/unique_ptr.h>
#include <__mutex/mutex.h>
@@ -30,7 +31,6 @@
#include <tuple>
#if _LIBCPP_HAS_LOCALIZATION
# include <locale>
# include <sstream>
#endif

View File

@@ -130,6 +130,11 @@ _LIBCPP_POP_MACROS
# include <optional>
# include <type_traits>
# endif
# if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 23
# include <locale>
# endif
#endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
#endif // _LIBCPP_EXPERIMENTAL_ITERATOR

View File

@@ -49,10 +49,12 @@ template <class charT, class traits, class Allocator>
# if _LIBCPP_HAS_LOCALIZATION
# include <__iterator/istreambuf_iterator.h>
# include <__locale_dir/money.h>
# include <__locale_dir/time.h>
# include <__ostream/put_character_sequence.h>
# include <ios>
# include <iosfwd>
# include <locale>
# include <version>
# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -564,6 +566,11 @@ _LIBCPP_END_NAMESPACE_STD
# include <unordered_map>
# include <vector>
# endif
# if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 23
# include <locale>
# endif
#endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
#endif // _LIBCPP_IOMANIP

View File

@@ -167,6 +167,7 @@ template <class Stream, class T>
# include <__fwd/istream.h>
# include <__iterator/istreambuf_iterator.h>
# include <__locale_dir/num.h>
# include <__ostream/basic_ostream.h>
# include <__type_traits/conjunction.h>
# include <__type_traits/enable_if.h>
@@ -176,7 +177,7 @@ template <class Stream, class T>
# include <__utility/forward.h>
# include <bitset>
# include <ios>
# include <locale>
# include <streambuf>
# include <version>
# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -1411,6 +1412,10 @@ _LIBCPP_POP_MACROS
# include <type_traits>
# endif
# if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 23
# include <locale>
# endif
#endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
#endif // _LIBCPP_ISTREAM

File diff suppressed because it is too large Load Diff

View File

@@ -1553,7 +1553,16 @@ module std [system] {
module locale {
header "locale"
module pad_and_output { header "__locale_dir/pad_and_output.h" }
module check_grouping { header "__locale_dir/check_grouping.h" }
module get_c_locale { header "__locale_dir/get_c_locale.h" }
module messages { header "__locale_dir/messages.h" }
module money { header "__locale_dir/money.h" }
module num { header "__locale_dir/num.h" }
module pad_and_output { header "__locale_dir/pad_and_output.h" }
module scan_keyword { header "__locale_dir/scan_keyword.h" }
module time { header "__locale_dir/time.h" }
module wbuffer_convert { header "__locale_dir/wbuffer_convert.h" }
module wstring_convert { header "__locale_dir/wstring_convert.h" }
module support {
header "__locale_dir/locale_base_api.h"

View File

@@ -205,6 +205,11 @@ void vprint_nonunicode(ostream& os, string_view fmt, format_args args);
# include <stdexcept>
# include <type_traits>
# endif
# if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 23
# include <locale>
# endif
#endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
#endif // _LIBCPP_OSTREAM

View File

@@ -325,7 +325,7 @@ typedef basic_stringstream<wchar_t> wstringstream;
# include <__utility/swap.h>
# include <ios>
# include <istream>
# include <locale>
# include <streambuf>
# include <string>
# include <string_view>
# include <version>

View File

@@ -35,8 +35,11 @@
// const _Ctype& __ct, ios_base::iostate& __err,
// bool __case_sensitive = true);
#include <locale>
// XFAIL: FROZEN-CXX03-HEADERS-FIXME
#include <__locale_dir/scan_keyword.h>
#include <cassert>
#include <locale>
#include "test_macros.h"

View File

@@ -82,7 +82,6 @@ ccomplex ios
ccomplex iosfwd
ccomplex istream
ccomplex limits
ccomplex locale
ccomplex ratio
ccomplex sstream
ccomplex stdexcept
@@ -120,7 +119,6 @@ chrono ios
chrono iosfwd
chrono istream
chrono limits
chrono locale
chrono optional
chrono ratio
chrono sstream
@@ -177,7 +175,6 @@ complex ios
complex iosfwd
complex istream
complex limits
complex locale
complex ratio
complex sstream
complex stdexcept
@@ -226,7 +223,6 @@ ctgmath ios
ctgmath iosfwd
ctgmath istream
ctgmath limits
ctgmath locale
ctgmath ratio
ctgmath sstream
ctgmath stdexcept
@@ -278,7 +274,6 @@ experimental/iterator ios
experimental/iterator iosfwd
experimental/iterator iterator
experimental/iterator limits
experimental/iterator locale
experimental/iterator ratio
experimental/iterator stdexcept
experimental/iterator streambuf
@@ -324,10 +319,8 @@ filesystem iomanip
filesystem ios
filesystem iosfwd
filesystem limits
filesystem locale
filesystem ratio
filesystem stdexcept
filesystem streambuf
filesystem string
filesystem string_view
filesystem tuple
@@ -412,7 +405,6 @@ fstream ios
fstream iosfwd
fstream istream
fstream limits
fstream locale
fstream ratio
fstream stdexcept
fstream streambuf
@@ -455,7 +447,6 @@ future ios
future iosfwd
future istream
future limits
future locale
future ratio
future sstream
future stdexcept
@@ -483,10 +474,8 @@ iomanip initializer_list
iomanip ios
iomanip iosfwd
iomanip limits
iomanip locale
iomanip ratio
iomanip stdexcept
iomanip streambuf
iomanip string
iomanip string_view
iomanip tuple
@@ -538,7 +527,6 @@ iostream ios
iostream iosfwd
iostream istream
iostream limits
iostream locale
iostream optional
iostream ostream
iostream print
@@ -568,7 +556,6 @@ istream initializer_list
istream ios
istream iosfwd
istream limits
istream locale
istream ratio
istream stdexcept
istream streambuf
@@ -724,7 +711,6 @@ ostream initializer_list
ostream ios
ostream iosfwd
ostream limits
ostream locale
ostream optional
ostream print
ostream ratio
@@ -905,7 +891,6 @@ sstream ios
sstream iosfwd
sstream istream
sstream limits
sstream locale
sstream ratio
sstream stdexcept
sstream streambuf
@@ -1004,7 +989,6 @@ strstream ios
strstream iosfwd
strstream istream
strstream limits
strstream locale
strstream ratio
strstream stdexcept
strstream streambuf
@@ -1034,7 +1018,6 @@ syncstream initializer_list
syncstream ios
syncstream iosfwd
syncstream limits
syncstream locale
syncstream map
syncstream optional
syncstream ostream
@@ -1086,7 +1069,6 @@ thread ios
thread iosfwd
thread istream
thread limits
thread locale
thread ratio
thread sstream
thread stdexcept
1 algorithm cctype
82 ccomplex iosfwd
83 ccomplex istream
84 ccomplex limits
ccomplex locale
85 ccomplex ratio
86 ccomplex sstream
87 ccomplex stdexcept
119 chrono iosfwd
120 chrono istream
121 chrono limits
chrono locale
122 chrono optional
123 chrono ratio
124 chrono sstream
175 complex iosfwd
176 complex istream
177 complex limits
complex locale
178 complex ratio
179 complex sstream
180 complex stdexcept
223 ctgmath iosfwd
224 ctgmath istream
225 ctgmath limits
ctgmath locale
226 ctgmath ratio
227 ctgmath sstream
228 ctgmath stdexcept
274 experimental/iterator iosfwd
275 experimental/iterator iterator
276 experimental/iterator limits
experimental/iterator locale
277 experimental/iterator ratio
278 experimental/iterator stdexcept
279 experimental/iterator streambuf
319 filesystem ios
320 filesystem iosfwd
321 filesystem limits
filesystem locale
322 filesystem ratio
323 filesystem stdexcept
filesystem streambuf
324 filesystem string
325 filesystem string_view
326 filesystem tuple
405 fstream iosfwd
406 fstream istream
407 fstream limits
fstream locale
408 fstream ratio
409 fstream stdexcept
410 fstream streambuf
447 future iosfwd
448 future istream
449 future limits
future locale
450 future ratio
451 future sstream
452 future stdexcept
474 iomanip ios
475 iomanip iosfwd
476 iomanip limits
iomanip locale
477 iomanip ratio
478 iomanip stdexcept
iomanip streambuf
479 iomanip string
480 iomanip string_view
481 iomanip tuple
527 iostream iosfwd
528 iostream istream
529 iostream limits
iostream locale
530 iostream optional
531 iostream ostream
532 iostream print
556 istream ios
557 istream iosfwd
558 istream limits
istream locale
559 istream ratio
560 istream stdexcept
561 istream streambuf
711 ostream ios
712 ostream iosfwd
713 ostream limits
ostream locale
714 ostream optional
715 ostream print
716 ostream ratio
891 sstream iosfwd
892 sstream istream
893 sstream limits
sstream locale
894 sstream ratio
895 sstream stdexcept
896 sstream streambuf
989 strstream iosfwd
990 strstream istream
991 strstream limits
strstream locale
992 strstream ratio
993 strstream stdexcept
994 strstream streambuf
1018 syncstream ios
1019 syncstream iosfwd
1020 syncstream limits
syncstream locale
1021 syncstream map
1022 syncstream optional
1023 syncstream ostream
1069 thread iosfwd
1070 thread istream
1071 thread limits
thread locale
1072 thread ratio
1073 thread sstream
1074 thread stdexcept

View File

@@ -15,9 +15,10 @@
// REQUIRES: locale.en_US.UTF-8
#include <cassert>
#include <iomanip>
#include <istream>
#include <cassert>
#include <streambuf>
#include "test_macros.h"
#include "platform_support.h" // locale name macros

View File

@@ -12,9 +12,11 @@
// template <class charT> T9 get_time(struct tm* tmb, const charT* fmt);
#include <cassert>
#include <ctime>
#include <iomanip>
#include <istream>
#include <cassert>
#include <streambuf>
#include "test_macros.h"
#include "platform_support.h" // locale name macros

View File

@@ -12,9 +12,10 @@
// template <class charT> T10 put_time(const struct tm* tmb, const charT* fmt);
#include <cassert>
#include <ctime>
#include <iomanip>
#include <ostream>
#include <cassert>
#include "test_macros.h"
#include "platform_support.h" // locale name macros

View File

@@ -22,8 +22,10 @@
// get_date(iter_type s, iter_type end, ios_base& str,
// ios_base::iostate& err, tm* t) const;
#include <locale>
#include <cassert>
#include <ctime>
#include <locale>
#include "test_macros.h"
#include "test_iterators.h"

View File

@@ -20,8 +20,10 @@
// get_monthname(iter_type s, iter_type end, ios_base& str,
// ios_base::iostate& err, tm* t) const;
#include <locale>
#include <cassert>
#include <ctime>
#include <locale>
#include "test_macros.h"
#include "test_iterators.h"

View File

@@ -23,8 +23,10 @@
// iter_type get(iter_type s, iter_type end, ios_base& f,
// ios_base::iostate& err, tm *t, char format, char modifier = 0) const;
#include <locale>
#include <cassert>
#include <ctime>
#include <locale>
#include "test_macros.h"
#include "test_iterators.h"

View File

@@ -19,9 +19,11 @@
// get_time(iter_type s, iter_type end, ios_base& str,
// ios_base::iostate& err, tm* t) const;
#include <locale>
#include <cassert>
#include <ctime>
#include <ios>
#include <locale>
#include "test_macros.h"
#include "test_iterators.h"

View File

@@ -19,8 +19,10 @@
// get_weekday(iter_type s, iter_type end, ios_base& str,
// ios_base::iostate& err, tm* t) const;
#include <locale>
#include <cassert>
#include <ctime>
#include <locale>
#include "test_macros.h"
#include "test_iterators.h"

View File

@@ -18,9 +18,11 @@
// iter_type get_year(iter_type s, iter_type end, ios_base& str,
// ios_base::iostate& err, tm* t) const;
#include <locale>
#include <cassert>
#include <ctime>
#include <ios>
#include <locale>
#include "test_macros.h"
#include "test_iterators.h"

View File

@@ -14,9 +14,11 @@
// get_date(iter_type s, iter_type end, ios_base& str,
// ios_base::iostate& err, tm* t) const;
#include <locale>
#include <cassert>
#include <ctime>
#include <ios>
#include <locale>
#include "test_macros.h"
#include "test_iterators.h"

View File

@@ -14,9 +14,11 @@
// get(iter_type s, iter_type end, ios_base& f, ios_base::iostate& err, tm *t,
// const char_type *fmt, const char_type *fmtend) const;
#include <locale>
#include <cassert>
#include <ctime>
#include <ios>
#include <locale>
#include "test_macros.h"
#include "test_iterators.h"

View File

@@ -14,8 +14,10 @@
// get_monthname(iter_type s, iter_type end, ios_base& str,
// ios_base::iostate& err, tm* t) const;
#include <locale>
#include <cassert>
#include <ctime>
#include <locale>
#include "test_macros.h"
#include "test_iterators.h"

View File

@@ -13,8 +13,10 @@
// iter_type get(iter_type s, iter_type end, ios_base& f,
// ios_base::iostate& err, tm *t, char format, char modifier = 0) const;
#include <locale>
#include <cassert>
#include <ctime>
#include <locale>
#include "test_macros.h"
#include "test_iterators.h"

View File

@@ -14,8 +14,10 @@
// get_time(iter_type s, iter_type end, ios_base& str,
// ios_base::iostate& err, tm* t) const;
#include <locale>
#include <cassert>
#include <ctime>
#include <locale>
#include "test_macros.h"
#include "test_iterators.h"

View File

@@ -14,8 +14,10 @@
// get_weekday(iter_type s, iter_type end, ios_base& str,
// ios_base::iostate& err, tm* t) const;
#include <locale>
#include <cassert>
#include <ctime>
#include <locale>
#include "test_macros.h"
#include "test_iterators.h"

View File

@@ -13,9 +13,11 @@
// iter_type get_year(iter_type s, iter_type end, ios_base& str,
// ios_base::iostate& err, tm* t) const;
#include <locale>
#include <cassert>
#include <ctime>
#include <ios>
#include <locale>
#include "test_macros.h"
#include "test_iterators.h"

View File

@@ -9,6 +9,7 @@
#ifndef TEST_SUPPORT_CONCAT_MACROS_H
#define TEST_SUPPORT_CONCAT_MACROS_H
#include <algorithm>
#include <cstdio>
#include <string>
#include <source_location>

View File

@@ -101,8 +101,10 @@ void header_exportable_declarations::registerMatchers(clang::ast_matchers::Match
// Looks at the common locations where headers store their data
// * header
// * __header/*.h
// * __header_dir/*.h // Used for transitioning from __header
// * __fwd/header.h
anyOf(isExpansionInFileMatching(("v1/__" + filename_ + "/").str()),
isExpansionInFileMatching(("v1/__" + filename_ + "_dir/").str()),
isExpansionInFileMatching(extra_header_),
isExpansionInFileMatching(("v1/__fwd/" + filename_ + "\\.h$").str()),
isExpansionInFileMatching(("v1/" + filename_ + "$").str())),