1*0b57cec5SDimitry Andric// -*- C++ -*- 2*0b57cec5SDimitry Andric//===-------------------------- locale ------------------------------------===// 3*0b57cec5SDimitry Andric// 4*0b57cec5SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5*0b57cec5SDimitry Andric// See https://llvm.org/LICENSE.txt for license information. 6*0b57cec5SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7*0b57cec5SDimitry Andric// 8*0b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 9*0b57cec5SDimitry Andric 10*0b57cec5SDimitry Andric#ifndef _LIBCPP_LOCALE 11*0b57cec5SDimitry Andric#define _LIBCPP_LOCALE 12*0b57cec5SDimitry Andric 13*0b57cec5SDimitry Andric/* 14*0b57cec5SDimitry Andric locale synopsis 15*0b57cec5SDimitry Andric 16*0b57cec5SDimitry Andricnamespace std 17*0b57cec5SDimitry Andric{ 18*0b57cec5SDimitry Andric 19*0b57cec5SDimitry Andricclass locale 20*0b57cec5SDimitry Andric{ 21*0b57cec5SDimitry Andricpublic: 22*0b57cec5SDimitry Andric // types: 23*0b57cec5SDimitry Andric class facet; 24*0b57cec5SDimitry Andric class id; 25*0b57cec5SDimitry Andric 26*0b57cec5SDimitry Andric typedef int category; 27*0b57cec5SDimitry Andric static const category // values assigned here are for exposition only 28*0b57cec5SDimitry Andric none = 0x000, 29*0b57cec5SDimitry Andric collate = 0x010, 30*0b57cec5SDimitry Andric ctype = 0x020, 31*0b57cec5SDimitry Andric monetary = 0x040, 32*0b57cec5SDimitry Andric numeric = 0x080, 33*0b57cec5SDimitry Andric time = 0x100, 34*0b57cec5SDimitry Andric messages = 0x200, 35*0b57cec5SDimitry Andric all = collate | ctype | monetary | numeric | time | messages; 36*0b57cec5SDimitry Andric 37*0b57cec5SDimitry Andric // construct/copy/destroy: 38*0b57cec5SDimitry Andric locale() noexcept; 39*0b57cec5SDimitry Andric locale(const locale& other) noexcept; 40*0b57cec5SDimitry Andric explicit locale(const char* std_name); 41*0b57cec5SDimitry Andric explicit locale(const string& std_name); 42*0b57cec5SDimitry Andric locale(const locale& other, const char* std_name, category); 43*0b57cec5SDimitry Andric locale(const locale& other, const string& std_name, category); 44*0b57cec5SDimitry Andric template <class Facet> locale(const locale& other, Facet* f); 45*0b57cec5SDimitry Andric locale(const locale& other, const locale& one, category); 46*0b57cec5SDimitry Andric 47*0b57cec5SDimitry Andric ~locale(); // not virtual 48*0b57cec5SDimitry Andric 49*0b57cec5SDimitry Andric const locale& operator=(const locale& other) noexcept; 50*0b57cec5SDimitry Andric 51*0b57cec5SDimitry Andric template <class Facet> locale combine(const locale& other) const; 52*0b57cec5SDimitry Andric 53*0b57cec5SDimitry Andric // locale operations: 54*0b57cec5SDimitry Andric basic_string<char> name() const; 55*0b57cec5SDimitry Andric bool operator==(const locale& other) const; 56*0b57cec5SDimitry Andric bool operator!=(const locale& other) const; 57*0b57cec5SDimitry Andric template <class charT, class Traits, class Allocator> 58*0b57cec5SDimitry Andric bool operator()(const basic_string<charT,Traits,Allocator>& s1, 59*0b57cec5SDimitry Andric const basic_string<charT,Traits,Allocator>& s2) const; 60*0b57cec5SDimitry Andric 61*0b57cec5SDimitry Andric // global locale objects: 62*0b57cec5SDimitry Andric static locale global(const locale&); 63*0b57cec5SDimitry Andric static const locale& classic(); 64*0b57cec5SDimitry Andric}; 65*0b57cec5SDimitry Andric 66*0b57cec5SDimitry Andrictemplate <class Facet> const Facet& use_facet(const locale&); 67*0b57cec5SDimitry Andrictemplate <class Facet> bool has_facet(const locale&) noexcept; 68*0b57cec5SDimitry Andric 69*0b57cec5SDimitry Andric// 22.3.3, convenience interfaces: 70*0b57cec5SDimitry Andrictemplate <class charT> bool isspace (charT c, const locale& loc); 71*0b57cec5SDimitry Andrictemplate <class charT> bool isprint (charT c, const locale& loc); 72*0b57cec5SDimitry Andrictemplate <class charT> bool iscntrl (charT c, const locale& loc); 73*0b57cec5SDimitry Andrictemplate <class charT> bool isupper (charT c, const locale& loc); 74*0b57cec5SDimitry Andrictemplate <class charT> bool islower (charT c, const locale& loc); 75*0b57cec5SDimitry Andrictemplate <class charT> bool isalpha (charT c, const locale& loc); 76*0b57cec5SDimitry Andrictemplate <class charT> bool isdigit (charT c, const locale& loc); 77*0b57cec5SDimitry Andrictemplate <class charT> bool ispunct (charT c, const locale& loc); 78*0b57cec5SDimitry Andrictemplate <class charT> bool isxdigit(charT c, const locale& loc); 79*0b57cec5SDimitry Andrictemplate <class charT> bool isalnum (charT c, const locale& loc); 80*0b57cec5SDimitry Andrictemplate <class charT> bool isgraph (charT c, const locale& loc); 81*0b57cec5SDimitry Andrictemplate <class charT> charT toupper(charT c, const locale& loc); 82*0b57cec5SDimitry Andrictemplate <class charT> charT tolower(charT c, const locale& loc); 83*0b57cec5SDimitry Andric 84*0b57cec5SDimitry Andrictemplate<class Codecvt, class Elem = wchar_t, 85*0b57cec5SDimitry Andric class Wide_alloc = allocator<Elem>, 86*0b57cec5SDimitry Andric class Byte_alloc = allocator<char>> 87*0b57cec5SDimitry Andricclass wstring_convert 88*0b57cec5SDimitry Andric{ 89*0b57cec5SDimitry Andricpublic: 90*0b57cec5SDimitry Andric typedef basic_string<char, char_traits<char>, Byte_alloc> byte_string; 91*0b57cec5SDimitry Andric typedef basic_string<Elem, char_traits<Elem>, Wide_alloc> wide_string; 92*0b57cec5SDimitry Andric typedef typename Codecvt::state_type state_type; 93*0b57cec5SDimitry Andric typedef typename wide_string::traits_type::int_type int_type; 94*0b57cec5SDimitry Andric 95*0b57cec5SDimitry Andric explicit wstring_convert(Codecvt* pcvt = new Codecvt); // explicit in C++14 96*0b57cec5SDimitry Andric wstring_convert(Codecvt* pcvt, state_type state); 97*0b57cec5SDimitry Andric explicit wstring_convert(const byte_string& byte_err, // explicit in C++14 98*0b57cec5SDimitry Andric const wide_string& wide_err = wide_string()); 99*0b57cec5SDimitry Andric wstring_convert(const wstring_convert&) = delete; // C++14 100*0b57cec5SDimitry Andric wstring_convert & operator=(const wstring_convert &) = delete; // C++14 101*0b57cec5SDimitry Andric ~wstring_convert(); 102*0b57cec5SDimitry Andric 103*0b57cec5SDimitry Andric wide_string from_bytes(char byte); 104*0b57cec5SDimitry Andric wide_string from_bytes(const char* ptr); 105*0b57cec5SDimitry Andric wide_string from_bytes(const byte_string& str); 106*0b57cec5SDimitry Andric wide_string from_bytes(const char* first, const char* last); 107*0b57cec5SDimitry Andric 108*0b57cec5SDimitry Andric byte_string to_bytes(Elem wchar); 109*0b57cec5SDimitry Andric byte_string to_bytes(const Elem* wptr); 110*0b57cec5SDimitry Andric byte_string to_bytes(const wide_string& wstr); 111*0b57cec5SDimitry Andric byte_string to_bytes(const Elem* first, const Elem* last); 112*0b57cec5SDimitry Andric 113*0b57cec5SDimitry Andric size_t converted() const; // noexcept in C++14 114*0b57cec5SDimitry Andric state_type state() const; 115*0b57cec5SDimitry Andric}; 116*0b57cec5SDimitry Andric 117*0b57cec5SDimitry Andrictemplate <class Codecvt, class Elem = wchar_t, class Tr = char_traits<Elem>> 118*0b57cec5SDimitry Andricclass wbuffer_convert 119*0b57cec5SDimitry Andric : public basic_streambuf<Elem, Tr> 120*0b57cec5SDimitry Andric{ 121*0b57cec5SDimitry Andricpublic: 122*0b57cec5SDimitry Andric typedef typename Tr::state_type state_type; 123*0b57cec5SDimitry Andric 124*0b57cec5SDimitry Andric explicit wbuffer_convert(streambuf* bytebuf = 0, Codecvt* pcvt = new Codecvt, 125*0b57cec5SDimitry Andric state_type state = state_type()); // explicit in C++14 126*0b57cec5SDimitry Andric wbuffer_convert(const wbuffer_convert&) = delete; // C++14 127*0b57cec5SDimitry Andric wbuffer_convert & operator=(const wbuffer_convert &) = delete; // C++14 128*0b57cec5SDimitry Andric ~wbuffer_convert(); // C++14 129*0b57cec5SDimitry Andric 130*0b57cec5SDimitry Andric streambuf* rdbuf() const; 131*0b57cec5SDimitry Andric streambuf* rdbuf(streambuf* bytebuf); 132*0b57cec5SDimitry Andric 133*0b57cec5SDimitry Andric state_type state() const; 134*0b57cec5SDimitry Andric}; 135*0b57cec5SDimitry Andric 136*0b57cec5SDimitry Andric// 22.4.1 and 22.4.1.3, ctype: 137*0b57cec5SDimitry Andricclass ctype_base; 138*0b57cec5SDimitry Andrictemplate <class charT> class ctype; 139*0b57cec5SDimitry Andrictemplate <> class ctype<char>; // specialization 140*0b57cec5SDimitry Andrictemplate <class charT> class ctype_byname; 141*0b57cec5SDimitry Andrictemplate <> class ctype_byname<char>; // specialization 142*0b57cec5SDimitry Andric 143*0b57cec5SDimitry Andricclass codecvt_base; 144*0b57cec5SDimitry Andrictemplate <class internT, class externT, class stateT> class codecvt; 145*0b57cec5SDimitry Andrictemplate <class internT, class externT, class stateT> class codecvt_byname; 146*0b57cec5SDimitry Andric 147*0b57cec5SDimitry Andric// 22.4.2 and 22.4.3, numeric: 148*0b57cec5SDimitry Andrictemplate <class charT, class InputIterator> class num_get; 149*0b57cec5SDimitry Andrictemplate <class charT, class OutputIterator> class num_put; 150*0b57cec5SDimitry Andrictemplate <class charT> class numpunct; 151*0b57cec5SDimitry Andrictemplate <class charT> class numpunct_byname; 152*0b57cec5SDimitry Andric 153*0b57cec5SDimitry Andric// 22.4.4, col lation: 154*0b57cec5SDimitry Andrictemplate <class charT> class collate; 155*0b57cec5SDimitry Andrictemplate <class charT> class collate_byname; 156*0b57cec5SDimitry Andric 157*0b57cec5SDimitry Andric// 22.4.5, date and time: 158*0b57cec5SDimitry Andricclass time_base; 159*0b57cec5SDimitry Andrictemplate <class charT, class InputIterator> class time_get; 160*0b57cec5SDimitry Andrictemplate <class charT, class InputIterator> class time_get_byname; 161*0b57cec5SDimitry Andrictemplate <class charT, class OutputIterator> class time_put; 162*0b57cec5SDimitry Andrictemplate <class charT, class OutputIterator> class time_put_byname; 163*0b57cec5SDimitry Andric 164*0b57cec5SDimitry Andric// 22.4.6, money: 165*0b57cec5SDimitry Andricclass money_base; 166*0b57cec5SDimitry Andrictemplate <class charT, class InputIterator> class money_get; 167*0b57cec5SDimitry Andrictemplate <class charT, class OutputIterator> class money_put; 168*0b57cec5SDimitry Andrictemplate <class charT, bool Intl> class moneypunct; 169*0b57cec5SDimitry Andrictemplate <class charT, bool Intl> class moneypunct_byname; 170*0b57cec5SDimitry Andric 171*0b57cec5SDimitry Andric// 22.4.7, message retrieval: 172*0b57cec5SDimitry Andricclass messages_base; 173*0b57cec5SDimitry Andrictemplate <class charT> class messages; 174*0b57cec5SDimitry Andrictemplate <class charT> class messages_byname; 175*0b57cec5SDimitry Andric 176*0b57cec5SDimitry Andric} // std 177*0b57cec5SDimitry Andric 178*0b57cec5SDimitry Andric*/ 179*0b57cec5SDimitry Andric 180*0b57cec5SDimitry Andric#include <__config> 181*0b57cec5SDimitry Andric#include <__locale> 182*0b57cec5SDimitry Andric#include <__debug> 183*0b57cec5SDimitry Andric#include <algorithm> 184*0b57cec5SDimitry Andric#include <memory> 185*0b57cec5SDimitry Andric#include <ios> 186*0b57cec5SDimitry Andric#include <streambuf> 187*0b57cec5SDimitry Andric#include <iterator> 188*0b57cec5SDimitry Andric#include <limits> 189*0b57cec5SDimitry Andric#include <version> 190*0b57cec5SDimitry Andric#ifndef __APPLE__ 191*0b57cec5SDimitry Andric#include <cstdarg> 192*0b57cec5SDimitry Andric#endif 193*0b57cec5SDimitry Andric#include <cstdlib> 194*0b57cec5SDimitry Andric#include <ctime> 195*0b57cec5SDimitry Andric#include <cstdio> 196*0b57cec5SDimitry Andric#ifdef _LIBCPP_HAS_CATOPEN 197*0b57cec5SDimitry Andric#include <nl_types.h> 198*0b57cec5SDimitry Andric#endif 199*0b57cec5SDimitry Andric 200*0b57cec5SDimitry Andric#ifdef __APPLE__ 201*0b57cec5SDimitry Andric#include <Availability.h> 202*0b57cec5SDimitry Andric#endif 203*0b57cec5SDimitry Andric 204*0b57cec5SDimitry Andric#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 205*0b57cec5SDimitry Andric#include <__bsd_locale_defaults.h> 206*0b57cec5SDimitry Andric#else 207*0b57cec5SDimitry Andric#include <__bsd_locale_fallbacks.h> 208*0b57cec5SDimitry Andric#endif 209*0b57cec5SDimitry Andric 210*0b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 211*0b57cec5SDimitry Andric#pragma GCC system_header 212*0b57cec5SDimitry Andric#endif 213*0b57cec5SDimitry Andric 214*0b57cec5SDimitry Andric_LIBCPP_PUSH_MACROS 215*0b57cec5SDimitry Andric#include <__undef_macros> 216*0b57cec5SDimitry Andric 217*0b57cec5SDimitry Andric 218*0b57cec5SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD 219*0b57cec5SDimitry Andric 220*0b57cec5SDimitry Andric#if defined(__APPLE__) || defined(__FreeBSD__) 221*0b57cec5SDimitry Andric# define _LIBCPP_GET_C_LOCALE 0 222*0b57cec5SDimitry Andric#elif defined(__CloudABI__) || defined(__NetBSD__) 223*0b57cec5SDimitry Andric# define _LIBCPP_GET_C_LOCALE LC_C_LOCALE 224*0b57cec5SDimitry Andric#else 225*0b57cec5SDimitry Andric# define _LIBCPP_GET_C_LOCALE __cloc() 226*0b57cec5SDimitry Andric // Get the C locale object 227*0b57cec5SDimitry Andric _LIBCPP_FUNC_VIS locale_t __cloc(); 228*0b57cec5SDimitry Andric#define __cloc_defined 229*0b57cec5SDimitry Andric#endif 230*0b57cec5SDimitry Andric 231*0b57cec5SDimitry Andric// __scan_keyword 232*0b57cec5SDimitry Andric// Scans [__b, __e) until a match is found in the basic_strings range 233*0b57cec5SDimitry Andric// [__kb, __ke) or until it can be shown that there is no match in [__kb, __ke). 234*0b57cec5SDimitry Andric// __b will be incremented (visibly), consuming CharT until a match is found 235*0b57cec5SDimitry Andric// or proved to not exist. A keyword may be "", in which will match anything. 236*0b57cec5SDimitry Andric// If one keyword is a prefix of another, and the next CharT in the input 237*0b57cec5SDimitry Andric// might match another keyword, the algorithm will attempt to find the longest 238*0b57cec5SDimitry Andric// matching keyword. If the longer matching keyword ends up not matching, then 239*0b57cec5SDimitry Andric// no keyword match is found. If no keyword match is found, __ke is returned 240*0b57cec5SDimitry Andric// and failbit is set in __err. 241*0b57cec5SDimitry Andric// Else an iterator pointing to the matching keyword is found. If more than 242*0b57cec5SDimitry Andric// one keyword matches, an iterator to the first matching keyword is returned. 243*0b57cec5SDimitry Andric// If on exit __b == __e, eofbit is set in __err. If __case_sensitive is false, 244*0b57cec5SDimitry Andric// __ct is used to force to lower case before comparing characters. 245*0b57cec5SDimitry Andric// Examples: 246*0b57cec5SDimitry Andric// Keywords: "a", "abb" 247*0b57cec5SDimitry Andric// If the input is "a", the first keyword matches and eofbit is set. 248*0b57cec5SDimitry Andric// If the input is "abc", no match is found and "ab" are consumed. 249*0b57cec5SDimitry Andrictemplate <class _InputIterator, class _ForwardIterator, class _Ctype> 250*0b57cec5SDimitry Andric_LIBCPP_HIDDEN 251*0b57cec5SDimitry Andric_ForwardIterator 252*0b57cec5SDimitry Andric__scan_keyword(_InputIterator& __b, _InputIterator __e, 253*0b57cec5SDimitry Andric _ForwardIterator __kb, _ForwardIterator __ke, 254*0b57cec5SDimitry Andric const _Ctype& __ct, ios_base::iostate& __err, 255*0b57cec5SDimitry Andric bool __case_sensitive = true) 256*0b57cec5SDimitry Andric{ 257*0b57cec5SDimitry Andric typedef typename iterator_traits<_InputIterator>::value_type _CharT; 258*0b57cec5SDimitry Andric size_t __nkw = static_cast<size_t>(_VSTD::distance(__kb, __ke)); 259*0b57cec5SDimitry Andric const unsigned char __doesnt_match = '\0'; 260*0b57cec5SDimitry Andric const unsigned char __might_match = '\1'; 261*0b57cec5SDimitry Andric const unsigned char __does_match = '\2'; 262*0b57cec5SDimitry Andric unsigned char __statbuf[100]; 263*0b57cec5SDimitry Andric unsigned char* __status = __statbuf; 264*0b57cec5SDimitry Andric unique_ptr<unsigned char, void(*)(void*)> __stat_hold(0, free); 265*0b57cec5SDimitry Andric if (__nkw > sizeof(__statbuf)) 266*0b57cec5SDimitry Andric { 267*0b57cec5SDimitry Andric __status = (unsigned char*)malloc(__nkw); 268*0b57cec5SDimitry Andric if (__status == 0) 269*0b57cec5SDimitry Andric __throw_bad_alloc(); 270*0b57cec5SDimitry Andric __stat_hold.reset(__status); 271*0b57cec5SDimitry Andric } 272*0b57cec5SDimitry Andric size_t __n_might_match = __nkw; // At this point, any keyword might match 273*0b57cec5SDimitry Andric size_t __n_does_match = 0; // but none of them definitely do 274*0b57cec5SDimitry Andric // Initialize all statuses to __might_match, except for "" keywords are __does_match 275*0b57cec5SDimitry Andric unsigned char* __st = __status; 276*0b57cec5SDimitry Andric for (_ForwardIterator __ky = __kb; __ky != __ke; ++__ky, (void) ++__st) 277*0b57cec5SDimitry Andric { 278*0b57cec5SDimitry Andric if (!__ky->empty()) 279*0b57cec5SDimitry Andric *__st = __might_match; 280*0b57cec5SDimitry Andric else 281*0b57cec5SDimitry Andric { 282*0b57cec5SDimitry Andric *__st = __does_match; 283*0b57cec5SDimitry Andric --__n_might_match; 284*0b57cec5SDimitry Andric ++__n_does_match; 285*0b57cec5SDimitry Andric } 286*0b57cec5SDimitry Andric } 287*0b57cec5SDimitry Andric // While there might be a match, test keywords against the next CharT 288*0b57cec5SDimitry Andric for (size_t __indx = 0; __b != __e && __n_might_match > 0; ++__indx) 289*0b57cec5SDimitry Andric { 290*0b57cec5SDimitry Andric // Peek at the next CharT but don't consume it 291*0b57cec5SDimitry Andric _CharT __c = *__b; 292*0b57cec5SDimitry Andric if (!__case_sensitive) 293*0b57cec5SDimitry Andric __c = __ct.toupper(__c); 294*0b57cec5SDimitry Andric bool __consume = false; 295*0b57cec5SDimitry Andric // For each keyword which might match, see if the __indx character is __c 296*0b57cec5SDimitry Andric // If a match if found, consume __c 297*0b57cec5SDimitry Andric // If a match is found, and that is the last character in the keyword, 298*0b57cec5SDimitry Andric // then that keyword matches. 299*0b57cec5SDimitry Andric // If the keyword doesn't match this character, then change the keyword 300*0b57cec5SDimitry Andric // to doesn't match 301*0b57cec5SDimitry Andric __st = __status; 302*0b57cec5SDimitry Andric for (_ForwardIterator __ky = __kb; __ky != __ke; ++__ky, (void) ++__st) 303*0b57cec5SDimitry Andric { 304*0b57cec5SDimitry Andric if (*__st == __might_match) 305*0b57cec5SDimitry Andric { 306*0b57cec5SDimitry Andric _CharT __kc = (*__ky)[__indx]; 307*0b57cec5SDimitry Andric if (!__case_sensitive) 308*0b57cec5SDimitry Andric __kc = __ct.toupper(__kc); 309*0b57cec5SDimitry Andric if (__c == __kc) 310*0b57cec5SDimitry Andric { 311*0b57cec5SDimitry Andric __consume = true; 312*0b57cec5SDimitry Andric if (__ky->size() == __indx+1) 313*0b57cec5SDimitry Andric { 314*0b57cec5SDimitry Andric *__st = __does_match; 315*0b57cec5SDimitry Andric --__n_might_match; 316*0b57cec5SDimitry Andric ++__n_does_match; 317*0b57cec5SDimitry Andric } 318*0b57cec5SDimitry Andric } 319*0b57cec5SDimitry Andric else 320*0b57cec5SDimitry Andric { 321*0b57cec5SDimitry Andric *__st = __doesnt_match; 322*0b57cec5SDimitry Andric --__n_might_match; 323*0b57cec5SDimitry Andric } 324*0b57cec5SDimitry Andric } 325*0b57cec5SDimitry Andric } 326*0b57cec5SDimitry Andric // consume if we matched a character 327*0b57cec5SDimitry Andric if (__consume) 328*0b57cec5SDimitry Andric { 329*0b57cec5SDimitry Andric ++__b; 330*0b57cec5SDimitry Andric // If we consumed a character and there might be a matched keyword that 331*0b57cec5SDimitry Andric // was marked matched on a previous iteration, then such keywords 332*0b57cec5SDimitry Andric // which are now marked as not matching. 333*0b57cec5SDimitry Andric if (__n_might_match + __n_does_match > 1) 334*0b57cec5SDimitry Andric { 335*0b57cec5SDimitry Andric __st = __status; 336*0b57cec5SDimitry Andric for (_ForwardIterator __ky = __kb; __ky != __ke; ++__ky, (void) ++__st) 337*0b57cec5SDimitry Andric { 338*0b57cec5SDimitry Andric if (*__st == __does_match && __ky->size() != __indx+1) 339*0b57cec5SDimitry Andric { 340*0b57cec5SDimitry Andric *__st = __doesnt_match; 341*0b57cec5SDimitry Andric --__n_does_match; 342*0b57cec5SDimitry Andric } 343*0b57cec5SDimitry Andric } 344*0b57cec5SDimitry Andric } 345*0b57cec5SDimitry Andric } 346*0b57cec5SDimitry Andric } 347*0b57cec5SDimitry Andric // We've exited the loop because we hit eof and/or we have no more "might matches". 348*0b57cec5SDimitry Andric if (__b == __e) 349*0b57cec5SDimitry Andric __err |= ios_base::eofbit; 350*0b57cec5SDimitry Andric // Return the first matching result 351*0b57cec5SDimitry Andric for (__st = __status; __kb != __ke; ++__kb, (void) ++__st) 352*0b57cec5SDimitry Andric if (*__st == __does_match) 353*0b57cec5SDimitry Andric break; 354*0b57cec5SDimitry Andric if (__kb == __ke) 355*0b57cec5SDimitry Andric __err |= ios_base::failbit; 356*0b57cec5SDimitry Andric return __kb; 357*0b57cec5SDimitry Andric} 358*0b57cec5SDimitry Andric 359*0b57cec5SDimitry Andricstruct _LIBCPP_TYPE_VIS __num_get_base 360*0b57cec5SDimitry Andric{ 361*0b57cec5SDimitry Andric static const int __num_get_buf_sz = 40; 362*0b57cec5SDimitry Andric 363*0b57cec5SDimitry Andric static int __get_base(ios_base&); 364*0b57cec5SDimitry Andric static const char __src[33]; 365*0b57cec5SDimitry Andric}; 366*0b57cec5SDimitry Andric 367*0b57cec5SDimitry Andric_LIBCPP_FUNC_VIS 368*0b57cec5SDimitry Andricvoid __check_grouping(const string& __grouping, unsigned* __g, unsigned* __g_end, 369*0b57cec5SDimitry Andric ios_base::iostate& __err); 370*0b57cec5SDimitry Andric 371*0b57cec5SDimitry Andrictemplate <class _CharT> 372*0b57cec5SDimitry Andricstruct __num_get 373*0b57cec5SDimitry Andric : protected __num_get_base 374*0b57cec5SDimitry Andric{ 375*0b57cec5SDimitry Andric static string __stage2_float_prep(ios_base& __iob, _CharT* __atoms, _CharT& __decimal_point, 376*0b57cec5SDimitry Andric _CharT& __thousands_sep); 377*0b57cec5SDimitry Andric 378*0b57cec5SDimitry Andric static int __stage2_float_loop(_CharT __ct, bool& __in_units, char& __exp, 379*0b57cec5SDimitry Andric char* __a, char*& __a_end, 380*0b57cec5SDimitry Andric _CharT __decimal_point, _CharT __thousands_sep, 381*0b57cec5SDimitry Andric const string& __grouping, unsigned* __g, 382*0b57cec5SDimitry Andric unsigned*& __g_end, unsigned& __dc, _CharT* __atoms); 383*0b57cec5SDimitry Andric#ifndef _LIBCPP_ABI_OPTIMIZED_LOCALE_NUM_GET 384*0b57cec5SDimitry Andric static string __stage2_int_prep(ios_base& __iob, _CharT* __atoms, _CharT& __thousands_sep); 385*0b57cec5SDimitry Andric static int __stage2_int_loop(_CharT __ct, int __base, char* __a, char*& __a_end, 386*0b57cec5SDimitry Andric unsigned& __dc, _CharT __thousands_sep, const string& __grouping, 387*0b57cec5SDimitry Andric unsigned* __g, unsigned*& __g_end, _CharT* __atoms); 388*0b57cec5SDimitry Andric 389*0b57cec5SDimitry Andric#else 390*0b57cec5SDimitry Andric static string __stage2_int_prep(ios_base& __iob, _CharT& __thousands_sep) 391*0b57cec5SDimitry Andric { 392*0b57cec5SDimitry Andric locale __loc = __iob.getloc(); 393*0b57cec5SDimitry Andric const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc); 394*0b57cec5SDimitry Andric __thousands_sep = __np.thousands_sep(); 395*0b57cec5SDimitry Andric return __np.grouping(); 396*0b57cec5SDimitry Andric } 397*0b57cec5SDimitry Andric 398*0b57cec5SDimitry Andric const _CharT* __do_widen(ios_base& __iob, _CharT* __atoms) const 399*0b57cec5SDimitry Andric { 400*0b57cec5SDimitry Andric return __do_widen_p(__iob, __atoms); 401*0b57cec5SDimitry Andric } 402*0b57cec5SDimitry Andric 403*0b57cec5SDimitry Andric 404*0b57cec5SDimitry Andric static int __stage2_int_loop(_CharT __ct, int __base, char* __a, char*& __a_end, 405*0b57cec5SDimitry Andric unsigned& __dc, _CharT __thousands_sep, const string& __grouping, 406*0b57cec5SDimitry Andric unsigned* __g, unsigned*& __g_end, const _CharT* __atoms); 407*0b57cec5SDimitry Andricprivate: 408*0b57cec5SDimitry Andric template<typename T> 409*0b57cec5SDimitry Andric const T* __do_widen_p(ios_base& __iob, T* __atoms) const 410*0b57cec5SDimitry Andric { 411*0b57cec5SDimitry Andric locale __loc = __iob.getloc(); 412*0b57cec5SDimitry Andric use_facet<ctype<T> >(__loc).widen(__src, __src + 26, __atoms); 413*0b57cec5SDimitry Andric return __atoms; 414*0b57cec5SDimitry Andric } 415*0b57cec5SDimitry Andric 416*0b57cec5SDimitry Andric const char* __do_widen_p(ios_base& __iob, char* __atoms) const 417*0b57cec5SDimitry Andric { 418*0b57cec5SDimitry Andric (void)__iob; 419*0b57cec5SDimitry Andric (void)__atoms; 420*0b57cec5SDimitry Andric return __src; 421*0b57cec5SDimitry Andric } 422*0b57cec5SDimitry Andric#endif 423*0b57cec5SDimitry Andric}; 424*0b57cec5SDimitry Andric 425*0b57cec5SDimitry Andric#ifndef _LIBCPP_ABI_OPTIMIZED_LOCALE_NUM_GET 426*0b57cec5SDimitry Andrictemplate <class _CharT> 427*0b57cec5SDimitry Andricstring 428*0b57cec5SDimitry Andric__num_get<_CharT>::__stage2_int_prep(ios_base& __iob, _CharT* __atoms, _CharT& __thousands_sep) 429*0b57cec5SDimitry Andric{ 430*0b57cec5SDimitry Andric locale __loc = __iob.getloc(); 431*0b57cec5SDimitry Andric use_facet<ctype<_CharT> >(__loc).widen(__src, __src + 26, __atoms); 432*0b57cec5SDimitry Andric const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc); 433*0b57cec5SDimitry Andric __thousands_sep = __np.thousands_sep(); 434*0b57cec5SDimitry Andric return __np.grouping(); 435*0b57cec5SDimitry Andric} 436*0b57cec5SDimitry Andric#endif 437*0b57cec5SDimitry Andric 438*0b57cec5SDimitry Andrictemplate <class _CharT> 439*0b57cec5SDimitry Andricstring 440*0b57cec5SDimitry Andric__num_get<_CharT>::__stage2_float_prep(ios_base& __iob, _CharT* __atoms, _CharT& __decimal_point, 441*0b57cec5SDimitry Andric _CharT& __thousands_sep) 442*0b57cec5SDimitry Andric{ 443*0b57cec5SDimitry Andric locale __loc = __iob.getloc(); 444*0b57cec5SDimitry Andric use_facet<ctype<_CharT> >(__loc).widen(__src, __src + 32, __atoms); 445*0b57cec5SDimitry Andric const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc); 446*0b57cec5SDimitry Andric __decimal_point = __np.decimal_point(); 447*0b57cec5SDimitry Andric __thousands_sep = __np.thousands_sep(); 448*0b57cec5SDimitry Andric return __np.grouping(); 449*0b57cec5SDimitry Andric} 450*0b57cec5SDimitry Andric 451*0b57cec5SDimitry Andrictemplate <class _CharT> 452*0b57cec5SDimitry Andricint 453*0b57cec5SDimitry Andric#ifndef _LIBCPP_ABI_OPTIMIZED_LOCALE_NUM_GET 454*0b57cec5SDimitry Andric__num_get<_CharT>::__stage2_int_loop(_CharT __ct, int __base, char* __a, char*& __a_end, 455*0b57cec5SDimitry Andric unsigned& __dc, _CharT __thousands_sep, const string& __grouping, 456*0b57cec5SDimitry Andric unsigned* __g, unsigned*& __g_end, _CharT* __atoms) 457*0b57cec5SDimitry Andric#else 458*0b57cec5SDimitry Andric__num_get<_CharT>::__stage2_int_loop(_CharT __ct, int __base, char* __a, char*& __a_end, 459*0b57cec5SDimitry Andric unsigned& __dc, _CharT __thousands_sep, const string& __grouping, 460*0b57cec5SDimitry Andric unsigned* __g, unsigned*& __g_end, const _CharT* __atoms) 461*0b57cec5SDimitry Andric 462*0b57cec5SDimitry Andric#endif 463*0b57cec5SDimitry Andric{ 464*0b57cec5SDimitry Andric if (__a_end == __a && (__ct == __atoms[24] || __ct == __atoms[25])) 465*0b57cec5SDimitry Andric { 466*0b57cec5SDimitry Andric *__a_end++ = __ct == __atoms[24] ? '+' : '-'; 467*0b57cec5SDimitry Andric __dc = 0; 468*0b57cec5SDimitry Andric return 0; 469*0b57cec5SDimitry Andric } 470*0b57cec5SDimitry Andric if (__grouping.size() != 0 && __ct == __thousands_sep) 471*0b57cec5SDimitry Andric { 472*0b57cec5SDimitry Andric if (__g_end-__g < __num_get_buf_sz) 473*0b57cec5SDimitry Andric { 474*0b57cec5SDimitry Andric *__g_end++ = __dc; 475*0b57cec5SDimitry Andric __dc = 0; 476*0b57cec5SDimitry Andric } 477*0b57cec5SDimitry Andric return 0; 478*0b57cec5SDimitry Andric } 479*0b57cec5SDimitry Andric ptrdiff_t __f = find(__atoms, __atoms + 26, __ct) - __atoms; 480*0b57cec5SDimitry Andric if (__f >= 24) 481*0b57cec5SDimitry Andric return -1; 482*0b57cec5SDimitry Andric switch (__base) 483*0b57cec5SDimitry Andric { 484*0b57cec5SDimitry Andric case 8: 485*0b57cec5SDimitry Andric case 10: 486*0b57cec5SDimitry Andric if (__f >= __base) 487*0b57cec5SDimitry Andric return -1; 488*0b57cec5SDimitry Andric break; 489*0b57cec5SDimitry Andric case 16: 490*0b57cec5SDimitry Andric if (__f < 22) 491*0b57cec5SDimitry Andric break; 492*0b57cec5SDimitry Andric if (__a_end != __a && __a_end - __a <= 2 && __a_end[-1] == '0') 493*0b57cec5SDimitry Andric { 494*0b57cec5SDimitry Andric __dc = 0; 495*0b57cec5SDimitry Andric *__a_end++ = __src[__f]; 496*0b57cec5SDimitry Andric return 0; 497*0b57cec5SDimitry Andric } 498*0b57cec5SDimitry Andric return -1; 499*0b57cec5SDimitry Andric } 500*0b57cec5SDimitry Andric *__a_end++ = __src[__f]; 501*0b57cec5SDimitry Andric ++__dc; 502*0b57cec5SDimitry Andric return 0; 503*0b57cec5SDimitry Andric} 504*0b57cec5SDimitry Andric 505*0b57cec5SDimitry Andrictemplate <class _CharT> 506*0b57cec5SDimitry Andricint 507*0b57cec5SDimitry Andric__num_get<_CharT>::__stage2_float_loop(_CharT __ct, bool& __in_units, char& __exp, char* __a, char*& __a_end, 508*0b57cec5SDimitry Andric _CharT __decimal_point, _CharT __thousands_sep, const string& __grouping, 509*0b57cec5SDimitry Andric unsigned* __g, unsigned*& __g_end, unsigned& __dc, _CharT* __atoms) 510*0b57cec5SDimitry Andric{ 511*0b57cec5SDimitry Andric if (__ct == __decimal_point) 512*0b57cec5SDimitry Andric { 513*0b57cec5SDimitry Andric if (!__in_units) 514*0b57cec5SDimitry Andric return -1; 515*0b57cec5SDimitry Andric __in_units = false; 516*0b57cec5SDimitry Andric *__a_end++ = '.'; 517*0b57cec5SDimitry Andric if (__grouping.size() != 0 && __g_end-__g < __num_get_buf_sz) 518*0b57cec5SDimitry Andric *__g_end++ = __dc; 519*0b57cec5SDimitry Andric return 0; 520*0b57cec5SDimitry Andric } 521*0b57cec5SDimitry Andric if (__ct == __thousands_sep && __grouping.size() != 0) 522*0b57cec5SDimitry Andric { 523*0b57cec5SDimitry Andric if (!__in_units) 524*0b57cec5SDimitry Andric return -1; 525*0b57cec5SDimitry Andric if (__g_end-__g < __num_get_buf_sz) 526*0b57cec5SDimitry Andric { 527*0b57cec5SDimitry Andric *__g_end++ = __dc; 528*0b57cec5SDimitry Andric __dc = 0; 529*0b57cec5SDimitry Andric } 530*0b57cec5SDimitry Andric return 0; 531*0b57cec5SDimitry Andric } 532*0b57cec5SDimitry Andric ptrdiff_t __f = find(__atoms, __atoms + 32, __ct) - __atoms; 533*0b57cec5SDimitry Andric if (__f >= 32) 534*0b57cec5SDimitry Andric return -1; 535*0b57cec5SDimitry Andric char __x = __src[__f]; 536*0b57cec5SDimitry Andric if (__x == '-' || __x == '+') 537*0b57cec5SDimitry Andric { 538*0b57cec5SDimitry Andric if (__a_end == __a || (__a_end[-1] & 0x5F) == (__exp & 0x7F)) 539*0b57cec5SDimitry Andric { 540*0b57cec5SDimitry Andric *__a_end++ = __x; 541*0b57cec5SDimitry Andric return 0; 542*0b57cec5SDimitry Andric } 543*0b57cec5SDimitry Andric return -1; 544*0b57cec5SDimitry Andric } 545*0b57cec5SDimitry Andric if (__x == 'x' || __x == 'X') 546*0b57cec5SDimitry Andric __exp = 'P'; 547*0b57cec5SDimitry Andric else if ((__x & 0x5F) == __exp) 548*0b57cec5SDimitry Andric { 549*0b57cec5SDimitry Andric __exp |= (char) 0x80; 550*0b57cec5SDimitry Andric if (__in_units) 551*0b57cec5SDimitry Andric { 552*0b57cec5SDimitry Andric __in_units = false; 553*0b57cec5SDimitry Andric if (__grouping.size() != 0 && __g_end-__g < __num_get_buf_sz) 554*0b57cec5SDimitry Andric *__g_end++ = __dc; 555*0b57cec5SDimitry Andric } 556*0b57cec5SDimitry Andric } 557*0b57cec5SDimitry Andric *__a_end++ = __x; 558*0b57cec5SDimitry Andric if (__f >= 22) 559*0b57cec5SDimitry Andric return 0; 560*0b57cec5SDimitry Andric ++__dc; 561*0b57cec5SDimitry Andric return 0; 562*0b57cec5SDimitry Andric} 563*0b57cec5SDimitry Andric 564*0b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE2(struct _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __num_get<char>) 565*0b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE2(struct _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __num_get<wchar_t>) 566*0b57cec5SDimitry Andric 567*0b57cec5SDimitry Andrictemplate <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> > 568*0b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS num_get 569*0b57cec5SDimitry Andric : public locale::facet, 570*0b57cec5SDimitry Andric private __num_get<_CharT> 571*0b57cec5SDimitry Andric{ 572*0b57cec5SDimitry Andricpublic: 573*0b57cec5SDimitry Andric typedef _CharT char_type; 574*0b57cec5SDimitry Andric typedef _InputIterator iter_type; 575*0b57cec5SDimitry Andric 576*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 577*0b57cec5SDimitry Andric explicit num_get(size_t __refs = 0) 578*0b57cec5SDimitry Andric : locale::facet(__refs) {} 579*0b57cec5SDimitry Andric 580*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 581*0b57cec5SDimitry Andric iter_type get(iter_type __b, iter_type __e, ios_base& __iob, 582*0b57cec5SDimitry Andric ios_base::iostate& __err, bool& __v) const 583*0b57cec5SDimitry Andric { 584*0b57cec5SDimitry Andric return do_get(__b, __e, __iob, __err, __v); 585*0b57cec5SDimitry Andric } 586*0b57cec5SDimitry Andric 587*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 588*0b57cec5SDimitry Andric iter_type get(iter_type __b, iter_type __e, ios_base& __iob, 589*0b57cec5SDimitry Andric ios_base::iostate& __err, long& __v) const 590*0b57cec5SDimitry Andric { 591*0b57cec5SDimitry Andric return do_get(__b, __e, __iob, __err, __v); 592*0b57cec5SDimitry Andric } 593*0b57cec5SDimitry Andric 594*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 595*0b57cec5SDimitry Andric iter_type get(iter_type __b, iter_type __e, ios_base& __iob, 596*0b57cec5SDimitry Andric ios_base::iostate& __err, long long& __v) const 597*0b57cec5SDimitry Andric { 598*0b57cec5SDimitry Andric return do_get(__b, __e, __iob, __err, __v); 599*0b57cec5SDimitry Andric } 600*0b57cec5SDimitry Andric 601*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 602*0b57cec5SDimitry Andric iter_type get(iter_type __b, iter_type __e, ios_base& __iob, 603*0b57cec5SDimitry Andric ios_base::iostate& __err, unsigned short& __v) const 604*0b57cec5SDimitry Andric { 605*0b57cec5SDimitry Andric return do_get(__b, __e, __iob, __err, __v); 606*0b57cec5SDimitry Andric } 607*0b57cec5SDimitry Andric 608*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 609*0b57cec5SDimitry Andric iter_type get(iter_type __b, iter_type __e, ios_base& __iob, 610*0b57cec5SDimitry Andric ios_base::iostate& __err, unsigned int& __v) const 611*0b57cec5SDimitry Andric { 612*0b57cec5SDimitry Andric return do_get(__b, __e, __iob, __err, __v); 613*0b57cec5SDimitry Andric } 614*0b57cec5SDimitry Andric 615*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 616*0b57cec5SDimitry Andric iter_type get(iter_type __b, iter_type __e, ios_base& __iob, 617*0b57cec5SDimitry Andric ios_base::iostate& __err, unsigned long& __v) const 618*0b57cec5SDimitry Andric { 619*0b57cec5SDimitry Andric return do_get(__b, __e, __iob, __err, __v); 620*0b57cec5SDimitry Andric } 621*0b57cec5SDimitry Andric 622*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 623*0b57cec5SDimitry Andric iter_type get(iter_type __b, iter_type __e, ios_base& __iob, 624*0b57cec5SDimitry Andric ios_base::iostate& __err, unsigned long long& __v) const 625*0b57cec5SDimitry Andric { 626*0b57cec5SDimitry Andric return do_get(__b, __e, __iob, __err, __v); 627*0b57cec5SDimitry Andric } 628*0b57cec5SDimitry Andric 629*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 630*0b57cec5SDimitry Andric iter_type get(iter_type __b, iter_type __e, ios_base& __iob, 631*0b57cec5SDimitry Andric ios_base::iostate& __err, float& __v) const 632*0b57cec5SDimitry Andric { 633*0b57cec5SDimitry Andric return do_get(__b, __e, __iob, __err, __v); 634*0b57cec5SDimitry Andric } 635*0b57cec5SDimitry Andric 636*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 637*0b57cec5SDimitry Andric iter_type get(iter_type __b, iter_type __e, ios_base& __iob, 638*0b57cec5SDimitry Andric ios_base::iostate& __err, double& __v) const 639*0b57cec5SDimitry Andric { 640*0b57cec5SDimitry Andric return do_get(__b, __e, __iob, __err, __v); 641*0b57cec5SDimitry Andric } 642*0b57cec5SDimitry Andric 643*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 644*0b57cec5SDimitry Andric iter_type get(iter_type __b, iter_type __e, ios_base& __iob, 645*0b57cec5SDimitry Andric ios_base::iostate& __err, long double& __v) const 646*0b57cec5SDimitry Andric { 647*0b57cec5SDimitry Andric return do_get(__b, __e, __iob, __err, __v); 648*0b57cec5SDimitry Andric } 649*0b57cec5SDimitry Andric 650*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 651*0b57cec5SDimitry Andric iter_type get(iter_type __b, iter_type __e, ios_base& __iob, 652*0b57cec5SDimitry Andric ios_base::iostate& __err, void*& __v) const 653*0b57cec5SDimitry Andric { 654*0b57cec5SDimitry Andric return do_get(__b, __e, __iob, __err, __v); 655*0b57cec5SDimitry Andric } 656*0b57cec5SDimitry Andric 657*0b57cec5SDimitry Andric static locale::id id; 658*0b57cec5SDimitry Andric 659*0b57cec5SDimitry Andricprotected: 660*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 661*0b57cec5SDimitry Andric ~num_get() {} 662*0b57cec5SDimitry Andric 663*0b57cec5SDimitry Andric template <class _Fp> 664*0b57cec5SDimitry Andric _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS 665*0b57cec5SDimitry Andric iter_type __do_get_floating_point 666*0b57cec5SDimitry Andric (iter_type __b, iter_type __e, ios_base& __iob, 667*0b57cec5SDimitry Andric ios_base::iostate& __err, _Fp& __v) const; 668*0b57cec5SDimitry Andric 669*0b57cec5SDimitry Andric template <class _Signed> 670*0b57cec5SDimitry Andric _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS 671*0b57cec5SDimitry Andric iter_type __do_get_signed 672*0b57cec5SDimitry Andric (iter_type __b, iter_type __e, ios_base& __iob, 673*0b57cec5SDimitry Andric ios_base::iostate& __err, _Signed& __v) const; 674*0b57cec5SDimitry Andric 675*0b57cec5SDimitry Andric template <class _Unsigned> 676*0b57cec5SDimitry Andric _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS 677*0b57cec5SDimitry Andric iter_type __do_get_unsigned 678*0b57cec5SDimitry Andric (iter_type __b, iter_type __e, ios_base& __iob, 679*0b57cec5SDimitry Andric ios_base::iostate& __err, _Unsigned& __v) const; 680*0b57cec5SDimitry Andric 681*0b57cec5SDimitry Andric 682*0b57cec5SDimitry Andric virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob, 683*0b57cec5SDimitry Andric ios_base::iostate& __err, bool& __v) const; 684*0b57cec5SDimitry Andric 685*0b57cec5SDimitry Andric virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob, 686*0b57cec5SDimitry Andric ios_base::iostate& __err, long& __v) const 687*0b57cec5SDimitry Andric { return this->__do_get_signed ( __b, __e, __iob, __err, __v ); } 688*0b57cec5SDimitry Andric 689*0b57cec5SDimitry Andric virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob, 690*0b57cec5SDimitry Andric ios_base::iostate& __err, long long& __v) const 691*0b57cec5SDimitry Andric { return this->__do_get_signed ( __b, __e, __iob, __err, __v ); } 692*0b57cec5SDimitry Andric 693*0b57cec5SDimitry Andric virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob, 694*0b57cec5SDimitry Andric ios_base::iostate& __err, unsigned short& __v) const 695*0b57cec5SDimitry Andric { return this->__do_get_unsigned ( __b, __e, __iob, __err, __v ); } 696*0b57cec5SDimitry Andric 697*0b57cec5SDimitry Andric virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob, 698*0b57cec5SDimitry Andric ios_base::iostate& __err, unsigned int& __v) const 699*0b57cec5SDimitry Andric { return this->__do_get_unsigned ( __b, __e, __iob, __err, __v ); } 700*0b57cec5SDimitry Andric 701*0b57cec5SDimitry Andric virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob, 702*0b57cec5SDimitry Andric ios_base::iostate& __err, unsigned long& __v) const 703*0b57cec5SDimitry Andric { return this->__do_get_unsigned ( __b, __e, __iob, __err, __v ); } 704*0b57cec5SDimitry Andric 705*0b57cec5SDimitry Andric virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob, 706*0b57cec5SDimitry Andric ios_base::iostate& __err, unsigned long long& __v) const 707*0b57cec5SDimitry Andric { return this->__do_get_unsigned ( __b, __e, __iob, __err, __v ); } 708*0b57cec5SDimitry Andric 709*0b57cec5SDimitry Andric virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob, 710*0b57cec5SDimitry Andric ios_base::iostate& __err, float& __v) const 711*0b57cec5SDimitry Andric { return this->__do_get_floating_point ( __b, __e, __iob, __err, __v ); } 712*0b57cec5SDimitry Andric 713*0b57cec5SDimitry Andric virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob, 714*0b57cec5SDimitry Andric ios_base::iostate& __err, double& __v) const 715*0b57cec5SDimitry Andric { return this->__do_get_floating_point ( __b, __e, __iob, __err, __v ); } 716*0b57cec5SDimitry Andric 717*0b57cec5SDimitry Andric virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob, 718*0b57cec5SDimitry Andric ios_base::iostate& __err, long double& __v) const 719*0b57cec5SDimitry Andric { return this->__do_get_floating_point ( __b, __e, __iob, __err, __v ); } 720*0b57cec5SDimitry Andric 721*0b57cec5SDimitry Andric virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob, 722*0b57cec5SDimitry Andric ios_base::iostate& __err, void*& __v) const; 723*0b57cec5SDimitry Andric}; 724*0b57cec5SDimitry Andric 725*0b57cec5SDimitry Andrictemplate <class _CharT, class _InputIterator> 726*0b57cec5SDimitry Andriclocale::id 727*0b57cec5SDimitry Andricnum_get<_CharT, _InputIterator>::id; 728*0b57cec5SDimitry Andric 729*0b57cec5SDimitry Andrictemplate <class _Tp> 730*0b57cec5SDimitry Andric_LIBCPP_HIDDEN _Tp 731*0b57cec5SDimitry Andric__num_get_signed_integral(const char* __a, const char* __a_end, 732*0b57cec5SDimitry Andric ios_base::iostate& __err, int __base) 733*0b57cec5SDimitry Andric{ 734*0b57cec5SDimitry Andric if (__a != __a_end) 735*0b57cec5SDimitry Andric { 736*0b57cec5SDimitry Andric typename remove_reference<decltype(errno)>::type __save_errno = errno; 737*0b57cec5SDimitry Andric errno = 0; 738*0b57cec5SDimitry Andric char *__p2; 739*0b57cec5SDimitry Andric long long __ll = strtoll_l(__a, &__p2, __base, _LIBCPP_GET_C_LOCALE); 740*0b57cec5SDimitry Andric typename remove_reference<decltype(errno)>::type __current_errno = errno; 741*0b57cec5SDimitry Andric if (__current_errno == 0) 742*0b57cec5SDimitry Andric errno = __save_errno; 743*0b57cec5SDimitry Andric if (__p2 != __a_end) 744*0b57cec5SDimitry Andric { 745*0b57cec5SDimitry Andric __err = ios_base::failbit; 746*0b57cec5SDimitry Andric return 0; 747*0b57cec5SDimitry Andric } 748*0b57cec5SDimitry Andric else if (__current_errno == ERANGE || 749*0b57cec5SDimitry Andric __ll < numeric_limits<_Tp>::min() || 750*0b57cec5SDimitry Andric numeric_limits<_Tp>::max() < __ll) 751*0b57cec5SDimitry Andric { 752*0b57cec5SDimitry Andric __err = ios_base::failbit; 753*0b57cec5SDimitry Andric if (__ll > 0) 754*0b57cec5SDimitry Andric return numeric_limits<_Tp>::max(); 755*0b57cec5SDimitry Andric else 756*0b57cec5SDimitry Andric return numeric_limits<_Tp>::min(); 757*0b57cec5SDimitry Andric } 758*0b57cec5SDimitry Andric return static_cast<_Tp>(__ll); 759*0b57cec5SDimitry Andric } 760*0b57cec5SDimitry Andric __err = ios_base::failbit; 761*0b57cec5SDimitry Andric return 0; 762*0b57cec5SDimitry Andric} 763*0b57cec5SDimitry Andric 764*0b57cec5SDimitry Andrictemplate <class _Tp> 765*0b57cec5SDimitry Andric_LIBCPP_HIDDEN _Tp 766*0b57cec5SDimitry Andric__num_get_unsigned_integral(const char* __a, const char* __a_end, 767*0b57cec5SDimitry Andric ios_base::iostate& __err, int __base) 768*0b57cec5SDimitry Andric{ 769*0b57cec5SDimitry Andric if (__a != __a_end) 770*0b57cec5SDimitry Andric { 771*0b57cec5SDimitry Andric const bool __negate = *__a == '-'; 772*0b57cec5SDimitry Andric if (__negate && ++__a == __a_end) { 773*0b57cec5SDimitry Andric __err = ios_base::failbit; 774*0b57cec5SDimitry Andric return 0; 775*0b57cec5SDimitry Andric } 776*0b57cec5SDimitry Andric typename remove_reference<decltype(errno)>::type __save_errno = errno; 777*0b57cec5SDimitry Andric errno = 0; 778*0b57cec5SDimitry Andric char *__p2; 779*0b57cec5SDimitry Andric unsigned long long __ll = strtoull_l(__a, &__p2, __base, _LIBCPP_GET_C_LOCALE); 780*0b57cec5SDimitry Andric typename remove_reference<decltype(errno)>::type __current_errno = errno; 781*0b57cec5SDimitry Andric if (__current_errno == 0) 782*0b57cec5SDimitry Andric errno = __save_errno; 783*0b57cec5SDimitry Andric if (__p2 != __a_end) 784*0b57cec5SDimitry Andric { 785*0b57cec5SDimitry Andric __err = ios_base::failbit; 786*0b57cec5SDimitry Andric return 0; 787*0b57cec5SDimitry Andric } 788*0b57cec5SDimitry Andric else if (__current_errno == ERANGE || numeric_limits<_Tp>::max() < __ll) 789*0b57cec5SDimitry Andric { 790*0b57cec5SDimitry Andric __err = ios_base::failbit; 791*0b57cec5SDimitry Andric return numeric_limits<_Tp>::max(); 792*0b57cec5SDimitry Andric } 793*0b57cec5SDimitry Andric _Tp __res = static_cast<_Tp>(__ll); 794*0b57cec5SDimitry Andric if (__negate) __res = -__res; 795*0b57cec5SDimitry Andric return __res; 796*0b57cec5SDimitry Andric } 797*0b57cec5SDimitry Andric __err = ios_base::failbit; 798*0b57cec5SDimitry Andric return 0; 799*0b57cec5SDimitry Andric} 800*0b57cec5SDimitry Andric 801*0b57cec5SDimitry Andrictemplate <class _Tp> 802*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 803*0b57cec5SDimitry Andric_Tp __do_strtod(const char* __a, char** __p2); 804*0b57cec5SDimitry Andric 805*0b57cec5SDimitry Andrictemplate <> 806*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 807*0b57cec5SDimitry Andricfloat __do_strtod<float>(const char* __a, char** __p2) { 808*0b57cec5SDimitry Andric return strtof_l(__a, __p2, _LIBCPP_GET_C_LOCALE); 809*0b57cec5SDimitry Andric} 810*0b57cec5SDimitry Andric 811*0b57cec5SDimitry Andrictemplate <> 812*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 813*0b57cec5SDimitry Andricdouble __do_strtod<double>(const char* __a, char** __p2) { 814*0b57cec5SDimitry Andric return strtod_l(__a, __p2, _LIBCPP_GET_C_LOCALE); 815*0b57cec5SDimitry Andric} 816*0b57cec5SDimitry Andric 817*0b57cec5SDimitry Andrictemplate <> 818*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 819*0b57cec5SDimitry Andriclong double __do_strtod<long double>(const char* __a, char** __p2) { 820*0b57cec5SDimitry Andric return strtold_l(__a, __p2, _LIBCPP_GET_C_LOCALE); 821*0b57cec5SDimitry Andric} 822*0b57cec5SDimitry Andric 823*0b57cec5SDimitry Andrictemplate <class _Tp> 824*0b57cec5SDimitry Andric_LIBCPP_HIDDEN 825*0b57cec5SDimitry Andric_Tp 826*0b57cec5SDimitry Andric__num_get_float(const char* __a, const char* __a_end, ios_base::iostate& __err) 827*0b57cec5SDimitry Andric{ 828*0b57cec5SDimitry Andric if (__a != __a_end) 829*0b57cec5SDimitry Andric { 830*0b57cec5SDimitry Andric typename remove_reference<decltype(errno)>::type __save_errno = errno; 831*0b57cec5SDimitry Andric errno = 0; 832*0b57cec5SDimitry Andric char *__p2; 833*0b57cec5SDimitry Andric _Tp __ld = __do_strtod<_Tp>(__a, &__p2); 834*0b57cec5SDimitry Andric typename remove_reference<decltype(errno)>::type __current_errno = errno; 835*0b57cec5SDimitry Andric if (__current_errno == 0) 836*0b57cec5SDimitry Andric errno = __save_errno; 837*0b57cec5SDimitry Andric if (__p2 != __a_end) 838*0b57cec5SDimitry Andric { 839*0b57cec5SDimitry Andric __err = ios_base::failbit; 840*0b57cec5SDimitry Andric return 0; 841*0b57cec5SDimitry Andric } 842*0b57cec5SDimitry Andric else if (__current_errno == ERANGE) 843*0b57cec5SDimitry Andric __err = ios_base::failbit; 844*0b57cec5SDimitry Andric return __ld; 845*0b57cec5SDimitry Andric } 846*0b57cec5SDimitry Andric __err = ios_base::failbit; 847*0b57cec5SDimitry Andric return 0; 848*0b57cec5SDimitry Andric} 849*0b57cec5SDimitry Andric 850*0b57cec5SDimitry Andrictemplate <class _CharT, class _InputIterator> 851*0b57cec5SDimitry Andric_InputIterator 852*0b57cec5SDimitry Andricnum_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e, 853*0b57cec5SDimitry Andric ios_base& __iob, 854*0b57cec5SDimitry Andric ios_base::iostate& __err, 855*0b57cec5SDimitry Andric bool& __v) const 856*0b57cec5SDimitry Andric{ 857*0b57cec5SDimitry Andric if ((__iob.flags() & ios_base::boolalpha) == 0) 858*0b57cec5SDimitry Andric { 859*0b57cec5SDimitry Andric long __lv = -1; 860*0b57cec5SDimitry Andric __b = do_get(__b, __e, __iob, __err, __lv); 861*0b57cec5SDimitry Andric switch (__lv) 862*0b57cec5SDimitry Andric { 863*0b57cec5SDimitry Andric case 0: 864*0b57cec5SDimitry Andric __v = false; 865*0b57cec5SDimitry Andric break; 866*0b57cec5SDimitry Andric case 1: 867*0b57cec5SDimitry Andric __v = true; 868*0b57cec5SDimitry Andric break; 869*0b57cec5SDimitry Andric default: 870*0b57cec5SDimitry Andric __v = true; 871*0b57cec5SDimitry Andric __err = ios_base::failbit; 872*0b57cec5SDimitry Andric break; 873*0b57cec5SDimitry Andric } 874*0b57cec5SDimitry Andric return __b; 875*0b57cec5SDimitry Andric } 876*0b57cec5SDimitry Andric const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__iob.getloc()); 877*0b57cec5SDimitry Andric const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__iob.getloc()); 878*0b57cec5SDimitry Andric typedef typename numpunct<_CharT>::string_type string_type; 879*0b57cec5SDimitry Andric const string_type __names[2] = {__np.truename(), __np.falsename()}; 880*0b57cec5SDimitry Andric const string_type* __i = __scan_keyword(__b, __e, __names, __names+2, 881*0b57cec5SDimitry Andric __ct, __err); 882*0b57cec5SDimitry Andric __v = __i == __names; 883*0b57cec5SDimitry Andric return __b; 884*0b57cec5SDimitry Andric} 885*0b57cec5SDimitry Andric 886*0b57cec5SDimitry Andric// signed 887*0b57cec5SDimitry Andric 888*0b57cec5SDimitry Andrictemplate <class _CharT, class _InputIterator> 889*0b57cec5SDimitry Andrictemplate <class _Signed> 890*0b57cec5SDimitry Andric_InputIterator 891*0b57cec5SDimitry Andricnum_get<_CharT, _InputIterator>::__do_get_signed(iter_type __b, iter_type __e, 892*0b57cec5SDimitry Andric ios_base& __iob, 893*0b57cec5SDimitry Andric ios_base::iostate& __err, 894*0b57cec5SDimitry Andric _Signed& __v) const 895*0b57cec5SDimitry Andric{ 896*0b57cec5SDimitry Andric // Stage 1 897*0b57cec5SDimitry Andric int __base = this->__get_base(__iob); 898*0b57cec5SDimitry Andric // Stage 2 899*0b57cec5SDimitry Andric char_type __thousands_sep; 900*0b57cec5SDimitry Andric const int __atoms_size = 26; 901*0b57cec5SDimitry Andric#ifdef _LIBCPP_ABI_OPTIMIZED_LOCALE_NUM_GET 902*0b57cec5SDimitry Andric char_type __atoms1[__atoms_size]; 903*0b57cec5SDimitry Andric const char_type *__atoms = this->__do_widen(__iob, __atoms1); 904*0b57cec5SDimitry Andric string __grouping = this->__stage2_int_prep(__iob, __thousands_sep); 905*0b57cec5SDimitry Andric#else 906*0b57cec5SDimitry Andric char_type __atoms[__atoms_size]; 907*0b57cec5SDimitry Andric string __grouping = this->__stage2_int_prep(__iob, __atoms, __thousands_sep); 908*0b57cec5SDimitry Andric#endif 909*0b57cec5SDimitry Andric string __buf; 910*0b57cec5SDimitry Andric __buf.resize(__buf.capacity()); 911*0b57cec5SDimitry Andric char* __a = &__buf[0]; 912*0b57cec5SDimitry Andric char* __a_end = __a; 913*0b57cec5SDimitry Andric unsigned __g[__num_get_base::__num_get_buf_sz]; 914*0b57cec5SDimitry Andric unsigned* __g_end = __g; 915*0b57cec5SDimitry Andric unsigned __dc = 0; 916*0b57cec5SDimitry Andric for (; __b != __e; ++__b) 917*0b57cec5SDimitry Andric { 918*0b57cec5SDimitry Andric if (__a_end == __a + __buf.size()) 919*0b57cec5SDimitry Andric { 920*0b57cec5SDimitry Andric size_t __tmp = __buf.size(); 921*0b57cec5SDimitry Andric __buf.resize(2*__buf.size()); 922*0b57cec5SDimitry Andric __buf.resize(__buf.capacity()); 923*0b57cec5SDimitry Andric __a = &__buf[0]; 924*0b57cec5SDimitry Andric __a_end = __a + __tmp; 925*0b57cec5SDimitry Andric } 926*0b57cec5SDimitry Andric if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc, 927*0b57cec5SDimitry Andric __thousands_sep, __grouping, __g, __g_end, 928*0b57cec5SDimitry Andric __atoms)) 929*0b57cec5SDimitry Andric break; 930*0b57cec5SDimitry Andric } 931*0b57cec5SDimitry Andric if (__grouping.size() != 0 && __g_end-__g < __num_get_base::__num_get_buf_sz) 932*0b57cec5SDimitry Andric *__g_end++ = __dc; 933*0b57cec5SDimitry Andric // Stage 3 934*0b57cec5SDimitry Andric __v = __num_get_signed_integral<_Signed>(__a, __a_end, __err, __base); 935*0b57cec5SDimitry Andric // Digit grouping checked 936*0b57cec5SDimitry Andric __check_grouping(__grouping, __g, __g_end, __err); 937*0b57cec5SDimitry Andric // EOF checked 938*0b57cec5SDimitry Andric if (__b == __e) 939*0b57cec5SDimitry Andric __err |= ios_base::eofbit; 940*0b57cec5SDimitry Andric return __b; 941*0b57cec5SDimitry Andric} 942*0b57cec5SDimitry Andric 943*0b57cec5SDimitry Andric// unsigned 944*0b57cec5SDimitry Andric 945*0b57cec5SDimitry Andrictemplate <class _CharT, class _InputIterator> 946*0b57cec5SDimitry Andrictemplate <class _Unsigned> 947*0b57cec5SDimitry Andric_InputIterator 948*0b57cec5SDimitry Andricnum_get<_CharT, _InputIterator>::__do_get_unsigned(iter_type __b, iter_type __e, 949*0b57cec5SDimitry Andric ios_base& __iob, 950*0b57cec5SDimitry Andric ios_base::iostate& __err, 951*0b57cec5SDimitry Andric _Unsigned& __v) const 952*0b57cec5SDimitry Andric{ 953*0b57cec5SDimitry Andric // Stage 1 954*0b57cec5SDimitry Andric int __base = this->__get_base(__iob); 955*0b57cec5SDimitry Andric // Stage 2 956*0b57cec5SDimitry Andric char_type __thousands_sep; 957*0b57cec5SDimitry Andric const int __atoms_size = 26; 958*0b57cec5SDimitry Andric#ifdef _LIBCPP_ABI_OPTIMIZED_LOCALE_NUM_GET 959*0b57cec5SDimitry Andric char_type __atoms1[__atoms_size]; 960*0b57cec5SDimitry Andric const char_type *__atoms = this->__do_widen(__iob, __atoms1); 961*0b57cec5SDimitry Andric string __grouping = this->__stage2_int_prep(__iob, __thousands_sep); 962*0b57cec5SDimitry Andric#else 963*0b57cec5SDimitry Andric char_type __atoms[__atoms_size]; 964*0b57cec5SDimitry Andric string __grouping = this->__stage2_int_prep(__iob, __atoms, __thousands_sep); 965*0b57cec5SDimitry Andric#endif 966*0b57cec5SDimitry Andric string __buf; 967*0b57cec5SDimitry Andric __buf.resize(__buf.capacity()); 968*0b57cec5SDimitry Andric char* __a = &__buf[0]; 969*0b57cec5SDimitry Andric char* __a_end = __a; 970*0b57cec5SDimitry Andric unsigned __g[__num_get_base::__num_get_buf_sz]; 971*0b57cec5SDimitry Andric unsigned* __g_end = __g; 972*0b57cec5SDimitry Andric unsigned __dc = 0; 973*0b57cec5SDimitry Andric for (; __b != __e; ++__b) 974*0b57cec5SDimitry Andric { 975*0b57cec5SDimitry Andric if (__a_end == __a + __buf.size()) 976*0b57cec5SDimitry Andric { 977*0b57cec5SDimitry Andric size_t __tmp = __buf.size(); 978*0b57cec5SDimitry Andric __buf.resize(2*__buf.size()); 979*0b57cec5SDimitry Andric __buf.resize(__buf.capacity()); 980*0b57cec5SDimitry Andric __a = &__buf[0]; 981*0b57cec5SDimitry Andric __a_end = __a + __tmp; 982*0b57cec5SDimitry Andric } 983*0b57cec5SDimitry Andric if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc, 984*0b57cec5SDimitry Andric __thousands_sep, __grouping, __g, __g_end, 985*0b57cec5SDimitry Andric __atoms)) 986*0b57cec5SDimitry Andric break; 987*0b57cec5SDimitry Andric } 988*0b57cec5SDimitry Andric if (__grouping.size() != 0 && __g_end-__g < __num_get_base::__num_get_buf_sz) 989*0b57cec5SDimitry Andric *__g_end++ = __dc; 990*0b57cec5SDimitry Andric // Stage 3 991*0b57cec5SDimitry Andric __v = __num_get_unsigned_integral<_Unsigned>(__a, __a_end, __err, __base); 992*0b57cec5SDimitry Andric // Digit grouping checked 993*0b57cec5SDimitry Andric __check_grouping(__grouping, __g, __g_end, __err); 994*0b57cec5SDimitry Andric // EOF checked 995*0b57cec5SDimitry Andric if (__b == __e) 996*0b57cec5SDimitry Andric __err |= ios_base::eofbit; 997*0b57cec5SDimitry Andric return __b; 998*0b57cec5SDimitry Andric} 999*0b57cec5SDimitry Andric 1000*0b57cec5SDimitry Andric// floating point 1001*0b57cec5SDimitry Andric 1002*0b57cec5SDimitry Andrictemplate <class _CharT, class _InputIterator> 1003*0b57cec5SDimitry Andrictemplate <class _Fp> 1004*0b57cec5SDimitry Andric_InputIterator 1005*0b57cec5SDimitry Andricnum_get<_CharT, _InputIterator>::__do_get_floating_point(iter_type __b, iter_type __e, 1006*0b57cec5SDimitry Andric ios_base& __iob, 1007*0b57cec5SDimitry Andric ios_base::iostate& __err, 1008*0b57cec5SDimitry Andric _Fp& __v) const 1009*0b57cec5SDimitry Andric{ 1010*0b57cec5SDimitry Andric // Stage 1, nothing to do 1011*0b57cec5SDimitry Andric // Stage 2 1012*0b57cec5SDimitry Andric char_type __atoms[32]; 1013*0b57cec5SDimitry Andric char_type __decimal_point; 1014*0b57cec5SDimitry Andric char_type __thousands_sep; 1015*0b57cec5SDimitry Andric string __grouping = this->__stage2_float_prep(__iob, __atoms, 1016*0b57cec5SDimitry Andric __decimal_point, 1017*0b57cec5SDimitry Andric __thousands_sep); 1018*0b57cec5SDimitry Andric string __buf; 1019*0b57cec5SDimitry Andric __buf.resize(__buf.capacity()); 1020*0b57cec5SDimitry Andric char* __a = &__buf[0]; 1021*0b57cec5SDimitry Andric char* __a_end = __a; 1022*0b57cec5SDimitry Andric unsigned __g[__num_get_base::__num_get_buf_sz]; 1023*0b57cec5SDimitry Andric unsigned* __g_end = __g; 1024*0b57cec5SDimitry Andric unsigned __dc = 0; 1025*0b57cec5SDimitry Andric bool __in_units = true; 1026*0b57cec5SDimitry Andric char __exp = 'E'; 1027*0b57cec5SDimitry Andric for (; __b != __e; ++__b) 1028*0b57cec5SDimitry Andric { 1029*0b57cec5SDimitry Andric if (__a_end == __a + __buf.size()) 1030*0b57cec5SDimitry Andric { 1031*0b57cec5SDimitry Andric size_t __tmp = __buf.size(); 1032*0b57cec5SDimitry Andric __buf.resize(2*__buf.size()); 1033*0b57cec5SDimitry Andric __buf.resize(__buf.capacity()); 1034*0b57cec5SDimitry Andric __a = &__buf[0]; 1035*0b57cec5SDimitry Andric __a_end = __a + __tmp; 1036*0b57cec5SDimitry Andric } 1037*0b57cec5SDimitry Andric if (this->__stage2_float_loop(*__b, __in_units, __exp, __a, __a_end, 1038*0b57cec5SDimitry Andric __decimal_point, __thousands_sep, 1039*0b57cec5SDimitry Andric __grouping, __g, __g_end, 1040*0b57cec5SDimitry Andric __dc, __atoms)) 1041*0b57cec5SDimitry Andric break; 1042*0b57cec5SDimitry Andric } 1043*0b57cec5SDimitry Andric if (__grouping.size() != 0 && __in_units && __g_end-__g < __num_get_base::__num_get_buf_sz) 1044*0b57cec5SDimitry Andric *__g_end++ = __dc; 1045*0b57cec5SDimitry Andric // Stage 3 1046*0b57cec5SDimitry Andric __v = __num_get_float<_Fp>(__a, __a_end, __err); 1047*0b57cec5SDimitry Andric // Digit grouping checked 1048*0b57cec5SDimitry Andric __check_grouping(__grouping, __g, __g_end, __err); 1049*0b57cec5SDimitry Andric // EOF checked 1050*0b57cec5SDimitry Andric if (__b == __e) 1051*0b57cec5SDimitry Andric __err |= ios_base::eofbit; 1052*0b57cec5SDimitry Andric return __b; 1053*0b57cec5SDimitry Andric} 1054*0b57cec5SDimitry Andric 1055*0b57cec5SDimitry Andrictemplate <class _CharT, class _InputIterator> 1056*0b57cec5SDimitry Andric_InputIterator 1057*0b57cec5SDimitry Andricnum_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e, 1058*0b57cec5SDimitry Andric ios_base& __iob, 1059*0b57cec5SDimitry Andric ios_base::iostate& __err, 1060*0b57cec5SDimitry Andric void*& __v) const 1061*0b57cec5SDimitry Andric{ 1062*0b57cec5SDimitry Andric // Stage 1 1063*0b57cec5SDimitry Andric int __base = 16; 1064*0b57cec5SDimitry Andric // Stage 2 1065*0b57cec5SDimitry Andric char_type __atoms[26]; 1066*0b57cec5SDimitry Andric char_type __thousands_sep = 0; 1067*0b57cec5SDimitry Andric string __grouping; 1068*0b57cec5SDimitry Andric use_facet<ctype<_CharT> >(__iob.getloc()).widen(__num_get_base::__src, 1069*0b57cec5SDimitry Andric __num_get_base::__src + 26, __atoms); 1070*0b57cec5SDimitry Andric string __buf; 1071*0b57cec5SDimitry Andric __buf.resize(__buf.capacity()); 1072*0b57cec5SDimitry Andric char* __a = &__buf[0]; 1073*0b57cec5SDimitry Andric char* __a_end = __a; 1074*0b57cec5SDimitry Andric unsigned __g[__num_get_base::__num_get_buf_sz]; 1075*0b57cec5SDimitry Andric unsigned* __g_end = __g; 1076*0b57cec5SDimitry Andric unsigned __dc = 0; 1077*0b57cec5SDimitry Andric for (; __b != __e; ++__b) 1078*0b57cec5SDimitry Andric { 1079*0b57cec5SDimitry Andric if (__a_end == __a + __buf.size()) 1080*0b57cec5SDimitry Andric { 1081*0b57cec5SDimitry Andric size_t __tmp = __buf.size(); 1082*0b57cec5SDimitry Andric __buf.resize(2*__buf.size()); 1083*0b57cec5SDimitry Andric __buf.resize(__buf.capacity()); 1084*0b57cec5SDimitry Andric __a = &__buf[0]; 1085*0b57cec5SDimitry Andric __a_end = __a + __tmp; 1086*0b57cec5SDimitry Andric } 1087*0b57cec5SDimitry Andric if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc, 1088*0b57cec5SDimitry Andric __thousands_sep, __grouping, 1089*0b57cec5SDimitry Andric __g, __g_end, __atoms)) 1090*0b57cec5SDimitry Andric break; 1091*0b57cec5SDimitry Andric } 1092*0b57cec5SDimitry Andric // Stage 3 1093*0b57cec5SDimitry Andric __buf.resize(__a_end - __a); 1094*0b57cec5SDimitry Andric if (__libcpp_sscanf_l(__buf.c_str(), _LIBCPP_GET_C_LOCALE, "%p", &__v) != 1) 1095*0b57cec5SDimitry Andric __err = ios_base::failbit; 1096*0b57cec5SDimitry Andric // EOF checked 1097*0b57cec5SDimitry Andric if (__b == __e) 1098*0b57cec5SDimitry Andric __err |= ios_base::eofbit; 1099*0b57cec5SDimitry Andric return __b; 1100*0b57cec5SDimitry Andric} 1101*0b57cec5SDimitry Andric 1102*0b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS num_get<char>) 1103*0b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS num_get<wchar_t>) 1104*0b57cec5SDimitry Andric 1105*0b57cec5SDimitry Andricstruct _LIBCPP_TYPE_VIS __num_put_base 1106*0b57cec5SDimitry Andric{ 1107*0b57cec5SDimitry Andricprotected: 1108*0b57cec5SDimitry Andric static void __format_int(char* __fmt, const char* __len, bool __signd, 1109*0b57cec5SDimitry Andric ios_base::fmtflags __flags); 1110*0b57cec5SDimitry Andric static bool __format_float(char* __fmt, const char* __len, 1111*0b57cec5SDimitry Andric ios_base::fmtflags __flags); 1112*0b57cec5SDimitry Andric static char* __identify_padding(char* __nb, char* __ne, 1113*0b57cec5SDimitry Andric const ios_base& __iob); 1114*0b57cec5SDimitry Andric}; 1115*0b57cec5SDimitry Andric 1116*0b57cec5SDimitry Andrictemplate <class _CharT> 1117*0b57cec5SDimitry Andricstruct __num_put 1118*0b57cec5SDimitry Andric : protected __num_put_base 1119*0b57cec5SDimitry Andric{ 1120*0b57cec5SDimitry Andric static void __widen_and_group_int(char* __nb, char* __np, char* __ne, 1121*0b57cec5SDimitry Andric _CharT* __ob, _CharT*& __op, _CharT*& __oe, 1122*0b57cec5SDimitry Andric const locale& __loc); 1123*0b57cec5SDimitry Andric static void __widen_and_group_float(char* __nb, char* __np, char* __ne, 1124*0b57cec5SDimitry Andric _CharT* __ob, _CharT*& __op, _CharT*& __oe, 1125*0b57cec5SDimitry Andric const locale& __loc); 1126*0b57cec5SDimitry Andric}; 1127*0b57cec5SDimitry Andric 1128*0b57cec5SDimitry Andrictemplate <class _CharT> 1129*0b57cec5SDimitry Andricvoid 1130*0b57cec5SDimitry Andric__num_put<_CharT>::__widen_and_group_int(char* __nb, char* __np, char* __ne, 1131*0b57cec5SDimitry Andric _CharT* __ob, _CharT*& __op, _CharT*& __oe, 1132*0b57cec5SDimitry Andric const locale& __loc) 1133*0b57cec5SDimitry Andric{ 1134*0b57cec5SDimitry Andric const ctype<_CharT>& __ct = use_facet<ctype<_CharT> > (__loc); 1135*0b57cec5SDimitry Andric const numpunct<_CharT>& __npt = use_facet<numpunct<_CharT> >(__loc); 1136*0b57cec5SDimitry Andric string __grouping = __npt.grouping(); 1137*0b57cec5SDimitry Andric if (__grouping.empty()) 1138*0b57cec5SDimitry Andric { 1139*0b57cec5SDimitry Andric __ct.widen(__nb, __ne, __ob); 1140*0b57cec5SDimitry Andric __oe = __ob + (__ne - __nb); 1141*0b57cec5SDimitry Andric } 1142*0b57cec5SDimitry Andric else 1143*0b57cec5SDimitry Andric { 1144*0b57cec5SDimitry Andric __oe = __ob; 1145*0b57cec5SDimitry Andric char* __nf = __nb; 1146*0b57cec5SDimitry Andric if (*__nf == '-' || *__nf == '+') 1147*0b57cec5SDimitry Andric *__oe++ = __ct.widen(*__nf++); 1148*0b57cec5SDimitry Andric if (__ne - __nf >= 2 && __nf[0] == '0' && (__nf[1] == 'x' || 1149*0b57cec5SDimitry Andric __nf[1] == 'X')) 1150*0b57cec5SDimitry Andric { 1151*0b57cec5SDimitry Andric *__oe++ = __ct.widen(*__nf++); 1152*0b57cec5SDimitry Andric *__oe++ = __ct.widen(*__nf++); 1153*0b57cec5SDimitry Andric } 1154*0b57cec5SDimitry Andric reverse(__nf, __ne); 1155*0b57cec5SDimitry Andric _CharT __thousands_sep = __npt.thousands_sep(); 1156*0b57cec5SDimitry Andric unsigned __dc = 0; 1157*0b57cec5SDimitry Andric unsigned __dg = 0; 1158*0b57cec5SDimitry Andric for (char* __p = __nf; __p < __ne; ++__p) 1159*0b57cec5SDimitry Andric { 1160*0b57cec5SDimitry Andric if (static_cast<unsigned>(__grouping[__dg]) > 0 && 1161*0b57cec5SDimitry Andric __dc == static_cast<unsigned>(__grouping[__dg])) 1162*0b57cec5SDimitry Andric { 1163*0b57cec5SDimitry Andric *__oe++ = __thousands_sep; 1164*0b57cec5SDimitry Andric __dc = 0; 1165*0b57cec5SDimitry Andric if (__dg < __grouping.size()-1) 1166*0b57cec5SDimitry Andric ++__dg; 1167*0b57cec5SDimitry Andric } 1168*0b57cec5SDimitry Andric *__oe++ = __ct.widen(*__p); 1169*0b57cec5SDimitry Andric ++__dc; 1170*0b57cec5SDimitry Andric } 1171*0b57cec5SDimitry Andric reverse(__ob + (__nf - __nb), __oe); 1172*0b57cec5SDimitry Andric } 1173*0b57cec5SDimitry Andric if (__np == __ne) 1174*0b57cec5SDimitry Andric __op = __oe; 1175*0b57cec5SDimitry Andric else 1176*0b57cec5SDimitry Andric __op = __ob + (__np - __nb); 1177*0b57cec5SDimitry Andric} 1178*0b57cec5SDimitry Andric 1179*0b57cec5SDimitry Andrictemplate <class _CharT> 1180*0b57cec5SDimitry Andricvoid 1181*0b57cec5SDimitry Andric__num_put<_CharT>::__widen_and_group_float(char* __nb, char* __np, char* __ne, 1182*0b57cec5SDimitry Andric _CharT* __ob, _CharT*& __op, _CharT*& __oe, 1183*0b57cec5SDimitry Andric const locale& __loc) 1184*0b57cec5SDimitry Andric{ 1185*0b57cec5SDimitry Andric const ctype<_CharT>& __ct = use_facet<ctype<_CharT> > (__loc); 1186*0b57cec5SDimitry Andric const numpunct<_CharT>& __npt = use_facet<numpunct<_CharT> >(__loc); 1187*0b57cec5SDimitry Andric string __grouping = __npt.grouping(); 1188*0b57cec5SDimitry Andric __oe = __ob; 1189*0b57cec5SDimitry Andric char* __nf = __nb; 1190*0b57cec5SDimitry Andric if (*__nf == '-' || *__nf == '+') 1191*0b57cec5SDimitry Andric *__oe++ = __ct.widen(*__nf++); 1192*0b57cec5SDimitry Andric char* __ns; 1193*0b57cec5SDimitry Andric if (__ne - __nf >= 2 && __nf[0] == '0' && (__nf[1] == 'x' || 1194*0b57cec5SDimitry Andric __nf[1] == 'X')) 1195*0b57cec5SDimitry Andric { 1196*0b57cec5SDimitry Andric *__oe++ = __ct.widen(*__nf++); 1197*0b57cec5SDimitry Andric *__oe++ = __ct.widen(*__nf++); 1198*0b57cec5SDimitry Andric for (__ns = __nf; __ns < __ne; ++__ns) 1199*0b57cec5SDimitry Andric if (!isxdigit_l(*__ns, _LIBCPP_GET_C_LOCALE)) 1200*0b57cec5SDimitry Andric break; 1201*0b57cec5SDimitry Andric } 1202*0b57cec5SDimitry Andric else 1203*0b57cec5SDimitry Andric { 1204*0b57cec5SDimitry Andric for (__ns = __nf; __ns < __ne; ++__ns) 1205*0b57cec5SDimitry Andric if (!isdigit_l(*__ns, _LIBCPP_GET_C_LOCALE)) 1206*0b57cec5SDimitry Andric break; 1207*0b57cec5SDimitry Andric } 1208*0b57cec5SDimitry Andric if (__grouping.empty()) 1209*0b57cec5SDimitry Andric { 1210*0b57cec5SDimitry Andric __ct.widen(__nf, __ns, __oe); 1211*0b57cec5SDimitry Andric __oe += __ns - __nf; 1212*0b57cec5SDimitry Andric } 1213*0b57cec5SDimitry Andric else 1214*0b57cec5SDimitry Andric { 1215*0b57cec5SDimitry Andric reverse(__nf, __ns); 1216*0b57cec5SDimitry Andric _CharT __thousands_sep = __npt.thousands_sep(); 1217*0b57cec5SDimitry Andric unsigned __dc = 0; 1218*0b57cec5SDimitry Andric unsigned __dg = 0; 1219*0b57cec5SDimitry Andric for (char* __p = __nf; __p < __ns; ++__p) 1220*0b57cec5SDimitry Andric { 1221*0b57cec5SDimitry Andric if (__grouping[__dg] > 0 && __dc == static_cast<unsigned>(__grouping[__dg])) 1222*0b57cec5SDimitry Andric { 1223*0b57cec5SDimitry Andric *__oe++ = __thousands_sep; 1224*0b57cec5SDimitry Andric __dc = 0; 1225*0b57cec5SDimitry Andric if (__dg < __grouping.size()-1) 1226*0b57cec5SDimitry Andric ++__dg; 1227*0b57cec5SDimitry Andric } 1228*0b57cec5SDimitry Andric *__oe++ = __ct.widen(*__p); 1229*0b57cec5SDimitry Andric ++__dc; 1230*0b57cec5SDimitry Andric } 1231*0b57cec5SDimitry Andric reverse(__ob + (__nf - __nb), __oe); 1232*0b57cec5SDimitry Andric } 1233*0b57cec5SDimitry Andric for (__nf = __ns; __nf < __ne; ++__nf) 1234*0b57cec5SDimitry Andric { 1235*0b57cec5SDimitry Andric if (*__nf == '.') 1236*0b57cec5SDimitry Andric { 1237*0b57cec5SDimitry Andric *__oe++ = __npt.decimal_point(); 1238*0b57cec5SDimitry Andric ++__nf; 1239*0b57cec5SDimitry Andric break; 1240*0b57cec5SDimitry Andric } 1241*0b57cec5SDimitry Andric else 1242*0b57cec5SDimitry Andric *__oe++ = __ct.widen(*__nf); 1243*0b57cec5SDimitry Andric } 1244*0b57cec5SDimitry Andric __ct.widen(__nf, __ne, __oe); 1245*0b57cec5SDimitry Andric __oe += __ne - __nf; 1246*0b57cec5SDimitry Andric if (__np == __ne) 1247*0b57cec5SDimitry Andric __op = __oe; 1248*0b57cec5SDimitry Andric else 1249*0b57cec5SDimitry Andric __op = __ob + (__np - __nb); 1250*0b57cec5SDimitry Andric} 1251*0b57cec5SDimitry Andric 1252*0b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE2(struct _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __num_put<char>) 1253*0b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE2(struct _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __num_put<wchar_t>) 1254*0b57cec5SDimitry Andric 1255*0b57cec5SDimitry Andrictemplate <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> > 1256*0b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS num_put 1257*0b57cec5SDimitry Andric : public locale::facet, 1258*0b57cec5SDimitry Andric private __num_put<_CharT> 1259*0b57cec5SDimitry Andric{ 1260*0b57cec5SDimitry Andricpublic: 1261*0b57cec5SDimitry Andric typedef _CharT char_type; 1262*0b57cec5SDimitry Andric typedef _OutputIterator iter_type; 1263*0b57cec5SDimitry Andric 1264*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1265*0b57cec5SDimitry Andric explicit num_put(size_t __refs = 0) 1266*0b57cec5SDimitry Andric : locale::facet(__refs) {} 1267*0b57cec5SDimitry Andric 1268*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1269*0b57cec5SDimitry Andric iter_type put(iter_type __s, ios_base& __iob, char_type __fl, 1270*0b57cec5SDimitry Andric bool __v) const 1271*0b57cec5SDimitry Andric { 1272*0b57cec5SDimitry Andric return do_put(__s, __iob, __fl, __v); 1273*0b57cec5SDimitry Andric } 1274*0b57cec5SDimitry Andric 1275*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1276*0b57cec5SDimitry Andric iter_type put(iter_type __s, ios_base& __iob, char_type __fl, 1277*0b57cec5SDimitry Andric long __v) const 1278*0b57cec5SDimitry Andric { 1279*0b57cec5SDimitry Andric return do_put(__s, __iob, __fl, __v); 1280*0b57cec5SDimitry Andric } 1281*0b57cec5SDimitry Andric 1282*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1283*0b57cec5SDimitry Andric iter_type put(iter_type __s, ios_base& __iob, char_type __fl, 1284*0b57cec5SDimitry Andric long long __v) const 1285*0b57cec5SDimitry Andric { 1286*0b57cec5SDimitry Andric return do_put(__s, __iob, __fl, __v); 1287*0b57cec5SDimitry Andric } 1288*0b57cec5SDimitry Andric 1289*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1290*0b57cec5SDimitry Andric iter_type put(iter_type __s, ios_base& __iob, char_type __fl, 1291*0b57cec5SDimitry Andric unsigned long __v) const 1292*0b57cec5SDimitry Andric { 1293*0b57cec5SDimitry Andric return do_put(__s, __iob, __fl, __v); 1294*0b57cec5SDimitry Andric } 1295*0b57cec5SDimitry Andric 1296*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1297*0b57cec5SDimitry Andric iter_type put(iter_type __s, ios_base& __iob, char_type __fl, 1298*0b57cec5SDimitry Andric unsigned long long __v) const 1299*0b57cec5SDimitry Andric { 1300*0b57cec5SDimitry Andric return do_put(__s, __iob, __fl, __v); 1301*0b57cec5SDimitry Andric } 1302*0b57cec5SDimitry Andric 1303*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1304*0b57cec5SDimitry Andric iter_type put(iter_type __s, ios_base& __iob, char_type __fl, 1305*0b57cec5SDimitry Andric double __v) const 1306*0b57cec5SDimitry Andric { 1307*0b57cec5SDimitry Andric return do_put(__s, __iob, __fl, __v); 1308*0b57cec5SDimitry Andric } 1309*0b57cec5SDimitry Andric 1310*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1311*0b57cec5SDimitry Andric iter_type put(iter_type __s, ios_base& __iob, char_type __fl, 1312*0b57cec5SDimitry Andric long double __v) const 1313*0b57cec5SDimitry Andric { 1314*0b57cec5SDimitry Andric return do_put(__s, __iob, __fl, __v); 1315*0b57cec5SDimitry Andric } 1316*0b57cec5SDimitry Andric 1317*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1318*0b57cec5SDimitry Andric iter_type put(iter_type __s, ios_base& __iob, char_type __fl, 1319*0b57cec5SDimitry Andric const void* __v) const 1320*0b57cec5SDimitry Andric { 1321*0b57cec5SDimitry Andric return do_put(__s, __iob, __fl, __v); 1322*0b57cec5SDimitry Andric } 1323*0b57cec5SDimitry Andric 1324*0b57cec5SDimitry Andric static locale::id id; 1325*0b57cec5SDimitry Andric 1326*0b57cec5SDimitry Andricprotected: 1327*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1328*0b57cec5SDimitry Andric ~num_put() {} 1329*0b57cec5SDimitry Andric 1330*0b57cec5SDimitry Andric virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl, 1331*0b57cec5SDimitry Andric bool __v) const; 1332*0b57cec5SDimitry Andric virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl, 1333*0b57cec5SDimitry Andric long __v) const; 1334*0b57cec5SDimitry Andric virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl, 1335*0b57cec5SDimitry Andric long long __v) const; 1336*0b57cec5SDimitry Andric virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl, 1337*0b57cec5SDimitry Andric unsigned long) const; 1338*0b57cec5SDimitry Andric virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl, 1339*0b57cec5SDimitry Andric unsigned long long) const; 1340*0b57cec5SDimitry Andric virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl, 1341*0b57cec5SDimitry Andric double __v) const; 1342*0b57cec5SDimitry Andric virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl, 1343*0b57cec5SDimitry Andric long double __v) const; 1344*0b57cec5SDimitry Andric virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl, 1345*0b57cec5SDimitry Andric const void* __v) const; 1346*0b57cec5SDimitry Andric}; 1347*0b57cec5SDimitry Andric 1348*0b57cec5SDimitry Andrictemplate <class _CharT, class _OutputIterator> 1349*0b57cec5SDimitry Andriclocale::id 1350*0b57cec5SDimitry Andricnum_put<_CharT, _OutputIterator>::id; 1351*0b57cec5SDimitry Andric 1352*0b57cec5SDimitry Andrictemplate <class _CharT, class _OutputIterator> 1353*0b57cec5SDimitry Andric_LIBCPP_HIDDEN 1354*0b57cec5SDimitry Andric_OutputIterator 1355*0b57cec5SDimitry Andric__pad_and_output(_OutputIterator __s, 1356*0b57cec5SDimitry Andric const _CharT* __ob, const _CharT* __op, const _CharT* __oe, 1357*0b57cec5SDimitry Andric ios_base& __iob, _CharT __fl) 1358*0b57cec5SDimitry Andric{ 1359*0b57cec5SDimitry Andric streamsize __sz = __oe - __ob; 1360*0b57cec5SDimitry Andric streamsize __ns = __iob.width(); 1361*0b57cec5SDimitry Andric if (__ns > __sz) 1362*0b57cec5SDimitry Andric __ns -= __sz; 1363*0b57cec5SDimitry Andric else 1364*0b57cec5SDimitry Andric __ns = 0; 1365*0b57cec5SDimitry Andric for (;__ob < __op; ++__ob, ++__s) 1366*0b57cec5SDimitry Andric *__s = *__ob; 1367*0b57cec5SDimitry Andric for (; __ns; --__ns, ++__s) 1368*0b57cec5SDimitry Andric *__s = __fl; 1369*0b57cec5SDimitry Andric for (; __ob < __oe; ++__ob, ++__s) 1370*0b57cec5SDimitry Andric *__s = *__ob; 1371*0b57cec5SDimitry Andric __iob.width(0); 1372*0b57cec5SDimitry Andric return __s; 1373*0b57cec5SDimitry Andric} 1374*0b57cec5SDimitry Andric 1375*0b57cec5SDimitry Andrictemplate <class _CharT, class _Traits> 1376*0b57cec5SDimitry Andric_LIBCPP_HIDDEN 1377*0b57cec5SDimitry Andricostreambuf_iterator<_CharT, _Traits> 1378*0b57cec5SDimitry Andric__pad_and_output(ostreambuf_iterator<_CharT, _Traits> __s, 1379*0b57cec5SDimitry Andric const _CharT* __ob, const _CharT* __op, const _CharT* __oe, 1380*0b57cec5SDimitry Andric ios_base& __iob, _CharT __fl) 1381*0b57cec5SDimitry Andric{ 1382*0b57cec5SDimitry Andric if (__s.__sbuf_ == nullptr) 1383*0b57cec5SDimitry Andric return __s; 1384*0b57cec5SDimitry Andric streamsize __sz = __oe - __ob; 1385*0b57cec5SDimitry Andric streamsize __ns = __iob.width(); 1386*0b57cec5SDimitry Andric if (__ns > __sz) 1387*0b57cec5SDimitry Andric __ns -= __sz; 1388*0b57cec5SDimitry Andric else 1389*0b57cec5SDimitry Andric __ns = 0; 1390*0b57cec5SDimitry Andric streamsize __np = __op - __ob; 1391*0b57cec5SDimitry Andric if (__np > 0) 1392*0b57cec5SDimitry Andric { 1393*0b57cec5SDimitry Andric if (__s.__sbuf_->sputn(__ob, __np) != __np) 1394*0b57cec5SDimitry Andric { 1395*0b57cec5SDimitry Andric __s.__sbuf_ = nullptr; 1396*0b57cec5SDimitry Andric return __s; 1397*0b57cec5SDimitry Andric } 1398*0b57cec5SDimitry Andric } 1399*0b57cec5SDimitry Andric if (__ns > 0) 1400*0b57cec5SDimitry Andric { 1401*0b57cec5SDimitry Andric basic_string<_CharT, _Traits> __sp(__ns, __fl); 1402*0b57cec5SDimitry Andric if (__s.__sbuf_->sputn(__sp.data(), __ns) != __ns) 1403*0b57cec5SDimitry Andric { 1404*0b57cec5SDimitry Andric __s.__sbuf_ = nullptr; 1405*0b57cec5SDimitry Andric return __s; 1406*0b57cec5SDimitry Andric } 1407*0b57cec5SDimitry Andric } 1408*0b57cec5SDimitry Andric __np = __oe - __op; 1409*0b57cec5SDimitry Andric if (__np > 0) 1410*0b57cec5SDimitry Andric { 1411*0b57cec5SDimitry Andric if (__s.__sbuf_->sputn(__op, __np) != __np) 1412*0b57cec5SDimitry Andric { 1413*0b57cec5SDimitry Andric __s.__sbuf_ = nullptr; 1414*0b57cec5SDimitry Andric return __s; 1415*0b57cec5SDimitry Andric } 1416*0b57cec5SDimitry Andric } 1417*0b57cec5SDimitry Andric __iob.width(0); 1418*0b57cec5SDimitry Andric return __s; 1419*0b57cec5SDimitry Andric} 1420*0b57cec5SDimitry Andric 1421*0b57cec5SDimitry Andrictemplate <class _CharT, class _OutputIterator> 1422*0b57cec5SDimitry Andric_OutputIterator 1423*0b57cec5SDimitry Andricnum_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, 1424*0b57cec5SDimitry Andric char_type __fl, bool __v) const 1425*0b57cec5SDimitry Andric{ 1426*0b57cec5SDimitry Andric if ((__iob.flags() & ios_base::boolalpha) == 0) 1427*0b57cec5SDimitry Andric return do_put(__s, __iob, __fl, (unsigned long)__v); 1428*0b57cec5SDimitry Andric const numpunct<char_type>& __np = use_facet<numpunct<char_type> >(__iob.getloc()); 1429*0b57cec5SDimitry Andric typedef typename numpunct<char_type>::string_type string_type; 1430*0b57cec5SDimitry Andric#if _LIBCPP_DEBUG_LEVEL >= 2 1431*0b57cec5SDimitry Andric string_type __tmp(__v ? __np.truename() : __np.falsename()); 1432*0b57cec5SDimitry Andric string_type __nm = _VSTD::move(__tmp); 1433*0b57cec5SDimitry Andric#else 1434*0b57cec5SDimitry Andric string_type __nm = __v ? __np.truename() : __np.falsename(); 1435*0b57cec5SDimitry Andric#endif 1436*0b57cec5SDimitry Andric for (typename string_type::iterator __i = __nm.begin(); __i != __nm.end(); ++__i, ++__s) 1437*0b57cec5SDimitry Andric *__s = *__i; 1438*0b57cec5SDimitry Andric return __s; 1439*0b57cec5SDimitry Andric} 1440*0b57cec5SDimitry Andric 1441*0b57cec5SDimitry Andrictemplate <class _CharT, class _OutputIterator> 1442*0b57cec5SDimitry Andric_OutputIterator 1443*0b57cec5SDimitry Andricnum_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, 1444*0b57cec5SDimitry Andric char_type __fl, long __v) const 1445*0b57cec5SDimitry Andric{ 1446*0b57cec5SDimitry Andric // Stage 1 - Get number in narrow char 1447*0b57cec5SDimitry Andric char __fmt[6] = {'%', 0}; 1448*0b57cec5SDimitry Andric const char* __len = "l"; 1449*0b57cec5SDimitry Andric this->__format_int(__fmt+1, __len, true, __iob.flags()); 1450*0b57cec5SDimitry Andric const unsigned __nbuf = (numeric_limits<long>::digits / 3) 1451*0b57cec5SDimitry Andric + ((numeric_limits<long>::digits % 3) != 0) 1452*0b57cec5SDimitry Andric + ((__iob.flags() & ios_base::showbase) != 0) 1453*0b57cec5SDimitry Andric + 2; 1454*0b57cec5SDimitry Andric char __nar[__nbuf]; 1455*0b57cec5SDimitry Andric int __nc = __libcpp_snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v); 1456*0b57cec5SDimitry Andric char* __ne = __nar + __nc; 1457*0b57cec5SDimitry Andric char* __np = this->__identify_padding(__nar, __ne, __iob); 1458*0b57cec5SDimitry Andric // Stage 2 - Widen __nar while adding thousands separators 1459*0b57cec5SDimitry Andric char_type __o[2*(__nbuf-1) - 1]; 1460*0b57cec5SDimitry Andric char_type* __op; // pad here 1461*0b57cec5SDimitry Andric char_type* __oe; // end of output 1462*0b57cec5SDimitry Andric this->__widen_and_group_int(__nar, __np, __ne, __o, __op, __oe, __iob.getloc()); 1463*0b57cec5SDimitry Andric // [__o, __oe) contains thousands_sep'd wide number 1464*0b57cec5SDimitry Andric // Stage 3 & 4 1465*0b57cec5SDimitry Andric return __pad_and_output(__s, __o, __op, __oe, __iob, __fl); 1466*0b57cec5SDimitry Andric} 1467*0b57cec5SDimitry Andric 1468*0b57cec5SDimitry Andrictemplate <class _CharT, class _OutputIterator> 1469*0b57cec5SDimitry Andric_OutputIterator 1470*0b57cec5SDimitry Andricnum_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, 1471*0b57cec5SDimitry Andric char_type __fl, long long __v) const 1472*0b57cec5SDimitry Andric{ 1473*0b57cec5SDimitry Andric // Stage 1 - Get number in narrow char 1474*0b57cec5SDimitry Andric char __fmt[8] = {'%', 0}; 1475*0b57cec5SDimitry Andric const char* __len = "ll"; 1476*0b57cec5SDimitry Andric this->__format_int(__fmt+1, __len, true, __iob.flags()); 1477*0b57cec5SDimitry Andric const unsigned __nbuf = (numeric_limits<long long>::digits / 3) 1478*0b57cec5SDimitry Andric + ((numeric_limits<long long>::digits % 3) != 0) 1479*0b57cec5SDimitry Andric + ((__iob.flags() & ios_base::showbase) != 0) 1480*0b57cec5SDimitry Andric + 2; 1481*0b57cec5SDimitry Andric char __nar[__nbuf]; 1482*0b57cec5SDimitry Andric int __nc = __libcpp_snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v); 1483*0b57cec5SDimitry Andric char* __ne = __nar + __nc; 1484*0b57cec5SDimitry Andric char* __np = this->__identify_padding(__nar, __ne, __iob); 1485*0b57cec5SDimitry Andric // Stage 2 - Widen __nar while adding thousands separators 1486*0b57cec5SDimitry Andric char_type __o[2*(__nbuf-1) - 1]; 1487*0b57cec5SDimitry Andric char_type* __op; // pad here 1488*0b57cec5SDimitry Andric char_type* __oe; // end of output 1489*0b57cec5SDimitry Andric this->__widen_and_group_int(__nar, __np, __ne, __o, __op, __oe, __iob.getloc()); 1490*0b57cec5SDimitry Andric // [__o, __oe) contains thousands_sep'd wide number 1491*0b57cec5SDimitry Andric // Stage 3 & 4 1492*0b57cec5SDimitry Andric return __pad_and_output(__s, __o, __op, __oe, __iob, __fl); 1493*0b57cec5SDimitry Andric} 1494*0b57cec5SDimitry Andric 1495*0b57cec5SDimitry Andrictemplate <class _CharT, class _OutputIterator> 1496*0b57cec5SDimitry Andric_OutputIterator 1497*0b57cec5SDimitry Andricnum_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, 1498*0b57cec5SDimitry Andric char_type __fl, unsigned long __v) const 1499*0b57cec5SDimitry Andric{ 1500*0b57cec5SDimitry Andric // Stage 1 - Get number in narrow char 1501*0b57cec5SDimitry Andric char __fmt[6] = {'%', 0}; 1502*0b57cec5SDimitry Andric const char* __len = "l"; 1503*0b57cec5SDimitry Andric this->__format_int(__fmt+1, __len, false, __iob.flags()); 1504*0b57cec5SDimitry Andric const unsigned __nbuf = (numeric_limits<unsigned long>::digits / 3) 1505*0b57cec5SDimitry Andric + ((numeric_limits<unsigned long>::digits % 3) != 0) 1506*0b57cec5SDimitry Andric + ((__iob.flags() & ios_base::showbase) != 0) 1507*0b57cec5SDimitry Andric + 1; 1508*0b57cec5SDimitry Andric char __nar[__nbuf]; 1509*0b57cec5SDimitry Andric int __nc = __libcpp_snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v); 1510*0b57cec5SDimitry Andric char* __ne = __nar + __nc; 1511*0b57cec5SDimitry Andric char* __np = this->__identify_padding(__nar, __ne, __iob); 1512*0b57cec5SDimitry Andric // Stage 2 - Widen __nar while adding thousands separators 1513*0b57cec5SDimitry Andric char_type __o[2*(__nbuf-1) - 1]; 1514*0b57cec5SDimitry Andric char_type* __op; // pad here 1515*0b57cec5SDimitry Andric char_type* __oe; // end of output 1516*0b57cec5SDimitry Andric this->__widen_and_group_int(__nar, __np, __ne, __o, __op, __oe, __iob.getloc()); 1517*0b57cec5SDimitry Andric // [__o, __oe) contains thousands_sep'd wide number 1518*0b57cec5SDimitry Andric // Stage 3 & 4 1519*0b57cec5SDimitry Andric return __pad_and_output(__s, __o, __op, __oe, __iob, __fl); 1520*0b57cec5SDimitry Andric} 1521*0b57cec5SDimitry Andric 1522*0b57cec5SDimitry Andrictemplate <class _CharT, class _OutputIterator> 1523*0b57cec5SDimitry Andric_OutputIterator 1524*0b57cec5SDimitry Andricnum_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, 1525*0b57cec5SDimitry Andric char_type __fl, unsigned long long __v) const 1526*0b57cec5SDimitry Andric{ 1527*0b57cec5SDimitry Andric // Stage 1 - Get number in narrow char 1528*0b57cec5SDimitry Andric char __fmt[8] = {'%', 0}; 1529*0b57cec5SDimitry Andric const char* __len = "ll"; 1530*0b57cec5SDimitry Andric this->__format_int(__fmt+1, __len, false, __iob.flags()); 1531*0b57cec5SDimitry Andric const unsigned __nbuf = (numeric_limits<unsigned long long>::digits / 3) 1532*0b57cec5SDimitry Andric + ((numeric_limits<unsigned long long>::digits % 3) != 0) 1533*0b57cec5SDimitry Andric + ((__iob.flags() & ios_base::showbase) != 0) 1534*0b57cec5SDimitry Andric + 1; 1535*0b57cec5SDimitry Andric char __nar[__nbuf]; 1536*0b57cec5SDimitry Andric int __nc = __libcpp_snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v); 1537*0b57cec5SDimitry Andric char* __ne = __nar + __nc; 1538*0b57cec5SDimitry Andric char* __np = this->__identify_padding(__nar, __ne, __iob); 1539*0b57cec5SDimitry Andric // Stage 2 - Widen __nar while adding thousands separators 1540*0b57cec5SDimitry Andric char_type __o[2*(__nbuf-1) - 1]; 1541*0b57cec5SDimitry Andric char_type* __op; // pad here 1542*0b57cec5SDimitry Andric char_type* __oe; // end of output 1543*0b57cec5SDimitry Andric this->__widen_and_group_int(__nar, __np, __ne, __o, __op, __oe, __iob.getloc()); 1544*0b57cec5SDimitry Andric // [__o, __oe) contains thousands_sep'd wide number 1545*0b57cec5SDimitry Andric // Stage 3 & 4 1546*0b57cec5SDimitry Andric return __pad_and_output(__s, __o, __op, __oe, __iob, __fl); 1547*0b57cec5SDimitry Andric} 1548*0b57cec5SDimitry Andric 1549*0b57cec5SDimitry Andrictemplate <class _CharT, class _OutputIterator> 1550*0b57cec5SDimitry Andric_OutputIterator 1551*0b57cec5SDimitry Andricnum_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, 1552*0b57cec5SDimitry Andric char_type __fl, double __v) const 1553*0b57cec5SDimitry Andric{ 1554*0b57cec5SDimitry Andric // Stage 1 - Get number in narrow char 1555*0b57cec5SDimitry Andric char __fmt[8] = {'%', 0}; 1556*0b57cec5SDimitry Andric const char* __len = ""; 1557*0b57cec5SDimitry Andric bool __specify_precision = this->__format_float(__fmt+1, __len, __iob.flags()); 1558*0b57cec5SDimitry Andric const unsigned __nbuf = 30; 1559*0b57cec5SDimitry Andric char __nar[__nbuf]; 1560*0b57cec5SDimitry Andric char* __nb = __nar; 1561*0b57cec5SDimitry Andric int __nc; 1562*0b57cec5SDimitry Andric if (__specify_precision) 1563*0b57cec5SDimitry Andric __nc = __libcpp_snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, 1564*0b57cec5SDimitry Andric (int)__iob.precision(), __v); 1565*0b57cec5SDimitry Andric else 1566*0b57cec5SDimitry Andric __nc = __libcpp_snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, __v); 1567*0b57cec5SDimitry Andric unique_ptr<char, void(*)(void*)> __nbh(0, free); 1568*0b57cec5SDimitry Andric if (__nc > static_cast<int>(__nbuf-1)) 1569*0b57cec5SDimitry Andric { 1570*0b57cec5SDimitry Andric if (__specify_precision) 1571*0b57cec5SDimitry Andric __nc = __libcpp_asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v); 1572*0b57cec5SDimitry Andric else 1573*0b57cec5SDimitry Andric __nc = __libcpp_asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, __v); 1574*0b57cec5SDimitry Andric if (__nb == 0) 1575*0b57cec5SDimitry Andric __throw_bad_alloc(); 1576*0b57cec5SDimitry Andric __nbh.reset(__nb); 1577*0b57cec5SDimitry Andric } 1578*0b57cec5SDimitry Andric char* __ne = __nb + __nc; 1579*0b57cec5SDimitry Andric char* __np = this->__identify_padding(__nb, __ne, __iob); 1580*0b57cec5SDimitry Andric // Stage 2 - Widen __nar while adding thousands separators 1581*0b57cec5SDimitry Andric char_type __o[2*(__nbuf-1) - 1]; 1582*0b57cec5SDimitry Andric char_type* __ob = __o; 1583*0b57cec5SDimitry Andric unique_ptr<char_type, void(*)(void*)> __obh(0, free); 1584*0b57cec5SDimitry Andric if (__nb != __nar) 1585*0b57cec5SDimitry Andric { 1586*0b57cec5SDimitry Andric __ob = (char_type*)malloc(2*static_cast<size_t>(__nc)*sizeof(char_type)); 1587*0b57cec5SDimitry Andric if (__ob == 0) 1588*0b57cec5SDimitry Andric __throw_bad_alloc(); 1589*0b57cec5SDimitry Andric __obh.reset(__ob); 1590*0b57cec5SDimitry Andric } 1591*0b57cec5SDimitry Andric char_type* __op; // pad here 1592*0b57cec5SDimitry Andric char_type* __oe; // end of output 1593*0b57cec5SDimitry Andric this->__widen_and_group_float(__nb, __np, __ne, __ob, __op, __oe, __iob.getloc()); 1594*0b57cec5SDimitry Andric // [__o, __oe) contains thousands_sep'd wide number 1595*0b57cec5SDimitry Andric // Stage 3 & 4 1596*0b57cec5SDimitry Andric __s = __pad_and_output(__s, __ob, __op, __oe, __iob, __fl); 1597*0b57cec5SDimitry Andric return __s; 1598*0b57cec5SDimitry Andric} 1599*0b57cec5SDimitry Andric 1600*0b57cec5SDimitry Andrictemplate <class _CharT, class _OutputIterator> 1601*0b57cec5SDimitry Andric_OutputIterator 1602*0b57cec5SDimitry Andricnum_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, 1603*0b57cec5SDimitry Andric char_type __fl, long double __v) const 1604*0b57cec5SDimitry Andric{ 1605*0b57cec5SDimitry Andric // Stage 1 - Get number in narrow char 1606*0b57cec5SDimitry Andric char __fmt[8] = {'%', 0}; 1607*0b57cec5SDimitry Andric const char* __len = "L"; 1608*0b57cec5SDimitry Andric bool __specify_precision = this->__format_float(__fmt+1, __len, __iob.flags()); 1609*0b57cec5SDimitry Andric const unsigned __nbuf = 30; 1610*0b57cec5SDimitry Andric char __nar[__nbuf]; 1611*0b57cec5SDimitry Andric char* __nb = __nar; 1612*0b57cec5SDimitry Andric int __nc; 1613*0b57cec5SDimitry Andric if (__specify_precision) 1614*0b57cec5SDimitry Andric __nc = __libcpp_snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, 1615*0b57cec5SDimitry Andric (int)__iob.precision(), __v); 1616*0b57cec5SDimitry Andric else 1617*0b57cec5SDimitry Andric __nc = __libcpp_snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, __v); 1618*0b57cec5SDimitry Andric unique_ptr<char, void(*)(void*)> __nbh(0, free); 1619*0b57cec5SDimitry Andric if (__nc > static_cast<int>(__nbuf-1)) 1620*0b57cec5SDimitry Andric { 1621*0b57cec5SDimitry Andric if (__specify_precision) 1622*0b57cec5SDimitry Andric __nc = __libcpp_asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v); 1623*0b57cec5SDimitry Andric else 1624*0b57cec5SDimitry Andric __nc = __libcpp_asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, __v); 1625*0b57cec5SDimitry Andric if (__nb == 0) 1626*0b57cec5SDimitry Andric __throw_bad_alloc(); 1627*0b57cec5SDimitry Andric __nbh.reset(__nb); 1628*0b57cec5SDimitry Andric } 1629*0b57cec5SDimitry Andric char* __ne = __nb + __nc; 1630*0b57cec5SDimitry Andric char* __np = this->__identify_padding(__nb, __ne, __iob); 1631*0b57cec5SDimitry Andric // Stage 2 - Widen __nar while adding thousands separators 1632*0b57cec5SDimitry Andric char_type __o[2*(__nbuf-1) - 1]; 1633*0b57cec5SDimitry Andric char_type* __ob = __o; 1634*0b57cec5SDimitry Andric unique_ptr<char_type, void(*)(void*)> __obh(0, free); 1635*0b57cec5SDimitry Andric if (__nb != __nar) 1636*0b57cec5SDimitry Andric { 1637*0b57cec5SDimitry Andric __ob = (char_type*)malloc(2*static_cast<size_t>(__nc)*sizeof(char_type)); 1638*0b57cec5SDimitry Andric if (__ob == 0) 1639*0b57cec5SDimitry Andric __throw_bad_alloc(); 1640*0b57cec5SDimitry Andric __obh.reset(__ob); 1641*0b57cec5SDimitry Andric } 1642*0b57cec5SDimitry Andric char_type* __op; // pad here 1643*0b57cec5SDimitry Andric char_type* __oe; // end of output 1644*0b57cec5SDimitry Andric this->__widen_and_group_float(__nb, __np, __ne, __ob, __op, __oe, __iob.getloc()); 1645*0b57cec5SDimitry Andric // [__o, __oe) contains thousands_sep'd wide number 1646*0b57cec5SDimitry Andric // Stage 3 & 4 1647*0b57cec5SDimitry Andric __s = __pad_and_output(__s, __ob, __op, __oe, __iob, __fl); 1648*0b57cec5SDimitry Andric return __s; 1649*0b57cec5SDimitry Andric} 1650*0b57cec5SDimitry Andric 1651*0b57cec5SDimitry Andrictemplate <class _CharT, class _OutputIterator> 1652*0b57cec5SDimitry Andric_OutputIterator 1653*0b57cec5SDimitry Andricnum_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, 1654*0b57cec5SDimitry Andric char_type __fl, const void* __v) const 1655*0b57cec5SDimitry Andric{ 1656*0b57cec5SDimitry Andric // Stage 1 - Get pointer in narrow char 1657*0b57cec5SDimitry Andric char __fmt[6] = "%p"; 1658*0b57cec5SDimitry Andric const unsigned __nbuf = 20; 1659*0b57cec5SDimitry Andric char __nar[__nbuf]; 1660*0b57cec5SDimitry Andric int __nc = __libcpp_snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v); 1661*0b57cec5SDimitry Andric char* __ne = __nar + __nc; 1662*0b57cec5SDimitry Andric char* __np = this->__identify_padding(__nar, __ne, __iob); 1663*0b57cec5SDimitry Andric // Stage 2 - Widen __nar 1664*0b57cec5SDimitry Andric char_type __o[2*(__nbuf-1) - 1]; 1665*0b57cec5SDimitry Andric char_type* __op; // pad here 1666*0b57cec5SDimitry Andric char_type* __oe; // end of output 1667*0b57cec5SDimitry Andric const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc()); 1668*0b57cec5SDimitry Andric __ct.widen(__nar, __ne, __o); 1669*0b57cec5SDimitry Andric __oe = __o + (__ne - __nar); 1670*0b57cec5SDimitry Andric if (__np == __ne) 1671*0b57cec5SDimitry Andric __op = __oe; 1672*0b57cec5SDimitry Andric else 1673*0b57cec5SDimitry Andric __op = __o + (__np - __nar); 1674*0b57cec5SDimitry Andric // [__o, __oe) contains wide number 1675*0b57cec5SDimitry Andric // Stage 3 & 4 1676*0b57cec5SDimitry Andric return __pad_and_output(__s, __o, __op, __oe, __iob, __fl); 1677*0b57cec5SDimitry Andric} 1678*0b57cec5SDimitry Andric 1679*0b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS num_put<char>) 1680*0b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS num_put<wchar_t>) 1681*0b57cec5SDimitry Andric 1682*0b57cec5SDimitry Andrictemplate <class _CharT, class _InputIterator> 1683*0b57cec5SDimitry Andric_LIBCPP_HIDDEN 1684*0b57cec5SDimitry Andricint 1685*0b57cec5SDimitry Andric__get_up_to_n_digits(_InputIterator& __b, _InputIterator __e, 1686*0b57cec5SDimitry Andric ios_base::iostate& __err, const ctype<_CharT>& __ct, int __n) 1687*0b57cec5SDimitry Andric{ 1688*0b57cec5SDimitry Andric // Precondition: __n >= 1 1689*0b57cec5SDimitry Andric if (__b == __e) 1690*0b57cec5SDimitry Andric { 1691*0b57cec5SDimitry Andric __err |= ios_base::eofbit | ios_base::failbit; 1692*0b57cec5SDimitry Andric return 0; 1693*0b57cec5SDimitry Andric } 1694*0b57cec5SDimitry Andric // get first digit 1695*0b57cec5SDimitry Andric _CharT __c = *__b; 1696*0b57cec5SDimitry Andric if (!__ct.is(ctype_base::digit, __c)) 1697*0b57cec5SDimitry Andric { 1698*0b57cec5SDimitry Andric __err |= ios_base::failbit; 1699*0b57cec5SDimitry Andric return 0; 1700*0b57cec5SDimitry Andric } 1701*0b57cec5SDimitry Andric int __r = __ct.narrow(__c, 0) - '0'; 1702*0b57cec5SDimitry Andric for (++__b, (void) --__n; __b != __e && __n > 0; ++__b, (void) --__n) 1703*0b57cec5SDimitry Andric { 1704*0b57cec5SDimitry Andric // get next digit 1705*0b57cec5SDimitry Andric __c = *__b; 1706*0b57cec5SDimitry Andric if (!__ct.is(ctype_base::digit, __c)) 1707*0b57cec5SDimitry Andric return __r; 1708*0b57cec5SDimitry Andric __r = __r * 10 + __ct.narrow(__c, 0) - '0'; 1709*0b57cec5SDimitry Andric } 1710*0b57cec5SDimitry Andric if (__b == __e) 1711*0b57cec5SDimitry Andric __err |= ios_base::eofbit; 1712*0b57cec5SDimitry Andric return __r; 1713*0b57cec5SDimitry Andric} 1714*0b57cec5SDimitry Andric 1715*0b57cec5SDimitry Andricclass _LIBCPP_TYPE_VIS time_base 1716*0b57cec5SDimitry Andric{ 1717*0b57cec5SDimitry Andricpublic: 1718*0b57cec5SDimitry Andric enum dateorder {no_order, dmy, mdy, ymd, ydm}; 1719*0b57cec5SDimitry Andric}; 1720*0b57cec5SDimitry Andric 1721*0b57cec5SDimitry Andrictemplate <class _CharT> 1722*0b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS __time_get_c_storage 1723*0b57cec5SDimitry Andric{ 1724*0b57cec5SDimitry Andricprotected: 1725*0b57cec5SDimitry Andric typedef basic_string<_CharT> string_type; 1726*0b57cec5SDimitry Andric 1727*0b57cec5SDimitry Andric virtual const string_type* __weeks() const; 1728*0b57cec5SDimitry Andric virtual const string_type* __months() const; 1729*0b57cec5SDimitry Andric virtual const string_type* __am_pm() const; 1730*0b57cec5SDimitry Andric virtual const string_type& __c() const; 1731*0b57cec5SDimitry Andric virtual const string_type& __r() const; 1732*0b57cec5SDimitry Andric virtual const string_type& __x() const; 1733*0b57cec5SDimitry Andric virtual const string_type& __X() const; 1734*0b57cec5SDimitry Andric 1735*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1736*0b57cec5SDimitry Andric ~__time_get_c_storage() {} 1737*0b57cec5SDimitry Andric}; 1738*0b57cec5SDimitry Andric 1739*0b57cec5SDimitry Andrictemplate <> _LIBCPP_FUNC_VIS const string* __time_get_c_storage<char>::__weeks() const; 1740*0b57cec5SDimitry Andrictemplate <> _LIBCPP_FUNC_VIS const string* __time_get_c_storage<char>::__months() const; 1741*0b57cec5SDimitry Andrictemplate <> _LIBCPP_FUNC_VIS const string* __time_get_c_storage<char>::__am_pm() const; 1742*0b57cec5SDimitry Andrictemplate <> _LIBCPP_FUNC_VIS const string& __time_get_c_storage<char>::__c() const; 1743*0b57cec5SDimitry Andrictemplate <> _LIBCPP_FUNC_VIS const string& __time_get_c_storage<char>::__r() const; 1744*0b57cec5SDimitry Andrictemplate <> _LIBCPP_FUNC_VIS const string& __time_get_c_storage<char>::__x() const; 1745*0b57cec5SDimitry Andrictemplate <> _LIBCPP_FUNC_VIS const string& __time_get_c_storage<char>::__X() const; 1746*0b57cec5SDimitry Andric 1747*0b57cec5SDimitry Andrictemplate <> _LIBCPP_FUNC_VIS const wstring* __time_get_c_storage<wchar_t>::__weeks() const; 1748*0b57cec5SDimitry Andrictemplate <> _LIBCPP_FUNC_VIS const wstring* __time_get_c_storage<wchar_t>::__months() const; 1749*0b57cec5SDimitry Andrictemplate <> _LIBCPP_FUNC_VIS const wstring* __time_get_c_storage<wchar_t>::__am_pm() const; 1750*0b57cec5SDimitry Andrictemplate <> _LIBCPP_FUNC_VIS const wstring& __time_get_c_storage<wchar_t>::__c() const; 1751*0b57cec5SDimitry Andrictemplate <> _LIBCPP_FUNC_VIS const wstring& __time_get_c_storage<wchar_t>::__r() const; 1752*0b57cec5SDimitry Andrictemplate <> _LIBCPP_FUNC_VIS const wstring& __time_get_c_storage<wchar_t>::__x() const; 1753*0b57cec5SDimitry Andrictemplate <> _LIBCPP_FUNC_VIS const wstring& __time_get_c_storage<wchar_t>::__X() const; 1754*0b57cec5SDimitry Andric 1755*0b57cec5SDimitry Andrictemplate <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> > 1756*0b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS time_get 1757*0b57cec5SDimitry Andric : public locale::facet, 1758*0b57cec5SDimitry Andric public time_base, 1759*0b57cec5SDimitry Andric private __time_get_c_storage<_CharT> 1760*0b57cec5SDimitry Andric{ 1761*0b57cec5SDimitry Andricpublic: 1762*0b57cec5SDimitry Andric typedef _CharT char_type; 1763*0b57cec5SDimitry Andric typedef _InputIterator iter_type; 1764*0b57cec5SDimitry Andric typedef time_base::dateorder dateorder; 1765*0b57cec5SDimitry Andric typedef basic_string<char_type> string_type; 1766*0b57cec5SDimitry Andric 1767*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1768*0b57cec5SDimitry Andric explicit time_get(size_t __refs = 0) 1769*0b57cec5SDimitry Andric : locale::facet(__refs) {} 1770*0b57cec5SDimitry Andric 1771*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1772*0b57cec5SDimitry Andric dateorder date_order() const 1773*0b57cec5SDimitry Andric { 1774*0b57cec5SDimitry Andric return this->do_date_order(); 1775*0b57cec5SDimitry Andric } 1776*0b57cec5SDimitry Andric 1777*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1778*0b57cec5SDimitry Andric iter_type get_time(iter_type __b, iter_type __e, ios_base& __iob, 1779*0b57cec5SDimitry Andric ios_base::iostate& __err, tm* __tm) const 1780*0b57cec5SDimitry Andric { 1781*0b57cec5SDimitry Andric return do_get_time(__b, __e, __iob, __err, __tm); 1782*0b57cec5SDimitry Andric } 1783*0b57cec5SDimitry Andric 1784*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1785*0b57cec5SDimitry Andric iter_type get_date(iter_type __b, iter_type __e, ios_base& __iob, 1786*0b57cec5SDimitry Andric ios_base::iostate& __err, tm* __tm) const 1787*0b57cec5SDimitry Andric { 1788*0b57cec5SDimitry Andric return do_get_date(__b, __e, __iob, __err, __tm); 1789*0b57cec5SDimitry Andric } 1790*0b57cec5SDimitry Andric 1791*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1792*0b57cec5SDimitry Andric iter_type get_weekday(iter_type __b, iter_type __e, ios_base& __iob, 1793*0b57cec5SDimitry Andric ios_base::iostate& __err, tm* __tm) const 1794*0b57cec5SDimitry Andric { 1795*0b57cec5SDimitry Andric return do_get_weekday(__b, __e, __iob, __err, __tm); 1796*0b57cec5SDimitry Andric } 1797*0b57cec5SDimitry Andric 1798*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1799*0b57cec5SDimitry Andric iter_type get_monthname(iter_type __b, iter_type __e, ios_base& __iob, 1800*0b57cec5SDimitry Andric ios_base::iostate& __err, tm* __tm) const 1801*0b57cec5SDimitry Andric { 1802*0b57cec5SDimitry Andric return do_get_monthname(__b, __e, __iob, __err, __tm); 1803*0b57cec5SDimitry Andric } 1804*0b57cec5SDimitry Andric 1805*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1806*0b57cec5SDimitry Andric iter_type get_year(iter_type __b, iter_type __e, ios_base& __iob, 1807*0b57cec5SDimitry Andric ios_base::iostate& __err, tm* __tm) const 1808*0b57cec5SDimitry Andric { 1809*0b57cec5SDimitry Andric return do_get_year(__b, __e, __iob, __err, __tm); 1810*0b57cec5SDimitry Andric } 1811*0b57cec5SDimitry Andric 1812*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1813*0b57cec5SDimitry Andric iter_type get(iter_type __b, iter_type __e, ios_base& __iob, 1814*0b57cec5SDimitry Andric ios_base::iostate& __err, tm *__tm, 1815*0b57cec5SDimitry Andric char __fmt, char __mod = 0) const 1816*0b57cec5SDimitry Andric { 1817*0b57cec5SDimitry Andric return do_get(__b, __e, __iob, __err, __tm, __fmt, __mod); 1818*0b57cec5SDimitry Andric } 1819*0b57cec5SDimitry Andric 1820*0b57cec5SDimitry Andric iter_type get(iter_type __b, iter_type __e, ios_base& __iob, 1821*0b57cec5SDimitry Andric ios_base::iostate& __err, tm* __tm, 1822*0b57cec5SDimitry Andric const char_type* __fmtb, const char_type* __fmte) const; 1823*0b57cec5SDimitry Andric 1824*0b57cec5SDimitry Andric static locale::id id; 1825*0b57cec5SDimitry Andric 1826*0b57cec5SDimitry Andricprotected: 1827*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1828*0b57cec5SDimitry Andric ~time_get() {} 1829*0b57cec5SDimitry Andric 1830*0b57cec5SDimitry Andric virtual dateorder do_date_order() const; 1831*0b57cec5SDimitry Andric virtual iter_type do_get_time(iter_type __b, iter_type __e, ios_base& __iob, 1832*0b57cec5SDimitry Andric ios_base::iostate& __err, tm* __tm) const; 1833*0b57cec5SDimitry Andric virtual iter_type do_get_date(iter_type __b, iter_type __e, ios_base& __iob, 1834*0b57cec5SDimitry Andric ios_base::iostate& __err, tm* __tm) const; 1835*0b57cec5SDimitry Andric virtual iter_type do_get_weekday(iter_type __b, iter_type __e, ios_base& __iob, 1836*0b57cec5SDimitry Andric ios_base::iostate& __err, tm* __tm) const; 1837*0b57cec5SDimitry Andric virtual iter_type do_get_monthname(iter_type __b, iter_type __e, ios_base& __iob, 1838*0b57cec5SDimitry Andric ios_base::iostate& __err, tm* __tm) const; 1839*0b57cec5SDimitry Andric virtual iter_type do_get_year(iter_type __b, iter_type __e, ios_base& __iob, 1840*0b57cec5SDimitry Andric ios_base::iostate& __err, tm* __tm) const; 1841*0b57cec5SDimitry Andric virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob, 1842*0b57cec5SDimitry Andric ios_base::iostate& __err, tm* __tm, 1843*0b57cec5SDimitry Andric char __fmt, char __mod) const; 1844*0b57cec5SDimitry Andricprivate: 1845*0b57cec5SDimitry Andric void __get_white_space(iter_type& __b, iter_type __e, 1846*0b57cec5SDimitry Andric ios_base::iostate& __err, const ctype<char_type>& __ct) const; 1847*0b57cec5SDimitry Andric void __get_percent(iter_type& __b, iter_type __e, ios_base::iostate& __err, 1848*0b57cec5SDimitry Andric const ctype<char_type>& __ct) const; 1849*0b57cec5SDimitry Andric 1850*0b57cec5SDimitry Andric void __get_weekdayname(int& __m, 1851*0b57cec5SDimitry Andric iter_type& __b, iter_type __e, 1852*0b57cec5SDimitry Andric ios_base::iostate& __err, 1853*0b57cec5SDimitry Andric const ctype<char_type>& __ct) const; 1854*0b57cec5SDimitry Andric void __get_monthname(int& __m, 1855*0b57cec5SDimitry Andric iter_type& __b, iter_type __e, 1856*0b57cec5SDimitry Andric ios_base::iostate& __err, 1857*0b57cec5SDimitry Andric const ctype<char_type>& __ct) const; 1858*0b57cec5SDimitry Andric void __get_day(int& __d, 1859*0b57cec5SDimitry Andric iter_type& __b, iter_type __e, 1860*0b57cec5SDimitry Andric ios_base::iostate& __err, 1861*0b57cec5SDimitry Andric const ctype<char_type>& __ct) const; 1862*0b57cec5SDimitry Andric void __get_month(int& __m, 1863*0b57cec5SDimitry Andric iter_type& __b, iter_type __e, 1864*0b57cec5SDimitry Andric ios_base::iostate& __err, 1865*0b57cec5SDimitry Andric const ctype<char_type>& __ct) const; 1866*0b57cec5SDimitry Andric void __get_year(int& __y, 1867*0b57cec5SDimitry Andric iter_type& __b, iter_type __e, 1868*0b57cec5SDimitry Andric ios_base::iostate& __err, 1869*0b57cec5SDimitry Andric const ctype<char_type>& __ct) const; 1870*0b57cec5SDimitry Andric void __get_year4(int& __y, 1871*0b57cec5SDimitry Andric iter_type& __b, iter_type __e, 1872*0b57cec5SDimitry Andric ios_base::iostate& __err, 1873*0b57cec5SDimitry Andric const ctype<char_type>& __ct) const; 1874*0b57cec5SDimitry Andric void __get_hour(int& __d, 1875*0b57cec5SDimitry Andric iter_type& __b, iter_type __e, 1876*0b57cec5SDimitry Andric ios_base::iostate& __err, 1877*0b57cec5SDimitry Andric const ctype<char_type>& __ct) const; 1878*0b57cec5SDimitry Andric void __get_12_hour(int& __h, 1879*0b57cec5SDimitry Andric iter_type& __b, iter_type __e, 1880*0b57cec5SDimitry Andric ios_base::iostate& __err, 1881*0b57cec5SDimitry Andric const ctype<char_type>& __ct) const; 1882*0b57cec5SDimitry Andric void __get_am_pm(int& __h, 1883*0b57cec5SDimitry Andric iter_type& __b, iter_type __e, 1884*0b57cec5SDimitry Andric ios_base::iostate& __err, 1885*0b57cec5SDimitry Andric const ctype<char_type>& __ct) const; 1886*0b57cec5SDimitry Andric void __get_minute(int& __m, 1887*0b57cec5SDimitry Andric iter_type& __b, iter_type __e, 1888*0b57cec5SDimitry Andric ios_base::iostate& __err, 1889*0b57cec5SDimitry Andric const ctype<char_type>& __ct) const; 1890*0b57cec5SDimitry Andric void __get_second(int& __s, 1891*0b57cec5SDimitry Andric iter_type& __b, iter_type __e, 1892*0b57cec5SDimitry Andric ios_base::iostate& __err, 1893*0b57cec5SDimitry Andric const ctype<char_type>& __ct) const; 1894*0b57cec5SDimitry Andric void __get_weekday(int& __w, 1895*0b57cec5SDimitry Andric iter_type& __b, iter_type __e, 1896*0b57cec5SDimitry Andric ios_base::iostate& __err, 1897*0b57cec5SDimitry Andric const ctype<char_type>& __ct) const; 1898*0b57cec5SDimitry Andric void __get_day_year_num(int& __w, 1899*0b57cec5SDimitry Andric iter_type& __b, iter_type __e, 1900*0b57cec5SDimitry Andric ios_base::iostate& __err, 1901*0b57cec5SDimitry Andric const ctype<char_type>& __ct) const; 1902*0b57cec5SDimitry Andric}; 1903*0b57cec5SDimitry Andric 1904*0b57cec5SDimitry Andrictemplate <class _CharT, class _InputIterator> 1905*0b57cec5SDimitry Andriclocale::id 1906*0b57cec5SDimitry Andrictime_get<_CharT, _InputIterator>::id; 1907*0b57cec5SDimitry Andric 1908*0b57cec5SDimitry Andric// time_get primitives 1909*0b57cec5SDimitry Andric 1910*0b57cec5SDimitry Andrictemplate <class _CharT, class _InputIterator> 1911*0b57cec5SDimitry Andricvoid 1912*0b57cec5SDimitry Andrictime_get<_CharT, _InputIterator>::__get_weekdayname(int& __w, 1913*0b57cec5SDimitry Andric iter_type& __b, iter_type __e, 1914*0b57cec5SDimitry Andric ios_base::iostate& __err, 1915*0b57cec5SDimitry Andric const ctype<char_type>& __ct) const 1916*0b57cec5SDimitry Andric{ 1917*0b57cec5SDimitry Andric // Note: ignoring case comes from the POSIX strptime spec 1918*0b57cec5SDimitry Andric const string_type* __wk = this->__weeks(); 1919*0b57cec5SDimitry Andric ptrdiff_t __i = __scan_keyword(__b, __e, __wk, __wk+14, __ct, __err, false) - __wk; 1920*0b57cec5SDimitry Andric if (__i < 14) 1921*0b57cec5SDimitry Andric __w = __i % 7; 1922*0b57cec5SDimitry Andric} 1923*0b57cec5SDimitry Andric 1924*0b57cec5SDimitry Andrictemplate <class _CharT, class _InputIterator> 1925*0b57cec5SDimitry Andricvoid 1926*0b57cec5SDimitry Andrictime_get<_CharT, _InputIterator>::__get_monthname(int& __m, 1927*0b57cec5SDimitry Andric iter_type& __b, iter_type __e, 1928*0b57cec5SDimitry Andric ios_base::iostate& __err, 1929*0b57cec5SDimitry Andric const ctype<char_type>& __ct) const 1930*0b57cec5SDimitry Andric{ 1931*0b57cec5SDimitry Andric // Note: ignoring case comes from the POSIX strptime spec 1932*0b57cec5SDimitry Andric const string_type* __month = this->__months(); 1933*0b57cec5SDimitry Andric ptrdiff_t __i = __scan_keyword(__b, __e, __month, __month+24, __ct, __err, false) - __month; 1934*0b57cec5SDimitry Andric if (__i < 24) 1935*0b57cec5SDimitry Andric __m = __i % 12; 1936*0b57cec5SDimitry Andric} 1937*0b57cec5SDimitry Andric 1938*0b57cec5SDimitry Andrictemplate <class _CharT, class _InputIterator> 1939*0b57cec5SDimitry Andricvoid 1940*0b57cec5SDimitry Andrictime_get<_CharT, _InputIterator>::__get_day(int& __d, 1941*0b57cec5SDimitry Andric iter_type& __b, iter_type __e, 1942*0b57cec5SDimitry Andric ios_base::iostate& __err, 1943*0b57cec5SDimitry Andric const ctype<char_type>& __ct) const 1944*0b57cec5SDimitry Andric{ 1945*0b57cec5SDimitry Andric int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2); 1946*0b57cec5SDimitry Andric if (!(__err & ios_base::failbit) && 1 <= __t && __t <= 31) 1947*0b57cec5SDimitry Andric __d = __t; 1948*0b57cec5SDimitry Andric else 1949*0b57cec5SDimitry Andric __err |= ios_base::failbit; 1950*0b57cec5SDimitry Andric} 1951*0b57cec5SDimitry Andric 1952*0b57cec5SDimitry Andrictemplate <class _CharT, class _InputIterator> 1953*0b57cec5SDimitry Andricvoid 1954*0b57cec5SDimitry Andrictime_get<_CharT, _InputIterator>::__get_month(int& __m, 1955*0b57cec5SDimitry Andric iter_type& __b, iter_type __e, 1956*0b57cec5SDimitry Andric ios_base::iostate& __err, 1957*0b57cec5SDimitry Andric const ctype<char_type>& __ct) const 1958*0b57cec5SDimitry Andric{ 1959*0b57cec5SDimitry Andric int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2) - 1; 1960*0b57cec5SDimitry Andric if (!(__err & ios_base::failbit) && __t <= 11) 1961*0b57cec5SDimitry Andric __m = __t; 1962*0b57cec5SDimitry Andric else 1963*0b57cec5SDimitry Andric __err |= ios_base::failbit; 1964*0b57cec5SDimitry Andric} 1965*0b57cec5SDimitry Andric 1966*0b57cec5SDimitry Andrictemplate <class _CharT, class _InputIterator> 1967*0b57cec5SDimitry Andricvoid 1968*0b57cec5SDimitry Andrictime_get<_CharT, _InputIterator>::__get_year(int& __y, 1969*0b57cec5SDimitry Andric iter_type& __b, iter_type __e, 1970*0b57cec5SDimitry Andric ios_base::iostate& __err, 1971*0b57cec5SDimitry Andric const ctype<char_type>& __ct) const 1972*0b57cec5SDimitry Andric{ 1973*0b57cec5SDimitry Andric int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 4); 1974*0b57cec5SDimitry Andric if (!(__err & ios_base::failbit)) 1975*0b57cec5SDimitry Andric { 1976*0b57cec5SDimitry Andric if (__t < 69) 1977*0b57cec5SDimitry Andric __t += 2000; 1978*0b57cec5SDimitry Andric else if (69 <= __t && __t <= 99) 1979*0b57cec5SDimitry Andric __t += 1900; 1980*0b57cec5SDimitry Andric __y = __t - 1900; 1981*0b57cec5SDimitry Andric } 1982*0b57cec5SDimitry Andric} 1983*0b57cec5SDimitry Andric 1984*0b57cec5SDimitry Andrictemplate <class _CharT, class _InputIterator> 1985*0b57cec5SDimitry Andricvoid 1986*0b57cec5SDimitry Andrictime_get<_CharT, _InputIterator>::__get_year4(int& __y, 1987*0b57cec5SDimitry Andric iter_type& __b, iter_type __e, 1988*0b57cec5SDimitry Andric ios_base::iostate& __err, 1989*0b57cec5SDimitry Andric const ctype<char_type>& __ct) const 1990*0b57cec5SDimitry Andric{ 1991*0b57cec5SDimitry Andric int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 4); 1992*0b57cec5SDimitry Andric if (!(__err & ios_base::failbit)) 1993*0b57cec5SDimitry Andric __y = __t - 1900; 1994*0b57cec5SDimitry Andric} 1995*0b57cec5SDimitry Andric 1996*0b57cec5SDimitry Andrictemplate <class _CharT, class _InputIterator> 1997*0b57cec5SDimitry Andricvoid 1998*0b57cec5SDimitry Andrictime_get<_CharT, _InputIterator>::__get_hour(int& __h, 1999*0b57cec5SDimitry Andric iter_type& __b, iter_type __e, 2000*0b57cec5SDimitry Andric ios_base::iostate& __err, 2001*0b57cec5SDimitry Andric const ctype<char_type>& __ct) const 2002*0b57cec5SDimitry Andric{ 2003*0b57cec5SDimitry Andric int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2); 2004*0b57cec5SDimitry Andric if (!(__err & ios_base::failbit) && __t <= 23) 2005*0b57cec5SDimitry Andric __h = __t; 2006*0b57cec5SDimitry Andric else 2007*0b57cec5SDimitry Andric __err |= ios_base::failbit; 2008*0b57cec5SDimitry Andric} 2009*0b57cec5SDimitry Andric 2010*0b57cec5SDimitry Andrictemplate <class _CharT, class _InputIterator> 2011*0b57cec5SDimitry Andricvoid 2012*0b57cec5SDimitry Andrictime_get<_CharT, _InputIterator>::__get_12_hour(int& __h, 2013*0b57cec5SDimitry Andric iter_type& __b, iter_type __e, 2014*0b57cec5SDimitry Andric ios_base::iostate& __err, 2015*0b57cec5SDimitry Andric const ctype<char_type>& __ct) const 2016*0b57cec5SDimitry Andric{ 2017*0b57cec5SDimitry Andric int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2); 2018*0b57cec5SDimitry Andric if (!(__err & ios_base::failbit) && 1 <= __t && __t <= 12) 2019*0b57cec5SDimitry Andric __h = __t; 2020*0b57cec5SDimitry Andric else 2021*0b57cec5SDimitry Andric __err |= ios_base::failbit; 2022*0b57cec5SDimitry Andric} 2023*0b57cec5SDimitry Andric 2024*0b57cec5SDimitry Andrictemplate <class _CharT, class _InputIterator> 2025*0b57cec5SDimitry Andricvoid 2026*0b57cec5SDimitry Andrictime_get<_CharT, _InputIterator>::__get_minute(int& __m, 2027*0b57cec5SDimitry Andric iter_type& __b, iter_type __e, 2028*0b57cec5SDimitry Andric ios_base::iostate& __err, 2029*0b57cec5SDimitry Andric const ctype<char_type>& __ct) const 2030*0b57cec5SDimitry Andric{ 2031*0b57cec5SDimitry Andric int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2); 2032*0b57cec5SDimitry Andric if (!(__err & ios_base::failbit) && __t <= 59) 2033*0b57cec5SDimitry Andric __m = __t; 2034*0b57cec5SDimitry Andric else 2035*0b57cec5SDimitry Andric __err |= ios_base::failbit; 2036*0b57cec5SDimitry Andric} 2037*0b57cec5SDimitry Andric 2038*0b57cec5SDimitry Andrictemplate <class _CharT, class _InputIterator> 2039*0b57cec5SDimitry Andricvoid 2040*0b57cec5SDimitry Andrictime_get<_CharT, _InputIterator>::__get_second(int& __s, 2041*0b57cec5SDimitry Andric iter_type& __b, iter_type __e, 2042*0b57cec5SDimitry Andric ios_base::iostate& __err, 2043*0b57cec5SDimitry Andric const ctype<char_type>& __ct) const 2044*0b57cec5SDimitry Andric{ 2045*0b57cec5SDimitry Andric int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2); 2046*0b57cec5SDimitry Andric if (!(__err & ios_base::failbit) && __t <= 60) 2047*0b57cec5SDimitry Andric __s = __t; 2048*0b57cec5SDimitry Andric else 2049*0b57cec5SDimitry Andric __err |= ios_base::failbit; 2050*0b57cec5SDimitry Andric} 2051*0b57cec5SDimitry Andric 2052*0b57cec5SDimitry Andrictemplate <class _CharT, class _InputIterator> 2053*0b57cec5SDimitry Andricvoid 2054*0b57cec5SDimitry Andrictime_get<_CharT, _InputIterator>::__get_weekday(int& __w, 2055*0b57cec5SDimitry Andric iter_type& __b, iter_type __e, 2056*0b57cec5SDimitry Andric ios_base::iostate& __err, 2057*0b57cec5SDimitry Andric const ctype<char_type>& __ct) const 2058*0b57cec5SDimitry Andric{ 2059*0b57cec5SDimitry Andric int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 1); 2060*0b57cec5SDimitry Andric if (!(__err & ios_base::failbit) && __t <= 6) 2061*0b57cec5SDimitry Andric __w = __t; 2062*0b57cec5SDimitry Andric else 2063*0b57cec5SDimitry Andric __err |= ios_base::failbit; 2064*0b57cec5SDimitry Andric} 2065*0b57cec5SDimitry Andric 2066*0b57cec5SDimitry Andrictemplate <class _CharT, class _InputIterator> 2067*0b57cec5SDimitry Andricvoid 2068*0b57cec5SDimitry Andrictime_get<_CharT, _InputIterator>::__get_day_year_num(int& __d, 2069*0b57cec5SDimitry Andric iter_type& __b, iter_type __e, 2070*0b57cec5SDimitry Andric ios_base::iostate& __err, 2071*0b57cec5SDimitry Andric const ctype<char_type>& __ct) const 2072*0b57cec5SDimitry Andric{ 2073*0b57cec5SDimitry Andric int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 3); 2074*0b57cec5SDimitry Andric if (!(__err & ios_base::failbit) && __t <= 365) 2075*0b57cec5SDimitry Andric __d = __t; 2076*0b57cec5SDimitry Andric else 2077*0b57cec5SDimitry Andric __err |= ios_base::failbit; 2078*0b57cec5SDimitry Andric} 2079*0b57cec5SDimitry Andric 2080*0b57cec5SDimitry Andrictemplate <class _CharT, class _InputIterator> 2081*0b57cec5SDimitry Andricvoid 2082*0b57cec5SDimitry Andrictime_get<_CharT, _InputIterator>::__get_white_space(iter_type& __b, iter_type __e, 2083*0b57cec5SDimitry Andric ios_base::iostate& __err, 2084*0b57cec5SDimitry Andric const ctype<char_type>& __ct) const 2085*0b57cec5SDimitry Andric{ 2086*0b57cec5SDimitry Andric for (; __b != __e && __ct.is(ctype_base::space, *__b); ++__b) 2087*0b57cec5SDimitry Andric ; 2088*0b57cec5SDimitry Andric if (__b == __e) 2089*0b57cec5SDimitry Andric __err |= ios_base::eofbit; 2090*0b57cec5SDimitry Andric} 2091*0b57cec5SDimitry Andric 2092*0b57cec5SDimitry Andrictemplate <class _CharT, class _InputIterator> 2093*0b57cec5SDimitry Andricvoid 2094*0b57cec5SDimitry Andrictime_get<_CharT, _InputIterator>::__get_am_pm(int& __h, 2095*0b57cec5SDimitry Andric iter_type& __b, iter_type __e, 2096*0b57cec5SDimitry Andric ios_base::iostate& __err, 2097*0b57cec5SDimitry Andric const ctype<char_type>& __ct) const 2098*0b57cec5SDimitry Andric{ 2099*0b57cec5SDimitry Andric const string_type* __ap = this->__am_pm(); 2100*0b57cec5SDimitry Andric if (__ap[0].size() + __ap[1].size() == 0) 2101*0b57cec5SDimitry Andric { 2102*0b57cec5SDimitry Andric __err |= ios_base::failbit; 2103*0b57cec5SDimitry Andric return; 2104*0b57cec5SDimitry Andric } 2105*0b57cec5SDimitry Andric ptrdiff_t __i = __scan_keyword(__b, __e, __ap, __ap+2, __ct, __err, false) - __ap; 2106*0b57cec5SDimitry Andric if (__i == 0 && __h == 12) 2107*0b57cec5SDimitry Andric __h = 0; 2108*0b57cec5SDimitry Andric else if (__i == 1 && __h < 12) 2109*0b57cec5SDimitry Andric __h += 12; 2110*0b57cec5SDimitry Andric} 2111*0b57cec5SDimitry Andric 2112*0b57cec5SDimitry Andrictemplate <class _CharT, class _InputIterator> 2113*0b57cec5SDimitry Andricvoid 2114*0b57cec5SDimitry Andrictime_get<_CharT, _InputIterator>::__get_percent(iter_type& __b, iter_type __e, 2115*0b57cec5SDimitry Andric ios_base::iostate& __err, 2116*0b57cec5SDimitry Andric const ctype<char_type>& __ct) const 2117*0b57cec5SDimitry Andric{ 2118*0b57cec5SDimitry Andric if (__b == __e) 2119*0b57cec5SDimitry Andric { 2120*0b57cec5SDimitry Andric __err |= ios_base::eofbit | ios_base::failbit; 2121*0b57cec5SDimitry Andric return; 2122*0b57cec5SDimitry Andric } 2123*0b57cec5SDimitry Andric if (__ct.narrow(*__b, 0) != '%') 2124*0b57cec5SDimitry Andric __err |= ios_base::failbit; 2125*0b57cec5SDimitry Andric else if(++__b == __e) 2126*0b57cec5SDimitry Andric __err |= ios_base::eofbit; 2127*0b57cec5SDimitry Andric} 2128*0b57cec5SDimitry Andric 2129*0b57cec5SDimitry Andric// time_get end primitives 2130*0b57cec5SDimitry Andric 2131*0b57cec5SDimitry Andrictemplate <class _CharT, class _InputIterator> 2132*0b57cec5SDimitry Andric_InputIterator 2133*0b57cec5SDimitry Andrictime_get<_CharT, _InputIterator>::get(iter_type __b, iter_type __e, 2134*0b57cec5SDimitry Andric ios_base& __iob, 2135*0b57cec5SDimitry Andric ios_base::iostate& __err, tm* __tm, 2136*0b57cec5SDimitry Andric const char_type* __fmtb, const char_type* __fmte) const 2137*0b57cec5SDimitry Andric{ 2138*0b57cec5SDimitry Andric const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc()); 2139*0b57cec5SDimitry Andric __err = ios_base::goodbit; 2140*0b57cec5SDimitry Andric while (__fmtb != __fmte && __err == ios_base::goodbit) 2141*0b57cec5SDimitry Andric { 2142*0b57cec5SDimitry Andric if (__b == __e) 2143*0b57cec5SDimitry Andric { 2144*0b57cec5SDimitry Andric __err = ios_base::failbit; 2145*0b57cec5SDimitry Andric break; 2146*0b57cec5SDimitry Andric } 2147*0b57cec5SDimitry Andric if (__ct.narrow(*__fmtb, 0) == '%') 2148*0b57cec5SDimitry Andric { 2149*0b57cec5SDimitry Andric if (++__fmtb == __fmte) 2150*0b57cec5SDimitry Andric { 2151*0b57cec5SDimitry Andric __err = ios_base::failbit; 2152*0b57cec5SDimitry Andric break; 2153*0b57cec5SDimitry Andric } 2154*0b57cec5SDimitry Andric char __cmd = __ct.narrow(*__fmtb, 0); 2155*0b57cec5SDimitry Andric char __opt = '\0'; 2156*0b57cec5SDimitry Andric if (__cmd == 'E' || __cmd == '0') 2157*0b57cec5SDimitry Andric { 2158*0b57cec5SDimitry Andric if (++__fmtb == __fmte) 2159*0b57cec5SDimitry Andric { 2160*0b57cec5SDimitry Andric __err = ios_base::failbit; 2161*0b57cec5SDimitry Andric break; 2162*0b57cec5SDimitry Andric } 2163*0b57cec5SDimitry Andric __opt = __cmd; 2164*0b57cec5SDimitry Andric __cmd = __ct.narrow(*__fmtb, 0); 2165*0b57cec5SDimitry Andric } 2166*0b57cec5SDimitry Andric __b = do_get(__b, __e, __iob, __err, __tm, __cmd, __opt); 2167*0b57cec5SDimitry Andric ++__fmtb; 2168*0b57cec5SDimitry Andric } 2169*0b57cec5SDimitry Andric else if (__ct.is(ctype_base::space, *__fmtb)) 2170*0b57cec5SDimitry Andric { 2171*0b57cec5SDimitry Andric for (++__fmtb; __fmtb != __fmte && __ct.is(ctype_base::space, *__fmtb); ++__fmtb) 2172*0b57cec5SDimitry Andric ; 2173*0b57cec5SDimitry Andric for ( ; __b != __e && __ct.is(ctype_base::space, *__b); ++__b) 2174*0b57cec5SDimitry Andric ; 2175*0b57cec5SDimitry Andric } 2176*0b57cec5SDimitry Andric else if (__ct.toupper(*__b) == __ct.toupper(*__fmtb)) 2177*0b57cec5SDimitry Andric { 2178*0b57cec5SDimitry Andric ++__b; 2179*0b57cec5SDimitry Andric ++__fmtb; 2180*0b57cec5SDimitry Andric } 2181*0b57cec5SDimitry Andric else 2182*0b57cec5SDimitry Andric __err = ios_base::failbit; 2183*0b57cec5SDimitry Andric } 2184*0b57cec5SDimitry Andric if (__b == __e) 2185*0b57cec5SDimitry Andric __err |= ios_base::eofbit; 2186*0b57cec5SDimitry Andric return __b; 2187*0b57cec5SDimitry Andric} 2188*0b57cec5SDimitry Andric 2189*0b57cec5SDimitry Andrictemplate <class _CharT, class _InputIterator> 2190*0b57cec5SDimitry Andrictypename time_get<_CharT, _InputIterator>::dateorder 2191*0b57cec5SDimitry Andrictime_get<_CharT, _InputIterator>::do_date_order() const 2192*0b57cec5SDimitry Andric{ 2193*0b57cec5SDimitry Andric return mdy; 2194*0b57cec5SDimitry Andric} 2195*0b57cec5SDimitry Andric 2196*0b57cec5SDimitry Andrictemplate <class _CharT, class _InputIterator> 2197*0b57cec5SDimitry Andric_InputIterator 2198*0b57cec5SDimitry Andrictime_get<_CharT, _InputIterator>::do_get_time(iter_type __b, iter_type __e, 2199*0b57cec5SDimitry Andric ios_base& __iob, 2200*0b57cec5SDimitry Andric ios_base::iostate& __err, 2201*0b57cec5SDimitry Andric tm* __tm) const 2202*0b57cec5SDimitry Andric{ 2203*0b57cec5SDimitry Andric const char_type __fmt[] = {'%', 'H', ':', '%', 'M', ':', '%', 'S'}; 2204*0b57cec5SDimitry Andric return get(__b, __e, __iob, __err, __tm, __fmt, __fmt + sizeof(__fmt)/sizeof(__fmt[0])); 2205*0b57cec5SDimitry Andric} 2206*0b57cec5SDimitry Andric 2207*0b57cec5SDimitry Andrictemplate <class _CharT, class _InputIterator> 2208*0b57cec5SDimitry Andric_InputIterator 2209*0b57cec5SDimitry Andrictime_get<_CharT, _InputIterator>::do_get_date(iter_type __b, iter_type __e, 2210*0b57cec5SDimitry Andric ios_base& __iob, 2211*0b57cec5SDimitry Andric ios_base::iostate& __err, 2212*0b57cec5SDimitry Andric tm* __tm) const 2213*0b57cec5SDimitry Andric{ 2214*0b57cec5SDimitry Andric const string_type& __fmt = this->__x(); 2215*0b57cec5SDimitry Andric return get(__b, __e, __iob, __err, __tm, __fmt.data(), __fmt.data() + __fmt.size()); 2216*0b57cec5SDimitry Andric} 2217*0b57cec5SDimitry Andric 2218*0b57cec5SDimitry Andrictemplate <class _CharT, class _InputIterator> 2219*0b57cec5SDimitry Andric_InputIterator 2220*0b57cec5SDimitry Andrictime_get<_CharT, _InputIterator>::do_get_weekday(iter_type __b, iter_type __e, 2221*0b57cec5SDimitry Andric ios_base& __iob, 2222*0b57cec5SDimitry Andric ios_base::iostate& __err, 2223*0b57cec5SDimitry Andric tm* __tm) const 2224*0b57cec5SDimitry Andric{ 2225*0b57cec5SDimitry Andric const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc()); 2226*0b57cec5SDimitry Andric __get_weekdayname(__tm->tm_wday, __b, __e, __err, __ct); 2227*0b57cec5SDimitry Andric return __b; 2228*0b57cec5SDimitry Andric} 2229*0b57cec5SDimitry Andric 2230*0b57cec5SDimitry Andrictemplate <class _CharT, class _InputIterator> 2231*0b57cec5SDimitry Andric_InputIterator 2232*0b57cec5SDimitry Andrictime_get<_CharT, _InputIterator>::do_get_monthname(iter_type __b, iter_type __e, 2233*0b57cec5SDimitry Andric ios_base& __iob, 2234*0b57cec5SDimitry Andric ios_base::iostate& __err, 2235*0b57cec5SDimitry Andric tm* __tm) const 2236*0b57cec5SDimitry Andric{ 2237*0b57cec5SDimitry Andric const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc()); 2238*0b57cec5SDimitry Andric __get_monthname(__tm->tm_mon, __b, __e, __err, __ct); 2239*0b57cec5SDimitry Andric return __b; 2240*0b57cec5SDimitry Andric} 2241*0b57cec5SDimitry Andric 2242*0b57cec5SDimitry Andrictemplate <class _CharT, class _InputIterator> 2243*0b57cec5SDimitry Andric_InputIterator 2244*0b57cec5SDimitry Andrictime_get<_CharT, _InputIterator>::do_get_year(iter_type __b, iter_type __e, 2245*0b57cec5SDimitry Andric ios_base& __iob, 2246*0b57cec5SDimitry Andric ios_base::iostate& __err, 2247*0b57cec5SDimitry Andric tm* __tm) const 2248*0b57cec5SDimitry Andric{ 2249*0b57cec5SDimitry Andric const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc()); 2250*0b57cec5SDimitry Andric __get_year(__tm->tm_year, __b, __e, __err, __ct); 2251*0b57cec5SDimitry Andric return __b; 2252*0b57cec5SDimitry Andric} 2253*0b57cec5SDimitry Andric 2254*0b57cec5SDimitry Andrictemplate <class _CharT, class _InputIterator> 2255*0b57cec5SDimitry Andric_InputIterator 2256*0b57cec5SDimitry Andrictime_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e, 2257*0b57cec5SDimitry Andric ios_base& __iob, 2258*0b57cec5SDimitry Andric ios_base::iostate& __err, tm* __tm, 2259*0b57cec5SDimitry Andric char __fmt, char) const 2260*0b57cec5SDimitry Andric{ 2261*0b57cec5SDimitry Andric __err = ios_base::goodbit; 2262*0b57cec5SDimitry Andric const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc()); 2263*0b57cec5SDimitry Andric switch (__fmt) 2264*0b57cec5SDimitry Andric { 2265*0b57cec5SDimitry Andric case 'a': 2266*0b57cec5SDimitry Andric case 'A': 2267*0b57cec5SDimitry Andric __get_weekdayname(__tm->tm_wday, __b, __e, __err, __ct); 2268*0b57cec5SDimitry Andric break; 2269*0b57cec5SDimitry Andric case 'b': 2270*0b57cec5SDimitry Andric case 'B': 2271*0b57cec5SDimitry Andric case 'h': 2272*0b57cec5SDimitry Andric __get_monthname(__tm->tm_mon, __b, __e, __err, __ct); 2273*0b57cec5SDimitry Andric break; 2274*0b57cec5SDimitry Andric case 'c': 2275*0b57cec5SDimitry Andric { 2276*0b57cec5SDimitry Andric const string_type& __fm = this->__c(); 2277*0b57cec5SDimitry Andric __b = get(__b, __e, __iob, __err, __tm, __fm.data(), __fm.data() + __fm.size()); 2278*0b57cec5SDimitry Andric } 2279*0b57cec5SDimitry Andric break; 2280*0b57cec5SDimitry Andric case 'd': 2281*0b57cec5SDimitry Andric case 'e': 2282*0b57cec5SDimitry Andric __get_day(__tm->tm_mday, __b, __e, __err, __ct); 2283*0b57cec5SDimitry Andric break; 2284*0b57cec5SDimitry Andric case 'D': 2285*0b57cec5SDimitry Andric { 2286*0b57cec5SDimitry Andric const char_type __fm[] = {'%', 'm', '/', '%', 'd', '/', '%', 'y'}; 2287*0b57cec5SDimitry Andric __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0])); 2288*0b57cec5SDimitry Andric } 2289*0b57cec5SDimitry Andric break; 2290*0b57cec5SDimitry Andric case 'F': 2291*0b57cec5SDimitry Andric { 2292*0b57cec5SDimitry Andric const char_type __fm[] = {'%', 'Y', '-', '%', 'm', '-', '%', 'd'}; 2293*0b57cec5SDimitry Andric __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0])); 2294*0b57cec5SDimitry Andric } 2295*0b57cec5SDimitry Andric break; 2296*0b57cec5SDimitry Andric case 'H': 2297*0b57cec5SDimitry Andric __get_hour(__tm->tm_hour, __b, __e, __err, __ct); 2298*0b57cec5SDimitry Andric break; 2299*0b57cec5SDimitry Andric case 'I': 2300*0b57cec5SDimitry Andric __get_12_hour(__tm->tm_hour, __b, __e, __err, __ct); 2301*0b57cec5SDimitry Andric break; 2302*0b57cec5SDimitry Andric case 'j': 2303*0b57cec5SDimitry Andric __get_day_year_num(__tm->tm_yday, __b, __e, __err, __ct); 2304*0b57cec5SDimitry Andric break; 2305*0b57cec5SDimitry Andric case 'm': 2306*0b57cec5SDimitry Andric __get_month(__tm->tm_mon, __b, __e, __err, __ct); 2307*0b57cec5SDimitry Andric break; 2308*0b57cec5SDimitry Andric case 'M': 2309*0b57cec5SDimitry Andric __get_minute(__tm->tm_min, __b, __e, __err, __ct); 2310*0b57cec5SDimitry Andric break; 2311*0b57cec5SDimitry Andric case 'n': 2312*0b57cec5SDimitry Andric case 't': 2313*0b57cec5SDimitry Andric __get_white_space(__b, __e, __err, __ct); 2314*0b57cec5SDimitry Andric break; 2315*0b57cec5SDimitry Andric case 'p': 2316*0b57cec5SDimitry Andric __get_am_pm(__tm->tm_hour, __b, __e, __err, __ct); 2317*0b57cec5SDimitry Andric break; 2318*0b57cec5SDimitry Andric case 'r': 2319*0b57cec5SDimitry Andric { 2320*0b57cec5SDimitry Andric const char_type __fm[] = {'%', 'I', ':', '%', 'M', ':', '%', 'S', ' ', '%', 'p'}; 2321*0b57cec5SDimitry Andric __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0])); 2322*0b57cec5SDimitry Andric } 2323*0b57cec5SDimitry Andric break; 2324*0b57cec5SDimitry Andric case 'R': 2325*0b57cec5SDimitry Andric { 2326*0b57cec5SDimitry Andric const char_type __fm[] = {'%', 'H', ':', '%', 'M'}; 2327*0b57cec5SDimitry Andric __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0])); 2328*0b57cec5SDimitry Andric } 2329*0b57cec5SDimitry Andric break; 2330*0b57cec5SDimitry Andric case 'S': 2331*0b57cec5SDimitry Andric __get_second(__tm->tm_sec, __b, __e, __err, __ct); 2332*0b57cec5SDimitry Andric break; 2333*0b57cec5SDimitry Andric case 'T': 2334*0b57cec5SDimitry Andric { 2335*0b57cec5SDimitry Andric const char_type __fm[] = {'%', 'H', ':', '%', 'M', ':', '%', 'S'}; 2336*0b57cec5SDimitry Andric __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0])); 2337*0b57cec5SDimitry Andric } 2338*0b57cec5SDimitry Andric break; 2339*0b57cec5SDimitry Andric case 'w': 2340*0b57cec5SDimitry Andric __get_weekday(__tm->tm_wday, __b, __e, __err, __ct); 2341*0b57cec5SDimitry Andric break; 2342*0b57cec5SDimitry Andric case 'x': 2343*0b57cec5SDimitry Andric return do_get_date(__b, __e, __iob, __err, __tm); 2344*0b57cec5SDimitry Andric case 'X': 2345*0b57cec5SDimitry Andric { 2346*0b57cec5SDimitry Andric const string_type& __fm = this->__X(); 2347*0b57cec5SDimitry Andric __b = get(__b, __e, __iob, __err, __tm, __fm.data(), __fm.data() + __fm.size()); 2348*0b57cec5SDimitry Andric } 2349*0b57cec5SDimitry Andric break; 2350*0b57cec5SDimitry Andric case 'y': 2351*0b57cec5SDimitry Andric __get_year(__tm->tm_year, __b, __e, __err, __ct); 2352*0b57cec5SDimitry Andric break; 2353*0b57cec5SDimitry Andric case 'Y': 2354*0b57cec5SDimitry Andric __get_year4(__tm->tm_year, __b, __e, __err, __ct); 2355*0b57cec5SDimitry Andric break; 2356*0b57cec5SDimitry Andric case '%': 2357*0b57cec5SDimitry Andric __get_percent(__b, __e, __err, __ct); 2358*0b57cec5SDimitry Andric break; 2359*0b57cec5SDimitry Andric default: 2360*0b57cec5SDimitry Andric __err |= ios_base::failbit; 2361*0b57cec5SDimitry Andric } 2362*0b57cec5SDimitry Andric return __b; 2363*0b57cec5SDimitry Andric} 2364*0b57cec5SDimitry Andric 2365*0b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_get<char>) 2366*0b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_get<wchar_t>) 2367*0b57cec5SDimitry Andric 2368*0b57cec5SDimitry Andricclass _LIBCPP_TYPE_VIS __time_get 2369*0b57cec5SDimitry Andric{ 2370*0b57cec5SDimitry Andricprotected: 2371*0b57cec5SDimitry Andric locale_t __loc_; 2372*0b57cec5SDimitry Andric 2373*0b57cec5SDimitry Andric __time_get(const char* __nm); 2374*0b57cec5SDimitry Andric __time_get(const string& __nm); 2375*0b57cec5SDimitry Andric ~__time_get(); 2376*0b57cec5SDimitry Andric}; 2377*0b57cec5SDimitry Andric 2378*0b57cec5SDimitry Andrictemplate <class _CharT> 2379*0b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS __time_get_storage 2380*0b57cec5SDimitry Andric : public __time_get 2381*0b57cec5SDimitry Andric{ 2382*0b57cec5SDimitry Andricprotected: 2383*0b57cec5SDimitry Andric typedef basic_string<_CharT> string_type; 2384*0b57cec5SDimitry Andric 2385*0b57cec5SDimitry Andric string_type __weeks_[14]; 2386*0b57cec5SDimitry Andric string_type __months_[24]; 2387*0b57cec5SDimitry Andric string_type __am_pm_[2]; 2388*0b57cec5SDimitry Andric string_type __c_; 2389*0b57cec5SDimitry Andric string_type __r_; 2390*0b57cec5SDimitry Andric string_type __x_; 2391*0b57cec5SDimitry Andric string_type __X_; 2392*0b57cec5SDimitry Andric 2393*0b57cec5SDimitry Andric explicit __time_get_storage(const char* __nm); 2394*0b57cec5SDimitry Andric explicit __time_get_storage(const string& __nm); 2395*0b57cec5SDimitry Andric 2396*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY ~__time_get_storage() {} 2397*0b57cec5SDimitry Andric 2398*0b57cec5SDimitry Andric time_base::dateorder __do_date_order() const; 2399*0b57cec5SDimitry Andric 2400*0b57cec5SDimitry Andricprivate: 2401*0b57cec5SDimitry Andric void init(const ctype<_CharT>&); 2402*0b57cec5SDimitry Andric string_type __analyze(char __fmt, const ctype<_CharT>&); 2403*0b57cec5SDimitry Andric}; 2404*0b57cec5SDimitry Andric 2405*0b57cec5SDimitry Andric#define _LIBCPP_TIME_GET_STORAGE_EXPLICIT_INSTANTIATION(_CharT) \ 2406*0b57cec5SDimitry Andrictemplate <> _LIBCPP_FUNC_VIS time_base::dateorder __time_get_storage<_CharT>::__do_date_order() const; \ 2407*0b57cec5SDimitry Andrictemplate <> _LIBCPP_FUNC_VIS __time_get_storage<_CharT>::__time_get_storage(const char*); \ 2408*0b57cec5SDimitry Andrictemplate <> _LIBCPP_FUNC_VIS __time_get_storage<_CharT>::__time_get_storage(const string&); \ 2409*0b57cec5SDimitry Andrictemplate <> _LIBCPP_FUNC_VIS void __time_get_storage<_CharT>::init(const ctype<_CharT>&); \ 2410*0b57cec5SDimitry Andrictemplate <> _LIBCPP_FUNC_VIS __time_get_storage<_CharT>::string_type __time_get_storage<_CharT>::__analyze(char, const ctype<_CharT>&); \ 2411*0b57cec5SDimitry Andricextern template _LIBCPP_FUNC_VIS time_base::dateorder __time_get_storage<_CharT>::__do_date_order() const; \ 2412*0b57cec5SDimitry Andricextern template _LIBCPP_FUNC_VIS __time_get_storage<_CharT>::__time_get_storage(const char*); \ 2413*0b57cec5SDimitry Andricextern template _LIBCPP_FUNC_VIS __time_get_storage<_CharT>::__time_get_storage(const string&); \ 2414*0b57cec5SDimitry Andricextern template _LIBCPP_FUNC_VIS void __time_get_storage<_CharT>::init(const ctype<_CharT>&); \ 2415*0b57cec5SDimitry Andricextern template _LIBCPP_FUNC_VIS __time_get_storage<_CharT>::string_type __time_get_storage<_CharT>::__analyze(char, const ctype<_CharT>&); \ 2416*0b57cec5SDimitry Andric/**/ 2417*0b57cec5SDimitry Andric 2418*0b57cec5SDimitry Andric_LIBCPP_TIME_GET_STORAGE_EXPLICIT_INSTANTIATION(char) 2419*0b57cec5SDimitry Andric_LIBCPP_TIME_GET_STORAGE_EXPLICIT_INSTANTIATION(wchar_t) 2420*0b57cec5SDimitry Andric#undef _LIBCPP_TIME_GET_STORAGE_EXPLICIT_INSTANTIATION 2421*0b57cec5SDimitry Andric 2422*0b57cec5SDimitry Andrictemplate <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> > 2423*0b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS time_get_byname 2424*0b57cec5SDimitry Andric : public time_get<_CharT, _InputIterator>, 2425*0b57cec5SDimitry Andric private __time_get_storage<_CharT> 2426*0b57cec5SDimitry Andric{ 2427*0b57cec5SDimitry Andricpublic: 2428*0b57cec5SDimitry Andric typedef time_base::dateorder dateorder; 2429*0b57cec5SDimitry Andric typedef _InputIterator iter_type; 2430*0b57cec5SDimitry Andric typedef _CharT char_type; 2431*0b57cec5SDimitry Andric typedef basic_string<char_type> string_type; 2432*0b57cec5SDimitry Andric 2433*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2434*0b57cec5SDimitry Andric explicit time_get_byname(const char* __nm, size_t __refs = 0) 2435*0b57cec5SDimitry Andric : time_get<_CharT, _InputIterator>(__refs), 2436*0b57cec5SDimitry Andric __time_get_storage<_CharT>(__nm) {} 2437*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2438*0b57cec5SDimitry Andric explicit time_get_byname(const string& __nm, size_t __refs = 0) 2439*0b57cec5SDimitry Andric : time_get<_CharT, _InputIterator>(__refs), 2440*0b57cec5SDimitry Andric __time_get_storage<_CharT>(__nm) {} 2441*0b57cec5SDimitry Andric 2442*0b57cec5SDimitry Andricprotected: 2443*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2444*0b57cec5SDimitry Andric ~time_get_byname() {} 2445*0b57cec5SDimitry Andric 2446*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2447*0b57cec5SDimitry Andric virtual dateorder do_date_order() const {return this->__do_date_order();} 2448*0b57cec5SDimitry Andricprivate: 2449*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2450*0b57cec5SDimitry Andric virtual const string_type* __weeks() const {return this->__weeks_;} 2451*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2452*0b57cec5SDimitry Andric virtual const string_type* __months() const {return this->__months_;} 2453*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2454*0b57cec5SDimitry Andric virtual const string_type* __am_pm() const {return this->__am_pm_;} 2455*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2456*0b57cec5SDimitry Andric virtual const string_type& __c() const {return this->__c_;} 2457*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2458*0b57cec5SDimitry Andric virtual const string_type& __r() const {return this->__r_;} 2459*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2460*0b57cec5SDimitry Andric virtual const string_type& __x() const {return this->__x_;} 2461*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2462*0b57cec5SDimitry Andric virtual const string_type& __X() const {return this->__X_;} 2463*0b57cec5SDimitry Andric}; 2464*0b57cec5SDimitry Andric 2465*0b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_get_byname<char>) 2466*0b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_get_byname<wchar_t>) 2467*0b57cec5SDimitry Andric 2468*0b57cec5SDimitry Andricclass _LIBCPP_TYPE_VIS __time_put 2469*0b57cec5SDimitry Andric{ 2470*0b57cec5SDimitry Andric locale_t __loc_; 2471*0b57cec5SDimitry Andricprotected: 2472*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY __time_put() : __loc_(_LIBCPP_GET_C_LOCALE) {} 2473*0b57cec5SDimitry Andric __time_put(const char* __nm); 2474*0b57cec5SDimitry Andric __time_put(const string& __nm); 2475*0b57cec5SDimitry Andric ~__time_put(); 2476*0b57cec5SDimitry Andric void __do_put(char* __nb, char*& __ne, const tm* __tm, 2477*0b57cec5SDimitry Andric char __fmt, char __mod) const; 2478*0b57cec5SDimitry Andric void __do_put(wchar_t* __wb, wchar_t*& __we, const tm* __tm, 2479*0b57cec5SDimitry Andric char __fmt, char __mod) const; 2480*0b57cec5SDimitry Andric}; 2481*0b57cec5SDimitry Andric 2482*0b57cec5SDimitry Andrictemplate <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> > 2483*0b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS time_put 2484*0b57cec5SDimitry Andric : public locale::facet, 2485*0b57cec5SDimitry Andric private __time_put 2486*0b57cec5SDimitry Andric{ 2487*0b57cec5SDimitry Andricpublic: 2488*0b57cec5SDimitry Andric typedef _CharT char_type; 2489*0b57cec5SDimitry Andric typedef _OutputIterator iter_type; 2490*0b57cec5SDimitry Andric 2491*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2492*0b57cec5SDimitry Andric explicit time_put(size_t __refs = 0) 2493*0b57cec5SDimitry Andric : locale::facet(__refs) {} 2494*0b57cec5SDimitry Andric 2495*0b57cec5SDimitry Andric iter_type put(iter_type __s, ios_base& __iob, char_type __fl, const tm* __tm, 2496*0b57cec5SDimitry Andric const char_type* __pb, const char_type* __pe) const; 2497*0b57cec5SDimitry Andric 2498*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2499*0b57cec5SDimitry Andric iter_type put(iter_type __s, ios_base& __iob, char_type __fl, 2500*0b57cec5SDimitry Andric const tm* __tm, char __fmt, char __mod = 0) const 2501*0b57cec5SDimitry Andric { 2502*0b57cec5SDimitry Andric return do_put(__s, __iob, __fl, __tm, __fmt, __mod); 2503*0b57cec5SDimitry Andric } 2504*0b57cec5SDimitry Andric 2505*0b57cec5SDimitry Andric static locale::id id; 2506*0b57cec5SDimitry Andric 2507*0b57cec5SDimitry Andricprotected: 2508*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2509*0b57cec5SDimitry Andric ~time_put() {} 2510*0b57cec5SDimitry Andric virtual iter_type do_put(iter_type __s, ios_base&, char_type, const tm* __tm, 2511*0b57cec5SDimitry Andric char __fmt, char __mod) const; 2512*0b57cec5SDimitry Andric 2513*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2514*0b57cec5SDimitry Andric explicit time_put(const char* __nm, size_t __refs) 2515*0b57cec5SDimitry Andric : locale::facet(__refs), 2516*0b57cec5SDimitry Andric __time_put(__nm) {} 2517*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2518*0b57cec5SDimitry Andric explicit time_put(const string& __nm, size_t __refs) 2519*0b57cec5SDimitry Andric : locale::facet(__refs), 2520*0b57cec5SDimitry Andric __time_put(__nm) {} 2521*0b57cec5SDimitry Andric}; 2522*0b57cec5SDimitry Andric 2523*0b57cec5SDimitry Andrictemplate <class _CharT, class _OutputIterator> 2524*0b57cec5SDimitry Andriclocale::id 2525*0b57cec5SDimitry Andrictime_put<_CharT, _OutputIterator>::id; 2526*0b57cec5SDimitry Andric 2527*0b57cec5SDimitry Andrictemplate <class _CharT, class _OutputIterator> 2528*0b57cec5SDimitry Andric_OutputIterator 2529*0b57cec5SDimitry Andrictime_put<_CharT, _OutputIterator>::put(iter_type __s, ios_base& __iob, 2530*0b57cec5SDimitry Andric char_type __fl, const tm* __tm, 2531*0b57cec5SDimitry Andric const char_type* __pb, 2532*0b57cec5SDimitry Andric const char_type* __pe) const 2533*0b57cec5SDimitry Andric{ 2534*0b57cec5SDimitry Andric const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc()); 2535*0b57cec5SDimitry Andric for (; __pb != __pe; ++__pb) 2536*0b57cec5SDimitry Andric { 2537*0b57cec5SDimitry Andric if (__ct.narrow(*__pb, 0) == '%') 2538*0b57cec5SDimitry Andric { 2539*0b57cec5SDimitry Andric if (++__pb == __pe) 2540*0b57cec5SDimitry Andric { 2541*0b57cec5SDimitry Andric *__s++ = __pb[-1]; 2542*0b57cec5SDimitry Andric break; 2543*0b57cec5SDimitry Andric } 2544*0b57cec5SDimitry Andric char __mod = 0; 2545*0b57cec5SDimitry Andric char __fmt = __ct.narrow(*__pb, 0); 2546*0b57cec5SDimitry Andric if (__fmt == 'E' || __fmt == 'O') 2547*0b57cec5SDimitry Andric { 2548*0b57cec5SDimitry Andric if (++__pb == __pe) 2549*0b57cec5SDimitry Andric { 2550*0b57cec5SDimitry Andric *__s++ = __pb[-2]; 2551*0b57cec5SDimitry Andric *__s++ = __pb[-1]; 2552*0b57cec5SDimitry Andric break; 2553*0b57cec5SDimitry Andric } 2554*0b57cec5SDimitry Andric __mod = __fmt; 2555*0b57cec5SDimitry Andric __fmt = __ct.narrow(*__pb, 0); 2556*0b57cec5SDimitry Andric } 2557*0b57cec5SDimitry Andric __s = do_put(__s, __iob, __fl, __tm, __fmt, __mod); 2558*0b57cec5SDimitry Andric } 2559*0b57cec5SDimitry Andric else 2560*0b57cec5SDimitry Andric *__s++ = *__pb; 2561*0b57cec5SDimitry Andric } 2562*0b57cec5SDimitry Andric return __s; 2563*0b57cec5SDimitry Andric} 2564*0b57cec5SDimitry Andric 2565*0b57cec5SDimitry Andrictemplate <class _CharT, class _OutputIterator> 2566*0b57cec5SDimitry Andric_OutputIterator 2567*0b57cec5SDimitry Andrictime_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base&, 2568*0b57cec5SDimitry Andric char_type, const tm* __tm, 2569*0b57cec5SDimitry Andric char __fmt, char __mod) const 2570*0b57cec5SDimitry Andric{ 2571*0b57cec5SDimitry Andric char_type __nar[100]; 2572*0b57cec5SDimitry Andric char_type* __nb = __nar; 2573*0b57cec5SDimitry Andric char_type* __ne = __nb + 100; 2574*0b57cec5SDimitry Andric __do_put(__nb, __ne, __tm, __fmt, __mod); 2575*0b57cec5SDimitry Andric return _VSTD::copy(__nb, __ne, __s); 2576*0b57cec5SDimitry Andric} 2577*0b57cec5SDimitry Andric 2578*0b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_put<char>) 2579*0b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_put<wchar_t>) 2580*0b57cec5SDimitry Andric 2581*0b57cec5SDimitry Andrictemplate <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> > 2582*0b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS time_put_byname 2583*0b57cec5SDimitry Andric : public time_put<_CharT, _OutputIterator> 2584*0b57cec5SDimitry Andric{ 2585*0b57cec5SDimitry Andricpublic: 2586*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2587*0b57cec5SDimitry Andric explicit time_put_byname(const char* __nm, size_t __refs = 0) 2588*0b57cec5SDimitry Andric : time_put<_CharT, _OutputIterator>(__nm, __refs) {} 2589*0b57cec5SDimitry Andric 2590*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2591*0b57cec5SDimitry Andric explicit time_put_byname(const string& __nm, size_t __refs = 0) 2592*0b57cec5SDimitry Andric : time_put<_CharT, _OutputIterator>(__nm, __refs) {} 2593*0b57cec5SDimitry Andric 2594*0b57cec5SDimitry Andricprotected: 2595*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2596*0b57cec5SDimitry Andric ~time_put_byname() {} 2597*0b57cec5SDimitry Andric}; 2598*0b57cec5SDimitry Andric 2599*0b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_put_byname<char>) 2600*0b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_put_byname<wchar_t>) 2601*0b57cec5SDimitry Andric 2602*0b57cec5SDimitry Andric// money_base 2603*0b57cec5SDimitry Andric 2604*0b57cec5SDimitry Andricclass _LIBCPP_TYPE_VIS money_base 2605*0b57cec5SDimitry Andric{ 2606*0b57cec5SDimitry Andricpublic: 2607*0b57cec5SDimitry Andric enum part {none, space, symbol, sign, value}; 2608*0b57cec5SDimitry Andric struct pattern {char field[4];}; 2609*0b57cec5SDimitry Andric 2610*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY money_base() {} 2611*0b57cec5SDimitry Andric}; 2612*0b57cec5SDimitry Andric 2613*0b57cec5SDimitry Andric// moneypunct 2614*0b57cec5SDimitry Andric 2615*0b57cec5SDimitry Andrictemplate <class _CharT, bool _International = false> 2616*0b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS moneypunct 2617*0b57cec5SDimitry Andric : public locale::facet, 2618*0b57cec5SDimitry Andric public money_base 2619*0b57cec5SDimitry Andric{ 2620*0b57cec5SDimitry Andricpublic: 2621*0b57cec5SDimitry Andric typedef _CharT char_type; 2622*0b57cec5SDimitry Andric typedef basic_string<char_type> string_type; 2623*0b57cec5SDimitry Andric 2624*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2625*0b57cec5SDimitry Andric explicit moneypunct(size_t __refs = 0) 2626*0b57cec5SDimitry Andric : locale::facet(__refs) {} 2627*0b57cec5SDimitry Andric 2628*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY char_type decimal_point() const {return do_decimal_point();} 2629*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY char_type thousands_sep() const {return do_thousands_sep();} 2630*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY string grouping() const {return do_grouping();} 2631*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY string_type curr_symbol() const {return do_curr_symbol();} 2632*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY string_type positive_sign() const {return do_positive_sign();} 2633*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY string_type negative_sign() const {return do_negative_sign();} 2634*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY int frac_digits() const {return do_frac_digits();} 2635*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY pattern pos_format() const {return do_pos_format();} 2636*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY pattern neg_format() const {return do_neg_format();} 2637*0b57cec5SDimitry Andric 2638*0b57cec5SDimitry Andric static locale::id id; 2639*0b57cec5SDimitry Andric static const bool intl = _International; 2640*0b57cec5SDimitry Andric 2641*0b57cec5SDimitry Andricprotected: 2642*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2643*0b57cec5SDimitry Andric ~moneypunct() {} 2644*0b57cec5SDimitry Andric 2645*0b57cec5SDimitry Andric virtual char_type do_decimal_point() const {return numeric_limits<char_type>::max();} 2646*0b57cec5SDimitry Andric virtual char_type do_thousands_sep() const {return numeric_limits<char_type>::max();} 2647*0b57cec5SDimitry Andric virtual string do_grouping() const {return string();} 2648*0b57cec5SDimitry Andric virtual string_type do_curr_symbol() const {return string_type();} 2649*0b57cec5SDimitry Andric virtual string_type do_positive_sign() const {return string_type();} 2650*0b57cec5SDimitry Andric virtual string_type do_negative_sign() const {return string_type(1, '-');} 2651*0b57cec5SDimitry Andric virtual int do_frac_digits() const {return 0;} 2652*0b57cec5SDimitry Andric virtual pattern do_pos_format() const 2653*0b57cec5SDimitry Andric {pattern __p = {{symbol, sign, none, value}}; return __p;} 2654*0b57cec5SDimitry Andric virtual pattern do_neg_format() const 2655*0b57cec5SDimitry Andric {pattern __p = {{symbol, sign, none, value}}; return __p;} 2656*0b57cec5SDimitry Andric}; 2657*0b57cec5SDimitry Andric 2658*0b57cec5SDimitry Andrictemplate <class _CharT, bool _International> 2659*0b57cec5SDimitry Andriclocale::id 2660*0b57cec5SDimitry Andricmoneypunct<_CharT, _International>::id; 2661*0b57cec5SDimitry Andric 2662*0b57cec5SDimitry Andrictemplate <class _CharT, bool _International> 2663*0b57cec5SDimitry Andricconst bool 2664*0b57cec5SDimitry Andricmoneypunct<_CharT, _International>::intl; 2665*0b57cec5SDimitry Andric 2666*0b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct<char, false>) 2667*0b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct<char, true>) 2668*0b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct<wchar_t, false>) 2669*0b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct<wchar_t, true>) 2670*0b57cec5SDimitry Andric 2671*0b57cec5SDimitry Andric// moneypunct_byname 2672*0b57cec5SDimitry Andric 2673*0b57cec5SDimitry Andrictemplate <class _CharT, bool _International = false> 2674*0b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS moneypunct_byname 2675*0b57cec5SDimitry Andric : public moneypunct<_CharT, _International> 2676*0b57cec5SDimitry Andric{ 2677*0b57cec5SDimitry Andricpublic: 2678*0b57cec5SDimitry Andric typedef money_base::pattern pattern; 2679*0b57cec5SDimitry Andric typedef _CharT char_type; 2680*0b57cec5SDimitry Andric typedef basic_string<char_type> string_type; 2681*0b57cec5SDimitry Andric 2682*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2683*0b57cec5SDimitry Andric explicit moneypunct_byname(const char* __nm, size_t __refs = 0) 2684*0b57cec5SDimitry Andric : moneypunct<_CharT, _International>(__refs) {init(__nm);} 2685*0b57cec5SDimitry Andric 2686*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2687*0b57cec5SDimitry Andric explicit moneypunct_byname(const string& __nm, size_t __refs = 0) 2688*0b57cec5SDimitry Andric : moneypunct<_CharT, _International>(__refs) {init(__nm.c_str());} 2689*0b57cec5SDimitry Andric 2690*0b57cec5SDimitry Andricprotected: 2691*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2692*0b57cec5SDimitry Andric ~moneypunct_byname() {} 2693*0b57cec5SDimitry Andric 2694*0b57cec5SDimitry Andric virtual char_type do_decimal_point() const {return __decimal_point_;} 2695*0b57cec5SDimitry Andric virtual char_type do_thousands_sep() const {return __thousands_sep_;} 2696*0b57cec5SDimitry Andric virtual string do_grouping() const {return __grouping_;} 2697*0b57cec5SDimitry Andric virtual string_type do_curr_symbol() const {return __curr_symbol_;} 2698*0b57cec5SDimitry Andric virtual string_type do_positive_sign() const {return __positive_sign_;} 2699*0b57cec5SDimitry Andric virtual string_type do_negative_sign() const {return __negative_sign_;} 2700*0b57cec5SDimitry Andric virtual int do_frac_digits() const {return __frac_digits_;} 2701*0b57cec5SDimitry Andric virtual pattern do_pos_format() const {return __pos_format_;} 2702*0b57cec5SDimitry Andric virtual pattern do_neg_format() const {return __neg_format_;} 2703*0b57cec5SDimitry Andric 2704*0b57cec5SDimitry Andricprivate: 2705*0b57cec5SDimitry Andric char_type __decimal_point_; 2706*0b57cec5SDimitry Andric char_type __thousands_sep_; 2707*0b57cec5SDimitry Andric string __grouping_; 2708*0b57cec5SDimitry Andric string_type __curr_symbol_; 2709*0b57cec5SDimitry Andric string_type __positive_sign_; 2710*0b57cec5SDimitry Andric string_type __negative_sign_; 2711*0b57cec5SDimitry Andric int __frac_digits_; 2712*0b57cec5SDimitry Andric pattern __pos_format_; 2713*0b57cec5SDimitry Andric pattern __neg_format_; 2714*0b57cec5SDimitry Andric 2715*0b57cec5SDimitry Andric void init(const char*); 2716*0b57cec5SDimitry Andric}; 2717*0b57cec5SDimitry Andric 2718*0b57cec5SDimitry Andrictemplate<> _LIBCPP_FUNC_VIS void moneypunct_byname<char, false>::init(const char*); 2719*0b57cec5SDimitry Andrictemplate<> _LIBCPP_FUNC_VIS void moneypunct_byname<char, true>::init(const char*); 2720*0b57cec5SDimitry Andrictemplate<> _LIBCPP_FUNC_VIS void moneypunct_byname<wchar_t, false>::init(const char*); 2721*0b57cec5SDimitry Andrictemplate<> _LIBCPP_FUNC_VIS void moneypunct_byname<wchar_t, true>::init(const char*); 2722*0b57cec5SDimitry Andric 2723*0b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct_byname<char, false>) 2724*0b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct_byname<char, true>) 2725*0b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct_byname<wchar_t, false>) 2726*0b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct_byname<wchar_t, true>) 2727*0b57cec5SDimitry Andric 2728*0b57cec5SDimitry Andric// money_get 2729*0b57cec5SDimitry Andric 2730*0b57cec5SDimitry Andrictemplate <class _CharT> 2731*0b57cec5SDimitry Andricclass __money_get 2732*0b57cec5SDimitry Andric{ 2733*0b57cec5SDimitry Andricprotected: 2734*0b57cec5SDimitry Andric typedef _CharT char_type; 2735*0b57cec5SDimitry Andric typedef basic_string<char_type> string_type; 2736*0b57cec5SDimitry Andric 2737*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY __money_get() {} 2738*0b57cec5SDimitry Andric 2739*0b57cec5SDimitry Andric static void __gather_info(bool __intl, const locale& __loc, 2740*0b57cec5SDimitry Andric money_base::pattern& __pat, char_type& __dp, 2741*0b57cec5SDimitry Andric char_type& __ts, string& __grp, 2742*0b57cec5SDimitry Andric string_type& __sym, string_type& __psn, 2743*0b57cec5SDimitry Andric string_type& __nsn, int& __fd); 2744*0b57cec5SDimitry Andric}; 2745*0b57cec5SDimitry Andric 2746*0b57cec5SDimitry Andrictemplate <class _CharT> 2747*0b57cec5SDimitry Andricvoid 2748*0b57cec5SDimitry Andric__money_get<_CharT>::__gather_info(bool __intl, const locale& __loc, 2749*0b57cec5SDimitry Andric money_base::pattern& __pat, char_type& __dp, 2750*0b57cec5SDimitry Andric char_type& __ts, string& __grp, 2751*0b57cec5SDimitry Andric string_type& __sym, string_type& __psn, 2752*0b57cec5SDimitry Andric string_type& __nsn, int& __fd) 2753*0b57cec5SDimitry Andric{ 2754*0b57cec5SDimitry Andric if (__intl) 2755*0b57cec5SDimitry Andric { 2756*0b57cec5SDimitry Andric const moneypunct<char_type, true>& __mp = 2757*0b57cec5SDimitry Andric use_facet<moneypunct<char_type, true> >(__loc); 2758*0b57cec5SDimitry Andric __pat = __mp.neg_format(); 2759*0b57cec5SDimitry Andric __nsn = __mp.negative_sign(); 2760*0b57cec5SDimitry Andric __psn = __mp.positive_sign(); 2761*0b57cec5SDimitry Andric __dp = __mp.decimal_point(); 2762*0b57cec5SDimitry Andric __ts = __mp.thousands_sep(); 2763*0b57cec5SDimitry Andric __grp = __mp.grouping(); 2764*0b57cec5SDimitry Andric __sym = __mp.curr_symbol(); 2765*0b57cec5SDimitry Andric __fd = __mp.frac_digits(); 2766*0b57cec5SDimitry Andric } 2767*0b57cec5SDimitry Andric else 2768*0b57cec5SDimitry Andric { 2769*0b57cec5SDimitry Andric const moneypunct<char_type, false>& __mp = 2770*0b57cec5SDimitry Andric use_facet<moneypunct<char_type, false> >(__loc); 2771*0b57cec5SDimitry Andric __pat = __mp.neg_format(); 2772*0b57cec5SDimitry Andric __nsn = __mp.negative_sign(); 2773*0b57cec5SDimitry Andric __psn = __mp.positive_sign(); 2774*0b57cec5SDimitry Andric __dp = __mp.decimal_point(); 2775*0b57cec5SDimitry Andric __ts = __mp.thousands_sep(); 2776*0b57cec5SDimitry Andric __grp = __mp.grouping(); 2777*0b57cec5SDimitry Andric __sym = __mp.curr_symbol(); 2778*0b57cec5SDimitry Andric __fd = __mp.frac_digits(); 2779*0b57cec5SDimitry Andric } 2780*0b57cec5SDimitry Andric} 2781*0b57cec5SDimitry Andric 2782*0b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __money_get<char>) 2783*0b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __money_get<wchar_t>) 2784*0b57cec5SDimitry Andric 2785*0b57cec5SDimitry Andrictemplate <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> > 2786*0b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS money_get 2787*0b57cec5SDimitry Andric : public locale::facet, 2788*0b57cec5SDimitry Andric private __money_get<_CharT> 2789*0b57cec5SDimitry Andric{ 2790*0b57cec5SDimitry Andricpublic: 2791*0b57cec5SDimitry Andric typedef _CharT char_type; 2792*0b57cec5SDimitry Andric typedef _InputIterator iter_type; 2793*0b57cec5SDimitry Andric typedef basic_string<char_type> string_type; 2794*0b57cec5SDimitry Andric 2795*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2796*0b57cec5SDimitry Andric explicit money_get(size_t __refs = 0) 2797*0b57cec5SDimitry Andric : locale::facet(__refs) {} 2798*0b57cec5SDimitry Andric 2799*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2800*0b57cec5SDimitry Andric iter_type get(iter_type __b, iter_type __e, bool __intl, ios_base& __iob, 2801*0b57cec5SDimitry Andric ios_base::iostate& __err, long double& __v) const 2802*0b57cec5SDimitry Andric { 2803*0b57cec5SDimitry Andric return do_get(__b, __e, __intl, __iob, __err, __v); 2804*0b57cec5SDimitry Andric } 2805*0b57cec5SDimitry Andric 2806*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2807*0b57cec5SDimitry Andric iter_type get(iter_type __b, iter_type __e, bool __intl, ios_base& __iob, 2808*0b57cec5SDimitry Andric ios_base::iostate& __err, string_type& __v) const 2809*0b57cec5SDimitry Andric { 2810*0b57cec5SDimitry Andric return do_get(__b, __e, __intl, __iob, __err, __v); 2811*0b57cec5SDimitry Andric } 2812*0b57cec5SDimitry Andric 2813*0b57cec5SDimitry Andric static locale::id id; 2814*0b57cec5SDimitry Andric 2815*0b57cec5SDimitry Andricprotected: 2816*0b57cec5SDimitry Andric 2817*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2818*0b57cec5SDimitry Andric ~money_get() {} 2819*0b57cec5SDimitry Andric 2820*0b57cec5SDimitry Andric virtual iter_type do_get(iter_type __b, iter_type __e, bool __intl, 2821*0b57cec5SDimitry Andric ios_base& __iob, ios_base::iostate& __err, 2822*0b57cec5SDimitry Andric long double& __v) const; 2823*0b57cec5SDimitry Andric virtual iter_type do_get(iter_type __b, iter_type __e, bool __intl, 2824*0b57cec5SDimitry Andric ios_base& __iob, ios_base::iostate& __err, 2825*0b57cec5SDimitry Andric string_type& __v) const; 2826*0b57cec5SDimitry Andric 2827*0b57cec5SDimitry Andricprivate: 2828*0b57cec5SDimitry Andric static bool __do_get(iter_type& __b, iter_type __e, 2829*0b57cec5SDimitry Andric bool __intl, const locale& __loc, 2830*0b57cec5SDimitry Andric ios_base::fmtflags __flags, ios_base::iostate& __err, 2831*0b57cec5SDimitry Andric bool& __neg, const ctype<char_type>& __ct, 2832*0b57cec5SDimitry Andric unique_ptr<char_type, void(*)(void*)>& __wb, 2833*0b57cec5SDimitry Andric char_type*& __wn, char_type* __we); 2834*0b57cec5SDimitry Andric}; 2835*0b57cec5SDimitry Andric 2836*0b57cec5SDimitry Andrictemplate <class _CharT, class _InputIterator> 2837*0b57cec5SDimitry Andriclocale::id 2838*0b57cec5SDimitry Andricmoney_get<_CharT, _InputIterator>::id; 2839*0b57cec5SDimitry Andric 2840*0b57cec5SDimitry Andric_LIBCPP_FUNC_VIS void __do_nothing(void*); 2841*0b57cec5SDimitry Andric 2842*0b57cec5SDimitry Andrictemplate <class _Tp> 2843*0b57cec5SDimitry Andric_LIBCPP_HIDDEN 2844*0b57cec5SDimitry Andricvoid 2845*0b57cec5SDimitry Andric__double_or_nothing(unique_ptr<_Tp, void(*)(void*)>& __b, _Tp*& __n, _Tp*& __e) 2846*0b57cec5SDimitry Andric{ 2847*0b57cec5SDimitry Andric bool __owns = __b.get_deleter() != __do_nothing; 2848*0b57cec5SDimitry Andric size_t __cur_cap = static_cast<size_t>(__e-__b.get()) * sizeof(_Tp); 2849*0b57cec5SDimitry Andric size_t __new_cap = __cur_cap < numeric_limits<size_t>::max() / 2 ? 2850*0b57cec5SDimitry Andric 2 * __cur_cap : numeric_limits<size_t>::max(); 2851*0b57cec5SDimitry Andric if (__new_cap == 0) 2852*0b57cec5SDimitry Andric __new_cap = sizeof(_Tp); 2853*0b57cec5SDimitry Andric size_t __n_off = static_cast<size_t>(__n - __b.get()); 2854*0b57cec5SDimitry Andric _Tp* __t = (_Tp*)realloc(__owns ? __b.get() : 0, __new_cap); 2855*0b57cec5SDimitry Andric if (__t == 0) 2856*0b57cec5SDimitry Andric __throw_bad_alloc(); 2857*0b57cec5SDimitry Andric if (__owns) 2858*0b57cec5SDimitry Andric __b.release(); 2859*0b57cec5SDimitry Andric __b = unique_ptr<_Tp, void(*)(void*)>(__t, free); 2860*0b57cec5SDimitry Andric __new_cap /= sizeof(_Tp); 2861*0b57cec5SDimitry Andric __n = __b.get() + __n_off; 2862*0b57cec5SDimitry Andric __e = __b.get() + __new_cap; 2863*0b57cec5SDimitry Andric} 2864*0b57cec5SDimitry Andric 2865*0b57cec5SDimitry Andric// true == success 2866*0b57cec5SDimitry Andrictemplate <class _CharT, class _InputIterator> 2867*0b57cec5SDimitry Andricbool 2868*0b57cec5SDimitry Andricmoney_get<_CharT, _InputIterator>::__do_get(iter_type& __b, iter_type __e, 2869*0b57cec5SDimitry Andric bool __intl, const locale& __loc, 2870*0b57cec5SDimitry Andric ios_base::fmtflags __flags, 2871*0b57cec5SDimitry Andric ios_base::iostate& __err, 2872*0b57cec5SDimitry Andric bool& __neg, 2873*0b57cec5SDimitry Andric const ctype<char_type>& __ct, 2874*0b57cec5SDimitry Andric unique_ptr<char_type, void(*)(void*)>& __wb, 2875*0b57cec5SDimitry Andric char_type*& __wn, char_type* __we) 2876*0b57cec5SDimitry Andric{ 2877*0b57cec5SDimitry Andric const unsigned __bz = 100; 2878*0b57cec5SDimitry Andric unsigned __gbuf[__bz]; 2879*0b57cec5SDimitry Andric unique_ptr<unsigned, void(*)(void*)> __gb(__gbuf, __do_nothing); 2880*0b57cec5SDimitry Andric unsigned* __gn = __gb.get(); 2881*0b57cec5SDimitry Andric unsigned* __ge = __gn + __bz; 2882*0b57cec5SDimitry Andric money_base::pattern __pat; 2883*0b57cec5SDimitry Andric char_type __dp; 2884*0b57cec5SDimitry Andric char_type __ts; 2885*0b57cec5SDimitry Andric string __grp; 2886*0b57cec5SDimitry Andric string_type __sym; 2887*0b57cec5SDimitry Andric string_type __psn; 2888*0b57cec5SDimitry Andric string_type __nsn; 2889*0b57cec5SDimitry Andric // Capture the spaces read into money_base::{space,none} so they 2890*0b57cec5SDimitry Andric // can be compared to initial spaces in __sym. 2891*0b57cec5SDimitry Andric string_type __spaces; 2892*0b57cec5SDimitry Andric int __fd; 2893*0b57cec5SDimitry Andric __money_get<_CharT>::__gather_info(__intl, __loc, __pat, __dp, __ts, __grp, 2894*0b57cec5SDimitry Andric __sym, __psn, __nsn, __fd); 2895*0b57cec5SDimitry Andric const string_type* __trailing_sign = 0; 2896*0b57cec5SDimitry Andric __wn = __wb.get(); 2897*0b57cec5SDimitry Andric for (unsigned __p = 0; __p < 4 && __b != __e; ++__p) 2898*0b57cec5SDimitry Andric { 2899*0b57cec5SDimitry Andric switch (__pat.field[__p]) 2900*0b57cec5SDimitry Andric { 2901*0b57cec5SDimitry Andric case money_base::space: 2902*0b57cec5SDimitry Andric if (__p != 3) 2903*0b57cec5SDimitry Andric { 2904*0b57cec5SDimitry Andric if (__ct.is(ctype_base::space, *__b)) 2905*0b57cec5SDimitry Andric __spaces.push_back(*__b++); 2906*0b57cec5SDimitry Andric else 2907*0b57cec5SDimitry Andric { 2908*0b57cec5SDimitry Andric __err |= ios_base::failbit; 2909*0b57cec5SDimitry Andric return false; 2910*0b57cec5SDimitry Andric } 2911*0b57cec5SDimitry Andric } 2912*0b57cec5SDimitry Andric _LIBCPP_FALLTHROUGH(); 2913*0b57cec5SDimitry Andric case money_base::none: 2914*0b57cec5SDimitry Andric if (__p != 3) 2915*0b57cec5SDimitry Andric { 2916*0b57cec5SDimitry Andric while (__b != __e && __ct.is(ctype_base::space, *__b)) 2917*0b57cec5SDimitry Andric __spaces.push_back(*__b++); 2918*0b57cec5SDimitry Andric } 2919*0b57cec5SDimitry Andric break; 2920*0b57cec5SDimitry Andric case money_base::sign: 2921*0b57cec5SDimitry Andric if (__psn.size() + __nsn.size() > 0) 2922*0b57cec5SDimitry Andric { 2923*0b57cec5SDimitry Andric if (__psn.size() == 0 || __nsn.size() == 0) 2924*0b57cec5SDimitry Andric { // sign is optional 2925*0b57cec5SDimitry Andric if (__psn.size() > 0) 2926*0b57cec5SDimitry Andric { // __nsn.size() == 0 2927*0b57cec5SDimitry Andric if (*__b == __psn[0]) 2928*0b57cec5SDimitry Andric { 2929*0b57cec5SDimitry Andric ++__b; 2930*0b57cec5SDimitry Andric if (__psn.size() > 1) 2931*0b57cec5SDimitry Andric __trailing_sign = &__psn; 2932*0b57cec5SDimitry Andric } 2933*0b57cec5SDimitry Andric else 2934*0b57cec5SDimitry Andric __neg = true; 2935*0b57cec5SDimitry Andric } 2936*0b57cec5SDimitry Andric else if (*__b == __nsn[0]) // __nsn.size() > 0 && __psn.size() == 0 2937*0b57cec5SDimitry Andric { 2938*0b57cec5SDimitry Andric ++__b; 2939*0b57cec5SDimitry Andric __neg = true; 2940*0b57cec5SDimitry Andric if (__nsn.size() > 1) 2941*0b57cec5SDimitry Andric __trailing_sign = &__nsn; 2942*0b57cec5SDimitry Andric } 2943*0b57cec5SDimitry Andric } 2944*0b57cec5SDimitry Andric else // sign is required 2945*0b57cec5SDimitry Andric { 2946*0b57cec5SDimitry Andric if (*__b == __psn[0]) 2947*0b57cec5SDimitry Andric { 2948*0b57cec5SDimitry Andric ++__b; 2949*0b57cec5SDimitry Andric if (__psn.size() > 1) 2950*0b57cec5SDimitry Andric __trailing_sign = &__psn; 2951*0b57cec5SDimitry Andric } 2952*0b57cec5SDimitry Andric else if (*__b == __nsn[0]) 2953*0b57cec5SDimitry Andric { 2954*0b57cec5SDimitry Andric ++__b; 2955*0b57cec5SDimitry Andric __neg = true; 2956*0b57cec5SDimitry Andric if (__nsn.size() > 1) 2957*0b57cec5SDimitry Andric __trailing_sign = &__nsn; 2958*0b57cec5SDimitry Andric } 2959*0b57cec5SDimitry Andric else 2960*0b57cec5SDimitry Andric { 2961*0b57cec5SDimitry Andric __err |= ios_base::failbit; 2962*0b57cec5SDimitry Andric return false; 2963*0b57cec5SDimitry Andric } 2964*0b57cec5SDimitry Andric } 2965*0b57cec5SDimitry Andric } 2966*0b57cec5SDimitry Andric break; 2967*0b57cec5SDimitry Andric case money_base::symbol: 2968*0b57cec5SDimitry Andric { 2969*0b57cec5SDimitry Andric bool __more_needed = __trailing_sign || 2970*0b57cec5SDimitry Andric (__p < 2) || 2971*0b57cec5SDimitry Andric (__p == 2 && __pat.field[3] != static_cast<char>(money_base::none)); 2972*0b57cec5SDimitry Andric bool __sb = (__flags & ios_base::showbase) != 0; 2973*0b57cec5SDimitry Andric if (__sb || __more_needed) 2974*0b57cec5SDimitry Andric { 2975*0b57cec5SDimitry Andric typename string_type::const_iterator __sym_space_end = __sym.begin(); 2976*0b57cec5SDimitry Andric if (__p > 0 && (__pat.field[__p - 1] == money_base::none || 2977*0b57cec5SDimitry Andric __pat.field[__p - 1] == money_base::space)) { 2978*0b57cec5SDimitry Andric // Match spaces we've already read against spaces at 2979*0b57cec5SDimitry Andric // the beginning of __sym. 2980*0b57cec5SDimitry Andric while (__sym_space_end != __sym.end() && 2981*0b57cec5SDimitry Andric __ct.is(ctype_base::space, *__sym_space_end)) 2982*0b57cec5SDimitry Andric ++__sym_space_end; 2983*0b57cec5SDimitry Andric const size_t __num_spaces = __sym_space_end - __sym.begin(); 2984*0b57cec5SDimitry Andric if (__num_spaces > __spaces.size() || 2985*0b57cec5SDimitry Andric !equal(__spaces.end() - __num_spaces, __spaces.end(), 2986*0b57cec5SDimitry Andric __sym.begin())) { 2987*0b57cec5SDimitry Andric // No match. Put __sym_space_end back at the 2988*0b57cec5SDimitry Andric // beginning of __sym, which will prevent a 2989*0b57cec5SDimitry Andric // match in the next loop. 2990*0b57cec5SDimitry Andric __sym_space_end = __sym.begin(); 2991*0b57cec5SDimitry Andric } 2992*0b57cec5SDimitry Andric } 2993*0b57cec5SDimitry Andric typename string_type::const_iterator __sym_curr_char = __sym_space_end; 2994*0b57cec5SDimitry Andric while (__sym_curr_char != __sym.end() && __b != __e && 2995*0b57cec5SDimitry Andric *__b == *__sym_curr_char) { 2996*0b57cec5SDimitry Andric ++__b; 2997*0b57cec5SDimitry Andric ++__sym_curr_char; 2998*0b57cec5SDimitry Andric } 2999*0b57cec5SDimitry Andric if (__sb && __sym_curr_char != __sym.end()) 3000*0b57cec5SDimitry Andric { 3001*0b57cec5SDimitry Andric __err |= ios_base::failbit; 3002*0b57cec5SDimitry Andric return false; 3003*0b57cec5SDimitry Andric } 3004*0b57cec5SDimitry Andric } 3005*0b57cec5SDimitry Andric } 3006*0b57cec5SDimitry Andric break; 3007*0b57cec5SDimitry Andric case money_base::value: 3008*0b57cec5SDimitry Andric { 3009*0b57cec5SDimitry Andric unsigned __ng = 0; 3010*0b57cec5SDimitry Andric for (; __b != __e; ++__b) 3011*0b57cec5SDimitry Andric { 3012*0b57cec5SDimitry Andric char_type __c = *__b; 3013*0b57cec5SDimitry Andric if (__ct.is(ctype_base::digit, __c)) 3014*0b57cec5SDimitry Andric { 3015*0b57cec5SDimitry Andric if (__wn == __we) 3016*0b57cec5SDimitry Andric __double_or_nothing(__wb, __wn, __we); 3017*0b57cec5SDimitry Andric *__wn++ = __c; 3018*0b57cec5SDimitry Andric ++__ng; 3019*0b57cec5SDimitry Andric } 3020*0b57cec5SDimitry Andric else if (__grp.size() > 0 && __ng > 0 && __c == __ts) 3021*0b57cec5SDimitry Andric { 3022*0b57cec5SDimitry Andric if (__gn == __ge) 3023*0b57cec5SDimitry Andric __double_or_nothing(__gb, __gn, __ge); 3024*0b57cec5SDimitry Andric *__gn++ = __ng; 3025*0b57cec5SDimitry Andric __ng = 0; 3026*0b57cec5SDimitry Andric } 3027*0b57cec5SDimitry Andric else 3028*0b57cec5SDimitry Andric break; 3029*0b57cec5SDimitry Andric } 3030*0b57cec5SDimitry Andric if (__gb.get() != __gn && __ng > 0) 3031*0b57cec5SDimitry Andric { 3032*0b57cec5SDimitry Andric if (__gn == __ge) 3033*0b57cec5SDimitry Andric __double_or_nothing(__gb, __gn, __ge); 3034*0b57cec5SDimitry Andric *__gn++ = __ng; 3035*0b57cec5SDimitry Andric } 3036*0b57cec5SDimitry Andric if (__fd > 0) 3037*0b57cec5SDimitry Andric { 3038*0b57cec5SDimitry Andric if (__b == __e || *__b != __dp) 3039*0b57cec5SDimitry Andric { 3040*0b57cec5SDimitry Andric __err |= ios_base::failbit; 3041*0b57cec5SDimitry Andric return false; 3042*0b57cec5SDimitry Andric } 3043*0b57cec5SDimitry Andric for (++__b; __fd > 0; --__fd, ++__b) 3044*0b57cec5SDimitry Andric { 3045*0b57cec5SDimitry Andric if (__b == __e || !__ct.is(ctype_base::digit, *__b)) 3046*0b57cec5SDimitry Andric { 3047*0b57cec5SDimitry Andric __err |= ios_base::failbit; 3048*0b57cec5SDimitry Andric return false; 3049*0b57cec5SDimitry Andric } 3050*0b57cec5SDimitry Andric if (__wn == __we) 3051*0b57cec5SDimitry Andric __double_or_nothing(__wb, __wn, __we); 3052*0b57cec5SDimitry Andric *__wn++ = *__b; 3053*0b57cec5SDimitry Andric } 3054*0b57cec5SDimitry Andric } 3055*0b57cec5SDimitry Andric if (__wn == __wb.get()) 3056*0b57cec5SDimitry Andric { 3057*0b57cec5SDimitry Andric __err |= ios_base::failbit; 3058*0b57cec5SDimitry Andric return false; 3059*0b57cec5SDimitry Andric } 3060*0b57cec5SDimitry Andric } 3061*0b57cec5SDimitry Andric break; 3062*0b57cec5SDimitry Andric } 3063*0b57cec5SDimitry Andric } 3064*0b57cec5SDimitry Andric if (__trailing_sign) 3065*0b57cec5SDimitry Andric { 3066*0b57cec5SDimitry Andric for (unsigned __i = 1; __i < __trailing_sign->size(); ++__i, ++__b) 3067*0b57cec5SDimitry Andric { 3068*0b57cec5SDimitry Andric if (__b == __e || *__b != (*__trailing_sign)[__i]) 3069*0b57cec5SDimitry Andric { 3070*0b57cec5SDimitry Andric __err |= ios_base::failbit; 3071*0b57cec5SDimitry Andric return false; 3072*0b57cec5SDimitry Andric } 3073*0b57cec5SDimitry Andric } 3074*0b57cec5SDimitry Andric } 3075*0b57cec5SDimitry Andric if (__gb.get() != __gn) 3076*0b57cec5SDimitry Andric { 3077*0b57cec5SDimitry Andric ios_base::iostate __et = ios_base::goodbit; 3078*0b57cec5SDimitry Andric __check_grouping(__grp, __gb.get(), __gn, __et); 3079*0b57cec5SDimitry Andric if (__et) 3080*0b57cec5SDimitry Andric { 3081*0b57cec5SDimitry Andric __err |= ios_base::failbit; 3082*0b57cec5SDimitry Andric return false; 3083*0b57cec5SDimitry Andric } 3084*0b57cec5SDimitry Andric } 3085*0b57cec5SDimitry Andric return true; 3086*0b57cec5SDimitry Andric} 3087*0b57cec5SDimitry Andric 3088*0b57cec5SDimitry Andrictemplate <class _CharT, class _InputIterator> 3089*0b57cec5SDimitry Andric_InputIterator 3090*0b57cec5SDimitry Andricmoney_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e, 3091*0b57cec5SDimitry Andric bool __intl, ios_base& __iob, 3092*0b57cec5SDimitry Andric ios_base::iostate& __err, 3093*0b57cec5SDimitry Andric long double& __v) const 3094*0b57cec5SDimitry Andric{ 3095*0b57cec5SDimitry Andric const int __bz = 100; 3096*0b57cec5SDimitry Andric char_type __wbuf[__bz]; 3097*0b57cec5SDimitry Andric unique_ptr<char_type, void(*)(void*)> __wb(__wbuf, __do_nothing); 3098*0b57cec5SDimitry Andric char_type* __wn; 3099*0b57cec5SDimitry Andric char_type* __we = __wbuf + __bz; 3100*0b57cec5SDimitry Andric locale __loc = __iob.getloc(); 3101*0b57cec5SDimitry Andric const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__loc); 3102*0b57cec5SDimitry Andric bool __neg = false; 3103*0b57cec5SDimitry Andric if (__do_get(__b, __e, __intl, __loc, __iob.flags(), __err, __neg, __ct, 3104*0b57cec5SDimitry Andric __wb, __wn, __we)) 3105*0b57cec5SDimitry Andric { 3106*0b57cec5SDimitry Andric const char __src[] = "0123456789"; 3107*0b57cec5SDimitry Andric char_type __atoms[sizeof(__src)-1]; 3108*0b57cec5SDimitry Andric __ct.widen(__src, __src + (sizeof(__src)-1), __atoms); 3109*0b57cec5SDimitry Andric char __nbuf[__bz]; 3110*0b57cec5SDimitry Andric char* __nc = __nbuf; 3111*0b57cec5SDimitry Andric unique_ptr<char, void(*)(void*)> __h(0, free); 3112*0b57cec5SDimitry Andric if (__wn - __wb.get() > __bz-2) 3113*0b57cec5SDimitry Andric { 3114*0b57cec5SDimitry Andric __h.reset((char*)malloc(static_cast<size_t>(__wn - __wb.get() + 2))); 3115*0b57cec5SDimitry Andric if (__h.get() == 0) 3116*0b57cec5SDimitry Andric __throw_bad_alloc(); 3117*0b57cec5SDimitry Andric __nc = __h.get(); 3118*0b57cec5SDimitry Andric } 3119*0b57cec5SDimitry Andric if (__neg) 3120*0b57cec5SDimitry Andric *__nc++ = '-'; 3121*0b57cec5SDimitry Andric for (const char_type* __w = __wb.get(); __w < __wn; ++__w, ++__nc) 3122*0b57cec5SDimitry Andric *__nc = __src[find(__atoms, _VSTD::end(__atoms), *__w) - __atoms]; 3123*0b57cec5SDimitry Andric *__nc = char(); 3124*0b57cec5SDimitry Andric if (sscanf(__nbuf, "%Lf", &__v) != 1) 3125*0b57cec5SDimitry Andric __throw_runtime_error("money_get error"); 3126*0b57cec5SDimitry Andric } 3127*0b57cec5SDimitry Andric if (__b == __e) 3128*0b57cec5SDimitry Andric __err |= ios_base::eofbit; 3129*0b57cec5SDimitry Andric return __b; 3130*0b57cec5SDimitry Andric} 3131*0b57cec5SDimitry Andric 3132*0b57cec5SDimitry Andrictemplate <class _CharT, class _InputIterator> 3133*0b57cec5SDimitry Andric_InputIterator 3134*0b57cec5SDimitry Andricmoney_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e, 3135*0b57cec5SDimitry Andric bool __intl, ios_base& __iob, 3136*0b57cec5SDimitry Andric ios_base::iostate& __err, 3137*0b57cec5SDimitry Andric string_type& __v) const 3138*0b57cec5SDimitry Andric{ 3139*0b57cec5SDimitry Andric const int __bz = 100; 3140*0b57cec5SDimitry Andric char_type __wbuf[__bz]; 3141*0b57cec5SDimitry Andric unique_ptr<char_type, void(*)(void*)> __wb(__wbuf, __do_nothing); 3142*0b57cec5SDimitry Andric char_type* __wn; 3143*0b57cec5SDimitry Andric char_type* __we = __wbuf + __bz; 3144*0b57cec5SDimitry Andric locale __loc = __iob.getloc(); 3145*0b57cec5SDimitry Andric const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__loc); 3146*0b57cec5SDimitry Andric bool __neg = false; 3147*0b57cec5SDimitry Andric if (__do_get(__b, __e, __intl, __loc, __iob.flags(), __err, __neg, __ct, 3148*0b57cec5SDimitry Andric __wb, __wn, __we)) 3149*0b57cec5SDimitry Andric { 3150*0b57cec5SDimitry Andric __v.clear(); 3151*0b57cec5SDimitry Andric if (__neg) 3152*0b57cec5SDimitry Andric __v.push_back(__ct.widen('-')); 3153*0b57cec5SDimitry Andric char_type __z = __ct.widen('0'); 3154*0b57cec5SDimitry Andric char_type* __w; 3155*0b57cec5SDimitry Andric for (__w = __wb.get(); __w < __wn-1; ++__w) 3156*0b57cec5SDimitry Andric if (*__w != __z) 3157*0b57cec5SDimitry Andric break; 3158*0b57cec5SDimitry Andric __v.append(__w, __wn); 3159*0b57cec5SDimitry Andric } 3160*0b57cec5SDimitry Andric if (__b == __e) 3161*0b57cec5SDimitry Andric __err |= ios_base::eofbit; 3162*0b57cec5SDimitry Andric return __b; 3163*0b57cec5SDimitry Andric} 3164*0b57cec5SDimitry Andric 3165*0b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS money_get<char>) 3166*0b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS money_get<wchar_t>) 3167*0b57cec5SDimitry Andric 3168*0b57cec5SDimitry Andric// money_put 3169*0b57cec5SDimitry Andric 3170*0b57cec5SDimitry Andrictemplate <class _CharT> 3171*0b57cec5SDimitry Andricclass __money_put 3172*0b57cec5SDimitry Andric{ 3173*0b57cec5SDimitry Andricprotected: 3174*0b57cec5SDimitry Andric typedef _CharT char_type; 3175*0b57cec5SDimitry Andric typedef basic_string<char_type> string_type; 3176*0b57cec5SDimitry Andric 3177*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY __money_put() {} 3178*0b57cec5SDimitry Andric 3179*0b57cec5SDimitry Andric static void __gather_info(bool __intl, bool __neg, const locale& __loc, 3180*0b57cec5SDimitry Andric money_base::pattern& __pat, char_type& __dp, 3181*0b57cec5SDimitry Andric char_type& __ts, string& __grp, 3182*0b57cec5SDimitry Andric string_type& __sym, string_type& __sn, 3183*0b57cec5SDimitry Andric int& __fd); 3184*0b57cec5SDimitry Andric static void __format(char_type* __mb, char_type*& __mi, char_type*& __me, 3185*0b57cec5SDimitry Andric ios_base::fmtflags __flags, 3186*0b57cec5SDimitry Andric const char_type* __db, const char_type* __de, 3187*0b57cec5SDimitry Andric const ctype<char_type>& __ct, bool __neg, 3188*0b57cec5SDimitry Andric const money_base::pattern& __pat, char_type __dp, 3189*0b57cec5SDimitry Andric char_type __ts, const string& __grp, 3190*0b57cec5SDimitry Andric const string_type& __sym, const string_type& __sn, 3191*0b57cec5SDimitry Andric int __fd); 3192*0b57cec5SDimitry Andric}; 3193*0b57cec5SDimitry Andric 3194*0b57cec5SDimitry Andrictemplate <class _CharT> 3195*0b57cec5SDimitry Andricvoid 3196*0b57cec5SDimitry Andric__money_put<_CharT>::__gather_info(bool __intl, bool __neg, const locale& __loc, 3197*0b57cec5SDimitry Andric money_base::pattern& __pat, char_type& __dp, 3198*0b57cec5SDimitry Andric char_type& __ts, string& __grp, 3199*0b57cec5SDimitry Andric string_type& __sym, string_type& __sn, 3200*0b57cec5SDimitry Andric int& __fd) 3201*0b57cec5SDimitry Andric{ 3202*0b57cec5SDimitry Andric if (__intl) 3203*0b57cec5SDimitry Andric { 3204*0b57cec5SDimitry Andric const moneypunct<char_type, true>& __mp = 3205*0b57cec5SDimitry Andric use_facet<moneypunct<char_type, true> >(__loc); 3206*0b57cec5SDimitry Andric if (__neg) 3207*0b57cec5SDimitry Andric { 3208*0b57cec5SDimitry Andric __pat = __mp.neg_format(); 3209*0b57cec5SDimitry Andric __sn = __mp.negative_sign(); 3210*0b57cec5SDimitry Andric } 3211*0b57cec5SDimitry Andric else 3212*0b57cec5SDimitry Andric { 3213*0b57cec5SDimitry Andric __pat = __mp.pos_format(); 3214*0b57cec5SDimitry Andric __sn = __mp.positive_sign(); 3215*0b57cec5SDimitry Andric } 3216*0b57cec5SDimitry Andric __dp = __mp.decimal_point(); 3217*0b57cec5SDimitry Andric __ts = __mp.thousands_sep(); 3218*0b57cec5SDimitry Andric __grp = __mp.grouping(); 3219*0b57cec5SDimitry Andric __sym = __mp.curr_symbol(); 3220*0b57cec5SDimitry Andric __fd = __mp.frac_digits(); 3221*0b57cec5SDimitry Andric } 3222*0b57cec5SDimitry Andric else 3223*0b57cec5SDimitry Andric { 3224*0b57cec5SDimitry Andric const moneypunct<char_type, false>& __mp = 3225*0b57cec5SDimitry Andric use_facet<moneypunct<char_type, false> >(__loc); 3226*0b57cec5SDimitry Andric if (__neg) 3227*0b57cec5SDimitry Andric { 3228*0b57cec5SDimitry Andric __pat = __mp.neg_format(); 3229*0b57cec5SDimitry Andric __sn = __mp.negative_sign(); 3230*0b57cec5SDimitry Andric } 3231*0b57cec5SDimitry Andric else 3232*0b57cec5SDimitry Andric { 3233*0b57cec5SDimitry Andric __pat = __mp.pos_format(); 3234*0b57cec5SDimitry Andric __sn = __mp.positive_sign(); 3235*0b57cec5SDimitry Andric } 3236*0b57cec5SDimitry Andric __dp = __mp.decimal_point(); 3237*0b57cec5SDimitry Andric __ts = __mp.thousands_sep(); 3238*0b57cec5SDimitry Andric __grp = __mp.grouping(); 3239*0b57cec5SDimitry Andric __sym = __mp.curr_symbol(); 3240*0b57cec5SDimitry Andric __fd = __mp.frac_digits(); 3241*0b57cec5SDimitry Andric } 3242*0b57cec5SDimitry Andric} 3243*0b57cec5SDimitry Andric 3244*0b57cec5SDimitry Andrictemplate <class _CharT> 3245*0b57cec5SDimitry Andricvoid 3246*0b57cec5SDimitry Andric__money_put<_CharT>::__format(char_type* __mb, char_type*& __mi, char_type*& __me, 3247*0b57cec5SDimitry Andric ios_base::fmtflags __flags, 3248*0b57cec5SDimitry Andric const char_type* __db, const char_type* __de, 3249*0b57cec5SDimitry Andric const ctype<char_type>& __ct, bool __neg, 3250*0b57cec5SDimitry Andric const money_base::pattern& __pat, char_type __dp, 3251*0b57cec5SDimitry Andric char_type __ts, const string& __grp, 3252*0b57cec5SDimitry Andric const string_type& __sym, const string_type& __sn, 3253*0b57cec5SDimitry Andric int __fd) 3254*0b57cec5SDimitry Andric{ 3255*0b57cec5SDimitry Andric __me = __mb; 3256*0b57cec5SDimitry Andric for (unsigned __p = 0; __p < 4; ++__p) 3257*0b57cec5SDimitry Andric { 3258*0b57cec5SDimitry Andric switch (__pat.field[__p]) 3259*0b57cec5SDimitry Andric { 3260*0b57cec5SDimitry Andric case money_base::none: 3261*0b57cec5SDimitry Andric __mi = __me; 3262*0b57cec5SDimitry Andric break; 3263*0b57cec5SDimitry Andric case money_base::space: 3264*0b57cec5SDimitry Andric __mi = __me; 3265*0b57cec5SDimitry Andric *__me++ = __ct.widen(' '); 3266*0b57cec5SDimitry Andric break; 3267*0b57cec5SDimitry Andric case money_base::sign: 3268*0b57cec5SDimitry Andric if (!__sn.empty()) 3269*0b57cec5SDimitry Andric *__me++ = __sn[0]; 3270*0b57cec5SDimitry Andric break; 3271*0b57cec5SDimitry Andric case money_base::symbol: 3272*0b57cec5SDimitry Andric if (!__sym.empty() && (__flags & ios_base::showbase)) 3273*0b57cec5SDimitry Andric __me = _VSTD::copy(__sym.begin(), __sym.end(), __me); 3274*0b57cec5SDimitry Andric break; 3275*0b57cec5SDimitry Andric case money_base::value: 3276*0b57cec5SDimitry Andric { 3277*0b57cec5SDimitry Andric // remember start of value so we can reverse it 3278*0b57cec5SDimitry Andric char_type* __t = __me; 3279*0b57cec5SDimitry Andric // find beginning of digits 3280*0b57cec5SDimitry Andric if (__neg) 3281*0b57cec5SDimitry Andric ++__db; 3282*0b57cec5SDimitry Andric // find end of digits 3283*0b57cec5SDimitry Andric const char_type* __d; 3284*0b57cec5SDimitry Andric for (__d = __db; __d < __de; ++__d) 3285*0b57cec5SDimitry Andric if (!__ct.is(ctype_base::digit, *__d)) 3286*0b57cec5SDimitry Andric break; 3287*0b57cec5SDimitry Andric // print fractional part 3288*0b57cec5SDimitry Andric if (__fd > 0) 3289*0b57cec5SDimitry Andric { 3290*0b57cec5SDimitry Andric int __f; 3291*0b57cec5SDimitry Andric for (__f = __fd; __d > __db && __f > 0; --__f) 3292*0b57cec5SDimitry Andric *__me++ = *--__d; 3293*0b57cec5SDimitry Andric char_type __z = __f > 0 ? __ct.widen('0') : char_type(); 3294*0b57cec5SDimitry Andric for (; __f > 0; --__f) 3295*0b57cec5SDimitry Andric *__me++ = __z; 3296*0b57cec5SDimitry Andric *__me++ = __dp; 3297*0b57cec5SDimitry Andric } 3298*0b57cec5SDimitry Andric // print units part 3299*0b57cec5SDimitry Andric if (__d == __db) 3300*0b57cec5SDimitry Andric { 3301*0b57cec5SDimitry Andric *__me++ = __ct.widen('0'); 3302*0b57cec5SDimitry Andric } 3303*0b57cec5SDimitry Andric else 3304*0b57cec5SDimitry Andric { 3305*0b57cec5SDimitry Andric unsigned __ng = 0; 3306*0b57cec5SDimitry Andric unsigned __ig = 0; 3307*0b57cec5SDimitry Andric unsigned __gl = __grp.empty() ? numeric_limits<unsigned>::max() 3308*0b57cec5SDimitry Andric : static_cast<unsigned>(__grp[__ig]); 3309*0b57cec5SDimitry Andric while (__d != __db) 3310*0b57cec5SDimitry Andric { 3311*0b57cec5SDimitry Andric if (__ng == __gl) 3312*0b57cec5SDimitry Andric { 3313*0b57cec5SDimitry Andric *__me++ = __ts; 3314*0b57cec5SDimitry Andric __ng = 0; 3315*0b57cec5SDimitry Andric if (++__ig < __grp.size()) 3316*0b57cec5SDimitry Andric __gl = __grp[__ig] == numeric_limits<char>::max() ? 3317*0b57cec5SDimitry Andric numeric_limits<unsigned>::max() : 3318*0b57cec5SDimitry Andric static_cast<unsigned>(__grp[__ig]); 3319*0b57cec5SDimitry Andric } 3320*0b57cec5SDimitry Andric *__me++ = *--__d; 3321*0b57cec5SDimitry Andric ++__ng; 3322*0b57cec5SDimitry Andric } 3323*0b57cec5SDimitry Andric } 3324*0b57cec5SDimitry Andric // reverse it 3325*0b57cec5SDimitry Andric reverse(__t, __me); 3326*0b57cec5SDimitry Andric } 3327*0b57cec5SDimitry Andric break; 3328*0b57cec5SDimitry Andric } 3329*0b57cec5SDimitry Andric } 3330*0b57cec5SDimitry Andric // print rest of sign, if any 3331*0b57cec5SDimitry Andric if (__sn.size() > 1) 3332*0b57cec5SDimitry Andric __me = _VSTD::copy(__sn.begin()+1, __sn.end(), __me); 3333*0b57cec5SDimitry Andric // set alignment 3334*0b57cec5SDimitry Andric if ((__flags & ios_base::adjustfield) == ios_base::left) 3335*0b57cec5SDimitry Andric __mi = __me; 3336*0b57cec5SDimitry Andric else if ((__flags & ios_base::adjustfield) != ios_base::internal) 3337*0b57cec5SDimitry Andric __mi = __mb; 3338*0b57cec5SDimitry Andric} 3339*0b57cec5SDimitry Andric 3340*0b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __money_put<char>) 3341*0b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __money_put<wchar_t>) 3342*0b57cec5SDimitry Andric 3343*0b57cec5SDimitry Andrictemplate <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> > 3344*0b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS money_put 3345*0b57cec5SDimitry Andric : public locale::facet, 3346*0b57cec5SDimitry Andric private __money_put<_CharT> 3347*0b57cec5SDimitry Andric{ 3348*0b57cec5SDimitry Andricpublic: 3349*0b57cec5SDimitry Andric typedef _CharT char_type; 3350*0b57cec5SDimitry Andric typedef _OutputIterator iter_type; 3351*0b57cec5SDimitry Andric typedef basic_string<char_type> string_type; 3352*0b57cec5SDimitry Andric 3353*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 3354*0b57cec5SDimitry Andric explicit money_put(size_t __refs = 0) 3355*0b57cec5SDimitry Andric : locale::facet(__refs) {} 3356*0b57cec5SDimitry Andric 3357*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 3358*0b57cec5SDimitry Andric iter_type put(iter_type __s, bool __intl, ios_base& __iob, char_type __fl, 3359*0b57cec5SDimitry Andric long double __units) const 3360*0b57cec5SDimitry Andric { 3361*0b57cec5SDimitry Andric return do_put(__s, __intl, __iob, __fl, __units); 3362*0b57cec5SDimitry Andric } 3363*0b57cec5SDimitry Andric 3364*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 3365*0b57cec5SDimitry Andric iter_type put(iter_type __s, bool __intl, ios_base& __iob, char_type __fl, 3366*0b57cec5SDimitry Andric const string_type& __digits) const 3367*0b57cec5SDimitry Andric { 3368*0b57cec5SDimitry Andric return do_put(__s, __intl, __iob, __fl, __digits); 3369*0b57cec5SDimitry Andric } 3370*0b57cec5SDimitry Andric 3371*0b57cec5SDimitry Andric static locale::id id; 3372*0b57cec5SDimitry Andric 3373*0b57cec5SDimitry Andricprotected: 3374*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 3375*0b57cec5SDimitry Andric ~money_put() {} 3376*0b57cec5SDimitry Andric 3377*0b57cec5SDimitry Andric virtual iter_type do_put(iter_type __s, bool __intl, ios_base& __iob, 3378*0b57cec5SDimitry Andric char_type __fl, long double __units) const; 3379*0b57cec5SDimitry Andric virtual iter_type do_put(iter_type __s, bool __intl, ios_base& __iob, 3380*0b57cec5SDimitry Andric char_type __fl, const string_type& __digits) const; 3381*0b57cec5SDimitry Andric}; 3382*0b57cec5SDimitry Andric 3383*0b57cec5SDimitry Andrictemplate <class _CharT, class _OutputIterator> 3384*0b57cec5SDimitry Andriclocale::id 3385*0b57cec5SDimitry Andricmoney_put<_CharT, _OutputIterator>::id; 3386*0b57cec5SDimitry Andric 3387*0b57cec5SDimitry Andrictemplate <class _CharT, class _OutputIterator> 3388*0b57cec5SDimitry Andric_OutputIterator 3389*0b57cec5SDimitry Andricmoney_put<_CharT, _OutputIterator>::do_put(iter_type __s, bool __intl, 3390*0b57cec5SDimitry Andric ios_base& __iob, char_type __fl, 3391*0b57cec5SDimitry Andric long double __units) const 3392*0b57cec5SDimitry Andric{ 3393*0b57cec5SDimitry Andric // convert to char 3394*0b57cec5SDimitry Andric const size_t __bs = 100; 3395*0b57cec5SDimitry Andric char __buf[__bs]; 3396*0b57cec5SDimitry Andric char* __bb = __buf; 3397*0b57cec5SDimitry Andric char_type __digits[__bs]; 3398*0b57cec5SDimitry Andric char_type* __db = __digits; 3399*0b57cec5SDimitry Andric size_t __n = static_cast<size_t>(snprintf(__bb, __bs, "%.0Lf", __units)); 3400*0b57cec5SDimitry Andric unique_ptr<char, void(*)(void*)> __hn(0, free); 3401*0b57cec5SDimitry Andric unique_ptr<char_type, void(*)(void*)> __hd(0, free); 3402*0b57cec5SDimitry Andric // secure memory for digit storage 3403*0b57cec5SDimitry Andric if (__n > __bs-1) 3404*0b57cec5SDimitry Andric { 3405*0b57cec5SDimitry Andric __n = static_cast<size_t>(__libcpp_asprintf_l(&__bb, _LIBCPP_GET_C_LOCALE, "%.0Lf", __units)); 3406*0b57cec5SDimitry Andric if (__bb == 0) 3407*0b57cec5SDimitry Andric __throw_bad_alloc(); 3408*0b57cec5SDimitry Andric __hn.reset(__bb); 3409*0b57cec5SDimitry Andric __hd.reset((char_type*)malloc(__n * sizeof(char_type))); 3410*0b57cec5SDimitry Andric if (__hd == nullptr) 3411*0b57cec5SDimitry Andric __throw_bad_alloc(); 3412*0b57cec5SDimitry Andric __db = __hd.get(); 3413*0b57cec5SDimitry Andric } 3414*0b57cec5SDimitry Andric // gather info 3415*0b57cec5SDimitry Andric locale __loc = __iob.getloc(); 3416*0b57cec5SDimitry Andric const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__loc); 3417*0b57cec5SDimitry Andric __ct.widen(__bb, __bb + __n, __db); 3418*0b57cec5SDimitry Andric bool __neg = __n > 0 && __bb[0] == '-'; 3419*0b57cec5SDimitry Andric money_base::pattern __pat; 3420*0b57cec5SDimitry Andric char_type __dp; 3421*0b57cec5SDimitry Andric char_type __ts; 3422*0b57cec5SDimitry Andric string __grp; 3423*0b57cec5SDimitry Andric string_type __sym; 3424*0b57cec5SDimitry Andric string_type __sn; 3425*0b57cec5SDimitry Andric int __fd; 3426*0b57cec5SDimitry Andric this->__gather_info(__intl, __neg, __loc, __pat, __dp, __ts, __grp, __sym, __sn, __fd); 3427*0b57cec5SDimitry Andric // secure memory for formatting 3428*0b57cec5SDimitry Andric char_type __mbuf[__bs]; 3429*0b57cec5SDimitry Andric char_type* __mb = __mbuf; 3430*0b57cec5SDimitry Andric unique_ptr<char_type, void(*)(void*)> __hw(0, free); 3431*0b57cec5SDimitry Andric size_t __exn = static_cast<int>(__n) > __fd ? 3432*0b57cec5SDimitry Andric (__n - static_cast<size_t>(__fd)) * 2 + __sn.size() + 3433*0b57cec5SDimitry Andric __sym.size() + static_cast<size_t>(__fd) + 1 3434*0b57cec5SDimitry Andric : __sn.size() + __sym.size() + static_cast<size_t>(__fd) + 2; 3435*0b57cec5SDimitry Andric if (__exn > __bs) 3436*0b57cec5SDimitry Andric { 3437*0b57cec5SDimitry Andric __hw.reset((char_type*)malloc(__exn * sizeof(char_type))); 3438*0b57cec5SDimitry Andric __mb = __hw.get(); 3439*0b57cec5SDimitry Andric if (__mb == 0) 3440*0b57cec5SDimitry Andric __throw_bad_alloc(); 3441*0b57cec5SDimitry Andric } 3442*0b57cec5SDimitry Andric // format 3443*0b57cec5SDimitry Andric char_type* __mi; 3444*0b57cec5SDimitry Andric char_type* __me; 3445*0b57cec5SDimitry Andric this->__format(__mb, __mi, __me, __iob.flags(), 3446*0b57cec5SDimitry Andric __db, __db + __n, __ct, 3447*0b57cec5SDimitry Andric __neg, __pat, __dp, __ts, __grp, __sym, __sn, __fd); 3448*0b57cec5SDimitry Andric return __pad_and_output(__s, __mb, __mi, __me, __iob, __fl); 3449*0b57cec5SDimitry Andric} 3450*0b57cec5SDimitry Andric 3451*0b57cec5SDimitry Andrictemplate <class _CharT, class _OutputIterator> 3452*0b57cec5SDimitry Andric_OutputIterator 3453*0b57cec5SDimitry Andricmoney_put<_CharT, _OutputIterator>::do_put(iter_type __s, bool __intl, 3454*0b57cec5SDimitry Andric ios_base& __iob, char_type __fl, 3455*0b57cec5SDimitry Andric const string_type& __digits) const 3456*0b57cec5SDimitry Andric{ 3457*0b57cec5SDimitry Andric // gather info 3458*0b57cec5SDimitry Andric locale __loc = __iob.getloc(); 3459*0b57cec5SDimitry Andric const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__loc); 3460*0b57cec5SDimitry Andric bool __neg = __digits.size() > 0 && __digits[0] == __ct.widen('-'); 3461*0b57cec5SDimitry Andric money_base::pattern __pat; 3462*0b57cec5SDimitry Andric char_type __dp; 3463*0b57cec5SDimitry Andric char_type __ts; 3464*0b57cec5SDimitry Andric string __grp; 3465*0b57cec5SDimitry Andric string_type __sym; 3466*0b57cec5SDimitry Andric string_type __sn; 3467*0b57cec5SDimitry Andric int __fd; 3468*0b57cec5SDimitry Andric this->__gather_info(__intl, __neg, __loc, __pat, __dp, __ts, __grp, __sym, __sn, __fd); 3469*0b57cec5SDimitry Andric // secure memory for formatting 3470*0b57cec5SDimitry Andric char_type __mbuf[100]; 3471*0b57cec5SDimitry Andric char_type* __mb = __mbuf; 3472*0b57cec5SDimitry Andric unique_ptr<char_type, void(*)(void*)> __h(0, free); 3473*0b57cec5SDimitry Andric size_t __exn = static_cast<int>(__digits.size()) > __fd ? 3474*0b57cec5SDimitry Andric (__digits.size() - static_cast<size_t>(__fd)) * 2 + 3475*0b57cec5SDimitry Andric __sn.size() + __sym.size() + static_cast<size_t>(__fd) + 1 3476*0b57cec5SDimitry Andric : __sn.size() + __sym.size() + static_cast<size_t>(__fd) + 2; 3477*0b57cec5SDimitry Andric if (__exn > 100) 3478*0b57cec5SDimitry Andric { 3479*0b57cec5SDimitry Andric __h.reset((char_type*)malloc(__exn * sizeof(char_type))); 3480*0b57cec5SDimitry Andric __mb = __h.get(); 3481*0b57cec5SDimitry Andric if (__mb == 0) 3482*0b57cec5SDimitry Andric __throw_bad_alloc(); 3483*0b57cec5SDimitry Andric } 3484*0b57cec5SDimitry Andric // format 3485*0b57cec5SDimitry Andric char_type* __mi; 3486*0b57cec5SDimitry Andric char_type* __me; 3487*0b57cec5SDimitry Andric this->__format(__mb, __mi, __me, __iob.flags(), 3488*0b57cec5SDimitry Andric __digits.data(), __digits.data() + __digits.size(), __ct, 3489*0b57cec5SDimitry Andric __neg, __pat, __dp, __ts, __grp, __sym, __sn, __fd); 3490*0b57cec5SDimitry Andric return __pad_and_output(__s, __mb, __mi, __me, __iob, __fl); 3491*0b57cec5SDimitry Andric} 3492*0b57cec5SDimitry Andric 3493*0b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS money_put<char>) 3494*0b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS money_put<wchar_t>) 3495*0b57cec5SDimitry Andric 3496*0b57cec5SDimitry Andric// messages 3497*0b57cec5SDimitry Andric 3498*0b57cec5SDimitry Andricclass _LIBCPP_TYPE_VIS messages_base 3499*0b57cec5SDimitry Andric{ 3500*0b57cec5SDimitry Andricpublic: 3501*0b57cec5SDimitry Andric typedef ptrdiff_t catalog; 3502*0b57cec5SDimitry Andric 3503*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY messages_base() {} 3504*0b57cec5SDimitry Andric}; 3505*0b57cec5SDimitry Andric 3506*0b57cec5SDimitry Andrictemplate <class _CharT> 3507*0b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS messages 3508*0b57cec5SDimitry Andric : public locale::facet, 3509*0b57cec5SDimitry Andric public messages_base 3510*0b57cec5SDimitry Andric{ 3511*0b57cec5SDimitry Andricpublic: 3512*0b57cec5SDimitry Andric typedef _CharT char_type; 3513*0b57cec5SDimitry Andric typedef basic_string<_CharT> string_type; 3514*0b57cec5SDimitry Andric 3515*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 3516*0b57cec5SDimitry Andric explicit messages(size_t __refs = 0) 3517*0b57cec5SDimitry Andric : locale::facet(__refs) {} 3518*0b57cec5SDimitry Andric 3519*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 3520*0b57cec5SDimitry Andric catalog open(const basic_string<char>& __nm, const locale& __loc) const 3521*0b57cec5SDimitry Andric { 3522*0b57cec5SDimitry Andric return do_open(__nm, __loc); 3523*0b57cec5SDimitry Andric } 3524*0b57cec5SDimitry Andric 3525*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 3526*0b57cec5SDimitry Andric string_type get(catalog __c, int __set, int __msgid, 3527*0b57cec5SDimitry Andric const string_type& __dflt) const 3528*0b57cec5SDimitry Andric { 3529*0b57cec5SDimitry Andric return do_get(__c, __set, __msgid, __dflt); 3530*0b57cec5SDimitry Andric } 3531*0b57cec5SDimitry Andric 3532*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 3533*0b57cec5SDimitry Andric void close(catalog __c) const 3534*0b57cec5SDimitry Andric { 3535*0b57cec5SDimitry Andric do_close(__c); 3536*0b57cec5SDimitry Andric } 3537*0b57cec5SDimitry Andric 3538*0b57cec5SDimitry Andric static locale::id id; 3539*0b57cec5SDimitry Andric 3540*0b57cec5SDimitry Andricprotected: 3541*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 3542*0b57cec5SDimitry Andric ~messages() {} 3543*0b57cec5SDimitry Andric 3544*0b57cec5SDimitry Andric virtual catalog do_open(const basic_string<char>&, const locale&) const; 3545*0b57cec5SDimitry Andric virtual string_type do_get(catalog, int __set, int __msgid, 3546*0b57cec5SDimitry Andric const string_type& __dflt) const; 3547*0b57cec5SDimitry Andric virtual void do_close(catalog) const; 3548*0b57cec5SDimitry Andric}; 3549*0b57cec5SDimitry Andric 3550*0b57cec5SDimitry Andrictemplate <class _CharT> 3551*0b57cec5SDimitry Andriclocale::id 3552*0b57cec5SDimitry Andricmessages<_CharT>::id; 3553*0b57cec5SDimitry Andric 3554*0b57cec5SDimitry Andrictemplate <class _CharT> 3555*0b57cec5SDimitry Andrictypename messages<_CharT>::catalog 3556*0b57cec5SDimitry Andricmessages<_CharT>::do_open(const basic_string<char>& __nm, const locale&) const 3557*0b57cec5SDimitry Andric{ 3558*0b57cec5SDimitry Andric#ifdef _LIBCPP_HAS_CATOPEN 3559*0b57cec5SDimitry Andric catalog __cat = (catalog)catopen(__nm.c_str(), NL_CAT_LOCALE); 3560*0b57cec5SDimitry Andric if (__cat != -1) 3561*0b57cec5SDimitry Andric __cat = static_cast<catalog>((static_cast<size_t>(__cat) >> 1)); 3562*0b57cec5SDimitry Andric return __cat; 3563*0b57cec5SDimitry Andric#else // !_LIBCPP_HAS_CATOPEN 3564*0b57cec5SDimitry Andric _LIBCPP_UNUSED_VAR(__nm); 3565*0b57cec5SDimitry Andric return -1; 3566*0b57cec5SDimitry Andric#endif // _LIBCPP_HAS_CATOPEN 3567*0b57cec5SDimitry Andric} 3568*0b57cec5SDimitry Andric 3569*0b57cec5SDimitry Andrictemplate <class _CharT> 3570*0b57cec5SDimitry Andrictypename messages<_CharT>::string_type 3571*0b57cec5SDimitry Andricmessages<_CharT>::do_get(catalog __c, int __set, int __msgid, 3572*0b57cec5SDimitry Andric const string_type& __dflt) const 3573*0b57cec5SDimitry Andric{ 3574*0b57cec5SDimitry Andric#ifdef _LIBCPP_HAS_CATOPEN 3575*0b57cec5SDimitry Andric string __ndflt; 3576*0b57cec5SDimitry Andric __narrow_to_utf8<sizeof(char_type)*__CHAR_BIT__>()(back_inserter(__ndflt), 3577*0b57cec5SDimitry Andric __dflt.c_str(), 3578*0b57cec5SDimitry Andric __dflt.c_str() + __dflt.size()); 3579*0b57cec5SDimitry Andric if (__c != -1) 3580*0b57cec5SDimitry Andric __c <<= 1; 3581*0b57cec5SDimitry Andric nl_catd __cat = (nl_catd)__c; 3582*0b57cec5SDimitry Andric char* __n = catgets(__cat, __set, __msgid, __ndflt.c_str()); 3583*0b57cec5SDimitry Andric string_type __w; 3584*0b57cec5SDimitry Andric __widen_from_utf8<sizeof(char_type)*__CHAR_BIT__>()(back_inserter(__w), 3585*0b57cec5SDimitry Andric __n, __n + strlen(__n)); 3586*0b57cec5SDimitry Andric return __w; 3587*0b57cec5SDimitry Andric#else // !_LIBCPP_HAS_CATOPEN 3588*0b57cec5SDimitry Andric _LIBCPP_UNUSED_VAR(__c); 3589*0b57cec5SDimitry Andric _LIBCPP_UNUSED_VAR(__set); 3590*0b57cec5SDimitry Andric _LIBCPP_UNUSED_VAR(__msgid); 3591*0b57cec5SDimitry Andric return __dflt; 3592*0b57cec5SDimitry Andric#endif // _LIBCPP_HAS_CATOPEN 3593*0b57cec5SDimitry Andric} 3594*0b57cec5SDimitry Andric 3595*0b57cec5SDimitry Andrictemplate <class _CharT> 3596*0b57cec5SDimitry Andricvoid 3597*0b57cec5SDimitry Andricmessages<_CharT>::do_close(catalog __c) const 3598*0b57cec5SDimitry Andric{ 3599*0b57cec5SDimitry Andric#ifdef _LIBCPP_HAS_CATOPEN 3600*0b57cec5SDimitry Andric if (__c != -1) 3601*0b57cec5SDimitry Andric __c <<= 1; 3602*0b57cec5SDimitry Andric nl_catd __cat = (nl_catd)__c; 3603*0b57cec5SDimitry Andric catclose(__cat); 3604*0b57cec5SDimitry Andric#else // !_LIBCPP_HAS_CATOPEN 3605*0b57cec5SDimitry Andric _LIBCPP_UNUSED_VAR(__c); 3606*0b57cec5SDimitry Andric#endif // _LIBCPP_HAS_CATOPEN 3607*0b57cec5SDimitry Andric} 3608*0b57cec5SDimitry Andric 3609*0b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS messages<char>) 3610*0b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS messages<wchar_t>) 3611*0b57cec5SDimitry Andric 3612*0b57cec5SDimitry Andrictemplate <class _CharT> 3613*0b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS messages_byname 3614*0b57cec5SDimitry Andric : public messages<_CharT> 3615*0b57cec5SDimitry Andric{ 3616*0b57cec5SDimitry Andricpublic: 3617*0b57cec5SDimitry Andric typedef messages_base::catalog catalog; 3618*0b57cec5SDimitry Andric typedef basic_string<_CharT> string_type; 3619*0b57cec5SDimitry Andric 3620*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 3621*0b57cec5SDimitry Andric explicit messages_byname(const char*, size_t __refs = 0) 3622*0b57cec5SDimitry Andric : messages<_CharT>(__refs) {} 3623*0b57cec5SDimitry Andric 3624*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 3625*0b57cec5SDimitry Andric explicit messages_byname(const string&, size_t __refs = 0) 3626*0b57cec5SDimitry Andric : messages<_CharT>(__refs) {} 3627*0b57cec5SDimitry Andric 3628*0b57cec5SDimitry Andricprotected: 3629*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 3630*0b57cec5SDimitry Andric ~messages_byname() {} 3631*0b57cec5SDimitry Andric}; 3632*0b57cec5SDimitry Andric 3633*0b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS messages_byname<char>) 3634*0b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS messages_byname<wchar_t>) 3635*0b57cec5SDimitry Andric 3636*0b57cec5SDimitry Andrictemplate<class _Codecvt, class _Elem = wchar_t, 3637*0b57cec5SDimitry Andric class _Wide_alloc = allocator<_Elem>, 3638*0b57cec5SDimitry Andric class _Byte_alloc = allocator<char> > 3639*0b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS wstring_convert 3640*0b57cec5SDimitry Andric{ 3641*0b57cec5SDimitry Andricpublic: 3642*0b57cec5SDimitry Andric typedef basic_string<char, char_traits<char>, _Byte_alloc> byte_string; 3643*0b57cec5SDimitry Andric typedef basic_string<_Elem, char_traits<_Elem>, _Wide_alloc> wide_string; 3644*0b57cec5SDimitry Andric typedef typename _Codecvt::state_type state_type; 3645*0b57cec5SDimitry Andric typedef typename wide_string::traits_type::int_type int_type; 3646*0b57cec5SDimitry Andric 3647*0b57cec5SDimitry Andricprivate: 3648*0b57cec5SDimitry Andric byte_string __byte_err_string_; 3649*0b57cec5SDimitry Andric wide_string __wide_err_string_; 3650*0b57cec5SDimitry Andric _Codecvt* __cvtptr_; 3651*0b57cec5SDimitry Andric state_type __cvtstate_; 3652*0b57cec5SDimitry Andric size_t __cvtcount_; 3653*0b57cec5SDimitry Andric 3654*0b57cec5SDimitry Andric wstring_convert(const wstring_convert& __wc); 3655*0b57cec5SDimitry Andric wstring_convert& operator=(const wstring_convert& __wc); 3656*0b57cec5SDimitry Andricpublic: 3657*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 3658*0b57cec5SDimitry Andric _LIBCPP_EXPLICIT_AFTER_CXX11 wstring_convert(_Codecvt* __pcvt = new _Codecvt); 3659*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 3660*0b57cec5SDimitry Andric wstring_convert(_Codecvt* __pcvt, state_type __state); 3661*0b57cec5SDimitry Andric _LIBCPP_EXPLICIT_AFTER_CXX11 wstring_convert(const byte_string& __byte_err, 3662*0b57cec5SDimitry Andric const wide_string& __wide_err = wide_string()); 3663*0b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG 3664*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 3665*0b57cec5SDimitry Andric wstring_convert(wstring_convert&& __wc); 3666*0b57cec5SDimitry Andric#endif 3667*0b57cec5SDimitry Andric ~wstring_convert(); 3668*0b57cec5SDimitry Andric 3669*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 3670*0b57cec5SDimitry Andric wide_string from_bytes(char __byte) 3671*0b57cec5SDimitry Andric {return from_bytes(&__byte, &__byte+1);} 3672*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 3673*0b57cec5SDimitry Andric wide_string from_bytes(const char* __ptr) 3674*0b57cec5SDimitry Andric {return from_bytes(__ptr, __ptr + char_traits<char>::length(__ptr));} 3675*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 3676*0b57cec5SDimitry Andric wide_string from_bytes(const byte_string& __str) 3677*0b57cec5SDimitry Andric {return from_bytes(__str.data(), __str.data() + __str.size());} 3678*0b57cec5SDimitry Andric wide_string from_bytes(const char* __first, const char* __last); 3679*0b57cec5SDimitry Andric 3680*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 3681*0b57cec5SDimitry Andric byte_string to_bytes(_Elem __wchar) 3682*0b57cec5SDimitry Andric {return to_bytes(&__wchar, &__wchar+1);} 3683*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 3684*0b57cec5SDimitry Andric byte_string to_bytes(const _Elem* __wptr) 3685*0b57cec5SDimitry Andric {return to_bytes(__wptr, __wptr + char_traits<_Elem>::length(__wptr));} 3686*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 3687*0b57cec5SDimitry Andric byte_string to_bytes(const wide_string& __wstr) 3688*0b57cec5SDimitry Andric {return to_bytes(__wstr.data(), __wstr.data() + __wstr.size());} 3689*0b57cec5SDimitry Andric byte_string to_bytes(const _Elem* __first, const _Elem* __last); 3690*0b57cec5SDimitry Andric 3691*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 3692*0b57cec5SDimitry Andric size_t converted() const _NOEXCEPT {return __cvtcount_;} 3693*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 3694*0b57cec5SDimitry Andric state_type state() const {return __cvtstate_;} 3695*0b57cec5SDimitry Andric}; 3696*0b57cec5SDimitry Andric 3697*0b57cec5SDimitry Andrictemplate<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc> 3698*0b57cec5SDimitry Andricinline 3699*0b57cec5SDimitry Andricwstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>:: 3700*0b57cec5SDimitry Andric wstring_convert(_Codecvt* __pcvt) 3701*0b57cec5SDimitry Andric : __cvtptr_(__pcvt), __cvtstate_(), __cvtcount_(0) 3702*0b57cec5SDimitry Andric{ 3703*0b57cec5SDimitry Andric} 3704*0b57cec5SDimitry Andric 3705*0b57cec5SDimitry Andrictemplate<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc> 3706*0b57cec5SDimitry Andricinline 3707*0b57cec5SDimitry Andricwstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>:: 3708*0b57cec5SDimitry Andric wstring_convert(_Codecvt* __pcvt, state_type __state) 3709*0b57cec5SDimitry Andric : __cvtptr_(__pcvt), __cvtstate_(__state), __cvtcount_(0) 3710*0b57cec5SDimitry Andric{ 3711*0b57cec5SDimitry Andric} 3712*0b57cec5SDimitry Andric 3713*0b57cec5SDimitry Andrictemplate<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc> 3714*0b57cec5SDimitry Andricwstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>:: 3715*0b57cec5SDimitry Andric wstring_convert(const byte_string& __byte_err, const wide_string& __wide_err) 3716*0b57cec5SDimitry Andric : __byte_err_string_(__byte_err), __wide_err_string_(__wide_err), 3717*0b57cec5SDimitry Andric __cvtstate_(), __cvtcount_(0) 3718*0b57cec5SDimitry Andric{ 3719*0b57cec5SDimitry Andric __cvtptr_ = new _Codecvt; 3720*0b57cec5SDimitry Andric} 3721*0b57cec5SDimitry Andric 3722*0b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG 3723*0b57cec5SDimitry Andric 3724*0b57cec5SDimitry Andrictemplate<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc> 3725*0b57cec5SDimitry Andricinline 3726*0b57cec5SDimitry Andricwstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>:: 3727*0b57cec5SDimitry Andric wstring_convert(wstring_convert&& __wc) 3728*0b57cec5SDimitry Andric : __byte_err_string_(_VSTD::move(__wc.__byte_err_string_)), 3729*0b57cec5SDimitry Andric __wide_err_string_(_VSTD::move(__wc.__wide_err_string_)), 3730*0b57cec5SDimitry Andric __cvtptr_(__wc.__cvtptr_), 3731*0b57cec5SDimitry Andric __cvtstate_(__wc.__cvtstate_), __cvtcount_(__wc.__cvtcount_) 3732*0b57cec5SDimitry Andric{ 3733*0b57cec5SDimitry Andric __wc.__cvtptr_ = nullptr; 3734*0b57cec5SDimitry Andric} 3735*0b57cec5SDimitry Andric 3736*0b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG 3737*0b57cec5SDimitry Andric 3738*0b57cec5SDimitry Andrictemplate<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc> 3739*0b57cec5SDimitry Andricwstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::~wstring_convert() 3740*0b57cec5SDimitry Andric{ 3741*0b57cec5SDimitry Andric delete __cvtptr_; 3742*0b57cec5SDimitry Andric} 3743*0b57cec5SDimitry Andric 3744*0b57cec5SDimitry Andrictemplate<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc> 3745*0b57cec5SDimitry Andrictypename wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::wide_string 3746*0b57cec5SDimitry Andricwstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>:: 3747*0b57cec5SDimitry Andric from_bytes(const char* __frm, const char* __frm_end) 3748*0b57cec5SDimitry Andric{ 3749*0b57cec5SDimitry Andric __cvtcount_ = 0; 3750*0b57cec5SDimitry Andric if (__cvtptr_ != nullptr) 3751*0b57cec5SDimitry Andric { 3752*0b57cec5SDimitry Andric wide_string __ws(2*(__frm_end - __frm), _Elem()); 3753*0b57cec5SDimitry Andric if (__frm != __frm_end) 3754*0b57cec5SDimitry Andric __ws.resize(__ws.capacity()); 3755*0b57cec5SDimitry Andric codecvt_base::result __r = codecvt_base::ok; 3756*0b57cec5SDimitry Andric state_type __st = __cvtstate_; 3757*0b57cec5SDimitry Andric if (__frm != __frm_end) 3758*0b57cec5SDimitry Andric { 3759*0b57cec5SDimitry Andric _Elem* __to = &__ws[0]; 3760*0b57cec5SDimitry Andric _Elem* __to_end = __to + __ws.size(); 3761*0b57cec5SDimitry Andric const char* __frm_nxt; 3762*0b57cec5SDimitry Andric do 3763*0b57cec5SDimitry Andric { 3764*0b57cec5SDimitry Andric _Elem* __to_nxt; 3765*0b57cec5SDimitry Andric __r = __cvtptr_->in(__st, __frm, __frm_end, __frm_nxt, 3766*0b57cec5SDimitry Andric __to, __to_end, __to_nxt); 3767*0b57cec5SDimitry Andric __cvtcount_ += __frm_nxt - __frm; 3768*0b57cec5SDimitry Andric if (__frm_nxt == __frm) 3769*0b57cec5SDimitry Andric { 3770*0b57cec5SDimitry Andric __r = codecvt_base::error; 3771*0b57cec5SDimitry Andric } 3772*0b57cec5SDimitry Andric else if (__r == codecvt_base::noconv) 3773*0b57cec5SDimitry Andric { 3774*0b57cec5SDimitry Andric __ws.resize(__to - &__ws[0]); 3775*0b57cec5SDimitry Andric // This only gets executed if _Elem is char 3776*0b57cec5SDimitry Andric __ws.append((const _Elem*)__frm, (const _Elem*)__frm_end); 3777*0b57cec5SDimitry Andric __frm = __frm_nxt; 3778*0b57cec5SDimitry Andric __r = codecvt_base::ok; 3779*0b57cec5SDimitry Andric } 3780*0b57cec5SDimitry Andric else if (__r == codecvt_base::ok) 3781*0b57cec5SDimitry Andric { 3782*0b57cec5SDimitry Andric __ws.resize(__to_nxt - &__ws[0]); 3783*0b57cec5SDimitry Andric __frm = __frm_nxt; 3784*0b57cec5SDimitry Andric } 3785*0b57cec5SDimitry Andric else if (__r == codecvt_base::partial) 3786*0b57cec5SDimitry Andric { 3787*0b57cec5SDimitry Andric ptrdiff_t __s = __to_nxt - &__ws[0]; 3788*0b57cec5SDimitry Andric __ws.resize(2 * __s); 3789*0b57cec5SDimitry Andric __to = &__ws[0] + __s; 3790*0b57cec5SDimitry Andric __to_end = &__ws[0] + __ws.size(); 3791*0b57cec5SDimitry Andric __frm = __frm_nxt; 3792*0b57cec5SDimitry Andric } 3793*0b57cec5SDimitry Andric } while (__r == codecvt_base::partial && __frm_nxt < __frm_end); 3794*0b57cec5SDimitry Andric } 3795*0b57cec5SDimitry Andric if (__r == codecvt_base::ok) 3796*0b57cec5SDimitry Andric return __ws; 3797*0b57cec5SDimitry Andric } 3798*0b57cec5SDimitry Andric 3799*0b57cec5SDimitry Andric if (__wide_err_string_.empty()) 3800*0b57cec5SDimitry Andric __throw_range_error("wstring_convert: from_bytes error"); 3801*0b57cec5SDimitry Andric 3802*0b57cec5SDimitry Andric return __wide_err_string_; 3803*0b57cec5SDimitry Andric} 3804*0b57cec5SDimitry Andric 3805*0b57cec5SDimitry Andrictemplate<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc> 3806*0b57cec5SDimitry Andrictypename wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::byte_string 3807*0b57cec5SDimitry Andricwstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>:: 3808*0b57cec5SDimitry Andric to_bytes(const _Elem* __frm, const _Elem* __frm_end) 3809*0b57cec5SDimitry Andric{ 3810*0b57cec5SDimitry Andric __cvtcount_ = 0; 3811*0b57cec5SDimitry Andric if (__cvtptr_ != nullptr) 3812*0b57cec5SDimitry Andric { 3813*0b57cec5SDimitry Andric byte_string __bs(2*(__frm_end - __frm), char()); 3814*0b57cec5SDimitry Andric if (__frm != __frm_end) 3815*0b57cec5SDimitry Andric __bs.resize(__bs.capacity()); 3816*0b57cec5SDimitry Andric codecvt_base::result __r = codecvt_base::ok; 3817*0b57cec5SDimitry Andric state_type __st = __cvtstate_; 3818*0b57cec5SDimitry Andric if (__frm != __frm_end) 3819*0b57cec5SDimitry Andric { 3820*0b57cec5SDimitry Andric char* __to = &__bs[0]; 3821*0b57cec5SDimitry Andric char* __to_end = __to + __bs.size(); 3822*0b57cec5SDimitry Andric const _Elem* __frm_nxt; 3823*0b57cec5SDimitry Andric do 3824*0b57cec5SDimitry Andric { 3825*0b57cec5SDimitry Andric char* __to_nxt; 3826*0b57cec5SDimitry Andric __r = __cvtptr_->out(__st, __frm, __frm_end, __frm_nxt, 3827*0b57cec5SDimitry Andric __to, __to_end, __to_nxt); 3828*0b57cec5SDimitry Andric __cvtcount_ += __frm_nxt - __frm; 3829*0b57cec5SDimitry Andric if (__frm_nxt == __frm) 3830*0b57cec5SDimitry Andric { 3831*0b57cec5SDimitry Andric __r = codecvt_base::error; 3832*0b57cec5SDimitry Andric } 3833*0b57cec5SDimitry Andric else if (__r == codecvt_base::noconv) 3834*0b57cec5SDimitry Andric { 3835*0b57cec5SDimitry Andric __bs.resize(__to - &__bs[0]); 3836*0b57cec5SDimitry Andric // This only gets executed if _Elem is char 3837*0b57cec5SDimitry Andric __bs.append((const char*)__frm, (const char*)__frm_end); 3838*0b57cec5SDimitry Andric __frm = __frm_nxt; 3839*0b57cec5SDimitry Andric __r = codecvt_base::ok; 3840*0b57cec5SDimitry Andric } 3841*0b57cec5SDimitry Andric else if (__r == codecvt_base::ok) 3842*0b57cec5SDimitry Andric { 3843*0b57cec5SDimitry Andric __bs.resize(__to_nxt - &__bs[0]); 3844*0b57cec5SDimitry Andric __frm = __frm_nxt; 3845*0b57cec5SDimitry Andric } 3846*0b57cec5SDimitry Andric else if (__r == codecvt_base::partial) 3847*0b57cec5SDimitry Andric { 3848*0b57cec5SDimitry Andric ptrdiff_t __s = __to_nxt - &__bs[0]; 3849*0b57cec5SDimitry Andric __bs.resize(2 * __s); 3850*0b57cec5SDimitry Andric __to = &__bs[0] + __s; 3851*0b57cec5SDimitry Andric __to_end = &__bs[0] + __bs.size(); 3852*0b57cec5SDimitry Andric __frm = __frm_nxt; 3853*0b57cec5SDimitry Andric } 3854*0b57cec5SDimitry Andric } while (__r == codecvt_base::partial && __frm_nxt < __frm_end); 3855*0b57cec5SDimitry Andric } 3856*0b57cec5SDimitry Andric if (__r == codecvt_base::ok) 3857*0b57cec5SDimitry Andric { 3858*0b57cec5SDimitry Andric size_t __s = __bs.size(); 3859*0b57cec5SDimitry Andric __bs.resize(__bs.capacity()); 3860*0b57cec5SDimitry Andric char* __to = &__bs[0] + __s; 3861*0b57cec5SDimitry Andric char* __to_end = __to + __bs.size(); 3862*0b57cec5SDimitry Andric do 3863*0b57cec5SDimitry Andric { 3864*0b57cec5SDimitry Andric char* __to_nxt; 3865*0b57cec5SDimitry Andric __r = __cvtptr_->unshift(__st, __to, __to_end, __to_nxt); 3866*0b57cec5SDimitry Andric if (__r == codecvt_base::noconv) 3867*0b57cec5SDimitry Andric { 3868*0b57cec5SDimitry Andric __bs.resize(__to - &__bs[0]); 3869*0b57cec5SDimitry Andric __r = codecvt_base::ok; 3870*0b57cec5SDimitry Andric } 3871*0b57cec5SDimitry Andric else if (__r == codecvt_base::ok) 3872*0b57cec5SDimitry Andric { 3873*0b57cec5SDimitry Andric __bs.resize(__to_nxt - &__bs[0]); 3874*0b57cec5SDimitry Andric } 3875*0b57cec5SDimitry Andric else if (__r == codecvt_base::partial) 3876*0b57cec5SDimitry Andric { 3877*0b57cec5SDimitry Andric ptrdiff_t __sp = __to_nxt - &__bs[0]; 3878*0b57cec5SDimitry Andric __bs.resize(2 * __sp); 3879*0b57cec5SDimitry Andric __to = &__bs[0] + __sp; 3880*0b57cec5SDimitry Andric __to_end = &__bs[0] + __bs.size(); 3881*0b57cec5SDimitry Andric } 3882*0b57cec5SDimitry Andric } while (__r == codecvt_base::partial); 3883*0b57cec5SDimitry Andric if (__r == codecvt_base::ok) 3884*0b57cec5SDimitry Andric return __bs; 3885*0b57cec5SDimitry Andric } 3886*0b57cec5SDimitry Andric } 3887*0b57cec5SDimitry Andric 3888*0b57cec5SDimitry Andric if (__byte_err_string_.empty()) 3889*0b57cec5SDimitry Andric __throw_range_error("wstring_convert: to_bytes error"); 3890*0b57cec5SDimitry Andric 3891*0b57cec5SDimitry Andric return __byte_err_string_; 3892*0b57cec5SDimitry Andric} 3893*0b57cec5SDimitry Andric 3894*0b57cec5SDimitry Andrictemplate <class _Codecvt, class _Elem = wchar_t, class _Tr = char_traits<_Elem> > 3895*0b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS wbuffer_convert 3896*0b57cec5SDimitry Andric : public basic_streambuf<_Elem, _Tr> 3897*0b57cec5SDimitry Andric{ 3898*0b57cec5SDimitry Andricpublic: 3899*0b57cec5SDimitry Andric // types: 3900*0b57cec5SDimitry Andric typedef _Elem char_type; 3901*0b57cec5SDimitry Andric typedef _Tr traits_type; 3902*0b57cec5SDimitry Andric typedef typename traits_type::int_type int_type; 3903*0b57cec5SDimitry Andric typedef typename traits_type::pos_type pos_type; 3904*0b57cec5SDimitry Andric typedef typename traits_type::off_type off_type; 3905*0b57cec5SDimitry Andric typedef typename _Codecvt::state_type state_type; 3906*0b57cec5SDimitry Andric 3907*0b57cec5SDimitry Andricprivate: 3908*0b57cec5SDimitry Andric char* __extbuf_; 3909*0b57cec5SDimitry Andric const char* __extbufnext_; 3910*0b57cec5SDimitry Andric const char* __extbufend_; 3911*0b57cec5SDimitry Andric char __extbuf_min_[8]; 3912*0b57cec5SDimitry Andric size_t __ebs_; 3913*0b57cec5SDimitry Andric char_type* __intbuf_; 3914*0b57cec5SDimitry Andric size_t __ibs_; 3915*0b57cec5SDimitry Andric streambuf* __bufptr_; 3916*0b57cec5SDimitry Andric _Codecvt* __cv_; 3917*0b57cec5SDimitry Andric state_type __st_; 3918*0b57cec5SDimitry Andric ios_base::openmode __cm_; 3919*0b57cec5SDimitry Andric bool __owns_eb_; 3920*0b57cec5SDimitry Andric bool __owns_ib_; 3921*0b57cec5SDimitry Andric bool __always_noconv_; 3922*0b57cec5SDimitry Andric 3923*0b57cec5SDimitry Andric wbuffer_convert(const wbuffer_convert&); 3924*0b57cec5SDimitry Andric wbuffer_convert& operator=(const wbuffer_convert&); 3925*0b57cec5SDimitry Andricpublic: 3926*0b57cec5SDimitry Andric _LIBCPP_EXPLICIT_AFTER_CXX11 wbuffer_convert(streambuf* __bytebuf = 0, 3927*0b57cec5SDimitry Andric _Codecvt* __pcvt = new _Codecvt, state_type __state = state_type()); 3928*0b57cec5SDimitry Andric ~wbuffer_convert(); 3929*0b57cec5SDimitry Andric 3930*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 3931*0b57cec5SDimitry Andric streambuf* rdbuf() const {return __bufptr_;} 3932*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 3933*0b57cec5SDimitry Andric streambuf* rdbuf(streambuf* __bytebuf) 3934*0b57cec5SDimitry Andric { 3935*0b57cec5SDimitry Andric streambuf* __r = __bufptr_; 3936*0b57cec5SDimitry Andric __bufptr_ = __bytebuf; 3937*0b57cec5SDimitry Andric return __r; 3938*0b57cec5SDimitry Andric } 3939*0b57cec5SDimitry Andric 3940*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 3941*0b57cec5SDimitry Andric state_type state() const {return __st_;} 3942*0b57cec5SDimitry Andric 3943*0b57cec5SDimitry Andricprotected: 3944*0b57cec5SDimitry Andric virtual int_type underflow(); 3945*0b57cec5SDimitry Andric virtual int_type pbackfail(int_type __c = traits_type::eof()); 3946*0b57cec5SDimitry Andric virtual int_type overflow (int_type __c = traits_type::eof()); 3947*0b57cec5SDimitry Andric virtual basic_streambuf<char_type, traits_type>* setbuf(char_type* __s, 3948*0b57cec5SDimitry Andric streamsize __n); 3949*0b57cec5SDimitry Andric virtual pos_type seekoff(off_type __off, ios_base::seekdir __way, 3950*0b57cec5SDimitry Andric ios_base::openmode __wch = ios_base::in | ios_base::out); 3951*0b57cec5SDimitry Andric virtual pos_type seekpos(pos_type __sp, 3952*0b57cec5SDimitry Andric ios_base::openmode __wch = ios_base::in | ios_base::out); 3953*0b57cec5SDimitry Andric virtual int sync(); 3954*0b57cec5SDimitry Andric 3955*0b57cec5SDimitry Andricprivate: 3956*0b57cec5SDimitry Andric bool __read_mode(); 3957*0b57cec5SDimitry Andric void __write_mode(); 3958*0b57cec5SDimitry Andric wbuffer_convert* __close(); 3959*0b57cec5SDimitry Andric}; 3960*0b57cec5SDimitry Andric 3961*0b57cec5SDimitry Andrictemplate <class _Codecvt, class _Elem, class _Tr> 3962*0b57cec5SDimitry Andricwbuffer_convert<_Codecvt, _Elem, _Tr>:: 3963*0b57cec5SDimitry Andric wbuffer_convert(streambuf* __bytebuf, _Codecvt* __pcvt, state_type __state) 3964*0b57cec5SDimitry Andric : __extbuf_(0), 3965*0b57cec5SDimitry Andric __extbufnext_(0), 3966*0b57cec5SDimitry Andric __extbufend_(0), 3967*0b57cec5SDimitry Andric __ebs_(0), 3968*0b57cec5SDimitry Andric __intbuf_(0), 3969*0b57cec5SDimitry Andric __ibs_(0), 3970*0b57cec5SDimitry Andric __bufptr_(__bytebuf), 3971*0b57cec5SDimitry Andric __cv_(__pcvt), 3972*0b57cec5SDimitry Andric __st_(__state), 3973*0b57cec5SDimitry Andric __cm_(0), 3974*0b57cec5SDimitry Andric __owns_eb_(false), 3975*0b57cec5SDimitry Andric __owns_ib_(false), 3976*0b57cec5SDimitry Andric __always_noconv_(__cv_ ? __cv_->always_noconv() : false) 3977*0b57cec5SDimitry Andric{ 3978*0b57cec5SDimitry Andric setbuf(0, 4096); 3979*0b57cec5SDimitry Andric} 3980*0b57cec5SDimitry Andric 3981*0b57cec5SDimitry Andrictemplate <class _Codecvt, class _Elem, class _Tr> 3982*0b57cec5SDimitry Andricwbuffer_convert<_Codecvt, _Elem, _Tr>::~wbuffer_convert() 3983*0b57cec5SDimitry Andric{ 3984*0b57cec5SDimitry Andric __close(); 3985*0b57cec5SDimitry Andric delete __cv_; 3986*0b57cec5SDimitry Andric if (__owns_eb_) 3987*0b57cec5SDimitry Andric delete [] __extbuf_; 3988*0b57cec5SDimitry Andric if (__owns_ib_) 3989*0b57cec5SDimitry Andric delete [] __intbuf_; 3990*0b57cec5SDimitry Andric} 3991*0b57cec5SDimitry Andric 3992*0b57cec5SDimitry Andrictemplate <class _Codecvt, class _Elem, class _Tr> 3993*0b57cec5SDimitry Andrictypename wbuffer_convert<_Codecvt, _Elem, _Tr>::int_type 3994*0b57cec5SDimitry Andricwbuffer_convert<_Codecvt, _Elem, _Tr>::underflow() 3995*0b57cec5SDimitry Andric{ 3996*0b57cec5SDimitry Andric if (__cv_ == 0 || __bufptr_ == 0) 3997*0b57cec5SDimitry Andric return traits_type::eof(); 3998*0b57cec5SDimitry Andric bool __initial = __read_mode(); 3999*0b57cec5SDimitry Andric char_type __1buf; 4000*0b57cec5SDimitry Andric if (this->gptr() == 0) 4001*0b57cec5SDimitry Andric this->setg(&__1buf, &__1buf+1, &__1buf+1); 4002*0b57cec5SDimitry Andric const size_t __unget_sz = __initial ? 0 : min<size_t>((this->egptr() - this->eback()) / 2, 4); 4003*0b57cec5SDimitry Andric int_type __c = traits_type::eof(); 4004*0b57cec5SDimitry Andric if (this->gptr() == this->egptr()) 4005*0b57cec5SDimitry Andric { 4006*0b57cec5SDimitry Andric memmove(this->eback(), this->egptr() - __unget_sz, __unget_sz * sizeof(char_type)); 4007*0b57cec5SDimitry Andric if (__always_noconv_) 4008*0b57cec5SDimitry Andric { 4009*0b57cec5SDimitry Andric streamsize __nmemb = static_cast<streamsize>(this->egptr() - this->eback() - __unget_sz); 4010*0b57cec5SDimitry Andric __nmemb = __bufptr_->sgetn((char*)this->eback() + __unget_sz, __nmemb); 4011*0b57cec5SDimitry Andric if (__nmemb != 0) 4012*0b57cec5SDimitry Andric { 4013*0b57cec5SDimitry Andric this->setg(this->eback(), 4014*0b57cec5SDimitry Andric this->eback() + __unget_sz, 4015*0b57cec5SDimitry Andric this->eback() + __unget_sz + __nmemb); 4016*0b57cec5SDimitry Andric __c = *this->gptr(); 4017*0b57cec5SDimitry Andric } 4018*0b57cec5SDimitry Andric } 4019*0b57cec5SDimitry Andric else 4020*0b57cec5SDimitry Andric { 4021*0b57cec5SDimitry Andric _LIBCPP_ASSERT(!(__extbufnext_ == NULL && (__extbufend_ != __extbufnext_)), "underflow moving from NULL" ); 4022*0b57cec5SDimitry Andric if (__extbufend_ != __extbufnext_) 4023*0b57cec5SDimitry Andric memmove(__extbuf_, __extbufnext_, __extbufend_ - __extbufnext_); 4024*0b57cec5SDimitry Andric __extbufnext_ = __extbuf_ + (__extbufend_ - __extbufnext_); 4025*0b57cec5SDimitry Andric __extbufend_ = __extbuf_ + (__extbuf_ == __extbuf_min_ ? sizeof(__extbuf_min_) : __ebs_); 4026*0b57cec5SDimitry Andric streamsize __nmemb = _VSTD::min(static_cast<streamsize>(this->egptr() - this->eback() - __unget_sz), 4027*0b57cec5SDimitry Andric static_cast<streamsize>(__extbufend_ - __extbufnext_)); 4028*0b57cec5SDimitry Andric codecvt_base::result __r; 4029*0b57cec5SDimitry Andric // FIXME: Do we ever need to restore the state here? 4030*0b57cec5SDimitry Andric //state_type __svs = __st_; 4031*0b57cec5SDimitry Andric streamsize __nr = __bufptr_->sgetn(const_cast<char*>(__extbufnext_), __nmemb); 4032*0b57cec5SDimitry Andric if (__nr != 0) 4033*0b57cec5SDimitry Andric { 4034*0b57cec5SDimitry Andric __extbufend_ = __extbufnext_ + __nr; 4035*0b57cec5SDimitry Andric char_type* __inext; 4036*0b57cec5SDimitry Andric __r = __cv_->in(__st_, __extbuf_, __extbufend_, __extbufnext_, 4037*0b57cec5SDimitry Andric this->eback() + __unget_sz, 4038*0b57cec5SDimitry Andric this->egptr(), __inext); 4039*0b57cec5SDimitry Andric if (__r == codecvt_base::noconv) 4040*0b57cec5SDimitry Andric { 4041*0b57cec5SDimitry Andric this->setg((char_type*)__extbuf_, (char_type*)__extbuf_, 4042*0b57cec5SDimitry Andric (char_type*) const_cast<char *>(__extbufend_)); 4043*0b57cec5SDimitry Andric __c = *this->gptr(); 4044*0b57cec5SDimitry Andric } 4045*0b57cec5SDimitry Andric else if (__inext != this->eback() + __unget_sz) 4046*0b57cec5SDimitry Andric { 4047*0b57cec5SDimitry Andric this->setg(this->eback(), this->eback() + __unget_sz, __inext); 4048*0b57cec5SDimitry Andric __c = *this->gptr(); 4049*0b57cec5SDimitry Andric } 4050*0b57cec5SDimitry Andric } 4051*0b57cec5SDimitry Andric } 4052*0b57cec5SDimitry Andric } 4053*0b57cec5SDimitry Andric else 4054*0b57cec5SDimitry Andric __c = *this->gptr(); 4055*0b57cec5SDimitry Andric if (this->eback() == &__1buf) 4056*0b57cec5SDimitry Andric this->setg(0, 0, 0); 4057*0b57cec5SDimitry Andric return __c; 4058*0b57cec5SDimitry Andric} 4059*0b57cec5SDimitry Andric 4060*0b57cec5SDimitry Andrictemplate <class _Codecvt, class _Elem, class _Tr> 4061*0b57cec5SDimitry Andrictypename wbuffer_convert<_Codecvt, _Elem, _Tr>::int_type 4062*0b57cec5SDimitry Andricwbuffer_convert<_Codecvt, _Elem, _Tr>::pbackfail(int_type __c) 4063*0b57cec5SDimitry Andric{ 4064*0b57cec5SDimitry Andric if (__cv_ != 0 && __bufptr_ != 0 && this->eback() < this->gptr()) 4065*0b57cec5SDimitry Andric { 4066*0b57cec5SDimitry Andric if (traits_type::eq_int_type(__c, traits_type::eof())) 4067*0b57cec5SDimitry Andric { 4068*0b57cec5SDimitry Andric this->gbump(-1); 4069*0b57cec5SDimitry Andric return traits_type::not_eof(__c); 4070*0b57cec5SDimitry Andric } 4071*0b57cec5SDimitry Andric if (traits_type::eq(traits_type::to_char_type(__c), this->gptr()[-1])) 4072*0b57cec5SDimitry Andric { 4073*0b57cec5SDimitry Andric this->gbump(-1); 4074*0b57cec5SDimitry Andric *this->gptr() = traits_type::to_char_type(__c); 4075*0b57cec5SDimitry Andric return __c; 4076*0b57cec5SDimitry Andric } 4077*0b57cec5SDimitry Andric } 4078*0b57cec5SDimitry Andric return traits_type::eof(); 4079*0b57cec5SDimitry Andric} 4080*0b57cec5SDimitry Andric 4081*0b57cec5SDimitry Andrictemplate <class _Codecvt, class _Elem, class _Tr> 4082*0b57cec5SDimitry Andrictypename wbuffer_convert<_Codecvt, _Elem, _Tr>::int_type 4083*0b57cec5SDimitry Andricwbuffer_convert<_Codecvt, _Elem, _Tr>::overflow(int_type __c) 4084*0b57cec5SDimitry Andric{ 4085*0b57cec5SDimitry Andric if (__cv_ == 0 || __bufptr_ == 0) 4086*0b57cec5SDimitry Andric return traits_type::eof(); 4087*0b57cec5SDimitry Andric __write_mode(); 4088*0b57cec5SDimitry Andric char_type __1buf; 4089*0b57cec5SDimitry Andric char_type* __pb_save = this->pbase(); 4090*0b57cec5SDimitry Andric char_type* __epb_save = this->epptr(); 4091*0b57cec5SDimitry Andric if (!traits_type::eq_int_type(__c, traits_type::eof())) 4092*0b57cec5SDimitry Andric { 4093*0b57cec5SDimitry Andric if (this->pptr() == 0) 4094*0b57cec5SDimitry Andric this->setp(&__1buf, &__1buf+1); 4095*0b57cec5SDimitry Andric *this->pptr() = traits_type::to_char_type(__c); 4096*0b57cec5SDimitry Andric this->pbump(1); 4097*0b57cec5SDimitry Andric } 4098*0b57cec5SDimitry Andric if (this->pptr() != this->pbase()) 4099*0b57cec5SDimitry Andric { 4100*0b57cec5SDimitry Andric if (__always_noconv_) 4101*0b57cec5SDimitry Andric { 4102*0b57cec5SDimitry Andric streamsize __nmemb = static_cast<streamsize>(this->pptr() - this->pbase()); 4103*0b57cec5SDimitry Andric if (__bufptr_->sputn((const char*)this->pbase(), __nmemb) != __nmemb) 4104*0b57cec5SDimitry Andric return traits_type::eof(); 4105*0b57cec5SDimitry Andric } 4106*0b57cec5SDimitry Andric else 4107*0b57cec5SDimitry Andric { 4108*0b57cec5SDimitry Andric char* __extbe = __extbuf_; 4109*0b57cec5SDimitry Andric codecvt_base::result __r; 4110*0b57cec5SDimitry Andric do 4111*0b57cec5SDimitry Andric { 4112*0b57cec5SDimitry Andric const char_type* __e; 4113*0b57cec5SDimitry Andric __r = __cv_->out(__st_, this->pbase(), this->pptr(), __e, 4114*0b57cec5SDimitry Andric __extbuf_, __extbuf_ + __ebs_, __extbe); 4115*0b57cec5SDimitry Andric if (__e == this->pbase()) 4116*0b57cec5SDimitry Andric return traits_type::eof(); 4117*0b57cec5SDimitry Andric if (__r == codecvt_base::noconv) 4118*0b57cec5SDimitry Andric { 4119*0b57cec5SDimitry Andric streamsize __nmemb = static_cast<size_t>(this->pptr() - this->pbase()); 4120*0b57cec5SDimitry Andric if (__bufptr_->sputn((const char*)this->pbase(), __nmemb) != __nmemb) 4121*0b57cec5SDimitry Andric return traits_type::eof(); 4122*0b57cec5SDimitry Andric } 4123*0b57cec5SDimitry Andric else if (__r == codecvt_base::ok || __r == codecvt_base::partial) 4124*0b57cec5SDimitry Andric { 4125*0b57cec5SDimitry Andric streamsize __nmemb = static_cast<size_t>(__extbe - __extbuf_); 4126*0b57cec5SDimitry Andric if (__bufptr_->sputn(__extbuf_, __nmemb) != __nmemb) 4127*0b57cec5SDimitry Andric return traits_type::eof(); 4128*0b57cec5SDimitry Andric if (__r == codecvt_base::partial) 4129*0b57cec5SDimitry Andric { 4130*0b57cec5SDimitry Andric this->setp(const_cast<char_type *>(__e), this->pptr()); 4131*0b57cec5SDimitry Andric this->__pbump(this->epptr() - this->pbase()); 4132*0b57cec5SDimitry Andric } 4133*0b57cec5SDimitry Andric } 4134*0b57cec5SDimitry Andric else 4135*0b57cec5SDimitry Andric return traits_type::eof(); 4136*0b57cec5SDimitry Andric } while (__r == codecvt_base::partial); 4137*0b57cec5SDimitry Andric } 4138*0b57cec5SDimitry Andric this->setp(__pb_save, __epb_save); 4139*0b57cec5SDimitry Andric } 4140*0b57cec5SDimitry Andric return traits_type::not_eof(__c); 4141*0b57cec5SDimitry Andric} 4142*0b57cec5SDimitry Andric 4143*0b57cec5SDimitry Andrictemplate <class _Codecvt, class _Elem, class _Tr> 4144*0b57cec5SDimitry Andricbasic_streambuf<_Elem, _Tr>* 4145*0b57cec5SDimitry Andricwbuffer_convert<_Codecvt, _Elem, _Tr>::setbuf(char_type* __s, streamsize __n) 4146*0b57cec5SDimitry Andric{ 4147*0b57cec5SDimitry Andric this->setg(0, 0, 0); 4148*0b57cec5SDimitry Andric this->setp(0, 0); 4149*0b57cec5SDimitry Andric if (__owns_eb_) 4150*0b57cec5SDimitry Andric delete [] __extbuf_; 4151*0b57cec5SDimitry Andric if (__owns_ib_) 4152*0b57cec5SDimitry Andric delete [] __intbuf_; 4153*0b57cec5SDimitry Andric __ebs_ = __n; 4154*0b57cec5SDimitry Andric if (__ebs_ > sizeof(__extbuf_min_)) 4155*0b57cec5SDimitry Andric { 4156*0b57cec5SDimitry Andric if (__always_noconv_ && __s) 4157*0b57cec5SDimitry Andric { 4158*0b57cec5SDimitry Andric __extbuf_ = (char*)__s; 4159*0b57cec5SDimitry Andric __owns_eb_ = false; 4160*0b57cec5SDimitry Andric } 4161*0b57cec5SDimitry Andric else 4162*0b57cec5SDimitry Andric { 4163*0b57cec5SDimitry Andric __extbuf_ = new char[__ebs_]; 4164*0b57cec5SDimitry Andric __owns_eb_ = true; 4165*0b57cec5SDimitry Andric } 4166*0b57cec5SDimitry Andric } 4167*0b57cec5SDimitry Andric else 4168*0b57cec5SDimitry Andric { 4169*0b57cec5SDimitry Andric __extbuf_ = __extbuf_min_; 4170*0b57cec5SDimitry Andric __ebs_ = sizeof(__extbuf_min_); 4171*0b57cec5SDimitry Andric __owns_eb_ = false; 4172*0b57cec5SDimitry Andric } 4173*0b57cec5SDimitry Andric if (!__always_noconv_) 4174*0b57cec5SDimitry Andric { 4175*0b57cec5SDimitry Andric __ibs_ = max<streamsize>(__n, sizeof(__extbuf_min_)); 4176*0b57cec5SDimitry Andric if (__s && __ibs_ >= sizeof(__extbuf_min_)) 4177*0b57cec5SDimitry Andric { 4178*0b57cec5SDimitry Andric __intbuf_ = __s; 4179*0b57cec5SDimitry Andric __owns_ib_ = false; 4180*0b57cec5SDimitry Andric } 4181*0b57cec5SDimitry Andric else 4182*0b57cec5SDimitry Andric { 4183*0b57cec5SDimitry Andric __intbuf_ = new char_type[__ibs_]; 4184*0b57cec5SDimitry Andric __owns_ib_ = true; 4185*0b57cec5SDimitry Andric } 4186*0b57cec5SDimitry Andric } 4187*0b57cec5SDimitry Andric else 4188*0b57cec5SDimitry Andric { 4189*0b57cec5SDimitry Andric __ibs_ = 0; 4190*0b57cec5SDimitry Andric __intbuf_ = 0; 4191*0b57cec5SDimitry Andric __owns_ib_ = false; 4192*0b57cec5SDimitry Andric } 4193*0b57cec5SDimitry Andric return this; 4194*0b57cec5SDimitry Andric} 4195*0b57cec5SDimitry Andric 4196*0b57cec5SDimitry Andrictemplate <class _Codecvt, class _Elem, class _Tr> 4197*0b57cec5SDimitry Andrictypename wbuffer_convert<_Codecvt, _Elem, _Tr>::pos_type 4198*0b57cec5SDimitry Andricwbuffer_convert<_Codecvt, _Elem, _Tr>::seekoff(off_type __off, ios_base::seekdir __way, 4199*0b57cec5SDimitry Andric ios_base::openmode __om) 4200*0b57cec5SDimitry Andric{ 4201*0b57cec5SDimitry Andric int __width = __cv_->encoding(); 4202*0b57cec5SDimitry Andric if (__cv_ == 0 || __bufptr_ == 0 || (__width <= 0 && __off != 0) || sync()) 4203*0b57cec5SDimitry Andric return pos_type(off_type(-1)); 4204*0b57cec5SDimitry Andric // __width > 0 || __off == 0, now check __way 4205*0b57cec5SDimitry Andric if (__way != ios_base::beg && __way != ios_base::cur && __way != ios_base::end) 4206*0b57cec5SDimitry Andric return pos_type(off_type(-1)); 4207*0b57cec5SDimitry Andric pos_type __r = __bufptr_->pubseekoff(__width * __off, __way, __om); 4208*0b57cec5SDimitry Andric __r.state(__st_); 4209*0b57cec5SDimitry Andric return __r; 4210*0b57cec5SDimitry Andric} 4211*0b57cec5SDimitry Andric 4212*0b57cec5SDimitry Andrictemplate <class _Codecvt, class _Elem, class _Tr> 4213*0b57cec5SDimitry Andrictypename wbuffer_convert<_Codecvt, _Elem, _Tr>::pos_type 4214*0b57cec5SDimitry Andricwbuffer_convert<_Codecvt, _Elem, _Tr>::seekpos(pos_type __sp, ios_base::openmode __wch) 4215*0b57cec5SDimitry Andric{ 4216*0b57cec5SDimitry Andric if (__cv_ == 0 || __bufptr_ == 0 || sync()) 4217*0b57cec5SDimitry Andric return pos_type(off_type(-1)); 4218*0b57cec5SDimitry Andric if (__bufptr_->pubseekpos(__sp, __wch) == pos_type(off_type(-1))) 4219*0b57cec5SDimitry Andric return pos_type(off_type(-1)); 4220*0b57cec5SDimitry Andric return __sp; 4221*0b57cec5SDimitry Andric} 4222*0b57cec5SDimitry Andric 4223*0b57cec5SDimitry Andrictemplate <class _Codecvt, class _Elem, class _Tr> 4224*0b57cec5SDimitry Andricint 4225*0b57cec5SDimitry Andricwbuffer_convert<_Codecvt, _Elem, _Tr>::sync() 4226*0b57cec5SDimitry Andric{ 4227*0b57cec5SDimitry Andric if (__cv_ == 0 || __bufptr_ == 0) 4228*0b57cec5SDimitry Andric return 0; 4229*0b57cec5SDimitry Andric if (__cm_ & ios_base::out) 4230*0b57cec5SDimitry Andric { 4231*0b57cec5SDimitry Andric if (this->pptr() != this->pbase()) 4232*0b57cec5SDimitry Andric if (overflow() == traits_type::eof()) 4233*0b57cec5SDimitry Andric return -1; 4234*0b57cec5SDimitry Andric codecvt_base::result __r; 4235*0b57cec5SDimitry Andric do 4236*0b57cec5SDimitry Andric { 4237*0b57cec5SDimitry Andric char* __extbe; 4238*0b57cec5SDimitry Andric __r = __cv_->unshift(__st_, __extbuf_, __extbuf_ + __ebs_, __extbe); 4239*0b57cec5SDimitry Andric streamsize __nmemb = static_cast<streamsize>(__extbe - __extbuf_); 4240*0b57cec5SDimitry Andric if (__bufptr_->sputn(__extbuf_, __nmemb) != __nmemb) 4241*0b57cec5SDimitry Andric return -1; 4242*0b57cec5SDimitry Andric } while (__r == codecvt_base::partial); 4243*0b57cec5SDimitry Andric if (__r == codecvt_base::error) 4244*0b57cec5SDimitry Andric return -1; 4245*0b57cec5SDimitry Andric if (__bufptr_->pubsync()) 4246*0b57cec5SDimitry Andric return -1; 4247*0b57cec5SDimitry Andric } 4248*0b57cec5SDimitry Andric else if (__cm_ & ios_base::in) 4249*0b57cec5SDimitry Andric { 4250*0b57cec5SDimitry Andric off_type __c; 4251*0b57cec5SDimitry Andric if (__always_noconv_) 4252*0b57cec5SDimitry Andric __c = this->egptr() - this->gptr(); 4253*0b57cec5SDimitry Andric else 4254*0b57cec5SDimitry Andric { 4255*0b57cec5SDimitry Andric int __width = __cv_->encoding(); 4256*0b57cec5SDimitry Andric __c = __extbufend_ - __extbufnext_; 4257*0b57cec5SDimitry Andric if (__width > 0) 4258*0b57cec5SDimitry Andric __c += __width * (this->egptr() - this->gptr()); 4259*0b57cec5SDimitry Andric else 4260*0b57cec5SDimitry Andric { 4261*0b57cec5SDimitry Andric if (this->gptr() != this->egptr()) 4262*0b57cec5SDimitry Andric { 4263*0b57cec5SDimitry Andric reverse(this->gptr(), this->egptr()); 4264*0b57cec5SDimitry Andric codecvt_base::result __r; 4265*0b57cec5SDimitry Andric const char_type* __e = this->gptr(); 4266*0b57cec5SDimitry Andric char* __extbe; 4267*0b57cec5SDimitry Andric do 4268*0b57cec5SDimitry Andric { 4269*0b57cec5SDimitry Andric __r = __cv_->out(__st_, __e, this->egptr(), __e, 4270*0b57cec5SDimitry Andric __extbuf_, __extbuf_ + __ebs_, __extbe); 4271*0b57cec5SDimitry Andric switch (__r) 4272*0b57cec5SDimitry Andric { 4273*0b57cec5SDimitry Andric case codecvt_base::noconv: 4274*0b57cec5SDimitry Andric __c += this->egptr() - this->gptr(); 4275*0b57cec5SDimitry Andric break; 4276*0b57cec5SDimitry Andric case codecvt_base::ok: 4277*0b57cec5SDimitry Andric case codecvt_base::partial: 4278*0b57cec5SDimitry Andric __c += __extbe - __extbuf_; 4279*0b57cec5SDimitry Andric break; 4280*0b57cec5SDimitry Andric default: 4281*0b57cec5SDimitry Andric return -1; 4282*0b57cec5SDimitry Andric } 4283*0b57cec5SDimitry Andric } while (__r == codecvt_base::partial); 4284*0b57cec5SDimitry Andric } 4285*0b57cec5SDimitry Andric } 4286*0b57cec5SDimitry Andric } 4287*0b57cec5SDimitry Andric if (__bufptr_->pubseekoff(-__c, ios_base::cur, __cm_) == pos_type(off_type(-1))) 4288*0b57cec5SDimitry Andric return -1; 4289*0b57cec5SDimitry Andric this->setg(0, 0, 0); 4290*0b57cec5SDimitry Andric __cm_ = 0; 4291*0b57cec5SDimitry Andric } 4292*0b57cec5SDimitry Andric return 0; 4293*0b57cec5SDimitry Andric} 4294*0b57cec5SDimitry Andric 4295*0b57cec5SDimitry Andrictemplate <class _Codecvt, class _Elem, class _Tr> 4296*0b57cec5SDimitry Andricbool 4297*0b57cec5SDimitry Andricwbuffer_convert<_Codecvt, _Elem, _Tr>::__read_mode() 4298*0b57cec5SDimitry Andric{ 4299*0b57cec5SDimitry Andric if (!(__cm_ & ios_base::in)) 4300*0b57cec5SDimitry Andric { 4301*0b57cec5SDimitry Andric this->setp(0, 0); 4302*0b57cec5SDimitry Andric if (__always_noconv_) 4303*0b57cec5SDimitry Andric this->setg((char_type*)__extbuf_, 4304*0b57cec5SDimitry Andric (char_type*)__extbuf_ + __ebs_, 4305*0b57cec5SDimitry Andric (char_type*)__extbuf_ + __ebs_); 4306*0b57cec5SDimitry Andric else 4307*0b57cec5SDimitry Andric this->setg(__intbuf_, __intbuf_ + __ibs_, __intbuf_ + __ibs_); 4308*0b57cec5SDimitry Andric __cm_ = ios_base::in; 4309*0b57cec5SDimitry Andric return true; 4310*0b57cec5SDimitry Andric } 4311*0b57cec5SDimitry Andric return false; 4312*0b57cec5SDimitry Andric} 4313*0b57cec5SDimitry Andric 4314*0b57cec5SDimitry Andrictemplate <class _Codecvt, class _Elem, class _Tr> 4315*0b57cec5SDimitry Andricvoid 4316*0b57cec5SDimitry Andricwbuffer_convert<_Codecvt, _Elem, _Tr>::__write_mode() 4317*0b57cec5SDimitry Andric{ 4318*0b57cec5SDimitry Andric if (!(__cm_ & ios_base::out)) 4319*0b57cec5SDimitry Andric { 4320*0b57cec5SDimitry Andric this->setg(0, 0, 0); 4321*0b57cec5SDimitry Andric if (__ebs_ > sizeof(__extbuf_min_)) 4322*0b57cec5SDimitry Andric { 4323*0b57cec5SDimitry Andric if (__always_noconv_) 4324*0b57cec5SDimitry Andric this->setp((char_type*)__extbuf_, 4325*0b57cec5SDimitry Andric (char_type*)__extbuf_ + (__ebs_ - 1)); 4326*0b57cec5SDimitry Andric else 4327*0b57cec5SDimitry Andric this->setp(__intbuf_, __intbuf_ + (__ibs_ - 1)); 4328*0b57cec5SDimitry Andric } 4329*0b57cec5SDimitry Andric else 4330*0b57cec5SDimitry Andric this->setp(0, 0); 4331*0b57cec5SDimitry Andric __cm_ = ios_base::out; 4332*0b57cec5SDimitry Andric } 4333*0b57cec5SDimitry Andric} 4334*0b57cec5SDimitry Andric 4335*0b57cec5SDimitry Andrictemplate <class _Codecvt, class _Elem, class _Tr> 4336*0b57cec5SDimitry Andricwbuffer_convert<_Codecvt, _Elem, _Tr>* 4337*0b57cec5SDimitry Andricwbuffer_convert<_Codecvt, _Elem, _Tr>::__close() 4338*0b57cec5SDimitry Andric{ 4339*0b57cec5SDimitry Andric wbuffer_convert* __rt = 0; 4340*0b57cec5SDimitry Andric if (__cv_ != 0 && __bufptr_ != 0) 4341*0b57cec5SDimitry Andric { 4342*0b57cec5SDimitry Andric __rt = this; 4343*0b57cec5SDimitry Andric if ((__cm_ & ios_base::out) && sync()) 4344*0b57cec5SDimitry Andric __rt = 0; 4345*0b57cec5SDimitry Andric } 4346*0b57cec5SDimitry Andric return __rt; 4347*0b57cec5SDimitry Andric} 4348*0b57cec5SDimitry Andric 4349*0b57cec5SDimitry Andric_LIBCPP_END_NAMESPACE_STD 4350*0b57cec5SDimitry Andric 4351*0b57cec5SDimitry Andric_LIBCPP_POP_MACROS 4352*0b57cec5SDimitry Andric 4353*0b57cec5SDimitry Andric#endif // _LIBCPP_LOCALE 4354