17a984708SDavid Chisnall// -*- C++ -*- 27a984708SDavid Chisnall//===-------------------------- locale ------------------------------------===// 37a984708SDavid Chisnall// 47a984708SDavid Chisnall// The LLVM Compiler Infrastructure 57a984708SDavid Chisnall// 67a984708SDavid Chisnall// This file is dual licensed under the MIT and the University of Illinois Open 77a984708SDavid Chisnall// Source Licenses. See LICENSE.TXT for details. 87a984708SDavid Chisnall// 97a984708SDavid Chisnall//===----------------------------------------------------------------------===// 107a984708SDavid Chisnall 117a984708SDavid Chisnall#ifndef _LIBCPP_LOCALE 127a984708SDavid Chisnall#define _LIBCPP_LOCALE 137a984708SDavid Chisnall 147a984708SDavid Chisnall/* 157a984708SDavid Chisnall locale synopsis 167a984708SDavid Chisnall 177a984708SDavid Chisnallnamespace std 187a984708SDavid Chisnall{ 197a984708SDavid Chisnall 207a984708SDavid Chisnallclass locale 217a984708SDavid Chisnall{ 227a984708SDavid Chisnallpublic: 237a984708SDavid Chisnall // types: 247a984708SDavid Chisnall class facet; 257a984708SDavid Chisnall class id; 267a984708SDavid Chisnall 277a984708SDavid Chisnall typedef int category; 287a984708SDavid Chisnall static const category // values assigned here are for exposition only 297a984708SDavid Chisnall none = 0x000, 307a984708SDavid Chisnall collate = 0x010, 317a984708SDavid Chisnall ctype = 0x020, 327a984708SDavid Chisnall monetary = 0x040, 337a984708SDavid Chisnall numeric = 0x080, 347a984708SDavid Chisnall time = 0x100, 357a984708SDavid Chisnall messages = 0x200, 367a984708SDavid Chisnall all = collate | ctype | monetary | numeric | time | messages; 377a984708SDavid Chisnall 387a984708SDavid Chisnall // construct/copy/destroy: 397a984708SDavid Chisnall locale() noexcept; 407a984708SDavid Chisnall locale(const locale& other) noexcept; 417a984708SDavid Chisnall explicit locale(const char* std_name); 427a984708SDavid Chisnall explicit locale(const string& std_name); 437a984708SDavid Chisnall locale(const locale& other, const char* std_name, category); 447a984708SDavid Chisnall locale(const locale& other, const string& std_name, category); 457a984708SDavid Chisnall template <class Facet> locale(const locale& other, Facet* f); 467a984708SDavid Chisnall locale(const locale& other, const locale& one, category); 477a984708SDavid Chisnall 487a984708SDavid Chisnall ~locale(); // not virtual 497a984708SDavid Chisnall 507a984708SDavid Chisnall const locale& operator=(const locale& other) noexcept; 517a984708SDavid Chisnall 527a984708SDavid Chisnall template <class Facet> locale combine(const locale& other) const; 537a984708SDavid Chisnall 547a984708SDavid Chisnall // locale operations: 557a984708SDavid Chisnall basic_string<char> name() const; 567a984708SDavid Chisnall bool operator==(const locale& other) const; 577a984708SDavid Chisnall bool operator!=(const locale& other) const; 587a984708SDavid Chisnall template <class charT, class Traits, class Allocator> 597a984708SDavid Chisnall bool operator()(const basic_string<charT,Traits,Allocator>& s1, 607a984708SDavid Chisnall const basic_string<charT,Traits,Allocator>& s2) const; 617a984708SDavid Chisnall 627a984708SDavid Chisnall // global locale objects: 637a984708SDavid Chisnall static locale global(const locale&); 647a984708SDavid Chisnall static const locale& classic(); 657a984708SDavid Chisnall}; 667a984708SDavid Chisnall 677a984708SDavid Chisnalltemplate <class Facet> const Facet& use_facet(const locale&); 687a984708SDavid Chisnalltemplate <class Facet> bool has_facet(const locale&) noexcept; 697a984708SDavid Chisnall 707a984708SDavid Chisnall// 22.3.3, convenience interfaces: 717a984708SDavid Chisnalltemplate <class charT> bool isspace (charT c, const locale& loc); 727a984708SDavid Chisnalltemplate <class charT> bool isprint (charT c, const locale& loc); 737a984708SDavid Chisnalltemplate <class charT> bool iscntrl (charT c, const locale& loc); 747a984708SDavid Chisnalltemplate <class charT> bool isupper (charT c, const locale& loc); 757a984708SDavid Chisnalltemplate <class charT> bool islower (charT c, const locale& loc); 767a984708SDavid Chisnalltemplate <class charT> bool isalpha (charT c, const locale& loc); 777a984708SDavid Chisnalltemplate <class charT> bool isdigit (charT c, const locale& loc); 787a984708SDavid Chisnalltemplate <class charT> bool ispunct (charT c, const locale& loc); 797a984708SDavid Chisnalltemplate <class charT> bool isxdigit(charT c, const locale& loc); 807a984708SDavid Chisnalltemplate <class charT> bool isalnum (charT c, const locale& loc); 817a984708SDavid Chisnalltemplate <class charT> bool isgraph (charT c, const locale& loc); 827a984708SDavid Chisnalltemplate <class charT> charT toupper(charT c, const locale& loc); 837a984708SDavid Chisnalltemplate <class charT> charT tolower(charT c, const locale& loc); 847a984708SDavid Chisnall 857a984708SDavid Chisnalltemplate<class Codecvt, class Elem = wchar_t, 867a984708SDavid Chisnall class Wide_alloc = allocator<Elem>, 877a984708SDavid Chisnall class Byte_alloc = allocator<char>> 887a984708SDavid Chisnallclass wstring_convert 897a984708SDavid Chisnall{ 907a984708SDavid Chisnallpublic: 917a984708SDavid Chisnall typedef basic_string<char, char_traits<char>, Byte_alloc> byte_string; 927a984708SDavid Chisnall typedef basic_string<Elem, char_traits<Elem>, Wide_alloc> wide_string; 937a984708SDavid Chisnall typedef typename Codecvt::state_type state_type; 947a984708SDavid Chisnall typedef typename wide_string::traits_type::int_type int_type; 957a984708SDavid Chisnall 964f7ab58eSDimitry Andric explicit wstring_convert(Codecvt* pcvt = new Codecvt); // explicit in C++14 977a984708SDavid Chisnall wstring_convert(Codecvt* pcvt, state_type state); 984f7ab58eSDimitry Andric explicit wstring_convert(const byte_string& byte_err, // explicit in C++14 997a984708SDavid Chisnall const wide_string& wide_err = wide_string()); 1004f7ab58eSDimitry Andric wstring_convert(const wstring_convert&) = delete; // C++14 1014f7ab58eSDimitry Andric wstring_convert & operator=(const wstring_convert &) = delete; // C++14 1027a984708SDavid Chisnall ~wstring_convert(); 1037a984708SDavid Chisnall 1047a984708SDavid Chisnall wide_string from_bytes(char byte); 1057a984708SDavid Chisnall wide_string from_bytes(const char* ptr); 1067a984708SDavid Chisnall wide_string from_bytes(const byte_string& str); 1077a984708SDavid Chisnall wide_string from_bytes(const char* first, const char* last); 1087a984708SDavid Chisnall 1097a984708SDavid Chisnall byte_string to_bytes(Elem wchar); 1107a984708SDavid Chisnall byte_string to_bytes(const Elem* wptr); 1117a984708SDavid Chisnall byte_string to_bytes(const wide_string& wstr); 1127a984708SDavid Chisnall byte_string to_bytes(const Elem* first, const Elem* last); 1137a984708SDavid Chisnall 1144f7ab58eSDimitry Andric size_t converted() const; // noexcept in C++14 1157a984708SDavid Chisnall state_type state() const; 1167a984708SDavid Chisnall}; 1177a984708SDavid Chisnall 1187a984708SDavid Chisnalltemplate <class Codecvt, class Elem = wchar_t, class Tr = char_traits<Elem>> 1197a984708SDavid Chisnallclass wbuffer_convert 1207a984708SDavid Chisnall : public basic_streambuf<Elem, Tr> 1217a984708SDavid Chisnall{ 1227a984708SDavid Chisnallpublic: 1237a984708SDavid Chisnall typedef typename Tr::state_type state_type; 1247a984708SDavid Chisnall 1254f7ab58eSDimitry Andric explicit wbuffer_convert(streambuf* bytebuf = 0, Codecvt* pcvt = new Codecvt, 1264f7ab58eSDimitry Andric state_type state = state_type()); // explicit in C++14 1274f7ab58eSDimitry Andric wbuffer_convert(const wbuffer_convert&) = delete; // C++14 1284f7ab58eSDimitry Andric wbuffer_convert & operator=(const wbuffer_convert &) = delete; // C++14 1294f7ab58eSDimitry Andric ~wbuffer_convert(); // C++14 1307a984708SDavid Chisnall 1317a984708SDavid Chisnall streambuf* rdbuf() const; 1327a984708SDavid Chisnall streambuf* rdbuf(streambuf* bytebuf); 1337a984708SDavid Chisnall 1347a984708SDavid Chisnall state_type state() const; 1357a984708SDavid Chisnall}; 1367a984708SDavid Chisnall 1377a984708SDavid Chisnall// 22.4.1 and 22.4.1.3, ctype: 1387a984708SDavid Chisnallclass ctype_base; 1397a984708SDavid Chisnalltemplate <class charT> class ctype; 1407a984708SDavid Chisnalltemplate <> class ctype<char>; // specialization 1417a984708SDavid Chisnalltemplate <class charT> class ctype_byname; 1427a984708SDavid Chisnalltemplate <> class ctype_byname<char>; // specialization 1437a984708SDavid Chisnall 1447a984708SDavid Chisnallclass codecvt_base; 1457a984708SDavid Chisnalltemplate <class internT, class externT, class stateT> class codecvt; 1467a984708SDavid Chisnalltemplate <class internT, class externT, class stateT> class codecvt_byname; 1477a984708SDavid Chisnall 1487a984708SDavid Chisnall// 22.4.2 and 22.4.3, numeric: 1497a984708SDavid Chisnalltemplate <class charT, class InputIterator> class num_get; 1507a984708SDavid Chisnalltemplate <class charT, class OutputIterator> class num_put; 1517a984708SDavid Chisnalltemplate <class charT> class numpunct; 1527a984708SDavid Chisnalltemplate <class charT> class numpunct_byname; 1537a984708SDavid Chisnall 1547a984708SDavid Chisnall// 22.4.4, col lation: 1557a984708SDavid Chisnalltemplate <class charT> class collate; 1567a984708SDavid Chisnalltemplate <class charT> class collate_byname; 1577a984708SDavid Chisnall 1587a984708SDavid Chisnall// 22.4.5, date and time: 1597a984708SDavid Chisnallclass time_base; 1607a984708SDavid Chisnalltemplate <class charT, class InputIterator> class time_get; 1617a984708SDavid Chisnalltemplate <class charT, class InputIterator> class time_get_byname; 1627a984708SDavid Chisnalltemplate <class charT, class OutputIterator> class time_put; 1637a984708SDavid Chisnalltemplate <class charT, class OutputIterator> class time_put_byname; 1647a984708SDavid Chisnall 1657a984708SDavid Chisnall// 22.4.6, money: 1667a984708SDavid Chisnallclass money_base; 1677a984708SDavid Chisnalltemplate <class charT, class InputIterator> class money_get; 1687a984708SDavid Chisnalltemplate <class charT, class OutputIterator> class money_put; 1697a984708SDavid Chisnalltemplate <class charT, bool Intl> class moneypunct; 1707a984708SDavid Chisnalltemplate <class charT, bool Intl> class moneypunct_byname; 1717a984708SDavid Chisnall 1727a984708SDavid Chisnall// 22.4.7, message retrieval: 1737a984708SDavid Chisnallclass messages_base; 1747a984708SDavid Chisnalltemplate <class charT> class messages; 1757a984708SDavid Chisnalltemplate <class charT> class messages_byname; 1767a984708SDavid Chisnall 1777a984708SDavid Chisnall} // std 1787a984708SDavid Chisnall 1797a984708SDavid Chisnall*/ 1807a984708SDavid Chisnall 1817a984708SDavid Chisnall#include <__config> 1827a984708SDavid Chisnall#include <__locale> 1837c82a1ecSDimitry Andric#include <__debug> 1847a984708SDavid Chisnall#include <algorithm> 1857a984708SDavid Chisnall#include <memory> 1867a984708SDavid Chisnall#include <ios> 1877a984708SDavid Chisnall#include <streambuf> 1887a984708SDavid Chisnall#include <iterator> 1897a984708SDavid Chisnall#include <limits> 190*b5893f02SDimitry Andric#include <version> 1911bf9f7c1SDimitry Andric#ifndef __APPLE__ 1927a984708SDavid Chisnall#include <cstdarg> 1937a984708SDavid Chisnall#endif 1947a984708SDavid Chisnall#include <cstdlib> 1957a984708SDavid Chisnall#include <ctime> 196f9448bf3SDimitry Andric#include <cstdio> 197854fa44bSDimitry Andric#ifdef _LIBCPP_HAS_CATOPEN 1987a984708SDavid Chisnall#include <nl_types.h> 199d72607e9SDimitry Andric#endif 2007a984708SDavid Chisnall 2011bf9f7c1SDimitry Andric#ifdef __APPLE__ 202fb6c5de6SDavid Chisnall#include <Availability.h> 203fb6c5de6SDavid Chisnall#endif 204fb6c5de6SDavid Chisnall 2057c82a1ecSDimitry Andric#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 2067c82a1ecSDimitry Andric#include <__bsd_locale_defaults.h> 2077c82a1ecSDimitry Andric#else 2087c82a1ecSDimitry Andric#include <__bsd_locale_fallbacks.h> 2097c82a1ecSDimitry Andric#endif 2107c82a1ecSDimitry Andric 211f9448bf3SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 212f9448bf3SDimitry Andric#pragma GCC system_header 213f9448bf3SDimitry Andric#endif 214f9448bf3SDimitry Andric 215f9448bf3SDimitry Andric_LIBCPP_PUSH_MACROS 216f9448bf3SDimitry Andric#include <__undef_macros> 217f9448bf3SDimitry Andric 218f9448bf3SDimitry Andric 2197a984708SDavid Chisnall_LIBCPP_BEGIN_NAMESPACE_STD 2207a984708SDavid Chisnall 2211bf9f7c1SDimitry Andric#if defined(__APPLE__) || defined(__FreeBSD__) 2227a984708SDavid Chisnall# define _LIBCPP_GET_C_LOCALE 0 223854fa44bSDimitry Andric#elif defined(__CloudABI__) || defined(__NetBSD__) 2244bab9fd9SDavid Chisnall# define _LIBCPP_GET_C_LOCALE LC_C_LOCALE 2257a984708SDavid Chisnall#else 2267a984708SDavid Chisnall# define _LIBCPP_GET_C_LOCALE __cloc() 2277a984708SDavid Chisnall // Get the C locale object 2284f7ab58eSDimitry Andric _LIBCPP_FUNC_VIS locale_t __cloc(); 2297a984708SDavid Chisnall#define __cloc_defined 2307a984708SDavid Chisnall#endif 2317a984708SDavid Chisnall 2327a984708SDavid Chisnall// __scan_keyword 2337a984708SDavid Chisnall// Scans [__b, __e) until a match is found in the basic_strings range 2347a984708SDavid Chisnall// [__kb, __ke) or until it can be shown that there is no match in [__kb, __ke). 2357a984708SDavid Chisnall// __b will be incremented (visibly), consuming CharT until a match is found 2367a984708SDavid Chisnall// or proved to not exist. A keyword may be "", in which will match anything. 2377a984708SDavid Chisnall// If one keyword is a prefix of another, and the next CharT in the input 2387a984708SDavid Chisnall// might match another keyword, the algorithm will attempt to find the longest 2397a984708SDavid Chisnall// matching keyword. If the longer matching keyword ends up not matching, then 2407a984708SDavid Chisnall// no keyword match is found. If no keyword match is found, __ke is returned 2417a984708SDavid Chisnall// and failbit is set in __err. 2427a984708SDavid Chisnall// Else an iterator pointing to the matching keyword is found. If more than 2437a984708SDavid Chisnall// one keyword matches, an iterator to the first matching keyword is returned. 244d72607e9SDimitry Andric// If on exit __b == __e, eofbit is set in __err. If __case_sensitive is false, 2457a984708SDavid Chisnall// __ct is used to force to lower case before comparing characters. 2467a984708SDavid Chisnall// Examples: 2477a984708SDavid Chisnall// Keywords: "a", "abb" 2487a984708SDavid Chisnall// If the input is "a", the first keyword matches and eofbit is set. 2497a984708SDavid Chisnall// If the input is "abc", no match is found and "ab" are consumed. 2507a984708SDavid Chisnalltemplate <class _InputIterator, class _ForwardIterator, class _Ctype> 2517a984708SDavid Chisnall_LIBCPP_HIDDEN 2527a984708SDavid Chisnall_ForwardIterator 2537a984708SDavid Chisnall__scan_keyword(_InputIterator& __b, _InputIterator __e, 2547a984708SDavid Chisnall _ForwardIterator __kb, _ForwardIterator __ke, 2557a984708SDavid Chisnall const _Ctype& __ct, ios_base::iostate& __err, 2567a984708SDavid Chisnall bool __case_sensitive = true) 2577a984708SDavid Chisnall{ 2587a984708SDavid Chisnall typedef typename iterator_traits<_InputIterator>::value_type _CharT; 25994e3ee44SDavid Chisnall size_t __nkw = static_cast<size_t>(_VSTD::distance(__kb, __ke)); 2607a984708SDavid Chisnall const unsigned char __doesnt_match = '\0'; 2617a984708SDavid Chisnall const unsigned char __might_match = '\1'; 2627a984708SDavid Chisnall const unsigned char __does_match = '\2'; 2637a984708SDavid Chisnall unsigned char __statbuf[100]; 2647a984708SDavid Chisnall unsigned char* __status = __statbuf; 2657a984708SDavid Chisnall unique_ptr<unsigned char, void(*)(void*)> __stat_hold(0, free); 2667a984708SDavid Chisnall if (__nkw > sizeof(__statbuf)) 2677a984708SDavid Chisnall { 2687a984708SDavid Chisnall __status = (unsigned char*)malloc(__nkw); 2697a984708SDavid Chisnall if (__status == 0) 2707a984708SDavid Chisnall __throw_bad_alloc(); 2717a984708SDavid Chisnall __stat_hold.reset(__status); 2727a984708SDavid Chisnall } 2737a984708SDavid Chisnall size_t __n_might_match = __nkw; // At this point, any keyword might match 2747a984708SDavid Chisnall size_t __n_does_match = 0; // but none of them definitely do 2757a984708SDavid Chisnall // Initialize all statuses to __might_match, except for "" keywords are __does_match 2767a984708SDavid Chisnall unsigned char* __st = __status; 277d72607e9SDimitry Andric for (_ForwardIterator __ky = __kb; __ky != __ke; ++__ky, (void) ++__st) 2787a984708SDavid Chisnall { 2797a984708SDavid Chisnall if (!__ky->empty()) 2807a984708SDavid Chisnall *__st = __might_match; 2817a984708SDavid Chisnall else 2827a984708SDavid Chisnall { 2837a984708SDavid Chisnall *__st = __does_match; 2847a984708SDavid Chisnall --__n_might_match; 2857a984708SDavid Chisnall ++__n_does_match; 2867a984708SDavid Chisnall } 2877a984708SDavid Chisnall } 2887a984708SDavid Chisnall // While there might be a match, test keywords against the next CharT 2897a984708SDavid Chisnall for (size_t __indx = 0; __b != __e && __n_might_match > 0; ++__indx) 2907a984708SDavid Chisnall { 2917a984708SDavid Chisnall // Peek at the next CharT but don't consume it 2927a984708SDavid Chisnall _CharT __c = *__b; 2937a984708SDavid Chisnall if (!__case_sensitive) 2947a984708SDavid Chisnall __c = __ct.toupper(__c); 2957a984708SDavid Chisnall bool __consume = false; 2967a984708SDavid Chisnall // For each keyword which might match, see if the __indx character is __c 2977a984708SDavid Chisnall // If a match if found, consume __c 2987a984708SDavid Chisnall // If a match is found, and that is the last character in the keyword, 2997a984708SDavid Chisnall // then that keyword matches. 3007a984708SDavid Chisnall // If the keyword doesn't match this character, then change the keyword 3017a984708SDavid Chisnall // to doesn't match 3027a984708SDavid Chisnall __st = __status; 303d72607e9SDimitry Andric for (_ForwardIterator __ky = __kb; __ky != __ke; ++__ky, (void) ++__st) 3047a984708SDavid Chisnall { 3057a984708SDavid Chisnall if (*__st == __might_match) 3067a984708SDavid Chisnall { 3077a984708SDavid Chisnall _CharT __kc = (*__ky)[__indx]; 3087a984708SDavid Chisnall if (!__case_sensitive) 3097a984708SDavid Chisnall __kc = __ct.toupper(__kc); 3107a984708SDavid Chisnall if (__c == __kc) 3117a984708SDavid Chisnall { 3127a984708SDavid Chisnall __consume = true; 3137a984708SDavid Chisnall if (__ky->size() == __indx+1) 3147a984708SDavid Chisnall { 3157a984708SDavid Chisnall *__st = __does_match; 3167a984708SDavid Chisnall --__n_might_match; 3177a984708SDavid Chisnall ++__n_does_match; 3187a984708SDavid Chisnall } 3197a984708SDavid Chisnall } 3207a984708SDavid Chisnall else 3217a984708SDavid Chisnall { 3227a984708SDavid Chisnall *__st = __doesnt_match; 3237a984708SDavid Chisnall --__n_might_match; 3247a984708SDavid Chisnall } 3257a984708SDavid Chisnall } 3267a984708SDavid Chisnall } 3277a984708SDavid Chisnall // consume if we matched a character 3287a984708SDavid Chisnall if (__consume) 3297a984708SDavid Chisnall { 3307a984708SDavid Chisnall ++__b; 3317a984708SDavid Chisnall // If we consumed a character and there might be a matched keyword that 3327a984708SDavid Chisnall // was marked matched on a previous iteration, then such keywords 3337a984708SDavid Chisnall // which are now marked as not matching. 3347a984708SDavid Chisnall if (__n_might_match + __n_does_match > 1) 3357a984708SDavid Chisnall { 3367a984708SDavid Chisnall __st = __status; 337d72607e9SDimitry Andric for (_ForwardIterator __ky = __kb; __ky != __ke; ++__ky, (void) ++__st) 3387a984708SDavid Chisnall { 3397a984708SDavid Chisnall if (*__st == __does_match && __ky->size() != __indx+1) 3407a984708SDavid Chisnall { 3417a984708SDavid Chisnall *__st = __doesnt_match; 3427a984708SDavid Chisnall --__n_does_match; 3437a984708SDavid Chisnall } 3447a984708SDavid Chisnall } 3457a984708SDavid Chisnall } 3467a984708SDavid Chisnall } 3477a984708SDavid Chisnall } 3487a984708SDavid Chisnall // We've exited the loop because we hit eof and/or we have no more "might matches". 3497a984708SDavid Chisnall if (__b == __e) 3507a984708SDavid Chisnall __err |= ios_base::eofbit; 3517a984708SDavid Chisnall // Return the first matching result 352d72607e9SDimitry Andric for (__st = __status; __kb != __ke; ++__kb, (void) ++__st) 3537a984708SDavid Chisnall if (*__st == __does_match) 3547a984708SDavid Chisnall break; 3557a984708SDavid Chisnall if (__kb == __ke) 3567a984708SDavid Chisnall __err |= ios_base::failbit; 3577a984708SDavid Chisnall return __kb; 3587a984708SDavid Chisnall} 3597a984708SDavid Chisnall 3604f7ab58eSDimitry Andricstruct _LIBCPP_TYPE_VIS __num_get_base 3617a984708SDavid Chisnall{ 3627a984708SDavid Chisnall static const int __num_get_buf_sz = 40; 3637a984708SDavid Chisnall 3647a984708SDavid Chisnall static int __get_base(ios_base&); 3657a984708SDavid Chisnall static const char __src[33]; 3667a984708SDavid Chisnall}; 3677a984708SDavid Chisnall 3684f7ab58eSDimitry Andric_LIBCPP_FUNC_VIS 3697a984708SDavid Chisnallvoid __check_grouping(const string& __grouping, unsigned* __g, unsigned* __g_end, 3707a984708SDavid Chisnall ios_base::iostate& __err); 3717a984708SDavid Chisnall 3727a984708SDavid Chisnalltemplate <class _CharT> 3737a984708SDavid Chisnallstruct __num_get 3747a984708SDavid Chisnall : protected __num_get_base 3757a984708SDavid Chisnall{ 3767a984708SDavid Chisnall static string __stage2_float_prep(ios_base& __iob, _CharT* __atoms, _CharT& __decimal_point, 3777a984708SDavid Chisnall _CharT& __thousands_sep); 37824d58133SDimitry Andric 3797a984708SDavid Chisnall static int __stage2_float_loop(_CharT __ct, bool& __in_units, char& __exp, 3807a984708SDavid Chisnall char* __a, char*& __a_end, 3817a984708SDavid Chisnall _CharT __decimal_point, _CharT __thousands_sep, 3827a984708SDavid Chisnall const string& __grouping, unsigned* __g, 3837a984708SDavid Chisnall unsigned*& __g_end, unsigned& __dc, _CharT* __atoms); 38424d58133SDimitry Andric#ifndef _LIBCPP_ABI_OPTIMIZED_LOCALE_NUM_GET 38524d58133SDimitry Andric static string __stage2_int_prep(ios_base& __iob, _CharT* __atoms, _CharT& __thousands_sep); 38624d58133SDimitry Andric static int __stage2_int_loop(_CharT __ct, int __base, char* __a, char*& __a_end, 38724d58133SDimitry Andric unsigned& __dc, _CharT __thousands_sep, const string& __grouping, 38824d58133SDimitry Andric unsigned* __g, unsigned*& __g_end, _CharT* __atoms); 38924d58133SDimitry Andric 39024d58133SDimitry Andric#else 39124d58133SDimitry Andric static string __stage2_int_prep(ios_base& __iob, _CharT& __thousands_sep) 39224d58133SDimitry Andric { 39324d58133SDimitry Andric locale __loc = __iob.getloc(); 39424d58133SDimitry Andric const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc); 39524d58133SDimitry Andric __thousands_sep = __np.thousands_sep(); 39624d58133SDimitry Andric return __np.grouping(); 39724d58133SDimitry Andric } 39824d58133SDimitry Andric 39924d58133SDimitry Andric const _CharT* __do_widen(ios_base& __iob, _CharT* __atoms) const 40024d58133SDimitry Andric { 40124d58133SDimitry Andric return __do_widen_p(__iob, __atoms); 40224d58133SDimitry Andric } 40324d58133SDimitry Andric 40424d58133SDimitry Andric 40524d58133SDimitry Andric static int __stage2_int_loop(_CharT __ct, int __base, char* __a, char*& __a_end, 40624d58133SDimitry Andric unsigned& __dc, _CharT __thousands_sep, const string& __grouping, 40724d58133SDimitry Andric unsigned* __g, unsigned*& __g_end, const _CharT* __atoms); 40824d58133SDimitry Andricprivate: 40924d58133SDimitry Andric template<typename T> 41024d58133SDimitry Andric const T* __do_widen_p(ios_base& __iob, T* __atoms) const 41124d58133SDimitry Andric { 41224d58133SDimitry Andric locale __loc = __iob.getloc(); 41324d58133SDimitry Andric use_facet<ctype<T> >(__loc).widen(__src, __src + 26, __atoms); 41424d58133SDimitry Andric return __atoms; 41524d58133SDimitry Andric } 41624d58133SDimitry Andric 41724d58133SDimitry Andric const char* __do_widen_p(ios_base& __iob, char* __atoms) const 41824d58133SDimitry Andric { 41924d58133SDimitry Andric (void)__iob; 42024d58133SDimitry Andric (void)__atoms; 42124d58133SDimitry Andric return __src; 42224d58133SDimitry Andric } 42324d58133SDimitry Andric#endif 4247a984708SDavid Chisnall}; 4257a984708SDavid Chisnall 42624d58133SDimitry Andric#ifndef _LIBCPP_ABI_OPTIMIZED_LOCALE_NUM_GET 4277a984708SDavid Chisnalltemplate <class _CharT> 4287a984708SDavid Chisnallstring 4297a984708SDavid Chisnall__num_get<_CharT>::__stage2_int_prep(ios_base& __iob, _CharT* __atoms, _CharT& __thousands_sep) 4307a984708SDavid Chisnall{ 4317a984708SDavid Chisnall locale __loc = __iob.getloc(); 4327a984708SDavid Chisnall use_facet<ctype<_CharT> >(__loc).widen(__src, __src + 26, __atoms); 4337a984708SDavid Chisnall const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc); 4347a984708SDavid Chisnall __thousands_sep = __np.thousands_sep(); 4357a984708SDavid Chisnall return __np.grouping(); 4367a984708SDavid Chisnall} 43724d58133SDimitry Andric#endif 4387a984708SDavid Chisnall 4397a984708SDavid Chisnalltemplate <class _CharT> 4407a984708SDavid Chisnallstring 4417a984708SDavid Chisnall__num_get<_CharT>::__stage2_float_prep(ios_base& __iob, _CharT* __atoms, _CharT& __decimal_point, 4427a984708SDavid Chisnall _CharT& __thousands_sep) 4437a984708SDavid Chisnall{ 4447a984708SDavid Chisnall locale __loc = __iob.getloc(); 4457a984708SDavid Chisnall use_facet<ctype<_CharT> >(__loc).widen(__src, __src + 32, __atoms); 4467a984708SDavid Chisnall const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc); 4477a984708SDavid Chisnall __decimal_point = __np.decimal_point(); 4487a984708SDavid Chisnall __thousands_sep = __np.thousands_sep(); 4497a984708SDavid Chisnall return __np.grouping(); 4507a984708SDavid Chisnall} 4517a984708SDavid Chisnall 4527a984708SDavid Chisnalltemplate <class _CharT> 4537a984708SDavid Chisnallint 45424d58133SDimitry Andric#ifndef _LIBCPP_ABI_OPTIMIZED_LOCALE_NUM_GET 4557a984708SDavid Chisnall__num_get<_CharT>::__stage2_int_loop(_CharT __ct, int __base, char* __a, char*& __a_end, 4567a984708SDavid Chisnall unsigned& __dc, _CharT __thousands_sep, const string& __grouping, 4577a984708SDavid Chisnall unsigned* __g, unsigned*& __g_end, _CharT* __atoms) 45824d58133SDimitry Andric#else 45924d58133SDimitry Andric__num_get<_CharT>::__stage2_int_loop(_CharT __ct, int __base, char* __a, char*& __a_end, 46024d58133SDimitry Andric unsigned& __dc, _CharT __thousands_sep, const string& __grouping, 46124d58133SDimitry Andric unsigned* __g, unsigned*& __g_end, const _CharT* __atoms) 46224d58133SDimitry Andric 46324d58133SDimitry Andric#endif 4647a984708SDavid Chisnall{ 4657a984708SDavid Chisnall if (__a_end == __a && (__ct == __atoms[24] || __ct == __atoms[25])) 4667a984708SDavid Chisnall { 4677a984708SDavid Chisnall *__a_end++ = __ct == __atoms[24] ? '+' : '-'; 4687a984708SDavid Chisnall __dc = 0; 4697a984708SDavid Chisnall return 0; 4707a984708SDavid Chisnall } 47194e3ee44SDavid Chisnall if (__grouping.size() != 0 && __ct == __thousands_sep) 4727a984708SDavid Chisnall { 4737a984708SDavid Chisnall if (__g_end-__g < __num_get_buf_sz) 4747a984708SDavid Chisnall { 4757a984708SDavid Chisnall *__g_end++ = __dc; 4767a984708SDavid Chisnall __dc = 0; 4777a984708SDavid Chisnall } 4787a984708SDavid Chisnall return 0; 4797a984708SDavid Chisnall } 4807a984708SDavid Chisnall ptrdiff_t __f = find(__atoms, __atoms + 26, __ct) - __atoms; 4817a984708SDavid Chisnall if (__f >= 24) 4827a984708SDavid Chisnall return -1; 4837a984708SDavid Chisnall switch (__base) 4847a984708SDavid Chisnall { 4857a984708SDavid Chisnall case 8: 4867a984708SDavid Chisnall case 10: 4877a984708SDavid Chisnall if (__f >= __base) 4887a984708SDavid Chisnall return -1; 4897a984708SDavid Chisnall break; 4907a984708SDavid Chisnall case 16: 4917a984708SDavid Chisnall if (__f < 22) 4927a984708SDavid Chisnall break; 4937a984708SDavid Chisnall if (__a_end != __a && __a_end - __a <= 2 && __a_end[-1] == '0') 4947a984708SDavid Chisnall { 4957a984708SDavid Chisnall __dc = 0; 4967a984708SDavid Chisnall *__a_end++ = __src[__f]; 4977a984708SDavid Chisnall return 0; 4987a984708SDavid Chisnall } 4997a984708SDavid Chisnall return -1; 5007a984708SDavid Chisnall } 5017a984708SDavid Chisnall *__a_end++ = __src[__f]; 5027a984708SDavid Chisnall ++__dc; 5037a984708SDavid Chisnall return 0; 5047a984708SDavid Chisnall} 5057a984708SDavid Chisnall 5067a984708SDavid Chisnalltemplate <class _CharT> 5077a984708SDavid Chisnallint 5087a984708SDavid Chisnall__num_get<_CharT>::__stage2_float_loop(_CharT __ct, bool& __in_units, char& __exp, char* __a, char*& __a_end, 5097a984708SDavid Chisnall _CharT __decimal_point, _CharT __thousands_sep, const string& __grouping, 5107a984708SDavid Chisnall unsigned* __g, unsigned*& __g_end, unsigned& __dc, _CharT* __atoms) 5117a984708SDavid Chisnall{ 5127a984708SDavid Chisnall if (__ct == __decimal_point) 5137a984708SDavid Chisnall { 5147a984708SDavid Chisnall if (!__in_units) 5157a984708SDavid Chisnall return -1; 5167a984708SDavid Chisnall __in_units = false; 5177a984708SDavid Chisnall *__a_end++ = '.'; 5187a984708SDavid Chisnall if (__grouping.size() != 0 && __g_end-__g < __num_get_buf_sz) 5197a984708SDavid Chisnall *__g_end++ = __dc; 5207a984708SDavid Chisnall return 0; 5217a984708SDavid Chisnall } 5227a984708SDavid Chisnall if (__ct == __thousands_sep && __grouping.size() != 0) 5237a984708SDavid Chisnall { 5247a984708SDavid Chisnall if (!__in_units) 5257a984708SDavid Chisnall return -1; 5267a984708SDavid Chisnall if (__g_end-__g < __num_get_buf_sz) 5277a984708SDavid Chisnall { 5287a984708SDavid Chisnall *__g_end++ = __dc; 5297a984708SDavid Chisnall __dc = 0; 5307a984708SDavid Chisnall } 5317a984708SDavid Chisnall return 0; 5327a984708SDavid Chisnall } 5337a984708SDavid Chisnall ptrdiff_t __f = find(__atoms, __atoms + 32, __ct) - __atoms; 5347a984708SDavid Chisnall if (__f >= 32) 5357a984708SDavid Chisnall return -1; 5367a984708SDavid Chisnall char __x = __src[__f]; 53794e3ee44SDavid Chisnall if (__x == '-' || __x == '+') 53894e3ee44SDavid Chisnall { 5391bf9f7c1SDimitry Andric if (__a_end == __a || (__a_end[-1] & 0x5F) == (__exp & 0x7F)) 54094e3ee44SDavid Chisnall { 54194e3ee44SDavid Chisnall *__a_end++ = __x; 54294e3ee44SDavid Chisnall return 0; 54394e3ee44SDavid Chisnall } 54494e3ee44SDavid Chisnall return -1; 54594e3ee44SDavid Chisnall } 5467a984708SDavid Chisnall if (__x == 'x' || __x == 'X') 5477a984708SDavid Chisnall __exp = 'P'; 5481bf9f7c1SDimitry Andric else if ((__x & 0x5F) == __exp) 5491bf9f7c1SDimitry Andric { 5501bf9f7c1SDimitry Andric __exp |= 0x80; 5511bf9f7c1SDimitry Andric if (__in_units) 5527a984708SDavid Chisnall { 5537a984708SDavid Chisnall __in_units = false; 5547a984708SDavid Chisnall if (__grouping.size() != 0 && __g_end-__g < __num_get_buf_sz) 5557a984708SDavid Chisnall *__g_end++ = __dc; 5567a984708SDavid Chisnall } 5571bf9f7c1SDimitry Andric } 5581bf9f7c1SDimitry Andric *__a_end++ = __x; 5597a984708SDavid Chisnall if (__f >= 22) 5607a984708SDavid Chisnall return 0; 5617a984708SDavid Chisnall ++__dc; 5627a984708SDavid Chisnall return 0; 5637a984708SDavid Chisnall} 5647a984708SDavid Chisnall 565aed8d94eSDimitry Andric_LIBCPP_EXTERN_TEMPLATE2(struct _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __num_get<char>) 566aed8d94eSDimitry Andric_LIBCPP_EXTERN_TEMPLATE2(struct _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __num_get<wchar_t>) 5677a984708SDavid Chisnall 5687a984708SDavid Chisnalltemplate <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> > 569aed8d94eSDimitry Andricclass _LIBCPP_TEMPLATE_VIS num_get 5707a984708SDavid Chisnall : public locale::facet, 5717a984708SDavid Chisnall private __num_get<_CharT> 5727a984708SDavid Chisnall{ 5737a984708SDavid Chisnallpublic: 5747a984708SDavid Chisnall typedef _CharT char_type; 5757a984708SDavid Chisnall typedef _InputIterator iter_type; 5767a984708SDavid Chisnall 5774ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 5787a984708SDavid Chisnall explicit num_get(size_t __refs = 0) 5797a984708SDavid Chisnall : locale::facet(__refs) {} 5807a984708SDavid Chisnall 5814ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 5827a984708SDavid Chisnall iter_type get(iter_type __b, iter_type __e, ios_base& __iob, 5837a984708SDavid Chisnall ios_base::iostate& __err, bool& __v) const 5847a984708SDavid Chisnall { 5857a984708SDavid Chisnall return do_get(__b, __e, __iob, __err, __v); 5867a984708SDavid Chisnall } 5877a984708SDavid Chisnall 5884ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 5897a984708SDavid Chisnall iter_type get(iter_type __b, iter_type __e, ios_base& __iob, 5907a984708SDavid Chisnall ios_base::iostate& __err, long& __v) const 5917a984708SDavid Chisnall { 5927a984708SDavid Chisnall return do_get(__b, __e, __iob, __err, __v); 5937a984708SDavid Chisnall } 5947a984708SDavid Chisnall 5954ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 5967a984708SDavid Chisnall iter_type get(iter_type __b, iter_type __e, ios_base& __iob, 5977a984708SDavid Chisnall ios_base::iostate& __err, long long& __v) const 5987a984708SDavid Chisnall { 5997a984708SDavid Chisnall return do_get(__b, __e, __iob, __err, __v); 6007a984708SDavid Chisnall } 6017a984708SDavid Chisnall 6024ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 6037a984708SDavid Chisnall iter_type get(iter_type __b, iter_type __e, ios_base& __iob, 6047a984708SDavid Chisnall ios_base::iostate& __err, unsigned short& __v) const 6057a984708SDavid Chisnall { 6067a984708SDavid Chisnall return do_get(__b, __e, __iob, __err, __v); 6077a984708SDavid Chisnall } 6087a984708SDavid Chisnall 6094ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 6107a984708SDavid Chisnall iter_type get(iter_type __b, iter_type __e, ios_base& __iob, 6117a984708SDavid Chisnall ios_base::iostate& __err, unsigned int& __v) const 6127a984708SDavid Chisnall { 6137a984708SDavid Chisnall return do_get(__b, __e, __iob, __err, __v); 6147a984708SDavid Chisnall } 6157a984708SDavid Chisnall 6164ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 6177a984708SDavid Chisnall iter_type get(iter_type __b, iter_type __e, ios_base& __iob, 6187a984708SDavid Chisnall ios_base::iostate& __err, unsigned long& __v) const 6197a984708SDavid Chisnall { 6207a984708SDavid Chisnall return do_get(__b, __e, __iob, __err, __v); 6217a984708SDavid Chisnall } 6227a984708SDavid Chisnall 6234ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 6247a984708SDavid Chisnall iter_type get(iter_type __b, iter_type __e, ios_base& __iob, 6257a984708SDavid Chisnall ios_base::iostate& __err, unsigned long long& __v) const 6267a984708SDavid Chisnall { 6277a984708SDavid Chisnall return do_get(__b, __e, __iob, __err, __v); 6287a984708SDavid Chisnall } 6297a984708SDavid Chisnall 6304ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 6317a984708SDavid Chisnall iter_type get(iter_type __b, iter_type __e, ios_base& __iob, 6327a984708SDavid Chisnall ios_base::iostate& __err, float& __v) const 6337a984708SDavid Chisnall { 6347a984708SDavid Chisnall return do_get(__b, __e, __iob, __err, __v); 6357a984708SDavid Chisnall } 6367a984708SDavid Chisnall 6374ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 6387a984708SDavid Chisnall iter_type get(iter_type __b, iter_type __e, ios_base& __iob, 6397a984708SDavid Chisnall ios_base::iostate& __err, double& __v) const 6407a984708SDavid Chisnall { 6417a984708SDavid Chisnall return do_get(__b, __e, __iob, __err, __v); 6427a984708SDavid Chisnall } 6437a984708SDavid Chisnall 6444ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 6457a984708SDavid Chisnall iter_type get(iter_type __b, iter_type __e, ios_base& __iob, 6467a984708SDavid Chisnall ios_base::iostate& __err, long double& __v) const 6477a984708SDavid Chisnall { 6487a984708SDavid Chisnall return do_get(__b, __e, __iob, __err, __v); 6497a984708SDavid Chisnall } 6507a984708SDavid Chisnall 6514ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 6527a984708SDavid Chisnall iter_type get(iter_type __b, iter_type __e, ios_base& __iob, 6537a984708SDavid Chisnall ios_base::iostate& __err, void*& __v) const 6547a984708SDavid Chisnall { 6557a984708SDavid Chisnall return do_get(__b, __e, __iob, __err, __v); 6567a984708SDavid Chisnall } 6577a984708SDavid Chisnall 6587a984708SDavid Chisnall static locale::id id; 6597a984708SDavid Chisnall 6607a984708SDavid Chisnallprotected: 6614ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 6627a984708SDavid Chisnall ~num_get() {} 6637a984708SDavid Chisnall 6644f7ab58eSDimitry Andric template <class _Fp> 665540d2a8bSDimitry Andric _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS 6664f7ab58eSDimitry Andric iter_type __do_get_floating_point 6674f7ab58eSDimitry Andric (iter_type __b, iter_type __e, ios_base& __iob, 6684f7ab58eSDimitry Andric ios_base::iostate& __err, _Fp& __v) const; 6694f7ab58eSDimitry Andric 6704f7ab58eSDimitry Andric template <class _Signed> 671540d2a8bSDimitry Andric _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS 6724f7ab58eSDimitry Andric iter_type __do_get_signed 6734f7ab58eSDimitry Andric (iter_type __b, iter_type __e, ios_base& __iob, 6744f7ab58eSDimitry Andric ios_base::iostate& __err, _Signed& __v) const; 6754f7ab58eSDimitry Andric 6764f7ab58eSDimitry Andric template <class _Unsigned> 677540d2a8bSDimitry Andric _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS 6784f7ab58eSDimitry Andric iter_type __do_get_unsigned 6794f7ab58eSDimitry Andric (iter_type __b, iter_type __e, ios_base& __iob, 6804f7ab58eSDimitry Andric ios_base::iostate& __err, _Unsigned& __v) const; 6814f7ab58eSDimitry Andric 6824f7ab58eSDimitry Andric 6837a984708SDavid Chisnall virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob, 6847a984708SDavid Chisnall ios_base::iostate& __err, bool& __v) const; 6854f7ab58eSDimitry Andric 6867a984708SDavid Chisnall virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob, 6874f7ab58eSDimitry Andric ios_base::iostate& __err, long& __v) const 6884f7ab58eSDimitry Andric { return this->__do_get_signed ( __b, __e, __iob, __err, __v ); } 6894f7ab58eSDimitry Andric 6907a984708SDavid Chisnall virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob, 6914f7ab58eSDimitry Andric ios_base::iostate& __err, long long& __v) const 6924f7ab58eSDimitry Andric { return this->__do_get_signed ( __b, __e, __iob, __err, __v ); } 6934f7ab58eSDimitry Andric 6947a984708SDavid Chisnall virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob, 6954f7ab58eSDimitry Andric ios_base::iostate& __err, unsigned short& __v) const 6964f7ab58eSDimitry Andric { return this->__do_get_unsigned ( __b, __e, __iob, __err, __v ); } 6974f7ab58eSDimitry Andric 6987a984708SDavid Chisnall virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob, 6994f7ab58eSDimitry Andric ios_base::iostate& __err, unsigned int& __v) const 7004f7ab58eSDimitry Andric { return this->__do_get_unsigned ( __b, __e, __iob, __err, __v ); } 7014f7ab58eSDimitry Andric 7027a984708SDavid Chisnall virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob, 7034f7ab58eSDimitry Andric ios_base::iostate& __err, unsigned long& __v) const 7044f7ab58eSDimitry Andric { return this->__do_get_unsigned ( __b, __e, __iob, __err, __v ); } 7054f7ab58eSDimitry Andric 7067a984708SDavid Chisnall virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob, 7074f7ab58eSDimitry Andric ios_base::iostate& __err, unsigned long long& __v) const 7084f7ab58eSDimitry Andric { return this->__do_get_unsigned ( __b, __e, __iob, __err, __v ); } 7094f7ab58eSDimitry Andric 7107a984708SDavid Chisnall virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob, 7114f7ab58eSDimitry Andric ios_base::iostate& __err, float& __v) const 7124f7ab58eSDimitry Andric { return this->__do_get_floating_point ( __b, __e, __iob, __err, __v ); } 7134f7ab58eSDimitry Andric 7147a984708SDavid Chisnall virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob, 7154f7ab58eSDimitry Andric ios_base::iostate& __err, double& __v) const 7164f7ab58eSDimitry Andric { return this->__do_get_floating_point ( __b, __e, __iob, __err, __v ); } 7174f7ab58eSDimitry Andric 7187a984708SDavid Chisnall virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob, 7194f7ab58eSDimitry Andric ios_base::iostate& __err, long double& __v) const 7204f7ab58eSDimitry Andric { return this->__do_get_floating_point ( __b, __e, __iob, __err, __v ); } 7214f7ab58eSDimitry Andric 7227a984708SDavid Chisnall virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob, 7237a984708SDavid Chisnall ios_base::iostate& __err, void*& __v) const; 7247a984708SDavid Chisnall}; 7257a984708SDavid Chisnall 7267a984708SDavid Chisnalltemplate <class _CharT, class _InputIterator> 7277a984708SDavid Chisnalllocale::id 7287a984708SDavid Chisnallnum_get<_CharT, _InputIterator>::id; 7297a984708SDavid Chisnall 7307a984708SDavid Chisnalltemplate <class _Tp> 731*b5893f02SDimitry Andric_LIBCPP_HIDDEN _Tp 7327a984708SDavid Chisnall__num_get_signed_integral(const char* __a, const char* __a_end, 7337a984708SDavid Chisnall ios_base::iostate& __err, int __base) 7347a984708SDavid Chisnall{ 7357a984708SDavid Chisnall if (__a != __a_end) 7367a984708SDavid Chisnall { 737cfdf2879SDavid Chisnall typename remove_reference<decltype(errno)>::type __save_errno = errno; 7387a984708SDavid Chisnall errno = 0; 7397a984708SDavid Chisnall char *__p2; 7407a984708SDavid Chisnall long long __ll = strtoll_l(__a, &__p2, __base, _LIBCPP_GET_C_LOCALE); 741cfdf2879SDavid Chisnall typename remove_reference<decltype(errno)>::type __current_errno = errno; 7427a984708SDavid Chisnall if (__current_errno == 0) 7437a984708SDavid Chisnall errno = __save_errno; 7447a984708SDavid Chisnall if (__p2 != __a_end) 7457a984708SDavid Chisnall { 7467a984708SDavid Chisnall __err = ios_base::failbit; 7477a984708SDavid Chisnall return 0; 7487a984708SDavid Chisnall } 7497a984708SDavid Chisnall else if (__current_errno == ERANGE || 7507a984708SDavid Chisnall __ll < numeric_limits<_Tp>::min() || 7517a984708SDavid Chisnall numeric_limits<_Tp>::max() < __ll) 7527a984708SDavid Chisnall { 7537a984708SDavid Chisnall __err = ios_base::failbit; 7547a984708SDavid Chisnall if (__ll > 0) 7557a984708SDavid Chisnall return numeric_limits<_Tp>::max(); 7567a984708SDavid Chisnall else 7577a984708SDavid Chisnall return numeric_limits<_Tp>::min(); 7587a984708SDavid Chisnall } 7597a984708SDavid Chisnall return static_cast<_Tp>(__ll); 7607a984708SDavid Chisnall } 7617a984708SDavid Chisnall __err = ios_base::failbit; 7627a984708SDavid Chisnall return 0; 7637a984708SDavid Chisnall} 7647a984708SDavid Chisnall 7657a984708SDavid Chisnalltemplate <class _Tp> 766*b5893f02SDimitry Andric_LIBCPP_HIDDEN _Tp 7677a984708SDavid Chisnall__num_get_unsigned_integral(const char* __a, const char* __a_end, 7687a984708SDavid Chisnall ios_base::iostate& __err, int __base) 7697a984708SDavid Chisnall{ 7707a984708SDavid Chisnall if (__a != __a_end) 7717a984708SDavid Chisnall { 7724ba319b5SDimitry Andric const bool __negate = *__a == '-'; 7734ba319b5SDimitry Andric if (__negate && ++__a == __a_end) { 7747a984708SDavid Chisnall __err = ios_base::failbit; 7757a984708SDavid Chisnall return 0; 7767a984708SDavid Chisnall } 777cfdf2879SDavid Chisnall typename remove_reference<decltype(errno)>::type __save_errno = errno; 7787a984708SDavid Chisnall errno = 0; 7797a984708SDavid Chisnall char *__p2; 7807a984708SDavid Chisnall unsigned long long __ll = strtoull_l(__a, &__p2, __base, _LIBCPP_GET_C_LOCALE); 781cfdf2879SDavid Chisnall typename remove_reference<decltype(errno)>::type __current_errno = errno; 7827a984708SDavid Chisnall if (__current_errno == 0) 7837a984708SDavid Chisnall errno = __save_errno; 7847a984708SDavid Chisnall if (__p2 != __a_end) 7857a984708SDavid Chisnall { 7867a984708SDavid Chisnall __err = ios_base::failbit; 7877a984708SDavid Chisnall return 0; 7887a984708SDavid Chisnall } 7894ba319b5SDimitry Andric else if (__current_errno == ERANGE || numeric_limits<_Tp>::max() < __ll) 7907a984708SDavid Chisnall { 7917a984708SDavid Chisnall __err = ios_base::failbit; 7927a984708SDavid Chisnall return numeric_limits<_Tp>::max(); 7937a984708SDavid Chisnall } 7944ba319b5SDimitry Andric _Tp __res = static_cast<_Tp>(__ll); 7954ba319b5SDimitry Andric if (__negate) __res = -__res; 7964ba319b5SDimitry Andric return __res; 7977a984708SDavid Chisnall } 7987a984708SDavid Chisnall __err = ios_base::failbit; 7997a984708SDavid Chisnall return 0; 8007a984708SDavid Chisnall} 8017a984708SDavid Chisnall 8027a984708SDavid Chisnalltemplate <class _Tp> 8037c82a1ecSDimitry Andric_LIBCPP_INLINE_VISIBILITY 8047c82a1ecSDimitry Andric_Tp __do_strtod(const char* __a, char** __p2); 8057c82a1ecSDimitry Andric 8067c82a1ecSDimitry Andrictemplate <> 8077c82a1ecSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 8087c82a1ecSDimitry Andricfloat __do_strtod<float>(const char* __a, char** __p2) { 8097c82a1ecSDimitry Andric return strtof_l(__a, __p2, _LIBCPP_GET_C_LOCALE); 8107c82a1ecSDimitry Andric} 8117c82a1ecSDimitry Andric 8127c82a1ecSDimitry Andrictemplate <> 8137c82a1ecSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 8147c82a1ecSDimitry Andricdouble __do_strtod<double>(const char* __a, char** __p2) { 8157c82a1ecSDimitry Andric return strtod_l(__a, __p2, _LIBCPP_GET_C_LOCALE); 8167c82a1ecSDimitry Andric} 8177c82a1ecSDimitry Andric 8187c82a1ecSDimitry Andrictemplate <> 8197c82a1ecSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 8207c82a1ecSDimitry Andriclong double __do_strtod<long double>(const char* __a, char** __p2) { 8217c82a1ecSDimitry Andric return strtold_l(__a, __p2, _LIBCPP_GET_C_LOCALE); 8227c82a1ecSDimitry Andric} 8237c82a1ecSDimitry Andric 8247c82a1ecSDimitry Andrictemplate <class _Tp> 825aed8d94eSDimitry Andric_LIBCPP_HIDDEN 8267a984708SDavid Chisnall_Tp 8277a984708SDavid Chisnall__num_get_float(const char* __a, const char* __a_end, ios_base::iostate& __err) 8287a984708SDavid Chisnall{ 8297a984708SDavid Chisnall if (__a != __a_end) 8307a984708SDavid Chisnall { 8311bf9f7c1SDimitry Andric typename remove_reference<decltype(errno)>::type __save_errno = errno; 8321bf9f7c1SDimitry Andric errno = 0; 8337a984708SDavid Chisnall char *__p2; 8347c82a1ecSDimitry Andric _Tp __ld = __do_strtod<_Tp>(__a, &__p2); 8351bf9f7c1SDimitry Andric typename remove_reference<decltype(errno)>::type __current_errno = errno; 8361bf9f7c1SDimitry Andric if (__current_errno == 0) 8371bf9f7c1SDimitry Andric errno = __save_errno; 8387a984708SDavid Chisnall if (__p2 != __a_end) 8397a984708SDavid Chisnall { 8407a984708SDavid Chisnall __err = ios_base::failbit; 8417a984708SDavid Chisnall return 0; 8427a984708SDavid Chisnall } 8431bf9f7c1SDimitry Andric else if (__current_errno == ERANGE) 8441bf9f7c1SDimitry Andric __err = ios_base::failbit; 8457c82a1ecSDimitry Andric return __ld; 8467a984708SDavid Chisnall } 8477a984708SDavid Chisnall __err = ios_base::failbit; 8487a984708SDavid Chisnall return 0; 8497a984708SDavid Chisnall} 8507a984708SDavid Chisnall 8517a984708SDavid Chisnalltemplate <class _CharT, class _InputIterator> 8527a984708SDavid Chisnall_InputIterator 8537a984708SDavid Chisnallnum_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e, 8547a984708SDavid Chisnall ios_base& __iob, 8557a984708SDavid Chisnall ios_base::iostate& __err, 8567a984708SDavid Chisnall bool& __v) const 8577a984708SDavid Chisnall{ 8587a984708SDavid Chisnall if ((__iob.flags() & ios_base::boolalpha) == 0) 8597a984708SDavid Chisnall { 8607a984708SDavid Chisnall long __lv = -1; 8617a984708SDavid Chisnall __b = do_get(__b, __e, __iob, __err, __lv); 8627a984708SDavid Chisnall switch (__lv) 8637a984708SDavid Chisnall { 8647a984708SDavid Chisnall case 0: 8657a984708SDavid Chisnall __v = false; 8667a984708SDavid Chisnall break; 8677a984708SDavid Chisnall case 1: 8687a984708SDavid Chisnall __v = true; 8697a984708SDavid Chisnall break; 8707a984708SDavid Chisnall default: 8717a984708SDavid Chisnall __v = true; 8727a984708SDavid Chisnall __err = ios_base::failbit; 8737a984708SDavid Chisnall break; 8747a984708SDavid Chisnall } 8757a984708SDavid Chisnall return __b; 8767a984708SDavid Chisnall } 8777a984708SDavid Chisnall const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__iob.getloc()); 8787a984708SDavid Chisnall const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__iob.getloc()); 8797a984708SDavid Chisnall typedef typename numpunct<_CharT>::string_type string_type; 8807a984708SDavid Chisnall const string_type __names[2] = {__np.truename(), __np.falsename()}; 8817a984708SDavid Chisnall const string_type* __i = __scan_keyword(__b, __e, __names, __names+2, 8827a984708SDavid Chisnall __ct, __err); 8837a984708SDavid Chisnall __v = __i == __names; 8847a984708SDavid Chisnall return __b; 8857a984708SDavid Chisnall} 8867a984708SDavid Chisnall 8874f7ab58eSDimitry Andric// signed 8884f7ab58eSDimitry Andric 8897a984708SDavid Chisnalltemplate <class _CharT, class _InputIterator> 8904f7ab58eSDimitry Andrictemplate <class _Signed> 8917a984708SDavid Chisnall_InputIterator 8924f7ab58eSDimitry Andricnum_get<_CharT, _InputIterator>::__do_get_signed(iter_type __b, iter_type __e, 8937a984708SDavid Chisnall ios_base& __iob, 8947a984708SDavid Chisnall ios_base::iostate& __err, 8954f7ab58eSDimitry Andric _Signed& __v) const 8967a984708SDavid Chisnall{ 8977a984708SDavid Chisnall // Stage 1 8987a984708SDavid Chisnall int __base = this->__get_base(__iob); 8997a984708SDavid Chisnall // Stage 2 9007a984708SDavid Chisnall char_type __thousands_sep; 90124d58133SDimitry Andric const int __atoms_size = 26; 90224d58133SDimitry Andric#ifdef _LIBCPP_ABI_OPTIMIZED_LOCALE_NUM_GET 90324d58133SDimitry Andric char_type __atoms1[__atoms_size]; 90424d58133SDimitry Andric const char_type *__atoms = this->__do_widen(__iob, __atoms1); 90524d58133SDimitry Andric string __grouping = this->__stage2_int_prep(__iob, __thousands_sep); 90624d58133SDimitry Andric#else 90724d58133SDimitry Andric char_type __atoms[__atoms_size]; 9087a984708SDavid Chisnall string __grouping = this->__stage2_int_prep(__iob, __atoms, __thousands_sep); 90924d58133SDimitry Andric#endif 9101bf9f7c1SDimitry Andric string __buf; 9111bf9f7c1SDimitry Andric __buf.resize(__buf.capacity()); 9121bf9f7c1SDimitry Andric char* __a = &__buf[0]; 9137a984708SDavid Chisnall char* __a_end = __a; 9147a984708SDavid Chisnall unsigned __g[__num_get_base::__num_get_buf_sz]; 9157a984708SDavid Chisnall unsigned* __g_end = __g; 9167a984708SDavid Chisnall unsigned __dc = 0; 9177a984708SDavid Chisnall for (; __b != __e; ++__b) 9181bf9f7c1SDimitry Andric { 919d4567974SDimitry Andric if (__a_end == __a + __buf.size()) 9201bf9f7c1SDimitry Andric { 9211bf9f7c1SDimitry Andric size_t __tmp = __buf.size(); 9221bf9f7c1SDimitry Andric __buf.resize(2*__buf.size()); 9231bf9f7c1SDimitry Andric __buf.resize(__buf.capacity()); 9241bf9f7c1SDimitry Andric __a = &__buf[0]; 9251bf9f7c1SDimitry Andric __a_end = __a + __tmp; 9261bf9f7c1SDimitry Andric } 9277a984708SDavid Chisnall if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc, 9287a984708SDavid Chisnall __thousands_sep, __grouping, __g, __g_end, 9297a984708SDavid Chisnall __atoms)) 9307a984708SDavid Chisnall break; 9311bf9f7c1SDimitry Andric } 9327a984708SDavid Chisnall if (__grouping.size() != 0 && __g_end-__g < __num_get_base::__num_get_buf_sz) 9337a984708SDavid Chisnall *__g_end++ = __dc; 9347a984708SDavid Chisnall // Stage 3 9354f7ab58eSDimitry Andric __v = __num_get_signed_integral<_Signed>(__a, __a_end, __err, __base); 9367a984708SDavid Chisnall // Digit grouping checked 9377a984708SDavid Chisnall __check_grouping(__grouping, __g, __g_end, __err); 9387a984708SDavid Chisnall // EOF checked 9397a984708SDavid Chisnall if (__b == __e) 9407a984708SDavid Chisnall __err |= ios_base::eofbit; 9417a984708SDavid Chisnall return __b; 9427a984708SDavid Chisnall} 9437a984708SDavid Chisnall 9444f7ab58eSDimitry Andric// unsigned 9454f7ab58eSDimitry Andric 9467a984708SDavid Chisnalltemplate <class _CharT, class _InputIterator> 9474f7ab58eSDimitry Andrictemplate <class _Unsigned> 9487a984708SDavid Chisnall_InputIterator 9494f7ab58eSDimitry Andricnum_get<_CharT, _InputIterator>::__do_get_unsigned(iter_type __b, iter_type __e, 9507a984708SDavid Chisnall ios_base& __iob, 9517a984708SDavid Chisnall ios_base::iostate& __err, 9524f7ab58eSDimitry Andric _Unsigned& __v) const 9537a984708SDavid Chisnall{ 9547a984708SDavid Chisnall // Stage 1 9557a984708SDavid Chisnall int __base = this->__get_base(__iob); 9567a984708SDavid Chisnall // Stage 2 9577a984708SDavid Chisnall char_type __thousands_sep; 95824d58133SDimitry Andric const int __atoms_size = 26; 95924d58133SDimitry Andric#ifdef _LIBCPP_ABI_OPTIMIZED_LOCALE_NUM_GET 96024d58133SDimitry Andric char_type __atoms1[__atoms_size]; 96124d58133SDimitry Andric const char_type *__atoms = this->__do_widen(__iob, __atoms1); 96224d58133SDimitry Andric string __grouping = this->__stage2_int_prep(__iob, __thousands_sep); 96324d58133SDimitry Andric#else 96424d58133SDimitry Andric char_type __atoms[__atoms_size]; 9657a984708SDavid Chisnall string __grouping = this->__stage2_int_prep(__iob, __atoms, __thousands_sep); 96624d58133SDimitry Andric#endif 9671bf9f7c1SDimitry Andric string __buf; 9681bf9f7c1SDimitry Andric __buf.resize(__buf.capacity()); 9691bf9f7c1SDimitry Andric char* __a = &__buf[0]; 9707a984708SDavid Chisnall char* __a_end = __a; 9717a984708SDavid Chisnall unsigned __g[__num_get_base::__num_get_buf_sz]; 9727a984708SDavid Chisnall unsigned* __g_end = __g; 9737a984708SDavid Chisnall unsigned __dc = 0; 9747a984708SDavid Chisnall for (; __b != __e; ++__b) 9751bf9f7c1SDimitry Andric { 976d4567974SDimitry Andric if (__a_end == __a + __buf.size()) 9771bf9f7c1SDimitry Andric { 9781bf9f7c1SDimitry Andric size_t __tmp = __buf.size(); 9791bf9f7c1SDimitry Andric __buf.resize(2*__buf.size()); 9801bf9f7c1SDimitry Andric __buf.resize(__buf.capacity()); 9811bf9f7c1SDimitry Andric __a = &__buf[0]; 9821bf9f7c1SDimitry Andric __a_end = __a + __tmp; 9831bf9f7c1SDimitry Andric } 9847a984708SDavid Chisnall if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc, 9857a984708SDavid Chisnall __thousands_sep, __grouping, __g, __g_end, 9867a984708SDavid Chisnall __atoms)) 9877a984708SDavid Chisnall break; 9881bf9f7c1SDimitry Andric } 9897a984708SDavid Chisnall if (__grouping.size() != 0 && __g_end-__g < __num_get_base::__num_get_buf_sz) 9907a984708SDavid Chisnall *__g_end++ = __dc; 9917a984708SDavid Chisnall // Stage 3 9924f7ab58eSDimitry Andric __v = __num_get_unsigned_integral<_Unsigned>(__a, __a_end, __err, __base); 9937a984708SDavid Chisnall // Digit grouping checked 9947a984708SDavid Chisnall __check_grouping(__grouping, __g, __g_end, __err); 9957a984708SDavid Chisnall // EOF checked 9967a984708SDavid Chisnall if (__b == __e) 9977a984708SDavid Chisnall __err |= ios_base::eofbit; 9987a984708SDavid Chisnall return __b; 9997a984708SDavid Chisnall} 10007a984708SDavid Chisnall 10014f7ab58eSDimitry Andric// floating point 10027a984708SDavid Chisnall 10037a984708SDavid Chisnalltemplate <class _CharT, class _InputIterator> 10044f7ab58eSDimitry Andrictemplate <class _Fp> 10057a984708SDavid Chisnall_InputIterator 10064f7ab58eSDimitry Andricnum_get<_CharT, _InputIterator>::__do_get_floating_point(iter_type __b, iter_type __e, 10077a984708SDavid Chisnall ios_base& __iob, 10087a984708SDavid Chisnall ios_base::iostate& __err, 10094f7ab58eSDimitry Andric _Fp& __v) const 10107a984708SDavid Chisnall{ 10117a984708SDavid Chisnall // Stage 1, nothing to do 10127a984708SDavid Chisnall // Stage 2 10137a984708SDavid Chisnall char_type __atoms[32]; 10147a984708SDavid Chisnall char_type __decimal_point; 10157a984708SDavid Chisnall char_type __thousands_sep; 10167a984708SDavid Chisnall string __grouping = this->__stage2_float_prep(__iob, __atoms, 10177a984708SDavid Chisnall __decimal_point, 10187a984708SDavid Chisnall __thousands_sep); 10191bf9f7c1SDimitry Andric string __buf; 10201bf9f7c1SDimitry Andric __buf.resize(__buf.capacity()); 10211bf9f7c1SDimitry Andric char* __a = &__buf[0]; 10227a984708SDavid Chisnall char* __a_end = __a; 10237a984708SDavid Chisnall unsigned __g[__num_get_base::__num_get_buf_sz]; 10247a984708SDavid Chisnall unsigned* __g_end = __g; 10257a984708SDavid Chisnall unsigned __dc = 0; 10267a984708SDavid Chisnall bool __in_units = true; 10277a984708SDavid Chisnall char __exp = 'E'; 10287a984708SDavid Chisnall for (; __b != __e; ++__b) 10291bf9f7c1SDimitry Andric { 1030d4567974SDimitry Andric if (__a_end == __a + __buf.size()) 10311bf9f7c1SDimitry Andric { 10321bf9f7c1SDimitry Andric size_t __tmp = __buf.size(); 10331bf9f7c1SDimitry Andric __buf.resize(2*__buf.size()); 10341bf9f7c1SDimitry Andric __buf.resize(__buf.capacity()); 10351bf9f7c1SDimitry Andric __a = &__buf[0]; 10361bf9f7c1SDimitry Andric __a_end = __a + __tmp; 10371bf9f7c1SDimitry Andric } 10387a984708SDavid Chisnall if (this->__stage2_float_loop(*__b, __in_units, __exp, __a, __a_end, 10397a984708SDavid Chisnall __decimal_point, __thousands_sep, 10407a984708SDavid Chisnall __grouping, __g, __g_end, 10417a984708SDavid Chisnall __dc, __atoms)) 10427a984708SDavid Chisnall break; 10431bf9f7c1SDimitry Andric } 10447a984708SDavid Chisnall if (__grouping.size() != 0 && __in_units && __g_end-__g < __num_get_base::__num_get_buf_sz) 10457a984708SDavid Chisnall *__g_end++ = __dc; 10467a984708SDavid Chisnall // Stage 3 10474f7ab58eSDimitry Andric __v = __num_get_float<_Fp>(__a, __a_end, __err); 10487a984708SDavid Chisnall // Digit grouping checked 10497a984708SDavid Chisnall __check_grouping(__grouping, __g, __g_end, __err); 10507a984708SDavid Chisnall // EOF checked 10517a984708SDavid Chisnall if (__b == __e) 10527a984708SDavid Chisnall __err |= ios_base::eofbit; 10537a984708SDavid Chisnall return __b; 10547a984708SDavid Chisnall} 10557a984708SDavid Chisnall 10567a984708SDavid Chisnalltemplate <class _CharT, class _InputIterator> 10577a984708SDavid Chisnall_InputIterator 10587a984708SDavid Chisnallnum_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e, 10597a984708SDavid Chisnall ios_base& __iob, 10607a984708SDavid Chisnall ios_base::iostate& __err, 10617a984708SDavid Chisnall void*& __v) const 10627a984708SDavid Chisnall{ 10637a984708SDavid Chisnall // Stage 1 10647a984708SDavid Chisnall int __base = 16; 10657a984708SDavid Chisnall // Stage 2 10667a984708SDavid Chisnall char_type __atoms[26]; 106794e3ee44SDavid Chisnall char_type __thousands_sep = 0; 10687a984708SDavid Chisnall string __grouping; 10697a984708SDavid Chisnall use_facet<ctype<_CharT> >(__iob.getloc()).widen(__num_get_base::__src, 10707a984708SDavid Chisnall __num_get_base::__src + 26, __atoms); 10711bf9f7c1SDimitry Andric string __buf; 10721bf9f7c1SDimitry Andric __buf.resize(__buf.capacity()); 10731bf9f7c1SDimitry Andric char* __a = &__buf[0]; 10747a984708SDavid Chisnall char* __a_end = __a; 10757a984708SDavid Chisnall unsigned __g[__num_get_base::__num_get_buf_sz]; 10767a984708SDavid Chisnall unsigned* __g_end = __g; 10777a984708SDavid Chisnall unsigned __dc = 0; 10787a984708SDavid Chisnall for (; __b != __e; ++__b) 10791bf9f7c1SDimitry Andric { 1080d4567974SDimitry Andric if (__a_end == __a + __buf.size()) 10811bf9f7c1SDimitry Andric { 10821bf9f7c1SDimitry Andric size_t __tmp = __buf.size(); 10831bf9f7c1SDimitry Andric __buf.resize(2*__buf.size()); 10841bf9f7c1SDimitry Andric __buf.resize(__buf.capacity()); 10851bf9f7c1SDimitry Andric __a = &__buf[0]; 10861bf9f7c1SDimitry Andric __a_end = __a + __tmp; 10871bf9f7c1SDimitry Andric } 10887a984708SDavid Chisnall if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc, 10897a984708SDavid Chisnall __thousands_sep, __grouping, 10907a984708SDavid Chisnall __g, __g_end, __atoms)) 10917a984708SDavid Chisnall break; 10921bf9f7c1SDimitry Andric } 10937a984708SDavid Chisnall // Stage 3 1094d72607e9SDimitry Andric __buf.resize(__a_end - __a); 10957c82a1ecSDimitry Andric if (__libcpp_sscanf_l(__buf.c_str(), _LIBCPP_GET_C_LOCALE, "%p", &__v) != 1) 10967a984708SDavid Chisnall __err = ios_base::failbit; 10977a984708SDavid Chisnall // EOF checked 10987a984708SDavid Chisnall if (__b == __e) 10997a984708SDavid Chisnall __err |= ios_base::eofbit; 11007a984708SDavid Chisnall return __b; 11017a984708SDavid Chisnall} 11027a984708SDavid Chisnall 1103aed8d94eSDimitry Andric_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS num_get<char>) 1104aed8d94eSDimitry Andric_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS num_get<wchar_t>) 11057a984708SDavid Chisnall 11064f7ab58eSDimitry Andricstruct _LIBCPP_TYPE_VIS __num_put_base 11077a984708SDavid Chisnall{ 11087a984708SDavid Chisnallprotected: 11097a984708SDavid Chisnall static void __format_int(char* __fmt, const char* __len, bool __signd, 11107a984708SDavid Chisnall ios_base::fmtflags __flags); 11117a984708SDavid Chisnall static bool __format_float(char* __fmt, const char* __len, 11127a984708SDavid Chisnall ios_base::fmtflags __flags); 11137a984708SDavid Chisnall static char* __identify_padding(char* __nb, char* __ne, 11147a984708SDavid Chisnall const ios_base& __iob); 11157a984708SDavid Chisnall}; 11167a984708SDavid Chisnall 11177a984708SDavid Chisnalltemplate <class _CharT> 11187a984708SDavid Chisnallstruct __num_put 11197a984708SDavid Chisnall : protected __num_put_base 11207a984708SDavid Chisnall{ 11217a984708SDavid Chisnall static void __widen_and_group_int(char* __nb, char* __np, char* __ne, 11227a984708SDavid Chisnall _CharT* __ob, _CharT*& __op, _CharT*& __oe, 11237a984708SDavid Chisnall const locale& __loc); 11247a984708SDavid Chisnall static void __widen_and_group_float(char* __nb, char* __np, char* __ne, 11257a984708SDavid Chisnall _CharT* __ob, _CharT*& __op, _CharT*& __oe, 11267a984708SDavid Chisnall const locale& __loc); 11277a984708SDavid Chisnall}; 11287a984708SDavid Chisnall 11297a984708SDavid Chisnalltemplate <class _CharT> 11307a984708SDavid Chisnallvoid 11317a984708SDavid Chisnall__num_put<_CharT>::__widen_and_group_int(char* __nb, char* __np, char* __ne, 11327a984708SDavid Chisnall _CharT* __ob, _CharT*& __op, _CharT*& __oe, 11337a984708SDavid Chisnall const locale& __loc) 11347a984708SDavid Chisnall{ 11357a984708SDavid Chisnall const ctype<_CharT>& __ct = use_facet<ctype<_CharT> > (__loc); 11367a984708SDavid Chisnall const numpunct<_CharT>& __npt = use_facet<numpunct<_CharT> >(__loc); 11377a984708SDavid Chisnall string __grouping = __npt.grouping(); 11387a984708SDavid Chisnall if (__grouping.empty()) 11397a984708SDavid Chisnall { 11407a984708SDavid Chisnall __ct.widen(__nb, __ne, __ob); 11417a984708SDavid Chisnall __oe = __ob + (__ne - __nb); 11427a984708SDavid Chisnall } 11437a984708SDavid Chisnall else 11447a984708SDavid Chisnall { 11457a984708SDavid Chisnall __oe = __ob; 11467a984708SDavid Chisnall char* __nf = __nb; 11477a984708SDavid Chisnall if (*__nf == '-' || *__nf == '+') 11487a984708SDavid Chisnall *__oe++ = __ct.widen(*__nf++); 11497a984708SDavid Chisnall if (__ne - __nf >= 2 && __nf[0] == '0' && (__nf[1] == 'x' || 11507a984708SDavid Chisnall __nf[1] == 'X')) 11517a984708SDavid Chisnall { 11527a984708SDavid Chisnall *__oe++ = __ct.widen(*__nf++); 11537a984708SDavid Chisnall *__oe++ = __ct.widen(*__nf++); 11547a984708SDavid Chisnall } 11557a984708SDavid Chisnall reverse(__nf, __ne); 11567a984708SDavid Chisnall _CharT __thousands_sep = __npt.thousands_sep(); 11577a984708SDavid Chisnall unsigned __dc = 0; 11587a984708SDavid Chisnall unsigned __dg = 0; 11597a984708SDavid Chisnall for (char* __p = __nf; __p < __ne; ++__p) 11607a984708SDavid Chisnall { 11617a984708SDavid Chisnall if (static_cast<unsigned>(__grouping[__dg]) > 0 && 11627a984708SDavid Chisnall __dc == static_cast<unsigned>(__grouping[__dg])) 11637a984708SDavid Chisnall { 11647a984708SDavid Chisnall *__oe++ = __thousands_sep; 11657a984708SDavid Chisnall __dc = 0; 11667a984708SDavid Chisnall if (__dg < __grouping.size()-1) 11677a984708SDavid Chisnall ++__dg; 11687a984708SDavid Chisnall } 11697a984708SDavid Chisnall *__oe++ = __ct.widen(*__p); 11707a984708SDavid Chisnall ++__dc; 11717a984708SDavid Chisnall } 11727a984708SDavid Chisnall reverse(__ob + (__nf - __nb), __oe); 11737a984708SDavid Chisnall } 11747a984708SDavid Chisnall if (__np == __ne) 11757a984708SDavid Chisnall __op = __oe; 11767a984708SDavid Chisnall else 11777a984708SDavid Chisnall __op = __ob + (__np - __nb); 11787a984708SDavid Chisnall} 11797a984708SDavid Chisnall 11807a984708SDavid Chisnalltemplate <class _CharT> 11817a984708SDavid Chisnallvoid 11827a984708SDavid Chisnall__num_put<_CharT>::__widen_and_group_float(char* __nb, char* __np, char* __ne, 11837a984708SDavid Chisnall _CharT* __ob, _CharT*& __op, _CharT*& __oe, 11847a984708SDavid Chisnall const locale& __loc) 11857a984708SDavid Chisnall{ 11867a984708SDavid Chisnall const ctype<_CharT>& __ct = use_facet<ctype<_CharT> > (__loc); 11877a984708SDavid Chisnall const numpunct<_CharT>& __npt = use_facet<numpunct<_CharT> >(__loc); 11887a984708SDavid Chisnall string __grouping = __npt.grouping(); 11897a984708SDavid Chisnall __oe = __ob; 11907a984708SDavid Chisnall char* __nf = __nb; 11917a984708SDavid Chisnall if (*__nf == '-' || *__nf == '+') 11927a984708SDavid Chisnall *__oe++ = __ct.widen(*__nf++); 11937a984708SDavid Chisnall char* __ns; 11947a984708SDavid Chisnall if (__ne - __nf >= 2 && __nf[0] == '0' && (__nf[1] == 'x' || 11957a984708SDavid Chisnall __nf[1] == 'X')) 11967a984708SDavid Chisnall { 11977a984708SDavid Chisnall *__oe++ = __ct.widen(*__nf++); 11987a984708SDavid Chisnall *__oe++ = __ct.widen(*__nf++); 11997a984708SDavid Chisnall for (__ns = __nf; __ns < __ne; ++__ns) 12007a984708SDavid Chisnall if (!isxdigit_l(*__ns, _LIBCPP_GET_C_LOCALE)) 12017a984708SDavid Chisnall break; 12027a984708SDavid Chisnall } 12037a984708SDavid Chisnall else 12047a984708SDavid Chisnall { 12057a984708SDavid Chisnall for (__ns = __nf; __ns < __ne; ++__ns) 12067a984708SDavid Chisnall if (!isdigit_l(*__ns, _LIBCPP_GET_C_LOCALE)) 12077a984708SDavid Chisnall break; 12087a984708SDavid Chisnall } 12097a984708SDavid Chisnall if (__grouping.empty()) 12107a984708SDavid Chisnall { 12117a984708SDavid Chisnall __ct.widen(__nf, __ns, __oe); 12127a984708SDavid Chisnall __oe += __ns - __nf; 12137a984708SDavid Chisnall } 12147a984708SDavid Chisnall else 12157a984708SDavid Chisnall { 12167a984708SDavid Chisnall reverse(__nf, __ns); 12177a984708SDavid Chisnall _CharT __thousands_sep = __npt.thousands_sep(); 12187a984708SDavid Chisnall unsigned __dc = 0; 12197a984708SDavid Chisnall unsigned __dg = 0; 12207a984708SDavid Chisnall for (char* __p = __nf; __p < __ns; ++__p) 12217a984708SDavid Chisnall { 12227a984708SDavid Chisnall if (__grouping[__dg] > 0 && __dc == static_cast<unsigned>(__grouping[__dg])) 12237a984708SDavid Chisnall { 12247a984708SDavid Chisnall *__oe++ = __thousands_sep; 12257a984708SDavid Chisnall __dc = 0; 12267a984708SDavid Chisnall if (__dg < __grouping.size()-1) 12277a984708SDavid Chisnall ++__dg; 12287a984708SDavid Chisnall } 12297a984708SDavid Chisnall *__oe++ = __ct.widen(*__p); 12307a984708SDavid Chisnall ++__dc; 12317a984708SDavid Chisnall } 12327a984708SDavid Chisnall reverse(__ob + (__nf - __nb), __oe); 12337a984708SDavid Chisnall } 12347a984708SDavid Chisnall for (__nf = __ns; __nf < __ne; ++__nf) 12357a984708SDavid Chisnall { 12367a984708SDavid Chisnall if (*__nf == '.') 12377a984708SDavid Chisnall { 12387a984708SDavid Chisnall *__oe++ = __npt.decimal_point(); 12397a984708SDavid Chisnall ++__nf; 12407a984708SDavid Chisnall break; 12417a984708SDavid Chisnall } 12427a984708SDavid Chisnall else 12437a984708SDavid Chisnall *__oe++ = __ct.widen(*__nf); 12447a984708SDavid Chisnall } 12457a984708SDavid Chisnall __ct.widen(__nf, __ne, __oe); 12467a984708SDavid Chisnall __oe += __ne - __nf; 12477a984708SDavid Chisnall if (__np == __ne) 12487a984708SDavid Chisnall __op = __oe; 12497a984708SDavid Chisnall else 12507a984708SDavid Chisnall __op = __ob + (__np - __nb); 12517a984708SDavid Chisnall} 12527a984708SDavid Chisnall 1253aed8d94eSDimitry Andric_LIBCPP_EXTERN_TEMPLATE2(struct _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __num_put<char>) 1254aed8d94eSDimitry Andric_LIBCPP_EXTERN_TEMPLATE2(struct _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __num_put<wchar_t>) 12557a984708SDavid Chisnall 12567a984708SDavid Chisnalltemplate <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> > 1257aed8d94eSDimitry Andricclass _LIBCPP_TEMPLATE_VIS num_put 12587a984708SDavid Chisnall : public locale::facet, 12597a984708SDavid Chisnall private __num_put<_CharT> 12607a984708SDavid Chisnall{ 12617a984708SDavid Chisnallpublic: 12627a984708SDavid Chisnall typedef _CharT char_type; 12637a984708SDavid Chisnall typedef _OutputIterator iter_type; 12647a984708SDavid Chisnall 12654ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 12667a984708SDavid Chisnall explicit num_put(size_t __refs = 0) 12677a984708SDavid Chisnall : locale::facet(__refs) {} 12687a984708SDavid Chisnall 12694ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 12707a984708SDavid Chisnall iter_type put(iter_type __s, ios_base& __iob, char_type __fl, 12717a984708SDavid Chisnall bool __v) const 12727a984708SDavid Chisnall { 12737a984708SDavid Chisnall return do_put(__s, __iob, __fl, __v); 12747a984708SDavid Chisnall } 12757a984708SDavid Chisnall 12764ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 12777a984708SDavid Chisnall iter_type put(iter_type __s, ios_base& __iob, char_type __fl, 12787a984708SDavid Chisnall long __v) const 12797a984708SDavid Chisnall { 12807a984708SDavid Chisnall return do_put(__s, __iob, __fl, __v); 12817a984708SDavid Chisnall } 12827a984708SDavid Chisnall 12834ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 12847a984708SDavid Chisnall iter_type put(iter_type __s, ios_base& __iob, char_type __fl, 12857a984708SDavid Chisnall long long __v) const 12867a984708SDavid Chisnall { 12877a984708SDavid Chisnall return do_put(__s, __iob, __fl, __v); 12887a984708SDavid Chisnall } 12897a984708SDavid Chisnall 12904ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 12917a984708SDavid Chisnall iter_type put(iter_type __s, ios_base& __iob, char_type __fl, 12927a984708SDavid Chisnall unsigned long __v) const 12937a984708SDavid Chisnall { 12947a984708SDavid Chisnall return do_put(__s, __iob, __fl, __v); 12957a984708SDavid Chisnall } 12967a984708SDavid Chisnall 12974ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 12987a984708SDavid Chisnall iter_type put(iter_type __s, ios_base& __iob, char_type __fl, 12997a984708SDavid Chisnall unsigned long long __v) const 13007a984708SDavid Chisnall { 13017a984708SDavid Chisnall return do_put(__s, __iob, __fl, __v); 13027a984708SDavid Chisnall } 13037a984708SDavid Chisnall 13044ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 13057a984708SDavid Chisnall iter_type put(iter_type __s, ios_base& __iob, char_type __fl, 13067a984708SDavid Chisnall double __v) const 13077a984708SDavid Chisnall { 13087a984708SDavid Chisnall return do_put(__s, __iob, __fl, __v); 13097a984708SDavid Chisnall } 13107a984708SDavid Chisnall 13114ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 13127a984708SDavid Chisnall iter_type put(iter_type __s, ios_base& __iob, char_type __fl, 13137a984708SDavid Chisnall long double __v) const 13147a984708SDavid Chisnall { 13157a984708SDavid Chisnall return do_put(__s, __iob, __fl, __v); 13167a984708SDavid Chisnall } 13177a984708SDavid Chisnall 13184ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 13197a984708SDavid Chisnall iter_type put(iter_type __s, ios_base& __iob, char_type __fl, 13207a984708SDavid Chisnall const void* __v) const 13217a984708SDavid Chisnall { 13227a984708SDavid Chisnall return do_put(__s, __iob, __fl, __v); 13237a984708SDavid Chisnall } 13247a984708SDavid Chisnall 13257a984708SDavid Chisnall static locale::id id; 13267a984708SDavid Chisnall 13277a984708SDavid Chisnallprotected: 13284ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 13297a984708SDavid Chisnall ~num_put() {} 13307a984708SDavid Chisnall 13317a984708SDavid Chisnall virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl, 13327a984708SDavid Chisnall bool __v) const; 13337a984708SDavid Chisnall virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl, 13347a984708SDavid Chisnall long __v) const; 13357a984708SDavid Chisnall virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl, 13367a984708SDavid Chisnall long long __v) const; 13377a984708SDavid Chisnall virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl, 13387a984708SDavid Chisnall unsigned long) const; 13397a984708SDavid Chisnall virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl, 13407a984708SDavid Chisnall unsigned long long) const; 13417a984708SDavid Chisnall virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl, 13427a984708SDavid Chisnall double __v) const; 13437a984708SDavid Chisnall virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl, 13447a984708SDavid Chisnall long double __v) const; 13457a984708SDavid Chisnall virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl, 13467a984708SDavid Chisnall const void* __v) const; 13477a984708SDavid Chisnall}; 13487a984708SDavid Chisnall 13497a984708SDavid Chisnalltemplate <class _CharT, class _OutputIterator> 13507a984708SDavid Chisnalllocale::id 13517a984708SDavid Chisnallnum_put<_CharT, _OutputIterator>::id; 13527a984708SDavid Chisnall 13537a984708SDavid Chisnalltemplate <class _CharT, class _OutputIterator> 13547a984708SDavid Chisnall_LIBCPP_HIDDEN 13557a984708SDavid Chisnall_OutputIterator 13567a984708SDavid Chisnall__pad_and_output(_OutputIterator __s, 13577a984708SDavid Chisnall const _CharT* __ob, const _CharT* __op, const _CharT* __oe, 13587a984708SDavid Chisnall ios_base& __iob, _CharT __fl) 13597a984708SDavid Chisnall{ 13607a984708SDavid Chisnall streamsize __sz = __oe - __ob; 13617a984708SDavid Chisnall streamsize __ns = __iob.width(); 13627a984708SDavid Chisnall if (__ns > __sz) 13637a984708SDavid Chisnall __ns -= __sz; 13647a984708SDavid Chisnall else 13657a984708SDavid Chisnall __ns = 0; 13667a984708SDavid Chisnall for (;__ob < __op; ++__ob, ++__s) 13677a984708SDavid Chisnall *__s = *__ob; 13687a984708SDavid Chisnall for (; __ns; --__ns, ++__s) 13697a984708SDavid Chisnall *__s = __fl; 13707a984708SDavid Chisnall for (; __ob < __oe; ++__ob, ++__s) 13717a984708SDavid Chisnall *__s = *__ob; 13727a984708SDavid Chisnall __iob.width(0); 13737a984708SDavid Chisnall return __s; 13747a984708SDavid Chisnall} 13757a984708SDavid Chisnall 1376fb6c5de6SDavid Chisnall#if !defined(__APPLE__) || \ 1377fb6c5de6SDavid Chisnall (defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED > __MAC_10_8) || \ 1378fb6c5de6SDavid Chisnall (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED > __IPHONE_6_0) 1379fb6c5de6SDavid Chisnall 1380936e9439SDimitry Andrictemplate <class _CharT, class _Traits> 1381936e9439SDimitry Andric_LIBCPP_HIDDEN 1382936e9439SDimitry Andricostreambuf_iterator<_CharT, _Traits> 1383936e9439SDimitry Andric__pad_and_output(ostreambuf_iterator<_CharT, _Traits> __s, 1384936e9439SDimitry Andric const _CharT* __ob, const _CharT* __op, const _CharT* __oe, 1385936e9439SDimitry Andric ios_base& __iob, _CharT __fl) 1386936e9439SDimitry Andric{ 1387936e9439SDimitry Andric if (__s.__sbuf_ == nullptr) 1388936e9439SDimitry Andric return __s; 1389936e9439SDimitry Andric streamsize __sz = __oe - __ob; 1390936e9439SDimitry Andric streamsize __ns = __iob.width(); 1391936e9439SDimitry Andric if (__ns > __sz) 1392936e9439SDimitry Andric __ns -= __sz; 1393936e9439SDimitry Andric else 1394936e9439SDimitry Andric __ns = 0; 1395936e9439SDimitry Andric streamsize __np = __op - __ob; 1396936e9439SDimitry Andric if (__np > 0) 1397936e9439SDimitry Andric { 1398936e9439SDimitry Andric if (__s.__sbuf_->sputn(__ob, __np) != __np) 1399936e9439SDimitry Andric { 1400936e9439SDimitry Andric __s.__sbuf_ = nullptr; 1401936e9439SDimitry Andric return __s; 1402936e9439SDimitry Andric } 1403936e9439SDimitry Andric } 1404936e9439SDimitry Andric if (__ns > 0) 1405936e9439SDimitry Andric { 1406936e9439SDimitry Andric basic_string<_CharT, _Traits> __sp(__ns, __fl); 1407936e9439SDimitry Andric if (__s.__sbuf_->sputn(__sp.data(), __ns) != __ns) 1408936e9439SDimitry Andric { 1409936e9439SDimitry Andric __s.__sbuf_ = nullptr; 1410936e9439SDimitry Andric return __s; 1411936e9439SDimitry Andric } 1412936e9439SDimitry Andric } 1413936e9439SDimitry Andric __np = __oe - __op; 1414936e9439SDimitry Andric if (__np > 0) 1415936e9439SDimitry Andric { 1416936e9439SDimitry Andric if (__s.__sbuf_->sputn(__op, __np) != __np) 1417936e9439SDimitry Andric { 1418936e9439SDimitry Andric __s.__sbuf_ = nullptr; 1419936e9439SDimitry Andric return __s; 1420936e9439SDimitry Andric } 1421936e9439SDimitry Andric } 1422936e9439SDimitry Andric __iob.width(0); 1423936e9439SDimitry Andric return __s; 1424936e9439SDimitry Andric} 1425936e9439SDimitry Andric 1426fb6c5de6SDavid Chisnall#endif 1427fb6c5de6SDavid Chisnall 14287a984708SDavid Chisnalltemplate <class _CharT, class _OutputIterator> 14297a984708SDavid Chisnall_OutputIterator 14307a984708SDavid Chisnallnum_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, 14317a984708SDavid Chisnall char_type __fl, bool __v) const 14327a984708SDavid Chisnall{ 14337a984708SDavid Chisnall if ((__iob.flags() & ios_base::boolalpha) == 0) 14347a984708SDavid Chisnall return do_put(__s, __iob, __fl, (unsigned long)__v); 14357a984708SDavid Chisnall const numpunct<char_type>& __np = use_facet<numpunct<char_type> >(__iob.getloc()); 14367a984708SDavid Chisnall typedef typename numpunct<char_type>::string_type string_type; 14374f7ab58eSDimitry Andric#if _LIBCPP_DEBUG_LEVEL >= 2 14384f7ab58eSDimitry Andric string_type __tmp(__v ? __np.truename() : __np.falsename()); 14394f7ab58eSDimitry Andric string_type __nm = _VSTD::move(__tmp); 14404f7ab58eSDimitry Andric#else 14417a984708SDavid Chisnall string_type __nm = __v ? __np.truename() : __np.falsename(); 14424f7ab58eSDimitry Andric#endif 14437a984708SDavid Chisnall for (typename string_type::iterator __i = __nm.begin(); __i != __nm.end(); ++__i, ++__s) 14447a984708SDavid Chisnall *__s = *__i; 14457a984708SDavid Chisnall return __s; 14467a984708SDavid Chisnall} 14477a984708SDavid Chisnall 14487a984708SDavid Chisnalltemplate <class _CharT, class _OutputIterator> 14497a984708SDavid Chisnall_OutputIterator 14507a984708SDavid Chisnallnum_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, 14517a984708SDavid Chisnall char_type __fl, long __v) const 14527a984708SDavid Chisnall{ 14537a984708SDavid Chisnall // Stage 1 - Get number in narrow char 14547a984708SDavid Chisnall char __fmt[6] = {'%', 0}; 14557a984708SDavid Chisnall const char* __len = "l"; 14567a984708SDavid Chisnall this->__format_int(__fmt+1, __len, true, __iob.flags()); 14577a984708SDavid Chisnall const unsigned __nbuf = (numeric_limits<long>::digits / 3) 14587a984708SDavid Chisnall + ((numeric_limits<long>::digits % 3) != 0) 14590f5676f4SDimitry Andric + ((__iob.flags() & ios_base::showbase) != 0) 14607c82a1ecSDimitry Andric + 2; 14617a984708SDavid Chisnall char __nar[__nbuf]; 14627c82a1ecSDimitry Andric int __nc = __libcpp_snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v); 14637a984708SDavid Chisnall char* __ne = __nar + __nc; 14647a984708SDavid Chisnall char* __np = this->__identify_padding(__nar, __ne, __iob); 14657a984708SDavid Chisnall // Stage 2 - Widen __nar while adding thousands separators 14667a984708SDavid Chisnall char_type __o[2*(__nbuf-1) - 1]; 14677a984708SDavid Chisnall char_type* __op; // pad here 14687a984708SDavid Chisnall char_type* __oe; // end of output 14697a984708SDavid Chisnall this->__widen_and_group_int(__nar, __np, __ne, __o, __op, __oe, __iob.getloc()); 14707a984708SDavid Chisnall // [__o, __oe) contains thousands_sep'd wide number 14717a984708SDavid Chisnall // Stage 3 & 4 14727a984708SDavid Chisnall return __pad_and_output(__s, __o, __op, __oe, __iob, __fl); 14737a984708SDavid Chisnall} 14747a984708SDavid Chisnall 14757a984708SDavid Chisnalltemplate <class _CharT, class _OutputIterator> 14767a984708SDavid Chisnall_OutputIterator 14777a984708SDavid Chisnallnum_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, 14787a984708SDavid Chisnall char_type __fl, long long __v) const 14797a984708SDavid Chisnall{ 14807a984708SDavid Chisnall // Stage 1 - Get number in narrow char 14817a984708SDavid Chisnall char __fmt[8] = {'%', 0}; 14827a984708SDavid Chisnall const char* __len = "ll"; 14837a984708SDavid Chisnall this->__format_int(__fmt+1, __len, true, __iob.flags()); 14847a984708SDavid Chisnall const unsigned __nbuf = (numeric_limits<long long>::digits / 3) 14857a984708SDavid Chisnall + ((numeric_limits<long long>::digits % 3) != 0) 14860f5676f4SDimitry Andric + ((__iob.flags() & ios_base::showbase) != 0) 1487854fa44bSDimitry Andric + 2; 14887a984708SDavid Chisnall char __nar[__nbuf]; 14897c82a1ecSDimitry Andric int __nc = __libcpp_snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v); 14907a984708SDavid Chisnall char* __ne = __nar + __nc; 14917a984708SDavid Chisnall char* __np = this->__identify_padding(__nar, __ne, __iob); 14927a984708SDavid Chisnall // Stage 2 - Widen __nar while adding thousands separators 14937a984708SDavid Chisnall char_type __o[2*(__nbuf-1) - 1]; 14947a984708SDavid Chisnall char_type* __op; // pad here 14957a984708SDavid Chisnall char_type* __oe; // end of output 14967a984708SDavid Chisnall this->__widen_and_group_int(__nar, __np, __ne, __o, __op, __oe, __iob.getloc()); 14977a984708SDavid Chisnall // [__o, __oe) contains thousands_sep'd wide number 14987a984708SDavid Chisnall // Stage 3 & 4 14997a984708SDavid Chisnall return __pad_and_output(__s, __o, __op, __oe, __iob, __fl); 15007a984708SDavid Chisnall} 15017a984708SDavid Chisnall 15027a984708SDavid Chisnalltemplate <class _CharT, class _OutputIterator> 15037a984708SDavid Chisnall_OutputIterator 15047a984708SDavid Chisnallnum_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, 15057a984708SDavid Chisnall char_type __fl, unsigned long __v) const 15067a984708SDavid Chisnall{ 15077a984708SDavid Chisnall // Stage 1 - Get number in narrow char 15087a984708SDavid Chisnall char __fmt[6] = {'%', 0}; 15097a984708SDavid Chisnall const char* __len = "l"; 15107a984708SDavid Chisnall this->__format_int(__fmt+1, __len, false, __iob.flags()); 15117a984708SDavid Chisnall const unsigned __nbuf = (numeric_limits<unsigned long>::digits / 3) 15127a984708SDavid Chisnall + ((numeric_limits<unsigned long>::digits % 3) != 0) 15130f5676f4SDimitry Andric + ((__iob.flags() & ios_base::showbase) != 0) 15147a984708SDavid Chisnall + 1; 15157a984708SDavid Chisnall char __nar[__nbuf]; 15167c82a1ecSDimitry Andric int __nc = __libcpp_snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v); 15177a984708SDavid Chisnall char* __ne = __nar + __nc; 15187a984708SDavid Chisnall char* __np = this->__identify_padding(__nar, __ne, __iob); 15197a984708SDavid Chisnall // Stage 2 - Widen __nar while adding thousands separators 15207a984708SDavid Chisnall char_type __o[2*(__nbuf-1) - 1]; 15217a984708SDavid Chisnall char_type* __op; // pad here 15227a984708SDavid Chisnall char_type* __oe; // end of output 15237a984708SDavid Chisnall this->__widen_and_group_int(__nar, __np, __ne, __o, __op, __oe, __iob.getloc()); 15247a984708SDavid Chisnall // [__o, __oe) contains thousands_sep'd wide number 15257a984708SDavid Chisnall // Stage 3 & 4 15267a984708SDavid Chisnall return __pad_and_output(__s, __o, __op, __oe, __iob, __fl); 15277a984708SDavid Chisnall} 15287a984708SDavid Chisnall 15297a984708SDavid Chisnalltemplate <class _CharT, class _OutputIterator> 15307a984708SDavid Chisnall_OutputIterator 15317a984708SDavid Chisnallnum_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, 15327a984708SDavid Chisnall char_type __fl, unsigned long long __v) const 15337a984708SDavid Chisnall{ 15347a984708SDavid Chisnall // Stage 1 - Get number in narrow char 15357a984708SDavid Chisnall char __fmt[8] = {'%', 0}; 15367a984708SDavid Chisnall const char* __len = "ll"; 15377a984708SDavid Chisnall this->__format_int(__fmt+1, __len, false, __iob.flags()); 15387a984708SDavid Chisnall const unsigned __nbuf = (numeric_limits<unsigned long long>::digits / 3) 15397a984708SDavid Chisnall + ((numeric_limits<unsigned long long>::digits % 3) != 0) 15400f5676f4SDimitry Andric + ((__iob.flags() & ios_base::showbase) != 0) 15417a984708SDavid Chisnall + 1; 15427a984708SDavid Chisnall char __nar[__nbuf]; 15437c82a1ecSDimitry Andric int __nc = __libcpp_snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v); 15447a984708SDavid Chisnall char* __ne = __nar + __nc; 15457a984708SDavid Chisnall char* __np = this->__identify_padding(__nar, __ne, __iob); 15467a984708SDavid Chisnall // Stage 2 - Widen __nar while adding thousands separators 15477a984708SDavid Chisnall char_type __o[2*(__nbuf-1) - 1]; 15487a984708SDavid Chisnall char_type* __op; // pad here 15497a984708SDavid Chisnall char_type* __oe; // end of output 15507a984708SDavid Chisnall this->__widen_and_group_int(__nar, __np, __ne, __o, __op, __oe, __iob.getloc()); 15517a984708SDavid Chisnall // [__o, __oe) contains thousands_sep'd wide number 15527a984708SDavid Chisnall // Stage 3 & 4 15537a984708SDavid Chisnall return __pad_and_output(__s, __o, __op, __oe, __iob, __fl); 15547a984708SDavid Chisnall} 15557a984708SDavid Chisnall 15567a984708SDavid Chisnalltemplate <class _CharT, class _OutputIterator> 15577a984708SDavid Chisnall_OutputIterator 15587a984708SDavid Chisnallnum_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, 15597a984708SDavid Chisnall char_type __fl, double __v) const 15607a984708SDavid Chisnall{ 15617a984708SDavid Chisnall // Stage 1 - Get number in narrow char 15627a984708SDavid Chisnall char __fmt[8] = {'%', 0}; 15637a984708SDavid Chisnall const char* __len = ""; 15647a984708SDavid Chisnall bool __specify_precision = this->__format_float(__fmt+1, __len, __iob.flags()); 15657a984708SDavid Chisnall const unsigned __nbuf = 30; 15667a984708SDavid Chisnall char __nar[__nbuf]; 15677a984708SDavid Chisnall char* __nb = __nar; 15687a984708SDavid Chisnall int __nc; 15697a984708SDavid Chisnall if (__specify_precision) 15707c82a1ecSDimitry Andric __nc = __libcpp_snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, 15717a984708SDavid Chisnall (int)__iob.precision(), __v); 15727a984708SDavid Chisnall else 15737c82a1ecSDimitry Andric __nc = __libcpp_snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, __v); 15747a984708SDavid Chisnall unique_ptr<char, void(*)(void*)> __nbh(0, free); 15757a984708SDavid Chisnall if (__nc > static_cast<int>(__nbuf-1)) 15767a984708SDavid Chisnall { 15777a984708SDavid Chisnall if (__specify_precision) 15787c82a1ecSDimitry Andric __nc = __libcpp_asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v); 15797a984708SDavid Chisnall else 15807c82a1ecSDimitry Andric __nc = __libcpp_asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, __v); 15817a984708SDavid Chisnall if (__nb == 0) 15827a984708SDavid Chisnall __throw_bad_alloc(); 15837a984708SDavid Chisnall __nbh.reset(__nb); 15847a984708SDavid Chisnall } 15857a984708SDavid Chisnall char* __ne = __nb + __nc; 15867a984708SDavid Chisnall char* __np = this->__identify_padding(__nb, __ne, __iob); 15877a984708SDavid Chisnall // Stage 2 - Widen __nar while adding thousands separators 15887a984708SDavid Chisnall char_type __o[2*(__nbuf-1) - 1]; 15897a984708SDavid Chisnall char_type* __ob = __o; 15907a984708SDavid Chisnall unique_ptr<char_type, void(*)(void*)> __obh(0, free); 15917a984708SDavid Chisnall if (__nb != __nar) 15927a984708SDavid Chisnall { 159394e3ee44SDavid Chisnall __ob = (char_type*)malloc(2*static_cast<size_t>(__nc)*sizeof(char_type)); 15947a984708SDavid Chisnall if (__ob == 0) 15957a984708SDavid Chisnall __throw_bad_alloc(); 15967a984708SDavid Chisnall __obh.reset(__ob); 15977a984708SDavid Chisnall } 15987a984708SDavid Chisnall char_type* __op; // pad here 15997a984708SDavid Chisnall char_type* __oe; // end of output 16007a984708SDavid Chisnall this->__widen_and_group_float(__nb, __np, __ne, __ob, __op, __oe, __iob.getloc()); 16017a984708SDavid Chisnall // [__o, __oe) contains thousands_sep'd wide number 16027a984708SDavid Chisnall // Stage 3 & 4 16037a984708SDavid Chisnall __s = __pad_and_output(__s, __ob, __op, __oe, __iob, __fl); 16047a984708SDavid Chisnall return __s; 16057a984708SDavid Chisnall} 16067a984708SDavid Chisnall 16077a984708SDavid Chisnalltemplate <class _CharT, class _OutputIterator> 16087a984708SDavid Chisnall_OutputIterator 16097a984708SDavid Chisnallnum_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, 16107a984708SDavid Chisnall char_type __fl, long double __v) const 16117a984708SDavid Chisnall{ 16127a984708SDavid Chisnall // Stage 1 - Get number in narrow char 16137a984708SDavid Chisnall char __fmt[8] = {'%', 0}; 16147a984708SDavid Chisnall const char* __len = "L"; 16157a984708SDavid Chisnall bool __specify_precision = this->__format_float(__fmt+1, __len, __iob.flags()); 16167a984708SDavid Chisnall const unsigned __nbuf = 30; 16177a984708SDavid Chisnall char __nar[__nbuf]; 16187a984708SDavid Chisnall char* __nb = __nar; 16197a984708SDavid Chisnall int __nc; 16207a984708SDavid Chisnall if (__specify_precision) 16217c82a1ecSDimitry Andric __nc = __libcpp_snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, 16227a984708SDavid Chisnall (int)__iob.precision(), __v); 16237a984708SDavid Chisnall else 16247c82a1ecSDimitry Andric __nc = __libcpp_snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, __v); 16257a984708SDavid Chisnall unique_ptr<char, void(*)(void*)> __nbh(0, free); 16267a984708SDavid Chisnall if (__nc > static_cast<int>(__nbuf-1)) 16277a984708SDavid Chisnall { 16287a984708SDavid Chisnall if (__specify_precision) 16297c82a1ecSDimitry Andric __nc = __libcpp_asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v); 16307a984708SDavid Chisnall else 16317c82a1ecSDimitry Andric __nc = __libcpp_asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, __v); 16327a984708SDavid Chisnall if (__nb == 0) 16337a984708SDavid Chisnall __throw_bad_alloc(); 16347a984708SDavid Chisnall __nbh.reset(__nb); 16357a984708SDavid Chisnall } 16367a984708SDavid Chisnall char* __ne = __nb + __nc; 16377a984708SDavid Chisnall char* __np = this->__identify_padding(__nb, __ne, __iob); 16387a984708SDavid Chisnall // Stage 2 - Widen __nar while adding thousands separators 16397a984708SDavid Chisnall char_type __o[2*(__nbuf-1) - 1]; 16407a984708SDavid Chisnall char_type* __ob = __o; 16417a984708SDavid Chisnall unique_ptr<char_type, void(*)(void*)> __obh(0, free); 16427a984708SDavid Chisnall if (__nb != __nar) 16437a984708SDavid Chisnall { 164494e3ee44SDavid Chisnall __ob = (char_type*)malloc(2*static_cast<size_t>(__nc)*sizeof(char_type)); 16457a984708SDavid Chisnall if (__ob == 0) 16467a984708SDavid Chisnall __throw_bad_alloc(); 16477a984708SDavid Chisnall __obh.reset(__ob); 16487a984708SDavid Chisnall } 16497a984708SDavid Chisnall char_type* __op; // pad here 16507a984708SDavid Chisnall char_type* __oe; // end of output 16517a984708SDavid Chisnall this->__widen_and_group_float(__nb, __np, __ne, __ob, __op, __oe, __iob.getloc()); 16527a984708SDavid Chisnall // [__o, __oe) contains thousands_sep'd wide number 16537a984708SDavid Chisnall // Stage 3 & 4 16547a984708SDavid Chisnall __s = __pad_and_output(__s, __ob, __op, __oe, __iob, __fl); 16557a984708SDavid Chisnall return __s; 16567a984708SDavid Chisnall} 16577a984708SDavid Chisnall 16587a984708SDavid Chisnalltemplate <class _CharT, class _OutputIterator> 16597a984708SDavid Chisnall_OutputIterator 16607a984708SDavid Chisnallnum_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, 16617a984708SDavid Chisnall char_type __fl, const void* __v) const 16627a984708SDavid Chisnall{ 16637a984708SDavid Chisnall // Stage 1 - Get pointer in narrow char 16647a984708SDavid Chisnall char __fmt[6] = "%p"; 16657a984708SDavid Chisnall const unsigned __nbuf = 20; 16667a984708SDavid Chisnall char __nar[__nbuf]; 16677c82a1ecSDimitry Andric int __nc = __libcpp_snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v); 16687a984708SDavid Chisnall char* __ne = __nar + __nc; 16697a984708SDavid Chisnall char* __np = this->__identify_padding(__nar, __ne, __iob); 16707a984708SDavid Chisnall // Stage 2 - Widen __nar 16717a984708SDavid Chisnall char_type __o[2*(__nbuf-1) - 1]; 16727a984708SDavid Chisnall char_type* __op; // pad here 16737a984708SDavid Chisnall char_type* __oe; // end of output 16747a984708SDavid Chisnall const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc()); 16757a984708SDavid Chisnall __ct.widen(__nar, __ne, __o); 16767a984708SDavid Chisnall __oe = __o + (__ne - __nar); 16777a984708SDavid Chisnall if (__np == __ne) 16787a984708SDavid Chisnall __op = __oe; 16797a984708SDavid Chisnall else 16807a984708SDavid Chisnall __op = __o + (__np - __nar); 16817a984708SDavid Chisnall // [__o, __oe) contains wide number 16827a984708SDavid Chisnall // Stage 3 & 4 16837a984708SDavid Chisnall return __pad_and_output(__s, __o, __op, __oe, __iob, __fl); 16847a984708SDavid Chisnall} 16857a984708SDavid Chisnall 1686aed8d94eSDimitry Andric_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS num_put<char>) 1687aed8d94eSDimitry Andric_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS num_put<wchar_t>) 16887a984708SDavid Chisnall 16897a984708SDavid Chisnalltemplate <class _CharT, class _InputIterator> 16907a984708SDavid Chisnall_LIBCPP_HIDDEN 16917a984708SDavid Chisnallint 16927a984708SDavid Chisnall__get_up_to_n_digits(_InputIterator& __b, _InputIterator __e, 16937a984708SDavid Chisnall ios_base::iostate& __err, const ctype<_CharT>& __ct, int __n) 16947a984708SDavid Chisnall{ 16957a984708SDavid Chisnall // Precondition: __n >= 1 16967a984708SDavid Chisnall if (__b == __e) 16977a984708SDavid Chisnall { 16987a984708SDavid Chisnall __err |= ios_base::eofbit | ios_base::failbit; 16997a984708SDavid Chisnall return 0; 17007a984708SDavid Chisnall } 17017a984708SDavid Chisnall // get first digit 17027a984708SDavid Chisnall _CharT __c = *__b; 17037a984708SDavid Chisnall if (!__ct.is(ctype_base::digit, __c)) 17047a984708SDavid Chisnall { 17057a984708SDavid Chisnall __err |= ios_base::failbit; 17067a984708SDavid Chisnall return 0; 17077a984708SDavid Chisnall } 17087a984708SDavid Chisnall int __r = __ct.narrow(__c, 0) - '0'; 1709d72607e9SDimitry Andric for (++__b, (void) --__n; __b != __e && __n > 0; ++__b, (void) --__n) 17107a984708SDavid Chisnall { 17117a984708SDavid Chisnall // get next digit 17127a984708SDavid Chisnall __c = *__b; 17137a984708SDavid Chisnall if (!__ct.is(ctype_base::digit, __c)) 17147a984708SDavid Chisnall return __r; 17157a984708SDavid Chisnall __r = __r * 10 + __ct.narrow(__c, 0) - '0'; 17167a984708SDavid Chisnall } 17177a984708SDavid Chisnall if (__b == __e) 17187a984708SDavid Chisnall __err |= ios_base::eofbit; 17197a984708SDavid Chisnall return __r; 17207a984708SDavid Chisnall} 17217a984708SDavid Chisnall 17221bf9f7c1SDimitry Andricclass _LIBCPP_TYPE_VIS time_base 17237a984708SDavid Chisnall{ 17247a984708SDavid Chisnallpublic: 17257a984708SDavid Chisnall enum dateorder {no_order, dmy, mdy, ymd, ydm}; 17267a984708SDavid Chisnall}; 17277a984708SDavid Chisnall 17287a984708SDavid Chisnalltemplate <class _CharT> 1729aed8d94eSDimitry Andricclass _LIBCPP_TEMPLATE_VIS __time_get_c_storage 17307a984708SDavid Chisnall{ 17317a984708SDavid Chisnallprotected: 17327a984708SDavid Chisnall typedef basic_string<_CharT> string_type; 17337a984708SDavid Chisnall 17347a984708SDavid Chisnall virtual const string_type* __weeks() const; 17357a984708SDavid Chisnall virtual const string_type* __months() const; 17367a984708SDavid Chisnall virtual const string_type* __am_pm() const; 17377a984708SDavid Chisnall virtual const string_type& __c() const; 17387a984708SDavid Chisnall virtual const string_type& __r() const; 17397a984708SDavid Chisnall virtual const string_type& __x() const; 17407a984708SDavid Chisnall virtual const string_type& __X() const; 17419729cf09SDimitry Andric 17424ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 17439729cf09SDimitry Andric ~__time_get_c_storage() {} 17447a984708SDavid Chisnall}; 17457a984708SDavid Chisnall 17460f5676f4SDimitry Andrictemplate <> _LIBCPP_FUNC_VIS const string* __time_get_c_storage<char>::__weeks() const; 17470f5676f4SDimitry Andrictemplate <> _LIBCPP_FUNC_VIS const string* __time_get_c_storage<char>::__months() const; 17480f5676f4SDimitry Andrictemplate <> _LIBCPP_FUNC_VIS const string* __time_get_c_storage<char>::__am_pm() const; 17490f5676f4SDimitry Andrictemplate <> _LIBCPP_FUNC_VIS const string& __time_get_c_storage<char>::__c() const; 17500f5676f4SDimitry Andrictemplate <> _LIBCPP_FUNC_VIS const string& __time_get_c_storage<char>::__r() const; 17510f5676f4SDimitry Andrictemplate <> _LIBCPP_FUNC_VIS const string& __time_get_c_storage<char>::__x() const; 17520f5676f4SDimitry Andrictemplate <> _LIBCPP_FUNC_VIS const string& __time_get_c_storage<char>::__X() const; 17530f5676f4SDimitry Andric 17540f5676f4SDimitry Andrictemplate <> _LIBCPP_FUNC_VIS const wstring* __time_get_c_storage<wchar_t>::__weeks() const; 17550f5676f4SDimitry Andrictemplate <> _LIBCPP_FUNC_VIS const wstring* __time_get_c_storage<wchar_t>::__months() const; 17560f5676f4SDimitry Andrictemplate <> _LIBCPP_FUNC_VIS const wstring* __time_get_c_storage<wchar_t>::__am_pm() const; 17570f5676f4SDimitry Andrictemplate <> _LIBCPP_FUNC_VIS const wstring& __time_get_c_storage<wchar_t>::__c() const; 17580f5676f4SDimitry Andrictemplate <> _LIBCPP_FUNC_VIS const wstring& __time_get_c_storage<wchar_t>::__r() const; 17590f5676f4SDimitry Andrictemplate <> _LIBCPP_FUNC_VIS const wstring& __time_get_c_storage<wchar_t>::__x() const; 17600f5676f4SDimitry Andrictemplate <> _LIBCPP_FUNC_VIS const wstring& __time_get_c_storage<wchar_t>::__X() const; 17610f5676f4SDimitry Andric 17627a984708SDavid Chisnalltemplate <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> > 1763aed8d94eSDimitry Andricclass _LIBCPP_TEMPLATE_VIS time_get 17647a984708SDavid Chisnall : public locale::facet, 17657a984708SDavid Chisnall public time_base, 17667a984708SDavid Chisnall private __time_get_c_storage<_CharT> 17677a984708SDavid Chisnall{ 17687a984708SDavid Chisnallpublic: 17697a984708SDavid Chisnall typedef _CharT char_type; 17707a984708SDavid Chisnall typedef _InputIterator iter_type; 17717a984708SDavid Chisnall typedef time_base::dateorder dateorder; 17727a984708SDavid Chisnall typedef basic_string<char_type> string_type; 17737a984708SDavid Chisnall 17744ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 17757a984708SDavid Chisnall explicit time_get(size_t __refs = 0) 17767a984708SDavid Chisnall : locale::facet(__refs) {} 17777a984708SDavid Chisnall 17784ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 17797a984708SDavid Chisnall dateorder date_order() const 17807a984708SDavid Chisnall { 17817a984708SDavid Chisnall return this->do_date_order(); 17827a984708SDavid Chisnall } 17837a984708SDavid Chisnall 17844ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 17857a984708SDavid Chisnall iter_type get_time(iter_type __b, iter_type __e, ios_base& __iob, 17867a984708SDavid Chisnall ios_base::iostate& __err, tm* __tm) const 17877a984708SDavid Chisnall { 17887a984708SDavid Chisnall return do_get_time(__b, __e, __iob, __err, __tm); 17897a984708SDavid Chisnall } 17907a984708SDavid Chisnall 17914ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 17927a984708SDavid Chisnall iter_type get_date(iter_type __b, iter_type __e, ios_base& __iob, 17937a984708SDavid Chisnall ios_base::iostate& __err, tm* __tm) const 17947a984708SDavid Chisnall { 17957a984708SDavid Chisnall return do_get_date(__b, __e, __iob, __err, __tm); 17967a984708SDavid Chisnall } 17977a984708SDavid Chisnall 17984ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 17997a984708SDavid Chisnall iter_type get_weekday(iter_type __b, iter_type __e, ios_base& __iob, 18007a984708SDavid Chisnall ios_base::iostate& __err, tm* __tm) const 18017a984708SDavid Chisnall { 18027a984708SDavid Chisnall return do_get_weekday(__b, __e, __iob, __err, __tm); 18037a984708SDavid Chisnall } 18047a984708SDavid Chisnall 18054ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 18067a984708SDavid Chisnall iter_type get_monthname(iter_type __b, iter_type __e, ios_base& __iob, 18077a984708SDavid Chisnall ios_base::iostate& __err, tm* __tm) const 18087a984708SDavid Chisnall { 18097a984708SDavid Chisnall return do_get_monthname(__b, __e, __iob, __err, __tm); 18107a984708SDavid Chisnall } 18117a984708SDavid Chisnall 18124ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 18137a984708SDavid Chisnall iter_type get_year(iter_type __b, iter_type __e, ios_base& __iob, 18147a984708SDavid Chisnall ios_base::iostate& __err, tm* __tm) const 18157a984708SDavid Chisnall { 18167a984708SDavid Chisnall return do_get_year(__b, __e, __iob, __err, __tm); 18177a984708SDavid Chisnall } 18187a984708SDavid Chisnall 18194ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 18207a984708SDavid Chisnall iter_type get(iter_type __b, iter_type __e, ios_base& __iob, 18217a984708SDavid Chisnall ios_base::iostate& __err, tm *__tm, 18227a984708SDavid Chisnall char __fmt, char __mod = 0) const 18237a984708SDavid Chisnall { 18247a984708SDavid Chisnall return do_get(__b, __e, __iob, __err, __tm, __fmt, __mod); 18257a984708SDavid Chisnall } 18267a984708SDavid Chisnall 18277a984708SDavid Chisnall iter_type get(iter_type __b, iter_type __e, ios_base& __iob, 18287a984708SDavid Chisnall ios_base::iostate& __err, tm* __tm, 18297a984708SDavid Chisnall const char_type* __fmtb, const char_type* __fmte) const; 18307a984708SDavid Chisnall 18317a984708SDavid Chisnall static locale::id id; 18327a984708SDavid Chisnall 18337a984708SDavid Chisnallprotected: 18344ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 18357a984708SDavid Chisnall ~time_get() {} 18367a984708SDavid Chisnall 18377a984708SDavid Chisnall virtual dateorder do_date_order() const; 18387a984708SDavid Chisnall virtual iter_type do_get_time(iter_type __b, iter_type __e, ios_base& __iob, 18397a984708SDavid Chisnall ios_base::iostate& __err, tm* __tm) const; 18407a984708SDavid Chisnall virtual iter_type do_get_date(iter_type __b, iter_type __e, ios_base& __iob, 18417a984708SDavid Chisnall ios_base::iostate& __err, tm* __tm) const; 18427a984708SDavid Chisnall virtual iter_type do_get_weekday(iter_type __b, iter_type __e, ios_base& __iob, 18437a984708SDavid Chisnall ios_base::iostate& __err, tm* __tm) const; 18447a984708SDavid Chisnall virtual iter_type do_get_monthname(iter_type __b, iter_type __e, ios_base& __iob, 18457a984708SDavid Chisnall ios_base::iostate& __err, tm* __tm) const; 18467a984708SDavid Chisnall virtual iter_type do_get_year(iter_type __b, iter_type __e, ios_base& __iob, 18477a984708SDavid Chisnall ios_base::iostate& __err, tm* __tm) const; 18487a984708SDavid Chisnall virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob, 18497a984708SDavid Chisnall ios_base::iostate& __err, tm* __tm, 18507a984708SDavid Chisnall char __fmt, char __mod) const; 18517a984708SDavid Chisnallprivate: 18527a984708SDavid Chisnall void __get_white_space(iter_type& __b, iter_type __e, 18537a984708SDavid Chisnall ios_base::iostate& __err, const ctype<char_type>& __ct) const; 18547a984708SDavid Chisnall void __get_percent(iter_type& __b, iter_type __e, ios_base::iostate& __err, 18557a984708SDavid Chisnall const ctype<char_type>& __ct) const; 18567a984708SDavid Chisnall 18577a984708SDavid Chisnall void __get_weekdayname(int& __m, 18587a984708SDavid Chisnall iter_type& __b, iter_type __e, 18597a984708SDavid Chisnall ios_base::iostate& __err, 18607a984708SDavid Chisnall const ctype<char_type>& __ct) const; 18617a984708SDavid Chisnall void __get_monthname(int& __m, 18627a984708SDavid Chisnall iter_type& __b, iter_type __e, 18637a984708SDavid Chisnall ios_base::iostate& __err, 18647a984708SDavid Chisnall const ctype<char_type>& __ct) const; 18657a984708SDavid Chisnall void __get_day(int& __d, 18667a984708SDavid Chisnall iter_type& __b, iter_type __e, 18677a984708SDavid Chisnall ios_base::iostate& __err, 18687a984708SDavid Chisnall const ctype<char_type>& __ct) const; 18697a984708SDavid Chisnall void __get_month(int& __m, 18707a984708SDavid Chisnall iter_type& __b, iter_type __e, 18717a984708SDavid Chisnall ios_base::iostate& __err, 18727a984708SDavid Chisnall const ctype<char_type>& __ct) const; 18737a984708SDavid Chisnall void __get_year(int& __y, 18747a984708SDavid Chisnall iter_type& __b, iter_type __e, 18757a984708SDavid Chisnall ios_base::iostate& __err, 18767a984708SDavid Chisnall const ctype<char_type>& __ct) const; 18777a984708SDavid Chisnall void __get_year4(int& __y, 18787a984708SDavid Chisnall iter_type& __b, iter_type __e, 18797a984708SDavid Chisnall ios_base::iostate& __err, 18807a984708SDavid Chisnall const ctype<char_type>& __ct) const; 18817a984708SDavid Chisnall void __get_hour(int& __d, 18827a984708SDavid Chisnall iter_type& __b, iter_type __e, 18837a984708SDavid Chisnall ios_base::iostate& __err, 18847a984708SDavid Chisnall const ctype<char_type>& __ct) const; 18857a984708SDavid Chisnall void __get_12_hour(int& __h, 18867a984708SDavid Chisnall iter_type& __b, iter_type __e, 18877a984708SDavid Chisnall ios_base::iostate& __err, 18887a984708SDavid Chisnall const ctype<char_type>& __ct) const; 18897a984708SDavid Chisnall void __get_am_pm(int& __h, 18907a984708SDavid Chisnall iter_type& __b, iter_type __e, 18917a984708SDavid Chisnall ios_base::iostate& __err, 18927a984708SDavid Chisnall const ctype<char_type>& __ct) const; 18937a984708SDavid Chisnall void __get_minute(int& __m, 18947a984708SDavid Chisnall iter_type& __b, iter_type __e, 18957a984708SDavid Chisnall ios_base::iostate& __err, 18967a984708SDavid Chisnall const ctype<char_type>& __ct) const; 18977a984708SDavid Chisnall void __get_second(int& __s, 18987a984708SDavid Chisnall iter_type& __b, iter_type __e, 18997a984708SDavid Chisnall ios_base::iostate& __err, 19007a984708SDavid Chisnall const ctype<char_type>& __ct) const; 19017a984708SDavid Chisnall void __get_weekday(int& __w, 19027a984708SDavid Chisnall iter_type& __b, iter_type __e, 19037a984708SDavid Chisnall ios_base::iostate& __err, 19047a984708SDavid Chisnall const ctype<char_type>& __ct) const; 19057a984708SDavid Chisnall void __get_day_year_num(int& __w, 19067a984708SDavid Chisnall iter_type& __b, iter_type __e, 19077a984708SDavid Chisnall ios_base::iostate& __err, 19087a984708SDavid Chisnall const ctype<char_type>& __ct) const; 19097a984708SDavid Chisnall}; 19107a984708SDavid Chisnall 19117a984708SDavid Chisnalltemplate <class _CharT, class _InputIterator> 19127a984708SDavid Chisnalllocale::id 19137a984708SDavid Chisnalltime_get<_CharT, _InputIterator>::id; 19147a984708SDavid Chisnall 1915d72607e9SDimitry Andric// time_get primitives 19167a984708SDavid Chisnall 19177a984708SDavid Chisnalltemplate <class _CharT, class _InputIterator> 19187a984708SDavid Chisnallvoid 19197a984708SDavid Chisnalltime_get<_CharT, _InputIterator>::__get_weekdayname(int& __w, 19207a984708SDavid Chisnall iter_type& __b, iter_type __e, 19217a984708SDavid Chisnall ios_base::iostate& __err, 19227a984708SDavid Chisnall const ctype<char_type>& __ct) const 19237a984708SDavid Chisnall{ 19247a984708SDavid Chisnall // Note: ignoring case comes from the POSIX strptime spec 19257a984708SDavid Chisnall const string_type* __wk = this->__weeks(); 192694e3ee44SDavid Chisnall ptrdiff_t __i = __scan_keyword(__b, __e, __wk, __wk+14, __ct, __err, false) - __wk; 19277a984708SDavid Chisnall if (__i < 14) 19287a984708SDavid Chisnall __w = __i % 7; 19297a984708SDavid Chisnall} 19307a984708SDavid Chisnall 19317a984708SDavid Chisnalltemplate <class _CharT, class _InputIterator> 19327a984708SDavid Chisnallvoid 19337a984708SDavid Chisnalltime_get<_CharT, _InputIterator>::__get_monthname(int& __m, 19347a984708SDavid Chisnall iter_type& __b, iter_type __e, 19357a984708SDavid Chisnall ios_base::iostate& __err, 19367a984708SDavid Chisnall const ctype<char_type>& __ct) const 19377a984708SDavid Chisnall{ 19387a984708SDavid Chisnall // Note: ignoring case comes from the POSIX strptime spec 19397a984708SDavid Chisnall const string_type* __month = this->__months(); 194094e3ee44SDavid Chisnall ptrdiff_t __i = __scan_keyword(__b, __e, __month, __month+24, __ct, __err, false) - __month; 19417a984708SDavid Chisnall if (__i < 24) 19427a984708SDavid Chisnall __m = __i % 12; 19437a984708SDavid Chisnall} 19447a984708SDavid Chisnall 19457a984708SDavid Chisnalltemplate <class _CharT, class _InputIterator> 19467a984708SDavid Chisnallvoid 19477a984708SDavid Chisnalltime_get<_CharT, _InputIterator>::__get_day(int& __d, 19487a984708SDavid Chisnall iter_type& __b, iter_type __e, 19497a984708SDavid Chisnall ios_base::iostate& __err, 19507a984708SDavid Chisnall const ctype<char_type>& __ct) const 19517a984708SDavid Chisnall{ 19527a984708SDavid Chisnall int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2); 19537a984708SDavid Chisnall if (!(__err & ios_base::failbit) && 1 <= __t && __t <= 31) 19547a984708SDavid Chisnall __d = __t; 19557a984708SDavid Chisnall else 19567a984708SDavid Chisnall __err |= ios_base::failbit; 19577a984708SDavid Chisnall} 19587a984708SDavid Chisnall 19597a984708SDavid Chisnalltemplate <class _CharT, class _InputIterator> 19607a984708SDavid Chisnallvoid 19617a984708SDavid Chisnalltime_get<_CharT, _InputIterator>::__get_month(int& __m, 19627a984708SDavid Chisnall iter_type& __b, iter_type __e, 19637a984708SDavid Chisnall ios_base::iostate& __err, 19647a984708SDavid Chisnall const ctype<char_type>& __ct) const 19657a984708SDavid Chisnall{ 19667a984708SDavid Chisnall int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2) - 1; 19677a984708SDavid Chisnall if (!(__err & ios_base::failbit) && __t <= 11) 19687a984708SDavid Chisnall __m = __t; 19697a984708SDavid Chisnall else 19707a984708SDavid Chisnall __err |= ios_base::failbit; 19717a984708SDavid Chisnall} 19727a984708SDavid Chisnall 19737a984708SDavid Chisnalltemplate <class _CharT, class _InputIterator> 19747a984708SDavid Chisnallvoid 19757a984708SDavid Chisnalltime_get<_CharT, _InputIterator>::__get_year(int& __y, 19767a984708SDavid Chisnall iter_type& __b, iter_type __e, 19777a984708SDavid Chisnall ios_base::iostate& __err, 19787a984708SDavid Chisnall const ctype<char_type>& __ct) const 19797a984708SDavid Chisnall{ 19807a984708SDavid Chisnall int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 4); 19817a984708SDavid Chisnall if (!(__err & ios_base::failbit)) 19827a984708SDavid Chisnall { 19837a984708SDavid Chisnall if (__t < 69) 19847a984708SDavid Chisnall __t += 2000; 19857a984708SDavid Chisnall else if (69 <= __t && __t <= 99) 19867a984708SDavid Chisnall __t += 1900; 19877a984708SDavid Chisnall __y = __t - 1900; 19887a984708SDavid Chisnall } 19897a984708SDavid Chisnall} 19907a984708SDavid Chisnall 19917a984708SDavid Chisnalltemplate <class _CharT, class _InputIterator> 19927a984708SDavid Chisnallvoid 19937a984708SDavid Chisnalltime_get<_CharT, _InputIterator>::__get_year4(int& __y, 19947a984708SDavid Chisnall iter_type& __b, iter_type __e, 19957a984708SDavid Chisnall ios_base::iostate& __err, 19967a984708SDavid Chisnall const ctype<char_type>& __ct) const 19977a984708SDavid Chisnall{ 19987a984708SDavid Chisnall int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 4); 19997a984708SDavid Chisnall if (!(__err & ios_base::failbit)) 20007a984708SDavid Chisnall __y = __t - 1900; 20017a984708SDavid Chisnall} 20027a984708SDavid Chisnall 20037a984708SDavid Chisnalltemplate <class _CharT, class _InputIterator> 20047a984708SDavid Chisnallvoid 20057a984708SDavid Chisnalltime_get<_CharT, _InputIterator>::__get_hour(int& __h, 20067a984708SDavid Chisnall iter_type& __b, iter_type __e, 20077a984708SDavid Chisnall ios_base::iostate& __err, 20087a984708SDavid Chisnall const ctype<char_type>& __ct) const 20097a984708SDavid Chisnall{ 20107a984708SDavid Chisnall int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2); 20117a984708SDavid Chisnall if (!(__err & ios_base::failbit) && __t <= 23) 20127a984708SDavid Chisnall __h = __t; 20137a984708SDavid Chisnall else 20147a984708SDavid Chisnall __err |= ios_base::failbit; 20157a984708SDavid Chisnall} 20167a984708SDavid Chisnall 20177a984708SDavid Chisnalltemplate <class _CharT, class _InputIterator> 20187a984708SDavid Chisnallvoid 20197a984708SDavid Chisnalltime_get<_CharT, _InputIterator>::__get_12_hour(int& __h, 20207a984708SDavid Chisnall iter_type& __b, iter_type __e, 20217a984708SDavid Chisnall ios_base::iostate& __err, 20227a984708SDavid Chisnall const ctype<char_type>& __ct) const 20237a984708SDavid Chisnall{ 20247a984708SDavid Chisnall int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2); 20257a984708SDavid Chisnall if (!(__err & ios_base::failbit) && 1 <= __t && __t <= 12) 20267a984708SDavid Chisnall __h = __t; 20277a984708SDavid Chisnall else 20287a984708SDavid Chisnall __err |= ios_base::failbit; 20297a984708SDavid Chisnall} 20307a984708SDavid Chisnall 20317a984708SDavid Chisnalltemplate <class _CharT, class _InputIterator> 20327a984708SDavid Chisnallvoid 20337a984708SDavid Chisnalltime_get<_CharT, _InputIterator>::__get_minute(int& __m, 20347a984708SDavid Chisnall iter_type& __b, iter_type __e, 20357a984708SDavid Chisnall ios_base::iostate& __err, 20367a984708SDavid Chisnall const ctype<char_type>& __ct) const 20377a984708SDavid Chisnall{ 20387a984708SDavid Chisnall int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2); 20397a984708SDavid Chisnall if (!(__err & ios_base::failbit) && __t <= 59) 20407a984708SDavid Chisnall __m = __t; 20417a984708SDavid Chisnall else 20427a984708SDavid Chisnall __err |= ios_base::failbit; 20437a984708SDavid Chisnall} 20447a984708SDavid Chisnall 20457a984708SDavid Chisnalltemplate <class _CharT, class _InputIterator> 20467a984708SDavid Chisnallvoid 20477a984708SDavid Chisnalltime_get<_CharT, _InputIterator>::__get_second(int& __s, 20487a984708SDavid Chisnall iter_type& __b, iter_type __e, 20497a984708SDavid Chisnall ios_base::iostate& __err, 20507a984708SDavid Chisnall const ctype<char_type>& __ct) const 20517a984708SDavid Chisnall{ 20527a984708SDavid Chisnall int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2); 20537a984708SDavid Chisnall if (!(__err & ios_base::failbit) && __t <= 60) 20547a984708SDavid Chisnall __s = __t; 20557a984708SDavid Chisnall else 20567a984708SDavid Chisnall __err |= ios_base::failbit; 20577a984708SDavid Chisnall} 20587a984708SDavid Chisnall 20597a984708SDavid Chisnalltemplate <class _CharT, class _InputIterator> 20607a984708SDavid Chisnallvoid 20617a984708SDavid Chisnalltime_get<_CharT, _InputIterator>::__get_weekday(int& __w, 20627a984708SDavid Chisnall iter_type& __b, iter_type __e, 20637a984708SDavid Chisnall ios_base::iostate& __err, 20647a984708SDavid Chisnall const ctype<char_type>& __ct) const 20657a984708SDavid Chisnall{ 20667a984708SDavid Chisnall int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 1); 20677a984708SDavid Chisnall if (!(__err & ios_base::failbit) && __t <= 6) 20687a984708SDavid Chisnall __w = __t; 20697a984708SDavid Chisnall else 20707a984708SDavid Chisnall __err |= ios_base::failbit; 20717a984708SDavid Chisnall} 20727a984708SDavid Chisnall 20737a984708SDavid Chisnalltemplate <class _CharT, class _InputIterator> 20747a984708SDavid Chisnallvoid 20757a984708SDavid Chisnalltime_get<_CharT, _InputIterator>::__get_day_year_num(int& __d, 20767a984708SDavid Chisnall iter_type& __b, iter_type __e, 20777a984708SDavid Chisnall ios_base::iostate& __err, 20787a984708SDavid Chisnall const ctype<char_type>& __ct) const 20797a984708SDavid Chisnall{ 20807a984708SDavid Chisnall int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 3); 20817a984708SDavid Chisnall if (!(__err & ios_base::failbit) && __t <= 365) 20827a984708SDavid Chisnall __d = __t; 20837a984708SDavid Chisnall else 20847a984708SDavid Chisnall __err |= ios_base::failbit; 20857a984708SDavid Chisnall} 20867a984708SDavid Chisnall 20877a984708SDavid Chisnalltemplate <class _CharT, class _InputIterator> 20887a984708SDavid Chisnallvoid 20897a984708SDavid Chisnalltime_get<_CharT, _InputIterator>::__get_white_space(iter_type& __b, iter_type __e, 20907a984708SDavid Chisnall ios_base::iostate& __err, 20917a984708SDavid Chisnall const ctype<char_type>& __ct) const 20927a984708SDavid Chisnall{ 20937a984708SDavid Chisnall for (; __b != __e && __ct.is(ctype_base::space, *__b); ++__b) 20947a984708SDavid Chisnall ; 20957a984708SDavid Chisnall if (__b == __e) 20967a984708SDavid Chisnall __err |= ios_base::eofbit; 20977a984708SDavid Chisnall} 20987a984708SDavid Chisnall 20997a984708SDavid Chisnalltemplate <class _CharT, class _InputIterator> 21007a984708SDavid Chisnallvoid 21017a984708SDavid Chisnalltime_get<_CharT, _InputIterator>::__get_am_pm(int& __h, 21027a984708SDavid Chisnall iter_type& __b, iter_type __e, 21037a984708SDavid Chisnall ios_base::iostate& __err, 21047a984708SDavid Chisnall const ctype<char_type>& __ct) const 21057a984708SDavid Chisnall{ 21067a984708SDavid Chisnall const string_type* __ap = this->__am_pm(); 21077a984708SDavid Chisnall if (__ap[0].size() + __ap[1].size() == 0) 21087a984708SDavid Chisnall { 21097a984708SDavid Chisnall __err |= ios_base::failbit; 21107a984708SDavid Chisnall return; 21117a984708SDavid Chisnall } 211294e3ee44SDavid Chisnall ptrdiff_t __i = __scan_keyword(__b, __e, __ap, __ap+2, __ct, __err, false) - __ap; 21137a984708SDavid Chisnall if (__i == 0 && __h == 12) 21147a984708SDavid Chisnall __h = 0; 21157a984708SDavid Chisnall else if (__i == 1 && __h < 12) 21167a984708SDavid Chisnall __h += 12; 21177a984708SDavid Chisnall} 21187a984708SDavid Chisnall 21197a984708SDavid Chisnalltemplate <class _CharT, class _InputIterator> 21207a984708SDavid Chisnallvoid 21217a984708SDavid Chisnalltime_get<_CharT, _InputIterator>::__get_percent(iter_type& __b, iter_type __e, 21227a984708SDavid Chisnall ios_base::iostate& __err, 21237a984708SDavid Chisnall const ctype<char_type>& __ct) const 21247a984708SDavid Chisnall{ 21257a984708SDavid Chisnall if (__b == __e) 21267a984708SDavid Chisnall { 21277a984708SDavid Chisnall __err |= ios_base::eofbit | ios_base::failbit; 21287a984708SDavid Chisnall return; 21297a984708SDavid Chisnall } 21307a984708SDavid Chisnall if (__ct.narrow(*__b, 0) != '%') 21317a984708SDavid Chisnall __err |= ios_base::failbit; 21327a984708SDavid Chisnall else if(++__b == __e) 21337a984708SDavid Chisnall __err |= ios_base::eofbit; 21347a984708SDavid Chisnall} 21357a984708SDavid Chisnall 2136d72607e9SDimitry Andric// time_get end primitives 21377a984708SDavid Chisnall 21387a984708SDavid Chisnalltemplate <class _CharT, class _InputIterator> 21397a984708SDavid Chisnall_InputIterator 21407a984708SDavid Chisnalltime_get<_CharT, _InputIterator>::get(iter_type __b, iter_type __e, 21417a984708SDavid Chisnall ios_base& __iob, 21427a984708SDavid Chisnall ios_base::iostate& __err, tm* __tm, 21437a984708SDavid Chisnall const char_type* __fmtb, const char_type* __fmte) const 21447a984708SDavid Chisnall{ 21457a984708SDavid Chisnall const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc()); 21467a984708SDavid Chisnall __err = ios_base::goodbit; 21477a984708SDavid Chisnall while (__fmtb != __fmte && __err == ios_base::goodbit) 21487a984708SDavid Chisnall { 21497a984708SDavid Chisnall if (__b == __e) 21507a984708SDavid Chisnall { 21517a984708SDavid Chisnall __err = ios_base::failbit; 21527a984708SDavid Chisnall break; 21537a984708SDavid Chisnall } 21547a984708SDavid Chisnall if (__ct.narrow(*__fmtb, 0) == '%') 21557a984708SDavid Chisnall { 21567a984708SDavid Chisnall if (++__fmtb == __fmte) 21577a984708SDavid Chisnall { 21587a984708SDavid Chisnall __err = ios_base::failbit; 21597a984708SDavid Chisnall break; 21607a984708SDavid Chisnall } 21617a984708SDavid Chisnall char __cmd = __ct.narrow(*__fmtb, 0); 21627a984708SDavid Chisnall char __opt = '\0'; 21637a984708SDavid Chisnall if (__cmd == 'E' || __cmd == '0') 21647a984708SDavid Chisnall { 21657a984708SDavid Chisnall if (++__fmtb == __fmte) 21667a984708SDavid Chisnall { 21677a984708SDavid Chisnall __err = ios_base::failbit; 21687a984708SDavid Chisnall break; 21697a984708SDavid Chisnall } 21707a984708SDavid Chisnall __opt = __cmd; 21717a984708SDavid Chisnall __cmd = __ct.narrow(*__fmtb, 0); 21727a984708SDavid Chisnall } 21737a984708SDavid Chisnall __b = do_get(__b, __e, __iob, __err, __tm, __cmd, __opt); 21747a984708SDavid Chisnall ++__fmtb; 21757a984708SDavid Chisnall } 21767a984708SDavid Chisnall else if (__ct.is(ctype_base::space, *__fmtb)) 21777a984708SDavid Chisnall { 21787a984708SDavid Chisnall for (++__fmtb; __fmtb != __fmte && __ct.is(ctype_base::space, *__fmtb); ++__fmtb) 21797a984708SDavid Chisnall ; 21807a984708SDavid Chisnall for ( ; __b != __e && __ct.is(ctype_base::space, *__b); ++__b) 21817a984708SDavid Chisnall ; 21827a984708SDavid Chisnall } 21837a984708SDavid Chisnall else if (__ct.toupper(*__b) == __ct.toupper(*__fmtb)) 21847a984708SDavid Chisnall { 21857a984708SDavid Chisnall ++__b; 21867a984708SDavid Chisnall ++__fmtb; 21877a984708SDavid Chisnall } 21887a984708SDavid Chisnall else 21897a984708SDavid Chisnall __err = ios_base::failbit; 21907a984708SDavid Chisnall } 21917a984708SDavid Chisnall if (__b == __e) 21927a984708SDavid Chisnall __err |= ios_base::eofbit; 21937a984708SDavid Chisnall return __b; 21947a984708SDavid Chisnall} 21957a984708SDavid Chisnall 21967a984708SDavid Chisnalltemplate <class _CharT, class _InputIterator> 21977a984708SDavid Chisnalltypename time_get<_CharT, _InputIterator>::dateorder 21987a984708SDavid Chisnalltime_get<_CharT, _InputIterator>::do_date_order() const 21997a984708SDavid Chisnall{ 22007a984708SDavid Chisnall return mdy; 22017a984708SDavid Chisnall} 22027a984708SDavid Chisnall 22037a984708SDavid Chisnalltemplate <class _CharT, class _InputIterator> 22047a984708SDavid Chisnall_InputIterator 22057a984708SDavid Chisnalltime_get<_CharT, _InputIterator>::do_get_time(iter_type __b, iter_type __e, 22067a984708SDavid Chisnall ios_base& __iob, 22077a984708SDavid Chisnall ios_base::iostate& __err, 22087a984708SDavid Chisnall tm* __tm) const 22097a984708SDavid Chisnall{ 22107a984708SDavid Chisnall const char_type __fmt[] = {'%', 'H', ':', '%', 'M', ':', '%', 'S'}; 22117a984708SDavid Chisnall return get(__b, __e, __iob, __err, __tm, __fmt, __fmt + sizeof(__fmt)/sizeof(__fmt[0])); 22127a984708SDavid Chisnall} 22137a984708SDavid Chisnall 22147a984708SDavid Chisnalltemplate <class _CharT, class _InputIterator> 22157a984708SDavid Chisnall_InputIterator 22167a984708SDavid Chisnalltime_get<_CharT, _InputIterator>::do_get_date(iter_type __b, iter_type __e, 22177a984708SDavid Chisnall ios_base& __iob, 22187a984708SDavid Chisnall ios_base::iostate& __err, 22197a984708SDavid Chisnall tm* __tm) const 22207a984708SDavid Chisnall{ 22217a984708SDavid Chisnall const string_type& __fmt = this->__x(); 22227a984708SDavid Chisnall return get(__b, __e, __iob, __err, __tm, __fmt.data(), __fmt.data() + __fmt.size()); 22237a984708SDavid Chisnall} 22247a984708SDavid Chisnall 22257a984708SDavid Chisnalltemplate <class _CharT, class _InputIterator> 22267a984708SDavid Chisnall_InputIterator 22277a984708SDavid Chisnalltime_get<_CharT, _InputIterator>::do_get_weekday(iter_type __b, iter_type __e, 22287a984708SDavid Chisnall ios_base& __iob, 22297a984708SDavid Chisnall ios_base::iostate& __err, 22307a984708SDavid Chisnall tm* __tm) const 22317a984708SDavid Chisnall{ 22327a984708SDavid Chisnall const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc()); 22337a984708SDavid Chisnall __get_weekdayname(__tm->tm_wday, __b, __e, __err, __ct); 22347a984708SDavid Chisnall return __b; 22357a984708SDavid Chisnall} 22367a984708SDavid Chisnall 22377a984708SDavid Chisnalltemplate <class _CharT, class _InputIterator> 22387a984708SDavid Chisnall_InputIterator 22397a984708SDavid Chisnalltime_get<_CharT, _InputIterator>::do_get_monthname(iter_type __b, iter_type __e, 22407a984708SDavid Chisnall ios_base& __iob, 22417a984708SDavid Chisnall ios_base::iostate& __err, 22427a984708SDavid Chisnall tm* __tm) const 22437a984708SDavid Chisnall{ 22447a984708SDavid Chisnall const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc()); 22457a984708SDavid Chisnall __get_monthname(__tm->tm_mon, __b, __e, __err, __ct); 22467a984708SDavid Chisnall return __b; 22477a984708SDavid Chisnall} 22487a984708SDavid Chisnall 22497a984708SDavid Chisnalltemplate <class _CharT, class _InputIterator> 22507a984708SDavid Chisnall_InputIterator 22517a984708SDavid Chisnalltime_get<_CharT, _InputIterator>::do_get_year(iter_type __b, iter_type __e, 22527a984708SDavid Chisnall ios_base& __iob, 22537a984708SDavid Chisnall ios_base::iostate& __err, 22547a984708SDavid Chisnall tm* __tm) const 22557a984708SDavid Chisnall{ 22567a984708SDavid Chisnall const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc()); 22577a984708SDavid Chisnall __get_year(__tm->tm_year, __b, __e, __err, __ct); 22587a984708SDavid Chisnall return __b; 22597a984708SDavid Chisnall} 22607a984708SDavid Chisnall 22617a984708SDavid Chisnalltemplate <class _CharT, class _InputIterator> 22627a984708SDavid Chisnall_InputIterator 22637a984708SDavid Chisnalltime_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e, 22647a984708SDavid Chisnall ios_base& __iob, 22657a984708SDavid Chisnall ios_base::iostate& __err, tm* __tm, 22667a984708SDavid Chisnall char __fmt, char) const 22677a984708SDavid Chisnall{ 22687a984708SDavid Chisnall __err = ios_base::goodbit; 22697a984708SDavid Chisnall const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc()); 22707a984708SDavid Chisnall switch (__fmt) 22717a984708SDavid Chisnall { 22727a984708SDavid Chisnall case 'a': 22737a984708SDavid Chisnall case 'A': 22747a984708SDavid Chisnall __get_weekdayname(__tm->tm_wday, __b, __e, __err, __ct); 22757a984708SDavid Chisnall break; 22767a984708SDavid Chisnall case 'b': 22777a984708SDavid Chisnall case 'B': 22787a984708SDavid Chisnall case 'h': 22797a984708SDavid Chisnall __get_monthname(__tm->tm_mon, __b, __e, __err, __ct); 22807a984708SDavid Chisnall break; 22817a984708SDavid Chisnall case 'c': 22827a984708SDavid Chisnall { 228394e3ee44SDavid Chisnall const string_type& __fm = this->__c(); 228494e3ee44SDavid Chisnall __b = get(__b, __e, __iob, __err, __tm, __fm.data(), __fm.data() + __fm.size()); 22857a984708SDavid Chisnall } 22867a984708SDavid Chisnall break; 22877a984708SDavid Chisnall case 'd': 22887a984708SDavid Chisnall case 'e': 22897a984708SDavid Chisnall __get_day(__tm->tm_mday, __b, __e, __err, __ct); 22907a984708SDavid Chisnall break; 22917a984708SDavid Chisnall case 'D': 22927a984708SDavid Chisnall { 229394e3ee44SDavid Chisnall const char_type __fm[] = {'%', 'm', '/', '%', 'd', '/', '%', 'y'}; 229494e3ee44SDavid Chisnall __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0])); 22957a984708SDavid Chisnall } 22967a984708SDavid Chisnall break; 22977a984708SDavid Chisnall case 'F': 22987a984708SDavid Chisnall { 229994e3ee44SDavid Chisnall const char_type __fm[] = {'%', 'Y', '-', '%', 'm', '-', '%', 'd'}; 230094e3ee44SDavid Chisnall __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0])); 23017a984708SDavid Chisnall } 23027a984708SDavid Chisnall break; 23037a984708SDavid Chisnall case 'H': 23047a984708SDavid Chisnall __get_hour(__tm->tm_hour, __b, __e, __err, __ct); 23057a984708SDavid Chisnall break; 23067a984708SDavid Chisnall case 'I': 23077a984708SDavid Chisnall __get_12_hour(__tm->tm_hour, __b, __e, __err, __ct); 23087a984708SDavid Chisnall break; 23097a984708SDavid Chisnall case 'j': 23107a984708SDavid Chisnall __get_day_year_num(__tm->tm_yday, __b, __e, __err, __ct); 23117a984708SDavid Chisnall break; 23127a984708SDavid Chisnall case 'm': 23137a984708SDavid Chisnall __get_month(__tm->tm_mon, __b, __e, __err, __ct); 23147a984708SDavid Chisnall break; 23157a984708SDavid Chisnall case 'M': 23167a984708SDavid Chisnall __get_minute(__tm->tm_min, __b, __e, __err, __ct); 23177a984708SDavid Chisnall break; 23187a984708SDavid Chisnall case 'n': 23197a984708SDavid Chisnall case 't': 23207a984708SDavid Chisnall __get_white_space(__b, __e, __err, __ct); 23217a984708SDavid Chisnall break; 23227a984708SDavid Chisnall case 'p': 23237a984708SDavid Chisnall __get_am_pm(__tm->tm_hour, __b, __e, __err, __ct); 23247a984708SDavid Chisnall break; 23257a984708SDavid Chisnall case 'r': 23267a984708SDavid Chisnall { 232794e3ee44SDavid Chisnall const char_type __fm[] = {'%', 'I', ':', '%', 'M', ':', '%', 'S', ' ', '%', 'p'}; 232894e3ee44SDavid Chisnall __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0])); 23297a984708SDavid Chisnall } 23307a984708SDavid Chisnall break; 23317a984708SDavid Chisnall case 'R': 23327a984708SDavid Chisnall { 233394e3ee44SDavid Chisnall const char_type __fm[] = {'%', 'H', ':', '%', 'M'}; 233494e3ee44SDavid Chisnall __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0])); 23357a984708SDavid Chisnall } 23367a984708SDavid Chisnall break; 23377a984708SDavid Chisnall case 'S': 23387a984708SDavid Chisnall __get_second(__tm->tm_sec, __b, __e, __err, __ct); 23397a984708SDavid Chisnall break; 23407a984708SDavid Chisnall case 'T': 23417a984708SDavid Chisnall { 234294e3ee44SDavid Chisnall const char_type __fm[] = {'%', 'H', ':', '%', 'M', ':', '%', 'S'}; 234394e3ee44SDavid Chisnall __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0])); 23447a984708SDavid Chisnall } 23457a984708SDavid Chisnall break; 23467a984708SDavid Chisnall case 'w': 23477a984708SDavid Chisnall __get_weekday(__tm->tm_wday, __b, __e, __err, __ct); 23487a984708SDavid Chisnall break; 23497a984708SDavid Chisnall case 'x': 23507a984708SDavid Chisnall return do_get_date(__b, __e, __iob, __err, __tm); 23517a984708SDavid Chisnall case 'X': 23527a984708SDavid Chisnall { 235394e3ee44SDavid Chisnall const string_type& __fm = this->__X(); 235494e3ee44SDavid Chisnall __b = get(__b, __e, __iob, __err, __tm, __fm.data(), __fm.data() + __fm.size()); 23557a984708SDavid Chisnall } 23567a984708SDavid Chisnall break; 23577a984708SDavid Chisnall case 'y': 23587a984708SDavid Chisnall __get_year(__tm->tm_year, __b, __e, __err, __ct); 23597a984708SDavid Chisnall break; 23607a984708SDavid Chisnall case 'Y': 23617a984708SDavid Chisnall __get_year4(__tm->tm_year, __b, __e, __err, __ct); 23627a984708SDavid Chisnall break; 23637a984708SDavid Chisnall case '%': 23647a984708SDavid Chisnall __get_percent(__b, __e, __err, __ct); 23657a984708SDavid Chisnall break; 23667a984708SDavid Chisnall default: 23677a984708SDavid Chisnall __err |= ios_base::failbit; 23687a984708SDavid Chisnall } 23697a984708SDavid Chisnall return __b; 23707a984708SDavid Chisnall} 23717a984708SDavid Chisnall 2372aed8d94eSDimitry Andric_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_get<char>) 2373aed8d94eSDimitry Andric_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_get<wchar_t>) 23747a984708SDavid Chisnall 23754f7ab58eSDimitry Andricclass _LIBCPP_TYPE_VIS __time_get 23767a984708SDavid Chisnall{ 23777a984708SDavid Chisnallprotected: 23787a984708SDavid Chisnall locale_t __loc_; 23797a984708SDavid Chisnall 23807a984708SDavid Chisnall __time_get(const char* __nm); 23817a984708SDavid Chisnall __time_get(const string& __nm); 23827a984708SDavid Chisnall ~__time_get(); 23837a984708SDavid Chisnall}; 23847a984708SDavid Chisnall 23857a984708SDavid Chisnalltemplate <class _CharT> 2386aed8d94eSDimitry Andricclass _LIBCPP_TEMPLATE_VIS __time_get_storage 23877a984708SDavid Chisnall : public __time_get 23887a984708SDavid Chisnall{ 23897a984708SDavid Chisnallprotected: 23907a984708SDavid Chisnall typedef basic_string<_CharT> string_type; 23917a984708SDavid Chisnall 23927a984708SDavid Chisnall string_type __weeks_[14]; 23937a984708SDavid Chisnall string_type __months_[24]; 23947a984708SDavid Chisnall string_type __am_pm_[2]; 23957a984708SDavid Chisnall string_type __c_; 23967a984708SDavid Chisnall string_type __r_; 23977a984708SDavid Chisnall string_type __x_; 23987a984708SDavid Chisnall string_type __X_; 23997a984708SDavid Chisnall 24007a984708SDavid Chisnall explicit __time_get_storage(const char* __nm); 24017a984708SDavid Chisnall explicit __time_get_storage(const string& __nm); 24027a984708SDavid Chisnall 24034ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY ~__time_get_storage() {} 24047a984708SDavid Chisnall 24057a984708SDavid Chisnall time_base::dateorder __do_date_order() const; 24067a984708SDavid Chisnall 24077a984708SDavid Chisnallprivate: 24087a984708SDavid Chisnall void init(const ctype<_CharT>&); 24097a984708SDavid Chisnall string_type __analyze(char __fmt, const ctype<_CharT>&); 24107a984708SDavid Chisnall}; 24117a984708SDavid Chisnall 2412*b5893f02SDimitry Andric#define _LIBCPP_TIME_GET_STORAGE_EXPLICIT_INSTANTIATION(_CharT) \ 2413*b5893f02SDimitry Andrictemplate <> _LIBCPP_FUNC_VIS time_base::dateorder __time_get_storage<_CharT>::__do_date_order() const; \ 2414*b5893f02SDimitry Andrictemplate <> _LIBCPP_FUNC_VIS __time_get_storage<_CharT>::__time_get_storage(const char*); \ 2415*b5893f02SDimitry Andrictemplate <> _LIBCPP_FUNC_VIS __time_get_storage<_CharT>::__time_get_storage(const string&); \ 2416*b5893f02SDimitry Andrictemplate <> _LIBCPP_FUNC_VIS void __time_get_storage<_CharT>::init(const ctype<_CharT>&); \ 2417*b5893f02SDimitry Andrictemplate <> _LIBCPP_FUNC_VIS __time_get_storage<_CharT>::string_type __time_get_storage<_CharT>::__analyze(char, const ctype<_CharT>&); \ 2418*b5893f02SDimitry Andricextern template _LIBCPP_FUNC_VIS time_base::dateorder __time_get_storage<_CharT>::__do_date_order() const; \ 2419*b5893f02SDimitry Andricextern template _LIBCPP_FUNC_VIS __time_get_storage<_CharT>::__time_get_storage(const char*); \ 2420*b5893f02SDimitry Andricextern template _LIBCPP_FUNC_VIS __time_get_storage<_CharT>::__time_get_storage(const string&); \ 2421*b5893f02SDimitry Andricextern template _LIBCPP_FUNC_VIS void __time_get_storage<_CharT>::init(const ctype<_CharT>&); \ 2422*b5893f02SDimitry Andricextern template _LIBCPP_FUNC_VIS __time_get_storage<_CharT>::string_type __time_get_storage<_CharT>::__analyze(char, const ctype<_CharT>&); \ 2423*b5893f02SDimitry Andric/**/ 2424*b5893f02SDimitry Andric 2425*b5893f02SDimitry Andric_LIBCPP_TIME_GET_STORAGE_EXPLICIT_INSTANTIATION(char) 2426*b5893f02SDimitry Andric_LIBCPP_TIME_GET_STORAGE_EXPLICIT_INSTANTIATION(wchar_t) 2427*b5893f02SDimitry Andric#undef _LIBCPP_TIME_GET_STORAGE_EXPLICIT_INSTANTIATION 2428*b5893f02SDimitry Andric 24297a984708SDavid Chisnalltemplate <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> > 2430aed8d94eSDimitry Andricclass _LIBCPP_TEMPLATE_VIS time_get_byname 24317a984708SDavid Chisnall : public time_get<_CharT, _InputIterator>, 24327a984708SDavid Chisnall private __time_get_storage<_CharT> 24337a984708SDavid Chisnall{ 24347a984708SDavid Chisnallpublic: 24357a984708SDavid Chisnall typedef time_base::dateorder dateorder; 24367a984708SDavid Chisnall typedef _InputIterator iter_type; 24377a984708SDavid Chisnall typedef _CharT char_type; 24387a984708SDavid Chisnall typedef basic_string<char_type> string_type; 24397a984708SDavid Chisnall 24407a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 24417a984708SDavid Chisnall explicit time_get_byname(const char* __nm, size_t __refs = 0) 24427a984708SDavid Chisnall : time_get<_CharT, _InputIterator>(__refs), 24437a984708SDavid Chisnall __time_get_storage<_CharT>(__nm) {} 24447a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 24457a984708SDavid Chisnall explicit time_get_byname(const string& __nm, size_t __refs = 0) 24467a984708SDavid Chisnall : time_get<_CharT, _InputIterator>(__refs), 24477a984708SDavid Chisnall __time_get_storage<_CharT>(__nm) {} 24487a984708SDavid Chisnall 24497a984708SDavid Chisnallprotected: 24507a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 24517a984708SDavid Chisnall ~time_get_byname() {} 24527a984708SDavid Chisnall 24537a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 24547a984708SDavid Chisnall virtual dateorder do_date_order() const {return this->__do_date_order();} 24557a984708SDavid Chisnallprivate: 24567a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 24577a984708SDavid Chisnall virtual const string_type* __weeks() const {return this->__weeks_;} 24587a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 24597a984708SDavid Chisnall virtual const string_type* __months() const {return this->__months_;} 24607a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 24617a984708SDavid Chisnall virtual const string_type* __am_pm() const {return this->__am_pm_;} 24627a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 24637a984708SDavid Chisnall virtual const string_type& __c() const {return this->__c_;} 24647a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 24657a984708SDavid Chisnall virtual const string_type& __r() const {return this->__r_;} 24667a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 24677a984708SDavid Chisnall virtual const string_type& __x() const {return this->__x_;} 24687a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 24697a984708SDavid Chisnall virtual const string_type& __X() const {return this->__X_;} 24707a984708SDavid Chisnall}; 24717a984708SDavid Chisnall 2472aed8d94eSDimitry Andric_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_get_byname<char>) 2473aed8d94eSDimitry Andric_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_get_byname<wchar_t>) 24747a984708SDavid Chisnall 24754f7ab58eSDimitry Andricclass _LIBCPP_TYPE_VIS __time_put 24767a984708SDavid Chisnall{ 24777a984708SDavid Chisnall locale_t __loc_; 24787a984708SDavid Chisnallprotected: 24794ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY __time_put() : __loc_(_LIBCPP_GET_C_LOCALE) {} 24807a984708SDavid Chisnall __time_put(const char* __nm); 24817a984708SDavid Chisnall __time_put(const string& __nm); 24827a984708SDavid Chisnall ~__time_put(); 24837a984708SDavid Chisnall void __do_put(char* __nb, char*& __ne, const tm* __tm, 24847a984708SDavid Chisnall char __fmt, char __mod) const; 24857a984708SDavid Chisnall void __do_put(wchar_t* __wb, wchar_t*& __we, const tm* __tm, 24867a984708SDavid Chisnall char __fmt, char __mod) const; 24877a984708SDavid Chisnall}; 24887a984708SDavid Chisnall 24897a984708SDavid Chisnalltemplate <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> > 2490aed8d94eSDimitry Andricclass _LIBCPP_TEMPLATE_VIS time_put 24917a984708SDavid Chisnall : public locale::facet, 24927a984708SDavid Chisnall private __time_put 24937a984708SDavid Chisnall{ 24947a984708SDavid Chisnallpublic: 24957a984708SDavid Chisnall typedef _CharT char_type; 24967a984708SDavid Chisnall typedef _OutputIterator iter_type; 24977a984708SDavid Chisnall 24984ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 24997a984708SDavid Chisnall explicit time_put(size_t __refs = 0) 25007a984708SDavid Chisnall : locale::facet(__refs) {} 25017a984708SDavid Chisnall 25027a984708SDavid Chisnall iter_type put(iter_type __s, ios_base& __iob, char_type __fl, const tm* __tm, 25037a984708SDavid Chisnall const char_type* __pb, const char_type* __pe) const; 25047a984708SDavid Chisnall 25054ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 25067a984708SDavid Chisnall iter_type put(iter_type __s, ios_base& __iob, char_type __fl, 25077a984708SDavid Chisnall const tm* __tm, char __fmt, char __mod = 0) const 25087a984708SDavid Chisnall { 25097a984708SDavid Chisnall return do_put(__s, __iob, __fl, __tm, __fmt, __mod); 25107a984708SDavid Chisnall } 25117a984708SDavid Chisnall 25127a984708SDavid Chisnall static locale::id id; 25137a984708SDavid Chisnall 25147a984708SDavid Chisnallprotected: 25154ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 25167a984708SDavid Chisnall ~time_put() {} 25177a984708SDavid Chisnall virtual iter_type do_put(iter_type __s, ios_base&, char_type, const tm* __tm, 25187a984708SDavid Chisnall char __fmt, char __mod) const; 25197a984708SDavid Chisnall 25204ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 25217a984708SDavid Chisnall explicit time_put(const char* __nm, size_t __refs) 25227a984708SDavid Chisnall : locale::facet(__refs), 25237a984708SDavid Chisnall __time_put(__nm) {} 25244ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 25257a984708SDavid Chisnall explicit time_put(const string& __nm, size_t __refs) 25267a984708SDavid Chisnall : locale::facet(__refs), 25277a984708SDavid Chisnall __time_put(__nm) {} 25287a984708SDavid Chisnall}; 25297a984708SDavid Chisnall 25307a984708SDavid Chisnalltemplate <class _CharT, class _OutputIterator> 25317a984708SDavid Chisnalllocale::id 25327a984708SDavid Chisnalltime_put<_CharT, _OutputIterator>::id; 25337a984708SDavid Chisnall 25347a984708SDavid Chisnalltemplate <class _CharT, class _OutputIterator> 25357a984708SDavid Chisnall_OutputIterator 25367a984708SDavid Chisnalltime_put<_CharT, _OutputIterator>::put(iter_type __s, ios_base& __iob, 25377a984708SDavid Chisnall char_type __fl, const tm* __tm, 25387a984708SDavid Chisnall const char_type* __pb, 25397a984708SDavid Chisnall const char_type* __pe) const 25407a984708SDavid Chisnall{ 25417a984708SDavid Chisnall const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc()); 25427a984708SDavid Chisnall for (; __pb != __pe; ++__pb) 25437a984708SDavid Chisnall { 25447a984708SDavid Chisnall if (__ct.narrow(*__pb, 0) == '%') 25457a984708SDavid Chisnall { 25467a984708SDavid Chisnall if (++__pb == __pe) 25477a984708SDavid Chisnall { 25487a984708SDavid Chisnall *__s++ = __pb[-1]; 25497a984708SDavid Chisnall break; 25507a984708SDavid Chisnall } 25517a984708SDavid Chisnall char __mod = 0; 25527a984708SDavid Chisnall char __fmt = __ct.narrow(*__pb, 0); 25537a984708SDavid Chisnall if (__fmt == 'E' || __fmt == 'O') 25547a984708SDavid Chisnall { 25557a984708SDavid Chisnall if (++__pb == __pe) 25567a984708SDavid Chisnall { 25577a984708SDavid Chisnall *__s++ = __pb[-2]; 25587a984708SDavid Chisnall *__s++ = __pb[-1]; 25597a984708SDavid Chisnall break; 25607a984708SDavid Chisnall } 25617a984708SDavid Chisnall __mod = __fmt; 25627a984708SDavid Chisnall __fmt = __ct.narrow(*__pb, 0); 25637a984708SDavid Chisnall } 25647a984708SDavid Chisnall __s = do_put(__s, __iob, __fl, __tm, __fmt, __mod); 25657a984708SDavid Chisnall } 25667a984708SDavid Chisnall else 25677a984708SDavid Chisnall *__s++ = *__pb; 25687a984708SDavid Chisnall } 25697a984708SDavid Chisnall return __s; 25707a984708SDavid Chisnall} 25717a984708SDavid Chisnall 25727a984708SDavid Chisnalltemplate <class _CharT, class _OutputIterator> 25737a984708SDavid Chisnall_OutputIterator 257494e3ee44SDavid Chisnalltime_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base&, 25757a984708SDavid Chisnall char_type, const tm* __tm, 25767a984708SDavid Chisnall char __fmt, char __mod) const 25777a984708SDavid Chisnall{ 25787a984708SDavid Chisnall char_type __nar[100]; 25797a984708SDavid Chisnall char_type* __nb = __nar; 25807a984708SDavid Chisnall char_type* __ne = __nb + 100; 25817a984708SDavid Chisnall __do_put(__nb, __ne, __tm, __fmt, __mod); 25827a984708SDavid Chisnall return _VSTD::copy(__nb, __ne, __s); 25837a984708SDavid Chisnall} 25847a984708SDavid Chisnall 2585aed8d94eSDimitry Andric_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_put<char>) 2586aed8d94eSDimitry Andric_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_put<wchar_t>) 25877a984708SDavid Chisnall 25887a984708SDavid Chisnalltemplate <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> > 2589aed8d94eSDimitry Andricclass _LIBCPP_TEMPLATE_VIS time_put_byname 25907a984708SDavid Chisnall : public time_put<_CharT, _OutputIterator> 25917a984708SDavid Chisnall{ 25927a984708SDavid Chisnallpublic: 25934ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 25947a984708SDavid Chisnall explicit time_put_byname(const char* __nm, size_t __refs = 0) 25957a984708SDavid Chisnall : time_put<_CharT, _OutputIterator>(__nm, __refs) {} 25967a984708SDavid Chisnall 25974ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 25987a984708SDavid Chisnall explicit time_put_byname(const string& __nm, size_t __refs = 0) 25997a984708SDavid Chisnall : time_put<_CharT, _OutputIterator>(__nm, __refs) {} 26007a984708SDavid Chisnall 26017a984708SDavid Chisnallprotected: 26024ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 26037a984708SDavid Chisnall ~time_put_byname() {} 26047a984708SDavid Chisnall}; 26057a984708SDavid Chisnall 2606aed8d94eSDimitry Andric_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_put_byname<char>) 2607aed8d94eSDimitry Andric_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_put_byname<wchar_t>) 26087a984708SDavid Chisnall 26097a984708SDavid Chisnall// money_base 26107a984708SDavid Chisnall 26111bf9f7c1SDimitry Andricclass _LIBCPP_TYPE_VIS money_base 26127a984708SDavid Chisnall{ 26137a984708SDavid Chisnallpublic: 26147a984708SDavid Chisnall enum part {none, space, symbol, sign, value}; 26157a984708SDavid Chisnall struct pattern {char field[4];}; 26167a984708SDavid Chisnall 26174ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY money_base() {} 26187a984708SDavid Chisnall}; 26197a984708SDavid Chisnall 26207a984708SDavid Chisnall// moneypunct 26217a984708SDavid Chisnall 26227a984708SDavid Chisnalltemplate <class _CharT, bool _International = false> 2623aed8d94eSDimitry Andricclass _LIBCPP_TEMPLATE_VIS moneypunct 26247a984708SDavid Chisnall : public locale::facet, 26257a984708SDavid Chisnall public money_base 26267a984708SDavid Chisnall{ 26277a984708SDavid Chisnallpublic: 26287a984708SDavid Chisnall typedef _CharT char_type; 26297a984708SDavid Chisnall typedef basic_string<char_type> string_type; 26307a984708SDavid Chisnall 26314ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 26327a984708SDavid Chisnall explicit moneypunct(size_t __refs = 0) 26337a984708SDavid Chisnall : locale::facet(__refs) {} 26347a984708SDavid Chisnall 26354ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY char_type decimal_point() const {return do_decimal_point();} 26364ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY char_type thousands_sep() const {return do_thousands_sep();} 26374ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY string grouping() const {return do_grouping();} 26384ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY string_type curr_symbol() const {return do_curr_symbol();} 26394ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY string_type positive_sign() const {return do_positive_sign();} 26404ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY string_type negative_sign() const {return do_negative_sign();} 26414ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY int frac_digits() const {return do_frac_digits();} 26424ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY pattern pos_format() const {return do_pos_format();} 26434ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY pattern neg_format() const {return do_neg_format();} 26447a984708SDavid Chisnall 26457a984708SDavid Chisnall static locale::id id; 26467a984708SDavid Chisnall static const bool intl = _International; 26477a984708SDavid Chisnall 26487a984708SDavid Chisnallprotected: 26494ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 26507a984708SDavid Chisnall ~moneypunct() {} 26517a984708SDavid Chisnall 26527a984708SDavid Chisnall virtual char_type do_decimal_point() const {return numeric_limits<char_type>::max();} 26537a984708SDavid Chisnall virtual char_type do_thousands_sep() const {return numeric_limits<char_type>::max();} 26547a984708SDavid Chisnall virtual string do_grouping() const {return string();} 26557a984708SDavid Chisnall virtual string_type do_curr_symbol() const {return string_type();} 26567a984708SDavid Chisnall virtual string_type do_positive_sign() const {return string_type();} 26577a984708SDavid Chisnall virtual string_type do_negative_sign() const {return string_type(1, '-');} 26587a984708SDavid Chisnall virtual int do_frac_digits() const {return 0;} 26597a984708SDavid Chisnall virtual pattern do_pos_format() const 2660d3c53822SDimitry Andric {pattern __p = {{symbol, sign, none, value}}; return __p;} 26617a984708SDavid Chisnall virtual pattern do_neg_format() const 2662d3c53822SDimitry Andric {pattern __p = {{symbol, sign, none, value}}; return __p;} 26637a984708SDavid Chisnall}; 26647a984708SDavid Chisnall 26657a984708SDavid Chisnalltemplate <class _CharT, bool _International> 26667a984708SDavid Chisnalllocale::id 26677a984708SDavid Chisnallmoneypunct<_CharT, _International>::id; 26687a984708SDavid Chisnall 2669cfdf2879SDavid Chisnalltemplate <class _CharT, bool _International> 2670cfdf2879SDavid Chisnallconst bool 2671cfdf2879SDavid Chisnallmoneypunct<_CharT, _International>::intl; 2672cfdf2879SDavid Chisnall 2673aed8d94eSDimitry Andric_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct<char, false>) 2674aed8d94eSDimitry Andric_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct<char, true>) 2675aed8d94eSDimitry Andric_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct<wchar_t, false>) 2676aed8d94eSDimitry Andric_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct<wchar_t, true>) 26777a984708SDavid Chisnall 26787a984708SDavid Chisnall// moneypunct_byname 26797a984708SDavid Chisnall 26807a984708SDavid Chisnalltemplate <class _CharT, bool _International = false> 2681aed8d94eSDimitry Andricclass _LIBCPP_TEMPLATE_VIS moneypunct_byname 26827a984708SDavid Chisnall : public moneypunct<_CharT, _International> 26837a984708SDavid Chisnall{ 26847a984708SDavid Chisnallpublic: 26857a984708SDavid Chisnall typedef money_base::pattern pattern; 26867a984708SDavid Chisnall typedef _CharT char_type; 26877a984708SDavid Chisnall typedef basic_string<char_type> string_type; 26887a984708SDavid Chisnall 26894ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 26907a984708SDavid Chisnall explicit moneypunct_byname(const char* __nm, size_t __refs = 0) 26917a984708SDavid Chisnall : moneypunct<_CharT, _International>(__refs) {init(__nm);} 26927a984708SDavid Chisnall 26934ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 26947a984708SDavid Chisnall explicit moneypunct_byname(const string& __nm, size_t __refs = 0) 26957a984708SDavid Chisnall : moneypunct<_CharT, _International>(__refs) {init(__nm.c_str());} 26967a984708SDavid Chisnall 26977a984708SDavid Chisnallprotected: 26984ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 26997a984708SDavid Chisnall ~moneypunct_byname() {} 27007a984708SDavid Chisnall 27017a984708SDavid Chisnall virtual char_type do_decimal_point() const {return __decimal_point_;} 27027a984708SDavid Chisnall virtual char_type do_thousands_sep() const {return __thousands_sep_;} 27037a984708SDavid Chisnall virtual string do_grouping() const {return __grouping_;} 27047a984708SDavid Chisnall virtual string_type do_curr_symbol() const {return __curr_symbol_;} 27057a984708SDavid Chisnall virtual string_type do_positive_sign() const {return __positive_sign_;} 27067a984708SDavid Chisnall virtual string_type do_negative_sign() const {return __negative_sign_;} 27077a984708SDavid Chisnall virtual int do_frac_digits() const {return __frac_digits_;} 27087a984708SDavid Chisnall virtual pattern do_pos_format() const {return __pos_format_;} 27097a984708SDavid Chisnall virtual pattern do_neg_format() const {return __neg_format_;} 27107a984708SDavid Chisnall 27117a984708SDavid Chisnallprivate: 27127a984708SDavid Chisnall char_type __decimal_point_; 27137a984708SDavid Chisnall char_type __thousands_sep_; 27147a984708SDavid Chisnall string __grouping_; 27157a984708SDavid Chisnall string_type __curr_symbol_; 27167a984708SDavid Chisnall string_type __positive_sign_; 27177a984708SDavid Chisnall string_type __negative_sign_; 27187a984708SDavid Chisnall int __frac_digits_; 27197a984708SDavid Chisnall pattern __pos_format_; 27207a984708SDavid Chisnall pattern __neg_format_; 27217a984708SDavid Chisnall 27227a984708SDavid Chisnall void init(const char*); 27237a984708SDavid Chisnall}; 27247a984708SDavid Chisnall 2725540d2a8bSDimitry Andrictemplate<> _LIBCPP_FUNC_VIS void moneypunct_byname<char, false>::init(const char*); 2726540d2a8bSDimitry Andrictemplate<> _LIBCPP_FUNC_VIS void moneypunct_byname<char, true>::init(const char*); 2727540d2a8bSDimitry Andrictemplate<> _LIBCPP_FUNC_VIS void moneypunct_byname<wchar_t, false>::init(const char*); 2728540d2a8bSDimitry Andrictemplate<> _LIBCPP_FUNC_VIS void moneypunct_byname<wchar_t, true>::init(const char*); 27297a984708SDavid Chisnall 2730aed8d94eSDimitry Andric_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct_byname<char, false>) 2731aed8d94eSDimitry Andric_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct_byname<char, true>) 2732aed8d94eSDimitry Andric_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct_byname<wchar_t, false>) 2733aed8d94eSDimitry Andric_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct_byname<wchar_t, true>) 27347a984708SDavid Chisnall 27357a984708SDavid Chisnall// money_get 27367a984708SDavid Chisnall 27377a984708SDavid Chisnalltemplate <class _CharT> 27387a984708SDavid Chisnallclass __money_get 27397a984708SDavid Chisnall{ 27407a984708SDavid Chisnallprotected: 27417a984708SDavid Chisnall typedef _CharT char_type; 27427a984708SDavid Chisnall typedef basic_string<char_type> string_type; 27437a984708SDavid Chisnall 27444ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY __money_get() {} 27457a984708SDavid Chisnall 27467a984708SDavid Chisnall static void __gather_info(bool __intl, const locale& __loc, 27477a984708SDavid Chisnall money_base::pattern& __pat, char_type& __dp, 27487a984708SDavid Chisnall char_type& __ts, string& __grp, 27497a984708SDavid Chisnall string_type& __sym, string_type& __psn, 27507a984708SDavid Chisnall string_type& __nsn, int& __fd); 27517a984708SDavid Chisnall}; 27527a984708SDavid Chisnall 27537a984708SDavid Chisnalltemplate <class _CharT> 27547a984708SDavid Chisnallvoid 27557a984708SDavid Chisnall__money_get<_CharT>::__gather_info(bool __intl, const locale& __loc, 27567a984708SDavid Chisnall money_base::pattern& __pat, char_type& __dp, 27577a984708SDavid Chisnall char_type& __ts, string& __grp, 27587a984708SDavid Chisnall string_type& __sym, string_type& __psn, 27597a984708SDavid Chisnall string_type& __nsn, int& __fd) 27607a984708SDavid Chisnall{ 27617a984708SDavid Chisnall if (__intl) 27627a984708SDavid Chisnall { 27637a984708SDavid Chisnall const moneypunct<char_type, true>& __mp = 27647a984708SDavid Chisnall use_facet<moneypunct<char_type, true> >(__loc); 27657a984708SDavid Chisnall __pat = __mp.neg_format(); 27667a984708SDavid Chisnall __nsn = __mp.negative_sign(); 27677a984708SDavid Chisnall __psn = __mp.positive_sign(); 27687a984708SDavid Chisnall __dp = __mp.decimal_point(); 27697a984708SDavid Chisnall __ts = __mp.thousands_sep(); 27707a984708SDavid Chisnall __grp = __mp.grouping(); 27717a984708SDavid Chisnall __sym = __mp.curr_symbol(); 27727a984708SDavid Chisnall __fd = __mp.frac_digits(); 27737a984708SDavid Chisnall } 27747a984708SDavid Chisnall else 27757a984708SDavid Chisnall { 27767a984708SDavid Chisnall const moneypunct<char_type, false>& __mp = 27777a984708SDavid Chisnall use_facet<moneypunct<char_type, false> >(__loc); 27787a984708SDavid Chisnall __pat = __mp.neg_format(); 27797a984708SDavid Chisnall __nsn = __mp.negative_sign(); 27807a984708SDavid Chisnall __psn = __mp.positive_sign(); 27817a984708SDavid Chisnall __dp = __mp.decimal_point(); 27827a984708SDavid Chisnall __ts = __mp.thousands_sep(); 27837a984708SDavid Chisnall __grp = __mp.grouping(); 27847a984708SDavid Chisnall __sym = __mp.curr_symbol(); 27857a984708SDavid Chisnall __fd = __mp.frac_digits(); 27867a984708SDavid Chisnall } 27877a984708SDavid Chisnall} 27887a984708SDavid Chisnall 2789aed8d94eSDimitry Andric_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __money_get<char>) 2790aed8d94eSDimitry Andric_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __money_get<wchar_t>) 27917a984708SDavid Chisnall 27927a984708SDavid Chisnalltemplate <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> > 2793aed8d94eSDimitry Andricclass _LIBCPP_TEMPLATE_VIS money_get 27947a984708SDavid Chisnall : public locale::facet, 27957a984708SDavid Chisnall private __money_get<_CharT> 27967a984708SDavid Chisnall{ 27977a984708SDavid Chisnallpublic: 27987a984708SDavid Chisnall typedef _CharT char_type; 27997a984708SDavid Chisnall typedef _InputIterator iter_type; 28007a984708SDavid Chisnall typedef basic_string<char_type> string_type; 28017a984708SDavid Chisnall 28024ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 28037a984708SDavid Chisnall explicit money_get(size_t __refs = 0) 28047a984708SDavid Chisnall : locale::facet(__refs) {} 28057a984708SDavid Chisnall 28064ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 28077a984708SDavid Chisnall iter_type get(iter_type __b, iter_type __e, bool __intl, ios_base& __iob, 28087a984708SDavid Chisnall ios_base::iostate& __err, long double& __v) const 28097a984708SDavid Chisnall { 28107a984708SDavid Chisnall return do_get(__b, __e, __intl, __iob, __err, __v); 28117a984708SDavid Chisnall } 28127a984708SDavid Chisnall 28134ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 28147a984708SDavid Chisnall iter_type get(iter_type __b, iter_type __e, bool __intl, ios_base& __iob, 28157a984708SDavid Chisnall ios_base::iostate& __err, string_type& __v) const 28167a984708SDavid Chisnall { 28177a984708SDavid Chisnall return do_get(__b, __e, __intl, __iob, __err, __v); 28187a984708SDavid Chisnall } 28197a984708SDavid Chisnall 28207a984708SDavid Chisnall static locale::id id; 28217a984708SDavid Chisnall 28227a984708SDavid Chisnallprotected: 28237a984708SDavid Chisnall 28244ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 28257a984708SDavid Chisnall ~money_get() {} 28267a984708SDavid Chisnall 28277a984708SDavid Chisnall virtual iter_type do_get(iter_type __b, iter_type __e, bool __intl, 28287a984708SDavid Chisnall ios_base& __iob, ios_base::iostate& __err, 28297a984708SDavid Chisnall long double& __v) const; 28307a984708SDavid Chisnall virtual iter_type do_get(iter_type __b, iter_type __e, bool __intl, 28317a984708SDavid Chisnall ios_base& __iob, ios_base::iostate& __err, 28327a984708SDavid Chisnall string_type& __v) const; 28337a984708SDavid Chisnall 28347a984708SDavid Chisnallprivate: 28357a984708SDavid Chisnall static bool __do_get(iter_type& __b, iter_type __e, 28367a984708SDavid Chisnall bool __intl, const locale& __loc, 28377a984708SDavid Chisnall ios_base::fmtflags __flags, ios_base::iostate& __err, 28387a984708SDavid Chisnall bool& __neg, const ctype<char_type>& __ct, 28397a984708SDavid Chisnall unique_ptr<char_type, void(*)(void*)>& __wb, 28407a984708SDavid Chisnall char_type*& __wn, char_type* __we); 28417a984708SDavid Chisnall}; 28427a984708SDavid Chisnall 28437a984708SDavid Chisnalltemplate <class _CharT, class _InputIterator> 28447a984708SDavid Chisnalllocale::id 28457a984708SDavid Chisnallmoney_get<_CharT, _InputIterator>::id; 28467a984708SDavid Chisnall 28474f7ab58eSDimitry Andric_LIBCPP_FUNC_VIS void __do_nothing(void*); 28487a984708SDavid Chisnall 28497a984708SDavid Chisnalltemplate <class _Tp> 28507a984708SDavid Chisnall_LIBCPP_HIDDEN 28517a984708SDavid Chisnallvoid 28527a984708SDavid Chisnall__double_or_nothing(unique_ptr<_Tp, void(*)(void*)>& __b, _Tp*& __n, _Tp*& __e) 28537a984708SDavid Chisnall{ 28547a984708SDavid Chisnall bool __owns = __b.get_deleter() != __do_nothing; 285594e3ee44SDavid Chisnall size_t __cur_cap = static_cast<size_t>(__e-__b.get()) * sizeof(_Tp); 28567a984708SDavid Chisnall size_t __new_cap = __cur_cap < numeric_limits<size_t>::max() / 2 ? 28577a984708SDavid Chisnall 2 * __cur_cap : numeric_limits<size_t>::max(); 2858d72607e9SDimitry Andric if (__new_cap == 0) 2859d72607e9SDimitry Andric __new_cap = sizeof(_Tp); 286094e3ee44SDavid Chisnall size_t __n_off = static_cast<size_t>(__n - __b.get()); 28617a984708SDavid Chisnall _Tp* __t = (_Tp*)realloc(__owns ? __b.get() : 0, __new_cap); 28627a984708SDavid Chisnall if (__t == 0) 28637a984708SDavid Chisnall __throw_bad_alloc(); 28647a984708SDavid Chisnall if (__owns) 28657a984708SDavid Chisnall __b.release(); 28667a984708SDavid Chisnall __b = unique_ptr<_Tp, void(*)(void*)>(__t, free); 28677a984708SDavid Chisnall __new_cap /= sizeof(_Tp); 28687a984708SDavid Chisnall __n = __b.get() + __n_off; 28697a984708SDavid Chisnall __e = __b.get() + __new_cap; 28707a984708SDavid Chisnall} 28717a984708SDavid Chisnall 28727a984708SDavid Chisnall// true == success 28737a984708SDavid Chisnalltemplate <class _CharT, class _InputIterator> 28747a984708SDavid Chisnallbool 28757a984708SDavid Chisnallmoney_get<_CharT, _InputIterator>::__do_get(iter_type& __b, iter_type __e, 28767a984708SDavid Chisnall bool __intl, const locale& __loc, 28777a984708SDavid Chisnall ios_base::fmtflags __flags, 28787a984708SDavid Chisnall ios_base::iostate& __err, 28797a984708SDavid Chisnall bool& __neg, 28807a984708SDavid Chisnall const ctype<char_type>& __ct, 28817a984708SDavid Chisnall unique_ptr<char_type, void(*)(void*)>& __wb, 28827a984708SDavid Chisnall char_type*& __wn, char_type* __we) 28837a984708SDavid Chisnall{ 28847a984708SDavid Chisnall const unsigned __bz = 100; 28857a984708SDavid Chisnall unsigned __gbuf[__bz]; 28867a984708SDavid Chisnall unique_ptr<unsigned, void(*)(void*)> __gb(__gbuf, __do_nothing); 28877a984708SDavid Chisnall unsigned* __gn = __gb.get(); 28887a984708SDavid Chisnall unsigned* __ge = __gn + __bz; 28897a984708SDavid Chisnall money_base::pattern __pat; 28907a984708SDavid Chisnall char_type __dp; 28917a984708SDavid Chisnall char_type __ts; 28927a984708SDavid Chisnall string __grp; 28937a984708SDavid Chisnall string_type __sym; 28947a984708SDavid Chisnall string_type __psn; 28957a984708SDavid Chisnall string_type __nsn; 289694e3ee44SDavid Chisnall // Capture the spaces read into money_base::{space,none} so they 289794e3ee44SDavid Chisnall // can be compared to initial spaces in __sym. 289894e3ee44SDavid Chisnall string_type __spaces; 28997a984708SDavid Chisnall int __fd; 29007a984708SDavid Chisnall __money_get<_CharT>::__gather_info(__intl, __loc, __pat, __dp, __ts, __grp, 29017a984708SDavid Chisnall __sym, __psn, __nsn, __fd); 29027a984708SDavid Chisnall const string_type* __trailing_sign = 0; 29037a984708SDavid Chisnall __wn = __wb.get(); 29047a984708SDavid Chisnall for (unsigned __p = 0; __p < 4 && __b != __e; ++__p) 29057a984708SDavid Chisnall { 29067a984708SDavid Chisnall switch (__pat.field[__p]) 29077a984708SDavid Chisnall { 29087a984708SDavid Chisnall case money_base::space: 29097a984708SDavid Chisnall if (__p != 3) 29107a984708SDavid Chisnall { 29117a984708SDavid Chisnall if (__ct.is(ctype_base::space, *__b)) 291294e3ee44SDavid Chisnall __spaces.push_back(*__b++); 29137a984708SDavid Chisnall else 29147a984708SDavid Chisnall { 29157a984708SDavid Chisnall __err |= ios_base::failbit; 29167a984708SDavid Chisnall return false; 29177a984708SDavid Chisnall } 29187a984708SDavid Chisnall } 29190f5676f4SDimitry Andric _LIBCPP_FALLTHROUGH(); 29207a984708SDavid Chisnall case money_base::none: 29217a984708SDavid Chisnall if (__p != 3) 29227a984708SDavid Chisnall { 29237a984708SDavid Chisnall while (__b != __e && __ct.is(ctype_base::space, *__b)) 292494e3ee44SDavid Chisnall __spaces.push_back(*__b++); 29257a984708SDavid Chisnall } 29267a984708SDavid Chisnall break; 29277a984708SDavid Chisnall case money_base::sign: 29287a984708SDavid Chisnall if (__psn.size() + __nsn.size() > 0) 29297a984708SDavid Chisnall { 29307a984708SDavid Chisnall if (__psn.size() == 0 || __nsn.size() == 0) 29317a984708SDavid Chisnall { // sign is optional 29327a984708SDavid Chisnall if (__psn.size() > 0) 29337a984708SDavid Chisnall { // __nsn.size() == 0 29347a984708SDavid Chisnall if (*__b == __psn[0]) 29357a984708SDavid Chisnall { 29367a984708SDavid Chisnall ++__b; 29377a984708SDavid Chisnall if (__psn.size() > 1) 29387a984708SDavid Chisnall __trailing_sign = &__psn; 29397a984708SDavid Chisnall } 29407a984708SDavid Chisnall else 29417a984708SDavid Chisnall __neg = true; 29427a984708SDavid Chisnall } 29437a984708SDavid Chisnall else if (*__b == __nsn[0]) // __nsn.size() > 0 && __psn.size() == 0 29447a984708SDavid Chisnall { 29457a984708SDavid Chisnall ++__b; 29467a984708SDavid Chisnall __neg = true; 29477a984708SDavid Chisnall if (__nsn.size() > 1) 29487a984708SDavid Chisnall __trailing_sign = &__nsn; 29497a984708SDavid Chisnall } 29507a984708SDavid Chisnall } 29517a984708SDavid Chisnall else // sign is required 29527a984708SDavid Chisnall { 29537a984708SDavid Chisnall if (*__b == __psn[0]) 29547a984708SDavid Chisnall { 29557a984708SDavid Chisnall ++__b; 29567a984708SDavid Chisnall if (__psn.size() > 1) 29577a984708SDavid Chisnall __trailing_sign = &__psn; 29587a984708SDavid Chisnall } 29597a984708SDavid Chisnall else if (*__b == __nsn[0]) 29607a984708SDavid Chisnall { 29617a984708SDavid Chisnall ++__b; 29627a984708SDavid Chisnall __neg = true; 29637a984708SDavid Chisnall if (__nsn.size() > 1) 29647a984708SDavid Chisnall __trailing_sign = &__nsn; 29657a984708SDavid Chisnall } 29667a984708SDavid Chisnall else 29677a984708SDavid Chisnall { 29687a984708SDavid Chisnall __err |= ios_base::failbit; 29697a984708SDavid Chisnall return false; 29707a984708SDavid Chisnall } 29717a984708SDavid Chisnall } 29727a984708SDavid Chisnall } 29737a984708SDavid Chisnall break; 29747a984708SDavid Chisnall case money_base::symbol: 29757a984708SDavid Chisnall { 29767a984708SDavid Chisnall bool __more_needed = __trailing_sign || 29777a984708SDavid Chisnall (__p < 2) || 29787a984708SDavid Chisnall (__p == 2 && __pat.field[3] != static_cast<char>(money_base::none)); 29794f7ab58eSDimitry Andric bool __sb = (__flags & ios_base::showbase) != 0; 29807a984708SDavid Chisnall if (__sb || __more_needed) 29817a984708SDavid Chisnall { 298294e3ee44SDavid Chisnall typename string_type::const_iterator __sym_space_end = __sym.begin(); 298394e3ee44SDavid Chisnall if (__p > 0 && (__pat.field[__p - 1] == money_base::none || 298494e3ee44SDavid Chisnall __pat.field[__p - 1] == money_base::space)) { 298594e3ee44SDavid Chisnall // Match spaces we've already read against spaces at 298694e3ee44SDavid Chisnall // the beginning of __sym. 298794e3ee44SDavid Chisnall while (__sym_space_end != __sym.end() && 298894e3ee44SDavid Chisnall __ct.is(ctype_base::space, *__sym_space_end)) 298994e3ee44SDavid Chisnall ++__sym_space_end; 299094e3ee44SDavid Chisnall const size_t __num_spaces = __sym_space_end - __sym.begin(); 299194e3ee44SDavid Chisnall if (__num_spaces > __spaces.size() || 299294e3ee44SDavid Chisnall !equal(__spaces.end() - __num_spaces, __spaces.end(), 299394e3ee44SDavid Chisnall __sym.begin())) { 299494e3ee44SDavid Chisnall // No match. Put __sym_space_end back at the 299594e3ee44SDavid Chisnall // beginning of __sym, which will prevent a 299694e3ee44SDavid Chisnall // match in the next loop. 299794e3ee44SDavid Chisnall __sym_space_end = __sym.begin(); 299894e3ee44SDavid Chisnall } 299994e3ee44SDavid Chisnall } 300094e3ee44SDavid Chisnall typename string_type::const_iterator __sym_curr_char = __sym_space_end; 300194e3ee44SDavid Chisnall while (__sym_curr_char != __sym.end() && __b != __e && 300294e3ee44SDavid Chisnall *__b == *__sym_curr_char) { 300394e3ee44SDavid Chisnall ++__b; 300494e3ee44SDavid Chisnall ++__sym_curr_char; 300594e3ee44SDavid Chisnall } 300694e3ee44SDavid Chisnall if (__sb && __sym_curr_char != __sym.end()) 30077a984708SDavid Chisnall { 30087a984708SDavid Chisnall __err |= ios_base::failbit; 30097a984708SDavid Chisnall return false; 30107a984708SDavid Chisnall } 30117a984708SDavid Chisnall } 30127a984708SDavid Chisnall } 30137a984708SDavid Chisnall break; 30147a984708SDavid Chisnall case money_base::value: 30157a984708SDavid Chisnall { 30167a984708SDavid Chisnall unsigned __ng = 0; 30177a984708SDavid Chisnall for (; __b != __e; ++__b) 30187a984708SDavid Chisnall { 30197a984708SDavid Chisnall char_type __c = *__b; 30207a984708SDavid Chisnall if (__ct.is(ctype_base::digit, __c)) 30217a984708SDavid Chisnall { 30227a984708SDavid Chisnall if (__wn == __we) 30237a984708SDavid Chisnall __double_or_nothing(__wb, __wn, __we); 30247a984708SDavid Chisnall *__wn++ = __c; 30257a984708SDavid Chisnall ++__ng; 30267a984708SDavid Chisnall } 30277a984708SDavid Chisnall else if (__grp.size() > 0 && __ng > 0 && __c == __ts) 30287a984708SDavid Chisnall { 30297a984708SDavid Chisnall if (__gn == __ge) 30307a984708SDavid Chisnall __double_or_nothing(__gb, __gn, __ge); 30317a984708SDavid Chisnall *__gn++ = __ng; 30327a984708SDavid Chisnall __ng = 0; 30337a984708SDavid Chisnall } 30347a984708SDavid Chisnall else 30357a984708SDavid Chisnall break; 30367a984708SDavid Chisnall } 30377a984708SDavid Chisnall if (__gb.get() != __gn && __ng > 0) 30387a984708SDavid Chisnall { 30397a984708SDavid Chisnall if (__gn == __ge) 30407a984708SDavid Chisnall __double_or_nothing(__gb, __gn, __ge); 30417a984708SDavid Chisnall *__gn++ = __ng; 30427a984708SDavid Chisnall } 30437a984708SDavid Chisnall if (__fd > 0) 30447a984708SDavid Chisnall { 30457a984708SDavid Chisnall if (__b == __e || *__b != __dp) 30467a984708SDavid Chisnall { 30477a984708SDavid Chisnall __err |= ios_base::failbit; 30487a984708SDavid Chisnall return false; 30497a984708SDavid Chisnall } 30507a984708SDavid Chisnall for (++__b; __fd > 0; --__fd, ++__b) 30517a984708SDavid Chisnall { 30527a984708SDavid Chisnall if (__b == __e || !__ct.is(ctype_base::digit, *__b)) 30537a984708SDavid Chisnall { 30547a984708SDavid Chisnall __err |= ios_base::failbit; 30557a984708SDavid Chisnall return false; 30567a984708SDavid Chisnall } 30577a984708SDavid Chisnall if (__wn == __we) 30587a984708SDavid Chisnall __double_or_nothing(__wb, __wn, __we); 30597a984708SDavid Chisnall *__wn++ = *__b; 30607a984708SDavid Chisnall } 30617a984708SDavid Chisnall } 30627a984708SDavid Chisnall if (__wn == __wb.get()) 30637a984708SDavid Chisnall { 30647a984708SDavid Chisnall __err |= ios_base::failbit; 30657a984708SDavid Chisnall return false; 30667a984708SDavid Chisnall } 30677a984708SDavid Chisnall } 30687a984708SDavid Chisnall break; 30697a984708SDavid Chisnall } 30707a984708SDavid Chisnall } 30717a984708SDavid Chisnall if (__trailing_sign) 30727a984708SDavid Chisnall { 30737a984708SDavid Chisnall for (unsigned __i = 1; __i < __trailing_sign->size(); ++__i, ++__b) 30747a984708SDavid Chisnall { 30757a984708SDavid Chisnall if (__b == __e || *__b != (*__trailing_sign)[__i]) 30767a984708SDavid Chisnall { 30777a984708SDavid Chisnall __err |= ios_base::failbit; 30787a984708SDavid Chisnall return false; 30797a984708SDavid Chisnall } 30807a984708SDavid Chisnall } 30817a984708SDavid Chisnall } 30827a984708SDavid Chisnall if (__gb.get() != __gn) 30837a984708SDavid Chisnall { 30847a984708SDavid Chisnall ios_base::iostate __et = ios_base::goodbit; 30857a984708SDavid Chisnall __check_grouping(__grp, __gb.get(), __gn, __et); 30867a984708SDavid Chisnall if (__et) 30877a984708SDavid Chisnall { 30887a984708SDavid Chisnall __err |= ios_base::failbit; 30897a984708SDavid Chisnall return false; 30907a984708SDavid Chisnall } 30917a984708SDavid Chisnall } 30927a984708SDavid Chisnall return true; 30937a984708SDavid Chisnall} 30947a984708SDavid Chisnall 30957a984708SDavid Chisnalltemplate <class _CharT, class _InputIterator> 30967a984708SDavid Chisnall_InputIterator 30977a984708SDavid Chisnallmoney_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e, 30987a984708SDavid Chisnall bool __intl, ios_base& __iob, 30997a984708SDavid Chisnall ios_base::iostate& __err, 31007a984708SDavid Chisnall long double& __v) const 31017a984708SDavid Chisnall{ 310294e3ee44SDavid Chisnall const int __bz = 100; 31037a984708SDavid Chisnall char_type __wbuf[__bz]; 31047a984708SDavid Chisnall unique_ptr<char_type, void(*)(void*)> __wb(__wbuf, __do_nothing); 31057a984708SDavid Chisnall char_type* __wn; 31067a984708SDavid Chisnall char_type* __we = __wbuf + __bz; 31077a984708SDavid Chisnall locale __loc = __iob.getloc(); 31087a984708SDavid Chisnall const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__loc); 31097a984708SDavid Chisnall bool __neg = false; 31107a984708SDavid Chisnall if (__do_get(__b, __e, __intl, __loc, __iob.flags(), __err, __neg, __ct, 31117a984708SDavid Chisnall __wb, __wn, __we)) 31127a984708SDavid Chisnall { 31137a984708SDavid Chisnall const char __src[] = "0123456789"; 31147a984708SDavid Chisnall char_type __atoms[sizeof(__src)-1]; 31157a984708SDavid Chisnall __ct.widen(__src, __src + (sizeof(__src)-1), __atoms); 31167a984708SDavid Chisnall char __nbuf[__bz]; 31177a984708SDavid Chisnall char* __nc = __nbuf; 31187a984708SDavid Chisnall unique_ptr<char, void(*)(void*)> __h(0, free); 31197a984708SDavid Chisnall if (__wn - __wb.get() > __bz-2) 31207a984708SDavid Chisnall { 312194e3ee44SDavid Chisnall __h.reset((char*)malloc(static_cast<size_t>(__wn - __wb.get() + 2))); 31227a984708SDavid Chisnall if (__h.get() == 0) 31237a984708SDavid Chisnall __throw_bad_alloc(); 31247a984708SDavid Chisnall __nc = __h.get(); 31257a984708SDavid Chisnall } 31267a984708SDavid Chisnall if (__neg) 31277a984708SDavid Chisnall *__nc++ = '-'; 31287a984708SDavid Chisnall for (const char_type* __w = __wb.get(); __w < __wn; ++__w, ++__nc) 31291bf9f7c1SDimitry Andric *__nc = __src[find(__atoms, _VSTD::end(__atoms), *__w) - __atoms]; 31307a984708SDavid Chisnall *__nc = char(); 31317a984708SDavid Chisnall if (sscanf(__nbuf, "%Lf", &__v) != 1) 31327a984708SDavid Chisnall __throw_runtime_error("money_get error"); 31337a984708SDavid Chisnall } 31347a984708SDavid Chisnall if (__b == __e) 31357a984708SDavid Chisnall __err |= ios_base::eofbit; 31367a984708SDavid Chisnall return __b; 31377a984708SDavid Chisnall} 31387a984708SDavid Chisnall 31397a984708SDavid Chisnalltemplate <class _CharT, class _InputIterator> 31407a984708SDavid Chisnall_InputIterator 31417a984708SDavid Chisnallmoney_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e, 31427a984708SDavid Chisnall bool __intl, ios_base& __iob, 31437a984708SDavid Chisnall ios_base::iostate& __err, 31447a984708SDavid Chisnall string_type& __v) const 31457a984708SDavid Chisnall{ 314694e3ee44SDavid Chisnall const int __bz = 100; 31477a984708SDavid Chisnall char_type __wbuf[__bz]; 31487a984708SDavid Chisnall unique_ptr<char_type, void(*)(void*)> __wb(__wbuf, __do_nothing); 31497a984708SDavid Chisnall char_type* __wn; 31507a984708SDavid Chisnall char_type* __we = __wbuf + __bz; 31517a984708SDavid Chisnall locale __loc = __iob.getloc(); 31527a984708SDavid Chisnall const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__loc); 31537a984708SDavid Chisnall bool __neg = false; 31547a984708SDavid Chisnall if (__do_get(__b, __e, __intl, __loc, __iob.flags(), __err, __neg, __ct, 31557a984708SDavid Chisnall __wb, __wn, __we)) 31567a984708SDavid Chisnall { 31577a984708SDavid Chisnall __v.clear(); 31587a984708SDavid Chisnall if (__neg) 31597a984708SDavid Chisnall __v.push_back(__ct.widen('-')); 31607a984708SDavid Chisnall char_type __z = __ct.widen('0'); 31617a984708SDavid Chisnall char_type* __w; 31627a984708SDavid Chisnall for (__w = __wb.get(); __w < __wn-1; ++__w) 31637a984708SDavid Chisnall if (*__w != __z) 31647a984708SDavid Chisnall break; 31657a984708SDavid Chisnall __v.append(__w, __wn); 31667a984708SDavid Chisnall } 31677a984708SDavid Chisnall if (__b == __e) 31687a984708SDavid Chisnall __err |= ios_base::eofbit; 31697a984708SDavid Chisnall return __b; 31707a984708SDavid Chisnall} 31717a984708SDavid Chisnall 3172aed8d94eSDimitry Andric_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS money_get<char>) 3173aed8d94eSDimitry Andric_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS money_get<wchar_t>) 31747a984708SDavid Chisnall 31757a984708SDavid Chisnall// money_put 31767a984708SDavid Chisnall 31777a984708SDavid Chisnalltemplate <class _CharT> 31787a984708SDavid Chisnallclass __money_put 31797a984708SDavid Chisnall{ 31807a984708SDavid Chisnallprotected: 31817a984708SDavid Chisnall typedef _CharT char_type; 31827a984708SDavid Chisnall typedef basic_string<char_type> string_type; 31837a984708SDavid Chisnall 31844ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY __money_put() {} 31857a984708SDavid Chisnall 31867a984708SDavid Chisnall static void __gather_info(bool __intl, bool __neg, const locale& __loc, 31877a984708SDavid Chisnall money_base::pattern& __pat, char_type& __dp, 31887a984708SDavid Chisnall char_type& __ts, string& __grp, 31897a984708SDavid Chisnall string_type& __sym, string_type& __sn, 31907a984708SDavid Chisnall int& __fd); 31917a984708SDavid Chisnall static void __format(char_type* __mb, char_type*& __mi, char_type*& __me, 31927a984708SDavid Chisnall ios_base::fmtflags __flags, 31937a984708SDavid Chisnall const char_type* __db, const char_type* __de, 31947a984708SDavid Chisnall const ctype<char_type>& __ct, bool __neg, 31957a984708SDavid Chisnall const money_base::pattern& __pat, char_type __dp, 31967a984708SDavid Chisnall char_type __ts, const string& __grp, 31977a984708SDavid Chisnall const string_type& __sym, const string_type& __sn, 31987a984708SDavid Chisnall int __fd); 31997a984708SDavid Chisnall}; 32007a984708SDavid Chisnall 32017a984708SDavid Chisnalltemplate <class _CharT> 32027a984708SDavid Chisnallvoid 32037a984708SDavid Chisnall__money_put<_CharT>::__gather_info(bool __intl, bool __neg, const locale& __loc, 32047a984708SDavid Chisnall money_base::pattern& __pat, char_type& __dp, 32057a984708SDavid Chisnall char_type& __ts, string& __grp, 32067a984708SDavid Chisnall string_type& __sym, string_type& __sn, 32077a984708SDavid Chisnall int& __fd) 32087a984708SDavid Chisnall{ 32097a984708SDavid Chisnall if (__intl) 32107a984708SDavid Chisnall { 32117a984708SDavid Chisnall const moneypunct<char_type, true>& __mp = 32127a984708SDavid Chisnall use_facet<moneypunct<char_type, true> >(__loc); 32137a984708SDavid Chisnall if (__neg) 32147a984708SDavid Chisnall { 32157a984708SDavid Chisnall __pat = __mp.neg_format(); 32167a984708SDavid Chisnall __sn = __mp.negative_sign(); 32177a984708SDavid Chisnall } 32187a984708SDavid Chisnall else 32197a984708SDavid Chisnall { 32207a984708SDavid Chisnall __pat = __mp.pos_format(); 32217a984708SDavid Chisnall __sn = __mp.positive_sign(); 32227a984708SDavid Chisnall } 32237a984708SDavid Chisnall __dp = __mp.decimal_point(); 32247a984708SDavid Chisnall __ts = __mp.thousands_sep(); 32257a984708SDavid Chisnall __grp = __mp.grouping(); 32267a984708SDavid Chisnall __sym = __mp.curr_symbol(); 32277a984708SDavid Chisnall __fd = __mp.frac_digits(); 32287a984708SDavid Chisnall } 32297a984708SDavid Chisnall else 32307a984708SDavid Chisnall { 32317a984708SDavid Chisnall const moneypunct<char_type, false>& __mp = 32327a984708SDavid Chisnall use_facet<moneypunct<char_type, false> >(__loc); 32337a984708SDavid Chisnall if (__neg) 32347a984708SDavid Chisnall { 32357a984708SDavid Chisnall __pat = __mp.neg_format(); 32367a984708SDavid Chisnall __sn = __mp.negative_sign(); 32377a984708SDavid Chisnall } 32387a984708SDavid Chisnall else 32397a984708SDavid Chisnall { 32407a984708SDavid Chisnall __pat = __mp.pos_format(); 32417a984708SDavid Chisnall __sn = __mp.positive_sign(); 32427a984708SDavid Chisnall } 32437a984708SDavid Chisnall __dp = __mp.decimal_point(); 32447a984708SDavid Chisnall __ts = __mp.thousands_sep(); 32457a984708SDavid Chisnall __grp = __mp.grouping(); 32467a984708SDavid Chisnall __sym = __mp.curr_symbol(); 32477a984708SDavid Chisnall __fd = __mp.frac_digits(); 32487a984708SDavid Chisnall } 32497a984708SDavid Chisnall} 32507a984708SDavid Chisnall 32517a984708SDavid Chisnalltemplate <class _CharT> 32527a984708SDavid Chisnallvoid 32537a984708SDavid Chisnall__money_put<_CharT>::__format(char_type* __mb, char_type*& __mi, char_type*& __me, 32547a984708SDavid Chisnall ios_base::fmtflags __flags, 32557a984708SDavid Chisnall const char_type* __db, const char_type* __de, 32567a984708SDavid Chisnall const ctype<char_type>& __ct, bool __neg, 32577a984708SDavid Chisnall const money_base::pattern& __pat, char_type __dp, 32587a984708SDavid Chisnall char_type __ts, const string& __grp, 32597a984708SDavid Chisnall const string_type& __sym, const string_type& __sn, 32607a984708SDavid Chisnall int __fd) 32617a984708SDavid Chisnall{ 32627a984708SDavid Chisnall __me = __mb; 32637a984708SDavid Chisnall for (unsigned __p = 0; __p < 4; ++__p) 32647a984708SDavid Chisnall { 32657a984708SDavid Chisnall switch (__pat.field[__p]) 32667a984708SDavid Chisnall { 32677a984708SDavid Chisnall case money_base::none: 32687a984708SDavid Chisnall __mi = __me; 32697a984708SDavid Chisnall break; 32707a984708SDavid Chisnall case money_base::space: 32717a984708SDavid Chisnall __mi = __me; 32727a984708SDavid Chisnall *__me++ = __ct.widen(' '); 32737a984708SDavid Chisnall break; 32747a984708SDavid Chisnall case money_base::sign: 32757a984708SDavid Chisnall if (!__sn.empty()) 32767a984708SDavid Chisnall *__me++ = __sn[0]; 32777a984708SDavid Chisnall break; 32787a984708SDavid Chisnall case money_base::symbol: 32797a984708SDavid Chisnall if (!__sym.empty() && (__flags & ios_base::showbase)) 32807a984708SDavid Chisnall __me = _VSTD::copy(__sym.begin(), __sym.end(), __me); 32817a984708SDavid Chisnall break; 32827a984708SDavid Chisnall case money_base::value: 32837a984708SDavid Chisnall { 32847a984708SDavid Chisnall // remember start of value so we can reverse it 32857a984708SDavid Chisnall char_type* __t = __me; 32867a984708SDavid Chisnall // find beginning of digits 32877a984708SDavid Chisnall if (__neg) 32887a984708SDavid Chisnall ++__db; 32897a984708SDavid Chisnall // find end of digits 32907a984708SDavid Chisnall const char_type* __d; 32917a984708SDavid Chisnall for (__d = __db; __d < __de; ++__d) 32927a984708SDavid Chisnall if (!__ct.is(ctype_base::digit, *__d)) 32937a984708SDavid Chisnall break; 32947a984708SDavid Chisnall // print fractional part 32957a984708SDavid Chisnall if (__fd > 0) 32967a984708SDavid Chisnall { 32977a984708SDavid Chisnall int __f; 32987a984708SDavid Chisnall for (__f = __fd; __d > __db && __f > 0; --__f) 32997a984708SDavid Chisnall *__me++ = *--__d; 33007a984708SDavid Chisnall char_type __z = __f > 0 ? __ct.widen('0') : char_type(); 33017a984708SDavid Chisnall for (; __f > 0; --__f) 33027a984708SDavid Chisnall *__me++ = __z; 33037a984708SDavid Chisnall *__me++ = __dp; 33047a984708SDavid Chisnall } 33057a984708SDavid Chisnall // print units part 33067a984708SDavid Chisnall if (__d == __db) 33077a984708SDavid Chisnall { 33087a984708SDavid Chisnall *__me++ = __ct.widen('0'); 33097a984708SDavid Chisnall } 33107a984708SDavid Chisnall else 33117a984708SDavid Chisnall { 33127a984708SDavid Chisnall unsigned __ng = 0; 33137a984708SDavid Chisnall unsigned __ig = 0; 33147a984708SDavid Chisnall unsigned __gl = __grp.empty() ? numeric_limits<unsigned>::max() 33157a984708SDavid Chisnall : static_cast<unsigned>(__grp[__ig]); 33167a984708SDavid Chisnall while (__d != __db) 33177a984708SDavid Chisnall { 33187a984708SDavid Chisnall if (__ng == __gl) 33197a984708SDavid Chisnall { 33207a984708SDavid Chisnall *__me++ = __ts; 33217a984708SDavid Chisnall __ng = 0; 33227a984708SDavid Chisnall if (++__ig < __grp.size()) 33237a984708SDavid Chisnall __gl = __grp[__ig] == numeric_limits<char>::max() ? 33247a984708SDavid Chisnall numeric_limits<unsigned>::max() : 33257a984708SDavid Chisnall static_cast<unsigned>(__grp[__ig]); 33267a984708SDavid Chisnall } 33277a984708SDavid Chisnall *__me++ = *--__d; 33287a984708SDavid Chisnall ++__ng; 33297a984708SDavid Chisnall } 33307a984708SDavid Chisnall } 33317a984708SDavid Chisnall // reverse it 33327a984708SDavid Chisnall reverse(__t, __me); 33337a984708SDavid Chisnall } 33347a984708SDavid Chisnall break; 33357a984708SDavid Chisnall } 33367a984708SDavid Chisnall } 33377a984708SDavid Chisnall // print rest of sign, if any 33387a984708SDavid Chisnall if (__sn.size() > 1) 33397a984708SDavid Chisnall __me = _VSTD::copy(__sn.begin()+1, __sn.end(), __me); 33407a984708SDavid Chisnall // set alignment 33417a984708SDavid Chisnall if ((__flags & ios_base::adjustfield) == ios_base::left) 33427a984708SDavid Chisnall __mi = __me; 33437a984708SDavid Chisnall else if ((__flags & ios_base::adjustfield) != ios_base::internal) 33447a984708SDavid Chisnall __mi = __mb; 33457a984708SDavid Chisnall} 33467a984708SDavid Chisnall 3347aed8d94eSDimitry Andric_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __money_put<char>) 3348aed8d94eSDimitry Andric_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __money_put<wchar_t>) 33497a984708SDavid Chisnall 33507a984708SDavid Chisnalltemplate <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> > 3351aed8d94eSDimitry Andricclass _LIBCPP_TEMPLATE_VIS money_put 33527a984708SDavid Chisnall : public locale::facet, 33537a984708SDavid Chisnall private __money_put<_CharT> 33547a984708SDavid Chisnall{ 33557a984708SDavid Chisnallpublic: 33567a984708SDavid Chisnall typedef _CharT char_type; 33577a984708SDavid Chisnall typedef _OutputIterator iter_type; 33587a984708SDavid Chisnall typedef basic_string<char_type> string_type; 33597a984708SDavid Chisnall 33604ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 33617a984708SDavid Chisnall explicit money_put(size_t __refs = 0) 33627a984708SDavid Chisnall : locale::facet(__refs) {} 33637a984708SDavid Chisnall 33644ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 33657a984708SDavid Chisnall iter_type put(iter_type __s, bool __intl, ios_base& __iob, char_type __fl, 33667a984708SDavid Chisnall long double __units) const 33677a984708SDavid Chisnall { 33687a984708SDavid Chisnall return do_put(__s, __intl, __iob, __fl, __units); 33697a984708SDavid Chisnall } 33707a984708SDavid Chisnall 33714ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 33727a984708SDavid Chisnall iter_type put(iter_type __s, bool __intl, ios_base& __iob, char_type __fl, 33737a984708SDavid Chisnall const string_type& __digits) const 33747a984708SDavid Chisnall { 33757a984708SDavid Chisnall return do_put(__s, __intl, __iob, __fl, __digits); 33767a984708SDavid Chisnall } 33777a984708SDavid Chisnall 33787a984708SDavid Chisnall static locale::id id; 33797a984708SDavid Chisnall 33807a984708SDavid Chisnallprotected: 33814ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 33827a984708SDavid Chisnall ~money_put() {} 33837a984708SDavid Chisnall 33847a984708SDavid Chisnall virtual iter_type do_put(iter_type __s, bool __intl, ios_base& __iob, 33857a984708SDavid Chisnall char_type __fl, long double __units) const; 33867a984708SDavid Chisnall virtual iter_type do_put(iter_type __s, bool __intl, ios_base& __iob, 33877a984708SDavid Chisnall char_type __fl, const string_type& __digits) const; 33887a984708SDavid Chisnall}; 33897a984708SDavid Chisnall 33907a984708SDavid Chisnalltemplate <class _CharT, class _OutputIterator> 33917a984708SDavid Chisnalllocale::id 33927a984708SDavid Chisnallmoney_put<_CharT, _OutputIterator>::id; 33937a984708SDavid Chisnall 33947a984708SDavid Chisnalltemplate <class _CharT, class _OutputIterator> 33957a984708SDavid Chisnall_OutputIterator 33967a984708SDavid Chisnallmoney_put<_CharT, _OutputIterator>::do_put(iter_type __s, bool __intl, 33977a984708SDavid Chisnall ios_base& __iob, char_type __fl, 33987a984708SDavid Chisnall long double __units) const 33997a984708SDavid Chisnall{ 34007a984708SDavid Chisnall // convert to char 34017a984708SDavid Chisnall const size_t __bs = 100; 34027a984708SDavid Chisnall char __buf[__bs]; 34037a984708SDavid Chisnall char* __bb = __buf; 34047a984708SDavid Chisnall char_type __digits[__bs]; 34057a984708SDavid Chisnall char_type* __db = __digits; 340694e3ee44SDavid Chisnall size_t __n = static_cast<size_t>(snprintf(__bb, __bs, "%.0Lf", __units)); 34077a984708SDavid Chisnall unique_ptr<char, void(*)(void*)> __hn(0, free); 34087a984708SDavid Chisnall unique_ptr<char_type, void(*)(void*)> __hd(0, free); 34097a984708SDavid Chisnall // secure memory for digit storage 34107a984708SDavid Chisnall if (__n > __bs-1) 34117a984708SDavid Chisnall { 34127c82a1ecSDimitry Andric __n = static_cast<size_t>(__libcpp_asprintf_l(&__bb, _LIBCPP_GET_C_LOCALE, "%.0Lf", __units)); 34137a984708SDavid Chisnall if (__bb == 0) 34147a984708SDavid Chisnall __throw_bad_alloc(); 34157a984708SDavid Chisnall __hn.reset(__bb); 34167a984708SDavid Chisnall __hd.reset((char_type*)malloc(__n * sizeof(char_type))); 341794e3ee44SDavid Chisnall if (__hd == nullptr) 34187a984708SDavid Chisnall __throw_bad_alloc(); 34197a984708SDavid Chisnall __db = __hd.get(); 34207a984708SDavid Chisnall } 34217a984708SDavid Chisnall // gather info 34227a984708SDavid Chisnall locale __loc = __iob.getloc(); 34237a984708SDavid Chisnall const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__loc); 34247a984708SDavid Chisnall __ct.widen(__bb, __bb + __n, __db); 34257a984708SDavid Chisnall bool __neg = __n > 0 && __bb[0] == '-'; 34267a984708SDavid Chisnall money_base::pattern __pat; 34277a984708SDavid Chisnall char_type __dp; 34287a984708SDavid Chisnall char_type __ts; 34297a984708SDavid Chisnall string __grp; 34307a984708SDavid Chisnall string_type __sym; 34317a984708SDavid Chisnall string_type __sn; 34327a984708SDavid Chisnall int __fd; 34337a984708SDavid Chisnall this->__gather_info(__intl, __neg, __loc, __pat, __dp, __ts, __grp, __sym, __sn, __fd); 34347a984708SDavid Chisnall // secure memory for formatting 34357a984708SDavid Chisnall char_type __mbuf[__bs]; 34367a984708SDavid Chisnall char_type* __mb = __mbuf; 34377a984708SDavid Chisnall unique_ptr<char_type, void(*)(void*)> __hw(0, free); 34387a984708SDavid Chisnall size_t __exn = static_cast<int>(__n) > __fd ? 343994e3ee44SDavid Chisnall (__n - static_cast<size_t>(__fd)) * 2 + __sn.size() + 344094e3ee44SDavid Chisnall __sym.size() + static_cast<size_t>(__fd) + 1 344194e3ee44SDavid Chisnall : __sn.size() + __sym.size() + static_cast<size_t>(__fd) + 2; 34427a984708SDavid Chisnall if (__exn > __bs) 34437a984708SDavid Chisnall { 34447a984708SDavid Chisnall __hw.reset((char_type*)malloc(__exn * sizeof(char_type))); 34457a984708SDavid Chisnall __mb = __hw.get(); 34467a984708SDavid Chisnall if (__mb == 0) 34477a984708SDavid Chisnall __throw_bad_alloc(); 34487a984708SDavid Chisnall } 34497a984708SDavid Chisnall // format 34507a984708SDavid Chisnall char_type* __mi; 34517a984708SDavid Chisnall char_type* __me; 34527a984708SDavid Chisnall this->__format(__mb, __mi, __me, __iob.flags(), 34537a984708SDavid Chisnall __db, __db + __n, __ct, 34547a984708SDavid Chisnall __neg, __pat, __dp, __ts, __grp, __sym, __sn, __fd); 34557a984708SDavid Chisnall return __pad_and_output(__s, __mb, __mi, __me, __iob, __fl); 34567a984708SDavid Chisnall} 34577a984708SDavid Chisnall 34587a984708SDavid Chisnalltemplate <class _CharT, class _OutputIterator> 34597a984708SDavid Chisnall_OutputIterator 34607a984708SDavid Chisnallmoney_put<_CharT, _OutputIterator>::do_put(iter_type __s, bool __intl, 34617a984708SDavid Chisnall ios_base& __iob, char_type __fl, 34627a984708SDavid Chisnall const string_type& __digits) const 34637a984708SDavid Chisnall{ 34647a984708SDavid Chisnall // gather info 34657a984708SDavid Chisnall locale __loc = __iob.getloc(); 34667a984708SDavid Chisnall const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__loc); 34677a984708SDavid Chisnall bool __neg = __digits.size() > 0 && __digits[0] == __ct.widen('-'); 34687a984708SDavid Chisnall money_base::pattern __pat; 34697a984708SDavid Chisnall char_type __dp; 34707a984708SDavid Chisnall char_type __ts; 34717a984708SDavid Chisnall string __grp; 34727a984708SDavid Chisnall string_type __sym; 34737a984708SDavid Chisnall string_type __sn; 34747a984708SDavid Chisnall int __fd; 34757a984708SDavid Chisnall this->__gather_info(__intl, __neg, __loc, __pat, __dp, __ts, __grp, __sym, __sn, __fd); 34767a984708SDavid Chisnall // secure memory for formatting 34777a984708SDavid Chisnall char_type __mbuf[100]; 34787a984708SDavid Chisnall char_type* __mb = __mbuf; 34797a984708SDavid Chisnall unique_ptr<char_type, void(*)(void*)> __h(0, free); 348094e3ee44SDavid Chisnall size_t __exn = static_cast<int>(__digits.size()) > __fd ? 348194e3ee44SDavid Chisnall (__digits.size() - static_cast<size_t>(__fd)) * 2 + 348294e3ee44SDavid Chisnall __sn.size() + __sym.size() + static_cast<size_t>(__fd) + 1 348394e3ee44SDavid Chisnall : __sn.size() + __sym.size() + static_cast<size_t>(__fd) + 2; 34847a984708SDavid Chisnall if (__exn > 100) 34857a984708SDavid Chisnall { 34867a984708SDavid Chisnall __h.reset((char_type*)malloc(__exn * sizeof(char_type))); 34877a984708SDavid Chisnall __mb = __h.get(); 34887a984708SDavid Chisnall if (__mb == 0) 34897a984708SDavid Chisnall __throw_bad_alloc(); 34907a984708SDavid Chisnall } 34917a984708SDavid Chisnall // format 34927a984708SDavid Chisnall char_type* __mi; 34937a984708SDavid Chisnall char_type* __me; 34947a984708SDavid Chisnall this->__format(__mb, __mi, __me, __iob.flags(), 34957a984708SDavid Chisnall __digits.data(), __digits.data() + __digits.size(), __ct, 34967a984708SDavid Chisnall __neg, __pat, __dp, __ts, __grp, __sym, __sn, __fd); 34977a984708SDavid Chisnall return __pad_and_output(__s, __mb, __mi, __me, __iob, __fl); 34987a984708SDavid Chisnall} 34997a984708SDavid Chisnall 3500aed8d94eSDimitry Andric_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS money_put<char>) 3501aed8d94eSDimitry Andric_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS money_put<wchar_t>) 35027a984708SDavid Chisnall 35037a984708SDavid Chisnall// messages 35047a984708SDavid Chisnall 35051bf9f7c1SDimitry Andricclass _LIBCPP_TYPE_VIS messages_base 35067a984708SDavid Chisnall{ 35077a984708SDavid Chisnallpublic: 35087a984708SDavid Chisnall typedef ptrdiff_t catalog; 35097a984708SDavid Chisnall 35104ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY messages_base() {} 35117a984708SDavid Chisnall}; 35127a984708SDavid Chisnall 35137a984708SDavid Chisnalltemplate <class _CharT> 3514aed8d94eSDimitry Andricclass _LIBCPP_TEMPLATE_VIS messages 35157a984708SDavid Chisnall : public locale::facet, 35167a984708SDavid Chisnall public messages_base 35177a984708SDavid Chisnall{ 35187a984708SDavid Chisnallpublic: 35197a984708SDavid Chisnall typedef _CharT char_type; 35207a984708SDavid Chisnall typedef basic_string<_CharT> string_type; 35217a984708SDavid Chisnall 35224ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 35237a984708SDavid Chisnall explicit messages(size_t __refs = 0) 35247a984708SDavid Chisnall : locale::facet(__refs) {} 35257a984708SDavid Chisnall 35264ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 35277a984708SDavid Chisnall catalog open(const basic_string<char>& __nm, const locale& __loc) const 35287a984708SDavid Chisnall { 35297a984708SDavid Chisnall return do_open(__nm, __loc); 35307a984708SDavid Chisnall } 35317a984708SDavid Chisnall 35324ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 35337a984708SDavid Chisnall string_type get(catalog __c, int __set, int __msgid, 35347a984708SDavid Chisnall const string_type& __dflt) const 35357a984708SDavid Chisnall { 35367a984708SDavid Chisnall return do_get(__c, __set, __msgid, __dflt); 35377a984708SDavid Chisnall } 35387a984708SDavid Chisnall 35394ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 35407a984708SDavid Chisnall void close(catalog __c) const 35417a984708SDavid Chisnall { 35427a984708SDavid Chisnall do_close(__c); 35437a984708SDavid Chisnall } 35447a984708SDavid Chisnall 35457a984708SDavid Chisnall static locale::id id; 35467a984708SDavid Chisnall 35477a984708SDavid Chisnallprotected: 35484ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 35497a984708SDavid Chisnall ~messages() {} 35507a984708SDavid Chisnall 35517a984708SDavid Chisnall virtual catalog do_open(const basic_string<char>&, const locale&) const; 35527a984708SDavid Chisnall virtual string_type do_get(catalog, int __set, int __msgid, 35537a984708SDavid Chisnall const string_type& __dflt) const; 35547a984708SDavid Chisnall virtual void do_close(catalog) const; 35557a984708SDavid Chisnall}; 35567a984708SDavid Chisnall 35577a984708SDavid Chisnalltemplate <class _CharT> 35587a984708SDavid Chisnalllocale::id 35597a984708SDavid Chisnallmessages<_CharT>::id; 35607a984708SDavid Chisnall 35617a984708SDavid Chisnalltemplate <class _CharT> 35627a984708SDavid Chisnalltypename messages<_CharT>::catalog 35637a984708SDavid Chisnallmessages<_CharT>::do_open(const basic_string<char>& __nm, const locale&) const 35647a984708SDavid Chisnall{ 3565854fa44bSDimitry Andric#ifdef _LIBCPP_HAS_CATOPEN 35667a984708SDavid Chisnall catalog __cat = (catalog)catopen(__nm.c_str(), NL_CAT_LOCALE); 35677a984708SDavid Chisnall if (__cat != -1) 35687a984708SDavid Chisnall __cat = static_cast<catalog>((static_cast<size_t>(__cat) >> 1)); 35697a984708SDavid Chisnall return __cat; 3570854fa44bSDimitry Andric#else // !_LIBCPP_HAS_CATOPEN 3571*b5893f02SDimitry Andric _LIBCPP_UNUSED_VAR(__nm); 3572854fa44bSDimitry Andric return -1; 3573854fa44bSDimitry Andric#endif // _LIBCPP_HAS_CATOPEN 35747a984708SDavid Chisnall} 35757a984708SDavid Chisnall 35767a984708SDavid Chisnalltemplate <class _CharT> 35777a984708SDavid Chisnalltypename messages<_CharT>::string_type 35787a984708SDavid Chisnallmessages<_CharT>::do_get(catalog __c, int __set, int __msgid, 35797a984708SDavid Chisnall const string_type& __dflt) const 35807a984708SDavid Chisnall{ 3581854fa44bSDimitry Andric#ifdef _LIBCPP_HAS_CATOPEN 35827a984708SDavid Chisnall string __ndflt; 35837a984708SDavid Chisnall __narrow_to_utf8<sizeof(char_type)*__CHAR_BIT__>()(back_inserter(__ndflt), 35847a984708SDavid Chisnall __dflt.c_str(), 35857a984708SDavid Chisnall __dflt.c_str() + __dflt.size()); 35867a984708SDavid Chisnall if (__c != -1) 35877a984708SDavid Chisnall __c <<= 1; 35887a984708SDavid Chisnall nl_catd __cat = (nl_catd)__c; 35897a984708SDavid Chisnall char* __n = catgets(__cat, __set, __msgid, __ndflt.c_str()); 35907a984708SDavid Chisnall string_type __w; 35917a984708SDavid Chisnall __widen_from_utf8<sizeof(char_type)*__CHAR_BIT__>()(back_inserter(__w), 35927a984708SDavid Chisnall __n, __n + strlen(__n)); 35937a984708SDavid Chisnall return __w; 3594854fa44bSDimitry Andric#else // !_LIBCPP_HAS_CATOPEN 3595*b5893f02SDimitry Andric _LIBCPP_UNUSED_VAR(__c); 3596*b5893f02SDimitry Andric _LIBCPP_UNUSED_VAR(__set); 3597*b5893f02SDimitry Andric _LIBCPP_UNUSED_VAR(__msgid); 3598854fa44bSDimitry Andric return __dflt; 3599854fa44bSDimitry Andric#endif // _LIBCPP_HAS_CATOPEN 36007a984708SDavid Chisnall} 36017a984708SDavid Chisnall 36027a984708SDavid Chisnalltemplate <class _CharT> 36037a984708SDavid Chisnallvoid 36047a984708SDavid Chisnallmessages<_CharT>::do_close(catalog __c) const 36057a984708SDavid Chisnall{ 3606854fa44bSDimitry Andric#ifdef _LIBCPP_HAS_CATOPEN 36077a984708SDavid Chisnall if (__c != -1) 36087a984708SDavid Chisnall __c <<= 1; 36097a984708SDavid Chisnall nl_catd __cat = (nl_catd)__c; 36107a984708SDavid Chisnall catclose(__cat); 3611*b5893f02SDimitry Andric#else // !_LIBCPP_HAS_CATOPEN 3612*b5893f02SDimitry Andric _LIBCPP_UNUSED_VAR(__c); 3613854fa44bSDimitry Andric#endif // _LIBCPP_HAS_CATOPEN 36147a984708SDavid Chisnall} 36157a984708SDavid Chisnall 3616aed8d94eSDimitry Andric_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS messages<char>) 3617aed8d94eSDimitry Andric_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS messages<wchar_t>) 36187a984708SDavid Chisnall 36197a984708SDavid Chisnalltemplate <class _CharT> 3620aed8d94eSDimitry Andricclass _LIBCPP_TEMPLATE_VIS messages_byname 36217a984708SDavid Chisnall : public messages<_CharT> 36227a984708SDavid Chisnall{ 36237a984708SDavid Chisnallpublic: 36247a984708SDavid Chisnall typedef messages_base::catalog catalog; 36257a984708SDavid Chisnall typedef basic_string<_CharT> string_type; 36267a984708SDavid Chisnall 36274ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 36287a984708SDavid Chisnall explicit messages_byname(const char*, size_t __refs = 0) 36297a984708SDavid Chisnall : messages<_CharT>(__refs) {} 36307a984708SDavid Chisnall 36314ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 36327a984708SDavid Chisnall explicit messages_byname(const string&, size_t __refs = 0) 36337a984708SDavid Chisnall : messages<_CharT>(__refs) {} 36347a984708SDavid Chisnall 36357a984708SDavid Chisnallprotected: 36364ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 36377a984708SDavid Chisnall ~messages_byname() {} 36387a984708SDavid Chisnall}; 36397a984708SDavid Chisnall 3640aed8d94eSDimitry Andric_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS messages_byname<char>) 3641aed8d94eSDimitry Andric_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS messages_byname<wchar_t>) 36427a984708SDavid Chisnall 36437a984708SDavid Chisnalltemplate<class _Codecvt, class _Elem = wchar_t, 36447a984708SDavid Chisnall class _Wide_alloc = allocator<_Elem>, 36457a984708SDavid Chisnall class _Byte_alloc = allocator<char> > 3646aed8d94eSDimitry Andricclass _LIBCPP_TEMPLATE_VIS wstring_convert 36477a984708SDavid Chisnall{ 36487a984708SDavid Chisnallpublic: 36497a984708SDavid Chisnall typedef basic_string<char, char_traits<char>, _Byte_alloc> byte_string; 36507a984708SDavid Chisnall typedef basic_string<_Elem, char_traits<_Elem>, _Wide_alloc> wide_string; 36517a984708SDavid Chisnall typedef typename _Codecvt::state_type state_type; 36527a984708SDavid Chisnall typedef typename wide_string::traits_type::int_type int_type; 36537a984708SDavid Chisnall 36547a984708SDavid Chisnallprivate: 36557a984708SDavid Chisnall byte_string __byte_err_string_; 36567a984708SDavid Chisnall wide_string __wide_err_string_; 36577a984708SDavid Chisnall _Codecvt* __cvtptr_; 36587a984708SDavid Chisnall state_type __cvtstate_; 36597a984708SDavid Chisnall size_t __cvtcount_; 36607a984708SDavid Chisnall 36617a984708SDavid Chisnall wstring_convert(const wstring_convert& __wc); 36627a984708SDavid Chisnall wstring_convert& operator=(const wstring_convert& __wc); 36637a984708SDavid Chisnallpublic: 36644ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 36654f7ab58eSDimitry Andric _LIBCPP_EXPLICIT_AFTER_CXX11 wstring_convert(_Codecvt* __pcvt = new _Codecvt); 36664ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 36677a984708SDavid Chisnall wstring_convert(_Codecvt* __pcvt, state_type __state); 36684f7ab58eSDimitry Andric _LIBCPP_EXPLICIT_AFTER_CXX11 wstring_convert(const byte_string& __byte_err, 36697a984708SDavid Chisnall const wide_string& __wide_err = wide_string()); 3670540d2a8bSDimitry Andric#ifndef _LIBCPP_CXX03_LANG 36714ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 36727a984708SDavid Chisnall wstring_convert(wstring_convert&& __wc); 36737a984708SDavid Chisnall#endif 36747a984708SDavid Chisnall ~wstring_convert(); 36757a984708SDavid Chisnall 36764ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 36777a984708SDavid Chisnall wide_string from_bytes(char __byte) 36787a984708SDavid Chisnall {return from_bytes(&__byte, &__byte+1);} 36794ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 36807a984708SDavid Chisnall wide_string from_bytes(const char* __ptr) 36817a984708SDavid Chisnall {return from_bytes(__ptr, __ptr + char_traits<char>::length(__ptr));} 36824ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 36837a984708SDavid Chisnall wide_string from_bytes(const byte_string& __str) 36847a984708SDavid Chisnall {return from_bytes(__str.data(), __str.data() + __str.size());} 36857a984708SDavid Chisnall wide_string from_bytes(const char* __first, const char* __last); 36867a984708SDavid Chisnall 36874ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 36887a984708SDavid Chisnall byte_string to_bytes(_Elem __wchar) 36897a984708SDavid Chisnall {return to_bytes(&__wchar, &__wchar+1);} 36904ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 36917a984708SDavid Chisnall byte_string to_bytes(const _Elem* __wptr) 36927a984708SDavid Chisnall {return to_bytes(__wptr, __wptr + char_traits<_Elem>::length(__wptr));} 36934ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 36947a984708SDavid Chisnall byte_string to_bytes(const wide_string& __wstr) 36957a984708SDavid Chisnall {return to_bytes(__wstr.data(), __wstr.data() + __wstr.size());} 36967a984708SDavid Chisnall byte_string to_bytes(const _Elem* __first, const _Elem* __last); 36977a984708SDavid Chisnall 36984ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 36994f7ab58eSDimitry Andric size_t converted() const _NOEXCEPT {return __cvtcount_;} 37004ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 37017a984708SDavid Chisnall state_type state() const {return __cvtstate_;} 37027a984708SDavid Chisnall}; 37037a984708SDavid Chisnall 37047a984708SDavid Chisnalltemplate<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc> 37059729cf09SDimitry Andricinline 37067a984708SDavid Chisnallwstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>:: 37077a984708SDavid Chisnall wstring_convert(_Codecvt* __pcvt) 37087a984708SDavid Chisnall : __cvtptr_(__pcvt), __cvtstate_(), __cvtcount_(0) 37097a984708SDavid Chisnall{ 37107a984708SDavid Chisnall} 37117a984708SDavid Chisnall 37127a984708SDavid Chisnalltemplate<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc> 37139729cf09SDimitry Andricinline 37147a984708SDavid Chisnallwstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>:: 37157a984708SDavid Chisnall wstring_convert(_Codecvt* __pcvt, state_type __state) 37167a984708SDavid Chisnall : __cvtptr_(__pcvt), __cvtstate_(__state), __cvtcount_(0) 37177a984708SDavid Chisnall{ 37187a984708SDavid Chisnall} 37197a984708SDavid Chisnall 37207a984708SDavid Chisnalltemplate<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc> 37217a984708SDavid Chisnallwstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>:: 37227a984708SDavid Chisnall wstring_convert(const byte_string& __byte_err, const wide_string& __wide_err) 37237a984708SDavid Chisnall : __byte_err_string_(__byte_err), __wide_err_string_(__wide_err), 37247a984708SDavid Chisnall __cvtstate_(), __cvtcount_(0) 37257a984708SDavid Chisnall{ 37267a984708SDavid Chisnall __cvtptr_ = new _Codecvt; 37277a984708SDavid Chisnall} 37287a984708SDavid Chisnall 3729540d2a8bSDimitry Andric#ifndef _LIBCPP_CXX03_LANG 37307a984708SDavid Chisnall 37317a984708SDavid Chisnalltemplate<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc> 37329729cf09SDimitry Andricinline 37337a984708SDavid Chisnallwstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>:: 37347a984708SDavid Chisnall wstring_convert(wstring_convert&& __wc) 37357a984708SDavid Chisnall : __byte_err_string_(_VSTD::move(__wc.__byte_err_string_)), 37367a984708SDavid Chisnall __wide_err_string_(_VSTD::move(__wc.__wide_err_string_)), 37377a984708SDavid Chisnall __cvtptr_(__wc.__cvtptr_), 37387c82a1ecSDimitry Andric __cvtstate_(__wc.__cvtstate_), __cvtcount_(__wc.__cvtcount_) 37397a984708SDavid Chisnall{ 37407a984708SDavid Chisnall __wc.__cvtptr_ = nullptr; 37417a984708SDavid Chisnall} 37427a984708SDavid Chisnall 3743540d2a8bSDimitry Andric#endif // _LIBCPP_CXX03_LANG 37447a984708SDavid Chisnall 37457a984708SDavid Chisnalltemplate<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc> 37467a984708SDavid Chisnallwstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::~wstring_convert() 37477a984708SDavid Chisnall{ 37487a984708SDavid Chisnall delete __cvtptr_; 37497a984708SDavid Chisnall} 37507a984708SDavid Chisnall 37517a984708SDavid Chisnalltemplate<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc> 37527a984708SDavid Chisnalltypename wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::wide_string 37537a984708SDavid Chisnallwstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>:: 37547a984708SDavid Chisnall from_bytes(const char* __frm, const char* __frm_end) 37557a984708SDavid Chisnall{ 37567a984708SDavid Chisnall __cvtcount_ = 0; 37577a984708SDavid Chisnall if (__cvtptr_ != nullptr) 37587a984708SDavid Chisnall { 37597a984708SDavid Chisnall wide_string __ws(2*(__frm_end - __frm), _Elem()); 3760936e9439SDimitry Andric if (__frm != __frm_end) 37617a984708SDavid Chisnall __ws.resize(__ws.capacity()); 37627a984708SDavid Chisnall codecvt_base::result __r = codecvt_base::ok; 37637a984708SDavid Chisnall state_type __st = __cvtstate_; 37647a984708SDavid Chisnall if (__frm != __frm_end) 37657a984708SDavid Chisnall { 37667a984708SDavid Chisnall _Elem* __to = &__ws[0]; 37677a984708SDavid Chisnall _Elem* __to_end = __to + __ws.size(); 37687a984708SDavid Chisnall const char* __frm_nxt; 37697a984708SDavid Chisnall do 37707a984708SDavid Chisnall { 37717a984708SDavid Chisnall _Elem* __to_nxt; 37727a984708SDavid Chisnall __r = __cvtptr_->in(__st, __frm, __frm_end, __frm_nxt, 37737a984708SDavid Chisnall __to, __to_end, __to_nxt); 37747a984708SDavid Chisnall __cvtcount_ += __frm_nxt - __frm; 37757a984708SDavid Chisnall if (__frm_nxt == __frm) 37767a984708SDavid Chisnall { 37777a984708SDavid Chisnall __r = codecvt_base::error; 37787a984708SDavid Chisnall } 37797a984708SDavid Chisnall else if (__r == codecvt_base::noconv) 37807a984708SDavid Chisnall { 37817a984708SDavid Chisnall __ws.resize(__to - &__ws[0]); 37827a984708SDavid Chisnall // This only gets executed if _Elem is char 37837a984708SDavid Chisnall __ws.append((const _Elem*)__frm, (const _Elem*)__frm_end); 37847a984708SDavid Chisnall __frm = __frm_nxt; 37857a984708SDavid Chisnall __r = codecvt_base::ok; 37867a984708SDavid Chisnall } 37877a984708SDavid Chisnall else if (__r == codecvt_base::ok) 37887a984708SDavid Chisnall { 37897a984708SDavid Chisnall __ws.resize(__to_nxt - &__ws[0]); 37907a984708SDavid Chisnall __frm = __frm_nxt; 37917a984708SDavid Chisnall } 37927a984708SDavid Chisnall else if (__r == codecvt_base::partial) 37937a984708SDavid Chisnall { 37947a984708SDavid Chisnall ptrdiff_t __s = __to_nxt - &__ws[0]; 37957a984708SDavid Chisnall __ws.resize(2 * __s); 37967a984708SDavid Chisnall __to = &__ws[0] + __s; 37977a984708SDavid Chisnall __to_end = &__ws[0] + __ws.size(); 37987a984708SDavid Chisnall __frm = __frm_nxt; 37997a984708SDavid Chisnall } 38007a984708SDavid Chisnall } while (__r == codecvt_base::partial && __frm_nxt < __frm_end); 38017a984708SDavid Chisnall } 38027a984708SDavid Chisnall if (__r == codecvt_base::ok) 38037a984708SDavid Chisnall return __ws; 38047a984708SDavid Chisnall } 3805aed8d94eSDimitry Andric 38067a984708SDavid Chisnall if (__wide_err_string_.empty()) 3807aed8d94eSDimitry Andric __throw_range_error("wstring_convert: from_bytes error"); 3808aed8d94eSDimitry Andric 38097a984708SDavid Chisnall return __wide_err_string_; 38107a984708SDavid Chisnall} 38117a984708SDavid Chisnall 38127a984708SDavid Chisnalltemplate<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc> 38137a984708SDavid Chisnalltypename wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::byte_string 38147a984708SDavid Chisnallwstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>:: 38157a984708SDavid Chisnall to_bytes(const _Elem* __frm, const _Elem* __frm_end) 38167a984708SDavid Chisnall{ 38177a984708SDavid Chisnall __cvtcount_ = 0; 38187a984708SDavid Chisnall if (__cvtptr_ != nullptr) 38197a984708SDavid Chisnall { 38207a984708SDavid Chisnall byte_string __bs(2*(__frm_end - __frm), char()); 3821936e9439SDimitry Andric if (__frm != __frm_end) 38227a984708SDavid Chisnall __bs.resize(__bs.capacity()); 38237a984708SDavid Chisnall codecvt_base::result __r = codecvt_base::ok; 38247a984708SDavid Chisnall state_type __st = __cvtstate_; 38257a984708SDavid Chisnall if (__frm != __frm_end) 38267a984708SDavid Chisnall { 38277a984708SDavid Chisnall char* __to = &__bs[0]; 38287a984708SDavid Chisnall char* __to_end = __to + __bs.size(); 38297a984708SDavid Chisnall const _Elem* __frm_nxt; 38307a984708SDavid Chisnall do 38317a984708SDavid Chisnall { 38327a984708SDavid Chisnall char* __to_nxt; 38337a984708SDavid Chisnall __r = __cvtptr_->out(__st, __frm, __frm_end, __frm_nxt, 38347a984708SDavid Chisnall __to, __to_end, __to_nxt); 38357a984708SDavid Chisnall __cvtcount_ += __frm_nxt - __frm; 38367a984708SDavid Chisnall if (__frm_nxt == __frm) 38377a984708SDavid Chisnall { 38387a984708SDavid Chisnall __r = codecvt_base::error; 38397a984708SDavid Chisnall } 38407a984708SDavid Chisnall else if (__r == codecvt_base::noconv) 38417a984708SDavid Chisnall { 38427a984708SDavid Chisnall __bs.resize(__to - &__bs[0]); 38437a984708SDavid Chisnall // This only gets executed if _Elem is char 38447a984708SDavid Chisnall __bs.append((const char*)__frm, (const char*)__frm_end); 38457a984708SDavid Chisnall __frm = __frm_nxt; 38467a984708SDavid Chisnall __r = codecvt_base::ok; 38477a984708SDavid Chisnall } 38487a984708SDavid Chisnall else if (__r == codecvt_base::ok) 38497a984708SDavid Chisnall { 38507a984708SDavid Chisnall __bs.resize(__to_nxt - &__bs[0]); 38517a984708SDavid Chisnall __frm = __frm_nxt; 38527a984708SDavid Chisnall } 38537a984708SDavid Chisnall else if (__r == codecvt_base::partial) 38547a984708SDavid Chisnall { 38557a984708SDavid Chisnall ptrdiff_t __s = __to_nxt - &__bs[0]; 38567a984708SDavid Chisnall __bs.resize(2 * __s); 38577a984708SDavid Chisnall __to = &__bs[0] + __s; 38587a984708SDavid Chisnall __to_end = &__bs[0] + __bs.size(); 38597a984708SDavid Chisnall __frm = __frm_nxt; 38607a984708SDavid Chisnall } 38617a984708SDavid Chisnall } while (__r == codecvt_base::partial && __frm_nxt < __frm_end); 38627a984708SDavid Chisnall } 38637a984708SDavid Chisnall if (__r == codecvt_base::ok) 38647a984708SDavid Chisnall { 38657a984708SDavid Chisnall size_t __s = __bs.size(); 38667a984708SDavid Chisnall __bs.resize(__bs.capacity()); 38677a984708SDavid Chisnall char* __to = &__bs[0] + __s; 38687a984708SDavid Chisnall char* __to_end = __to + __bs.size(); 38697a984708SDavid Chisnall do 38707a984708SDavid Chisnall { 38717a984708SDavid Chisnall char* __to_nxt; 38727a984708SDavid Chisnall __r = __cvtptr_->unshift(__st, __to, __to_end, __to_nxt); 38737a984708SDavid Chisnall if (__r == codecvt_base::noconv) 38747a984708SDavid Chisnall { 38757a984708SDavid Chisnall __bs.resize(__to - &__bs[0]); 38767a984708SDavid Chisnall __r = codecvt_base::ok; 38777a984708SDavid Chisnall } 38787a984708SDavid Chisnall else if (__r == codecvt_base::ok) 38797a984708SDavid Chisnall { 38807a984708SDavid Chisnall __bs.resize(__to_nxt - &__bs[0]); 38817a984708SDavid Chisnall } 38827a984708SDavid Chisnall else if (__r == codecvt_base::partial) 38837a984708SDavid Chisnall { 388494e3ee44SDavid Chisnall ptrdiff_t __sp = __to_nxt - &__bs[0]; 388594e3ee44SDavid Chisnall __bs.resize(2 * __sp); 388694e3ee44SDavid Chisnall __to = &__bs[0] + __sp; 38877a984708SDavid Chisnall __to_end = &__bs[0] + __bs.size(); 38887a984708SDavid Chisnall } 38897a984708SDavid Chisnall } while (__r == codecvt_base::partial); 38907a984708SDavid Chisnall if (__r == codecvt_base::ok) 38917a984708SDavid Chisnall return __bs; 38927a984708SDavid Chisnall } 38937a984708SDavid Chisnall } 3894aed8d94eSDimitry Andric 38957a984708SDavid Chisnall if (__byte_err_string_.empty()) 3896aed8d94eSDimitry Andric __throw_range_error("wstring_convert: to_bytes error"); 3897aed8d94eSDimitry Andric 38987a984708SDavid Chisnall return __byte_err_string_; 38997a984708SDavid Chisnall} 39007a984708SDavid Chisnall 39017a984708SDavid Chisnalltemplate <class _Codecvt, class _Elem = wchar_t, class _Tr = char_traits<_Elem> > 3902aed8d94eSDimitry Andricclass _LIBCPP_TEMPLATE_VIS wbuffer_convert 39037a984708SDavid Chisnall : public basic_streambuf<_Elem, _Tr> 39047a984708SDavid Chisnall{ 39057a984708SDavid Chisnallpublic: 39067a984708SDavid Chisnall // types: 39077a984708SDavid Chisnall typedef _Elem char_type; 39087a984708SDavid Chisnall typedef _Tr traits_type; 39097a984708SDavid Chisnall typedef typename traits_type::int_type int_type; 39107a984708SDavid Chisnall typedef typename traits_type::pos_type pos_type; 39117a984708SDavid Chisnall typedef typename traits_type::off_type off_type; 39127a984708SDavid Chisnall typedef typename _Codecvt::state_type state_type; 39137a984708SDavid Chisnall 39147a984708SDavid Chisnallprivate: 39157a984708SDavid Chisnall char* __extbuf_; 39167a984708SDavid Chisnall const char* __extbufnext_; 39177a984708SDavid Chisnall const char* __extbufend_; 39187a984708SDavid Chisnall char __extbuf_min_[8]; 39197a984708SDavid Chisnall size_t __ebs_; 39207a984708SDavid Chisnall char_type* __intbuf_; 39217a984708SDavid Chisnall size_t __ibs_; 39227a984708SDavid Chisnall streambuf* __bufptr_; 39237a984708SDavid Chisnall _Codecvt* __cv_; 39247a984708SDavid Chisnall state_type __st_; 39257a984708SDavid Chisnall ios_base::openmode __cm_; 39267a984708SDavid Chisnall bool __owns_eb_; 39277a984708SDavid Chisnall bool __owns_ib_; 39287a984708SDavid Chisnall bool __always_noconv_; 39297a984708SDavid Chisnall 39307a984708SDavid Chisnall wbuffer_convert(const wbuffer_convert&); 39317a984708SDavid Chisnall wbuffer_convert& operator=(const wbuffer_convert&); 39327a984708SDavid Chisnallpublic: 39334f7ab58eSDimitry Andric _LIBCPP_EXPLICIT_AFTER_CXX11 wbuffer_convert(streambuf* __bytebuf = 0, 39344f7ab58eSDimitry Andric _Codecvt* __pcvt = new _Codecvt, state_type __state = state_type()); 39357a984708SDavid Chisnall ~wbuffer_convert(); 39367a984708SDavid Chisnall 39377a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 39387a984708SDavid Chisnall streambuf* rdbuf() const {return __bufptr_;} 39397a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 39407a984708SDavid Chisnall streambuf* rdbuf(streambuf* __bytebuf) 39417a984708SDavid Chisnall { 39427a984708SDavid Chisnall streambuf* __r = __bufptr_; 39437a984708SDavid Chisnall __bufptr_ = __bytebuf; 39447a984708SDavid Chisnall return __r; 39457a984708SDavid Chisnall } 39467a984708SDavid Chisnall 39477a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 39487a984708SDavid Chisnall state_type state() const {return __st_;} 39497a984708SDavid Chisnall 39507a984708SDavid Chisnallprotected: 39517a984708SDavid Chisnall virtual int_type underflow(); 39527a984708SDavid Chisnall virtual int_type pbackfail(int_type __c = traits_type::eof()); 39537a984708SDavid Chisnall virtual int_type overflow (int_type __c = traits_type::eof()); 39547a984708SDavid Chisnall virtual basic_streambuf<char_type, traits_type>* setbuf(char_type* __s, 39557a984708SDavid Chisnall streamsize __n); 39567a984708SDavid Chisnall virtual pos_type seekoff(off_type __off, ios_base::seekdir __way, 39577a984708SDavid Chisnall ios_base::openmode __wch = ios_base::in | ios_base::out); 39587a984708SDavid Chisnall virtual pos_type seekpos(pos_type __sp, 39597a984708SDavid Chisnall ios_base::openmode __wch = ios_base::in | ios_base::out); 39607a984708SDavid Chisnall virtual int sync(); 39617a984708SDavid Chisnall 39627a984708SDavid Chisnallprivate: 39637a984708SDavid Chisnall bool __read_mode(); 39647a984708SDavid Chisnall void __write_mode(); 39657a984708SDavid Chisnall wbuffer_convert* __close(); 39667a984708SDavid Chisnall}; 39677a984708SDavid Chisnall 39687a984708SDavid Chisnalltemplate <class _Codecvt, class _Elem, class _Tr> 39697a984708SDavid Chisnallwbuffer_convert<_Codecvt, _Elem, _Tr>:: 39707a984708SDavid Chisnall wbuffer_convert(streambuf* __bytebuf, _Codecvt* __pcvt, state_type __state) 39717a984708SDavid Chisnall : __extbuf_(0), 39727a984708SDavid Chisnall __extbufnext_(0), 39737a984708SDavid Chisnall __extbufend_(0), 39747a984708SDavid Chisnall __ebs_(0), 39757a984708SDavid Chisnall __intbuf_(0), 39767a984708SDavid Chisnall __ibs_(0), 39777a984708SDavid Chisnall __bufptr_(__bytebuf), 39787a984708SDavid Chisnall __cv_(__pcvt), 39797a984708SDavid Chisnall __st_(__state), 39807a984708SDavid Chisnall __cm_(0), 39817a984708SDavid Chisnall __owns_eb_(false), 39827a984708SDavid Chisnall __owns_ib_(false), 39837a984708SDavid Chisnall __always_noconv_(__cv_ ? __cv_->always_noconv() : false) 39847a984708SDavid Chisnall{ 39857a984708SDavid Chisnall setbuf(0, 4096); 39867a984708SDavid Chisnall} 39877a984708SDavid Chisnall 39887a984708SDavid Chisnalltemplate <class _Codecvt, class _Elem, class _Tr> 39897a984708SDavid Chisnallwbuffer_convert<_Codecvt, _Elem, _Tr>::~wbuffer_convert() 39907a984708SDavid Chisnall{ 39917a984708SDavid Chisnall __close(); 39927a984708SDavid Chisnall delete __cv_; 39937a984708SDavid Chisnall if (__owns_eb_) 39947a984708SDavid Chisnall delete [] __extbuf_; 39957a984708SDavid Chisnall if (__owns_ib_) 39967a984708SDavid Chisnall delete [] __intbuf_; 39977a984708SDavid Chisnall} 39987a984708SDavid Chisnall 39997a984708SDavid Chisnalltemplate <class _Codecvt, class _Elem, class _Tr> 40007a984708SDavid Chisnalltypename wbuffer_convert<_Codecvt, _Elem, _Tr>::int_type 40017a984708SDavid Chisnallwbuffer_convert<_Codecvt, _Elem, _Tr>::underflow() 40027a984708SDavid Chisnall{ 40037a984708SDavid Chisnall if (__cv_ == 0 || __bufptr_ == 0) 40047a984708SDavid Chisnall return traits_type::eof(); 40057a984708SDavid Chisnall bool __initial = __read_mode(); 40067a984708SDavid Chisnall char_type __1buf; 40077a984708SDavid Chisnall if (this->gptr() == 0) 40087a984708SDavid Chisnall this->setg(&__1buf, &__1buf+1, &__1buf+1); 40097a984708SDavid Chisnall const size_t __unget_sz = __initial ? 0 : min<size_t>((this->egptr() - this->eback()) / 2, 4); 40107a984708SDavid Chisnall int_type __c = traits_type::eof(); 40117a984708SDavid Chisnall if (this->gptr() == this->egptr()) 40127a984708SDavid Chisnall { 40137a984708SDavid Chisnall memmove(this->eback(), this->egptr() - __unget_sz, __unget_sz * sizeof(char_type)); 40147a984708SDavid Chisnall if (__always_noconv_) 40157a984708SDavid Chisnall { 40167a984708SDavid Chisnall streamsize __nmemb = static_cast<streamsize>(this->egptr() - this->eback() - __unget_sz); 40177a984708SDavid Chisnall __nmemb = __bufptr_->sgetn((char*)this->eback() + __unget_sz, __nmemb); 40187a984708SDavid Chisnall if (__nmemb != 0) 40197a984708SDavid Chisnall { 40207a984708SDavid Chisnall this->setg(this->eback(), 40217a984708SDavid Chisnall this->eback() + __unget_sz, 40227a984708SDavid Chisnall this->eback() + __unget_sz + __nmemb); 40237a984708SDavid Chisnall __c = *this->gptr(); 40247a984708SDavid Chisnall } 40257a984708SDavid Chisnall } 40267a984708SDavid Chisnall else 40277a984708SDavid Chisnall { 40287c82a1ecSDimitry Andric _LIBCPP_ASSERT(!(__extbufnext_ == NULL && (__extbufend_ != __extbufnext_)), "underflow moving from NULL" ); 40297c82a1ecSDimitry Andric if (__extbufend_ != __extbufnext_) 40307a984708SDavid Chisnall memmove(__extbuf_, __extbufnext_, __extbufend_ - __extbufnext_); 40317a984708SDavid Chisnall __extbufnext_ = __extbuf_ + (__extbufend_ - __extbufnext_); 40327a984708SDavid Chisnall __extbufend_ = __extbuf_ + (__extbuf_ == __extbuf_min_ ? sizeof(__extbuf_min_) : __ebs_); 40337a984708SDavid Chisnall streamsize __nmemb = _VSTD::min(static_cast<streamsize>(this->egptr() - this->eback() - __unget_sz), 40347a984708SDavid Chisnall static_cast<streamsize>(__extbufend_ - __extbufnext_)); 40357a984708SDavid Chisnall codecvt_base::result __r; 4036aed8d94eSDimitry Andric // FIXME: Do we ever need to restore the state here? 4037aed8d94eSDimitry Andric //state_type __svs = __st_; 40387a984708SDavid Chisnall streamsize __nr = __bufptr_->sgetn(const_cast<char*>(__extbufnext_), __nmemb); 40397a984708SDavid Chisnall if (__nr != 0) 40407a984708SDavid Chisnall { 40417a984708SDavid Chisnall __extbufend_ = __extbufnext_ + __nr; 40427a984708SDavid Chisnall char_type* __inext; 40437a984708SDavid Chisnall __r = __cv_->in(__st_, __extbuf_, __extbufend_, __extbufnext_, 40447a984708SDavid Chisnall this->eback() + __unget_sz, 40457a984708SDavid Chisnall this->egptr(), __inext); 40467a984708SDavid Chisnall if (__r == codecvt_base::noconv) 40477a984708SDavid Chisnall { 404824d58133SDimitry Andric this->setg((char_type*)__extbuf_, (char_type*)__extbuf_, 404924d58133SDimitry Andric (char_type*) const_cast<char *>(__extbufend_)); 40507a984708SDavid Chisnall __c = *this->gptr(); 40517a984708SDavid Chisnall } 40527a984708SDavid Chisnall else if (__inext != this->eback() + __unget_sz) 40537a984708SDavid Chisnall { 40547a984708SDavid Chisnall this->setg(this->eback(), this->eback() + __unget_sz, __inext); 40557a984708SDavid Chisnall __c = *this->gptr(); 40567a984708SDavid Chisnall } 40577a984708SDavid Chisnall } 40587a984708SDavid Chisnall } 40597a984708SDavid Chisnall } 40607a984708SDavid Chisnall else 40617a984708SDavid Chisnall __c = *this->gptr(); 40627a984708SDavid Chisnall if (this->eback() == &__1buf) 40637a984708SDavid Chisnall this->setg(0, 0, 0); 40647a984708SDavid Chisnall return __c; 40657a984708SDavid Chisnall} 40667a984708SDavid Chisnall 40677a984708SDavid Chisnalltemplate <class _Codecvt, class _Elem, class _Tr> 40687a984708SDavid Chisnalltypename wbuffer_convert<_Codecvt, _Elem, _Tr>::int_type 40697a984708SDavid Chisnallwbuffer_convert<_Codecvt, _Elem, _Tr>::pbackfail(int_type __c) 40707a984708SDavid Chisnall{ 40717a984708SDavid Chisnall if (__cv_ != 0 && __bufptr_ != 0 && this->eback() < this->gptr()) 40727a984708SDavid Chisnall { 40737a984708SDavid Chisnall if (traits_type::eq_int_type(__c, traits_type::eof())) 40747a984708SDavid Chisnall { 40757a984708SDavid Chisnall this->gbump(-1); 40767a984708SDavid Chisnall return traits_type::not_eof(__c); 40777a984708SDavid Chisnall } 40787a984708SDavid Chisnall if (traits_type::eq(traits_type::to_char_type(__c), this->gptr()[-1])) 40797a984708SDavid Chisnall { 40807a984708SDavid Chisnall this->gbump(-1); 40817a984708SDavid Chisnall *this->gptr() = traits_type::to_char_type(__c); 40827a984708SDavid Chisnall return __c; 40837a984708SDavid Chisnall } 40847a984708SDavid Chisnall } 40857a984708SDavid Chisnall return traits_type::eof(); 40867a984708SDavid Chisnall} 40877a984708SDavid Chisnall 40887a984708SDavid Chisnalltemplate <class _Codecvt, class _Elem, class _Tr> 40897a984708SDavid Chisnalltypename wbuffer_convert<_Codecvt, _Elem, _Tr>::int_type 40907a984708SDavid Chisnallwbuffer_convert<_Codecvt, _Elem, _Tr>::overflow(int_type __c) 40917a984708SDavid Chisnall{ 40927a984708SDavid Chisnall if (__cv_ == 0 || __bufptr_ == 0) 40937a984708SDavid Chisnall return traits_type::eof(); 40947a984708SDavid Chisnall __write_mode(); 40957a984708SDavid Chisnall char_type __1buf; 40967a984708SDavid Chisnall char_type* __pb_save = this->pbase(); 40977a984708SDavid Chisnall char_type* __epb_save = this->epptr(); 40987a984708SDavid Chisnall if (!traits_type::eq_int_type(__c, traits_type::eof())) 40997a984708SDavid Chisnall { 41007a984708SDavid Chisnall if (this->pptr() == 0) 41017a984708SDavid Chisnall this->setp(&__1buf, &__1buf+1); 41027a984708SDavid Chisnall *this->pptr() = traits_type::to_char_type(__c); 41037a984708SDavid Chisnall this->pbump(1); 41047a984708SDavid Chisnall } 41057a984708SDavid Chisnall if (this->pptr() != this->pbase()) 41067a984708SDavid Chisnall { 41077a984708SDavid Chisnall if (__always_noconv_) 41087a984708SDavid Chisnall { 41097a984708SDavid Chisnall streamsize __nmemb = static_cast<streamsize>(this->pptr() - this->pbase()); 41107a984708SDavid Chisnall if (__bufptr_->sputn((const char*)this->pbase(), __nmemb) != __nmemb) 41117a984708SDavid Chisnall return traits_type::eof(); 41127a984708SDavid Chisnall } 41137a984708SDavid Chisnall else 41147a984708SDavid Chisnall { 41157a984708SDavid Chisnall char* __extbe = __extbuf_; 41167a984708SDavid Chisnall codecvt_base::result __r; 41177a984708SDavid Chisnall do 41187a984708SDavid Chisnall { 41197a984708SDavid Chisnall const char_type* __e; 41207a984708SDavid Chisnall __r = __cv_->out(__st_, this->pbase(), this->pptr(), __e, 41217a984708SDavid Chisnall __extbuf_, __extbuf_ + __ebs_, __extbe); 41227a984708SDavid Chisnall if (__e == this->pbase()) 41237a984708SDavid Chisnall return traits_type::eof(); 41247a984708SDavid Chisnall if (__r == codecvt_base::noconv) 41257a984708SDavid Chisnall { 41267a984708SDavid Chisnall streamsize __nmemb = static_cast<size_t>(this->pptr() - this->pbase()); 41277a984708SDavid Chisnall if (__bufptr_->sputn((const char*)this->pbase(), __nmemb) != __nmemb) 41287a984708SDavid Chisnall return traits_type::eof(); 41297a984708SDavid Chisnall } 41307a984708SDavid Chisnall else if (__r == codecvt_base::ok || __r == codecvt_base::partial) 41317a984708SDavid Chisnall { 41327a984708SDavid Chisnall streamsize __nmemb = static_cast<size_t>(__extbe - __extbuf_); 41337a984708SDavid Chisnall if (__bufptr_->sputn(__extbuf_, __nmemb) != __nmemb) 41347a984708SDavid Chisnall return traits_type::eof(); 41357a984708SDavid Chisnall if (__r == codecvt_base::partial) 41367a984708SDavid Chisnall { 413724d58133SDimitry Andric this->setp(const_cast<char_type *>(__e), this->pptr()); 4138b2c7081bSDimitry Andric this->__pbump(this->epptr() - this->pbase()); 41397a984708SDavid Chisnall } 41407a984708SDavid Chisnall } 41417a984708SDavid Chisnall else 41427a984708SDavid Chisnall return traits_type::eof(); 41437a984708SDavid Chisnall } while (__r == codecvt_base::partial); 41447a984708SDavid Chisnall } 41457a984708SDavid Chisnall this->setp(__pb_save, __epb_save); 41467a984708SDavid Chisnall } 41477a984708SDavid Chisnall return traits_type::not_eof(__c); 41487a984708SDavid Chisnall} 41497a984708SDavid Chisnall 41507a984708SDavid Chisnalltemplate <class _Codecvt, class _Elem, class _Tr> 41517a984708SDavid Chisnallbasic_streambuf<_Elem, _Tr>* 41527a984708SDavid Chisnallwbuffer_convert<_Codecvt, _Elem, _Tr>::setbuf(char_type* __s, streamsize __n) 41537a984708SDavid Chisnall{ 41547a984708SDavid Chisnall this->setg(0, 0, 0); 41557a984708SDavid Chisnall this->setp(0, 0); 41567a984708SDavid Chisnall if (__owns_eb_) 41577a984708SDavid Chisnall delete [] __extbuf_; 41587a984708SDavid Chisnall if (__owns_ib_) 41597a984708SDavid Chisnall delete [] __intbuf_; 41607a984708SDavid Chisnall __ebs_ = __n; 41617a984708SDavid Chisnall if (__ebs_ > sizeof(__extbuf_min_)) 41627a984708SDavid Chisnall { 41637a984708SDavid Chisnall if (__always_noconv_ && __s) 41647a984708SDavid Chisnall { 41657a984708SDavid Chisnall __extbuf_ = (char*)__s; 41667a984708SDavid Chisnall __owns_eb_ = false; 41677a984708SDavid Chisnall } 41687a984708SDavid Chisnall else 41697a984708SDavid Chisnall { 41707a984708SDavid Chisnall __extbuf_ = new char[__ebs_]; 41717a984708SDavid Chisnall __owns_eb_ = true; 41727a984708SDavid Chisnall } 41737a984708SDavid Chisnall } 41747a984708SDavid Chisnall else 41757a984708SDavid Chisnall { 41767a984708SDavid Chisnall __extbuf_ = __extbuf_min_; 41777a984708SDavid Chisnall __ebs_ = sizeof(__extbuf_min_); 41787a984708SDavid Chisnall __owns_eb_ = false; 41797a984708SDavid Chisnall } 41807a984708SDavid Chisnall if (!__always_noconv_) 41817a984708SDavid Chisnall { 41827a984708SDavid Chisnall __ibs_ = max<streamsize>(__n, sizeof(__extbuf_min_)); 41837a984708SDavid Chisnall if (__s && __ibs_ >= sizeof(__extbuf_min_)) 41847a984708SDavid Chisnall { 41857a984708SDavid Chisnall __intbuf_ = __s; 41867a984708SDavid Chisnall __owns_ib_ = false; 41877a984708SDavid Chisnall } 41887a984708SDavid Chisnall else 41897a984708SDavid Chisnall { 41907a984708SDavid Chisnall __intbuf_ = new char_type[__ibs_]; 41917a984708SDavid Chisnall __owns_ib_ = true; 41927a984708SDavid Chisnall } 41937a984708SDavid Chisnall } 41947a984708SDavid Chisnall else 41957a984708SDavid Chisnall { 41967a984708SDavid Chisnall __ibs_ = 0; 41977a984708SDavid Chisnall __intbuf_ = 0; 41987a984708SDavid Chisnall __owns_ib_ = false; 41997a984708SDavid Chisnall } 42007a984708SDavid Chisnall return this; 42017a984708SDavid Chisnall} 42027a984708SDavid Chisnall 42037a984708SDavid Chisnalltemplate <class _Codecvt, class _Elem, class _Tr> 42047a984708SDavid Chisnalltypename wbuffer_convert<_Codecvt, _Elem, _Tr>::pos_type 42057a984708SDavid Chisnallwbuffer_convert<_Codecvt, _Elem, _Tr>::seekoff(off_type __off, ios_base::seekdir __way, 42067a984708SDavid Chisnall ios_base::openmode __om) 42077a984708SDavid Chisnall{ 42087a984708SDavid Chisnall int __width = __cv_->encoding(); 42097a984708SDavid Chisnall if (__cv_ == 0 || __bufptr_ == 0 || (__width <= 0 && __off != 0) || sync()) 42107a984708SDavid Chisnall return pos_type(off_type(-1)); 42119729cf09SDimitry Andric // __width > 0 || __off == 0, now check __way 42129729cf09SDimitry Andric if (__way != ios_base::beg && __way != ios_base::cur && __way != ios_base::end) 42137a984708SDavid Chisnall return pos_type(off_type(-1)); 42147a984708SDavid Chisnall pos_type __r = __bufptr_->pubseekoff(__width * __off, __way, __om); 42157a984708SDavid Chisnall __r.state(__st_); 42167a984708SDavid Chisnall return __r; 42177a984708SDavid Chisnall} 42187a984708SDavid Chisnall 42197a984708SDavid Chisnalltemplate <class _Codecvt, class _Elem, class _Tr> 42207a984708SDavid Chisnalltypename wbuffer_convert<_Codecvt, _Elem, _Tr>::pos_type 42217a984708SDavid Chisnallwbuffer_convert<_Codecvt, _Elem, _Tr>::seekpos(pos_type __sp, ios_base::openmode __wch) 42227a984708SDavid Chisnall{ 42237a984708SDavid Chisnall if (__cv_ == 0 || __bufptr_ == 0 || sync()) 42247a984708SDavid Chisnall return pos_type(off_type(-1)); 42257a984708SDavid Chisnall if (__bufptr_->pubseekpos(__sp, __wch) == pos_type(off_type(-1))) 42267a984708SDavid Chisnall return pos_type(off_type(-1)); 42277a984708SDavid Chisnall return __sp; 42287a984708SDavid Chisnall} 42297a984708SDavid Chisnall 42307a984708SDavid Chisnalltemplate <class _Codecvt, class _Elem, class _Tr> 42317a984708SDavid Chisnallint 42327a984708SDavid Chisnallwbuffer_convert<_Codecvt, _Elem, _Tr>::sync() 42337a984708SDavid Chisnall{ 42347a984708SDavid Chisnall if (__cv_ == 0 || __bufptr_ == 0) 42357a984708SDavid Chisnall return 0; 42367a984708SDavid Chisnall if (__cm_ & ios_base::out) 42377a984708SDavid Chisnall { 42387a984708SDavid Chisnall if (this->pptr() != this->pbase()) 42397a984708SDavid Chisnall if (overflow() == traits_type::eof()) 42407a984708SDavid Chisnall return -1; 42417a984708SDavid Chisnall codecvt_base::result __r; 42427a984708SDavid Chisnall do 42437a984708SDavid Chisnall { 42447a984708SDavid Chisnall char* __extbe; 42457a984708SDavid Chisnall __r = __cv_->unshift(__st_, __extbuf_, __extbuf_ + __ebs_, __extbe); 42467a984708SDavid Chisnall streamsize __nmemb = static_cast<streamsize>(__extbe - __extbuf_); 42477a984708SDavid Chisnall if (__bufptr_->sputn(__extbuf_, __nmemb) != __nmemb) 42487a984708SDavid Chisnall return -1; 42497a984708SDavid Chisnall } while (__r == codecvt_base::partial); 42507a984708SDavid Chisnall if (__r == codecvt_base::error) 42517a984708SDavid Chisnall return -1; 42527a984708SDavid Chisnall if (__bufptr_->pubsync()) 42537a984708SDavid Chisnall return -1; 42547a984708SDavid Chisnall } 42557a984708SDavid Chisnall else if (__cm_ & ios_base::in) 42567a984708SDavid Chisnall { 42577a984708SDavid Chisnall off_type __c; 42587a984708SDavid Chisnall if (__always_noconv_) 42597a984708SDavid Chisnall __c = this->egptr() - this->gptr(); 42607a984708SDavid Chisnall else 42617a984708SDavid Chisnall { 42627a984708SDavid Chisnall int __width = __cv_->encoding(); 42637a984708SDavid Chisnall __c = __extbufend_ - __extbufnext_; 42647a984708SDavid Chisnall if (__width > 0) 42657a984708SDavid Chisnall __c += __width * (this->egptr() - this->gptr()); 42667a984708SDavid Chisnall else 42677a984708SDavid Chisnall { 42687a984708SDavid Chisnall if (this->gptr() != this->egptr()) 42697a984708SDavid Chisnall { 42707a984708SDavid Chisnall reverse(this->gptr(), this->egptr()); 42717a984708SDavid Chisnall codecvt_base::result __r; 42727a984708SDavid Chisnall const char_type* __e = this->gptr(); 42737a984708SDavid Chisnall char* __extbe; 42747a984708SDavid Chisnall do 42757a984708SDavid Chisnall { 42767a984708SDavid Chisnall __r = __cv_->out(__st_, __e, this->egptr(), __e, 42777a984708SDavid Chisnall __extbuf_, __extbuf_ + __ebs_, __extbe); 42787a984708SDavid Chisnall switch (__r) 42797a984708SDavid Chisnall { 42807a984708SDavid Chisnall case codecvt_base::noconv: 42817a984708SDavid Chisnall __c += this->egptr() - this->gptr(); 42827a984708SDavid Chisnall break; 42837a984708SDavid Chisnall case codecvt_base::ok: 42847a984708SDavid Chisnall case codecvt_base::partial: 42857a984708SDavid Chisnall __c += __extbe - __extbuf_; 42867a984708SDavid Chisnall break; 42877a984708SDavid Chisnall default: 42887a984708SDavid Chisnall return -1; 42897a984708SDavid Chisnall } 42907a984708SDavid Chisnall } while (__r == codecvt_base::partial); 42917a984708SDavid Chisnall } 42927a984708SDavid Chisnall } 42937a984708SDavid Chisnall } 42947a984708SDavid Chisnall if (__bufptr_->pubseekoff(-__c, ios_base::cur, __cm_) == pos_type(off_type(-1))) 42957a984708SDavid Chisnall return -1; 42967a984708SDavid Chisnall this->setg(0, 0, 0); 42977a984708SDavid Chisnall __cm_ = 0; 42987a984708SDavid Chisnall } 42997a984708SDavid Chisnall return 0; 43007a984708SDavid Chisnall} 43017a984708SDavid Chisnall 43027a984708SDavid Chisnalltemplate <class _Codecvt, class _Elem, class _Tr> 43037a984708SDavid Chisnallbool 43047a984708SDavid Chisnallwbuffer_convert<_Codecvt, _Elem, _Tr>::__read_mode() 43057a984708SDavid Chisnall{ 43067a984708SDavid Chisnall if (!(__cm_ & ios_base::in)) 43077a984708SDavid Chisnall { 43087a984708SDavid Chisnall this->setp(0, 0); 43097a984708SDavid Chisnall if (__always_noconv_) 43107a984708SDavid Chisnall this->setg((char_type*)__extbuf_, 43117a984708SDavid Chisnall (char_type*)__extbuf_ + __ebs_, 43127a984708SDavid Chisnall (char_type*)__extbuf_ + __ebs_); 43137a984708SDavid Chisnall else 43147a984708SDavid Chisnall this->setg(__intbuf_, __intbuf_ + __ibs_, __intbuf_ + __ibs_); 43157a984708SDavid Chisnall __cm_ = ios_base::in; 43167a984708SDavid Chisnall return true; 43177a984708SDavid Chisnall } 43187a984708SDavid Chisnall return false; 43197a984708SDavid Chisnall} 43207a984708SDavid Chisnall 43217a984708SDavid Chisnalltemplate <class _Codecvt, class _Elem, class _Tr> 43227a984708SDavid Chisnallvoid 43237a984708SDavid Chisnallwbuffer_convert<_Codecvt, _Elem, _Tr>::__write_mode() 43247a984708SDavid Chisnall{ 43257a984708SDavid Chisnall if (!(__cm_ & ios_base::out)) 43267a984708SDavid Chisnall { 43277a984708SDavid Chisnall this->setg(0, 0, 0); 43287a984708SDavid Chisnall if (__ebs_ > sizeof(__extbuf_min_)) 43297a984708SDavid Chisnall { 43307a984708SDavid Chisnall if (__always_noconv_) 43317a984708SDavid Chisnall this->setp((char_type*)__extbuf_, 43327a984708SDavid Chisnall (char_type*)__extbuf_ + (__ebs_ - 1)); 43337a984708SDavid Chisnall else 43347a984708SDavid Chisnall this->setp(__intbuf_, __intbuf_ + (__ibs_ - 1)); 43357a984708SDavid Chisnall } 43367a984708SDavid Chisnall else 43377a984708SDavid Chisnall this->setp(0, 0); 43387a984708SDavid Chisnall __cm_ = ios_base::out; 43397a984708SDavid Chisnall } 43407a984708SDavid Chisnall} 43417a984708SDavid Chisnall 43427a984708SDavid Chisnalltemplate <class _Codecvt, class _Elem, class _Tr> 43437a984708SDavid Chisnallwbuffer_convert<_Codecvt, _Elem, _Tr>* 43447a984708SDavid Chisnallwbuffer_convert<_Codecvt, _Elem, _Tr>::__close() 43457a984708SDavid Chisnall{ 43467a984708SDavid Chisnall wbuffer_convert* __rt = 0; 43477a984708SDavid Chisnall if (__cv_ != 0 && __bufptr_ != 0) 43487a984708SDavid Chisnall { 43497a984708SDavid Chisnall __rt = this; 43507a984708SDavid Chisnall if ((__cm_ & ios_base::out) && sync()) 43517a984708SDavid Chisnall __rt = 0; 43527a984708SDavid Chisnall } 43537a984708SDavid Chisnall return __rt; 43547a984708SDavid Chisnall} 43557a984708SDavid Chisnall 43567a984708SDavid Chisnall_LIBCPP_END_NAMESPACE_STD 43577a984708SDavid Chisnall 4358f9448bf3SDimitry Andric_LIBCPP_POP_MACROS 4359f9448bf3SDimitry Andric 43607a984708SDavid Chisnall#endif // _LIBCPP_LOCALE 4361