10b57cec5SDimitry Andric// -*- C++ -*- 2349cc55cSDimitry Andric//===----------------------------------------------------------------------===// 30b57cec5SDimitry Andric// 40b57cec5SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 50b57cec5SDimitry Andric// See https://llvm.org/LICENSE.txt for license information. 60b57cec5SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 70b57cec5SDimitry Andric// 80b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 90b57cec5SDimitry Andric 100b57cec5SDimitry Andric#ifndef _LIBCPP_LOCALE 110b57cec5SDimitry Andric#define _LIBCPP_LOCALE 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric/* 140b57cec5SDimitry Andric locale synopsis 150b57cec5SDimitry Andric 160b57cec5SDimitry Andricnamespace std 170b57cec5SDimitry Andric{ 180b57cec5SDimitry Andric 190b57cec5SDimitry Andricclass locale 200b57cec5SDimitry Andric{ 210b57cec5SDimitry Andricpublic: 220b57cec5SDimitry Andric // types: 230b57cec5SDimitry Andric class facet; 240b57cec5SDimitry Andric class id; 250b57cec5SDimitry Andric 260b57cec5SDimitry Andric typedef int category; 270b57cec5SDimitry Andric static const category // values assigned here are for exposition only 280b57cec5SDimitry Andric none = 0x000, 290b57cec5SDimitry Andric collate = 0x010, 300b57cec5SDimitry Andric ctype = 0x020, 310b57cec5SDimitry Andric monetary = 0x040, 320b57cec5SDimitry Andric numeric = 0x080, 330b57cec5SDimitry Andric time = 0x100, 340b57cec5SDimitry Andric messages = 0x200, 350b57cec5SDimitry Andric all = collate | ctype | monetary | numeric | time | messages; 360b57cec5SDimitry Andric 370b57cec5SDimitry Andric // construct/copy/destroy: 380b57cec5SDimitry Andric locale() noexcept; 390b57cec5SDimitry Andric locale(const locale& other) noexcept; 400b57cec5SDimitry Andric explicit locale(const char* std_name); 410b57cec5SDimitry Andric explicit locale(const string& std_name); 420b57cec5SDimitry Andric locale(const locale& other, const char* std_name, category); 430b57cec5SDimitry Andric locale(const locale& other, const string& std_name, category); 440b57cec5SDimitry Andric template <class Facet> locale(const locale& other, Facet* f); 450b57cec5SDimitry Andric locale(const locale& other, const locale& one, category); 460b57cec5SDimitry Andric 470b57cec5SDimitry Andric ~locale(); // not virtual 480b57cec5SDimitry Andric 490b57cec5SDimitry Andric const locale& operator=(const locale& other) noexcept; 500b57cec5SDimitry Andric 510b57cec5SDimitry Andric template <class Facet> locale combine(const locale& other) const; 520b57cec5SDimitry Andric 530b57cec5SDimitry Andric // locale operations: 540b57cec5SDimitry Andric basic_string<char> name() const; 550b57cec5SDimitry Andric bool operator==(const locale& other) const; 5606c3fb27SDimitry Andric bool operator!=(const locale& other) const; // removed C++20 570b57cec5SDimitry Andric template <class charT, class Traits, class Allocator> 580b57cec5SDimitry Andric bool operator()(const basic_string<charT,Traits,Allocator>& s1, 590b57cec5SDimitry Andric const basic_string<charT,Traits,Allocator>& s2) const; 600b57cec5SDimitry Andric 610b57cec5SDimitry Andric // global locale objects: 620b57cec5SDimitry Andric static locale global(const locale&); 630b57cec5SDimitry Andric static const locale& classic(); 640b57cec5SDimitry Andric}; 650b57cec5SDimitry Andric 660b57cec5SDimitry Andrictemplate <class Facet> const Facet& use_facet(const locale&); 670b57cec5SDimitry Andrictemplate <class Facet> bool has_facet(const locale&) noexcept; 680b57cec5SDimitry Andric 690b57cec5SDimitry Andric// 22.3.3, convenience interfaces: 700b57cec5SDimitry Andrictemplate <class charT> bool isspace (charT c, const locale& loc); 710b57cec5SDimitry Andrictemplate <class charT> bool isprint (charT c, const locale& loc); 720b57cec5SDimitry Andrictemplate <class charT> bool iscntrl (charT c, const locale& loc); 730b57cec5SDimitry Andrictemplate <class charT> bool isupper (charT c, const locale& loc); 740b57cec5SDimitry Andrictemplate <class charT> bool islower (charT c, const locale& loc); 750b57cec5SDimitry Andrictemplate <class charT> bool isalpha (charT c, const locale& loc); 760b57cec5SDimitry Andrictemplate <class charT> bool isdigit (charT c, const locale& loc); 770b57cec5SDimitry Andrictemplate <class charT> bool ispunct (charT c, const locale& loc); 780b57cec5SDimitry Andrictemplate <class charT> bool isxdigit(charT c, const locale& loc); 790b57cec5SDimitry Andrictemplate <class charT> bool isalnum (charT c, const locale& loc); 800b57cec5SDimitry Andrictemplate <class charT> bool isgraph (charT c, const locale& loc); 810b57cec5SDimitry Andrictemplate <class charT> charT toupper(charT c, const locale& loc); 820b57cec5SDimitry Andrictemplate <class charT> charT tolower(charT c, const locale& loc); 830b57cec5SDimitry Andric 840b57cec5SDimitry Andrictemplate<class Codecvt, class Elem = wchar_t, 850b57cec5SDimitry Andric class Wide_alloc = allocator<Elem>, 860b57cec5SDimitry Andric class Byte_alloc = allocator<char>> 870b57cec5SDimitry Andricclass wstring_convert 880b57cec5SDimitry Andric{ 890b57cec5SDimitry Andricpublic: 900b57cec5SDimitry Andric typedef basic_string<char, char_traits<char>, Byte_alloc> byte_string; 910b57cec5SDimitry Andric typedef basic_string<Elem, char_traits<Elem>, Wide_alloc> wide_string; 920b57cec5SDimitry Andric typedef typename Codecvt::state_type state_type; 930b57cec5SDimitry Andric typedef typename wide_string::traits_type::int_type int_type; 940b57cec5SDimitry Andric 95e8d8bef9SDimitry Andric wstring_convert(Codecvt* pcvt = new Codecvt); // before C++14 96e8d8bef9SDimitry Andric explicit wstring_convert(Codecvt* pcvt = new Codecvt); // before C++20 97e8d8bef9SDimitry Andric wstring_convert() : wstring_convert(new Codecvt) {} // C++20 98e8d8bef9SDimitry Andric explicit wstring_convert(Codecvt* pcvt); // C++20 99e8d8bef9SDimitry Andric 1000b57cec5SDimitry Andric wstring_convert(Codecvt* pcvt, state_type state); 1010b57cec5SDimitry Andric explicit wstring_convert(const byte_string& byte_err, // explicit in C++14 1020b57cec5SDimitry Andric const wide_string& wide_err = wide_string()); 1030b57cec5SDimitry Andric wstring_convert(const wstring_convert&) = delete; // C++14 1040b57cec5SDimitry Andric wstring_convert & operator=(const wstring_convert &) = delete; // C++14 1050b57cec5SDimitry Andric ~wstring_convert(); 1060b57cec5SDimitry Andric 1070b57cec5SDimitry Andric wide_string from_bytes(char byte); 1080b57cec5SDimitry Andric wide_string from_bytes(const char* ptr); 1090b57cec5SDimitry Andric wide_string from_bytes(const byte_string& str); 1100b57cec5SDimitry Andric wide_string from_bytes(const char* first, const char* last); 1110b57cec5SDimitry Andric 1120b57cec5SDimitry Andric byte_string to_bytes(Elem wchar); 1130b57cec5SDimitry Andric byte_string to_bytes(const Elem* wptr); 1140b57cec5SDimitry Andric byte_string to_bytes(const wide_string& wstr); 1150b57cec5SDimitry Andric byte_string to_bytes(const Elem* first, const Elem* last); 1160b57cec5SDimitry Andric 1170b57cec5SDimitry Andric size_t converted() const; // noexcept in C++14 1180b57cec5SDimitry Andric state_type state() const; 1190b57cec5SDimitry Andric}; 1200b57cec5SDimitry Andric 1210b57cec5SDimitry Andrictemplate <class Codecvt, class Elem = wchar_t, class Tr = char_traits<Elem>> 1220b57cec5SDimitry Andricclass wbuffer_convert 1230b57cec5SDimitry Andric : public basic_streambuf<Elem, Tr> 1240b57cec5SDimitry Andric{ 1250b57cec5SDimitry Andricpublic: 1260b57cec5SDimitry Andric typedef typename Tr::state_type state_type; 1270b57cec5SDimitry Andric 128e8d8bef9SDimitry Andric wbuffer_convert(streambuf* bytebuf = 0, Codecvt* pcvt = new Codecvt, 129e8d8bef9SDimitry Andric state_type state = state_type()); // before C++14 130e8d8bef9SDimitry Andric explicit wbuffer_convert(streambuf* bytebuf = nullptr, Codecvt* pcvt = new Codecvt, 131e8d8bef9SDimitry Andric state_type state = state_type()); // before C++20 132e8d8bef9SDimitry Andric wbuffer_convert() : wbuffer_convert(nullptr) {} // C++20 133e8d8bef9SDimitry Andric explicit wbuffer_convert(streambuf* bytebuf, Codecvt* pcvt = new Codecvt, 134e8d8bef9SDimitry Andric state_type state = state_type()); // C++20 135e8d8bef9SDimitry Andric 1360b57cec5SDimitry Andric wbuffer_convert(const wbuffer_convert&) = delete; // C++14 1370b57cec5SDimitry Andric wbuffer_convert & operator=(const wbuffer_convert &) = delete; // C++14 1380b57cec5SDimitry Andric ~wbuffer_convert(); // C++14 1390b57cec5SDimitry Andric 1400b57cec5SDimitry Andric streambuf* rdbuf() const; 1410b57cec5SDimitry Andric streambuf* rdbuf(streambuf* bytebuf); 1420b57cec5SDimitry Andric 1430b57cec5SDimitry Andric state_type state() const; 1440b57cec5SDimitry Andric}; 1450b57cec5SDimitry Andric 1460b57cec5SDimitry Andric// 22.4.1 and 22.4.1.3, ctype: 1470b57cec5SDimitry Andricclass ctype_base; 1480b57cec5SDimitry Andrictemplate <class charT> class ctype; 1490b57cec5SDimitry Andrictemplate <> class ctype<char>; // specialization 1500b57cec5SDimitry Andrictemplate <class charT> class ctype_byname; 1510b57cec5SDimitry Andrictemplate <> class ctype_byname<char>; // specialization 1520b57cec5SDimitry Andric 1530b57cec5SDimitry Andricclass codecvt_base; 1540b57cec5SDimitry Andrictemplate <class internT, class externT, class stateT> class codecvt; 1550b57cec5SDimitry Andrictemplate <class internT, class externT, class stateT> class codecvt_byname; 1560b57cec5SDimitry Andric 1570b57cec5SDimitry Andric// 22.4.2 and 22.4.3, numeric: 1580b57cec5SDimitry Andrictemplate <class charT, class InputIterator> class num_get; 1590b57cec5SDimitry Andrictemplate <class charT, class OutputIterator> class num_put; 1600b57cec5SDimitry Andrictemplate <class charT> class numpunct; 1610b57cec5SDimitry Andrictemplate <class charT> class numpunct_byname; 1620b57cec5SDimitry Andric 1630b57cec5SDimitry Andric// 22.4.4, col lation: 1640b57cec5SDimitry Andrictemplate <class charT> class collate; 1650b57cec5SDimitry Andrictemplate <class charT> class collate_byname; 1660b57cec5SDimitry Andric 1670b57cec5SDimitry Andric// 22.4.5, date and time: 1680b57cec5SDimitry Andricclass time_base; 1690b57cec5SDimitry Andrictemplate <class charT, class InputIterator> class time_get; 1700b57cec5SDimitry Andrictemplate <class charT, class InputIterator> class time_get_byname; 1710b57cec5SDimitry Andrictemplate <class charT, class OutputIterator> class time_put; 1720b57cec5SDimitry Andrictemplate <class charT, class OutputIterator> class time_put_byname; 1730b57cec5SDimitry Andric 1740b57cec5SDimitry Andric// 22.4.6, money: 1750b57cec5SDimitry Andricclass money_base; 1760b57cec5SDimitry Andrictemplate <class charT, class InputIterator> class money_get; 1770b57cec5SDimitry Andrictemplate <class charT, class OutputIterator> class money_put; 1780b57cec5SDimitry Andrictemplate <class charT, bool Intl> class moneypunct; 1790b57cec5SDimitry Andrictemplate <class charT, bool Intl> class moneypunct_byname; 1800b57cec5SDimitry Andric 1810b57cec5SDimitry Andric// 22.4.7, message retrieval: 1820b57cec5SDimitry Andricclass messages_base; 1830b57cec5SDimitry Andrictemplate <class charT> class messages; 1840b57cec5SDimitry Andrictemplate <class charT> class messages_byname; 1850b57cec5SDimitry Andric 1860b57cec5SDimitry Andric} // std 1870b57cec5SDimitry Andric 1880b57cec5SDimitry Andric*/ 1890b57cec5SDimitry Andric 19081ad6265SDimitry Andric#include <__algorithm/copy.h> 19181ad6265SDimitry Andric#include <__algorithm/equal.h> 19281ad6265SDimitry Andric#include <__algorithm/find.h> 19381ad6265SDimitry Andric#include <__algorithm/max.h> 19481ad6265SDimitry Andric#include <__algorithm/reverse.h> 19581ad6265SDimitry Andric#include <__algorithm/unwrap_iter.h> 19681ad6265SDimitry Andric#include <__assert> // all public C++ headers provide the assertion handler 1970b57cec5SDimitry Andric#include <__config> 19881ad6265SDimitry Andric#include <__iterator/access.h> 19981ad6265SDimitry Andric#include <__iterator/back_insert_iterator.h> 20081ad6265SDimitry Andric#include <__iterator/istreambuf_iterator.h> 20181ad6265SDimitry Andric#include <__iterator/ostreambuf_iterator.h> 202fe6060f1SDimitry Andric#include <__locale> 203bdd1243dSDimitry Andric#include <__memory/unique_ptr.h> 20406c3fb27SDimitry Andric#include <__type_traits/make_unsigned.h> 20506c3fb27SDimitry Andric#include <cerrno> 206fe6060f1SDimitry Andric#include <cstdio> 2070b57cec5SDimitry Andric#include <cstdlib> 2080b57cec5SDimitry Andric#include <ctime> 209fe6060f1SDimitry Andric#include <ios> 210fe6060f1SDimitry Andric#include <limits> 211bdd1243dSDimitry Andric#include <new> 212fe6060f1SDimitry Andric#include <streambuf> 213fe6060f1SDimitry Andric#include <version> 214fe6060f1SDimitry Andric 215bdd1243dSDimitry Andric// TODO: Fix __bsd_locale_defaults.h 216bdd1243dSDimitry Andric// NOLINTBEGIN(libcpp-robust-against-adl) 21781ad6265SDimitry Andric 218fe6060f1SDimitry Andric#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) 219fe6060f1SDimitry Andric// Most unix variants have catopen. These are the specific ones that don't. 22081ad6265SDimitry Andric# if !defined(__BIONIC__) && !defined(_NEWLIB_VERSION) && !defined(__EMSCRIPTEN__) 221fe6060f1SDimitry Andric# define _LIBCPP_HAS_CATOPEN 1 2220b57cec5SDimitry Andric# include <nl_types.h> 2230b57cec5SDimitry Andric# endif 224fe6060f1SDimitry Andric#endif 2250b57cec5SDimitry Andric 2260b57cec5SDimitry Andric#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 22706c3fb27SDimitry Andric# include <__locale_dir/locale_base_api/bsd_locale_defaults.h> 2280b57cec5SDimitry Andric#else 22906c3fb27SDimitry Andric# include <__locale_dir/locale_base_api/bsd_locale_fallbacks.h> 2300b57cec5SDimitry Andric#endif 2310b57cec5SDimitry Andric 2320b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 2330b57cec5SDimitry Andric# pragma GCC system_header 2340b57cec5SDimitry Andric#endif 2350b57cec5SDimitry Andric 2360b57cec5SDimitry Andric_LIBCPP_PUSH_MACROS 2370b57cec5SDimitry Andric#include <__undef_macros> 2380b57cec5SDimitry Andric 2390b57cec5SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD 2400b57cec5SDimitry Andric 2410b57cec5SDimitry Andric#if defined(__APPLE__) || defined(__FreeBSD__) 2420b57cec5SDimitry Andric# define _LIBCPP_GET_C_LOCALE 0 243349cc55cSDimitry Andric#elif defined(__NetBSD__) 2440b57cec5SDimitry Andric# define _LIBCPP_GET_C_LOCALE LC_C_LOCALE 2450b57cec5SDimitry Andric#else 2460b57cec5SDimitry Andric# define _LIBCPP_GET_C_LOCALE __cloc() 2470b57cec5SDimitry Andric// Get the C locale object 24806c3fb27SDimitry Andric_LIBCPP_EXPORTED_FROM_ABI locale_t __cloc(); 2490b57cec5SDimitry Andric# define __cloc_defined 2500b57cec5SDimitry Andric#endif 2510b57cec5SDimitry Andric 2520b57cec5SDimitry Andric// __scan_keyword 2530b57cec5SDimitry Andric// Scans [__b, __e) until a match is found in the basic_strings range 2540b57cec5SDimitry Andric// [__kb, __ke) or until it can be shown that there is no match in [__kb, __ke). 2550b57cec5SDimitry Andric// __b will be incremented (visibly), consuming CharT until a match is found 2560b57cec5SDimitry Andric// or proved to not exist. A keyword may be "", in which will match anything. 2570b57cec5SDimitry Andric// If one keyword is a prefix of another, and the next CharT in the input 2580b57cec5SDimitry Andric// might match another keyword, the algorithm will attempt to find the longest 2590b57cec5SDimitry Andric// matching keyword. If the longer matching keyword ends up not matching, then 2600b57cec5SDimitry Andric// no keyword match is found. If no keyword match is found, __ke is returned 2610b57cec5SDimitry Andric// and failbit is set in __err. 2620b57cec5SDimitry Andric// Else an iterator pointing to the matching keyword is found. If more than 2630b57cec5SDimitry Andric// one keyword matches, an iterator to the first matching keyword is returned. 2640b57cec5SDimitry Andric// If on exit __b == __e, eofbit is set in __err. If __case_sensitive is false, 2650b57cec5SDimitry Andric// __ct is used to force to lower case before comparing characters. 2660b57cec5SDimitry Andric// Examples: 2670b57cec5SDimitry Andric// Keywords: "a", "abb" 2680b57cec5SDimitry Andric// If the input is "a", the first keyword matches and eofbit is set. 2690b57cec5SDimitry Andric// If the input is "abc", no match is found and "ab" are consumed. 2700b57cec5SDimitry Andrictemplate <class _InputIterator, class _ForwardIterator, class _Ctype> 271cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI _ForwardIterator __scan_keyword( 272cb14a3feSDimitry Andric _InputIterator& __b, 273cb14a3feSDimitry Andric _InputIterator __e, 274cb14a3feSDimitry Andric _ForwardIterator __kb, 275cb14a3feSDimitry Andric _ForwardIterator __ke, 276cb14a3feSDimitry Andric const _Ctype& __ct, 277cb14a3feSDimitry Andric ios_base::iostate& __err, 278cb14a3feSDimitry Andric bool __case_sensitive = true) { 2790b57cec5SDimitry Andric typedef typename iterator_traits<_InputIterator>::value_type _CharT; 2805f757f3fSDimitry Andric size_t __nkw = static_cast<size_t>(std::distance(__kb, __ke)); 2810b57cec5SDimitry Andric const unsigned char __doesnt_match = '\0'; 2820b57cec5SDimitry Andric const unsigned char __might_match = '\1'; 2830b57cec5SDimitry Andric const unsigned char __does_match = '\2'; 2840b57cec5SDimitry Andric unsigned char __statbuf[100]; 2850b57cec5SDimitry Andric unsigned char* __status = __statbuf; 286e8d8bef9SDimitry Andric unique_ptr<unsigned char, void (*)(void*)> __stat_hold(nullptr, free); 287cb14a3feSDimitry Andric if (__nkw > sizeof(__statbuf)) { 2880b57cec5SDimitry Andric __status = (unsigned char*)malloc(__nkw); 289e8d8bef9SDimitry Andric if (__status == nullptr) 2900b57cec5SDimitry Andric __throw_bad_alloc(); 2910b57cec5SDimitry Andric __stat_hold.reset(__status); 2920b57cec5SDimitry Andric } 2930b57cec5SDimitry Andric size_t __n_might_match = __nkw; // At this point, any keyword might match 2940b57cec5SDimitry Andric size_t __n_does_match = 0; // but none of them definitely do 2950b57cec5SDimitry Andric // Initialize all statuses to __might_match, except for "" keywords are __does_match 2960b57cec5SDimitry Andric unsigned char* __st = __status; 297cb14a3feSDimitry Andric for (_ForwardIterator __ky = __kb; __ky != __ke; ++__ky, (void)++__st) { 2980b57cec5SDimitry Andric if (!__ky->empty()) 2990b57cec5SDimitry Andric *__st = __might_match; 300cb14a3feSDimitry Andric else { 3010b57cec5SDimitry Andric *__st = __does_match; 3020b57cec5SDimitry Andric --__n_might_match; 3030b57cec5SDimitry Andric ++__n_does_match; 3040b57cec5SDimitry Andric } 3050b57cec5SDimitry Andric } 3060b57cec5SDimitry Andric // While there might be a match, test keywords against the next CharT 307cb14a3feSDimitry Andric for (size_t __indx = 0; __b != __e && __n_might_match > 0; ++__indx) { 3080b57cec5SDimitry Andric // Peek at the next CharT but don't consume it 3090b57cec5SDimitry Andric _CharT __c = *__b; 3100b57cec5SDimitry Andric if (!__case_sensitive) 3110b57cec5SDimitry Andric __c = __ct.toupper(__c); 3120b57cec5SDimitry Andric bool __consume = false; 3130b57cec5SDimitry Andric // For each keyword which might match, see if the __indx character is __c 3140b57cec5SDimitry Andric // If a match if found, consume __c 3150b57cec5SDimitry Andric // If a match is found, and that is the last character in the keyword, 3160b57cec5SDimitry Andric // then that keyword matches. 3170b57cec5SDimitry Andric // If the keyword doesn't match this character, then change the keyword 3180b57cec5SDimitry Andric // to doesn't match 3190b57cec5SDimitry Andric __st = __status; 320cb14a3feSDimitry Andric for (_ForwardIterator __ky = __kb; __ky != __ke; ++__ky, (void)++__st) { 321cb14a3feSDimitry Andric if (*__st == __might_match) { 3220b57cec5SDimitry Andric _CharT __kc = (*__ky)[__indx]; 3230b57cec5SDimitry Andric if (!__case_sensitive) 3240b57cec5SDimitry Andric __kc = __ct.toupper(__kc); 325cb14a3feSDimitry Andric if (__c == __kc) { 3260b57cec5SDimitry Andric __consume = true; 327cb14a3feSDimitry Andric if (__ky->size() == __indx + 1) { 3280b57cec5SDimitry Andric *__st = __does_match; 3290b57cec5SDimitry Andric --__n_might_match; 3300b57cec5SDimitry Andric ++__n_does_match; 3310b57cec5SDimitry Andric } 332cb14a3feSDimitry Andric } else { 3330b57cec5SDimitry Andric *__st = __doesnt_match; 3340b57cec5SDimitry Andric --__n_might_match; 3350b57cec5SDimitry Andric } 3360b57cec5SDimitry Andric } 3370b57cec5SDimitry Andric } 3380b57cec5SDimitry Andric // consume if we matched a character 339cb14a3feSDimitry Andric if (__consume) { 3400b57cec5SDimitry Andric ++__b; 3410b57cec5SDimitry Andric // If we consumed a character and there might be a matched keyword that 3420b57cec5SDimitry Andric // was marked matched on a previous iteration, then such keywords 3430b57cec5SDimitry Andric // which are now marked as not matching. 344cb14a3feSDimitry Andric if (__n_might_match + __n_does_match > 1) { 3450b57cec5SDimitry Andric __st = __status; 346cb14a3feSDimitry Andric for (_ForwardIterator __ky = __kb; __ky != __ke; ++__ky, (void)++__st) { 347cb14a3feSDimitry Andric if (*__st == __does_match && __ky->size() != __indx + 1) { 3480b57cec5SDimitry Andric *__st = __doesnt_match; 3490b57cec5SDimitry Andric --__n_does_match; 3500b57cec5SDimitry Andric } 3510b57cec5SDimitry Andric } 3520b57cec5SDimitry Andric } 3530b57cec5SDimitry Andric } 3540b57cec5SDimitry Andric } 3550b57cec5SDimitry Andric // We've exited the loop because we hit eof and/or we have no more "might matches". 3560b57cec5SDimitry Andric if (__b == __e) 3570b57cec5SDimitry Andric __err |= ios_base::eofbit; 3580b57cec5SDimitry Andric // Return the first matching result 3590b57cec5SDimitry Andric for (__st = __status; __kb != __ke; ++__kb, (void)++__st) 3600b57cec5SDimitry Andric if (*__st == __does_match) 3610b57cec5SDimitry Andric break; 3620b57cec5SDimitry Andric if (__kb == __ke) 3630b57cec5SDimitry Andric __err |= ios_base::failbit; 3640b57cec5SDimitry Andric return __kb; 3650b57cec5SDimitry Andric} 3660b57cec5SDimitry Andric 367cb14a3feSDimitry Andricstruct _LIBCPP_EXPORTED_FROM_ABI __num_get_base { 3680b57cec5SDimitry Andric static const int __num_get_buf_sz = 40; 3690b57cec5SDimitry Andric 3700b57cec5SDimitry Andric static int __get_base(ios_base&); 3710b57cec5SDimitry Andric static const char __src[33]; 3720b57cec5SDimitry Andric}; 3730b57cec5SDimitry Andric 374cb14a3feSDimitry Andric_LIBCPP_EXPORTED_FROM_ABI void 375cb14a3feSDimitry Andric__check_grouping(const string& __grouping, unsigned* __g, unsigned* __g_end, ios_base::iostate& __err); 3760b57cec5SDimitry Andric 3770b57cec5SDimitry Andrictemplate <class _CharT> 378cb14a3feSDimitry Andricstruct __num_get : protected __num_get_base { 379cb14a3feSDimitry Andric static string __stage2_float_prep(ios_base& __iob, _CharT* __atoms, _CharT& __decimal_point, _CharT& __thousands_sep); 3800b57cec5SDimitry Andric 381cb14a3feSDimitry Andric static int __stage2_float_loop( 382cb14a3feSDimitry Andric _CharT __ct, 383cb14a3feSDimitry Andric bool& __in_units, 384cb14a3feSDimitry Andric char& __exp, 385cb14a3feSDimitry Andric char* __a, 386cb14a3feSDimitry Andric char*& __a_end, 387cb14a3feSDimitry Andric _CharT __decimal_point, 388cb14a3feSDimitry Andric _CharT __thousands_sep, 389cb14a3feSDimitry Andric const string& __grouping, 390cb14a3feSDimitry Andric unsigned* __g, 391cb14a3feSDimitry Andric unsigned*& __g_end, 392cb14a3feSDimitry Andric unsigned& __dc, 393cb14a3feSDimitry Andric _CharT* __atoms); 3940b57cec5SDimitry Andric#ifndef _LIBCPP_ABI_OPTIMIZED_LOCALE_NUM_GET 3950b57cec5SDimitry Andric static string __stage2_int_prep(ios_base& __iob, _CharT* __atoms, _CharT& __thousands_sep); 396cb14a3feSDimitry Andric static int __stage2_int_loop( 397cb14a3feSDimitry Andric _CharT __ct, 398cb14a3feSDimitry Andric int __base, 399cb14a3feSDimitry Andric char* __a, 400cb14a3feSDimitry Andric char*& __a_end, 401cb14a3feSDimitry Andric unsigned& __dc, 402cb14a3feSDimitry Andric _CharT __thousands_sep, 403cb14a3feSDimitry Andric const string& __grouping, 404cb14a3feSDimitry Andric unsigned* __g, 405cb14a3feSDimitry Andric unsigned*& __g_end, 406cb14a3feSDimitry Andric _CharT* __atoms); 4070b57cec5SDimitry Andric 4080b57cec5SDimitry Andric#else 409cb14a3feSDimitry Andric static string __stage2_int_prep(ios_base& __iob, _CharT& __thousands_sep) { 4100b57cec5SDimitry Andric locale __loc = __iob.getloc(); 4110b57cec5SDimitry Andric const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc); 4120b57cec5SDimitry Andric __thousands_sep = __np.thousands_sep(); 4130b57cec5SDimitry Andric return __np.grouping(); 4140b57cec5SDimitry Andric } 4150b57cec5SDimitry Andric 416cb14a3feSDimitry Andric const _CharT* __do_widen(ios_base& __iob, _CharT* __atoms) const { return __do_widen_p(__iob, __atoms); } 4170b57cec5SDimitry Andric 418cb14a3feSDimitry Andric static int __stage2_int_loop( 419cb14a3feSDimitry Andric _CharT __ct, 420cb14a3feSDimitry Andric int __base, 421cb14a3feSDimitry Andric char* __a, 422cb14a3feSDimitry Andric char*& __a_end, 423cb14a3feSDimitry Andric unsigned& __dc, 424cb14a3feSDimitry Andric _CharT __thousands_sep, 425cb14a3feSDimitry Andric const string& __grouping, 426cb14a3feSDimitry Andric unsigned* __g, 427cb14a3feSDimitry Andric unsigned*& __g_end, 428cb14a3feSDimitry Andric const _CharT* __atoms); 4290b57cec5SDimitry Andric 4300b57cec5SDimitry Andricprivate: 43104eeddc0SDimitry Andric template <typename _Tp> 432cb14a3feSDimitry Andric const _Tp* __do_widen_p(ios_base& __iob, _Tp* __atoms) const { 4330b57cec5SDimitry Andric locale __loc = __iob.getloc(); 43404eeddc0SDimitry Andric use_facet<ctype<_Tp> >(__loc).widen(__src, __src + 26, __atoms); 4350b57cec5SDimitry Andric return __atoms; 4360b57cec5SDimitry Andric } 4370b57cec5SDimitry Andric 438cb14a3feSDimitry Andric const char* __do_widen_p(ios_base& __iob, char* __atoms) const { 4390b57cec5SDimitry Andric (void)__iob; 4400b57cec5SDimitry Andric (void)__atoms; 4410b57cec5SDimitry Andric return __src; 4420b57cec5SDimitry Andric } 4430b57cec5SDimitry Andric#endif 4440b57cec5SDimitry Andric}; 4450b57cec5SDimitry Andric 4460b57cec5SDimitry Andric#ifndef _LIBCPP_ABI_OPTIMIZED_LOCALE_NUM_GET 4470b57cec5SDimitry Andrictemplate <class _CharT> 448cb14a3feSDimitry Andricstring __num_get<_CharT>::__stage2_int_prep(ios_base& __iob, _CharT* __atoms, _CharT& __thousands_sep) { 4490b57cec5SDimitry Andric locale __loc = __iob.getloc(); 450bdd1243dSDimitry Andric std::use_facet<ctype<_CharT> >(__loc).widen(__src, __src + 26, __atoms); 451bdd1243dSDimitry Andric const numpunct<_CharT>& __np = std::use_facet<numpunct<_CharT> >(__loc); 4520b57cec5SDimitry Andric __thousands_sep = __np.thousands_sep(); 4530b57cec5SDimitry Andric return __np.grouping(); 4540b57cec5SDimitry Andric} 4550b57cec5SDimitry Andric#endif 4560b57cec5SDimitry Andric 4570b57cec5SDimitry Andrictemplate <class _CharT> 458cb14a3feSDimitry Andricstring __num_get<_CharT>::__stage2_float_prep( 459cb14a3feSDimitry Andric ios_base& __iob, _CharT* __atoms, _CharT& __decimal_point, _CharT& __thousands_sep) { 4600b57cec5SDimitry Andric locale __loc = __iob.getloc(); 461bdd1243dSDimitry Andric std::use_facet<ctype<_CharT> >(__loc).widen(__src, __src + 32, __atoms); 462bdd1243dSDimitry Andric const numpunct<_CharT>& __np = std::use_facet<numpunct<_CharT> >(__loc); 4630b57cec5SDimitry Andric __decimal_point = __np.decimal_point(); 4640b57cec5SDimitry Andric __thousands_sep = __np.thousands_sep(); 4650b57cec5SDimitry Andric return __np.grouping(); 4660b57cec5SDimitry Andric} 4670b57cec5SDimitry Andric 4680b57cec5SDimitry Andrictemplate <class _CharT> 4690b57cec5SDimitry Andricint 4700b57cec5SDimitry Andric#ifndef _LIBCPP_ABI_OPTIMIZED_LOCALE_NUM_GET 4710b57cec5SDimitry Andric__num_get<_CharT>::__stage2_int_loop(_CharT __ct, int __base, char* __a, char*& __a_end, 4720b57cec5SDimitry Andric unsigned& __dc, _CharT __thousands_sep, const string& __grouping, 4730b57cec5SDimitry Andric unsigned* __g, unsigned*& __g_end, _CharT* __atoms) 4740b57cec5SDimitry Andric#else 4750b57cec5SDimitry Andric__num_get<_CharT>::__stage2_int_loop(_CharT __ct, int __base, char* __a, char*& __a_end, 4760b57cec5SDimitry Andric unsigned& __dc, _CharT __thousands_sep, const string& __grouping, 4770b57cec5SDimitry Andric unsigned* __g, unsigned*& __g_end, const _CharT* __atoms) 4780b57cec5SDimitry Andric 4790b57cec5SDimitry Andric#endif 4800b57cec5SDimitry Andric{ 481cb14a3feSDimitry Andric if (__a_end == __a && (__ct == __atoms[24] || __ct == __atoms[25])) { 4820b57cec5SDimitry Andric *__a_end++ = __ct == __atoms[24] ? '+' : '-'; 4830b57cec5SDimitry Andric __dc = 0; 4840b57cec5SDimitry Andric return 0; 4850b57cec5SDimitry Andric } 486cb14a3feSDimitry Andric if (__grouping.size() != 0 && __ct == __thousands_sep) { 487cb14a3feSDimitry Andric if (__g_end - __g < __num_get_buf_sz) { 4880b57cec5SDimitry Andric *__g_end++ = __dc; 4890b57cec5SDimitry Andric __dc = 0; 4900b57cec5SDimitry Andric } 4910b57cec5SDimitry Andric return 0; 4920b57cec5SDimitry Andric } 493bdd1243dSDimitry Andric ptrdiff_t __f = std::find(__atoms, __atoms + 26, __ct) - __atoms; 4940b57cec5SDimitry Andric if (__f >= 24) 4950b57cec5SDimitry Andric return -1; 496cb14a3feSDimitry Andric switch (__base) { 4970b57cec5SDimitry Andric case 8: 4980b57cec5SDimitry Andric case 10: 4990b57cec5SDimitry Andric if (__f >= __base) 5000b57cec5SDimitry Andric return -1; 5010b57cec5SDimitry Andric break; 5020b57cec5SDimitry Andric case 16: 5030b57cec5SDimitry Andric if (__f < 22) 5040b57cec5SDimitry Andric break; 505cb14a3feSDimitry Andric if (__a_end != __a && __a_end - __a <= 2 && __a_end[-1] == '0') { 5060b57cec5SDimitry Andric __dc = 0; 5070b57cec5SDimitry Andric *__a_end++ = __src[__f]; 5080b57cec5SDimitry Andric return 0; 5090b57cec5SDimitry Andric } 5100b57cec5SDimitry Andric return -1; 5110b57cec5SDimitry Andric } 5120b57cec5SDimitry Andric *__a_end++ = __src[__f]; 5130b57cec5SDimitry Andric ++__dc; 5140b57cec5SDimitry Andric return 0; 5150b57cec5SDimitry Andric} 5160b57cec5SDimitry Andric 5170b57cec5SDimitry Andrictemplate <class _CharT> 518cb14a3feSDimitry Andricint __num_get<_CharT>::__stage2_float_loop( 519cb14a3feSDimitry Andric _CharT __ct, 520cb14a3feSDimitry Andric bool& __in_units, 521cb14a3feSDimitry Andric char& __exp, 522cb14a3feSDimitry Andric char* __a, 523cb14a3feSDimitry Andric char*& __a_end, 524cb14a3feSDimitry Andric _CharT __decimal_point, 525cb14a3feSDimitry Andric _CharT __thousands_sep, 526cb14a3feSDimitry Andric const string& __grouping, 527cb14a3feSDimitry Andric unsigned* __g, 528cb14a3feSDimitry Andric unsigned*& __g_end, 529cb14a3feSDimitry Andric unsigned& __dc, 530cb14a3feSDimitry Andric _CharT* __atoms) { 531cb14a3feSDimitry Andric if (__ct == __decimal_point) { 5320b57cec5SDimitry Andric if (!__in_units) 5330b57cec5SDimitry Andric return -1; 5340b57cec5SDimitry Andric __in_units = false; 5350b57cec5SDimitry Andric *__a_end++ = '.'; 5360b57cec5SDimitry Andric if (__grouping.size() != 0 && __g_end - __g < __num_get_buf_sz) 5370b57cec5SDimitry Andric *__g_end++ = __dc; 5380b57cec5SDimitry Andric return 0; 5390b57cec5SDimitry Andric } 540cb14a3feSDimitry Andric if (__ct == __thousands_sep && __grouping.size() != 0) { 5410b57cec5SDimitry Andric if (!__in_units) 5420b57cec5SDimitry Andric return -1; 543cb14a3feSDimitry Andric if (__g_end - __g < __num_get_buf_sz) { 5440b57cec5SDimitry Andric *__g_end++ = __dc; 5450b57cec5SDimitry Andric __dc = 0; 5460b57cec5SDimitry Andric } 5470b57cec5SDimitry Andric return 0; 5480b57cec5SDimitry Andric } 549bdd1243dSDimitry Andric ptrdiff_t __f = std::find(__atoms, __atoms + 32, __ct) - __atoms; 5500b57cec5SDimitry Andric if (__f >= 32) 5510b57cec5SDimitry Andric return -1; 5520b57cec5SDimitry Andric char __x = __src[__f]; 553cb14a3feSDimitry Andric if (__x == '-' || __x == '+') { 554cb14a3feSDimitry Andric if (__a_end == __a || (std::toupper(__a_end[-1]) == std::toupper(__exp))) { 5550b57cec5SDimitry Andric *__a_end++ = __x; 5560b57cec5SDimitry Andric return 0; 5570b57cec5SDimitry Andric } 5580b57cec5SDimitry Andric return -1; 5590b57cec5SDimitry Andric } 5600b57cec5SDimitry Andric if (__x == 'x' || __x == 'X') 5610b57cec5SDimitry Andric __exp = 'P'; 562cb14a3feSDimitry Andric else if (std::toupper(__x) == __exp) { 563bdd1243dSDimitry Andric __exp = std::tolower(__exp); 564cb14a3feSDimitry Andric if (__in_units) { 5650b57cec5SDimitry Andric __in_units = false; 5660b57cec5SDimitry Andric if (__grouping.size() != 0 && __g_end - __g < __num_get_buf_sz) 5670b57cec5SDimitry Andric *__g_end++ = __dc; 5680b57cec5SDimitry Andric } 5690b57cec5SDimitry Andric } 5700b57cec5SDimitry Andric *__a_end++ = __x; 5710b57cec5SDimitry Andric if (__f >= 22) 5720b57cec5SDimitry Andric return 0; 5730b57cec5SDimitry Andric ++__dc; 5740b57cec5SDimitry Andric return 0; 5750b57cec5SDimitry Andric} 5760b57cec5SDimitry Andric 57781ad6265SDimitry Andricextern template struct _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __num_get<char>; 578349cc55cSDimitry Andric#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 57981ad6265SDimitry Andricextern template struct _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __num_get<wchar_t>; 580349cc55cSDimitry Andric#endif 5810b57cec5SDimitry Andric 5820b57cec5SDimitry Andrictemplate <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> > 583cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS num_get : public locale::facet, private __num_get<_CharT> { 5840b57cec5SDimitry Andricpublic: 5850b57cec5SDimitry Andric typedef _CharT char_type; 5860b57cec5SDimitry Andric typedef _InputIterator iter_type; 5870b57cec5SDimitry Andric 588cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit num_get(size_t __refs = 0) : locale::facet(__refs) {} 5890b57cec5SDimitry Andric 590cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iter_type 591cb14a3feSDimitry Andric get(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, bool& __v) const { 5920b57cec5SDimitry Andric return do_get(__b, __e, __iob, __err, __v); 5930b57cec5SDimitry Andric } 5940b57cec5SDimitry Andric 595cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iter_type 596cb14a3feSDimitry Andric get(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, long& __v) const { 5970b57cec5SDimitry Andric return do_get(__b, __e, __iob, __err, __v); 5980b57cec5SDimitry Andric } 5990b57cec5SDimitry Andric 600cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iter_type 601cb14a3feSDimitry Andric get(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, long long& __v) const { 6020b57cec5SDimitry Andric return do_get(__b, __e, __iob, __err, __v); 6030b57cec5SDimitry Andric } 6040b57cec5SDimitry Andric 605cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iter_type 606cb14a3feSDimitry Andric get(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, unsigned short& __v) const { 6070b57cec5SDimitry Andric return do_get(__b, __e, __iob, __err, __v); 6080b57cec5SDimitry Andric } 6090b57cec5SDimitry Andric 610cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iter_type 611cb14a3feSDimitry Andric get(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, unsigned int& __v) const { 6120b57cec5SDimitry Andric return do_get(__b, __e, __iob, __err, __v); 6130b57cec5SDimitry Andric } 6140b57cec5SDimitry Andric 615cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iter_type 616cb14a3feSDimitry Andric get(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, unsigned long& __v) const { 6170b57cec5SDimitry Andric return do_get(__b, __e, __iob, __err, __v); 6180b57cec5SDimitry Andric } 6190b57cec5SDimitry Andric 620cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iter_type 621cb14a3feSDimitry Andric get(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, unsigned long long& __v) const { 6220b57cec5SDimitry Andric return do_get(__b, __e, __iob, __err, __v); 6230b57cec5SDimitry Andric } 6240b57cec5SDimitry Andric 625cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iter_type 626cb14a3feSDimitry Andric get(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, float& __v) const { 6270b57cec5SDimitry Andric return do_get(__b, __e, __iob, __err, __v); 6280b57cec5SDimitry Andric } 6290b57cec5SDimitry Andric 630cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iter_type 631cb14a3feSDimitry Andric get(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, double& __v) const { 6320b57cec5SDimitry Andric return do_get(__b, __e, __iob, __err, __v); 6330b57cec5SDimitry Andric } 6340b57cec5SDimitry Andric 635cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iter_type 636cb14a3feSDimitry Andric get(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, long double& __v) const { 6370b57cec5SDimitry Andric return do_get(__b, __e, __iob, __err, __v); 6380b57cec5SDimitry Andric } 6390b57cec5SDimitry Andric 640cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iter_type 641cb14a3feSDimitry Andric get(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, void*& __v) const { 6420b57cec5SDimitry Andric return do_get(__b, __e, __iob, __err, __v); 6430b57cec5SDimitry Andric } 6440b57cec5SDimitry Andric 6450b57cec5SDimitry Andric static locale::id id; 6460b57cec5SDimitry Andric 6470b57cec5SDimitry Andricprotected: 648bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI_VIRTUAL ~num_get() override {} 6490b57cec5SDimitry Andric 6500b57cec5SDimitry Andric template <class _Fp> 651cb14a3feSDimitry Andric _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS iter_type 652cb14a3feSDimitry Andric __do_get_floating_point(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, _Fp& __v) const; 6530b57cec5SDimitry Andric 6540b57cec5SDimitry Andric template <class _Signed> 655cb14a3feSDimitry Andric _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS iter_type 656cb14a3feSDimitry Andric __do_get_signed(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, _Signed& __v) const; 6570b57cec5SDimitry Andric 6580b57cec5SDimitry Andric template <class _Unsigned> 659cb14a3feSDimitry Andric _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS iter_type 660cb14a3feSDimitry Andric __do_get_unsigned(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, _Unsigned& __v) const; 6610b57cec5SDimitry Andric 662cb14a3feSDimitry Andric virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, bool& __v) const; 6630b57cec5SDimitry Andric 664cb14a3feSDimitry Andric virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, long& __v) const { 665cb14a3feSDimitry Andric return this->__do_get_signed(__b, __e, __iob, __err, __v); 666cb14a3feSDimitry Andric } 6670b57cec5SDimitry Andric 668cb14a3feSDimitry Andric virtual iter_type 669cb14a3feSDimitry Andric do_get(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, long long& __v) const { 670cb14a3feSDimitry Andric return this->__do_get_signed(__b, __e, __iob, __err, __v); 671cb14a3feSDimitry Andric } 6720b57cec5SDimitry Andric 673cb14a3feSDimitry Andric virtual iter_type 674cb14a3feSDimitry Andric do_get(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, unsigned short& __v) const { 675cb14a3feSDimitry Andric return this->__do_get_unsigned(__b, __e, __iob, __err, __v); 676cb14a3feSDimitry Andric } 6770b57cec5SDimitry Andric 678cb14a3feSDimitry Andric virtual iter_type 679cb14a3feSDimitry Andric do_get(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, unsigned int& __v) const { 680cb14a3feSDimitry Andric return this->__do_get_unsigned(__b, __e, __iob, __err, __v); 681cb14a3feSDimitry Andric } 6820b57cec5SDimitry Andric 683cb14a3feSDimitry Andric virtual iter_type 684cb14a3feSDimitry Andric do_get(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, unsigned long& __v) const { 685cb14a3feSDimitry Andric return this->__do_get_unsigned(__b, __e, __iob, __err, __v); 686cb14a3feSDimitry Andric } 6870b57cec5SDimitry Andric 688cb14a3feSDimitry Andric virtual iter_type 689cb14a3feSDimitry Andric do_get(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, unsigned long long& __v) const { 690cb14a3feSDimitry Andric return this->__do_get_unsigned(__b, __e, __iob, __err, __v); 691cb14a3feSDimitry Andric } 6920b57cec5SDimitry Andric 693cb14a3feSDimitry Andric virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, float& __v) const { 694cb14a3feSDimitry Andric return this->__do_get_floating_point(__b, __e, __iob, __err, __v); 695cb14a3feSDimitry Andric } 6960b57cec5SDimitry Andric 697cb14a3feSDimitry Andric virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, double& __v) const { 698cb14a3feSDimitry Andric return this->__do_get_floating_point(__b, __e, __iob, __err, __v); 699cb14a3feSDimitry Andric } 7000b57cec5SDimitry Andric 701cb14a3feSDimitry Andric virtual iter_type 702cb14a3feSDimitry Andric do_get(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, long double& __v) const { 703cb14a3feSDimitry Andric return this->__do_get_floating_point(__b, __e, __iob, __err, __v); 704cb14a3feSDimitry Andric } 7050b57cec5SDimitry Andric 706cb14a3feSDimitry Andric virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, void*& __v) const; 7070b57cec5SDimitry Andric}; 7080b57cec5SDimitry Andric 7090b57cec5SDimitry Andrictemplate <class _CharT, class _InputIterator> 710cb14a3feSDimitry Andriclocale::id num_get<_CharT, _InputIterator>::id; 7110b57cec5SDimitry Andric 7120b57cec5SDimitry Andrictemplate <class _Tp> 713bdd1243dSDimitry Andric_LIBCPP_HIDE_FROM_ABI _Tp 714cb14a3feSDimitry Andric__num_get_signed_integral(const char* __a, const char* __a_end, ios_base::iostate& __err, int __base) { 715cb14a3feSDimitry Andric if (__a != __a_end) { 716bdd1243dSDimitry Andric __libcpp_remove_reference_t<decltype(errno)> __save_errno = errno; 7170b57cec5SDimitry Andric errno = 0; 7180b57cec5SDimitry Andric char* __p2; 7190b57cec5SDimitry Andric long long __ll = strtoll_l(__a, &__p2, __base, _LIBCPP_GET_C_LOCALE); 720bdd1243dSDimitry Andric __libcpp_remove_reference_t<decltype(errno)> __current_errno = errno; 7210b57cec5SDimitry Andric if (__current_errno == 0) 7220b57cec5SDimitry Andric errno = __save_errno; 723cb14a3feSDimitry Andric if (__p2 != __a_end) { 7240b57cec5SDimitry Andric __err = ios_base::failbit; 7250b57cec5SDimitry Andric return 0; 726cb14a3feSDimitry Andric } else if (__current_errno == ERANGE || __ll < numeric_limits<_Tp>::min() || numeric_limits<_Tp>::max() < __ll) { 7270b57cec5SDimitry Andric __err = ios_base::failbit; 7280b57cec5SDimitry Andric if (__ll > 0) 7290b57cec5SDimitry Andric return numeric_limits<_Tp>::max(); 7300b57cec5SDimitry Andric else 7310b57cec5SDimitry Andric return numeric_limits<_Tp>::min(); 7320b57cec5SDimitry Andric } 7330b57cec5SDimitry Andric return static_cast<_Tp>(__ll); 7340b57cec5SDimitry Andric } 7350b57cec5SDimitry Andric __err = ios_base::failbit; 7360b57cec5SDimitry Andric return 0; 7370b57cec5SDimitry Andric} 7380b57cec5SDimitry Andric 7390b57cec5SDimitry Andrictemplate <class _Tp> 740bdd1243dSDimitry Andric_LIBCPP_HIDE_FROM_ABI _Tp 741cb14a3feSDimitry Andric__num_get_unsigned_integral(const char* __a, const char* __a_end, ios_base::iostate& __err, int __base) { 742cb14a3feSDimitry Andric if (__a != __a_end) { 7430b57cec5SDimitry Andric const bool __negate = *__a == '-'; 7440b57cec5SDimitry Andric if (__negate && ++__a == __a_end) { 7450b57cec5SDimitry Andric __err = ios_base::failbit; 7460b57cec5SDimitry Andric return 0; 7470b57cec5SDimitry Andric } 748bdd1243dSDimitry Andric __libcpp_remove_reference_t<decltype(errno)> __save_errno = errno; 7490b57cec5SDimitry Andric errno = 0; 7500b57cec5SDimitry Andric char* __p2; 7510b57cec5SDimitry Andric unsigned long long __ll = strtoull_l(__a, &__p2, __base, _LIBCPP_GET_C_LOCALE); 752bdd1243dSDimitry Andric __libcpp_remove_reference_t<decltype(errno)> __current_errno = errno; 7530b57cec5SDimitry Andric if (__current_errno == 0) 7540b57cec5SDimitry Andric errno = __save_errno; 755cb14a3feSDimitry Andric if (__p2 != __a_end) { 7560b57cec5SDimitry Andric __err = ios_base::failbit; 7570b57cec5SDimitry Andric return 0; 758cb14a3feSDimitry Andric } else if (__current_errno == ERANGE || numeric_limits<_Tp>::max() < __ll) { 7590b57cec5SDimitry Andric __err = ios_base::failbit; 7600b57cec5SDimitry Andric return numeric_limits<_Tp>::max(); 7610b57cec5SDimitry Andric } 7620b57cec5SDimitry Andric _Tp __res = static_cast<_Tp>(__ll); 763cb14a3feSDimitry Andric if (__negate) 764cb14a3feSDimitry Andric __res = -__res; 7650b57cec5SDimitry Andric return __res; 7660b57cec5SDimitry Andric } 7670b57cec5SDimitry Andric __err = ios_base::failbit; 7680b57cec5SDimitry Andric return 0; 7690b57cec5SDimitry Andric} 7700b57cec5SDimitry Andric 7710b57cec5SDimitry Andrictemplate <class _Tp> 772cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI _Tp __do_strtod(const char* __a, char** __p2); 7730b57cec5SDimitry Andric 7740b57cec5SDimitry Andrictemplate <> 775cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI float __do_strtod<float>(const char* __a, char** __p2) { 7760b57cec5SDimitry Andric return strtof_l(__a, __p2, _LIBCPP_GET_C_LOCALE); 7770b57cec5SDimitry Andric} 7780b57cec5SDimitry Andric 7790b57cec5SDimitry Andrictemplate <> 780cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI double __do_strtod<double>(const char* __a, char** __p2) { 7810b57cec5SDimitry Andric return strtod_l(__a, __p2, _LIBCPP_GET_C_LOCALE); 7820b57cec5SDimitry Andric} 7830b57cec5SDimitry Andric 7840b57cec5SDimitry Andrictemplate <> 785cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI long double __do_strtod<long double>(const char* __a, char** __p2) { 7860b57cec5SDimitry Andric return strtold_l(__a, __p2, _LIBCPP_GET_C_LOCALE); 7870b57cec5SDimitry Andric} 7880b57cec5SDimitry Andric 7890b57cec5SDimitry Andrictemplate <class _Tp> 790cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI _Tp __num_get_float(const char* __a, const char* __a_end, ios_base::iostate& __err) { 791cb14a3feSDimitry Andric if (__a != __a_end) { 792bdd1243dSDimitry Andric __libcpp_remove_reference_t<decltype(errno)> __save_errno = errno; 7930b57cec5SDimitry Andric errno = 0; 7940b57cec5SDimitry Andric char* __p2; 795bdd1243dSDimitry Andric _Tp __ld = std::__do_strtod<_Tp>(__a, &__p2); 796bdd1243dSDimitry Andric __libcpp_remove_reference_t<decltype(errno)> __current_errno = errno; 7970b57cec5SDimitry Andric if (__current_errno == 0) 7980b57cec5SDimitry Andric errno = __save_errno; 799cb14a3feSDimitry Andric if (__p2 != __a_end) { 8000b57cec5SDimitry Andric __err = ios_base::failbit; 8010b57cec5SDimitry Andric return 0; 802cb14a3feSDimitry Andric } else if (__current_errno == ERANGE) 8030b57cec5SDimitry Andric __err = ios_base::failbit; 8040b57cec5SDimitry Andric return __ld; 8050b57cec5SDimitry Andric } 8060b57cec5SDimitry Andric __err = ios_base::failbit; 8070b57cec5SDimitry Andric return 0; 8080b57cec5SDimitry Andric} 8090b57cec5SDimitry Andric 8100b57cec5SDimitry Andrictemplate <class _CharT, class _InputIterator> 811cb14a3feSDimitry Andric_InputIterator num_get<_CharT, _InputIterator>::do_get( 812cb14a3feSDimitry Andric iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, bool& __v) const { 813cb14a3feSDimitry Andric if ((__iob.flags() & ios_base::boolalpha) == 0) { 8140b57cec5SDimitry Andric long __lv = -1; 8150b57cec5SDimitry Andric __b = do_get(__b, __e, __iob, __err, __lv); 816cb14a3feSDimitry Andric switch (__lv) { 8170b57cec5SDimitry Andric case 0: 8180b57cec5SDimitry Andric __v = false; 8190b57cec5SDimitry Andric break; 8200b57cec5SDimitry Andric case 1: 8210b57cec5SDimitry Andric __v = true; 8220b57cec5SDimitry Andric break; 8230b57cec5SDimitry Andric default: 8240b57cec5SDimitry Andric __v = true; 8250b57cec5SDimitry Andric __err = ios_base::failbit; 8260b57cec5SDimitry Andric break; 8270b57cec5SDimitry Andric } 8280b57cec5SDimitry Andric return __b; 8290b57cec5SDimitry Andric } 830bdd1243dSDimitry Andric const ctype<_CharT>& __ct = std::use_facet<ctype<_CharT> >(__iob.getloc()); 831bdd1243dSDimitry Andric const numpunct<_CharT>& __np = std::use_facet<numpunct<_CharT> >(__iob.getloc()); 8320b57cec5SDimitry Andric typedef typename numpunct<_CharT>::string_type string_type; 8330b57cec5SDimitry Andric const string_type __names[2] = {__np.truename(), __np.falsename()}; 834cb14a3feSDimitry Andric const string_type* __i = std::__scan_keyword(__b, __e, __names, __names + 2, __ct, __err); 8350b57cec5SDimitry Andric __v = __i == __names; 8360b57cec5SDimitry Andric return __b; 8370b57cec5SDimitry Andric} 8380b57cec5SDimitry Andric 8390b57cec5SDimitry Andric// signed 8400b57cec5SDimitry Andric 8410b57cec5SDimitry Andrictemplate <class _CharT, class _InputIterator> 8420b57cec5SDimitry Andrictemplate <class _Signed> 843cb14a3feSDimitry Andric_InputIterator num_get<_CharT, _InputIterator>::__do_get_signed( 844cb14a3feSDimitry Andric iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, _Signed& __v) const { 8450b57cec5SDimitry Andric // Stage 1 8460b57cec5SDimitry Andric int __base = this->__get_base(__iob); 8470b57cec5SDimitry Andric // Stage 2 8480b57cec5SDimitry Andric char_type __thousands_sep; 8490b57cec5SDimitry Andric const int __atoms_size = 26; 8500b57cec5SDimitry Andric#ifdef _LIBCPP_ABI_OPTIMIZED_LOCALE_NUM_GET 8510b57cec5SDimitry Andric char_type __atoms1[__atoms_size]; 8520b57cec5SDimitry Andric const char_type* __atoms = this->__do_widen(__iob, __atoms1); 8530b57cec5SDimitry Andric string __grouping = this->__stage2_int_prep(__iob, __thousands_sep); 8540b57cec5SDimitry Andric#else 8550b57cec5SDimitry Andric char_type __atoms[__atoms_size]; 8560b57cec5SDimitry Andric string __grouping = this->__stage2_int_prep(__iob, __atoms, __thousands_sep); 8570b57cec5SDimitry Andric#endif 8580b57cec5SDimitry Andric string __buf; 8590b57cec5SDimitry Andric __buf.resize(__buf.capacity()); 8600b57cec5SDimitry Andric char* __a = &__buf[0]; 8610b57cec5SDimitry Andric char* __a_end = __a; 8620b57cec5SDimitry Andric unsigned __g[__num_get_base::__num_get_buf_sz]; 8630b57cec5SDimitry Andric unsigned* __g_end = __g; 8640b57cec5SDimitry Andric unsigned __dc = 0; 865cb14a3feSDimitry Andric for (; __b != __e; ++__b) { 866cb14a3feSDimitry Andric if (__a_end == __a + __buf.size()) { 8670b57cec5SDimitry Andric size_t __tmp = __buf.size(); 8680b57cec5SDimitry Andric __buf.resize(2 * __buf.size()); 8690b57cec5SDimitry Andric __buf.resize(__buf.capacity()); 8700b57cec5SDimitry Andric __a = &__buf[0]; 8710b57cec5SDimitry Andric __a_end = __a + __tmp; 8720b57cec5SDimitry Andric } 873cb14a3feSDimitry Andric if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc, __thousands_sep, __grouping, __g, __g_end, __atoms)) 8740b57cec5SDimitry Andric break; 8750b57cec5SDimitry Andric } 8760b57cec5SDimitry Andric if (__grouping.size() != 0 && __g_end - __g < __num_get_base::__num_get_buf_sz) 8770b57cec5SDimitry Andric *__g_end++ = __dc; 8780b57cec5SDimitry Andric // Stage 3 879bdd1243dSDimitry Andric __v = std::__num_get_signed_integral<_Signed>(__a, __a_end, __err, __base); 8800b57cec5SDimitry Andric // Digit grouping checked 8810b57cec5SDimitry Andric __check_grouping(__grouping, __g, __g_end, __err); 8820b57cec5SDimitry Andric // EOF checked 8830b57cec5SDimitry Andric if (__b == __e) 8840b57cec5SDimitry Andric __err |= ios_base::eofbit; 8850b57cec5SDimitry Andric return __b; 8860b57cec5SDimitry Andric} 8870b57cec5SDimitry Andric 8880b57cec5SDimitry Andric// unsigned 8890b57cec5SDimitry Andric 8900b57cec5SDimitry Andrictemplate <class _CharT, class _InputIterator> 8910b57cec5SDimitry Andrictemplate <class _Unsigned> 892cb14a3feSDimitry Andric_InputIterator num_get<_CharT, _InputIterator>::__do_get_unsigned( 893cb14a3feSDimitry Andric iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, _Unsigned& __v) const { 8940b57cec5SDimitry Andric // Stage 1 8950b57cec5SDimitry Andric int __base = this->__get_base(__iob); 8960b57cec5SDimitry Andric // Stage 2 8970b57cec5SDimitry Andric char_type __thousands_sep; 8980b57cec5SDimitry Andric const int __atoms_size = 26; 8990b57cec5SDimitry Andric#ifdef _LIBCPP_ABI_OPTIMIZED_LOCALE_NUM_GET 9000b57cec5SDimitry Andric char_type __atoms1[__atoms_size]; 9010b57cec5SDimitry Andric const char_type* __atoms = this->__do_widen(__iob, __atoms1); 9020b57cec5SDimitry Andric string __grouping = this->__stage2_int_prep(__iob, __thousands_sep); 9030b57cec5SDimitry Andric#else 9040b57cec5SDimitry Andric char_type __atoms[__atoms_size]; 9050b57cec5SDimitry Andric string __grouping = this->__stage2_int_prep(__iob, __atoms, __thousands_sep); 9060b57cec5SDimitry Andric#endif 9070b57cec5SDimitry Andric string __buf; 9080b57cec5SDimitry Andric __buf.resize(__buf.capacity()); 9090b57cec5SDimitry Andric char* __a = &__buf[0]; 9100b57cec5SDimitry Andric char* __a_end = __a; 9110b57cec5SDimitry Andric unsigned __g[__num_get_base::__num_get_buf_sz]; 9120b57cec5SDimitry Andric unsigned* __g_end = __g; 9130b57cec5SDimitry Andric unsigned __dc = 0; 914cb14a3feSDimitry Andric for (; __b != __e; ++__b) { 915cb14a3feSDimitry Andric if (__a_end == __a + __buf.size()) { 9160b57cec5SDimitry Andric size_t __tmp = __buf.size(); 9170b57cec5SDimitry Andric __buf.resize(2 * __buf.size()); 9180b57cec5SDimitry Andric __buf.resize(__buf.capacity()); 9190b57cec5SDimitry Andric __a = &__buf[0]; 9200b57cec5SDimitry Andric __a_end = __a + __tmp; 9210b57cec5SDimitry Andric } 922cb14a3feSDimitry Andric if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc, __thousands_sep, __grouping, __g, __g_end, __atoms)) 9230b57cec5SDimitry Andric break; 9240b57cec5SDimitry Andric } 9250b57cec5SDimitry Andric if (__grouping.size() != 0 && __g_end - __g < __num_get_base::__num_get_buf_sz) 9260b57cec5SDimitry Andric *__g_end++ = __dc; 9270b57cec5SDimitry Andric // Stage 3 928bdd1243dSDimitry Andric __v = std::__num_get_unsigned_integral<_Unsigned>(__a, __a_end, __err, __base); 9290b57cec5SDimitry Andric // Digit grouping checked 9300b57cec5SDimitry Andric __check_grouping(__grouping, __g, __g_end, __err); 9310b57cec5SDimitry Andric // EOF checked 9320b57cec5SDimitry Andric if (__b == __e) 9330b57cec5SDimitry Andric __err |= ios_base::eofbit; 9340b57cec5SDimitry Andric return __b; 9350b57cec5SDimitry Andric} 9360b57cec5SDimitry Andric 9370b57cec5SDimitry Andric// floating point 9380b57cec5SDimitry Andric 9390b57cec5SDimitry Andrictemplate <class _CharT, class _InputIterator> 9400b57cec5SDimitry Andrictemplate <class _Fp> 941cb14a3feSDimitry Andric_InputIterator num_get<_CharT, _InputIterator>::__do_get_floating_point( 942cb14a3feSDimitry Andric iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, _Fp& __v) const { 9430b57cec5SDimitry Andric // Stage 1, nothing to do 9440b57cec5SDimitry Andric // Stage 2 9450b57cec5SDimitry Andric char_type __atoms[32]; 9460b57cec5SDimitry Andric char_type __decimal_point; 9470b57cec5SDimitry Andric char_type __thousands_sep; 948cb14a3feSDimitry Andric string __grouping = this->__stage2_float_prep(__iob, __atoms, __decimal_point, __thousands_sep); 9490b57cec5SDimitry Andric string __buf; 9500b57cec5SDimitry Andric __buf.resize(__buf.capacity()); 9510b57cec5SDimitry Andric char* __a = &__buf[0]; 9520b57cec5SDimitry Andric char* __a_end = __a; 9530b57cec5SDimitry Andric unsigned __g[__num_get_base::__num_get_buf_sz]; 9540b57cec5SDimitry Andric unsigned* __g_end = __g; 9550b57cec5SDimitry Andric unsigned __dc = 0; 9560b57cec5SDimitry Andric bool __in_units = true; 9570b57cec5SDimitry Andric char __exp = 'E'; 958cb14a3feSDimitry Andric for (; __b != __e; ++__b) { 959cb14a3feSDimitry Andric if (__a_end == __a + __buf.size()) { 9600b57cec5SDimitry Andric size_t __tmp = __buf.size(); 9610b57cec5SDimitry Andric __buf.resize(2 * __buf.size()); 9620b57cec5SDimitry Andric __buf.resize(__buf.capacity()); 9630b57cec5SDimitry Andric __a = &__buf[0]; 9640b57cec5SDimitry Andric __a_end = __a + __tmp; 9650b57cec5SDimitry Andric } 966cb14a3feSDimitry Andric if (this->__stage2_float_loop( 967cb14a3feSDimitry Andric *__b, 968cb14a3feSDimitry Andric __in_units, 969cb14a3feSDimitry Andric __exp, 970cb14a3feSDimitry Andric __a, 971cb14a3feSDimitry Andric __a_end, 972cb14a3feSDimitry Andric __decimal_point, 973cb14a3feSDimitry Andric __thousands_sep, 974cb14a3feSDimitry Andric __grouping, 975cb14a3feSDimitry Andric __g, 976cb14a3feSDimitry Andric __g_end, 977cb14a3feSDimitry Andric __dc, 978cb14a3feSDimitry Andric __atoms)) 9790b57cec5SDimitry Andric break; 9800b57cec5SDimitry Andric } 9810b57cec5SDimitry Andric if (__grouping.size() != 0 && __in_units && __g_end - __g < __num_get_base::__num_get_buf_sz) 9820b57cec5SDimitry Andric *__g_end++ = __dc; 9830b57cec5SDimitry Andric // Stage 3 984bdd1243dSDimitry Andric __v = std::__num_get_float<_Fp>(__a, __a_end, __err); 9850b57cec5SDimitry Andric // Digit grouping checked 9860b57cec5SDimitry Andric __check_grouping(__grouping, __g, __g_end, __err); 9870b57cec5SDimitry Andric // EOF checked 9880b57cec5SDimitry Andric if (__b == __e) 9890b57cec5SDimitry Andric __err |= ios_base::eofbit; 9900b57cec5SDimitry Andric return __b; 9910b57cec5SDimitry Andric} 9920b57cec5SDimitry Andric 9930b57cec5SDimitry Andrictemplate <class _CharT, class _InputIterator> 994cb14a3feSDimitry Andric_InputIterator num_get<_CharT, _InputIterator>::do_get( 995cb14a3feSDimitry Andric iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, void*& __v) const { 9960b57cec5SDimitry Andric // Stage 1 9970b57cec5SDimitry Andric int __base = 16; 9980b57cec5SDimitry Andric // Stage 2 9990b57cec5SDimitry Andric char_type __atoms[26]; 10005f757f3fSDimitry Andric char_type __thousands_sep = char_type(); 10010b57cec5SDimitry Andric string __grouping; 1002cb14a3feSDimitry Andric std::use_facet<ctype<_CharT> >(__iob.getloc()).widen(__num_get_base::__src, __num_get_base::__src + 26, __atoms); 10030b57cec5SDimitry Andric string __buf; 10040b57cec5SDimitry Andric __buf.resize(__buf.capacity()); 10050b57cec5SDimitry Andric char* __a = &__buf[0]; 10060b57cec5SDimitry Andric char* __a_end = __a; 10070b57cec5SDimitry Andric unsigned __g[__num_get_base::__num_get_buf_sz]; 10080b57cec5SDimitry Andric unsigned* __g_end = __g; 10090b57cec5SDimitry Andric unsigned __dc = 0; 1010cb14a3feSDimitry Andric for (; __b != __e; ++__b) { 1011cb14a3feSDimitry Andric if (__a_end == __a + __buf.size()) { 10120b57cec5SDimitry Andric size_t __tmp = __buf.size(); 10130b57cec5SDimitry Andric __buf.resize(2 * __buf.size()); 10140b57cec5SDimitry Andric __buf.resize(__buf.capacity()); 10150b57cec5SDimitry Andric __a = &__buf[0]; 10160b57cec5SDimitry Andric __a_end = __a + __tmp; 10170b57cec5SDimitry Andric } 1018cb14a3feSDimitry Andric if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc, __thousands_sep, __grouping, __g, __g_end, __atoms)) 10190b57cec5SDimitry Andric break; 10200b57cec5SDimitry Andric } 10210b57cec5SDimitry Andric // Stage 3 10220b57cec5SDimitry Andric __buf.resize(__a_end - __a); 10230b57cec5SDimitry Andric if (__libcpp_sscanf_l(__buf.c_str(), _LIBCPP_GET_C_LOCALE, "%p", &__v) != 1) 10240b57cec5SDimitry Andric __err = ios_base::failbit; 10250b57cec5SDimitry Andric // EOF checked 10260b57cec5SDimitry Andric if (__b == __e) 10270b57cec5SDimitry Andric __err |= ios_base::eofbit; 10280b57cec5SDimitry Andric return __b; 10290b57cec5SDimitry Andric} 10300b57cec5SDimitry Andric 103181ad6265SDimitry Andricextern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS num_get<char>; 1032349cc55cSDimitry Andric#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 103381ad6265SDimitry Andricextern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS num_get<wchar_t>; 1034349cc55cSDimitry Andric#endif 10350b57cec5SDimitry Andric 1036cb14a3feSDimitry Andricstruct _LIBCPP_EXPORTED_FROM_ABI __num_put_base { 10370b57cec5SDimitry Andricprotected: 1038cb14a3feSDimitry Andric static void __format_int(char* __fmt, const char* __len, bool __signd, ios_base::fmtflags __flags); 1039cb14a3feSDimitry Andric static bool __format_float(char* __fmt, const char* __len, ios_base::fmtflags __flags); 1040cb14a3feSDimitry Andric static char* __identify_padding(char* __nb, char* __ne, const ios_base& __iob); 10410b57cec5SDimitry Andric}; 10420b57cec5SDimitry Andric 10430b57cec5SDimitry Andrictemplate <class _CharT> 1044cb14a3feSDimitry Andricstruct __num_put : protected __num_put_base { 1045cb14a3feSDimitry Andric static void __widen_and_group_int( 1046cb14a3feSDimitry Andric char* __nb, char* __np, char* __ne, _CharT* __ob, _CharT*& __op, _CharT*& __oe, const locale& __loc); 1047cb14a3feSDimitry Andric static void __widen_and_group_float( 1048cb14a3feSDimitry Andric char* __nb, char* __np, char* __ne, _CharT* __ob, _CharT*& __op, _CharT*& __oe, const locale& __loc); 10490b57cec5SDimitry Andric}; 10500b57cec5SDimitry Andric 10510b57cec5SDimitry Andrictemplate <class _CharT> 1052cb14a3feSDimitry Andricvoid __num_put<_CharT>::__widen_and_group_int( 1053cb14a3feSDimitry Andric char* __nb, char* __np, char* __ne, _CharT* __ob, _CharT*& __op, _CharT*& __oe, const locale& __loc) { 1054bdd1243dSDimitry Andric const ctype<_CharT>& __ct = std::use_facet<ctype<_CharT> >(__loc); 1055bdd1243dSDimitry Andric const numpunct<_CharT>& __npt = std::use_facet<numpunct<_CharT> >(__loc); 10560b57cec5SDimitry Andric string __grouping = __npt.grouping(); 1057cb14a3feSDimitry Andric if (__grouping.empty()) { 10580b57cec5SDimitry Andric __ct.widen(__nb, __ne, __ob); 10590b57cec5SDimitry Andric __oe = __ob + (__ne - __nb); 1060cb14a3feSDimitry Andric } else { 10610b57cec5SDimitry Andric __oe = __ob; 10620b57cec5SDimitry Andric char* __nf = __nb; 10630b57cec5SDimitry Andric if (*__nf == '-' || *__nf == '+') 10640b57cec5SDimitry Andric *__oe++ = __ct.widen(*__nf++); 1065cb14a3feSDimitry Andric if (__ne - __nf >= 2 && __nf[0] == '0' && (__nf[1] == 'x' || __nf[1] == 'X')) { 10660b57cec5SDimitry Andric *__oe++ = __ct.widen(*__nf++); 10670b57cec5SDimitry Andric *__oe++ = __ct.widen(*__nf++); 10680b57cec5SDimitry Andric } 1069bdd1243dSDimitry Andric std::reverse(__nf, __ne); 10700b57cec5SDimitry Andric _CharT __thousands_sep = __npt.thousands_sep(); 10710b57cec5SDimitry Andric unsigned __dc = 0; 10720b57cec5SDimitry Andric unsigned __dg = 0; 1073cb14a3feSDimitry Andric for (char* __p = __nf; __p < __ne; ++__p) { 1074cb14a3feSDimitry Andric if (static_cast<unsigned>(__grouping[__dg]) > 0 && __dc == static_cast<unsigned>(__grouping[__dg])) { 10750b57cec5SDimitry Andric *__oe++ = __thousands_sep; 10760b57cec5SDimitry Andric __dc = 0; 10770b57cec5SDimitry Andric if (__dg < __grouping.size() - 1) 10780b57cec5SDimitry Andric ++__dg; 10790b57cec5SDimitry Andric } 10800b57cec5SDimitry Andric *__oe++ = __ct.widen(*__p); 10810b57cec5SDimitry Andric ++__dc; 10820b57cec5SDimitry Andric } 1083bdd1243dSDimitry Andric std::reverse(__ob + (__nf - __nb), __oe); 10840b57cec5SDimitry Andric } 10850b57cec5SDimitry Andric if (__np == __ne) 10860b57cec5SDimitry Andric __op = __oe; 10870b57cec5SDimitry Andric else 10880b57cec5SDimitry Andric __op = __ob + (__np - __nb); 10890b57cec5SDimitry Andric} 10900b57cec5SDimitry Andric 10910b57cec5SDimitry Andrictemplate <class _CharT> 1092cb14a3feSDimitry Andricvoid __num_put<_CharT>::__widen_and_group_float( 1093cb14a3feSDimitry Andric char* __nb, char* __np, char* __ne, _CharT* __ob, _CharT*& __op, _CharT*& __oe, const locale& __loc) { 1094bdd1243dSDimitry Andric const ctype<_CharT>& __ct = std::use_facet<ctype<_CharT> >(__loc); 1095bdd1243dSDimitry Andric const numpunct<_CharT>& __npt = std::use_facet<numpunct<_CharT> >(__loc); 10960b57cec5SDimitry Andric string __grouping = __npt.grouping(); 10970b57cec5SDimitry Andric __oe = __ob; 10980b57cec5SDimitry Andric char* __nf = __nb; 10990b57cec5SDimitry Andric if (*__nf == '-' || *__nf == '+') 11000b57cec5SDimitry Andric *__oe++ = __ct.widen(*__nf++); 11010b57cec5SDimitry Andric char* __ns; 1102cb14a3feSDimitry Andric if (__ne - __nf >= 2 && __nf[0] == '0' && (__nf[1] == 'x' || __nf[1] == 'X')) { 11030b57cec5SDimitry Andric *__oe++ = __ct.widen(*__nf++); 11040b57cec5SDimitry Andric *__oe++ = __ct.widen(*__nf++); 11050b57cec5SDimitry Andric for (__ns = __nf; __ns < __ne; ++__ns) 11060b57cec5SDimitry Andric if (!isxdigit_l(*__ns, _LIBCPP_GET_C_LOCALE)) 11070b57cec5SDimitry Andric break; 1108cb14a3feSDimitry Andric } else { 11090b57cec5SDimitry Andric for (__ns = __nf; __ns < __ne; ++__ns) 11100b57cec5SDimitry Andric if (!isdigit_l(*__ns, _LIBCPP_GET_C_LOCALE)) 11110b57cec5SDimitry Andric break; 11120b57cec5SDimitry Andric } 1113cb14a3feSDimitry Andric if (__grouping.empty()) { 11140b57cec5SDimitry Andric __ct.widen(__nf, __ns, __oe); 11150b57cec5SDimitry Andric __oe += __ns - __nf; 1116cb14a3feSDimitry Andric } else { 1117bdd1243dSDimitry Andric std::reverse(__nf, __ns); 11180b57cec5SDimitry Andric _CharT __thousands_sep = __npt.thousands_sep(); 11190b57cec5SDimitry Andric unsigned __dc = 0; 11200b57cec5SDimitry Andric unsigned __dg = 0; 1121cb14a3feSDimitry Andric for (char* __p = __nf; __p < __ns; ++__p) { 1122cb14a3feSDimitry Andric if (__grouping[__dg] > 0 && __dc == static_cast<unsigned>(__grouping[__dg])) { 11230b57cec5SDimitry Andric *__oe++ = __thousands_sep; 11240b57cec5SDimitry Andric __dc = 0; 11250b57cec5SDimitry Andric if (__dg < __grouping.size() - 1) 11260b57cec5SDimitry Andric ++__dg; 11270b57cec5SDimitry Andric } 11280b57cec5SDimitry Andric *__oe++ = __ct.widen(*__p); 11290b57cec5SDimitry Andric ++__dc; 11300b57cec5SDimitry Andric } 1131bdd1243dSDimitry Andric std::reverse(__ob + (__nf - __nb), __oe); 11320b57cec5SDimitry Andric } 1133cb14a3feSDimitry Andric for (__nf = __ns; __nf < __ne; ++__nf) { 1134cb14a3feSDimitry Andric if (*__nf == '.') { 11350b57cec5SDimitry Andric *__oe++ = __npt.decimal_point(); 11360b57cec5SDimitry Andric ++__nf; 11370b57cec5SDimitry Andric break; 1138cb14a3feSDimitry Andric } else 11390b57cec5SDimitry Andric *__oe++ = __ct.widen(*__nf); 11400b57cec5SDimitry Andric } 11410b57cec5SDimitry Andric __ct.widen(__nf, __ne, __oe); 11420b57cec5SDimitry Andric __oe += __ne - __nf; 11430b57cec5SDimitry Andric if (__np == __ne) 11440b57cec5SDimitry Andric __op = __oe; 11450b57cec5SDimitry Andric else 11460b57cec5SDimitry Andric __op = __ob + (__np - __nb); 11470b57cec5SDimitry Andric} 11480b57cec5SDimitry Andric 114981ad6265SDimitry Andricextern template struct _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __num_put<char>; 1150349cc55cSDimitry Andric#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 115181ad6265SDimitry Andricextern template struct _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __num_put<wchar_t>; 1152349cc55cSDimitry Andric#endif 11530b57cec5SDimitry Andric 11540b57cec5SDimitry Andrictemplate <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> > 1155cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS num_put : public locale::facet, private __num_put<_CharT> { 11560b57cec5SDimitry Andricpublic: 11570b57cec5SDimitry Andric typedef _CharT char_type; 11580b57cec5SDimitry Andric typedef _OutputIterator iter_type; 11590b57cec5SDimitry Andric 1160cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit num_put(size_t __refs = 0) : locale::facet(__refs) {} 11610b57cec5SDimitry Andric 1162cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iter_type put(iter_type __s, ios_base& __iob, char_type __fl, bool __v) const { 11630b57cec5SDimitry Andric return do_put(__s, __iob, __fl, __v); 11640b57cec5SDimitry Andric } 11650b57cec5SDimitry Andric 1166cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iter_type put(iter_type __s, ios_base& __iob, char_type __fl, long __v) const { 11670b57cec5SDimitry Andric return do_put(__s, __iob, __fl, __v); 11680b57cec5SDimitry Andric } 11690b57cec5SDimitry Andric 1170cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iter_type put(iter_type __s, ios_base& __iob, char_type __fl, long long __v) const { 11710b57cec5SDimitry Andric return do_put(__s, __iob, __fl, __v); 11720b57cec5SDimitry Andric } 11730b57cec5SDimitry Andric 1174cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iter_type put(iter_type __s, ios_base& __iob, char_type __fl, unsigned long __v) const { 11750b57cec5SDimitry Andric return do_put(__s, __iob, __fl, __v); 11760b57cec5SDimitry Andric } 11770b57cec5SDimitry Andric 1178cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iter_type put(iter_type __s, ios_base& __iob, char_type __fl, unsigned long long __v) const { 11790b57cec5SDimitry Andric return do_put(__s, __iob, __fl, __v); 11800b57cec5SDimitry Andric } 11810b57cec5SDimitry Andric 1182cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iter_type put(iter_type __s, ios_base& __iob, char_type __fl, double __v) const { 11830b57cec5SDimitry Andric return do_put(__s, __iob, __fl, __v); 11840b57cec5SDimitry Andric } 11850b57cec5SDimitry Andric 1186cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iter_type put(iter_type __s, ios_base& __iob, char_type __fl, long double __v) const { 11870b57cec5SDimitry Andric return do_put(__s, __iob, __fl, __v); 11880b57cec5SDimitry Andric } 11890b57cec5SDimitry Andric 1190cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iter_type put(iter_type __s, ios_base& __iob, char_type __fl, const void* __v) const { 11910b57cec5SDimitry Andric return do_put(__s, __iob, __fl, __v); 11920b57cec5SDimitry Andric } 11930b57cec5SDimitry Andric 11940b57cec5SDimitry Andric static locale::id id; 11950b57cec5SDimitry Andric 11960b57cec5SDimitry Andricprotected: 1197bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI_VIRTUAL ~num_put() override {} 11980b57cec5SDimitry Andric 1199cb14a3feSDimitry Andric virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl, bool __v) const; 1200cb14a3feSDimitry Andric virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl, long __v) const; 1201cb14a3feSDimitry Andric virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl, long long __v) const; 1202cb14a3feSDimitry Andric virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl, unsigned long) const; 1203cb14a3feSDimitry Andric virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl, unsigned long long) const; 1204cb14a3feSDimitry Andric virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl, double __v) const; 1205cb14a3feSDimitry Andric virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl, long double __v) const; 1206cb14a3feSDimitry Andric virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl, const void* __v) const; 1207349cc55cSDimitry Andric 1208349cc55cSDimitry Andric template <class _Integral> 1209cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI inline _OutputIterator 1210cb14a3feSDimitry Andric __do_put_integral(iter_type __s, ios_base& __iob, char_type __fl, _Integral __v, char const* __len) const; 1211349cc55cSDimitry Andric 1212349cc55cSDimitry Andric template <class _Float> 1213cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI inline _OutputIterator 1214cb14a3feSDimitry Andric __do_put_floating_point(iter_type __s, ios_base& __iob, char_type __fl, _Float __v, char const* __len) const; 12150b57cec5SDimitry Andric}; 12160b57cec5SDimitry Andric 12170b57cec5SDimitry Andrictemplate <class _CharT, class _OutputIterator> 1218cb14a3feSDimitry Andriclocale::id num_put<_CharT, _OutputIterator>::id; 12190b57cec5SDimitry Andric 12200b57cec5SDimitry Andrictemplate <class _CharT, class _OutputIterator> 1221cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI _OutputIterator __pad_and_output( 1222cb14a3feSDimitry Andric _OutputIterator __s, const _CharT* __ob, const _CharT* __op, const _CharT* __oe, ios_base& __iob, _CharT __fl) { 12230b57cec5SDimitry Andric streamsize __sz = __oe - __ob; 12240b57cec5SDimitry Andric streamsize __ns = __iob.width(); 12250b57cec5SDimitry Andric if (__ns > __sz) 12260b57cec5SDimitry Andric __ns -= __sz; 12270b57cec5SDimitry Andric else 12280b57cec5SDimitry Andric __ns = 0; 12290b57cec5SDimitry Andric for (; __ob < __op; ++__ob, ++__s) 12300b57cec5SDimitry Andric *__s = *__ob; 12310b57cec5SDimitry Andric for (; __ns; --__ns, ++__s) 12320b57cec5SDimitry Andric *__s = __fl; 12330b57cec5SDimitry Andric for (; __ob < __oe; ++__ob, ++__s) 12340b57cec5SDimitry Andric *__s = *__ob; 12350b57cec5SDimitry Andric __iob.width(0); 12360b57cec5SDimitry Andric return __s; 12370b57cec5SDimitry Andric} 12380b57cec5SDimitry Andric 12390b57cec5SDimitry Andrictemplate <class _CharT, class _Traits> 1240cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI ostreambuf_iterator<_CharT, _Traits> __pad_and_output( 1241cb14a3feSDimitry Andric ostreambuf_iterator<_CharT, _Traits> __s, 1242cb14a3feSDimitry Andric const _CharT* __ob, 1243cb14a3feSDimitry Andric const _CharT* __op, 1244cb14a3feSDimitry Andric const _CharT* __oe, 1245cb14a3feSDimitry Andric ios_base& __iob, 1246cb14a3feSDimitry Andric _CharT __fl) { 12470b57cec5SDimitry Andric if (__s.__sbuf_ == nullptr) 12480b57cec5SDimitry Andric return __s; 12490b57cec5SDimitry Andric streamsize __sz = __oe - __ob; 12500b57cec5SDimitry Andric streamsize __ns = __iob.width(); 12510b57cec5SDimitry Andric if (__ns > __sz) 12520b57cec5SDimitry Andric __ns -= __sz; 12530b57cec5SDimitry Andric else 12540b57cec5SDimitry Andric __ns = 0; 12550b57cec5SDimitry Andric streamsize __np = __op - __ob; 1256cb14a3feSDimitry Andric if (__np > 0) { 1257cb14a3feSDimitry Andric if (__s.__sbuf_->sputn(__ob, __np) != __np) { 12580b57cec5SDimitry Andric __s.__sbuf_ = nullptr; 12590b57cec5SDimitry Andric return __s; 12600b57cec5SDimitry Andric } 12610b57cec5SDimitry Andric } 1262cb14a3feSDimitry Andric if (__ns > 0) { 12630b57cec5SDimitry Andric basic_string<_CharT, _Traits> __sp(__ns, __fl); 1264cb14a3feSDimitry Andric if (__s.__sbuf_->sputn(__sp.data(), __ns) != __ns) { 12650b57cec5SDimitry Andric __s.__sbuf_ = nullptr; 12660b57cec5SDimitry Andric return __s; 12670b57cec5SDimitry Andric } 12680b57cec5SDimitry Andric } 12690b57cec5SDimitry Andric __np = __oe - __op; 1270cb14a3feSDimitry Andric if (__np > 0) { 1271cb14a3feSDimitry Andric if (__s.__sbuf_->sputn(__op, __np) != __np) { 12720b57cec5SDimitry Andric __s.__sbuf_ = nullptr; 12730b57cec5SDimitry Andric return __s; 12740b57cec5SDimitry Andric } 12750b57cec5SDimitry Andric } 12760b57cec5SDimitry Andric __iob.width(0); 12770b57cec5SDimitry Andric return __s; 12780b57cec5SDimitry Andric} 12790b57cec5SDimitry Andric 12800b57cec5SDimitry Andrictemplate <class _CharT, class _OutputIterator> 12810b57cec5SDimitry Andric_OutputIterator 1282cb14a3feSDimitry Andricnum_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, char_type __fl, bool __v) const { 12830b57cec5SDimitry Andric if ((__iob.flags() & ios_base::boolalpha) == 0) 12840b57cec5SDimitry Andric return do_put(__s, __iob, __fl, (unsigned long)__v); 1285bdd1243dSDimitry Andric const numpunct<char_type>& __np = std::use_facet<numpunct<char_type> >(__iob.getloc()); 12860b57cec5SDimitry Andric typedef typename numpunct<char_type>::string_type string_type; 12870b57cec5SDimitry Andric string_type __nm = __v ? __np.truename() : __np.falsename(); 12880b57cec5SDimitry Andric for (typename string_type::iterator __i = __nm.begin(); __i != __nm.end(); ++__i, ++__s) 12890b57cec5SDimitry Andric *__s = *__i; 12900b57cec5SDimitry Andric return __s; 12910b57cec5SDimitry Andric} 12920b57cec5SDimitry Andric 12930b57cec5SDimitry Andrictemplate <class _CharT, class _OutputIterator> 1294349cc55cSDimitry Andrictemplate <class _Integral> 1295cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI inline _OutputIterator num_put<_CharT, _OutputIterator>::__do_put_integral( 1296cb14a3feSDimitry Andric iter_type __s, ios_base& __iob, char_type __fl, _Integral __v, char const* __len) const { 12970b57cec5SDimitry Andric // Stage 1 - Get number in narrow char 1298349cc55cSDimitry Andric char __fmt[8] = {'%', 0}; 1299349cc55cSDimitry Andric this->__format_int(__fmt + 1, __len, is_signed<_Integral>::value, __iob.flags()); 1300fe6060f1SDimitry Andric // Worst case is octal, with showbase enabled. Note that octal is always 1301fe6060f1SDimitry Andric // printed as an unsigned value. 1302349cc55cSDimitry Andric using _Unsigned = typename make_unsigned<_Integral>::type; 1303cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR const unsigned __nbuf = 1304cb14a3feSDimitry Andric (numeric_limits<_Unsigned>::digits / 3) // 1 char per 3 bits 1305349cc55cSDimitry Andric + ((numeric_limits<_Unsigned>::digits % 3) != 0) // round up 1306fe6060f1SDimitry Andric + 2; // base prefix + terminating null character 13070b57cec5SDimitry Andric char __nar[__nbuf]; 130881ad6265SDimitry Andric _LIBCPP_DIAGNOSTIC_PUSH 130981ad6265SDimitry Andric _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wformat-nonliteral") 131081ad6265SDimitry Andric _LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wformat-nonliteral") 13110b57cec5SDimitry Andric int __nc = __libcpp_snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v); 131281ad6265SDimitry Andric _LIBCPP_DIAGNOSTIC_POP 13130b57cec5SDimitry Andric char* __ne = __nar + __nc; 13140b57cec5SDimitry Andric char* __np = this->__identify_padding(__nar, __ne, __iob); 13150b57cec5SDimitry Andric // Stage 2 - Widen __nar while adding thousands separators 13160b57cec5SDimitry Andric char_type __o[2 * (__nbuf - 1) - 1]; 13170b57cec5SDimitry Andric char_type* __op; // pad here 13180b57cec5SDimitry Andric char_type* __oe; // end of output 13190b57cec5SDimitry Andric this->__widen_and_group_int(__nar, __np, __ne, __o, __op, __oe, __iob.getloc()); 13200b57cec5SDimitry Andric // [__o, __oe) contains thousands_sep'd wide number 13210b57cec5SDimitry Andric // Stage 3 & 4 1322bdd1243dSDimitry Andric return std::__pad_and_output(__s, __o, __op, __oe, __iob, __fl); 13230b57cec5SDimitry Andric} 13240b57cec5SDimitry Andric 13250b57cec5SDimitry Andrictemplate <class _CharT, class _OutputIterator> 13260b57cec5SDimitry Andric_OutputIterator 1327cb14a3feSDimitry Andricnum_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, char_type __fl, long __v) const { 1328349cc55cSDimitry Andric return this->__do_put_integral(__s, __iob, __fl, __v, "l"); 1329349cc55cSDimitry Andric} 1330349cc55cSDimitry Andric 1331349cc55cSDimitry Andrictemplate <class _CharT, class _OutputIterator> 1332349cc55cSDimitry Andric_OutputIterator 1333cb14a3feSDimitry Andricnum_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, char_type __fl, long long __v) const { 1334349cc55cSDimitry Andric return this->__do_put_integral(__s, __iob, __fl, __v, "ll"); 13350b57cec5SDimitry Andric} 13360b57cec5SDimitry Andric 13370b57cec5SDimitry Andrictemplate <class _CharT, class _OutputIterator> 13380b57cec5SDimitry Andric_OutputIterator 1339cb14a3feSDimitry Andricnum_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, char_type __fl, unsigned long __v) const { 1340349cc55cSDimitry Andric return this->__do_put_integral(__s, __iob, __fl, __v, "l"); 13410b57cec5SDimitry Andric} 13420b57cec5SDimitry Andric 13430b57cec5SDimitry Andrictemplate <class _CharT, class _OutputIterator> 13440b57cec5SDimitry Andric_OutputIterator 1345cb14a3feSDimitry Andricnum_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, char_type __fl, unsigned long long __v) const { 1346349cc55cSDimitry Andric return this->__do_put_integral(__s, __iob, __fl, __v, "ll"); 1347349cc55cSDimitry Andric} 1348349cc55cSDimitry Andric 1349349cc55cSDimitry Andrictemplate <class _CharT, class _OutputIterator> 1350349cc55cSDimitry Andrictemplate <class _Float> 1351cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI inline _OutputIterator num_put<_CharT, _OutputIterator>::__do_put_floating_point( 1352cb14a3feSDimitry Andric iter_type __s, ios_base& __iob, char_type __fl, _Float __v, char const* __len) const { 13530b57cec5SDimitry Andric // Stage 1 - Get number in narrow char 13540b57cec5SDimitry Andric char __fmt[8] = {'%', 0}; 1355349cc55cSDimitry Andric bool __specify_precision = this->__format_float(__fmt + 1, __len, __iob.flags()); 1356349cc55cSDimitry Andric const unsigned __nbuf = 30; 13570b57cec5SDimitry Andric char __nar[__nbuf]; 1358349cc55cSDimitry Andric char* __nb = __nar; 1359349cc55cSDimitry Andric int __nc; 136081ad6265SDimitry Andric _LIBCPP_DIAGNOSTIC_PUSH 136181ad6265SDimitry Andric _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wformat-nonliteral") 136281ad6265SDimitry Andric _LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wformat-nonliteral") 1363349cc55cSDimitry Andric if (__specify_precision) 1364cb14a3feSDimitry Andric __nc = __libcpp_snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v); 1365349cc55cSDimitry Andric else 1366349cc55cSDimitry Andric __nc = __libcpp_snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, __v); 1367349cc55cSDimitry Andric unique_ptr<char, void (*)(void*)> __nbh(nullptr, free); 1368cb14a3feSDimitry Andric if (__nc > static_cast<int>(__nbuf - 1)) { 1369349cc55cSDimitry Andric if (__specify_precision) 1370349cc55cSDimitry Andric __nc = __libcpp_asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v); 1371349cc55cSDimitry Andric else 1372349cc55cSDimitry Andric __nc = __libcpp_asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, __v); 1373349cc55cSDimitry Andric if (__nc == -1) 1374349cc55cSDimitry Andric __throw_bad_alloc(); 1375349cc55cSDimitry Andric __nbh.reset(__nb); 1376349cc55cSDimitry Andric } 137781ad6265SDimitry Andric _LIBCPP_DIAGNOSTIC_POP 1378349cc55cSDimitry Andric char* __ne = __nb + __nc; 1379349cc55cSDimitry Andric char* __np = this->__identify_padding(__nb, __ne, __iob); 13800b57cec5SDimitry Andric // Stage 2 - Widen __nar while adding thousands separators 13810b57cec5SDimitry Andric char_type __o[2 * (__nbuf - 1) - 1]; 1382349cc55cSDimitry Andric char_type* __ob = __o; 1383349cc55cSDimitry Andric unique_ptr<char_type, void (*)(void*)> __obh(0, free); 1384cb14a3feSDimitry Andric if (__nb != __nar) { 1385349cc55cSDimitry Andric __ob = (char_type*)malloc(2 * static_cast<size_t>(__nc) * sizeof(char_type)); 1386349cc55cSDimitry Andric if (__ob == 0) 1387349cc55cSDimitry Andric __throw_bad_alloc(); 1388349cc55cSDimitry Andric __obh.reset(__ob); 1389349cc55cSDimitry Andric } 13900b57cec5SDimitry Andric char_type* __op; // pad here 13910b57cec5SDimitry Andric char_type* __oe; // end of output 1392349cc55cSDimitry Andric this->__widen_and_group_float(__nb, __np, __ne, __ob, __op, __oe, __iob.getloc()); 13930b57cec5SDimitry Andric // [__o, __oe) contains thousands_sep'd wide number 13940b57cec5SDimitry Andric // Stage 3 & 4 1395bdd1243dSDimitry Andric __s = std::__pad_and_output(__s, __ob, __op, __oe, __iob, __fl); 1396349cc55cSDimitry Andric return __s; 13970b57cec5SDimitry Andric} 13980b57cec5SDimitry Andric 13990b57cec5SDimitry Andrictemplate <class _CharT, class _OutputIterator> 14000b57cec5SDimitry Andric_OutputIterator 1401cb14a3feSDimitry Andricnum_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, char_type __fl, double __v) const { 1402349cc55cSDimitry Andric return this->__do_put_floating_point(__s, __iob, __fl, __v, ""); 14030b57cec5SDimitry Andric} 14040b57cec5SDimitry Andric 14050b57cec5SDimitry Andrictemplate <class _CharT, class _OutputIterator> 14060b57cec5SDimitry Andric_OutputIterator 1407cb14a3feSDimitry Andricnum_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, char_type __fl, long double __v) const { 1408349cc55cSDimitry Andric return this->__do_put_floating_point(__s, __iob, __fl, __v, "L"); 14090b57cec5SDimitry Andric} 14100b57cec5SDimitry Andric 14110b57cec5SDimitry Andrictemplate <class _CharT, class _OutputIterator> 14120b57cec5SDimitry Andric_OutputIterator 1413cb14a3feSDimitry Andricnum_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, char_type __fl, const void* __v) const { 14140b57cec5SDimitry Andric // Stage 1 - Get pointer in narrow char 14150b57cec5SDimitry Andric const unsigned __nbuf = 20; 14160b57cec5SDimitry Andric char __nar[__nbuf]; 1417349cc55cSDimitry Andric int __nc = __libcpp_snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, "%p", __v); 14180b57cec5SDimitry Andric char* __ne = __nar + __nc; 14190b57cec5SDimitry Andric char* __np = this->__identify_padding(__nar, __ne, __iob); 14200b57cec5SDimitry Andric // Stage 2 - Widen __nar 14210b57cec5SDimitry Andric char_type __o[2 * (__nbuf - 1) - 1]; 14220b57cec5SDimitry Andric char_type* __op; // pad here 14230b57cec5SDimitry Andric char_type* __oe; // end of output 1424bdd1243dSDimitry Andric const ctype<char_type>& __ct = std::use_facet<ctype<char_type> >(__iob.getloc()); 14250b57cec5SDimitry Andric __ct.widen(__nar, __ne, __o); 14260b57cec5SDimitry Andric __oe = __o + (__ne - __nar); 14270b57cec5SDimitry Andric if (__np == __ne) 14280b57cec5SDimitry Andric __op = __oe; 14290b57cec5SDimitry Andric else 14300b57cec5SDimitry Andric __op = __o + (__np - __nar); 14310b57cec5SDimitry Andric // [__o, __oe) contains wide number 14320b57cec5SDimitry Andric // Stage 3 & 4 1433bdd1243dSDimitry Andric return std::__pad_and_output(__s, __o, __op, __oe, __iob, __fl); 14340b57cec5SDimitry Andric} 14350b57cec5SDimitry Andric 143681ad6265SDimitry Andricextern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS num_put<char>; 1437349cc55cSDimitry Andric#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 143881ad6265SDimitry Andricextern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS num_put<wchar_t>; 1439349cc55cSDimitry Andric#endif 14400b57cec5SDimitry Andric 14410b57cec5SDimitry Andrictemplate <class _CharT, class _InputIterator> 1442cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI int __get_up_to_n_digits( 1443cb14a3feSDimitry Andric _InputIterator& __b, _InputIterator __e, ios_base::iostate& __err, const ctype<_CharT>& __ct, int __n) { 14440b57cec5SDimitry Andric // Precondition: __n >= 1 1445cb14a3feSDimitry Andric if (__b == __e) { 14460b57cec5SDimitry Andric __err |= ios_base::eofbit | ios_base::failbit; 14470b57cec5SDimitry Andric return 0; 14480b57cec5SDimitry Andric } 14490b57cec5SDimitry Andric // get first digit 14500b57cec5SDimitry Andric _CharT __c = *__b; 1451cb14a3feSDimitry Andric if (!__ct.is(ctype_base::digit, __c)) { 14520b57cec5SDimitry Andric __err |= ios_base::failbit; 14530b57cec5SDimitry Andric return 0; 14540b57cec5SDimitry Andric } 14550b57cec5SDimitry Andric int __r = __ct.narrow(__c, 0) - '0'; 1456cb14a3feSDimitry Andric for (++__b, (void)--__n; __b != __e && __n > 0; ++__b, (void)--__n) { 14570b57cec5SDimitry Andric // get next digit 14580b57cec5SDimitry Andric __c = *__b; 14590b57cec5SDimitry Andric if (!__ct.is(ctype_base::digit, __c)) 14600b57cec5SDimitry Andric return __r; 14610b57cec5SDimitry Andric __r = __r * 10 + __ct.narrow(__c, 0) - '0'; 14620b57cec5SDimitry Andric } 14630b57cec5SDimitry Andric if (__b == __e) 14640b57cec5SDimitry Andric __err |= ios_base::eofbit; 14650b57cec5SDimitry Andric return __r; 14660b57cec5SDimitry Andric} 14670b57cec5SDimitry Andric 1468cb14a3feSDimitry Andricclass _LIBCPP_EXPORTED_FROM_ABI time_base { 14690b57cec5SDimitry Andricpublic: 14700b57cec5SDimitry Andric enum dateorder { no_order, dmy, mdy, ymd, ydm }; 14710b57cec5SDimitry Andric}; 14720b57cec5SDimitry Andric 14730b57cec5SDimitry Andrictemplate <class _CharT> 1474cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS __time_get_c_storage { 14750b57cec5SDimitry Andricprotected: 14760b57cec5SDimitry Andric typedef basic_string<_CharT> string_type; 14770b57cec5SDimitry Andric 14780b57cec5SDimitry Andric virtual const string_type* __weeks() const; 14790b57cec5SDimitry Andric virtual const string_type* __months() const; 14800b57cec5SDimitry Andric virtual const string_type* __am_pm() const; 14810b57cec5SDimitry Andric virtual const string_type& __c() const; 14820b57cec5SDimitry Andric virtual const string_type& __r() const; 14830b57cec5SDimitry Andric virtual const string_type& __x() const; 14840b57cec5SDimitry Andric virtual const string_type& __X() const; 14850b57cec5SDimitry Andric 1486cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI ~__time_get_c_storage() {} 14870b57cec5SDimitry Andric}; 14880b57cec5SDimitry Andric 1489cb14a3feSDimitry Andrictemplate <> 1490cb14a3feSDimitry Andric_LIBCPP_EXPORTED_FROM_ABI const string* __time_get_c_storage<char>::__weeks() const; 1491cb14a3feSDimitry Andrictemplate <> 1492cb14a3feSDimitry Andric_LIBCPP_EXPORTED_FROM_ABI const string* __time_get_c_storage<char>::__months() const; 1493cb14a3feSDimitry Andrictemplate <> 1494cb14a3feSDimitry Andric_LIBCPP_EXPORTED_FROM_ABI const string* __time_get_c_storage<char>::__am_pm() const; 1495cb14a3feSDimitry Andrictemplate <> 1496cb14a3feSDimitry Andric_LIBCPP_EXPORTED_FROM_ABI const string& __time_get_c_storage<char>::__c() const; 1497cb14a3feSDimitry Andrictemplate <> 1498cb14a3feSDimitry Andric_LIBCPP_EXPORTED_FROM_ABI const string& __time_get_c_storage<char>::__r() const; 1499cb14a3feSDimitry Andrictemplate <> 1500cb14a3feSDimitry Andric_LIBCPP_EXPORTED_FROM_ABI const string& __time_get_c_storage<char>::__x() const; 1501cb14a3feSDimitry Andrictemplate <> 1502cb14a3feSDimitry Andric_LIBCPP_EXPORTED_FROM_ABI const string& __time_get_c_storage<char>::__X() const; 15030b57cec5SDimitry Andric 1504349cc55cSDimitry Andric#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 1505cb14a3feSDimitry Andrictemplate <> 1506cb14a3feSDimitry Andric_LIBCPP_EXPORTED_FROM_ABI const wstring* __time_get_c_storage<wchar_t>::__weeks() const; 1507cb14a3feSDimitry Andrictemplate <> 1508cb14a3feSDimitry Andric_LIBCPP_EXPORTED_FROM_ABI const wstring* __time_get_c_storage<wchar_t>::__months() const; 1509cb14a3feSDimitry Andrictemplate <> 1510cb14a3feSDimitry Andric_LIBCPP_EXPORTED_FROM_ABI const wstring* __time_get_c_storage<wchar_t>::__am_pm() const; 1511cb14a3feSDimitry Andrictemplate <> 1512cb14a3feSDimitry Andric_LIBCPP_EXPORTED_FROM_ABI const wstring& __time_get_c_storage<wchar_t>::__c() const; 1513cb14a3feSDimitry Andrictemplate <> 1514cb14a3feSDimitry Andric_LIBCPP_EXPORTED_FROM_ABI const wstring& __time_get_c_storage<wchar_t>::__r() const; 1515cb14a3feSDimitry Andrictemplate <> 1516cb14a3feSDimitry Andric_LIBCPP_EXPORTED_FROM_ABI const wstring& __time_get_c_storage<wchar_t>::__x() const; 1517cb14a3feSDimitry Andrictemplate <> 1518cb14a3feSDimitry Andric_LIBCPP_EXPORTED_FROM_ABI const wstring& __time_get_c_storage<wchar_t>::__X() const; 1519349cc55cSDimitry Andric#endif 15200b57cec5SDimitry Andric 15210b57cec5SDimitry Andrictemplate <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> > 1522cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS time_get : public locale::facet, public time_base, private __time_get_c_storage<_CharT> { 15230b57cec5SDimitry Andricpublic: 15240b57cec5SDimitry Andric typedef _CharT char_type; 15250b57cec5SDimitry Andric typedef _InputIterator iter_type; 15260b57cec5SDimitry Andric typedef time_base::dateorder dateorder; 15270b57cec5SDimitry Andric typedef basic_string<char_type> string_type; 15280b57cec5SDimitry Andric 1529cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit time_get(size_t __refs = 0) : locale::facet(__refs) {} 15300b57cec5SDimitry Andric 1531cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI dateorder date_order() const { return this->do_date_order(); } 15320b57cec5SDimitry Andric 1533cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iter_type 1534cb14a3feSDimitry Andric get_time(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, tm* __tm) const { 15350b57cec5SDimitry Andric return do_get_time(__b, __e, __iob, __err, __tm); 15360b57cec5SDimitry Andric } 15370b57cec5SDimitry Andric 1538cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iter_type 1539cb14a3feSDimitry Andric get_date(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, tm* __tm) const { 15400b57cec5SDimitry Andric return do_get_date(__b, __e, __iob, __err, __tm); 15410b57cec5SDimitry Andric } 15420b57cec5SDimitry Andric 1543cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iter_type 1544cb14a3feSDimitry Andric get_weekday(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, tm* __tm) const { 15450b57cec5SDimitry Andric return do_get_weekday(__b, __e, __iob, __err, __tm); 15460b57cec5SDimitry Andric } 15470b57cec5SDimitry Andric 1548cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iter_type 1549cb14a3feSDimitry Andric get_monthname(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, tm* __tm) const { 15500b57cec5SDimitry Andric return do_get_monthname(__b, __e, __iob, __err, __tm); 15510b57cec5SDimitry Andric } 15520b57cec5SDimitry Andric 1553cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iter_type 1554cb14a3feSDimitry Andric get_year(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, tm* __tm) const { 15550b57cec5SDimitry Andric return do_get_year(__b, __e, __iob, __err, __tm); 15560b57cec5SDimitry Andric } 15570b57cec5SDimitry Andric 1558cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iter_type 1559cb14a3feSDimitry Andric get(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, tm* __tm, char __fmt, char __mod = 0) 1560cb14a3feSDimitry Andric const { 15610b57cec5SDimitry Andric return do_get(__b, __e, __iob, __err, __tm, __fmt, __mod); 15620b57cec5SDimitry Andric } 15630b57cec5SDimitry Andric 1564cb14a3feSDimitry Andric iter_type 1565cb14a3feSDimitry Andric get(iter_type __b, 1566cb14a3feSDimitry Andric iter_type __e, 1567cb14a3feSDimitry Andric ios_base& __iob, 1568cb14a3feSDimitry Andric ios_base::iostate& __err, 1569cb14a3feSDimitry Andric tm* __tm, 1570cb14a3feSDimitry Andric const char_type* __fmtb, 1571cb14a3feSDimitry Andric const char_type* __fmte) const; 15720b57cec5SDimitry Andric 15730b57cec5SDimitry Andric static locale::id id; 15740b57cec5SDimitry Andric 15750b57cec5SDimitry Andricprotected: 1576bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI_VIRTUAL ~time_get() override {} 15770b57cec5SDimitry Andric 15780b57cec5SDimitry Andric virtual dateorder do_date_order() const; 1579cb14a3feSDimitry Andric virtual iter_type 1580cb14a3feSDimitry Andric do_get_time(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, tm* __tm) const; 1581cb14a3feSDimitry Andric virtual iter_type 1582cb14a3feSDimitry Andric do_get_date(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, tm* __tm) const; 1583cb14a3feSDimitry Andric virtual iter_type 1584cb14a3feSDimitry Andric do_get_weekday(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, tm* __tm) const; 1585cb14a3feSDimitry Andric virtual iter_type 1586cb14a3feSDimitry Andric do_get_monthname(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, tm* __tm) const; 1587cb14a3feSDimitry Andric virtual iter_type 1588cb14a3feSDimitry Andric do_get_year(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, tm* __tm) const; 1589cb14a3feSDimitry Andric virtual iter_type do_get( 1590cb14a3feSDimitry Andric iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, tm* __tm, char __fmt, char __mod) const; 15910b57cec5SDimitry Andric 1592cb14a3feSDimitry Andricprivate: 1593cb14a3feSDimitry Andric void __get_white_space(iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const; 1594cb14a3feSDimitry Andric void __get_percent(iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const; 1595cb14a3feSDimitry Andric 1596cb14a3feSDimitry Andric void __get_weekdayname( 1597cb14a3feSDimitry Andric int& __m, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const; 1598cb14a3feSDimitry Andric void __get_monthname( 1599cb14a3feSDimitry Andric int& __m, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const; 1600cb14a3feSDimitry Andric void __get_day(int& __d, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const; 1601cb14a3feSDimitry Andric void 1602cb14a3feSDimitry Andric __get_month(int& __m, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const; 1603cb14a3feSDimitry Andric void 1604cb14a3feSDimitry Andric __get_year(int& __y, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const; 1605cb14a3feSDimitry Andric void 1606cb14a3feSDimitry Andric __get_year4(int& __y, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const; 1607cb14a3feSDimitry Andric void 1608cb14a3feSDimitry Andric __get_hour(int& __d, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const; 1609cb14a3feSDimitry Andric void 1610cb14a3feSDimitry Andric __get_12_hour(int& __h, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const; 1611cb14a3feSDimitry Andric void 1612cb14a3feSDimitry Andric __get_am_pm(int& __h, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const; 1613cb14a3feSDimitry Andric void 1614cb14a3feSDimitry Andric __get_minute(int& __m, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const; 1615cb14a3feSDimitry Andric void 1616cb14a3feSDimitry Andric __get_second(int& __s, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const; 1617cb14a3feSDimitry Andric void 1618cb14a3feSDimitry Andric __get_weekday(int& __w, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const; 1619cb14a3feSDimitry Andric void __get_day_year_num( 1620cb14a3feSDimitry Andric int& __w, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const; 16210b57cec5SDimitry Andric}; 16220b57cec5SDimitry Andric 16230b57cec5SDimitry Andrictemplate <class _CharT, class _InputIterator> 1624cb14a3feSDimitry Andriclocale::id time_get<_CharT, _InputIterator>::id; 16250b57cec5SDimitry Andric 16260b57cec5SDimitry Andric// time_get primitives 16270b57cec5SDimitry Andric 16280b57cec5SDimitry Andrictemplate <class _CharT, class _InputIterator> 1629cb14a3feSDimitry Andricvoid time_get<_CharT, _InputIterator>::__get_weekdayname( 1630cb14a3feSDimitry Andric int& __w, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const { 16310b57cec5SDimitry Andric // Note: ignoring case comes from the POSIX strptime spec 16320b57cec5SDimitry Andric const string_type* __wk = this->__weeks(); 16335f757f3fSDimitry Andric ptrdiff_t __i = std::__scan_keyword(__b, __e, __wk, __wk + 14, __ct, __err, false) - __wk; 16340b57cec5SDimitry Andric if (__i < 14) 16350b57cec5SDimitry Andric __w = __i % 7; 16360b57cec5SDimitry Andric} 16370b57cec5SDimitry Andric 16380b57cec5SDimitry Andrictemplate <class _CharT, class _InputIterator> 1639cb14a3feSDimitry Andricvoid time_get<_CharT, _InputIterator>::__get_monthname( 1640cb14a3feSDimitry Andric int& __m, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const { 16410b57cec5SDimitry Andric // Note: ignoring case comes from the POSIX strptime spec 16420b57cec5SDimitry Andric const string_type* __month = this->__months(); 16435f757f3fSDimitry Andric ptrdiff_t __i = std::__scan_keyword(__b, __e, __month, __month + 24, __ct, __err, false) - __month; 16440b57cec5SDimitry Andric if (__i < 24) 16450b57cec5SDimitry Andric __m = __i % 12; 16460b57cec5SDimitry Andric} 16470b57cec5SDimitry Andric 16480b57cec5SDimitry Andrictemplate <class _CharT, class _InputIterator> 1649cb14a3feSDimitry Andricvoid time_get<_CharT, _InputIterator>::__get_day( 1650cb14a3feSDimitry Andric int& __d, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const { 16515f757f3fSDimitry Andric int __t = std::__get_up_to_n_digits(__b, __e, __err, __ct, 2); 16520b57cec5SDimitry Andric if (!(__err & ios_base::failbit) && 1 <= __t && __t <= 31) 16530b57cec5SDimitry Andric __d = __t; 16540b57cec5SDimitry Andric else 16550b57cec5SDimitry Andric __err |= ios_base::failbit; 16560b57cec5SDimitry Andric} 16570b57cec5SDimitry Andric 16580b57cec5SDimitry Andrictemplate <class _CharT, class _InputIterator> 1659cb14a3feSDimitry Andricvoid time_get<_CharT, _InputIterator>::__get_month( 1660cb14a3feSDimitry Andric int& __m, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const { 1661bdd1243dSDimitry Andric int __t = std::__get_up_to_n_digits(__b, __e, __err, __ct, 2) - 1; 166281ad6265SDimitry Andric if (!(__err & ios_base::failbit) && 0 <= __t && __t <= 11) 16630b57cec5SDimitry Andric __m = __t; 16640b57cec5SDimitry Andric else 16650b57cec5SDimitry Andric __err |= ios_base::failbit; 16660b57cec5SDimitry Andric} 16670b57cec5SDimitry Andric 16680b57cec5SDimitry Andrictemplate <class _CharT, class _InputIterator> 1669cb14a3feSDimitry Andricvoid time_get<_CharT, _InputIterator>::__get_year( 1670cb14a3feSDimitry Andric int& __y, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const { 1671bdd1243dSDimitry Andric int __t = std::__get_up_to_n_digits(__b, __e, __err, __ct, 4); 1672cb14a3feSDimitry Andric if (!(__err & ios_base::failbit)) { 16730b57cec5SDimitry Andric if (__t < 69) 16740b57cec5SDimitry Andric __t += 2000; 16750b57cec5SDimitry Andric else if (69 <= __t && __t <= 99) 16760b57cec5SDimitry Andric __t += 1900; 16770b57cec5SDimitry Andric __y = __t - 1900; 16780b57cec5SDimitry Andric } 16790b57cec5SDimitry Andric} 16800b57cec5SDimitry Andric 16810b57cec5SDimitry Andrictemplate <class _CharT, class _InputIterator> 1682cb14a3feSDimitry Andricvoid time_get<_CharT, _InputIterator>::__get_year4( 1683cb14a3feSDimitry Andric int& __y, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const { 1684bdd1243dSDimitry Andric int __t = std::__get_up_to_n_digits(__b, __e, __err, __ct, 4); 16850b57cec5SDimitry Andric if (!(__err & ios_base::failbit)) 16860b57cec5SDimitry Andric __y = __t - 1900; 16870b57cec5SDimitry Andric} 16880b57cec5SDimitry Andric 16890b57cec5SDimitry Andrictemplate <class _CharT, class _InputIterator> 1690cb14a3feSDimitry Andricvoid time_get<_CharT, _InputIterator>::__get_hour( 1691cb14a3feSDimitry Andric int& __h, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const { 1692bdd1243dSDimitry Andric int __t = std::__get_up_to_n_digits(__b, __e, __err, __ct, 2); 16930b57cec5SDimitry Andric if (!(__err & ios_base::failbit) && __t <= 23) 16940b57cec5SDimitry Andric __h = __t; 16950b57cec5SDimitry Andric else 16960b57cec5SDimitry Andric __err |= ios_base::failbit; 16970b57cec5SDimitry Andric} 16980b57cec5SDimitry Andric 16990b57cec5SDimitry Andrictemplate <class _CharT, class _InputIterator> 1700cb14a3feSDimitry Andricvoid time_get<_CharT, _InputIterator>::__get_12_hour( 1701cb14a3feSDimitry Andric int& __h, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const { 1702bdd1243dSDimitry Andric int __t = std::__get_up_to_n_digits(__b, __e, __err, __ct, 2); 17030b57cec5SDimitry Andric if (!(__err & ios_base::failbit) && 1 <= __t && __t <= 12) 17040b57cec5SDimitry Andric __h = __t; 17050b57cec5SDimitry Andric else 17060b57cec5SDimitry Andric __err |= ios_base::failbit; 17070b57cec5SDimitry Andric} 17080b57cec5SDimitry Andric 17090b57cec5SDimitry Andrictemplate <class _CharT, class _InputIterator> 1710cb14a3feSDimitry Andricvoid time_get<_CharT, _InputIterator>::__get_minute( 1711cb14a3feSDimitry Andric int& __m, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const { 1712bdd1243dSDimitry Andric int __t = std::__get_up_to_n_digits(__b, __e, __err, __ct, 2); 17130b57cec5SDimitry Andric if (!(__err & ios_base::failbit) && __t <= 59) 17140b57cec5SDimitry Andric __m = __t; 17150b57cec5SDimitry Andric else 17160b57cec5SDimitry Andric __err |= ios_base::failbit; 17170b57cec5SDimitry Andric} 17180b57cec5SDimitry Andric 17190b57cec5SDimitry Andrictemplate <class _CharT, class _InputIterator> 1720cb14a3feSDimitry Andricvoid time_get<_CharT, _InputIterator>::__get_second( 1721cb14a3feSDimitry Andric int& __s, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const { 1722bdd1243dSDimitry Andric int __t = std::__get_up_to_n_digits(__b, __e, __err, __ct, 2); 17230b57cec5SDimitry Andric if (!(__err & ios_base::failbit) && __t <= 60) 17240b57cec5SDimitry Andric __s = __t; 17250b57cec5SDimitry Andric else 17260b57cec5SDimitry Andric __err |= ios_base::failbit; 17270b57cec5SDimitry Andric} 17280b57cec5SDimitry Andric 17290b57cec5SDimitry Andrictemplate <class _CharT, class _InputIterator> 1730cb14a3feSDimitry Andricvoid time_get<_CharT, _InputIterator>::__get_weekday( 1731cb14a3feSDimitry Andric int& __w, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const { 1732bdd1243dSDimitry Andric int __t = std::__get_up_to_n_digits(__b, __e, __err, __ct, 1); 17330b57cec5SDimitry Andric if (!(__err & ios_base::failbit) && __t <= 6) 17340b57cec5SDimitry Andric __w = __t; 17350b57cec5SDimitry Andric else 17360b57cec5SDimitry Andric __err |= ios_base::failbit; 17370b57cec5SDimitry Andric} 17380b57cec5SDimitry Andric 17390b57cec5SDimitry Andrictemplate <class _CharT, class _InputIterator> 1740cb14a3feSDimitry Andricvoid time_get<_CharT, _InputIterator>::__get_day_year_num( 1741cb14a3feSDimitry Andric int& __d, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const { 1742bdd1243dSDimitry Andric int __t = std::__get_up_to_n_digits(__b, __e, __err, __ct, 3); 17430b57cec5SDimitry Andric if (!(__err & ios_base::failbit) && __t <= 365) 17440b57cec5SDimitry Andric __d = __t; 17450b57cec5SDimitry Andric else 17460b57cec5SDimitry Andric __err |= ios_base::failbit; 17470b57cec5SDimitry Andric} 17480b57cec5SDimitry Andric 17490b57cec5SDimitry Andrictemplate <class _CharT, class _InputIterator> 1750cb14a3feSDimitry Andricvoid time_get<_CharT, _InputIterator>::__get_white_space( 1751cb14a3feSDimitry Andric iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const { 17520b57cec5SDimitry Andric for (; __b != __e && __ct.is(ctype_base::space, *__b); ++__b) 17530b57cec5SDimitry Andric ; 17540b57cec5SDimitry Andric if (__b == __e) 17550b57cec5SDimitry Andric __err |= ios_base::eofbit; 17560b57cec5SDimitry Andric} 17570b57cec5SDimitry Andric 17580b57cec5SDimitry Andrictemplate <class _CharT, class _InputIterator> 1759cb14a3feSDimitry Andricvoid time_get<_CharT, _InputIterator>::__get_am_pm( 1760cb14a3feSDimitry Andric int& __h, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const { 17610b57cec5SDimitry Andric const string_type* __ap = this->__am_pm(); 1762cb14a3feSDimitry Andric if (__ap[0].size() + __ap[1].size() == 0) { 17630b57cec5SDimitry Andric __err |= ios_base::failbit; 17640b57cec5SDimitry Andric return; 17650b57cec5SDimitry Andric } 17665f757f3fSDimitry Andric ptrdiff_t __i = std::__scan_keyword(__b, __e, __ap, __ap + 2, __ct, __err, false) - __ap; 17670b57cec5SDimitry Andric if (__i == 0 && __h == 12) 17680b57cec5SDimitry Andric __h = 0; 17690b57cec5SDimitry Andric else if (__i == 1 && __h < 12) 17700b57cec5SDimitry Andric __h += 12; 17710b57cec5SDimitry Andric} 17720b57cec5SDimitry Andric 17730b57cec5SDimitry Andrictemplate <class _CharT, class _InputIterator> 1774cb14a3feSDimitry Andricvoid time_get<_CharT, _InputIterator>::__get_percent( 1775cb14a3feSDimitry Andric iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const { 1776cb14a3feSDimitry Andric if (__b == __e) { 17770b57cec5SDimitry Andric __err |= ios_base::eofbit | ios_base::failbit; 17780b57cec5SDimitry Andric return; 17790b57cec5SDimitry Andric } 17800b57cec5SDimitry Andric if (__ct.narrow(*__b, 0) != '%') 17810b57cec5SDimitry Andric __err |= ios_base::failbit; 17820b57cec5SDimitry Andric else if (++__b == __e) 17830b57cec5SDimitry Andric __err |= ios_base::eofbit; 17840b57cec5SDimitry Andric} 17850b57cec5SDimitry Andric 17860b57cec5SDimitry Andric// time_get end primitives 17870b57cec5SDimitry Andric 17880b57cec5SDimitry Andrictemplate <class _CharT, class _InputIterator> 1789cb14a3feSDimitry Andric_InputIterator time_get<_CharT, _InputIterator>::get( 1790cb14a3feSDimitry Andric iter_type __b, 1791cb14a3feSDimitry Andric iter_type __e, 17920b57cec5SDimitry Andric ios_base& __iob, 1793cb14a3feSDimitry Andric ios_base::iostate& __err, 1794cb14a3feSDimitry Andric tm* __tm, 1795cb14a3feSDimitry Andric const char_type* __fmtb, 1796cb14a3feSDimitry Andric const char_type* __fmte) const { 1797bdd1243dSDimitry Andric const ctype<char_type>& __ct = std::use_facet<ctype<char_type> >(__iob.getloc()); 17980b57cec5SDimitry Andric __err = ios_base::goodbit; 1799cb14a3feSDimitry Andric while (__fmtb != __fmte && __err == ios_base::goodbit) { 1800cb14a3feSDimitry Andric if (__b == __e) { 18010b57cec5SDimitry Andric __err = ios_base::failbit; 18020b57cec5SDimitry Andric break; 18030b57cec5SDimitry Andric } 1804cb14a3feSDimitry Andric if (__ct.narrow(*__fmtb, 0) == '%') { 1805cb14a3feSDimitry Andric if (++__fmtb == __fmte) { 18060b57cec5SDimitry Andric __err = ios_base::failbit; 18070b57cec5SDimitry Andric break; 18080b57cec5SDimitry Andric } 18090b57cec5SDimitry Andric char __cmd = __ct.narrow(*__fmtb, 0); 18100b57cec5SDimitry Andric char __opt = '\0'; 1811cb14a3feSDimitry Andric if (__cmd == 'E' || __cmd == '0') { 1812cb14a3feSDimitry Andric if (++__fmtb == __fmte) { 18130b57cec5SDimitry Andric __err = ios_base::failbit; 18140b57cec5SDimitry Andric break; 18150b57cec5SDimitry Andric } 18160b57cec5SDimitry Andric __opt = __cmd; 18170b57cec5SDimitry Andric __cmd = __ct.narrow(*__fmtb, 0); 18180b57cec5SDimitry Andric } 18190b57cec5SDimitry Andric __b = do_get(__b, __e, __iob, __err, __tm, __cmd, __opt); 18200b57cec5SDimitry Andric ++__fmtb; 1821cb14a3feSDimitry Andric } else if (__ct.is(ctype_base::space, *__fmtb)) { 18220b57cec5SDimitry Andric for (++__fmtb; __fmtb != __fmte && __ct.is(ctype_base::space, *__fmtb); ++__fmtb) 18230b57cec5SDimitry Andric ; 18240b57cec5SDimitry Andric for (; __b != __e && __ct.is(ctype_base::space, *__b); ++__b) 18250b57cec5SDimitry Andric ; 1826cb14a3feSDimitry Andric } else if (__ct.toupper(*__b) == __ct.toupper(*__fmtb)) { 18270b57cec5SDimitry Andric ++__b; 18280b57cec5SDimitry Andric ++__fmtb; 1829cb14a3feSDimitry Andric } else 18300b57cec5SDimitry Andric __err = ios_base::failbit; 18310b57cec5SDimitry Andric } 18320b57cec5SDimitry Andric if (__b == __e) 18330b57cec5SDimitry Andric __err |= ios_base::eofbit; 18340b57cec5SDimitry Andric return __b; 18350b57cec5SDimitry Andric} 18360b57cec5SDimitry Andric 18370b57cec5SDimitry Andrictemplate <class _CharT, class _InputIterator> 1838cb14a3feSDimitry Andrictypename time_get<_CharT, _InputIterator>::dateorder time_get<_CharT, _InputIterator>::do_date_order() const { 18390b57cec5SDimitry Andric return mdy; 18400b57cec5SDimitry Andric} 18410b57cec5SDimitry Andric 18420b57cec5SDimitry Andrictemplate <class _CharT, class _InputIterator> 1843cb14a3feSDimitry Andric_InputIterator time_get<_CharT, _InputIterator>::do_get_time( 1844cb14a3feSDimitry Andric iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, tm* __tm) const { 18450b57cec5SDimitry Andric const char_type __fmt[] = {'%', 'H', ':', '%', 'M', ':', '%', 'S'}; 18460b57cec5SDimitry Andric return get(__b, __e, __iob, __err, __tm, __fmt, __fmt + sizeof(__fmt) / sizeof(__fmt[0])); 18470b57cec5SDimitry Andric} 18480b57cec5SDimitry Andric 18490b57cec5SDimitry Andrictemplate <class _CharT, class _InputIterator> 1850cb14a3feSDimitry Andric_InputIterator time_get<_CharT, _InputIterator>::do_get_date( 1851cb14a3feSDimitry Andric iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, tm* __tm) const { 18520b57cec5SDimitry Andric const string_type& __fmt = this->__x(); 18530b57cec5SDimitry Andric return get(__b, __e, __iob, __err, __tm, __fmt.data(), __fmt.data() + __fmt.size()); 18540b57cec5SDimitry Andric} 18550b57cec5SDimitry Andric 18560b57cec5SDimitry Andrictemplate <class _CharT, class _InputIterator> 1857cb14a3feSDimitry Andric_InputIterator time_get<_CharT, _InputIterator>::do_get_weekday( 1858cb14a3feSDimitry Andric iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, tm* __tm) const { 1859bdd1243dSDimitry Andric const ctype<char_type>& __ct = std::use_facet<ctype<char_type> >(__iob.getloc()); 18600b57cec5SDimitry Andric __get_weekdayname(__tm->tm_wday, __b, __e, __err, __ct); 18610b57cec5SDimitry Andric return __b; 18620b57cec5SDimitry Andric} 18630b57cec5SDimitry Andric 18640b57cec5SDimitry Andrictemplate <class _CharT, class _InputIterator> 1865cb14a3feSDimitry Andric_InputIterator time_get<_CharT, _InputIterator>::do_get_monthname( 1866cb14a3feSDimitry Andric iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, tm* __tm) const { 1867bdd1243dSDimitry Andric const ctype<char_type>& __ct = std::use_facet<ctype<char_type> >(__iob.getloc()); 18680b57cec5SDimitry Andric __get_monthname(__tm->tm_mon, __b, __e, __err, __ct); 18690b57cec5SDimitry Andric return __b; 18700b57cec5SDimitry Andric} 18710b57cec5SDimitry Andric 18720b57cec5SDimitry Andrictemplate <class _CharT, class _InputIterator> 1873cb14a3feSDimitry Andric_InputIterator time_get<_CharT, _InputIterator>::do_get_year( 1874cb14a3feSDimitry Andric iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, tm* __tm) const { 1875bdd1243dSDimitry Andric const ctype<char_type>& __ct = std::use_facet<ctype<char_type> >(__iob.getloc()); 18760b57cec5SDimitry Andric __get_year(__tm->tm_year, __b, __e, __err, __ct); 18770b57cec5SDimitry Andric return __b; 18780b57cec5SDimitry Andric} 18790b57cec5SDimitry Andric 18800b57cec5SDimitry Andrictemplate <class _CharT, class _InputIterator> 1881cb14a3feSDimitry Andric_InputIterator time_get<_CharT, _InputIterator>::do_get( 1882cb14a3feSDimitry Andric iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, tm* __tm, char __fmt, char) const { 18830b57cec5SDimitry Andric __err = ios_base::goodbit; 1884bdd1243dSDimitry Andric const ctype<char_type>& __ct = std::use_facet<ctype<char_type> >(__iob.getloc()); 1885cb14a3feSDimitry Andric switch (__fmt) { 18860b57cec5SDimitry Andric case 'a': 18870b57cec5SDimitry Andric case 'A': 18880b57cec5SDimitry Andric __get_weekdayname(__tm->tm_wday, __b, __e, __err, __ct); 18890b57cec5SDimitry Andric break; 18900b57cec5SDimitry Andric case 'b': 18910b57cec5SDimitry Andric case 'B': 18920b57cec5SDimitry Andric case 'h': 18930b57cec5SDimitry Andric __get_monthname(__tm->tm_mon, __b, __e, __err, __ct); 18940b57cec5SDimitry Andric break; 1895cb14a3feSDimitry Andric case 'c': { 18960b57cec5SDimitry Andric const string_type& __fm = this->__c(); 18970b57cec5SDimitry Andric __b = get(__b, __e, __iob, __err, __tm, __fm.data(), __fm.data() + __fm.size()); 1898cb14a3feSDimitry Andric } break; 18990b57cec5SDimitry Andric case 'd': 19000b57cec5SDimitry Andric case 'e': 19010b57cec5SDimitry Andric __get_day(__tm->tm_mday, __b, __e, __err, __ct); 19020b57cec5SDimitry Andric break; 1903cb14a3feSDimitry Andric case 'D': { 19040b57cec5SDimitry Andric const char_type __fm[] = {'%', 'm', '/', '%', 'd', '/', '%', 'y'}; 19050b57cec5SDimitry Andric __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm) / sizeof(__fm[0])); 1906cb14a3feSDimitry Andric } break; 1907cb14a3feSDimitry Andric case 'F': { 19080b57cec5SDimitry Andric const char_type __fm[] = {'%', 'Y', '-', '%', 'm', '-', '%', 'd'}; 19090b57cec5SDimitry Andric __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm) / sizeof(__fm[0])); 1910cb14a3feSDimitry Andric } break; 19110b57cec5SDimitry Andric case 'H': 19120b57cec5SDimitry Andric __get_hour(__tm->tm_hour, __b, __e, __err, __ct); 19130b57cec5SDimitry Andric break; 19140b57cec5SDimitry Andric case 'I': 19150b57cec5SDimitry Andric __get_12_hour(__tm->tm_hour, __b, __e, __err, __ct); 19160b57cec5SDimitry Andric break; 19170b57cec5SDimitry Andric case 'j': 19180b57cec5SDimitry Andric __get_day_year_num(__tm->tm_yday, __b, __e, __err, __ct); 19190b57cec5SDimitry Andric break; 19200b57cec5SDimitry Andric case 'm': 19210b57cec5SDimitry Andric __get_month(__tm->tm_mon, __b, __e, __err, __ct); 19220b57cec5SDimitry Andric break; 19230b57cec5SDimitry Andric case 'M': 19240b57cec5SDimitry Andric __get_minute(__tm->tm_min, __b, __e, __err, __ct); 19250b57cec5SDimitry Andric break; 19260b57cec5SDimitry Andric case 'n': 19270b57cec5SDimitry Andric case 't': 19280b57cec5SDimitry Andric __get_white_space(__b, __e, __err, __ct); 19290b57cec5SDimitry Andric break; 19300b57cec5SDimitry Andric case 'p': 19310b57cec5SDimitry Andric __get_am_pm(__tm->tm_hour, __b, __e, __err, __ct); 19320b57cec5SDimitry Andric break; 1933cb14a3feSDimitry Andric case 'r': { 19340b57cec5SDimitry Andric const char_type __fm[] = {'%', 'I', ':', '%', 'M', ':', '%', 'S', ' ', '%', 'p'}; 19350b57cec5SDimitry Andric __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm) / sizeof(__fm[0])); 1936cb14a3feSDimitry Andric } break; 1937cb14a3feSDimitry Andric case 'R': { 19380b57cec5SDimitry Andric const char_type __fm[] = {'%', 'H', ':', '%', 'M'}; 19390b57cec5SDimitry Andric __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm) / sizeof(__fm[0])); 1940cb14a3feSDimitry Andric } break; 19410b57cec5SDimitry Andric case 'S': 19420b57cec5SDimitry Andric __get_second(__tm->tm_sec, __b, __e, __err, __ct); 19430b57cec5SDimitry Andric break; 1944cb14a3feSDimitry Andric case 'T': { 19450b57cec5SDimitry Andric const char_type __fm[] = {'%', 'H', ':', '%', 'M', ':', '%', 'S'}; 19460b57cec5SDimitry Andric __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm) / sizeof(__fm[0])); 1947cb14a3feSDimitry Andric } break; 19480b57cec5SDimitry Andric case 'w': 19490b57cec5SDimitry Andric __get_weekday(__tm->tm_wday, __b, __e, __err, __ct); 19500b57cec5SDimitry Andric break; 19510b57cec5SDimitry Andric case 'x': 19520b57cec5SDimitry Andric return do_get_date(__b, __e, __iob, __err, __tm); 1953cb14a3feSDimitry Andric case 'X': { 19540b57cec5SDimitry Andric const string_type& __fm = this->__X(); 19550b57cec5SDimitry Andric __b = get(__b, __e, __iob, __err, __tm, __fm.data(), __fm.data() + __fm.size()); 1956cb14a3feSDimitry Andric } break; 19570b57cec5SDimitry Andric case 'y': 19580b57cec5SDimitry Andric __get_year(__tm->tm_year, __b, __e, __err, __ct); 19590b57cec5SDimitry Andric break; 19600b57cec5SDimitry Andric case 'Y': 19610b57cec5SDimitry Andric __get_year4(__tm->tm_year, __b, __e, __err, __ct); 19620b57cec5SDimitry Andric break; 19630b57cec5SDimitry Andric case '%': 19640b57cec5SDimitry Andric __get_percent(__b, __e, __err, __ct); 19650b57cec5SDimitry Andric break; 19660b57cec5SDimitry Andric default: 19670b57cec5SDimitry Andric __err |= ios_base::failbit; 19680b57cec5SDimitry Andric } 19690b57cec5SDimitry Andric return __b; 19700b57cec5SDimitry Andric} 19710b57cec5SDimitry Andric 197281ad6265SDimitry Andricextern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_get<char>; 1973349cc55cSDimitry Andric#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 197481ad6265SDimitry Andricextern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_get<wchar_t>; 1975349cc55cSDimitry Andric#endif 19760b57cec5SDimitry Andric 1977cb14a3feSDimitry Andricclass _LIBCPP_EXPORTED_FROM_ABI __time_get { 19780b57cec5SDimitry Andricprotected: 19790b57cec5SDimitry Andric locale_t __loc_; 19800b57cec5SDimitry Andric 19810b57cec5SDimitry Andric __time_get(const char* __nm); 19820b57cec5SDimitry Andric __time_get(const string& __nm); 19830b57cec5SDimitry Andric ~__time_get(); 19840b57cec5SDimitry Andric}; 19850b57cec5SDimitry Andric 19860b57cec5SDimitry Andrictemplate <class _CharT> 1987cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS __time_get_storage : public __time_get { 19880b57cec5SDimitry Andricprotected: 19890b57cec5SDimitry Andric typedef basic_string<_CharT> string_type; 19900b57cec5SDimitry Andric 19910b57cec5SDimitry Andric string_type __weeks_[14]; 19920b57cec5SDimitry Andric string_type __months_[24]; 19930b57cec5SDimitry Andric string_type __am_pm_[2]; 19940b57cec5SDimitry Andric string_type __c_; 19950b57cec5SDimitry Andric string_type __r_; 19960b57cec5SDimitry Andric string_type __x_; 19970b57cec5SDimitry Andric string_type __X_; 19980b57cec5SDimitry Andric 19990b57cec5SDimitry Andric explicit __time_get_storage(const char* __nm); 20000b57cec5SDimitry Andric explicit __time_get_storage(const string& __nm); 20010b57cec5SDimitry Andric 20025f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI ~__time_get_storage() {} 20030b57cec5SDimitry Andric 20040b57cec5SDimitry Andric time_base::dateorder __do_date_order() const; 20050b57cec5SDimitry Andric 20060b57cec5SDimitry Andricprivate: 20070b57cec5SDimitry Andric void init(const ctype<_CharT>&); 20080b57cec5SDimitry Andric string_type __analyze(char __fmt, const ctype<_CharT>&); 20090b57cec5SDimitry Andric}; 20100b57cec5SDimitry Andric 20110b57cec5SDimitry Andric#define _LIBCPP_TIME_GET_STORAGE_EXPLICIT_INSTANTIATION(_CharT) \ 2012cb14a3feSDimitry Andric template <> \ 2013cb14a3feSDimitry Andric _LIBCPP_EXPORTED_FROM_ABI time_base::dateorder __time_get_storage<_CharT>::__do_date_order() const; \ 2014cb14a3feSDimitry Andric template <> \ 2015cb14a3feSDimitry Andric _LIBCPP_EXPORTED_FROM_ABI __time_get_storage<_CharT>::__time_get_storage(const char*); \ 2016cb14a3feSDimitry Andric template <> \ 2017cb14a3feSDimitry Andric _LIBCPP_EXPORTED_FROM_ABI __time_get_storage<_CharT>::__time_get_storage(const string&); \ 2018cb14a3feSDimitry Andric template <> \ 2019cb14a3feSDimitry Andric _LIBCPP_EXPORTED_FROM_ABI void __time_get_storage<_CharT>::init(const ctype<_CharT>&); \ 2020cb14a3feSDimitry Andric template <> \ 2021cb14a3feSDimitry Andric _LIBCPP_EXPORTED_FROM_ABI __time_get_storage<_CharT>::string_type __time_get_storage<_CharT>::__analyze( \ 2022cb14a3feSDimitry Andric char, const ctype<_CharT>&); \ 202306c3fb27SDimitry Andric extern template _LIBCPP_EXPORTED_FROM_ABI time_base::dateorder __time_get_storage<_CharT>::__do_date_order() const; \ 202406c3fb27SDimitry Andric extern template _LIBCPP_EXPORTED_FROM_ABI __time_get_storage<_CharT>::__time_get_storage(const char*); \ 202506c3fb27SDimitry Andric extern template _LIBCPP_EXPORTED_FROM_ABI __time_get_storage<_CharT>::__time_get_storage(const string&); \ 202606c3fb27SDimitry Andric extern template _LIBCPP_EXPORTED_FROM_ABI void __time_get_storage<_CharT>::init(const ctype<_CharT>&); \ 2027cb14a3feSDimitry Andric extern template _LIBCPP_EXPORTED_FROM_ABI __time_get_storage<_CharT>::string_type \ 2028cb14a3feSDimitry Andric __time_get_storage<_CharT>::__analyze(char, const ctype<_CharT>&); \ 20290b57cec5SDimitry Andric /**/ 20300b57cec5SDimitry Andric 20310b57cec5SDimitry Andric_LIBCPP_TIME_GET_STORAGE_EXPLICIT_INSTANTIATION(char) 2032bdd1243dSDimitry Andric#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 20330b57cec5SDimitry Andric_LIBCPP_TIME_GET_STORAGE_EXPLICIT_INSTANTIATION(wchar_t) 2034bdd1243dSDimitry Andric#endif 20350b57cec5SDimitry Andric#undef _LIBCPP_TIME_GET_STORAGE_EXPLICIT_INSTANTIATION 20360b57cec5SDimitry Andric 20370b57cec5SDimitry Andrictemplate <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> > 20380b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS time_get_byname 20390b57cec5SDimitry Andric : public time_get<_CharT, _InputIterator>, 2040cb14a3feSDimitry Andric private __time_get_storage<_CharT> { 20410b57cec5SDimitry Andricpublic: 20420b57cec5SDimitry Andric typedef time_base::dateorder dateorder; 20430b57cec5SDimitry Andric typedef _InputIterator iter_type; 20440b57cec5SDimitry Andric typedef _CharT char_type; 20450b57cec5SDimitry Andric typedef basic_string<char_type> string_type; 20460b57cec5SDimitry Andric 2047cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit time_get_byname(const char* __nm, size_t __refs = 0) 2048cb14a3feSDimitry Andric : time_get<_CharT, _InputIterator>(__refs), __time_get_storage<_CharT>(__nm) {} 2049cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit time_get_byname(const string& __nm, size_t __refs = 0) 2050cb14a3feSDimitry Andric : time_get<_CharT, _InputIterator>(__refs), __time_get_storage<_CharT>(__nm) {} 20510b57cec5SDimitry Andric 20520b57cec5SDimitry Andricprotected: 2053bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI_VIRTUAL ~time_get_byname() override {} 20540b57cec5SDimitry Andric 2055bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI_VIRTUAL dateorder do_date_order() const override { return this->__do_date_order(); } 2056cb14a3feSDimitry Andric 20570b57cec5SDimitry Andricprivate: 2058bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI_VIRTUAL const string_type* __weeks() const override { return this->__weeks_; } 2059bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI_VIRTUAL const string_type* __months() const override { return this->__months_; } 2060bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI_VIRTUAL const string_type* __am_pm() const override { return this->__am_pm_; } 2061bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI_VIRTUAL const string_type& __c() const override { return this->__c_; } 2062bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI_VIRTUAL const string_type& __r() const override { return this->__r_; } 2063bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI_VIRTUAL const string_type& __x() const override { return this->__x_; } 2064bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI_VIRTUAL const string_type& __X() const override { return this->__X_; } 20650b57cec5SDimitry Andric}; 20660b57cec5SDimitry Andric 206781ad6265SDimitry Andricextern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_get_byname<char>; 2068349cc55cSDimitry Andric#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 206981ad6265SDimitry Andricextern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_get_byname<wchar_t>; 2070349cc55cSDimitry Andric#endif 20710b57cec5SDimitry Andric 2072cb14a3feSDimitry Andricclass _LIBCPP_EXPORTED_FROM_ABI __time_put { 20730b57cec5SDimitry Andric locale_t __loc_; 2074cb14a3feSDimitry Andric 20750b57cec5SDimitry Andricprotected: 20765f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI __time_put() : __loc_(_LIBCPP_GET_C_LOCALE) {} 20770b57cec5SDimitry Andric __time_put(const char* __nm); 20780b57cec5SDimitry Andric __time_put(const string& __nm); 20790b57cec5SDimitry Andric ~__time_put(); 2080cb14a3feSDimitry Andric void __do_put(char* __nb, char*& __ne, const tm* __tm, char __fmt, char __mod) const; 2081bdd1243dSDimitry Andric#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 2082cb14a3feSDimitry Andric void __do_put(wchar_t* __wb, wchar_t*& __we, const tm* __tm, char __fmt, char __mod) const; 2083bdd1243dSDimitry Andric#endif 20840b57cec5SDimitry Andric}; 20850b57cec5SDimitry Andric 20860b57cec5SDimitry Andrictemplate <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> > 2087cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS time_put : public locale::facet, private __time_put { 20880b57cec5SDimitry Andricpublic: 20890b57cec5SDimitry Andric typedef _CharT char_type; 20900b57cec5SDimitry Andric typedef _OutputIterator iter_type; 20910b57cec5SDimitry Andric 2092cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit time_put(size_t __refs = 0) : locale::facet(__refs) {} 20930b57cec5SDimitry Andric 2094cb14a3feSDimitry Andric iter_type 2095cb14a3feSDimitry Andric put(iter_type __s, ios_base& __iob, char_type __fl, const tm* __tm, const char_type* __pb, const char_type* __pe) 2096cb14a3feSDimitry Andric const; 20970b57cec5SDimitry Andric 2098cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iter_type 2099cb14a3feSDimitry Andric put(iter_type __s, ios_base& __iob, char_type __fl, const tm* __tm, char __fmt, char __mod = 0) const { 21000b57cec5SDimitry Andric return do_put(__s, __iob, __fl, __tm, __fmt, __mod); 21010b57cec5SDimitry Andric } 21020b57cec5SDimitry Andric 21030b57cec5SDimitry Andric static locale::id id; 21040b57cec5SDimitry Andric 21050b57cec5SDimitry Andricprotected: 2106bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI_VIRTUAL ~time_put() override {} 2107cb14a3feSDimitry Andric virtual iter_type do_put(iter_type __s, ios_base&, char_type, const tm* __tm, char __fmt, char __mod) const; 21080b57cec5SDimitry Andric 2109cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit time_put(const char* __nm, size_t __refs) : locale::facet(__refs), __time_put(__nm) {} 2110cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit time_put(const string& __nm, size_t __refs) 2111cb14a3feSDimitry Andric : locale::facet(__refs), __time_put(__nm) {} 21120b57cec5SDimitry Andric}; 21130b57cec5SDimitry Andric 21140b57cec5SDimitry Andrictemplate <class _CharT, class _OutputIterator> 2115cb14a3feSDimitry Andriclocale::id time_put<_CharT, _OutputIterator>::id; 21160b57cec5SDimitry Andric 21170b57cec5SDimitry Andrictemplate <class _CharT, class _OutputIterator> 2118cb14a3feSDimitry Andric_OutputIterator time_put<_CharT, _OutputIterator>::put( 2119cb14a3feSDimitry Andric iter_type __s, ios_base& __iob, char_type __fl, const tm* __tm, const char_type* __pb, const char_type* __pe) 2120cb14a3feSDimitry Andric const { 2121bdd1243dSDimitry Andric const ctype<char_type>& __ct = std::use_facet<ctype<char_type> >(__iob.getloc()); 2122cb14a3feSDimitry Andric for (; __pb != __pe; ++__pb) { 2123cb14a3feSDimitry Andric if (__ct.narrow(*__pb, 0) == '%') { 2124cb14a3feSDimitry Andric if (++__pb == __pe) { 21250b57cec5SDimitry Andric *__s++ = __pb[-1]; 21260b57cec5SDimitry Andric break; 21270b57cec5SDimitry Andric } 21280b57cec5SDimitry Andric char __mod = 0; 21290b57cec5SDimitry Andric char __fmt = __ct.narrow(*__pb, 0); 2130cb14a3feSDimitry Andric if (__fmt == 'E' || __fmt == 'O') { 2131cb14a3feSDimitry Andric if (++__pb == __pe) { 21320b57cec5SDimitry Andric *__s++ = __pb[-2]; 21330b57cec5SDimitry Andric *__s++ = __pb[-1]; 21340b57cec5SDimitry Andric break; 21350b57cec5SDimitry Andric } 21360b57cec5SDimitry Andric __mod = __fmt; 21370b57cec5SDimitry Andric __fmt = __ct.narrow(*__pb, 0); 21380b57cec5SDimitry Andric } 21390b57cec5SDimitry Andric __s = do_put(__s, __iob, __fl, __tm, __fmt, __mod); 2140cb14a3feSDimitry Andric } else 21410b57cec5SDimitry Andric *__s++ = *__pb; 21420b57cec5SDimitry Andric } 21430b57cec5SDimitry Andric return __s; 21440b57cec5SDimitry Andric} 21450b57cec5SDimitry Andric 21460b57cec5SDimitry Andrictemplate <class _CharT, class _OutputIterator> 2147cb14a3feSDimitry Andric_OutputIterator time_put<_CharT, _OutputIterator>::do_put( 2148cb14a3feSDimitry Andric iter_type __s, ios_base&, char_type, const tm* __tm, char __fmt, char __mod) const { 21490b57cec5SDimitry Andric char_type __nar[100]; 21500b57cec5SDimitry Andric char_type* __nb = __nar; 21510b57cec5SDimitry Andric char_type* __ne = __nb + 100; 21520b57cec5SDimitry Andric __do_put(__nb, __ne, __tm, __fmt, __mod); 21535f757f3fSDimitry Andric return std::copy(__nb, __ne, __s); 21540b57cec5SDimitry Andric} 21550b57cec5SDimitry Andric 215681ad6265SDimitry Andricextern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_put<char>; 2157349cc55cSDimitry Andric#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 215881ad6265SDimitry Andricextern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_put<wchar_t>; 2159349cc55cSDimitry Andric#endif 21600b57cec5SDimitry Andric 21610b57cec5SDimitry Andrictemplate <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> > 2162cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS time_put_byname : public time_put<_CharT, _OutputIterator> { 21630b57cec5SDimitry Andricpublic: 2164cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit time_put_byname(const char* __nm, size_t __refs = 0) 21650b57cec5SDimitry Andric : time_put<_CharT, _OutputIterator>(__nm, __refs) {} 21660b57cec5SDimitry Andric 2167cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit time_put_byname(const string& __nm, size_t __refs = 0) 21680b57cec5SDimitry Andric : time_put<_CharT, _OutputIterator>(__nm, __refs) {} 21690b57cec5SDimitry Andric 21700b57cec5SDimitry Andricprotected: 2171bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI_VIRTUAL ~time_put_byname() override {} 21720b57cec5SDimitry Andric}; 21730b57cec5SDimitry Andric 217481ad6265SDimitry Andricextern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_put_byname<char>; 2175349cc55cSDimitry Andric#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 217681ad6265SDimitry Andricextern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_put_byname<wchar_t>; 2177349cc55cSDimitry Andric#endif 21780b57cec5SDimitry Andric 21790b57cec5SDimitry Andric// money_base 21800b57cec5SDimitry Andric 2181cb14a3feSDimitry Andricclass _LIBCPP_EXPORTED_FROM_ABI money_base { 21820b57cec5SDimitry Andricpublic: 21830b57cec5SDimitry Andric enum part { none, space, symbol, sign, value }; 2184cb14a3feSDimitry Andric struct pattern { 2185cb14a3feSDimitry Andric char field[4]; 2186cb14a3feSDimitry Andric }; 21870b57cec5SDimitry Andric 21885f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI money_base() {} 21890b57cec5SDimitry Andric}; 21900b57cec5SDimitry Andric 21910b57cec5SDimitry Andric// moneypunct 21920b57cec5SDimitry Andric 21930b57cec5SDimitry Andrictemplate <class _CharT, bool _International = false> 2194cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS moneypunct : public locale::facet, public money_base { 21950b57cec5SDimitry Andricpublic: 21960b57cec5SDimitry Andric typedef _CharT char_type; 21970b57cec5SDimitry Andric typedef basic_string<char_type> string_type; 21980b57cec5SDimitry Andric 2199cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit moneypunct(size_t __refs = 0) : locale::facet(__refs) {} 22000b57cec5SDimitry Andric 22015f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI char_type decimal_point() const { return do_decimal_point(); } 22025f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI char_type thousands_sep() const { return do_thousands_sep(); } 22035f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI string grouping() const { return do_grouping(); } 22045f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI string_type curr_symbol() const { return do_curr_symbol(); } 22055f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI string_type positive_sign() const { return do_positive_sign(); } 22065f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI string_type negative_sign() const { return do_negative_sign(); } 22075f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI int frac_digits() const { return do_frac_digits(); } 22085f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI pattern pos_format() const { return do_pos_format(); } 22095f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI pattern neg_format() const { return do_neg_format(); } 22100b57cec5SDimitry Andric 22110b57cec5SDimitry Andric static locale::id id; 22120b57cec5SDimitry Andric static const bool intl = _International; 22130b57cec5SDimitry Andric 22140b57cec5SDimitry Andricprotected: 2215bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI_VIRTUAL ~moneypunct() override {} 22160b57cec5SDimitry Andric 22170b57cec5SDimitry Andric virtual char_type do_decimal_point() const { return numeric_limits<char_type>::max(); } 22180b57cec5SDimitry Andric virtual char_type do_thousands_sep() const { return numeric_limits<char_type>::max(); } 22190b57cec5SDimitry Andric virtual string do_grouping() const { return string(); } 22200b57cec5SDimitry Andric virtual string_type do_curr_symbol() const { return string_type(); } 22210b57cec5SDimitry Andric virtual string_type do_positive_sign() const { return string_type(); } 22220b57cec5SDimitry Andric virtual string_type do_negative_sign() const { return string_type(1, '-'); } 22230b57cec5SDimitry Andric virtual int do_frac_digits() const { return 0; } 2224cb14a3feSDimitry Andric virtual pattern do_pos_format() const { 2225cb14a3feSDimitry Andric pattern __p = {{symbol, sign, none, value}}; 2226cb14a3feSDimitry Andric return __p; 2227cb14a3feSDimitry Andric } 2228cb14a3feSDimitry Andric virtual pattern do_neg_format() const { 2229cb14a3feSDimitry Andric pattern __p = {{symbol, sign, none, value}}; 2230cb14a3feSDimitry Andric return __p; 2231cb14a3feSDimitry Andric } 22320b57cec5SDimitry Andric}; 22330b57cec5SDimitry Andric 22340b57cec5SDimitry Andrictemplate <class _CharT, bool _International> 2235cb14a3feSDimitry Andriclocale::id moneypunct<_CharT, _International>::id; 22360b57cec5SDimitry Andric 22370b57cec5SDimitry Andrictemplate <class _CharT, bool _International> 2238cb14a3feSDimitry Andricconst bool moneypunct<_CharT, _International>::intl; 22390b57cec5SDimitry Andric 224081ad6265SDimitry Andricextern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct<char, false>; 224181ad6265SDimitry Andricextern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct<char, true>; 2242349cc55cSDimitry Andric#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 224381ad6265SDimitry Andricextern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct<wchar_t, false>; 224481ad6265SDimitry Andricextern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct<wchar_t, true>; 2245349cc55cSDimitry Andric#endif 22460b57cec5SDimitry Andric 22470b57cec5SDimitry Andric// moneypunct_byname 22480b57cec5SDimitry Andric 22490b57cec5SDimitry Andrictemplate <class _CharT, bool _International = false> 2250cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS moneypunct_byname : public moneypunct<_CharT, _International> { 22510b57cec5SDimitry Andricpublic: 22520b57cec5SDimitry Andric typedef money_base::pattern pattern; 22530b57cec5SDimitry Andric typedef _CharT char_type; 22540b57cec5SDimitry Andric typedef basic_string<char_type> string_type; 22550b57cec5SDimitry Andric 2256cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit moneypunct_byname(const char* __nm, size_t __refs = 0) 2257cb14a3feSDimitry Andric : moneypunct<_CharT, _International>(__refs) { 2258cb14a3feSDimitry Andric init(__nm); 2259cb14a3feSDimitry Andric } 22600b57cec5SDimitry Andric 2261cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit moneypunct_byname(const string& __nm, size_t __refs = 0) 2262cb14a3feSDimitry Andric : moneypunct<_CharT, _International>(__refs) { 2263cb14a3feSDimitry Andric init(__nm.c_str()); 2264cb14a3feSDimitry Andric } 22650b57cec5SDimitry Andric 22660b57cec5SDimitry Andricprotected: 2267bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI_VIRTUAL ~moneypunct_byname() override {} 22680b57cec5SDimitry Andric 2269bdd1243dSDimitry Andric char_type do_decimal_point() const override { return __decimal_point_; } 2270bdd1243dSDimitry Andric char_type do_thousands_sep() const override { return __thousands_sep_; } 2271bdd1243dSDimitry Andric string do_grouping() const override { return __grouping_; } 2272bdd1243dSDimitry Andric string_type do_curr_symbol() const override { return __curr_symbol_; } 2273bdd1243dSDimitry Andric string_type do_positive_sign() const override { return __positive_sign_; } 2274bdd1243dSDimitry Andric string_type do_negative_sign() const override { return __negative_sign_; } 2275bdd1243dSDimitry Andric int do_frac_digits() const override { return __frac_digits_; } 2276bdd1243dSDimitry Andric pattern do_pos_format() const override { return __pos_format_; } 2277bdd1243dSDimitry Andric pattern do_neg_format() const override { return __neg_format_; } 22780b57cec5SDimitry Andric 22790b57cec5SDimitry Andricprivate: 22800b57cec5SDimitry Andric char_type __decimal_point_; 22810b57cec5SDimitry Andric char_type __thousands_sep_; 22820b57cec5SDimitry Andric string __grouping_; 22830b57cec5SDimitry Andric string_type __curr_symbol_; 22840b57cec5SDimitry Andric string_type __positive_sign_; 22850b57cec5SDimitry Andric string_type __negative_sign_; 22860b57cec5SDimitry Andric int __frac_digits_; 22870b57cec5SDimitry Andric pattern __pos_format_; 22880b57cec5SDimitry Andric pattern __neg_format_; 22890b57cec5SDimitry Andric 22900b57cec5SDimitry Andric void init(const char*); 22910b57cec5SDimitry Andric}; 22920b57cec5SDimitry Andric 2293cb14a3feSDimitry Andrictemplate <> 2294cb14a3feSDimitry Andric_LIBCPP_EXPORTED_FROM_ABI void moneypunct_byname<char, false>::init(const char*); 2295cb14a3feSDimitry Andrictemplate <> 2296cb14a3feSDimitry Andric_LIBCPP_EXPORTED_FROM_ABI void moneypunct_byname<char, true>::init(const char*); 229781ad6265SDimitry Andricextern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct_byname<char, false>; 229881ad6265SDimitry Andricextern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct_byname<char, true>; 2299349cc55cSDimitry Andric 2300349cc55cSDimitry Andric#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 2301cb14a3feSDimitry Andrictemplate <> 2302cb14a3feSDimitry Andric_LIBCPP_EXPORTED_FROM_ABI void moneypunct_byname<wchar_t, false>::init(const char*); 2303cb14a3feSDimitry Andrictemplate <> 2304cb14a3feSDimitry Andric_LIBCPP_EXPORTED_FROM_ABI void moneypunct_byname<wchar_t, true>::init(const char*); 230581ad6265SDimitry Andricextern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct_byname<wchar_t, false>; 230681ad6265SDimitry Andricextern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct_byname<wchar_t, true>; 2307349cc55cSDimitry Andric#endif 23080b57cec5SDimitry Andric 23090b57cec5SDimitry Andric// money_get 23100b57cec5SDimitry Andric 23110b57cec5SDimitry Andrictemplate <class _CharT> 2312cb14a3feSDimitry Andricclass __money_get { 23130b57cec5SDimitry Andricprotected: 23140b57cec5SDimitry Andric typedef _CharT char_type; 23150b57cec5SDimitry Andric typedef basic_string<char_type> string_type; 23160b57cec5SDimitry Andric 23175f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI __money_get() {} 23180b57cec5SDimitry Andric 2319cb14a3feSDimitry Andric static void __gather_info( 2320cb14a3feSDimitry Andric bool __intl, 2321cb14a3feSDimitry Andric const locale& __loc, 2322cb14a3feSDimitry Andric money_base::pattern& __pat, 2323cb14a3feSDimitry Andric char_type& __dp, 2324cb14a3feSDimitry Andric char_type& __ts, 2325cb14a3feSDimitry Andric string& __grp, 2326cb14a3feSDimitry Andric string_type& __sym, 2327cb14a3feSDimitry Andric string_type& __psn, 2328cb14a3feSDimitry Andric string_type& __nsn, 2329cb14a3feSDimitry Andric int& __fd); 23300b57cec5SDimitry Andric}; 23310b57cec5SDimitry Andric 23320b57cec5SDimitry Andrictemplate <class _CharT> 2333cb14a3feSDimitry Andricvoid __money_get<_CharT>::__gather_info( 2334cb14a3feSDimitry Andric bool __intl, 2335cb14a3feSDimitry Andric const locale& __loc, 2336cb14a3feSDimitry Andric money_base::pattern& __pat, 2337cb14a3feSDimitry Andric char_type& __dp, 2338cb14a3feSDimitry Andric char_type& __ts, 2339cb14a3feSDimitry Andric string& __grp, 2340cb14a3feSDimitry Andric string_type& __sym, 2341cb14a3feSDimitry Andric string_type& __psn, 2342cb14a3feSDimitry Andric string_type& __nsn, 2343cb14a3feSDimitry Andric int& __fd) { 2344cb14a3feSDimitry Andric if (__intl) { 2345cb14a3feSDimitry Andric const moneypunct<char_type, true>& __mp = std::use_facet<moneypunct<char_type, true> >(__loc); 23460b57cec5SDimitry Andric __pat = __mp.neg_format(); 23470b57cec5SDimitry Andric __nsn = __mp.negative_sign(); 23480b57cec5SDimitry Andric __psn = __mp.positive_sign(); 23490b57cec5SDimitry Andric __dp = __mp.decimal_point(); 23500b57cec5SDimitry Andric __ts = __mp.thousands_sep(); 23510b57cec5SDimitry Andric __grp = __mp.grouping(); 23520b57cec5SDimitry Andric __sym = __mp.curr_symbol(); 23530b57cec5SDimitry Andric __fd = __mp.frac_digits(); 2354cb14a3feSDimitry Andric } else { 2355cb14a3feSDimitry Andric const moneypunct<char_type, false>& __mp = std::use_facet<moneypunct<char_type, false> >(__loc); 23560b57cec5SDimitry Andric __pat = __mp.neg_format(); 23570b57cec5SDimitry Andric __nsn = __mp.negative_sign(); 23580b57cec5SDimitry Andric __psn = __mp.positive_sign(); 23590b57cec5SDimitry Andric __dp = __mp.decimal_point(); 23600b57cec5SDimitry Andric __ts = __mp.thousands_sep(); 23610b57cec5SDimitry Andric __grp = __mp.grouping(); 23620b57cec5SDimitry Andric __sym = __mp.curr_symbol(); 23630b57cec5SDimitry Andric __fd = __mp.frac_digits(); 23640b57cec5SDimitry Andric } 23650b57cec5SDimitry Andric} 23660b57cec5SDimitry Andric 236781ad6265SDimitry Andricextern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __money_get<char>; 2368349cc55cSDimitry Andric#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 236981ad6265SDimitry Andricextern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __money_get<wchar_t>; 2370349cc55cSDimitry Andric#endif 23710b57cec5SDimitry Andric 23720b57cec5SDimitry Andrictemplate <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> > 2373cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS money_get : public locale::facet, private __money_get<_CharT> { 23740b57cec5SDimitry Andricpublic: 23750b57cec5SDimitry Andric typedef _CharT char_type; 23760b57cec5SDimitry Andric typedef _InputIterator iter_type; 23770b57cec5SDimitry Andric typedef basic_string<char_type> string_type; 23780b57cec5SDimitry Andric 2379cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit money_get(size_t __refs = 0) : locale::facet(__refs) {} 23800b57cec5SDimitry Andric 2381cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iter_type 2382cb14a3feSDimitry Andric get(iter_type __b, iter_type __e, bool __intl, ios_base& __iob, ios_base::iostate& __err, long double& __v) const { 23830b57cec5SDimitry Andric return do_get(__b, __e, __intl, __iob, __err, __v); 23840b57cec5SDimitry Andric } 23850b57cec5SDimitry Andric 2386cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iter_type 2387cb14a3feSDimitry Andric get(iter_type __b, iter_type __e, bool __intl, ios_base& __iob, ios_base::iostate& __err, string_type& __v) const { 23880b57cec5SDimitry Andric return do_get(__b, __e, __intl, __iob, __err, __v); 23890b57cec5SDimitry Andric } 23900b57cec5SDimitry Andric 23910b57cec5SDimitry Andric static locale::id id; 23920b57cec5SDimitry Andric 23930b57cec5SDimitry Andricprotected: 2394bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI_VIRTUAL ~money_get() override {} 23950b57cec5SDimitry Andric 2396cb14a3feSDimitry Andric virtual iter_type 2397cb14a3feSDimitry Andric do_get(iter_type __b, iter_type __e, bool __intl, ios_base& __iob, ios_base::iostate& __err, long double& __v) const; 2398cb14a3feSDimitry Andric virtual iter_type 2399cb14a3feSDimitry Andric do_get(iter_type __b, iter_type __e, bool __intl, ios_base& __iob, ios_base::iostate& __err, string_type& __v) const; 24000b57cec5SDimitry Andric 24010b57cec5SDimitry Andricprivate: 2402cb14a3feSDimitry Andric static bool __do_get( 2403cb14a3feSDimitry Andric iter_type& __b, 2404cb14a3feSDimitry Andric iter_type __e, 2405cb14a3feSDimitry Andric bool __intl, 2406cb14a3feSDimitry Andric const locale& __loc, 2407cb14a3feSDimitry Andric ios_base::fmtflags __flags, 2408cb14a3feSDimitry Andric ios_base::iostate& __err, 2409cb14a3feSDimitry Andric bool& __neg, 2410cb14a3feSDimitry Andric const ctype<char_type>& __ct, 24110b57cec5SDimitry Andric unique_ptr<char_type, void (*)(void*)>& __wb, 2412cb14a3feSDimitry Andric char_type*& __wn, 2413cb14a3feSDimitry Andric char_type* __we); 24140b57cec5SDimitry Andric}; 24150b57cec5SDimitry Andric 24160b57cec5SDimitry Andrictemplate <class _CharT, class _InputIterator> 2417cb14a3feSDimitry Andriclocale::id money_get<_CharT, _InputIterator>::id; 24180b57cec5SDimitry Andric 241906c3fb27SDimitry Andric_LIBCPP_EXPORTED_FROM_ABI void __do_nothing(void*); 24200b57cec5SDimitry Andric 24210b57cec5SDimitry Andrictemplate <class _Tp> 2422cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI void __double_or_nothing(unique_ptr<_Tp, void (*)(void*)>& __b, _Tp*& __n, _Tp*& __e) { 24230b57cec5SDimitry Andric bool __owns = __b.get_deleter() != __do_nothing; 24240b57cec5SDimitry Andric size_t __cur_cap = static_cast<size_t>(__e - __b.get()) * sizeof(_Tp); 2425cb14a3feSDimitry Andric size_t __new_cap = __cur_cap < numeric_limits<size_t>::max() / 2 ? 2 * __cur_cap : numeric_limits<size_t>::max(); 24260b57cec5SDimitry Andric if (__new_cap == 0) 24270b57cec5SDimitry Andric __new_cap = sizeof(_Tp); 24280b57cec5SDimitry Andric size_t __n_off = static_cast<size_t>(__n - __b.get()); 2429bdd1243dSDimitry Andric _Tp* __t = (_Tp*)std::realloc(__owns ? __b.get() : 0, __new_cap); 24300b57cec5SDimitry Andric if (__t == 0) 24310b57cec5SDimitry Andric __throw_bad_alloc(); 24320b57cec5SDimitry Andric if (__owns) 24330b57cec5SDimitry Andric __b.release(); 24340b57cec5SDimitry Andric __b = unique_ptr<_Tp, void (*)(void*)>(__t, free); 24350b57cec5SDimitry Andric __new_cap /= sizeof(_Tp); 24360b57cec5SDimitry Andric __n = __b.get() + __n_off; 24370b57cec5SDimitry Andric __e = __b.get() + __new_cap; 24380b57cec5SDimitry Andric} 24390b57cec5SDimitry Andric 24400b57cec5SDimitry Andric// true == success 24410b57cec5SDimitry Andrictemplate <class _CharT, class _InputIterator> 2442cb14a3feSDimitry Andricbool money_get<_CharT, _InputIterator>::__do_get( 2443cb14a3feSDimitry Andric iter_type& __b, 2444cb14a3feSDimitry Andric iter_type __e, 2445cb14a3feSDimitry Andric bool __intl, 2446cb14a3feSDimitry Andric const locale& __loc, 24470b57cec5SDimitry Andric ios_base::fmtflags __flags, 24480b57cec5SDimitry Andric ios_base::iostate& __err, 24490b57cec5SDimitry Andric bool& __neg, 24500b57cec5SDimitry Andric const ctype<char_type>& __ct, 24510b57cec5SDimitry Andric unique_ptr<char_type, void (*)(void*)>& __wb, 2452cb14a3feSDimitry Andric char_type*& __wn, 2453cb14a3feSDimitry Andric char_type* __we) { 2454349cc55cSDimitry Andric if (__b == __e) { 2455349cc55cSDimitry Andric __err |= ios_base::failbit; 2456349cc55cSDimitry Andric return false; 2457349cc55cSDimitry Andric } 24580b57cec5SDimitry Andric const unsigned __bz = 100; 24590b57cec5SDimitry Andric unsigned __gbuf[__bz]; 24600b57cec5SDimitry Andric unique_ptr<unsigned, void (*)(void*)> __gb(__gbuf, __do_nothing); 24610b57cec5SDimitry Andric unsigned* __gn = __gb.get(); 24620b57cec5SDimitry Andric unsigned* __ge = __gn + __bz; 24630b57cec5SDimitry Andric money_base::pattern __pat; 24640b57cec5SDimitry Andric char_type __dp; 24650b57cec5SDimitry Andric char_type __ts; 24660b57cec5SDimitry Andric string __grp; 24670b57cec5SDimitry Andric string_type __sym; 24680b57cec5SDimitry Andric string_type __psn; 24690b57cec5SDimitry Andric string_type __nsn; 24700b57cec5SDimitry Andric // Capture the spaces read into money_base::{space,none} so they 24710b57cec5SDimitry Andric // can be compared to initial spaces in __sym. 24720b57cec5SDimitry Andric string_type __spaces; 24730b57cec5SDimitry Andric int __fd; 2474cb14a3feSDimitry Andric __money_get<_CharT>::__gather_info(__intl, __loc, __pat, __dp, __ts, __grp, __sym, __psn, __nsn, __fd); 24750b57cec5SDimitry Andric const string_type* __trailing_sign = 0; 24760b57cec5SDimitry Andric __wn = __wb.get(); 2477cb14a3feSDimitry Andric for (unsigned __p = 0; __p < 4 && __b != __e; ++__p) { 2478cb14a3feSDimitry Andric switch (__pat.field[__p]) { 24790b57cec5SDimitry Andric case money_base::space: 2480cb14a3feSDimitry Andric if (__p != 3) { 24810b57cec5SDimitry Andric if (__ct.is(ctype_base::space, *__b)) 24820b57cec5SDimitry Andric __spaces.push_back(*__b++); 2483cb14a3feSDimitry Andric else { 24840b57cec5SDimitry Andric __err |= ios_base::failbit; 24850b57cec5SDimitry Andric return false; 24860b57cec5SDimitry Andric } 24870b57cec5SDimitry Andric } 24880b57cec5SDimitry Andric _LIBCPP_FALLTHROUGH(); 24890b57cec5SDimitry Andric case money_base::none: 2490cb14a3feSDimitry Andric if (__p != 3) { 24910b57cec5SDimitry Andric while (__b != __e && __ct.is(ctype_base::space, *__b)) 24920b57cec5SDimitry Andric __spaces.push_back(*__b++); 24930b57cec5SDimitry Andric } 24940b57cec5SDimitry Andric break; 24950b57cec5SDimitry Andric case money_base::sign: 2496cb14a3feSDimitry Andric if (__psn.size() > 0 && *__b == __psn[0]) { 24970b57cec5SDimitry Andric ++__b; 2498349cc55cSDimitry Andric __neg = false; 24990b57cec5SDimitry Andric if (__psn.size() > 1) 25000b57cec5SDimitry Andric __trailing_sign = &__psn; 2501349cc55cSDimitry Andric break; 25020b57cec5SDimitry Andric } 2503cb14a3feSDimitry Andric if (__nsn.size() > 0 && *__b == __nsn[0]) { 25040b57cec5SDimitry Andric ++__b; 25050b57cec5SDimitry Andric __neg = true; 25060b57cec5SDimitry Andric if (__nsn.size() > 1) 25070b57cec5SDimitry Andric __trailing_sign = &__nsn; 2508349cc55cSDimitry Andric break; 25090b57cec5SDimitry Andric } 2510cb14a3feSDimitry Andric if (__psn.size() > 0 && __nsn.size() > 0) { // sign is required 25110b57cec5SDimitry Andric __err |= ios_base::failbit; 25120b57cec5SDimitry Andric return false; 25130b57cec5SDimitry Andric } 2514349cc55cSDimitry Andric if (__psn.size() == 0 && __nsn.size() == 0) 2515349cc55cSDimitry Andric // locale has no way of specifying a sign. Use the initial value of __neg as a default 2516349cc55cSDimitry Andric break; 2517349cc55cSDimitry Andric __neg = (__nsn.size() == 0); 25180b57cec5SDimitry Andric break; 2519cb14a3feSDimitry Andric case money_base::symbol: { 2520cb14a3feSDimitry Andric bool __more_needed = 2521cb14a3feSDimitry Andric __trailing_sign || (__p < 2) || (__p == 2 && __pat.field[3] != static_cast<char>(money_base::none)); 25220b57cec5SDimitry Andric bool __sb = (__flags & ios_base::showbase) != 0; 2523cb14a3feSDimitry Andric if (__sb || __more_needed) { 25240b57cec5SDimitry Andric typename string_type::const_iterator __sym_space_end = __sym.begin(); 2525cb14a3feSDimitry Andric if (__p > 0 && (__pat.field[__p - 1] == money_base::none || __pat.field[__p - 1] == money_base::space)) { 25260b57cec5SDimitry Andric // Match spaces we've already read against spaces at 25270b57cec5SDimitry Andric // the beginning of __sym. 2528cb14a3feSDimitry Andric while (__sym_space_end != __sym.end() && __ct.is(ctype_base::space, *__sym_space_end)) 25290b57cec5SDimitry Andric ++__sym_space_end; 25300b57cec5SDimitry Andric const size_t __num_spaces = __sym_space_end - __sym.begin(); 25310b57cec5SDimitry Andric if (__num_spaces > __spaces.size() || 2532cb14a3feSDimitry Andric !std::equal(__spaces.end() - __num_spaces, __spaces.end(), __sym.begin())) { 25330b57cec5SDimitry Andric // No match. Put __sym_space_end back at the 25340b57cec5SDimitry Andric // beginning of __sym, which will prevent a 25350b57cec5SDimitry Andric // match in the next loop. 25360b57cec5SDimitry Andric __sym_space_end = __sym.begin(); 25370b57cec5SDimitry Andric } 25380b57cec5SDimitry Andric } 25390b57cec5SDimitry Andric typename string_type::const_iterator __sym_curr_char = __sym_space_end; 2540cb14a3feSDimitry Andric while (__sym_curr_char != __sym.end() && __b != __e && *__b == *__sym_curr_char) { 25410b57cec5SDimitry Andric ++__b; 25420b57cec5SDimitry Andric ++__sym_curr_char; 25430b57cec5SDimitry Andric } 2544cb14a3feSDimitry Andric if (__sb && __sym_curr_char != __sym.end()) { 25450b57cec5SDimitry Andric __err |= ios_base::failbit; 25460b57cec5SDimitry Andric return false; 25470b57cec5SDimitry Andric } 25480b57cec5SDimitry Andric } 2549cb14a3feSDimitry Andric } break; 2550cb14a3feSDimitry Andric case money_base::value: { 25510b57cec5SDimitry Andric unsigned __ng = 0; 2552cb14a3feSDimitry Andric for (; __b != __e; ++__b) { 25530b57cec5SDimitry Andric char_type __c = *__b; 2554cb14a3feSDimitry Andric if (__ct.is(ctype_base::digit, __c)) { 25550b57cec5SDimitry Andric if (__wn == __we) 2556bdd1243dSDimitry Andric std::__double_or_nothing(__wb, __wn, __we); 25570b57cec5SDimitry Andric *__wn++ = __c; 25580b57cec5SDimitry Andric ++__ng; 2559cb14a3feSDimitry Andric } else if (__grp.size() > 0 && __ng > 0 && __c == __ts) { 25600b57cec5SDimitry Andric if (__gn == __ge) 2561bdd1243dSDimitry Andric std::__double_or_nothing(__gb, __gn, __ge); 25620b57cec5SDimitry Andric *__gn++ = __ng; 25630b57cec5SDimitry Andric __ng = 0; 2564cb14a3feSDimitry Andric } else 25650b57cec5SDimitry Andric break; 25660b57cec5SDimitry Andric } 2567cb14a3feSDimitry Andric if (__gb.get() != __gn && __ng > 0) { 25680b57cec5SDimitry Andric if (__gn == __ge) 2569bdd1243dSDimitry Andric std::__double_or_nothing(__gb, __gn, __ge); 25700b57cec5SDimitry Andric *__gn++ = __ng; 25710b57cec5SDimitry Andric } 2572cb14a3feSDimitry Andric if (__fd > 0) { 2573cb14a3feSDimitry Andric if (__b == __e || *__b != __dp) { 25740b57cec5SDimitry Andric __err |= ios_base::failbit; 25750b57cec5SDimitry Andric return false; 25760b57cec5SDimitry Andric } 2577cb14a3feSDimitry Andric for (++__b; __fd > 0; --__fd, ++__b) { 2578cb14a3feSDimitry Andric if (__b == __e || !__ct.is(ctype_base::digit, *__b)) { 25790b57cec5SDimitry Andric __err |= ios_base::failbit; 25800b57cec5SDimitry Andric return false; 25810b57cec5SDimitry Andric } 25820b57cec5SDimitry Andric if (__wn == __we) 2583bdd1243dSDimitry Andric std::__double_or_nothing(__wb, __wn, __we); 25840b57cec5SDimitry Andric *__wn++ = *__b; 25850b57cec5SDimitry Andric } 25860b57cec5SDimitry Andric } 2587cb14a3feSDimitry Andric if (__wn == __wb.get()) { 25880b57cec5SDimitry Andric __err |= ios_base::failbit; 25890b57cec5SDimitry Andric return false; 25900b57cec5SDimitry Andric } 2591cb14a3feSDimitry Andric } break; 25920b57cec5SDimitry Andric } 25930b57cec5SDimitry Andric } 2594cb14a3feSDimitry Andric if (__trailing_sign) { 2595cb14a3feSDimitry Andric for (unsigned __i = 1; __i < __trailing_sign->size(); ++__i, ++__b) { 2596cb14a3feSDimitry Andric if (__b == __e || *__b != (*__trailing_sign)[__i]) { 25970b57cec5SDimitry Andric __err |= ios_base::failbit; 25980b57cec5SDimitry Andric return false; 25990b57cec5SDimitry Andric } 26000b57cec5SDimitry Andric } 26010b57cec5SDimitry Andric } 2602cb14a3feSDimitry Andric if (__gb.get() != __gn) { 26030b57cec5SDimitry Andric ios_base::iostate __et = ios_base::goodbit; 26040b57cec5SDimitry Andric __check_grouping(__grp, __gb.get(), __gn, __et); 2605cb14a3feSDimitry Andric if (__et) { 26060b57cec5SDimitry Andric __err |= ios_base::failbit; 26070b57cec5SDimitry Andric return false; 26080b57cec5SDimitry Andric } 26090b57cec5SDimitry Andric } 26100b57cec5SDimitry Andric return true; 26110b57cec5SDimitry Andric} 26120b57cec5SDimitry Andric 26130b57cec5SDimitry Andrictemplate <class _CharT, class _InputIterator> 2614cb14a3feSDimitry Andric_InputIterator money_get<_CharT, _InputIterator>::do_get( 2615cb14a3feSDimitry Andric iter_type __b, iter_type __e, bool __intl, ios_base& __iob, ios_base::iostate& __err, long double& __v) const { 26160b57cec5SDimitry Andric const int __bz = 100; 26170b57cec5SDimitry Andric char_type __wbuf[__bz]; 26180b57cec5SDimitry Andric unique_ptr<char_type, void (*)(void*)> __wb(__wbuf, __do_nothing); 26190b57cec5SDimitry Andric char_type* __wn; 26200b57cec5SDimitry Andric char_type* __we = __wbuf + __bz; 26210b57cec5SDimitry Andric locale __loc = __iob.getloc(); 2622bdd1243dSDimitry Andric const ctype<char_type>& __ct = std::use_facet<ctype<char_type> >(__loc); 26230b57cec5SDimitry Andric bool __neg = false; 2624cb14a3feSDimitry Andric if (__do_get(__b, __e, __intl, __loc, __iob.flags(), __err, __neg, __ct, __wb, __wn, __we)) { 26250b57cec5SDimitry Andric const char __src[] = "0123456789"; 26260b57cec5SDimitry Andric char_type __atoms[sizeof(__src) - 1]; 26270b57cec5SDimitry Andric __ct.widen(__src, __src + (sizeof(__src) - 1), __atoms); 26280b57cec5SDimitry Andric char __nbuf[__bz]; 26290b57cec5SDimitry Andric char* __nc = __nbuf; 2630e8d8bef9SDimitry Andric unique_ptr<char, void (*)(void*)> __h(nullptr, free); 2631cb14a3feSDimitry Andric if (__wn - __wb.get() > __bz - 2) { 26320b57cec5SDimitry Andric __h.reset((char*)malloc(static_cast<size_t>(__wn - __wb.get() + 2))); 2633e8d8bef9SDimitry Andric if (__h.get() == nullptr) 26340b57cec5SDimitry Andric __throw_bad_alloc(); 26350b57cec5SDimitry Andric __nc = __h.get(); 26360b57cec5SDimitry Andric } 26370b57cec5SDimitry Andric if (__neg) 26380b57cec5SDimitry Andric *__nc++ = '-'; 26390b57cec5SDimitry Andric for (const char_type* __w = __wb.get(); __w < __wn; ++__w, ++__nc) 26405f757f3fSDimitry Andric *__nc = __src[std::find(__atoms, std::end(__atoms), *__w) - __atoms]; 26410b57cec5SDimitry Andric *__nc = char(); 26420b57cec5SDimitry Andric if (sscanf(__nbuf, "%Lf", &__v) != 1) 26430b57cec5SDimitry Andric __throw_runtime_error("money_get error"); 26440b57cec5SDimitry Andric } 26450b57cec5SDimitry Andric if (__b == __e) 26460b57cec5SDimitry Andric __err |= ios_base::eofbit; 26470b57cec5SDimitry Andric return __b; 26480b57cec5SDimitry Andric} 26490b57cec5SDimitry Andric 26500b57cec5SDimitry Andrictemplate <class _CharT, class _InputIterator> 2651cb14a3feSDimitry Andric_InputIterator money_get<_CharT, _InputIterator>::do_get( 2652cb14a3feSDimitry Andric iter_type __b, iter_type __e, bool __intl, ios_base& __iob, ios_base::iostate& __err, string_type& __v) const { 26530b57cec5SDimitry Andric const int __bz = 100; 26540b57cec5SDimitry Andric char_type __wbuf[__bz]; 26550b57cec5SDimitry Andric unique_ptr<char_type, void (*)(void*)> __wb(__wbuf, __do_nothing); 26560b57cec5SDimitry Andric char_type* __wn; 26570b57cec5SDimitry Andric char_type* __we = __wbuf + __bz; 26580b57cec5SDimitry Andric locale __loc = __iob.getloc(); 2659bdd1243dSDimitry Andric const ctype<char_type>& __ct = std::use_facet<ctype<char_type> >(__loc); 26600b57cec5SDimitry Andric bool __neg = false; 2661cb14a3feSDimitry Andric if (__do_get(__b, __e, __intl, __loc, __iob.flags(), __err, __neg, __ct, __wb, __wn, __we)) { 26620b57cec5SDimitry Andric __v.clear(); 26630b57cec5SDimitry Andric if (__neg) 26640b57cec5SDimitry Andric __v.push_back(__ct.widen('-')); 26650b57cec5SDimitry Andric char_type __z = __ct.widen('0'); 26660b57cec5SDimitry Andric char_type* __w; 26670b57cec5SDimitry Andric for (__w = __wb.get(); __w < __wn - 1; ++__w) 26680b57cec5SDimitry Andric if (*__w != __z) 26690b57cec5SDimitry Andric break; 26700b57cec5SDimitry Andric __v.append(__w, __wn); 26710b57cec5SDimitry Andric } 26720b57cec5SDimitry Andric if (__b == __e) 26730b57cec5SDimitry Andric __err |= ios_base::eofbit; 26740b57cec5SDimitry Andric return __b; 26750b57cec5SDimitry Andric} 26760b57cec5SDimitry Andric 267781ad6265SDimitry Andricextern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS money_get<char>; 2678349cc55cSDimitry Andric#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 267981ad6265SDimitry Andricextern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS money_get<wchar_t>; 2680349cc55cSDimitry Andric#endif 26810b57cec5SDimitry Andric 26820b57cec5SDimitry Andric// money_put 26830b57cec5SDimitry Andric 26840b57cec5SDimitry Andrictemplate <class _CharT> 2685cb14a3feSDimitry Andricclass __money_put { 26860b57cec5SDimitry Andricprotected: 26870b57cec5SDimitry Andric typedef _CharT char_type; 26880b57cec5SDimitry Andric typedef basic_string<char_type> string_type; 26890b57cec5SDimitry Andric 26905f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI __money_put() {} 26910b57cec5SDimitry Andric 2692cb14a3feSDimitry Andric static void __gather_info( 2693cb14a3feSDimitry Andric bool __intl, 2694cb14a3feSDimitry Andric bool __neg, 2695cb14a3feSDimitry Andric const locale& __loc, 2696cb14a3feSDimitry Andric money_base::pattern& __pat, 2697cb14a3feSDimitry Andric char_type& __dp, 2698cb14a3feSDimitry Andric char_type& __ts, 2699cb14a3feSDimitry Andric string& __grp, 2700cb14a3feSDimitry Andric string_type& __sym, 2701cb14a3feSDimitry Andric string_type& __sn, 27020b57cec5SDimitry Andric int& __fd); 2703cb14a3feSDimitry Andric static void __format( 2704cb14a3feSDimitry Andric char_type* __mb, 2705cb14a3feSDimitry Andric char_type*& __mi, 2706cb14a3feSDimitry Andric char_type*& __me, 27070b57cec5SDimitry Andric ios_base::fmtflags __flags, 2708cb14a3feSDimitry Andric const char_type* __db, 2709cb14a3feSDimitry Andric const char_type* __de, 2710cb14a3feSDimitry Andric const ctype<char_type>& __ct, 2711cb14a3feSDimitry Andric bool __neg, 2712cb14a3feSDimitry Andric const money_base::pattern& __pat, 2713cb14a3feSDimitry Andric char_type __dp, 2714cb14a3feSDimitry Andric char_type __ts, 2715cb14a3feSDimitry Andric const string& __grp, 2716cb14a3feSDimitry Andric const string_type& __sym, 2717cb14a3feSDimitry Andric const string_type& __sn, 27180b57cec5SDimitry Andric int __fd); 27190b57cec5SDimitry Andric}; 27200b57cec5SDimitry Andric 27210b57cec5SDimitry Andrictemplate <class _CharT> 2722cb14a3feSDimitry Andricvoid __money_put<_CharT>::__gather_info( 2723cb14a3feSDimitry Andric bool __intl, 2724cb14a3feSDimitry Andric bool __neg, 2725cb14a3feSDimitry Andric const locale& __loc, 2726cb14a3feSDimitry Andric money_base::pattern& __pat, 2727cb14a3feSDimitry Andric char_type& __dp, 2728cb14a3feSDimitry Andric char_type& __ts, 2729cb14a3feSDimitry Andric string& __grp, 2730cb14a3feSDimitry Andric string_type& __sym, 2731cb14a3feSDimitry Andric string_type& __sn, 2732cb14a3feSDimitry Andric int& __fd) { 2733cb14a3feSDimitry Andric if (__intl) { 2734cb14a3feSDimitry Andric const moneypunct<char_type, true>& __mp = std::use_facet<moneypunct<char_type, true> >(__loc); 2735cb14a3feSDimitry Andric if (__neg) { 27360b57cec5SDimitry Andric __pat = __mp.neg_format(); 27370b57cec5SDimitry Andric __sn = __mp.negative_sign(); 2738cb14a3feSDimitry Andric } else { 27390b57cec5SDimitry Andric __pat = __mp.pos_format(); 27400b57cec5SDimitry Andric __sn = __mp.positive_sign(); 27410b57cec5SDimitry Andric } 27420b57cec5SDimitry Andric __dp = __mp.decimal_point(); 27430b57cec5SDimitry Andric __ts = __mp.thousands_sep(); 27440b57cec5SDimitry Andric __grp = __mp.grouping(); 27450b57cec5SDimitry Andric __sym = __mp.curr_symbol(); 27460b57cec5SDimitry Andric __fd = __mp.frac_digits(); 2747cb14a3feSDimitry Andric } else { 2748cb14a3feSDimitry Andric const moneypunct<char_type, false>& __mp = std::use_facet<moneypunct<char_type, false> >(__loc); 2749cb14a3feSDimitry Andric if (__neg) { 27500b57cec5SDimitry Andric __pat = __mp.neg_format(); 27510b57cec5SDimitry Andric __sn = __mp.negative_sign(); 2752cb14a3feSDimitry Andric } else { 27530b57cec5SDimitry Andric __pat = __mp.pos_format(); 27540b57cec5SDimitry Andric __sn = __mp.positive_sign(); 27550b57cec5SDimitry Andric } 27560b57cec5SDimitry Andric __dp = __mp.decimal_point(); 27570b57cec5SDimitry Andric __ts = __mp.thousands_sep(); 27580b57cec5SDimitry Andric __grp = __mp.grouping(); 27590b57cec5SDimitry Andric __sym = __mp.curr_symbol(); 27600b57cec5SDimitry Andric __fd = __mp.frac_digits(); 27610b57cec5SDimitry Andric } 27620b57cec5SDimitry Andric} 27630b57cec5SDimitry Andric 27640b57cec5SDimitry Andrictemplate <class _CharT> 2765cb14a3feSDimitry Andricvoid __money_put<_CharT>::__format( 2766cb14a3feSDimitry Andric char_type* __mb, 2767cb14a3feSDimitry Andric char_type*& __mi, 2768cb14a3feSDimitry Andric char_type*& __me, 27690b57cec5SDimitry Andric ios_base::fmtflags __flags, 2770cb14a3feSDimitry Andric const char_type* __db, 2771cb14a3feSDimitry Andric const char_type* __de, 2772cb14a3feSDimitry Andric const ctype<char_type>& __ct, 2773cb14a3feSDimitry Andric bool __neg, 2774cb14a3feSDimitry Andric const money_base::pattern& __pat, 2775cb14a3feSDimitry Andric char_type __dp, 2776cb14a3feSDimitry Andric char_type __ts, 2777cb14a3feSDimitry Andric const string& __grp, 2778cb14a3feSDimitry Andric const string_type& __sym, 2779cb14a3feSDimitry Andric const string_type& __sn, 2780cb14a3feSDimitry Andric int __fd) { 27810b57cec5SDimitry Andric __me = __mb; 2782cb14a3feSDimitry Andric for (char __p : __pat.field) { 2783cb14a3feSDimitry Andric switch (__p) { 27840b57cec5SDimitry Andric case money_base::none: 27850b57cec5SDimitry Andric __mi = __me; 27860b57cec5SDimitry Andric break; 27870b57cec5SDimitry Andric case money_base::space: 27880b57cec5SDimitry Andric __mi = __me; 27890b57cec5SDimitry Andric *__me++ = __ct.widen(' '); 27900b57cec5SDimitry Andric break; 27910b57cec5SDimitry Andric case money_base::sign: 27920b57cec5SDimitry Andric if (!__sn.empty()) 27930b57cec5SDimitry Andric *__me++ = __sn[0]; 27940b57cec5SDimitry Andric break; 27950b57cec5SDimitry Andric case money_base::symbol: 27960b57cec5SDimitry Andric if (!__sym.empty() && (__flags & ios_base::showbase)) 27975f757f3fSDimitry Andric __me = std::copy(__sym.begin(), __sym.end(), __me); 27980b57cec5SDimitry Andric break; 2799cb14a3feSDimitry Andric case money_base::value: { 28000b57cec5SDimitry Andric // remember start of value so we can reverse it 28010b57cec5SDimitry Andric char_type* __t = __me; 28020b57cec5SDimitry Andric // find beginning of digits 28030b57cec5SDimitry Andric if (__neg) 28040b57cec5SDimitry Andric ++__db; 28050b57cec5SDimitry Andric // find end of digits 28060b57cec5SDimitry Andric const char_type* __d; 28070b57cec5SDimitry Andric for (__d = __db; __d < __de; ++__d) 28080b57cec5SDimitry Andric if (!__ct.is(ctype_base::digit, *__d)) 28090b57cec5SDimitry Andric break; 28100b57cec5SDimitry Andric // print fractional part 2811cb14a3feSDimitry Andric if (__fd > 0) { 28120b57cec5SDimitry Andric int __f; 28130b57cec5SDimitry Andric for (__f = __fd; __d > __db && __f > 0; --__f) 28140b57cec5SDimitry Andric *__me++ = *--__d; 28150b57cec5SDimitry Andric char_type __z = __f > 0 ? __ct.widen('0') : char_type(); 28160b57cec5SDimitry Andric for (; __f > 0; --__f) 28170b57cec5SDimitry Andric *__me++ = __z; 28180b57cec5SDimitry Andric *__me++ = __dp; 28190b57cec5SDimitry Andric } 28200b57cec5SDimitry Andric // print units part 2821cb14a3feSDimitry Andric if (__d == __db) { 28220b57cec5SDimitry Andric *__me++ = __ct.widen('0'); 2823cb14a3feSDimitry Andric } else { 28240b57cec5SDimitry Andric unsigned __ng = 0; 28250b57cec5SDimitry Andric unsigned __ig = 0; 2826cb14a3feSDimitry Andric unsigned __gl = __grp.empty() ? numeric_limits<unsigned>::max() : static_cast<unsigned>(__grp[__ig]); 2827cb14a3feSDimitry Andric while (__d != __db) { 2828cb14a3feSDimitry Andric if (__ng == __gl) { 28290b57cec5SDimitry Andric *__me++ = __ts; 28300b57cec5SDimitry Andric __ng = 0; 28310b57cec5SDimitry Andric if (++__ig < __grp.size()) 2832cb14a3feSDimitry Andric __gl = __grp[__ig] == numeric_limits<char>::max() 2833cb14a3feSDimitry Andric ? numeric_limits<unsigned>::max() 2834cb14a3feSDimitry Andric : static_cast<unsigned>(__grp[__ig]); 28350b57cec5SDimitry Andric } 28360b57cec5SDimitry Andric *__me++ = *--__d; 28370b57cec5SDimitry Andric ++__ng; 28380b57cec5SDimitry Andric } 28390b57cec5SDimitry Andric } 28400b57cec5SDimitry Andric // reverse it 2841bdd1243dSDimitry Andric std::reverse(__t, __me); 2842cb14a3feSDimitry Andric } break; 28430b57cec5SDimitry Andric } 28440b57cec5SDimitry Andric } 28450b57cec5SDimitry Andric // print rest of sign, if any 28460b57cec5SDimitry Andric if (__sn.size() > 1) 28475f757f3fSDimitry Andric __me = std::copy(__sn.begin() + 1, __sn.end(), __me); 28480b57cec5SDimitry Andric // set alignment 28490b57cec5SDimitry Andric if ((__flags & ios_base::adjustfield) == ios_base::left) 28500b57cec5SDimitry Andric __mi = __me; 28510b57cec5SDimitry Andric else if ((__flags & ios_base::adjustfield) != ios_base::internal) 28520b57cec5SDimitry Andric __mi = __mb; 28530b57cec5SDimitry Andric} 28540b57cec5SDimitry Andric 285581ad6265SDimitry Andricextern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __money_put<char>; 2856349cc55cSDimitry Andric#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 285781ad6265SDimitry Andricextern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __money_put<wchar_t>; 2858349cc55cSDimitry Andric#endif 28590b57cec5SDimitry Andric 28600b57cec5SDimitry Andrictemplate <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> > 2861cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS money_put : public locale::facet, private __money_put<_CharT> { 28620b57cec5SDimitry Andricpublic: 28630b57cec5SDimitry Andric typedef _CharT char_type; 28640b57cec5SDimitry Andric typedef _OutputIterator iter_type; 28650b57cec5SDimitry Andric typedef basic_string<char_type> string_type; 28660b57cec5SDimitry Andric 2867cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit money_put(size_t __refs = 0) : locale::facet(__refs) {} 28680b57cec5SDimitry Andric 2869cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iter_type 2870cb14a3feSDimitry Andric put(iter_type __s, bool __intl, ios_base& __iob, char_type __fl, long double __units) const { 28710b57cec5SDimitry Andric return do_put(__s, __intl, __iob, __fl, __units); 28720b57cec5SDimitry Andric } 28730b57cec5SDimitry Andric 2874cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iter_type 2875cb14a3feSDimitry Andric put(iter_type __s, bool __intl, ios_base& __iob, char_type __fl, const string_type& __digits) const { 28760b57cec5SDimitry Andric return do_put(__s, __intl, __iob, __fl, __digits); 28770b57cec5SDimitry Andric } 28780b57cec5SDimitry Andric 28790b57cec5SDimitry Andric static locale::id id; 28800b57cec5SDimitry Andric 28810b57cec5SDimitry Andricprotected: 2882bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI_VIRTUAL ~money_put() override {} 28830b57cec5SDimitry Andric 2884cb14a3feSDimitry Andric virtual iter_type do_put(iter_type __s, bool __intl, ios_base& __iob, char_type __fl, long double __units) const; 2885cb14a3feSDimitry Andric virtual iter_type 2886cb14a3feSDimitry Andric do_put(iter_type __s, bool __intl, ios_base& __iob, char_type __fl, const string_type& __digits) const; 28870b57cec5SDimitry Andric}; 28880b57cec5SDimitry Andric 28890b57cec5SDimitry Andrictemplate <class _CharT, class _OutputIterator> 2890cb14a3feSDimitry Andriclocale::id money_put<_CharT, _OutputIterator>::id; 28910b57cec5SDimitry Andric 28920b57cec5SDimitry Andrictemplate <class _CharT, class _OutputIterator> 2893cb14a3feSDimitry Andric_OutputIterator money_put<_CharT, _OutputIterator>::do_put( 2894cb14a3feSDimitry Andric iter_type __s, bool __intl, ios_base& __iob, char_type __fl, long double __units) const { 28950b57cec5SDimitry Andric // convert to char 28960b57cec5SDimitry Andric const size_t __bs = 100; 28970b57cec5SDimitry Andric char __buf[__bs]; 28980b57cec5SDimitry Andric char* __bb = __buf; 28990b57cec5SDimitry Andric char_type __digits[__bs]; 29000b57cec5SDimitry Andric char_type* __db = __digits; 2901e8d8bef9SDimitry Andric int __n = snprintf(__bb, __bs, "%.0Lf", __units); 2902e8d8bef9SDimitry Andric unique_ptr<char, void (*)(void*)> __hn(nullptr, free); 29030b57cec5SDimitry Andric unique_ptr<char_type, void (*)(void*)> __hd(0, free); 29040b57cec5SDimitry Andric // secure memory for digit storage 2905cb14a3feSDimitry Andric if (static_cast<size_t>(__n) > __bs - 1) { 2906e8d8bef9SDimitry Andric __n = __libcpp_asprintf_l(&__bb, _LIBCPP_GET_C_LOCALE, "%.0Lf", __units); 2907e8d8bef9SDimitry Andric if (__n == -1) 29080b57cec5SDimitry Andric __throw_bad_alloc(); 29090b57cec5SDimitry Andric __hn.reset(__bb); 2910e8d8bef9SDimitry Andric __hd.reset((char_type*)malloc(static_cast<size_t>(__n) * sizeof(char_type))); 29110b57cec5SDimitry Andric if (__hd == nullptr) 29120b57cec5SDimitry Andric __throw_bad_alloc(); 29130b57cec5SDimitry Andric __db = __hd.get(); 29140b57cec5SDimitry Andric } 29150b57cec5SDimitry Andric // gather info 29160b57cec5SDimitry Andric locale __loc = __iob.getloc(); 2917bdd1243dSDimitry Andric const ctype<char_type>& __ct = std::use_facet<ctype<char_type> >(__loc); 29180b57cec5SDimitry Andric __ct.widen(__bb, __bb + __n, __db); 29190b57cec5SDimitry Andric bool __neg = __n > 0 && __bb[0] == '-'; 29200b57cec5SDimitry Andric money_base::pattern __pat; 29210b57cec5SDimitry Andric char_type __dp; 29220b57cec5SDimitry Andric char_type __ts; 29230b57cec5SDimitry Andric string __grp; 29240b57cec5SDimitry Andric string_type __sym; 29250b57cec5SDimitry Andric string_type __sn; 29260b57cec5SDimitry Andric int __fd; 29270b57cec5SDimitry Andric this->__gather_info(__intl, __neg, __loc, __pat, __dp, __ts, __grp, __sym, __sn, __fd); 29280b57cec5SDimitry Andric // secure memory for formatting 29290b57cec5SDimitry Andric char_type __mbuf[__bs]; 29300b57cec5SDimitry Andric char_type* __mb = __mbuf; 29310b57cec5SDimitry Andric unique_ptr<char_type, void (*)(void*)> __hw(0, free); 2932cb14a3feSDimitry Andric size_t __exn = __n > __fd ? (static_cast<size_t>(__n) - static_cast<size_t>(__fd)) * 2 + __sn.size() + __sym.size() + 2933cb14a3feSDimitry Andric static_cast<size_t>(__fd) + 1 29340b57cec5SDimitry Andric : __sn.size() + __sym.size() + static_cast<size_t>(__fd) + 2; 2935cb14a3feSDimitry Andric if (__exn > __bs) { 29360b57cec5SDimitry Andric __hw.reset((char_type*)malloc(__exn * sizeof(char_type))); 29370b57cec5SDimitry Andric __mb = __hw.get(); 29380b57cec5SDimitry Andric if (__mb == 0) 29390b57cec5SDimitry Andric __throw_bad_alloc(); 29400b57cec5SDimitry Andric } 29410b57cec5SDimitry Andric // format 29420b57cec5SDimitry Andric char_type* __mi; 29430b57cec5SDimitry Andric char_type* __me; 2944cb14a3feSDimitry Andric this->__format( 2945cb14a3feSDimitry Andric __mb, __mi, __me, __iob.flags(), __db, __db + __n, __ct, __neg, __pat, __dp, __ts, __grp, __sym, __sn, __fd); 2946bdd1243dSDimitry Andric return std::__pad_and_output(__s, __mb, __mi, __me, __iob, __fl); 29470b57cec5SDimitry Andric} 29480b57cec5SDimitry Andric 29490b57cec5SDimitry Andrictemplate <class _CharT, class _OutputIterator> 2950cb14a3feSDimitry Andric_OutputIterator money_put<_CharT, _OutputIterator>::do_put( 2951cb14a3feSDimitry Andric iter_type __s, bool __intl, ios_base& __iob, char_type __fl, const string_type& __digits) const { 29520b57cec5SDimitry Andric // gather info 29530b57cec5SDimitry Andric locale __loc = __iob.getloc(); 2954bdd1243dSDimitry Andric const ctype<char_type>& __ct = std::use_facet<ctype<char_type> >(__loc); 29550b57cec5SDimitry Andric bool __neg = __digits.size() > 0 && __digits[0] == __ct.widen('-'); 29560b57cec5SDimitry Andric money_base::pattern __pat; 29570b57cec5SDimitry Andric char_type __dp; 29580b57cec5SDimitry Andric char_type __ts; 29590b57cec5SDimitry Andric string __grp; 29600b57cec5SDimitry Andric string_type __sym; 29610b57cec5SDimitry Andric string_type __sn; 29620b57cec5SDimitry Andric int __fd; 29630b57cec5SDimitry Andric this->__gather_info(__intl, __neg, __loc, __pat, __dp, __ts, __grp, __sym, __sn, __fd); 29640b57cec5SDimitry Andric // secure memory for formatting 29650b57cec5SDimitry Andric char_type __mbuf[100]; 29660b57cec5SDimitry Andric char_type* __mb = __mbuf; 29670b57cec5SDimitry Andric unique_ptr<char_type, void (*)(void*)> __h(0, free); 2968cb14a3feSDimitry Andric size_t __exn = 2969cb14a3feSDimitry Andric static_cast<int>(__digits.size()) > __fd 2970cb14a3feSDimitry Andric ? (__digits.size() - static_cast<size_t>(__fd)) * 2 + __sn.size() + __sym.size() + static_cast<size_t>(__fd) + 2971cb14a3feSDimitry Andric 1 29720b57cec5SDimitry Andric : __sn.size() + __sym.size() + static_cast<size_t>(__fd) + 2; 2973cb14a3feSDimitry Andric if (__exn > 100) { 29740b57cec5SDimitry Andric __h.reset((char_type*)malloc(__exn * sizeof(char_type))); 29750b57cec5SDimitry Andric __mb = __h.get(); 29760b57cec5SDimitry Andric if (__mb == 0) 29770b57cec5SDimitry Andric __throw_bad_alloc(); 29780b57cec5SDimitry Andric } 29790b57cec5SDimitry Andric // format 29800b57cec5SDimitry Andric char_type* __mi; 29810b57cec5SDimitry Andric char_type* __me; 2982cb14a3feSDimitry Andric this->__format( 2983cb14a3feSDimitry Andric __mb, 2984cb14a3feSDimitry Andric __mi, 2985cb14a3feSDimitry Andric __me, 2986cb14a3feSDimitry Andric __iob.flags(), 2987cb14a3feSDimitry Andric __digits.data(), 2988cb14a3feSDimitry Andric __digits.data() + __digits.size(), 2989cb14a3feSDimitry Andric __ct, 2990cb14a3feSDimitry Andric __neg, 2991cb14a3feSDimitry Andric __pat, 2992cb14a3feSDimitry Andric __dp, 2993cb14a3feSDimitry Andric __ts, 2994cb14a3feSDimitry Andric __grp, 2995cb14a3feSDimitry Andric __sym, 2996cb14a3feSDimitry Andric __sn, 2997cb14a3feSDimitry Andric __fd); 2998bdd1243dSDimitry Andric return std::__pad_and_output(__s, __mb, __mi, __me, __iob, __fl); 29990b57cec5SDimitry Andric} 30000b57cec5SDimitry Andric 300181ad6265SDimitry Andricextern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS money_put<char>; 3002349cc55cSDimitry Andric#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 300381ad6265SDimitry Andricextern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS money_put<wchar_t>; 3004349cc55cSDimitry Andric#endif 30050b57cec5SDimitry Andric 30060b57cec5SDimitry Andric// messages 30070b57cec5SDimitry Andric 3008cb14a3feSDimitry Andricclass _LIBCPP_EXPORTED_FROM_ABI messages_base { 30090b57cec5SDimitry Andricpublic: 30105f757f3fSDimitry Andric typedef intptr_t catalog; 30110b57cec5SDimitry Andric 30125f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI messages_base() {} 30130b57cec5SDimitry Andric}; 30140b57cec5SDimitry Andric 30150b57cec5SDimitry Andrictemplate <class _CharT> 3016cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS messages : public locale::facet, public messages_base { 30170b57cec5SDimitry Andricpublic: 30180b57cec5SDimitry Andric typedef _CharT char_type; 30190b57cec5SDimitry Andric typedef basic_string<_CharT> string_type; 30200b57cec5SDimitry Andric 3021cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit messages(size_t __refs = 0) : locale::facet(__refs) {} 30220b57cec5SDimitry Andric 3023cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI catalog open(const basic_string<char>& __nm, const locale& __loc) const { 30240b57cec5SDimitry Andric return do_open(__nm, __loc); 30250b57cec5SDimitry Andric } 30260b57cec5SDimitry Andric 3027cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI string_type get(catalog __c, int __set, int __msgid, const string_type& __dflt) const { 30280b57cec5SDimitry Andric return do_get(__c, __set, __msgid, __dflt); 30290b57cec5SDimitry Andric } 30300b57cec5SDimitry Andric 3031cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void close(catalog __c) const { do_close(__c); } 30320b57cec5SDimitry Andric 30330b57cec5SDimitry Andric static locale::id id; 30340b57cec5SDimitry Andric 30350b57cec5SDimitry Andricprotected: 3036bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI_VIRTUAL ~messages() override {} 30370b57cec5SDimitry Andric 30380b57cec5SDimitry Andric virtual catalog do_open(const basic_string<char>&, const locale&) const; 3039cb14a3feSDimitry Andric virtual string_type do_get(catalog, int __set, int __msgid, const string_type& __dflt) const; 30400b57cec5SDimitry Andric virtual void do_close(catalog) const; 30410b57cec5SDimitry Andric}; 30420b57cec5SDimitry Andric 30430b57cec5SDimitry Andrictemplate <class _CharT> 3044cb14a3feSDimitry Andriclocale::id messages<_CharT>::id; 30450b57cec5SDimitry Andric 30460b57cec5SDimitry Andrictemplate <class _CharT> 3047cb14a3feSDimitry Andrictypename messages<_CharT>::catalog messages<_CharT>::do_open(const basic_string<char>& __nm, const locale&) const { 30480b57cec5SDimitry Andric#ifdef _LIBCPP_HAS_CATOPEN 30495f757f3fSDimitry Andric return (catalog)catopen(__nm.c_str(), NL_CAT_LOCALE); 30500b57cec5SDimitry Andric#else // !_LIBCPP_HAS_CATOPEN 3051fe6060f1SDimitry Andric (void)__nm; 30520b57cec5SDimitry Andric return -1; 30530b57cec5SDimitry Andric#endif // _LIBCPP_HAS_CATOPEN 30540b57cec5SDimitry Andric} 30550b57cec5SDimitry Andric 30560b57cec5SDimitry Andrictemplate <class _CharT> 30570b57cec5SDimitry Andrictypename messages<_CharT>::string_type 3058cb14a3feSDimitry Andricmessages<_CharT>::do_get(catalog __c, int __set, int __msgid, const string_type& __dflt) const { 30590b57cec5SDimitry Andric#ifdef _LIBCPP_HAS_CATOPEN 30600b57cec5SDimitry Andric string __ndflt; 3061cb14a3feSDimitry Andric __narrow_to_utf8<sizeof(char_type) * __CHAR_BIT__>()( 3062cb14a3feSDimitry Andric std::back_inserter(__ndflt), __dflt.c_str(), __dflt.c_str() + __dflt.size()); 30630b57cec5SDimitry Andric nl_catd __cat = (nl_catd)__c; 30645f757f3fSDimitry Andric static_assert(sizeof(catalog) >= sizeof(nl_catd), "Unexpected nl_catd type"); 30650b57cec5SDimitry Andric char* __n = catgets(__cat, __set, __msgid, __ndflt.c_str()); 30660b57cec5SDimitry Andric string_type __w; 3067cb14a3feSDimitry Andric __widen_from_utf8<sizeof(char_type) * __CHAR_BIT__>()(std::back_inserter(__w), __n, __n + std::strlen(__n)); 30680b57cec5SDimitry Andric return __w; 30690b57cec5SDimitry Andric#else // !_LIBCPP_HAS_CATOPEN 3070fe6060f1SDimitry Andric (void)__c; 3071fe6060f1SDimitry Andric (void)__set; 3072fe6060f1SDimitry Andric (void)__msgid; 30730b57cec5SDimitry Andric return __dflt; 30740b57cec5SDimitry Andric#endif // _LIBCPP_HAS_CATOPEN 30750b57cec5SDimitry Andric} 30760b57cec5SDimitry Andric 30770b57cec5SDimitry Andrictemplate <class _CharT> 3078cb14a3feSDimitry Andricvoid messages<_CharT>::do_close(catalog __c) const { 30790b57cec5SDimitry Andric#ifdef _LIBCPP_HAS_CATOPEN 30805f757f3fSDimitry Andric catclose((nl_catd)__c); 30810b57cec5SDimitry Andric#else // !_LIBCPP_HAS_CATOPEN 3082fe6060f1SDimitry Andric (void)__c; 30830b57cec5SDimitry Andric#endif // _LIBCPP_HAS_CATOPEN 30840b57cec5SDimitry Andric} 30850b57cec5SDimitry Andric 308681ad6265SDimitry Andricextern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS messages<char>; 3087349cc55cSDimitry Andric#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 308881ad6265SDimitry Andricextern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS messages<wchar_t>; 3089349cc55cSDimitry Andric#endif 30900b57cec5SDimitry Andric 30910b57cec5SDimitry Andrictemplate <class _CharT> 3092cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS messages_byname : public messages<_CharT> { 30930b57cec5SDimitry Andricpublic: 30940b57cec5SDimitry Andric typedef messages_base::catalog catalog; 30950b57cec5SDimitry Andric typedef basic_string<_CharT> string_type; 30960b57cec5SDimitry Andric 3097cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit messages_byname(const char*, size_t __refs = 0) : messages<_CharT>(__refs) {} 30980b57cec5SDimitry Andric 3099cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit messages_byname(const string&, size_t __refs = 0) : messages<_CharT>(__refs) {} 31000b57cec5SDimitry Andric 31010b57cec5SDimitry Andricprotected: 3102bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI_VIRTUAL ~messages_byname() override {} 31030b57cec5SDimitry Andric}; 31040b57cec5SDimitry Andric 310581ad6265SDimitry Andricextern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS messages_byname<char>; 3106349cc55cSDimitry Andric#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 310781ad6265SDimitry Andricextern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS messages_byname<wchar_t>; 3108349cc55cSDimitry Andric#endif 31090b57cec5SDimitry Andric 3110cb14a3feSDimitry Andrictemplate <class _Codecvt, 3111cb14a3feSDimitry Andric class _Elem = wchar_t, 311206c3fb27SDimitry Andric class _WideAlloc = allocator<_Elem>, 311306c3fb27SDimitry Andric class _ByteAlloc = allocator<char> > 3114cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 wstring_convert { 31150b57cec5SDimitry Andricpublic: 311606c3fb27SDimitry Andric typedef basic_string<char, char_traits<char>, _ByteAlloc> byte_string; 311706c3fb27SDimitry Andric typedef basic_string<_Elem, char_traits<_Elem>, _WideAlloc> wide_string; 31180b57cec5SDimitry Andric typedef typename _Codecvt::state_type state_type; 31190b57cec5SDimitry Andric typedef typename wide_string::traits_type::int_type int_type; 31200b57cec5SDimitry Andric 31210b57cec5SDimitry Andricprivate: 31220b57cec5SDimitry Andric byte_string __byte_err_string_; 31230b57cec5SDimitry Andric wide_string __wide_err_string_; 31240b57cec5SDimitry Andric _Codecvt* __cvtptr_; 31250b57cec5SDimitry Andric state_type __cvtstate_; 31260b57cec5SDimitry Andric size_t __cvtcount_; 31270b57cec5SDimitry Andric 31280b57cec5SDimitry Andric wstring_convert(const wstring_convert& __wc); 31290b57cec5SDimitry Andric wstring_convert& operator=(const wstring_convert& __wc); 3130cb14a3feSDimitry Andric 31310b57cec5SDimitry Andricpublic: 3132e8d8bef9SDimitry Andric#ifndef _LIBCPP_CXX03_LANG 3133cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI wstring_convert() : wstring_convert(new _Codecvt) {} 3134cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit wstring_convert(_Codecvt* __pcvt); 3135e8d8bef9SDimitry Andric#else 3136cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_EXPLICIT_SINCE_CXX14 wstring_convert(_Codecvt* __pcvt = new _Codecvt); 3137e8d8bef9SDimitry Andric#endif 3138e8d8bef9SDimitry Andric 3139cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI wstring_convert(_Codecvt* __pcvt, state_type __state); 3140cb14a3feSDimitry Andric _LIBCPP_EXPLICIT_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI 3141cb14a3feSDimitry Andric wstring_convert(const byte_string& __byte_err, const wide_string& __wide_err = wide_string()); 31420b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG 3143cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI wstring_convert(wstring_convert&& __wc); 31440b57cec5SDimitry Andric#endif 314506c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI ~wstring_convert(); 31460b57cec5SDimitry Andric 3147cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI wide_string from_bytes(char __byte) { return from_bytes(&__byte, &__byte + 1); } 3148cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI wide_string from_bytes(const char* __ptr) { 3149cb14a3feSDimitry Andric return from_bytes(__ptr, __ptr + char_traits<char>::length(__ptr)); 3150cb14a3feSDimitry Andric } 3151cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI wide_string from_bytes(const byte_string& __str) { 3152cb14a3feSDimitry Andric return from_bytes(__str.data(), __str.data() + __str.size()); 3153cb14a3feSDimitry Andric } 315406c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI wide_string from_bytes(const char* __first, const char* __last); 31550b57cec5SDimitry Andric 3156cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI byte_string to_bytes(_Elem __wchar) { return to_bytes(&__wchar, &__wchar + 1); } 3157cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI byte_string to_bytes(const _Elem* __wptr) { 3158cb14a3feSDimitry Andric return to_bytes(__wptr, __wptr + char_traits<_Elem>::length(__wptr)); 3159cb14a3feSDimitry Andric } 3160cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI byte_string to_bytes(const wide_string& __wstr) { 3161cb14a3feSDimitry Andric return to_bytes(__wstr.data(), __wstr.data() + __wstr.size()); 3162cb14a3feSDimitry Andric } 316306c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI byte_string to_bytes(const _Elem* __first, const _Elem* __last); 31640b57cec5SDimitry Andric 3165cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_t converted() const _NOEXCEPT { return __cvtcount_; } 3166cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI state_type state() const { return __cvtstate_; } 31670b57cec5SDimitry Andric}; 31680b57cec5SDimitry Andric 316981ad6265SDimitry Andric_LIBCPP_SUPPRESS_DEPRECATED_PUSH 317006c3fb27SDimitry Andrictemplate <class _Codecvt, class _Elem, class _WideAlloc, class _ByteAlloc> 3171cb14a3feSDimitry Andricinline wstring_convert<_Codecvt, _Elem, _WideAlloc, _ByteAlloc>::wstring_convert(_Codecvt* __pcvt) 3172cb14a3feSDimitry Andric : __cvtptr_(__pcvt), __cvtstate_(), __cvtcount_(0) {} 317381ad6265SDimitry Andric_LIBCPP_SUPPRESS_DEPRECATED_POP 31740b57cec5SDimitry Andric 317506c3fb27SDimitry Andrictemplate <class _Codecvt, class _Elem, class _WideAlloc, class _ByteAlloc> 3176cb14a3feSDimitry Andricinline wstring_convert<_Codecvt, _Elem, _WideAlloc, _ByteAlloc>::wstring_convert(_Codecvt* __pcvt, state_type __state) 3177cb14a3feSDimitry Andric : __cvtptr_(__pcvt), __cvtstate_(__state), __cvtcount_(0) {} 31780b57cec5SDimitry Andric 317906c3fb27SDimitry Andrictemplate <class _Codecvt, class _Elem, class _WideAlloc, class _ByteAlloc> 3180cb14a3feSDimitry Andricwstring_convert<_Codecvt, _Elem, _WideAlloc, _ByteAlloc>::wstring_convert( 3181cb14a3feSDimitry Andric const byte_string& __byte_err, const wide_string& __wide_err) 3182cb14a3feSDimitry Andric : __byte_err_string_(__byte_err), __wide_err_string_(__wide_err), __cvtstate_(), __cvtcount_(0) { 31830b57cec5SDimitry Andric __cvtptr_ = new _Codecvt; 31840b57cec5SDimitry Andric} 31850b57cec5SDimitry Andric 31860b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG 31870b57cec5SDimitry Andric 318806c3fb27SDimitry Andrictemplate <class _Codecvt, class _Elem, class _WideAlloc, class _ByteAlloc> 3189cb14a3feSDimitry Andricinline wstring_convert<_Codecvt, _Elem, _WideAlloc, _ByteAlloc>::wstring_convert(wstring_convert&& __wc) 31905f757f3fSDimitry Andric : __byte_err_string_(std::move(__wc.__byte_err_string_)), 31915f757f3fSDimitry Andric __wide_err_string_(std::move(__wc.__wide_err_string_)), 31920b57cec5SDimitry Andric __cvtptr_(__wc.__cvtptr_), 3193cb14a3feSDimitry Andric __cvtstate_(__wc.__cvtstate_), 3194cb14a3feSDimitry Andric __cvtcount_(__wc.__cvtcount_) { 31950b57cec5SDimitry Andric __wc.__cvtptr_ = nullptr; 31960b57cec5SDimitry Andric} 31970b57cec5SDimitry Andric 31980b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG 31990b57cec5SDimitry Andric 320081ad6265SDimitry Andric_LIBCPP_SUPPRESS_DEPRECATED_PUSH 320106c3fb27SDimitry Andrictemplate <class _Codecvt, class _Elem, class _WideAlloc, class _ByteAlloc> 3202cb14a3feSDimitry Andricwstring_convert<_Codecvt, _Elem, _WideAlloc, _ByteAlloc>::~wstring_convert() { 32030b57cec5SDimitry Andric delete __cvtptr_; 32040b57cec5SDimitry Andric} 32050b57cec5SDimitry Andric 320606c3fb27SDimitry Andrictemplate <class _Codecvt, class _Elem, class _WideAlloc, class _ByteAlloc> 320706c3fb27SDimitry Andrictypename wstring_convert<_Codecvt, _Elem, _WideAlloc, _ByteAlloc>::wide_string 3208cb14a3feSDimitry Andricwstring_convert<_Codecvt, _Elem, _WideAlloc, _ByteAlloc>::from_bytes(const char* __frm, const char* __frm_end) { 320981ad6265SDimitry Andric _LIBCPP_SUPPRESS_DEPRECATED_POP 32100b57cec5SDimitry Andric __cvtcount_ = 0; 3211cb14a3feSDimitry Andric if (__cvtptr_ != nullptr) { 32120b57cec5SDimitry Andric wide_string __ws(2 * (__frm_end - __frm), _Elem()); 32130b57cec5SDimitry Andric if (__frm != __frm_end) 32140b57cec5SDimitry Andric __ws.resize(__ws.capacity()); 32150b57cec5SDimitry Andric codecvt_base::result __r = codecvt_base::ok; 32160b57cec5SDimitry Andric state_type __st = __cvtstate_; 3217cb14a3feSDimitry Andric if (__frm != __frm_end) { 32180b57cec5SDimitry Andric _Elem* __to = &__ws[0]; 32190b57cec5SDimitry Andric _Elem* __to_end = __to + __ws.size(); 32200b57cec5SDimitry Andric const char* __frm_nxt; 3221cb14a3feSDimitry Andric do { 32220b57cec5SDimitry Andric _Elem* __to_nxt; 3223cb14a3feSDimitry Andric __r = __cvtptr_->in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt); 32240b57cec5SDimitry Andric __cvtcount_ += __frm_nxt - __frm; 3225cb14a3feSDimitry Andric if (__frm_nxt == __frm) { 32260b57cec5SDimitry Andric __r = codecvt_base::error; 3227cb14a3feSDimitry Andric } else if (__r == codecvt_base::noconv) { 32280b57cec5SDimitry Andric __ws.resize(__to - &__ws[0]); 32290b57cec5SDimitry Andric // This only gets executed if _Elem is char 32300b57cec5SDimitry Andric __ws.append((const _Elem*)__frm, (const _Elem*)__frm_end); 32310b57cec5SDimitry Andric __frm = __frm_nxt; 32320b57cec5SDimitry Andric __r = codecvt_base::ok; 3233cb14a3feSDimitry Andric } else if (__r == codecvt_base::ok) { 32340b57cec5SDimitry Andric __ws.resize(__to_nxt - &__ws[0]); 32350b57cec5SDimitry Andric __frm = __frm_nxt; 3236cb14a3feSDimitry Andric } else if (__r == codecvt_base::partial) { 32370b57cec5SDimitry Andric ptrdiff_t __s = __to_nxt - &__ws[0]; 32380b57cec5SDimitry Andric __ws.resize(2 * __s); 32390b57cec5SDimitry Andric __to = &__ws[0] + __s; 32400b57cec5SDimitry Andric __to_end = &__ws[0] + __ws.size(); 32410b57cec5SDimitry Andric __frm = __frm_nxt; 32420b57cec5SDimitry Andric } 32430b57cec5SDimitry Andric } while (__r == codecvt_base::partial && __frm_nxt < __frm_end); 32440b57cec5SDimitry Andric } 32450b57cec5SDimitry Andric if (__r == codecvt_base::ok) 32460b57cec5SDimitry Andric return __ws; 32470b57cec5SDimitry Andric } 32480b57cec5SDimitry Andric 32490b57cec5SDimitry Andric if (__wide_err_string_.empty()) 32500b57cec5SDimitry Andric __throw_range_error("wstring_convert: from_bytes error"); 32510b57cec5SDimitry Andric 32520b57cec5SDimitry Andric return __wide_err_string_; 32530b57cec5SDimitry Andric} 32540b57cec5SDimitry Andric 325506c3fb27SDimitry Andrictemplate <class _Codecvt, class _Elem, class _WideAlloc, class _ByteAlloc> 325606c3fb27SDimitry Andrictypename wstring_convert<_Codecvt, _Elem, _WideAlloc, _ByteAlloc>::byte_string 3257cb14a3feSDimitry Andricwstring_convert<_Codecvt, _Elem, _WideAlloc, _ByteAlloc>::to_bytes(const _Elem* __frm, const _Elem* __frm_end) { 32580b57cec5SDimitry Andric __cvtcount_ = 0; 3259cb14a3feSDimitry Andric if (__cvtptr_ != nullptr) { 32600b57cec5SDimitry Andric byte_string __bs(2 * (__frm_end - __frm), char()); 32610b57cec5SDimitry Andric if (__frm != __frm_end) 32620b57cec5SDimitry Andric __bs.resize(__bs.capacity()); 32630b57cec5SDimitry Andric codecvt_base::result __r = codecvt_base::ok; 32640b57cec5SDimitry Andric state_type __st = __cvtstate_; 3265cb14a3feSDimitry Andric if (__frm != __frm_end) { 32660b57cec5SDimitry Andric char* __to = &__bs[0]; 32670b57cec5SDimitry Andric char* __to_end = __to + __bs.size(); 32680b57cec5SDimitry Andric const _Elem* __frm_nxt; 3269cb14a3feSDimitry Andric do { 32700b57cec5SDimitry Andric char* __to_nxt; 3271cb14a3feSDimitry Andric __r = __cvtptr_->out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt); 32720b57cec5SDimitry Andric __cvtcount_ += __frm_nxt - __frm; 3273cb14a3feSDimitry Andric if (__frm_nxt == __frm) { 32740b57cec5SDimitry Andric __r = codecvt_base::error; 3275cb14a3feSDimitry Andric } else if (__r == codecvt_base::noconv) { 32760b57cec5SDimitry Andric __bs.resize(__to - &__bs[0]); 32770b57cec5SDimitry Andric // This only gets executed if _Elem is char 32780b57cec5SDimitry Andric __bs.append((const char*)__frm, (const char*)__frm_end); 32790b57cec5SDimitry Andric __frm = __frm_nxt; 32800b57cec5SDimitry Andric __r = codecvt_base::ok; 3281cb14a3feSDimitry Andric } else if (__r == codecvt_base::ok) { 32820b57cec5SDimitry Andric __bs.resize(__to_nxt - &__bs[0]); 32830b57cec5SDimitry Andric __frm = __frm_nxt; 3284cb14a3feSDimitry Andric } else if (__r == codecvt_base::partial) { 32850b57cec5SDimitry Andric ptrdiff_t __s = __to_nxt - &__bs[0]; 32860b57cec5SDimitry Andric __bs.resize(2 * __s); 32870b57cec5SDimitry Andric __to = &__bs[0] + __s; 32880b57cec5SDimitry Andric __to_end = &__bs[0] + __bs.size(); 32890b57cec5SDimitry Andric __frm = __frm_nxt; 32900b57cec5SDimitry Andric } 32910b57cec5SDimitry Andric } while (__r == codecvt_base::partial && __frm_nxt < __frm_end); 32920b57cec5SDimitry Andric } 3293cb14a3feSDimitry Andric if (__r == codecvt_base::ok) { 32940b57cec5SDimitry Andric size_t __s = __bs.size(); 32950b57cec5SDimitry Andric __bs.resize(__bs.capacity()); 32960b57cec5SDimitry Andric char* __to = &__bs[0] + __s; 32970b57cec5SDimitry Andric char* __to_end = __to + __bs.size(); 3298cb14a3feSDimitry Andric do { 32990b57cec5SDimitry Andric char* __to_nxt; 33000b57cec5SDimitry Andric __r = __cvtptr_->unshift(__st, __to, __to_end, __to_nxt); 3301cb14a3feSDimitry Andric if (__r == codecvt_base::noconv) { 33020b57cec5SDimitry Andric __bs.resize(__to - &__bs[0]); 33030b57cec5SDimitry Andric __r = codecvt_base::ok; 3304cb14a3feSDimitry Andric } else if (__r == codecvt_base::ok) { 33050b57cec5SDimitry Andric __bs.resize(__to_nxt - &__bs[0]); 3306cb14a3feSDimitry Andric } else if (__r == codecvt_base::partial) { 33070b57cec5SDimitry Andric ptrdiff_t __sp = __to_nxt - &__bs[0]; 33080b57cec5SDimitry Andric __bs.resize(2 * __sp); 33090b57cec5SDimitry Andric __to = &__bs[0] + __sp; 33100b57cec5SDimitry Andric __to_end = &__bs[0] + __bs.size(); 33110b57cec5SDimitry Andric } 33120b57cec5SDimitry Andric } while (__r == codecvt_base::partial); 33130b57cec5SDimitry Andric if (__r == codecvt_base::ok) 33140b57cec5SDimitry Andric return __bs; 33150b57cec5SDimitry Andric } 33160b57cec5SDimitry Andric } 33170b57cec5SDimitry Andric 33180b57cec5SDimitry Andric if (__byte_err_string_.empty()) 33190b57cec5SDimitry Andric __throw_range_error("wstring_convert: to_bytes error"); 33200b57cec5SDimitry Andric 33210b57cec5SDimitry Andric return __byte_err_string_; 33220b57cec5SDimitry Andric} 33230b57cec5SDimitry Andric 33240b57cec5SDimitry Andrictemplate <class _Codecvt, class _Elem = wchar_t, class _Tr = char_traits<_Elem> > 3325cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 wbuffer_convert : public basic_streambuf<_Elem, _Tr> { 33260b57cec5SDimitry Andricpublic: 33270b57cec5SDimitry Andric // types: 33280b57cec5SDimitry Andric typedef _Elem char_type; 33290b57cec5SDimitry Andric typedef _Tr traits_type; 33300b57cec5SDimitry Andric typedef typename traits_type::int_type int_type; 33310b57cec5SDimitry Andric typedef typename traits_type::pos_type pos_type; 33320b57cec5SDimitry Andric typedef typename traits_type::off_type off_type; 33330b57cec5SDimitry Andric typedef typename _Codecvt::state_type state_type; 33340b57cec5SDimitry Andric 33350b57cec5SDimitry Andricprivate: 33360b57cec5SDimitry Andric char* __extbuf_; 33370b57cec5SDimitry Andric const char* __extbufnext_; 33380b57cec5SDimitry Andric const char* __extbufend_; 33390b57cec5SDimitry Andric char __extbuf_min_[8]; 33400b57cec5SDimitry Andric size_t __ebs_; 33410b57cec5SDimitry Andric char_type* __intbuf_; 33420b57cec5SDimitry Andric size_t __ibs_; 33430b57cec5SDimitry Andric streambuf* __bufptr_; 33440b57cec5SDimitry Andric _Codecvt* __cv_; 33450b57cec5SDimitry Andric state_type __st_; 33460b57cec5SDimitry Andric ios_base::openmode __cm_; 33470b57cec5SDimitry Andric bool __owns_eb_; 33480b57cec5SDimitry Andric bool __owns_ib_; 33490b57cec5SDimitry Andric bool __always_noconv_; 33500b57cec5SDimitry Andric 33510b57cec5SDimitry Andric wbuffer_convert(const wbuffer_convert&); 33520b57cec5SDimitry Andric wbuffer_convert& operator=(const wbuffer_convert&); 3353e8d8bef9SDimitry Andric 33540b57cec5SDimitry Andricpublic: 3355e8d8bef9SDimitry Andric#ifndef _LIBCPP_CXX03_LANG 335606c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI wbuffer_convert() : wbuffer_convert(nullptr) {} 3357cb14a3feSDimitry Andric explicit _LIBCPP_HIDE_FROM_ABI 3358cb14a3feSDimitry Andric wbuffer_convert(streambuf* __bytebuf, _Codecvt* __pcvt = new _Codecvt, state_type __state = state_type()); 3359e8d8bef9SDimitry Andric#else 336006c3fb27SDimitry Andric _LIBCPP_EXPLICIT_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI 3361cb14a3feSDimitry Andric wbuffer_convert(streambuf* __bytebuf = nullptr, _Codecvt* __pcvt = new _Codecvt, state_type __state = state_type()); 3362e8d8bef9SDimitry Andric#endif 3363e8d8bef9SDimitry Andric 336406c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI ~wbuffer_convert(); 33650b57cec5SDimitry Andric 3366cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI streambuf* rdbuf() const { return __bufptr_; } 3367cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI streambuf* rdbuf(streambuf* __bytebuf) { 33680b57cec5SDimitry Andric streambuf* __r = __bufptr_; 33690b57cec5SDimitry Andric __bufptr_ = __bytebuf; 33700b57cec5SDimitry Andric return __r; 33710b57cec5SDimitry Andric } 33720b57cec5SDimitry Andric 3373cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI state_type state() const { return __st_; } 33740b57cec5SDimitry Andric 33750b57cec5SDimitry Andricprotected: 337606c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual int_type underflow(); 337706c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual int_type pbackfail(int_type __c = traits_type::eof()); 337806c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual int_type overflow(int_type __c = traits_type::eof()); 3379cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual basic_streambuf<char_type, traits_type>* setbuf(char_type* __s, streamsize __n); 3380cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual pos_type 3381cb14a3feSDimitry Andric seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode __wch = ios_base::in | ios_base::out); 3382cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual pos_type 3383cb14a3feSDimitry Andric seekpos(pos_type __sp, ios_base::openmode __wch = ios_base::in | ios_base::out); 338406c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual int sync(); 33850b57cec5SDimitry Andric 33860b57cec5SDimitry Andricprivate: 338706c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI_VIRTUAL bool __read_mode(); 338806c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __write_mode(); 338906c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI_VIRTUAL wbuffer_convert* __close(); 33900b57cec5SDimitry Andric}; 33910b57cec5SDimitry Andric 339281ad6265SDimitry Andric_LIBCPP_SUPPRESS_DEPRECATED_PUSH 33930b57cec5SDimitry Andrictemplate <class _Codecvt, class _Elem, class _Tr> 3394cb14a3feSDimitry Andricwbuffer_convert<_Codecvt, _Elem, _Tr>::wbuffer_convert(streambuf* __bytebuf, _Codecvt* __pcvt, state_type __state) 3395e8d8bef9SDimitry Andric : __extbuf_(nullptr), 3396e8d8bef9SDimitry Andric __extbufnext_(nullptr), 3397e8d8bef9SDimitry Andric __extbufend_(nullptr), 33980b57cec5SDimitry Andric __ebs_(0), 33990b57cec5SDimitry Andric __intbuf_(0), 34000b57cec5SDimitry Andric __ibs_(0), 34010b57cec5SDimitry Andric __bufptr_(__bytebuf), 34020b57cec5SDimitry Andric __cv_(__pcvt), 34030b57cec5SDimitry Andric __st_(__state), 34040b57cec5SDimitry Andric __cm_(0), 34050b57cec5SDimitry Andric __owns_eb_(false), 34060b57cec5SDimitry Andric __owns_ib_(false), 3407cb14a3feSDimitry Andric __always_noconv_(__cv_ ? __cv_->always_noconv() : false) { 34080b57cec5SDimitry Andric setbuf(0, 4096); 34090b57cec5SDimitry Andric} 34100b57cec5SDimitry Andric 34110b57cec5SDimitry Andrictemplate <class _Codecvt, class _Elem, class _Tr> 3412cb14a3feSDimitry Andricwbuffer_convert<_Codecvt, _Elem, _Tr>::~wbuffer_convert() { 34130b57cec5SDimitry Andric __close(); 34140b57cec5SDimitry Andric delete __cv_; 34150b57cec5SDimitry Andric if (__owns_eb_) 34160b57cec5SDimitry Andric delete[] __extbuf_; 34170b57cec5SDimitry Andric if (__owns_ib_) 34180b57cec5SDimitry Andric delete[] __intbuf_; 34190b57cec5SDimitry Andric} 34200b57cec5SDimitry Andric 34210b57cec5SDimitry Andrictemplate <class _Codecvt, class _Elem, class _Tr> 3422cb14a3feSDimitry Andrictypename wbuffer_convert<_Codecvt, _Elem, _Tr>::int_type wbuffer_convert<_Codecvt, _Elem, _Tr>::underflow() { 342381ad6265SDimitry Andric _LIBCPP_SUPPRESS_DEPRECATED_POP 34247a6dacacSDimitry Andric if (__cv_ == 0 || __bufptr_ == nullptr) 34250b57cec5SDimitry Andric return traits_type::eof(); 34260b57cec5SDimitry Andric bool __initial = __read_mode(); 34270b57cec5SDimitry Andric char_type __1buf; 34280b57cec5SDimitry Andric if (this->gptr() == 0) 34290b57cec5SDimitry Andric this->setg(&__1buf, &__1buf + 1, &__1buf + 1); 3430bdd1243dSDimitry Andric const size_t __unget_sz = __initial ? 0 : std::min<size_t>((this->egptr() - this->eback()) / 2, 4); 34310b57cec5SDimitry Andric int_type __c = traits_type::eof(); 3432cb14a3feSDimitry Andric if (this->gptr() == this->egptr()) { 34335f757f3fSDimitry Andric std::memmove(this->eback(), this->egptr() - __unget_sz, __unget_sz * sizeof(char_type)); 3434cb14a3feSDimitry Andric if (__always_noconv_) { 34350b57cec5SDimitry Andric streamsize __nmemb = static_cast<streamsize>(this->egptr() - this->eback() - __unget_sz); 34360b57cec5SDimitry Andric __nmemb = __bufptr_->sgetn((char*)this->eback() + __unget_sz, __nmemb); 3437cb14a3feSDimitry Andric if (__nmemb != 0) { 3438cb14a3feSDimitry Andric this->setg(this->eback(), this->eback() + __unget_sz, this->eback() + __unget_sz + __nmemb); 34390b57cec5SDimitry Andric __c = *this->gptr(); 34400b57cec5SDimitry Andric } 3441cb14a3feSDimitry Andric } else { 3442bdd1243dSDimitry Andric if (__extbufend_ != __extbufnext_) { 34435f757f3fSDimitry Andric _LIBCPP_ASSERT_NON_NULL(__extbufnext_ != nullptr, "underflow moving from nullptr"); 34445f757f3fSDimitry Andric _LIBCPP_ASSERT_NON_NULL(__extbuf_ != nullptr, "underflow moving into nullptr"); 34455f757f3fSDimitry Andric std::memmove(__extbuf_, __extbufnext_, __extbufend_ - __extbufnext_); 3446bdd1243dSDimitry Andric } 34470b57cec5SDimitry Andric __extbufnext_ = __extbuf_ + (__extbufend_ - __extbufnext_); 34480b57cec5SDimitry Andric __extbufend_ = __extbuf_ + (__extbuf_ == __extbuf_min_ ? sizeof(__extbuf_min_) : __ebs_); 34495f757f3fSDimitry Andric streamsize __nmemb = std::min(static_cast<streamsize>(this->egptr() - this->eback() - __unget_sz), 34500b57cec5SDimitry Andric static_cast<streamsize>(__extbufend_ - __extbufnext_)); 34510b57cec5SDimitry Andric codecvt_base::result __r; 34520b57cec5SDimitry Andric // FIXME: Do we ever need to restore the state here? 34530b57cec5SDimitry Andric // state_type __svs = __st_; 34540b57cec5SDimitry Andric streamsize __nr = __bufptr_->sgetn(const_cast<char*>(__extbufnext_), __nmemb); 3455cb14a3feSDimitry Andric if (__nr != 0) { 34560b57cec5SDimitry Andric __extbufend_ = __extbufnext_ + __nr; 34570b57cec5SDimitry Andric char_type* __inext; 3458cb14a3feSDimitry Andric __r = __cv_->in( 3459cb14a3feSDimitry Andric __st_, __extbuf_, __extbufend_, __extbufnext_, this->eback() + __unget_sz, this->egptr(), __inext); 3460cb14a3feSDimitry Andric if (__r == codecvt_base::noconv) { 3461cb14a3feSDimitry Andric this->setg((char_type*)__extbuf_, (char_type*)__extbuf_, (char_type*)const_cast<char*>(__extbufend_)); 34620b57cec5SDimitry Andric __c = *this->gptr(); 3463cb14a3feSDimitry Andric } else if (__inext != this->eback() + __unget_sz) { 34640b57cec5SDimitry Andric this->setg(this->eback(), this->eback() + __unget_sz, __inext); 34650b57cec5SDimitry Andric __c = *this->gptr(); 34660b57cec5SDimitry Andric } 34670b57cec5SDimitry Andric } 34680b57cec5SDimitry Andric } 3469cb14a3feSDimitry Andric } else 34700b57cec5SDimitry Andric __c = *this->gptr(); 34710b57cec5SDimitry Andric if (this->eback() == &__1buf) 34720b57cec5SDimitry Andric this->setg(0, 0, 0); 34730b57cec5SDimitry Andric return __c; 34740b57cec5SDimitry Andric} 34750b57cec5SDimitry Andric 347681ad6265SDimitry Andric_LIBCPP_SUPPRESS_DEPRECATED_PUSH 34770b57cec5SDimitry Andrictemplate <class _Codecvt, class _Elem, class _Tr> 34780b57cec5SDimitry Andrictypename wbuffer_convert<_Codecvt, _Elem, _Tr>::int_type 3479cb14a3feSDimitry Andricwbuffer_convert<_Codecvt, _Elem, _Tr>::pbackfail(int_type __c) { 348081ad6265SDimitry Andric _LIBCPP_SUPPRESS_DEPRECATED_POP 34817a6dacacSDimitry Andric if (__cv_ != 0 && __bufptr_ && this->eback() < this->gptr()) { 3482cb14a3feSDimitry Andric if (traits_type::eq_int_type(__c, traits_type::eof())) { 34830b57cec5SDimitry Andric this->gbump(-1); 34840b57cec5SDimitry Andric return traits_type::not_eof(__c); 34850b57cec5SDimitry Andric } 3486cb14a3feSDimitry Andric if (traits_type::eq(traits_type::to_char_type(__c), this->gptr()[-1])) { 34870b57cec5SDimitry Andric this->gbump(-1); 34880b57cec5SDimitry Andric *this->gptr() = traits_type::to_char_type(__c); 34890b57cec5SDimitry Andric return __c; 34900b57cec5SDimitry Andric } 34910b57cec5SDimitry Andric } 34920b57cec5SDimitry Andric return traits_type::eof(); 34930b57cec5SDimitry Andric} 34940b57cec5SDimitry Andric 349581ad6265SDimitry Andric_LIBCPP_SUPPRESS_DEPRECATED_PUSH 34960b57cec5SDimitry Andrictemplate <class _Codecvt, class _Elem, class _Tr> 3497cb14a3feSDimitry Andrictypename wbuffer_convert<_Codecvt, _Elem, _Tr>::int_type wbuffer_convert<_Codecvt, _Elem, _Tr>::overflow(int_type __c) { 349881ad6265SDimitry Andric _LIBCPP_SUPPRESS_DEPRECATED_POP 34997a6dacacSDimitry Andric if (__cv_ == 0 || !__bufptr_) 35000b57cec5SDimitry Andric return traits_type::eof(); 35010b57cec5SDimitry Andric __write_mode(); 35020b57cec5SDimitry Andric char_type __1buf; 35030b57cec5SDimitry Andric char_type* __pb_save = this->pbase(); 35040b57cec5SDimitry Andric char_type* __epb_save = this->epptr(); 3505cb14a3feSDimitry Andric if (!traits_type::eq_int_type(__c, traits_type::eof())) { 35060b57cec5SDimitry Andric if (this->pptr() == 0) 35070b57cec5SDimitry Andric this->setp(&__1buf, &__1buf + 1); 35080b57cec5SDimitry Andric *this->pptr() = traits_type::to_char_type(__c); 35090b57cec5SDimitry Andric this->pbump(1); 35100b57cec5SDimitry Andric } 3511cb14a3feSDimitry Andric if (this->pptr() != this->pbase()) { 3512cb14a3feSDimitry Andric if (__always_noconv_) { 35130b57cec5SDimitry Andric streamsize __nmemb = static_cast<streamsize>(this->pptr() - this->pbase()); 35140b57cec5SDimitry Andric if (__bufptr_->sputn((const char*)this->pbase(), __nmemb) != __nmemb) 35150b57cec5SDimitry Andric return traits_type::eof(); 3516cb14a3feSDimitry Andric } else { 35170b57cec5SDimitry Andric char* __extbe = __extbuf_; 35180b57cec5SDimitry Andric codecvt_base::result __r; 3519cb14a3feSDimitry Andric do { 35200b57cec5SDimitry Andric const char_type* __e; 3521cb14a3feSDimitry Andric __r = __cv_->out(__st_, this->pbase(), this->pptr(), __e, __extbuf_, __extbuf_ + __ebs_, __extbe); 35220b57cec5SDimitry Andric if (__e == this->pbase()) 35230b57cec5SDimitry Andric return traits_type::eof(); 3524cb14a3feSDimitry Andric if (__r == codecvt_base::noconv) { 35250b57cec5SDimitry Andric streamsize __nmemb = static_cast<size_t>(this->pptr() - this->pbase()); 35260b57cec5SDimitry Andric if (__bufptr_->sputn((const char*)this->pbase(), __nmemb) != __nmemb) 35270b57cec5SDimitry Andric return traits_type::eof(); 3528cb14a3feSDimitry Andric } else if (__r == codecvt_base::ok || __r == codecvt_base::partial) { 35290b57cec5SDimitry Andric streamsize __nmemb = static_cast<size_t>(__extbe - __extbuf_); 35300b57cec5SDimitry Andric if (__bufptr_->sputn(__extbuf_, __nmemb) != __nmemb) 35310b57cec5SDimitry Andric return traits_type::eof(); 3532cb14a3feSDimitry Andric if (__r == codecvt_base::partial) { 35330b57cec5SDimitry Andric this->setp(const_cast<char_type*>(__e), this->pptr()); 35340b57cec5SDimitry Andric this->__pbump(this->epptr() - this->pbase()); 35350b57cec5SDimitry Andric } 3536cb14a3feSDimitry Andric } else 35370b57cec5SDimitry Andric return traits_type::eof(); 35380b57cec5SDimitry Andric } while (__r == codecvt_base::partial); 35390b57cec5SDimitry Andric } 35400b57cec5SDimitry Andric this->setp(__pb_save, __epb_save); 35410b57cec5SDimitry Andric } 35420b57cec5SDimitry Andric return traits_type::not_eof(__c); 35430b57cec5SDimitry Andric} 35440b57cec5SDimitry Andric 354581ad6265SDimitry Andric_LIBCPP_SUPPRESS_DEPRECATED_PUSH 35460b57cec5SDimitry Andrictemplate <class _Codecvt, class _Elem, class _Tr> 3547cb14a3feSDimitry Andricbasic_streambuf<_Elem, _Tr>* wbuffer_convert<_Codecvt, _Elem, _Tr>::setbuf(char_type* __s, streamsize __n) { 354881ad6265SDimitry Andric _LIBCPP_SUPPRESS_DEPRECATED_POP 35490b57cec5SDimitry Andric this->setg(0, 0, 0); 35500b57cec5SDimitry Andric this->setp(0, 0); 35510b57cec5SDimitry Andric if (__owns_eb_) 35520b57cec5SDimitry Andric delete[] __extbuf_; 35530b57cec5SDimitry Andric if (__owns_ib_) 35540b57cec5SDimitry Andric delete[] __intbuf_; 35550b57cec5SDimitry Andric __ebs_ = __n; 3556cb14a3feSDimitry Andric if (__ebs_ > sizeof(__extbuf_min_)) { 3557cb14a3feSDimitry Andric if (__always_noconv_ && __s) { 35580b57cec5SDimitry Andric __extbuf_ = (char*)__s; 35590b57cec5SDimitry Andric __owns_eb_ = false; 3560cb14a3feSDimitry Andric } else { 35610b57cec5SDimitry Andric __extbuf_ = new char[__ebs_]; 35620b57cec5SDimitry Andric __owns_eb_ = true; 35630b57cec5SDimitry Andric } 3564cb14a3feSDimitry Andric } else { 35650b57cec5SDimitry Andric __extbuf_ = __extbuf_min_; 35660b57cec5SDimitry Andric __ebs_ = sizeof(__extbuf_min_); 35670b57cec5SDimitry Andric __owns_eb_ = false; 35680b57cec5SDimitry Andric } 3569cb14a3feSDimitry Andric if (!__always_noconv_) { 35700b57cec5SDimitry Andric __ibs_ = max<streamsize>(__n, sizeof(__extbuf_min_)); 3571cb14a3feSDimitry Andric if (__s && __ibs_ >= sizeof(__extbuf_min_)) { 35720b57cec5SDimitry Andric __intbuf_ = __s; 35730b57cec5SDimitry Andric __owns_ib_ = false; 3574cb14a3feSDimitry Andric } else { 35750b57cec5SDimitry Andric __intbuf_ = new char_type[__ibs_]; 35760b57cec5SDimitry Andric __owns_ib_ = true; 35770b57cec5SDimitry Andric } 3578cb14a3feSDimitry Andric } else { 35790b57cec5SDimitry Andric __ibs_ = 0; 35800b57cec5SDimitry Andric __intbuf_ = 0; 35810b57cec5SDimitry Andric __owns_ib_ = false; 35820b57cec5SDimitry Andric } 35830b57cec5SDimitry Andric return this; 35840b57cec5SDimitry Andric} 35850b57cec5SDimitry Andric 358681ad6265SDimitry Andric_LIBCPP_SUPPRESS_DEPRECATED_PUSH 35870b57cec5SDimitry Andrictemplate <class _Codecvt, class _Elem, class _Tr> 35880b57cec5SDimitry Andrictypename wbuffer_convert<_Codecvt, _Elem, _Tr>::pos_type 3589cb14a3feSDimitry Andricwbuffer_convert<_Codecvt, _Elem, _Tr>::seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode __om) { 35900b57cec5SDimitry Andric int __width = __cv_->encoding(); 35917a6dacacSDimitry Andric if (__cv_ == 0 || !__bufptr_ || (__width <= 0 && __off != 0) || sync()) 35920b57cec5SDimitry Andric return pos_type(off_type(-1)); 35930b57cec5SDimitry Andric // __width > 0 || __off == 0, now check __way 35940b57cec5SDimitry Andric if (__way != ios_base::beg && __way != ios_base::cur && __way != ios_base::end) 35950b57cec5SDimitry Andric return pos_type(off_type(-1)); 35960b57cec5SDimitry Andric pos_type __r = __bufptr_->pubseekoff(__width * __off, __way, __om); 35970b57cec5SDimitry Andric __r.state(__st_); 35980b57cec5SDimitry Andric return __r; 35990b57cec5SDimitry Andric} 36000b57cec5SDimitry Andric 36010b57cec5SDimitry Andrictemplate <class _Codecvt, class _Elem, class _Tr> 36020b57cec5SDimitry Andrictypename wbuffer_convert<_Codecvt, _Elem, _Tr>::pos_type 3603cb14a3feSDimitry Andricwbuffer_convert<_Codecvt, _Elem, _Tr>::seekpos(pos_type __sp, ios_base::openmode __wch) { 36047a6dacacSDimitry Andric if (__cv_ == 0 || !__bufptr_ || sync()) 36050b57cec5SDimitry Andric return pos_type(off_type(-1)); 36060b57cec5SDimitry Andric if (__bufptr_->pubseekpos(__sp, __wch) == pos_type(off_type(-1))) 36070b57cec5SDimitry Andric return pos_type(off_type(-1)); 36080b57cec5SDimitry Andric return __sp; 36090b57cec5SDimitry Andric} 36100b57cec5SDimitry Andric 36110b57cec5SDimitry Andrictemplate <class _Codecvt, class _Elem, class _Tr> 3612cb14a3feSDimitry Andricint wbuffer_convert<_Codecvt, _Elem, _Tr>::sync() { 361381ad6265SDimitry Andric _LIBCPP_SUPPRESS_DEPRECATED_POP 36147a6dacacSDimitry Andric if (__cv_ == 0 || !__bufptr_) 36150b57cec5SDimitry Andric return 0; 3616cb14a3feSDimitry Andric if (__cm_ & ios_base::out) { 36170b57cec5SDimitry Andric if (this->pptr() != this->pbase()) 36180b57cec5SDimitry Andric if (overflow() == traits_type::eof()) 36190b57cec5SDimitry Andric return -1; 36200b57cec5SDimitry Andric codecvt_base::result __r; 3621cb14a3feSDimitry Andric do { 36220b57cec5SDimitry Andric char* __extbe; 36230b57cec5SDimitry Andric __r = __cv_->unshift(__st_, __extbuf_, __extbuf_ + __ebs_, __extbe); 36240b57cec5SDimitry Andric streamsize __nmemb = static_cast<streamsize>(__extbe - __extbuf_); 36250b57cec5SDimitry Andric if (__bufptr_->sputn(__extbuf_, __nmemb) != __nmemb) 36260b57cec5SDimitry Andric return -1; 36270b57cec5SDimitry Andric } while (__r == codecvt_base::partial); 36280b57cec5SDimitry Andric if (__r == codecvt_base::error) 36290b57cec5SDimitry Andric return -1; 36300b57cec5SDimitry Andric if (__bufptr_->pubsync()) 36310b57cec5SDimitry Andric return -1; 3632cb14a3feSDimitry Andric } else if (__cm_ & ios_base::in) { 36330b57cec5SDimitry Andric off_type __c; 36340b57cec5SDimitry Andric if (__always_noconv_) 36350b57cec5SDimitry Andric __c = this->egptr() - this->gptr(); 3636cb14a3feSDimitry Andric else { 36370b57cec5SDimitry Andric int __width = __cv_->encoding(); 36380b57cec5SDimitry Andric __c = __extbufend_ - __extbufnext_; 36390b57cec5SDimitry Andric if (__width > 0) 36400b57cec5SDimitry Andric __c += __width * (this->egptr() - this->gptr()); 3641cb14a3feSDimitry Andric else { 3642cb14a3feSDimitry Andric if (this->gptr() != this->egptr()) { 3643bdd1243dSDimitry Andric std::reverse(this->gptr(), this->egptr()); 36440b57cec5SDimitry Andric codecvt_base::result __r; 36450b57cec5SDimitry Andric const char_type* __e = this->gptr(); 36460b57cec5SDimitry Andric char* __extbe; 3647cb14a3feSDimitry Andric do { 3648cb14a3feSDimitry Andric __r = __cv_->out(__st_, __e, this->egptr(), __e, __extbuf_, __extbuf_ + __ebs_, __extbe); 3649cb14a3feSDimitry Andric switch (__r) { 36500b57cec5SDimitry Andric case codecvt_base::noconv: 36510b57cec5SDimitry Andric __c += this->egptr() - this->gptr(); 36520b57cec5SDimitry Andric break; 36530b57cec5SDimitry Andric case codecvt_base::ok: 36540b57cec5SDimitry Andric case codecvt_base::partial: 36550b57cec5SDimitry Andric __c += __extbe - __extbuf_; 36560b57cec5SDimitry Andric break; 36570b57cec5SDimitry Andric default: 36580b57cec5SDimitry Andric return -1; 36590b57cec5SDimitry Andric } 36600b57cec5SDimitry Andric } while (__r == codecvt_base::partial); 36610b57cec5SDimitry Andric } 36620b57cec5SDimitry Andric } 36630b57cec5SDimitry Andric } 36640b57cec5SDimitry Andric if (__bufptr_->pubseekoff(-__c, ios_base::cur, __cm_) == pos_type(off_type(-1))) 36650b57cec5SDimitry Andric return -1; 36660b57cec5SDimitry Andric this->setg(0, 0, 0); 36670b57cec5SDimitry Andric __cm_ = 0; 36680b57cec5SDimitry Andric } 36690b57cec5SDimitry Andric return 0; 36700b57cec5SDimitry Andric} 36710b57cec5SDimitry Andric 367281ad6265SDimitry Andric_LIBCPP_SUPPRESS_DEPRECATED_PUSH 36730b57cec5SDimitry Andrictemplate <class _Codecvt, class _Elem, class _Tr> 3674cb14a3feSDimitry Andricbool wbuffer_convert<_Codecvt, _Elem, _Tr>::__read_mode() { 3675cb14a3feSDimitry Andric if (!(__cm_ & ios_base::in)) { 36760b57cec5SDimitry Andric this->setp(0, 0); 36770b57cec5SDimitry Andric if (__always_noconv_) 3678cb14a3feSDimitry Andric this->setg((char_type*)__extbuf_, (char_type*)__extbuf_ + __ebs_, (char_type*)__extbuf_ + __ebs_); 36790b57cec5SDimitry Andric else 36800b57cec5SDimitry Andric this->setg(__intbuf_, __intbuf_ + __ibs_, __intbuf_ + __ibs_); 36810b57cec5SDimitry Andric __cm_ = ios_base::in; 36820b57cec5SDimitry Andric return true; 36830b57cec5SDimitry Andric } 36840b57cec5SDimitry Andric return false; 36850b57cec5SDimitry Andric} 36860b57cec5SDimitry Andric 36870b57cec5SDimitry Andrictemplate <class _Codecvt, class _Elem, class _Tr> 3688cb14a3feSDimitry Andricvoid wbuffer_convert<_Codecvt, _Elem, _Tr>::__write_mode() { 3689cb14a3feSDimitry Andric if (!(__cm_ & ios_base::out)) { 36900b57cec5SDimitry Andric this->setg(0, 0, 0); 3691cb14a3feSDimitry Andric if (__ebs_ > sizeof(__extbuf_min_)) { 36920b57cec5SDimitry Andric if (__always_noconv_) 3693cb14a3feSDimitry Andric this->setp((char_type*)__extbuf_, (char_type*)__extbuf_ + (__ebs_ - 1)); 36940b57cec5SDimitry Andric else 36950b57cec5SDimitry Andric this->setp(__intbuf_, __intbuf_ + (__ibs_ - 1)); 3696cb14a3feSDimitry Andric } else 36970b57cec5SDimitry Andric this->setp(0, 0); 36980b57cec5SDimitry Andric __cm_ = ios_base::out; 36990b57cec5SDimitry Andric } 37000b57cec5SDimitry Andric} 37010b57cec5SDimitry Andric 37020b57cec5SDimitry Andrictemplate <class _Codecvt, class _Elem, class _Tr> 3703cb14a3feSDimitry Andricwbuffer_convert<_Codecvt, _Elem, _Tr>* wbuffer_convert<_Codecvt, _Elem, _Tr>::__close() { 3704e8d8bef9SDimitry Andric wbuffer_convert* __rt = nullptr; 3705cb14a3feSDimitry Andric if (__cv_ != nullptr && __bufptr_ != nullptr) { 37060b57cec5SDimitry Andric __rt = this; 37070b57cec5SDimitry Andric if ((__cm_ & ios_base::out) && sync()) 3708e8d8bef9SDimitry Andric __rt = nullptr; 37090b57cec5SDimitry Andric } 37100b57cec5SDimitry Andric return __rt; 37110b57cec5SDimitry Andric} 37120b57cec5SDimitry Andric 371381ad6265SDimitry Andric_LIBCPP_SUPPRESS_DEPRECATED_POP 371481ad6265SDimitry Andric 37150b57cec5SDimitry Andric_LIBCPP_END_NAMESPACE_STD 37160b57cec5SDimitry Andric 37170b57cec5SDimitry Andric_LIBCPP_POP_MACROS 37180b57cec5SDimitry Andric 3719bdd1243dSDimitry Andric// NOLINTEND(libcpp-robust-against-adl) 3720bdd1243dSDimitry Andric 3721bdd1243dSDimitry Andric#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 3722bdd1243dSDimitry Andric# include <atomic> 3723bdd1243dSDimitry Andric# include <concepts> 3724bdd1243dSDimitry Andric# include <cstdarg> 3725bdd1243dSDimitry Andric# include <iterator> 37265f757f3fSDimitry Andric# include <mutex> 3727bdd1243dSDimitry Andric# include <stdexcept> 3728bdd1243dSDimitry Andric# include <type_traits> 3729bdd1243dSDimitry Andric# include <typeinfo> 3730bdd1243dSDimitry Andric#endif 3731bdd1243dSDimitry Andric 37320b57cec5SDimitry Andric#endif // _LIBCPP_LOCALE 3733