xref: /minix3/external/bsd/libc++/dist/libcxx/src/locale.cpp (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
14684ddb6SLionel Sambuc //===------------------------- locale.cpp ---------------------------------===//
24684ddb6SLionel Sambuc //
34684ddb6SLionel Sambuc //                     The LLVM Compiler Infrastructure
44684ddb6SLionel Sambuc //
54684ddb6SLionel Sambuc // This file is dual licensed under the MIT and the University of Illinois Open
64684ddb6SLionel Sambuc // Source Licenses. See LICENSE.TXT for details.
74684ddb6SLionel Sambuc //
84684ddb6SLionel Sambuc //===----------------------------------------------------------------------===//
94684ddb6SLionel Sambuc 
104684ddb6SLionel Sambuc // On Solaris, we need to define something to make the C99 parts of localeconv
114684ddb6SLionel Sambuc // visible.
124684ddb6SLionel Sambuc #ifdef __sun__
134684ddb6SLionel Sambuc #define _LCONV_C99
144684ddb6SLionel Sambuc #endif
154684ddb6SLionel Sambuc 
164684ddb6SLionel Sambuc #include "string"
174684ddb6SLionel Sambuc #include "locale"
184684ddb6SLionel Sambuc #include "codecvt"
194684ddb6SLionel Sambuc #include "vector"
204684ddb6SLionel Sambuc #include "algorithm"
214684ddb6SLionel Sambuc #include "typeinfo"
224684ddb6SLionel Sambuc #ifndef _LIBCPP_NO_EXCEPTIONS
234684ddb6SLionel Sambuc #  include "type_traits"
244684ddb6SLionel Sambuc #endif
254684ddb6SLionel Sambuc #include "clocale"
264684ddb6SLionel Sambuc #include "cstring"
274684ddb6SLionel Sambuc #include "cwctype"
284684ddb6SLionel Sambuc #include "__sso_allocator"
294684ddb6SLionel Sambuc #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
30*0a6a1f1dSLionel Sambuc #include "support/win32/locale_win32.h"
31*0a6a1f1dSLionel Sambuc #elif !defined(__ANDROID__)
324684ddb6SLionel Sambuc #include <langinfo.h>
33*0a6a1f1dSLionel Sambuc #endif
344684ddb6SLionel Sambuc #include <stdlib.h>
354684ddb6SLionel Sambuc #include <stdio.h>
364684ddb6SLionel Sambuc 
374684ddb6SLionel Sambuc // On Linux, wint_t and wchar_t have different signed-ness, and this causes
384684ddb6SLionel Sambuc // lots of noise in the build log, but no bugs that I know of.
394684ddb6SLionel Sambuc #if defined(__clang__)
404684ddb6SLionel Sambuc #pragma clang diagnostic ignored "-Wsign-conversion"
414684ddb6SLionel Sambuc #endif
424684ddb6SLionel Sambuc 
434684ddb6SLionel Sambuc _LIBCPP_BEGIN_NAMESPACE_STD
444684ddb6SLionel Sambuc 
454684ddb6SLionel Sambuc #ifdef __cloc_defined
__cloc()464684ddb6SLionel Sambuc locale_t __cloc() {
474684ddb6SLionel Sambuc   // In theory this could create a race condition. In practice
484684ddb6SLionel Sambuc   // the race condition is non-fatal since it will just create
494684ddb6SLionel Sambuc   // a little resource leak. Better approach would be appreciated.
504684ddb6SLionel Sambuc   static locale_t result = newlocale(LC_ALL_MASK, "C", 0);
514684ddb6SLionel Sambuc   return result;
524684ddb6SLionel Sambuc }
534684ddb6SLionel Sambuc #endif // __cloc_defined
544684ddb6SLionel Sambuc 
554684ddb6SLionel Sambuc namespace {
564684ddb6SLionel Sambuc 
574684ddb6SLionel Sambuc struct release
584684ddb6SLionel Sambuc {
operator ()__anon5076b3680111::release594684ddb6SLionel Sambuc     void operator()(locale::facet* p) {p->__release_shared();}
604684ddb6SLionel Sambuc };
614684ddb6SLionel Sambuc 
624684ddb6SLionel Sambuc template <class T, class A0>
634684ddb6SLionel Sambuc inline
644684ddb6SLionel Sambuc T&
make(A0 a0)654684ddb6SLionel Sambuc make(A0 a0)
664684ddb6SLionel Sambuc {
674684ddb6SLionel Sambuc     static typename aligned_storage<sizeof(T)>::type buf;
684684ddb6SLionel Sambuc     ::new (&buf) T(a0);
69*0a6a1f1dSLionel Sambuc     return *reinterpret_cast<T*>(&buf);
704684ddb6SLionel Sambuc }
714684ddb6SLionel Sambuc 
724684ddb6SLionel Sambuc template <class T, class A0, class A1>
734684ddb6SLionel Sambuc inline
744684ddb6SLionel Sambuc T&
make(A0 a0,A1 a1)754684ddb6SLionel Sambuc make(A0 a0, A1 a1)
764684ddb6SLionel Sambuc {
774684ddb6SLionel Sambuc     static typename aligned_storage<sizeof(T)>::type buf;
784684ddb6SLionel Sambuc     ::new (&buf) T(a0, a1);
79*0a6a1f1dSLionel Sambuc     return *reinterpret_cast<T*>(&buf);
804684ddb6SLionel Sambuc }
814684ddb6SLionel Sambuc 
824684ddb6SLionel Sambuc template <class T, class A0, class A1, class A2>
834684ddb6SLionel Sambuc inline
844684ddb6SLionel Sambuc T&
make(A0 a0,A1 a1,A2 a2)854684ddb6SLionel Sambuc make(A0 a0, A1 a1, A2 a2)
864684ddb6SLionel Sambuc {
874684ddb6SLionel Sambuc     static typename aligned_storage<sizeof(T)>::type buf;
884684ddb6SLionel Sambuc     ::new (&buf) T(a0, a1, a2);
89*0a6a1f1dSLionel Sambuc     return *reinterpret_cast<T*>(&buf);
904684ddb6SLionel Sambuc }
914684ddb6SLionel Sambuc 
924684ddb6SLionel Sambuc template <typename T, size_t N>
934684ddb6SLionel Sambuc inline
944684ddb6SLionel Sambuc _LIBCPP_CONSTEXPR
954684ddb6SLionel Sambuc size_t
countof(const T (&)[N])964684ddb6SLionel Sambuc countof(const T (&)[N])
974684ddb6SLionel Sambuc {
984684ddb6SLionel Sambuc     return N;
994684ddb6SLionel Sambuc }
1004684ddb6SLionel Sambuc 
1014684ddb6SLionel Sambuc template <typename T>
1024684ddb6SLionel Sambuc inline
1034684ddb6SLionel Sambuc _LIBCPP_CONSTEXPR
1044684ddb6SLionel Sambuc size_t
countof(const T * const begin,const T * const end)1054684ddb6SLionel Sambuc countof(const T * const begin, const T * const end)
1064684ddb6SLionel Sambuc {
1074684ddb6SLionel Sambuc     return static_cast<size_t>(end - begin);
1084684ddb6SLionel Sambuc }
1094684ddb6SLionel Sambuc 
1104684ddb6SLionel Sambuc }
1114684ddb6SLionel Sambuc 
1124684ddb6SLionel Sambuc #if defined(_AIX)
1134684ddb6SLionel Sambuc // Set priority to INT_MIN + 256 + 150
1144684ddb6SLionel Sambuc # pragma priority ( -2147483242 )
1154684ddb6SLionel Sambuc #endif
1164684ddb6SLionel Sambuc 
1174684ddb6SLionel Sambuc const locale::category locale::none;
1184684ddb6SLionel Sambuc const locale::category locale::collate;
1194684ddb6SLionel Sambuc const locale::category locale::ctype;
1204684ddb6SLionel Sambuc const locale::category locale::monetary;
1214684ddb6SLionel Sambuc const locale::category locale::numeric;
1224684ddb6SLionel Sambuc const locale::category locale::time;
1234684ddb6SLionel Sambuc const locale::category locale::messages;
1244684ddb6SLionel Sambuc const locale::category locale::all;
1254684ddb6SLionel Sambuc 
1264684ddb6SLionel Sambuc #if defined(__clang__)
1274684ddb6SLionel Sambuc #pragma clang diagnostic push
1284684ddb6SLionel Sambuc #pragma clang diagnostic ignored "-Wpadded"
1294684ddb6SLionel Sambuc #endif
1304684ddb6SLionel Sambuc 
1314684ddb6SLionel Sambuc class _LIBCPP_HIDDEN locale::__imp
1324684ddb6SLionel Sambuc     : public facet
1334684ddb6SLionel Sambuc {
1344684ddb6SLionel Sambuc     enum {N = 28};
1354684ddb6SLionel Sambuc #if defined(_LIBCPP_MSVC)
1364684ddb6SLionel Sambuc // FIXME: MSVC doesn't support aligned parameters by value.
1374684ddb6SLionel Sambuc // I can't get the __sso_allocator to work here
1384684ddb6SLionel Sambuc // for MSVC I think for this reason.
1394684ddb6SLionel Sambuc     vector<facet*> facets_;
1404684ddb6SLionel Sambuc #else
1414684ddb6SLionel Sambuc     vector<facet*, __sso_allocator<facet*, N> > facets_;
1424684ddb6SLionel Sambuc #endif
1434684ddb6SLionel Sambuc     string         name_;
1444684ddb6SLionel Sambuc public:
1454684ddb6SLionel Sambuc     explicit __imp(size_t refs = 0);
1464684ddb6SLionel Sambuc     explicit __imp(const string& name, size_t refs = 0);
1474684ddb6SLionel Sambuc     __imp(const __imp&);
1484684ddb6SLionel Sambuc     __imp(const __imp&, const string&, locale::category c);
1494684ddb6SLionel Sambuc     __imp(const __imp& other, const __imp& one, locale::category c);
1504684ddb6SLionel Sambuc     __imp(const __imp&, facet* f, long id);
1514684ddb6SLionel Sambuc     ~__imp();
1524684ddb6SLionel Sambuc 
name() const1534684ddb6SLionel Sambuc     const string& name() const {return name_;}
has_facet(long id) const1544684ddb6SLionel Sambuc     bool has_facet(long id) const
1554684ddb6SLionel Sambuc         {return static_cast<size_t>(id) < facets_.size() && facets_[static_cast<size_t>(id)];}
1564684ddb6SLionel Sambuc     const locale::facet* use_facet(long id) const;
1574684ddb6SLionel Sambuc 
1584684ddb6SLionel Sambuc     static const locale& make_classic();
1594684ddb6SLionel Sambuc     static       locale& make_global();
1604684ddb6SLionel Sambuc private:
1614684ddb6SLionel Sambuc     void install(facet* f, long id);
install(F * f)1624684ddb6SLionel Sambuc     template <class F> void install(F* f) {install(f, f->id.__get());}
1634684ddb6SLionel Sambuc     template <class F> void install_from(const __imp& other);
1644684ddb6SLionel Sambuc };
1654684ddb6SLionel Sambuc 
1664684ddb6SLionel Sambuc #if defined(__clang__)
1674684ddb6SLionel Sambuc #pragma clang diagnostic pop
1684684ddb6SLionel Sambuc #endif
1694684ddb6SLionel Sambuc 
__imp(size_t refs)1704684ddb6SLionel Sambuc locale::__imp::__imp(size_t refs)
1714684ddb6SLionel Sambuc     : facet(refs),
1724684ddb6SLionel Sambuc       facets_(N),
1734684ddb6SLionel Sambuc       name_("C")
1744684ddb6SLionel Sambuc {
1754684ddb6SLionel Sambuc     facets_.clear();
1764684ddb6SLionel Sambuc     install(&make<_VSTD::collate<char> >(1u));
1774684ddb6SLionel Sambuc     install(&make<_VSTD::collate<wchar_t> >(1u));
178*0a6a1f1dSLionel Sambuc     install(&make<_VSTD::ctype<char> >(nullptr, false, 1u));
1794684ddb6SLionel Sambuc     install(&make<_VSTD::ctype<wchar_t> >(1u));
1804684ddb6SLionel Sambuc     install(&make<codecvt<char, char, mbstate_t> >(1u));
1814684ddb6SLionel Sambuc     install(&make<codecvt<wchar_t, char, mbstate_t> >(1u));
1824684ddb6SLionel Sambuc     install(&make<codecvt<char16_t, char, mbstate_t> >(1u));
1834684ddb6SLionel Sambuc     install(&make<codecvt<char32_t, char, mbstate_t> >(1u));
1844684ddb6SLionel Sambuc     install(&make<numpunct<char> >(1u));
1854684ddb6SLionel Sambuc     install(&make<numpunct<wchar_t> >(1u));
1864684ddb6SLionel Sambuc     install(&make<num_get<char> >(1u));
1874684ddb6SLionel Sambuc     install(&make<num_get<wchar_t> >(1u));
1884684ddb6SLionel Sambuc     install(&make<num_put<char> >(1u));
1894684ddb6SLionel Sambuc     install(&make<num_put<wchar_t> >(1u));
1904684ddb6SLionel Sambuc     install(&make<moneypunct<char, false> >(1u));
1914684ddb6SLionel Sambuc     install(&make<moneypunct<char, true> >(1u));
1924684ddb6SLionel Sambuc     install(&make<moneypunct<wchar_t, false> >(1u));
1934684ddb6SLionel Sambuc     install(&make<moneypunct<wchar_t, true> >(1u));
1944684ddb6SLionel Sambuc     install(&make<money_get<char> >(1u));
1954684ddb6SLionel Sambuc     install(&make<money_get<wchar_t> >(1u));
1964684ddb6SLionel Sambuc     install(&make<money_put<char> >(1u));
1974684ddb6SLionel Sambuc     install(&make<money_put<wchar_t> >(1u));
1984684ddb6SLionel Sambuc     install(&make<time_get<char> >(1u));
1994684ddb6SLionel Sambuc     install(&make<time_get<wchar_t> >(1u));
2004684ddb6SLionel Sambuc     install(&make<time_put<char> >(1u));
2014684ddb6SLionel Sambuc     install(&make<time_put<wchar_t> >(1u));
2024684ddb6SLionel Sambuc     install(&make<_VSTD::messages<char> >(1u));
2034684ddb6SLionel Sambuc     install(&make<_VSTD::messages<wchar_t> >(1u));
2044684ddb6SLionel Sambuc }
2054684ddb6SLionel Sambuc 
__imp(const string & name,size_t refs)2064684ddb6SLionel Sambuc locale::__imp::__imp(const string& name, size_t refs)
2074684ddb6SLionel Sambuc     : facet(refs),
2084684ddb6SLionel Sambuc       facets_(N),
2094684ddb6SLionel Sambuc       name_(name)
2104684ddb6SLionel Sambuc {
2114684ddb6SLionel Sambuc #ifndef _LIBCPP_NO_EXCEPTIONS
2124684ddb6SLionel Sambuc     try
2134684ddb6SLionel Sambuc     {
2144684ddb6SLionel Sambuc #endif  // _LIBCPP_NO_EXCEPTIONS
2154684ddb6SLionel Sambuc         facets_ = locale::classic().__locale_->facets_;
2164684ddb6SLionel Sambuc         for (unsigned i = 0; i < facets_.size(); ++i)
2174684ddb6SLionel Sambuc             if (facets_[i])
2184684ddb6SLionel Sambuc                 facets_[i]->__add_shared();
2194684ddb6SLionel Sambuc         install(new collate_byname<char>(name_));
2204684ddb6SLionel Sambuc         install(new collate_byname<wchar_t>(name_));
2214684ddb6SLionel Sambuc         install(new ctype_byname<char>(name_));
2224684ddb6SLionel Sambuc         install(new ctype_byname<wchar_t>(name_));
2234684ddb6SLionel Sambuc         install(new codecvt_byname<char, char, mbstate_t>(name_));
2244684ddb6SLionel Sambuc         install(new codecvt_byname<wchar_t, char, mbstate_t>(name_));
2254684ddb6SLionel Sambuc         install(new codecvt_byname<char16_t, char, mbstate_t>(name_));
2264684ddb6SLionel Sambuc         install(new codecvt_byname<char32_t, char, mbstate_t>(name_));
2274684ddb6SLionel Sambuc         install(new numpunct_byname<char>(name_));
2284684ddb6SLionel Sambuc         install(new numpunct_byname<wchar_t>(name_));
2294684ddb6SLionel Sambuc         install(new moneypunct_byname<char, false>(name_));
2304684ddb6SLionel Sambuc         install(new moneypunct_byname<char, true>(name_));
2314684ddb6SLionel Sambuc         install(new moneypunct_byname<wchar_t, false>(name_));
2324684ddb6SLionel Sambuc         install(new moneypunct_byname<wchar_t, true>(name_));
2334684ddb6SLionel Sambuc         install(new time_get_byname<char>(name_));
2344684ddb6SLionel Sambuc         install(new time_get_byname<wchar_t>(name_));
2354684ddb6SLionel Sambuc         install(new time_put_byname<char>(name_));
2364684ddb6SLionel Sambuc         install(new time_put_byname<wchar_t>(name_));
2374684ddb6SLionel Sambuc         install(new messages_byname<char>(name_));
2384684ddb6SLionel Sambuc         install(new messages_byname<wchar_t>(name_));
2394684ddb6SLionel Sambuc #ifndef _LIBCPP_NO_EXCEPTIONS
2404684ddb6SLionel Sambuc     }
2414684ddb6SLionel Sambuc     catch (...)
2424684ddb6SLionel Sambuc     {
2434684ddb6SLionel Sambuc         for (unsigned i = 0; i < facets_.size(); ++i)
2444684ddb6SLionel Sambuc             if (facets_[i])
2454684ddb6SLionel Sambuc                 facets_[i]->__release_shared();
2464684ddb6SLionel Sambuc         throw;
2474684ddb6SLionel Sambuc     }
2484684ddb6SLionel Sambuc #endif  // _LIBCPP_NO_EXCEPTIONS
2494684ddb6SLionel Sambuc }
2504684ddb6SLionel Sambuc 
2514684ddb6SLionel Sambuc // NOTE avoid the `base class should be explicitly initialized in the
2524684ddb6SLionel Sambuc // copy constructor` warning emitted by GCC
2534684ddb6SLionel Sambuc #if defined(__clang__) || _GNUC_VER >= 406
2544684ddb6SLionel Sambuc #pragma GCC diagnostic push
2554684ddb6SLionel Sambuc #pragma GCC diagnostic ignored "-Wextra"
2564684ddb6SLionel Sambuc #endif
2574684ddb6SLionel Sambuc 
__imp(const __imp & other)2584684ddb6SLionel Sambuc locale::__imp::__imp(const __imp& other)
2594684ddb6SLionel Sambuc     : facets_(max<size_t>(N, other.facets_.size())),
2604684ddb6SLionel Sambuc       name_(other.name_)
2614684ddb6SLionel Sambuc {
2624684ddb6SLionel Sambuc     facets_ = other.facets_;
2634684ddb6SLionel Sambuc     for (unsigned i = 0; i < facets_.size(); ++i)
2644684ddb6SLionel Sambuc         if (facets_[i])
2654684ddb6SLionel Sambuc             facets_[i]->__add_shared();
2664684ddb6SLionel Sambuc }
2674684ddb6SLionel Sambuc 
2684684ddb6SLionel Sambuc #if defined(__clang__) || _GNUC_VER >= 406
2694684ddb6SLionel Sambuc #pragma GCC diagnostic pop
2704684ddb6SLionel Sambuc #endif
2714684ddb6SLionel Sambuc 
__imp(const __imp & other,const string & name,locale::category c)2724684ddb6SLionel Sambuc locale::__imp::__imp(const __imp& other, const string& name, locale::category c)
2734684ddb6SLionel Sambuc     : facets_(N),
2744684ddb6SLionel Sambuc       name_("*")
2754684ddb6SLionel Sambuc {
2764684ddb6SLionel Sambuc     facets_ = other.facets_;
2774684ddb6SLionel Sambuc     for (unsigned i = 0; i < facets_.size(); ++i)
2784684ddb6SLionel Sambuc         if (facets_[i])
2794684ddb6SLionel Sambuc             facets_[i]->__add_shared();
2804684ddb6SLionel Sambuc #ifndef _LIBCPP_NO_EXCEPTIONS
2814684ddb6SLionel Sambuc     try
2824684ddb6SLionel Sambuc     {
2834684ddb6SLionel Sambuc #endif  // _LIBCPP_NO_EXCEPTIONS
2844684ddb6SLionel Sambuc         if (c & locale::collate)
2854684ddb6SLionel Sambuc         {
2864684ddb6SLionel Sambuc             install(new collate_byname<char>(name));
2874684ddb6SLionel Sambuc             install(new collate_byname<wchar_t>(name));
2884684ddb6SLionel Sambuc         }
2894684ddb6SLionel Sambuc         if (c & locale::ctype)
2904684ddb6SLionel Sambuc         {
2914684ddb6SLionel Sambuc             install(new ctype_byname<char>(name));
2924684ddb6SLionel Sambuc             install(new ctype_byname<wchar_t>(name));
2934684ddb6SLionel Sambuc             install(new codecvt_byname<char, char, mbstate_t>(name));
2944684ddb6SLionel Sambuc             install(new codecvt_byname<wchar_t, char, mbstate_t>(name));
2954684ddb6SLionel Sambuc             install(new codecvt_byname<char16_t, char, mbstate_t>(name));
2964684ddb6SLionel Sambuc             install(new codecvt_byname<char32_t, char, mbstate_t>(name));
2974684ddb6SLionel Sambuc         }
2984684ddb6SLionel Sambuc         if (c & locale::monetary)
2994684ddb6SLionel Sambuc         {
3004684ddb6SLionel Sambuc             install(new moneypunct_byname<char, false>(name));
3014684ddb6SLionel Sambuc             install(new moneypunct_byname<char, true>(name));
3024684ddb6SLionel Sambuc             install(new moneypunct_byname<wchar_t, false>(name));
3034684ddb6SLionel Sambuc             install(new moneypunct_byname<wchar_t, true>(name));
3044684ddb6SLionel Sambuc         }
3054684ddb6SLionel Sambuc         if (c & locale::numeric)
3064684ddb6SLionel Sambuc         {
3074684ddb6SLionel Sambuc             install(new numpunct_byname<char>(name));
3084684ddb6SLionel Sambuc             install(new numpunct_byname<wchar_t>(name));
3094684ddb6SLionel Sambuc         }
3104684ddb6SLionel Sambuc         if (c & locale::time)
3114684ddb6SLionel Sambuc         {
3124684ddb6SLionel Sambuc             install(new time_get_byname<char>(name));
3134684ddb6SLionel Sambuc             install(new time_get_byname<wchar_t>(name));
3144684ddb6SLionel Sambuc             install(new time_put_byname<char>(name));
3154684ddb6SLionel Sambuc             install(new time_put_byname<wchar_t>(name));
3164684ddb6SLionel Sambuc         }
3174684ddb6SLionel Sambuc         if (c & locale::messages)
3184684ddb6SLionel Sambuc         {
3194684ddb6SLionel Sambuc             install(new messages_byname<char>(name));
3204684ddb6SLionel Sambuc             install(new messages_byname<wchar_t>(name));
3214684ddb6SLionel Sambuc         }
3224684ddb6SLionel Sambuc #ifndef _LIBCPP_NO_EXCEPTIONS
3234684ddb6SLionel Sambuc     }
3244684ddb6SLionel Sambuc     catch (...)
3254684ddb6SLionel Sambuc     {
3264684ddb6SLionel Sambuc         for (unsigned i = 0; i < facets_.size(); ++i)
3274684ddb6SLionel Sambuc             if (facets_[i])
3284684ddb6SLionel Sambuc                 facets_[i]->__release_shared();
3294684ddb6SLionel Sambuc         throw;
3304684ddb6SLionel Sambuc     }
3314684ddb6SLionel Sambuc #endif  // _LIBCPP_NO_EXCEPTIONS
3324684ddb6SLionel Sambuc }
3334684ddb6SLionel Sambuc 
3344684ddb6SLionel Sambuc template<class F>
3354684ddb6SLionel Sambuc inline
3364684ddb6SLionel Sambuc void
install_from(const locale::__imp & one)3374684ddb6SLionel Sambuc locale::__imp::install_from(const locale::__imp& one)
3384684ddb6SLionel Sambuc {
3394684ddb6SLionel Sambuc     long id = F::id.__get();
3404684ddb6SLionel Sambuc     install(const_cast<F*>(static_cast<const F*>(one.use_facet(id))), id);
3414684ddb6SLionel Sambuc }
3424684ddb6SLionel Sambuc 
__imp(const __imp & other,const __imp & one,locale::category c)3434684ddb6SLionel Sambuc locale::__imp::__imp(const __imp& other, const __imp& one, locale::category c)
3444684ddb6SLionel Sambuc     : facets_(N),
3454684ddb6SLionel Sambuc       name_("*")
3464684ddb6SLionel Sambuc {
3474684ddb6SLionel Sambuc     facets_ = other.facets_;
3484684ddb6SLionel Sambuc     for (unsigned i = 0; i < facets_.size(); ++i)
3494684ddb6SLionel Sambuc         if (facets_[i])
3504684ddb6SLionel Sambuc             facets_[i]->__add_shared();
3514684ddb6SLionel Sambuc #ifndef _LIBCPP_NO_EXCEPTIONS
3524684ddb6SLionel Sambuc     try
3534684ddb6SLionel Sambuc     {
3544684ddb6SLionel Sambuc #endif  // _LIBCPP_NO_EXCEPTIONS
3554684ddb6SLionel Sambuc         if (c & locale::collate)
3564684ddb6SLionel Sambuc         {
3574684ddb6SLionel Sambuc             install_from<_VSTD::collate<char> >(one);
3584684ddb6SLionel Sambuc             install_from<_VSTD::collate<wchar_t> >(one);
3594684ddb6SLionel Sambuc         }
3604684ddb6SLionel Sambuc         if (c & locale::ctype)
3614684ddb6SLionel Sambuc         {
3624684ddb6SLionel Sambuc             install_from<_VSTD::ctype<char> >(one);
3634684ddb6SLionel Sambuc             install_from<_VSTD::ctype<wchar_t> >(one);
3644684ddb6SLionel Sambuc             install_from<_VSTD::codecvt<char, char, mbstate_t> >(one);
3654684ddb6SLionel Sambuc             install_from<_VSTD::codecvt<char16_t, char, mbstate_t> >(one);
3664684ddb6SLionel Sambuc             install_from<_VSTD::codecvt<char32_t, char, mbstate_t> >(one);
3674684ddb6SLionel Sambuc             install_from<_VSTD::codecvt<wchar_t, char, mbstate_t> >(one);
3684684ddb6SLionel Sambuc         }
3694684ddb6SLionel Sambuc         if (c & locale::monetary)
3704684ddb6SLionel Sambuc         {
3714684ddb6SLionel Sambuc             install_from<moneypunct<char, false> >(one);
3724684ddb6SLionel Sambuc             install_from<moneypunct<char, true> >(one);
3734684ddb6SLionel Sambuc             install_from<moneypunct<wchar_t, false> >(one);
3744684ddb6SLionel Sambuc             install_from<moneypunct<wchar_t, true> >(one);
3754684ddb6SLionel Sambuc             install_from<money_get<char> >(one);
3764684ddb6SLionel Sambuc             install_from<money_get<wchar_t> >(one);
3774684ddb6SLionel Sambuc             install_from<money_put<char> >(one);
3784684ddb6SLionel Sambuc             install_from<money_put<wchar_t> >(one);
3794684ddb6SLionel Sambuc         }
3804684ddb6SLionel Sambuc         if (c & locale::numeric)
3814684ddb6SLionel Sambuc         {
3824684ddb6SLionel Sambuc             install_from<numpunct<char> >(one);
3834684ddb6SLionel Sambuc             install_from<numpunct<wchar_t> >(one);
3844684ddb6SLionel Sambuc             install_from<num_get<char> >(one);
3854684ddb6SLionel Sambuc             install_from<num_get<wchar_t> >(one);
3864684ddb6SLionel Sambuc             install_from<num_put<char> >(one);
3874684ddb6SLionel Sambuc             install_from<num_put<wchar_t> >(one);
3884684ddb6SLionel Sambuc         }
3894684ddb6SLionel Sambuc         if (c & locale::time)
3904684ddb6SLionel Sambuc         {
3914684ddb6SLionel Sambuc             install_from<time_get<char> >(one);
3924684ddb6SLionel Sambuc             install_from<time_get<wchar_t> >(one);
3934684ddb6SLionel Sambuc             install_from<time_put<char> >(one);
3944684ddb6SLionel Sambuc             install_from<time_put<wchar_t> >(one);
3954684ddb6SLionel Sambuc         }
3964684ddb6SLionel Sambuc         if (c & locale::messages)
3974684ddb6SLionel Sambuc         {
3984684ddb6SLionel Sambuc             install_from<_VSTD::messages<char> >(one);
3994684ddb6SLionel Sambuc             install_from<_VSTD::messages<wchar_t> >(one);
4004684ddb6SLionel Sambuc         }
4014684ddb6SLionel Sambuc #ifndef _LIBCPP_NO_EXCEPTIONS
4024684ddb6SLionel Sambuc     }
4034684ddb6SLionel Sambuc     catch (...)
4044684ddb6SLionel Sambuc     {
4054684ddb6SLionel Sambuc         for (unsigned i = 0; i < facets_.size(); ++i)
4064684ddb6SLionel Sambuc             if (facets_[i])
4074684ddb6SLionel Sambuc                 facets_[i]->__release_shared();
4084684ddb6SLionel Sambuc         throw;
4094684ddb6SLionel Sambuc     }
4104684ddb6SLionel Sambuc #endif  // _LIBCPP_NO_EXCEPTIONS
4114684ddb6SLionel Sambuc }
4124684ddb6SLionel Sambuc 
__imp(const __imp & other,facet * f,long id)4134684ddb6SLionel Sambuc locale::__imp::__imp(const __imp& other, facet* f, long id)
4144684ddb6SLionel Sambuc     : facets_(max<size_t>(N, other.facets_.size()+1)),
4154684ddb6SLionel Sambuc       name_("*")
4164684ddb6SLionel Sambuc {
4174684ddb6SLionel Sambuc     f->__add_shared();
4184684ddb6SLionel Sambuc     unique_ptr<facet, release> hold(f);
4194684ddb6SLionel Sambuc     facets_ = other.facets_;
4204684ddb6SLionel Sambuc     for (unsigned i = 0; i < other.facets_.size(); ++i)
4214684ddb6SLionel Sambuc         if (facets_[i])
4224684ddb6SLionel Sambuc             facets_[i]->__add_shared();
4234684ddb6SLionel Sambuc     install(hold.get(), id);
4244684ddb6SLionel Sambuc }
4254684ddb6SLionel Sambuc 
~__imp()4264684ddb6SLionel Sambuc locale::__imp::~__imp()
4274684ddb6SLionel Sambuc {
4284684ddb6SLionel Sambuc     for (unsigned i = 0; i < facets_.size(); ++i)
4294684ddb6SLionel Sambuc         if (facets_[i])
4304684ddb6SLionel Sambuc             facets_[i]->__release_shared();
4314684ddb6SLionel Sambuc }
4324684ddb6SLionel Sambuc 
4334684ddb6SLionel Sambuc void
install(facet * f,long id)4344684ddb6SLionel Sambuc locale::__imp::install(facet* f, long id)
4354684ddb6SLionel Sambuc {
4364684ddb6SLionel Sambuc     f->__add_shared();
4374684ddb6SLionel Sambuc     unique_ptr<facet, release> hold(f);
4384684ddb6SLionel Sambuc     if (static_cast<size_t>(id) >= facets_.size())
4394684ddb6SLionel Sambuc         facets_.resize(static_cast<size_t>(id+1));
4404684ddb6SLionel Sambuc     if (facets_[static_cast<size_t>(id)])
4414684ddb6SLionel Sambuc         facets_[static_cast<size_t>(id)]->__release_shared();
4424684ddb6SLionel Sambuc     facets_[static_cast<size_t>(id)] = hold.release();
4434684ddb6SLionel Sambuc }
4444684ddb6SLionel Sambuc 
4454684ddb6SLionel Sambuc const locale::facet*
use_facet(long id) const4464684ddb6SLionel Sambuc locale::__imp::use_facet(long id) const
4474684ddb6SLionel Sambuc {
4484684ddb6SLionel Sambuc #ifndef _LIBCPP_NO_EXCEPTIONS
4494684ddb6SLionel Sambuc     if (!has_facet(id))
4504684ddb6SLionel Sambuc         throw bad_cast();
4514684ddb6SLionel Sambuc #endif  // _LIBCPP_NO_EXCEPTIONS
4524684ddb6SLionel Sambuc     return facets_[static_cast<size_t>(id)];
4534684ddb6SLionel Sambuc }
4544684ddb6SLionel Sambuc 
4554684ddb6SLionel Sambuc // locale
4564684ddb6SLionel Sambuc 
4574684ddb6SLionel Sambuc const locale&
make_classic()4584684ddb6SLionel Sambuc locale::__imp::make_classic()
4594684ddb6SLionel Sambuc {
4604684ddb6SLionel Sambuc     // only one thread can get in here and it only gets in once
4614684ddb6SLionel Sambuc     static aligned_storage<sizeof(locale)>::type buf;
462*0a6a1f1dSLionel Sambuc     locale* c = reinterpret_cast<locale*>(&buf);
4634684ddb6SLionel Sambuc     c->__locale_ = &make<__imp>(1u);
4644684ddb6SLionel Sambuc     return *c;
4654684ddb6SLionel Sambuc }
4664684ddb6SLionel Sambuc 
4674684ddb6SLionel Sambuc const locale&
classic()4684684ddb6SLionel Sambuc locale::classic()
4694684ddb6SLionel Sambuc {
4704684ddb6SLionel Sambuc     static const locale& c = __imp::make_classic();
4714684ddb6SLionel Sambuc     return c;
4724684ddb6SLionel Sambuc }
4734684ddb6SLionel Sambuc 
4744684ddb6SLionel Sambuc locale&
make_global()4754684ddb6SLionel Sambuc locale::__imp::make_global()
4764684ddb6SLionel Sambuc {
4774684ddb6SLionel Sambuc     // only one thread can get in here and it only gets in once
4784684ddb6SLionel Sambuc     static aligned_storage<sizeof(locale)>::type buf;
4794684ddb6SLionel Sambuc     ::new (&buf) locale(locale::classic());
480*0a6a1f1dSLionel Sambuc     return *reinterpret_cast<locale*>(&buf);
4814684ddb6SLionel Sambuc }
4824684ddb6SLionel Sambuc 
4834684ddb6SLionel Sambuc locale&
__global()4844684ddb6SLionel Sambuc locale::__global()
4854684ddb6SLionel Sambuc {
4864684ddb6SLionel Sambuc     static locale& g = __imp::make_global();
4874684ddb6SLionel Sambuc     return g;
4884684ddb6SLionel Sambuc }
4894684ddb6SLionel Sambuc 
locale()4904684ddb6SLionel Sambuc locale::locale()  _NOEXCEPT
4914684ddb6SLionel Sambuc     : __locale_(__global().__locale_)
4924684ddb6SLionel Sambuc {
4934684ddb6SLionel Sambuc     __locale_->__add_shared();
4944684ddb6SLionel Sambuc }
4954684ddb6SLionel Sambuc 
locale(const locale & l)4964684ddb6SLionel Sambuc locale::locale(const locale& l)  _NOEXCEPT
4974684ddb6SLionel Sambuc     : __locale_(l.__locale_)
4984684ddb6SLionel Sambuc {
4994684ddb6SLionel Sambuc     __locale_->__add_shared();
5004684ddb6SLionel Sambuc }
5014684ddb6SLionel Sambuc 
~locale()5024684ddb6SLionel Sambuc locale::~locale()
5034684ddb6SLionel Sambuc {
5044684ddb6SLionel Sambuc     __locale_->__release_shared();
5054684ddb6SLionel Sambuc }
5064684ddb6SLionel Sambuc 
5074684ddb6SLionel Sambuc const locale&
operator =(const locale & other)5084684ddb6SLionel Sambuc locale::operator=(const locale& other)  _NOEXCEPT
5094684ddb6SLionel Sambuc {
5104684ddb6SLionel Sambuc     other.__locale_->__add_shared();
5114684ddb6SLionel Sambuc     __locale_->__release_shared();
5124684ddb6SLionel Sambuc     __locale_ = other.__locale_;
5134684ddb6SLionel Sambuc     return *this;
5144684ddb6SLionel Sambuc }
5154684ddb6SLionel Sambuc 
locale(const char * name)5164684ddb6SLionel Sambuc locale::locale(const char* name)
5174684ddb6SLionel Sambuc #ifndef _LIBCPP_NO_EXCEPTIONS
5184684ddb6SLionel Sambuc     : __locale_(name ? new __imp(name)
5194684ddb6SLionel Sambuc                      : throw runtime_error("locale constructed with null"))
5204684ddb6SLionel Sambuc #else  // _LIBCPP_NO_EXCEPTIONS
5214684ddb6SLionel Sambuc     : __locale_(new __imp(name))
5224684ddb6SLionel Sambuc #endif
5234684ddb6SLionel Sambuc {
5244684ddb6SLionel Sambuc     __locale_->__add_shared();
5254684ddb6SLionel Sambuc }
5264684ddb6SLionel Sambuc 
locale(const string & name)5274684ddb6SLionel Sambuc locale::locale(const string& name)
5284684ddb6SLionel Sambuc     : __locale_(new __imp(name))
5294684ddb6SLionel Sambuc {
5304684ddb6SLionel Sambuc     __locale_->__add_shared();
5314684ddb6SLionel Sambuc }
5324684ddb6SLionel Sambuc 
locale(const locale & other,const char * name,category c)5334684ddb6SLionel Sambuc locale::locale(const locale& other, const char* name, category c)
5344684ddb6SLionel Sambuc #ifndef _LIBCPP_NO_EXCEPTIONS
5354684ddb6SLionel Sambuc     : __locale_(name ? new __imp(*other.__locale_, name, c)
5364684ddb6SLionel Sambuc                      : throw runtime_error("locale constructed with null"))
5374684ddb6SLionel Sambuc #else  // _LIBCPP_NO_EXCEPTIONS
5384684ddb6SLionel Sambuc     : __locale_(new __imp(*other.__locale_, name, c))
5394684ddb6SLionel Sambuc #endif
5404684ddb6SLionel Sambuc {
5414684ddb6SLionel Sambuc     __locale_->__add_shared();
5424684ddb6SLionel Sambuc }
5434684ddb6SLionel Sambuc 
locale(const locale & other,const string & name,category c)5444684ddb6SLionel Sambuc locale::locale(const locale& other, const string& name, category c)
5454684ddb6SLionel Sambuc     : __locale_(new __imp(*other.__locale_, name, c))
5464684ddb6SLionel Sambuc {
5474684ddb6SLionel Sambuc     __locale_->__add_shared();
5484684ddb6SLionel Sambuc }
5494684ddb6SLionel Sambuc 
locale(const locale & other,const locale & one,category c)5504684ddb6SLionel Sambuc locale::locale(const locale& other, const locale& one, category c)
5514684ddb6SLionel Sambuc     : __locale_(new __imp(*other.__locale_, *one.__locale_, c))
5524684ddb6SLionel Sambuc {
5534684ddb6SLionel Sambuc     __locale_->__add_shared();
5544684ddb6SLionel Sambuc }
5554684ddb6SLionel Sambuc 
5564684ddb6SLionel Sambuc string
name() const5574684ddb6SLionel Sambuc locale::name() const
5584684ddb6SLionel Sambuc {
5594684ddb6SLionel Sambuc     return __locale_->name();
5604684ddb6SLionel Sambuc }
5614684ddb6SLionel Sambuc 
5624684ddb6SLionel Sambuc void
__install_ctor(const locale & other,facet * f,long id)5634684ddb6SLionel Sambuc locale::__install_ctor(const locale& other, facet* f, long id)
5644684ddb6SLionel Sambuc {
5654684ddb6SLionel Sambuc     if (f)
5664684ddb6SLionel Sambuc         __locale_ = new __imp(*other.__locale_, f, id);
5674684ddb6SLionel Sambuc     else
5684684ddb6SLionel Sambuc         __locale_ = other.__locale_;
5694684ddb6SLionel Sambuc     __locale_->__add_shared();
5704684ddb6SLionel Sambuc }
5714684ddb6SLionel Sambuc 
5724684ddb6SLionel Sambuc locale
global(const locale & loc)5734684ddb6SLionel Sambuc locale::global(const locale& loc)
5744684ddb6SLionel Sambuc {
5754684ddb6SLionel Sambuc     locale& g = __global();
5764684ddb6SLionel Sambuc     locale r = g;
5774684ddb6SLionel Sambuc     g = loc;
578*0a6a1f1dSLionel Sambuc #ifndef __CloudABI__
5794684ddb6SLionel Sambuc     if (g.name() != "*")
5804684ddb6SLionel Sambuc         setlocale(LC_ALL, g.name().c_str());
581*0a6a1f1dSLionel Sambuc #endif
5824684ddb6SLionel Sambuc     return r;
5834684ddb6SLionel Sambuc }
5844684ddb6SLionel Sambuc 
5854684ddb6SLionel Sambuc bool
has_facet(id & x) const5864684ddb6SLionel Sambuc locale::has_facet(id& x) const
5874684ddb6SLionel Sambuc {
5884684ddb6SLionel Sambuc     return __locale_->has_facet(x.__get());
5894684ddb6SLionel Sambuc }
5904684ddb6SLionel Sambuc 
5914684ddb6SLionel Sambuc const locale::facet*
use_facet(id & x) const5924684ddb6SLionel Sambuc locale::use_facet(id& x) const
5934684ddb6SLionel Sambuc {
5944684ddb6SLionel Sambuc     return __locale_->use_facet(x.__get());
5954684ddb6SLionel Sambuc }
5964684ddb6SLionel Sambuc 
5974684ddb6SLionel Sambuc bool
operator ==(const locale & y) const5984684ddb6SLionel Sambuc locale::operator==(const locale& y) const
5994684ddb6SLionel Sambuc {
6004684ddb6SLionel Sambuc     return (__locale_ == y.__locale_)
6014684ddb6SLionel Sambuc         || (__locale_->name() != "*" && __locale_->name() == y.__locale_->name());
6024684ddb6SLionel Sambuc }
6034684ddb6SLionel Sambuc 
6044684ddb6SLionel Sambuc // locale::facet
6054684ddb6SLionel Sambuc 
~facet()6064684ddb6SLionel Sambuc locale::facet::~facet()
6074684ddb6SLionel Sambuc {
6084684ddb6SLionel Sambuc }
6094684ddb6SLionel Sambuc 
6104684ddb6SLionel Sambuc void
__on_zero_shared()6114684ddb6SLionel Sambuc locale::facet::__on_zero_shared() _NOEXCEPT
6124684ddb6SLionel Sambuc {
6134684ddb6SLionel Sambuc     delete this;
6144684ddb6SLionel Sambuc }
6154684ddb6SLionel Sambuc 
6164684ddb6SLionel Sambuc // locale::id
6174684ddb6SLionel Sambuc 
6184684ddb6SLionel Sambuc int32_t locale::id::__next_id = 0;
6194684ddb6SLionel Sambuc 
6204684ddb6SLionel Sambuc namespace
6214684ddb6SLionel Sambuc {
6224684ddb6SLionel Sambuc 
6234684ddb6SLionel Sambuc class __fake_bind
6244684ddb6SLionel Sambuc {
6254684ddb6SLionel Sambuc     locale::id* id_;
6264684ddb6SLionel Sambuc     void (locale::id::* pmf_)();
6274684ddb6SLionel Sambuc public:
__fake_bind(void (locale::id::* pmf)(),locale::id * id)6284684ddb6SLionel Sambuc     __fake_bind(void (locale::id::* pmf)(), locale::id* id)
6294684ddb6SLionel Sambuc         : id_(id), pmf_(pmf) {}
6304684ddb6SLionel Sambuc 
operator ()() const6314684ddb6SLionel Sambuc     void operator()() const
6324684ddb6SLionel Sambuc     {
6334684ddb6SLionel Sambuc         (id_->*pmf_)();
6344684ddb6SLionel Sambuc     }
6354684ddb6SLionel Sambuc };
6364684ddb6SLionel Sambuc 
6374684ddb6SLionel Sambuc }
6384684ddb6SLionel Sambuc 
6394684ddb6SLionel Sambuc long
__get()6404684ddb6SLionel Sambuc locale::id::__get()
6414684ddb6SLionel Sambuc {
6424684ddb6SLionel Sambuc     call_once(__flag_, __fake_bind(&locale::id::__init, this));
6434684ddb6SLionel Sambuc     return __id_ - 1;
6444684ddb6SLionel Sambuc }
6454684ddb6SLionel Sambuc 
6464684ddb6SLionel Sambuc void
__init()6474684ddb6SLionel Sambuc locale::id::__init()
6484684ddb6SLionel Sambuc {
6494684ddb6SLionel Sambuc     __id_ = __sync_add_and_fetch(&__next_id, 1);
6504684ddb6SLionel Sambuc }
6514684ddb6SLionel Sambuc 
6524684ddb6SLionel Sambuc // template <> class collate_byname<char>
6534684ddb6SLionel Sambuc 
collate_byname(const char * n,size_t refs)6544684ddb6SLionel Sambuc collate_byname<char>::collate_byname(const char* n, size_t refs)
6554684ddb6SLionel Sambuc     : collate<char>(refs),
6564684ddb6SLionel Sambuc       __l(newlocale(LC_ALL_MASK, n, 0))
6574684ddb6SLionel Sambuc {
6584684ddb6SLionel Sambuc #ifndef _LIBCPP_NO_EXCEPTIONS
6594684ddb6SLionel Sambuc     if (__l == 0)
6604684ddb6SLionel Sambuc         throw runtime_error("collate_byname<char>::collate_byname"
6614684ddb6SLionel Sambuc                             " failed to construct for " + string(n));
6624684ddb6SLionel Sambuc #endif  // _LIBCPP_NO_EXCEPTIONS
6634684ddb6SLionel Sambuc }
6644684ddb6SLionel Sambuc 
collate_byname(const string & name,size_t refs)6654684ddb6SLionel Sambuc collate_byname<char>::collate_byname(const string& name, size_t refs)
6664684ddb6SLionel Sambuc     : collate<char>(refs),
6674684ddb6SLionel Sambuc       __l(newlocale(LC_ALL_MASK, name.c_str(), 0))
6684684ddb6SLionel Sambuc {
6694684ddb6SLionel Sambuc #ifndef _LIBCPP_NO_EXCEPTIONS
6704684ddb6SLionel Sambuc     if (__l == 0)
6714684ddb6SLionel Sambuc         throw runtime_error("collate_byname<char>::collate_byname"
6724684ddb6SLionel Sambuc                             " failed to construct for " + name);
6734684ddb6SLionel Sambuc #endif  // _LIBCPP_NO_EXCEPTIONS
6744684ddb6SLionel Sambuc }
6754684ddb6SLionel Sambuc 
~collate_byname()6764684ddb6SLionel Sambuc collate_byname<char>::~collate_byname()
6774684ddb6SLionel Sambuc {
6784684ddb6SLionel Sambuc     freelocale(__l);
6794684ddb6SLionel Sambuc }
6804684ddb6SLionel Sambuc 
6814684ddb6SLionel Sambuc int
do_compare(const char_type * __lo1,const char_type * __hi1,const char_type * __lo2,const char_type * __hi2) const6824684ddb6SLionel Sambuc collate_byname<char>::do_compare(const char_type* __lo1, const char_type* __hi1,
6834684ddb6SLionel Sambuc                                  const char_type* __lo2, const char_type* __hi2) const
6844684ddb6SLionel Sambuc {
6854684ddb6SLionel Sambuc     string_type lhs(__lo1, __hi1);
6864684ddb6SLionel Sambuc     string_type rhs(__lo2, __hi2);
6874684ddb6SLionel Sambuc     int r = strcoll_l(lhs.c_str(), rhs.c_str(), __l);
6884684ddb6SLionel Sambuc     if (r < 0)
6894684ddb6SLionel Sambuc         return -1;
6904684ddb6SLionel Sambuc     if (r > 0)
6914684ddb6SLionel Sambuc         return 1;
6924684ddb6SLionel Sambuc     return r;
6934684ddb6SLionel Sambuc }
6944684ddb6SLionel Sambuc 
6954684ddb6SLionel Sambuc collate_byname<char>::string_type
do_transform(const char_type * lo,const char_type * hi) const6964684ddb6SLionel Sambuc collate_byname<char>::do_transform(const char_type* lo, const char_type* hi) const
6974684ddb6SLionel Sambuc {
6984684ddb6SLionel Sambuc     const string_type in(lo, hi);
6994684ddb6SLionel Sambuc     string_type out(strxfrm_l(0, in.c_str(), 0, __l), char());
7004684ddb6SLionel Sambuc     strxfrm_l(const_cast<char*>(out.c_str()), in.c_str(), out.size()+1, __l);
7014684ddb6SLionel Sambuc     return out;
7024684ddb6SLionel Sambuc }
7034684ddb6SLionel Sambuc 
7044684ddb6SLionel Sambuc // template <> class collate_byname<wchar_t>
7054684ddb6SLionel Sambuc 
collate_byname(const char * n,size_t refs)7064684ddb6SLionel Sambuc collate_byname<wchar_t>::collate_byname(const char* n, size_t refs)
7074684ddb6SLionel Sambuc     : collate<wchar_t>(refs),
7084684ddb6SLionel Sambuc       __l(newlocale(LC_ALL_MASK, n, 0))
7094684ddb6SLionel Sambuc {
7104684ddb6SLionel Sambuc #ifndef _LIBCPP_NO_EXCEPTIONS
7114684ddb6SLionel Sambuc     if (__l == 0)
7124684ddb6SLionel Sambuc         throw runtime_error("collate_byname<wchar_t>::collate_byname(size_t refs)"
7134684ddb6SLionel Sambuc                             " failed to construct for " + string(n));
7144684ddb6SLionel Sambuc #endif  // _LIBCPP_NO_EXCEPTIONS
7154684ddb6SLionel Sambuc }
7164684ddb6SLionel Sambuc 
collate_byname(const string & name,size_t refs)7174684ddb6SLionel Sambuc collate_byname<wchar_t>::collate_byname(const string& name, size_t refs)
7184684ddb6SLionel Sambuc     : collate<wchar_t>(refs),
7194684ddb6SLionel Sambuc       __l(newlocale(LC_ALL_MASK, name.c_str(), 0))
7204684ddb6SLionel Sambuc {
7214684ddb6SLionel Sambuc #ifndef _LIBCPP_NO_EXCEPTIONS
7224684ddb6SLionel Sambuc     if (__l == 0)
7234684ddb6SLionel Sambuc         throw runtime_error("collate_byname<wchar_t>::collate_byname(size_t refs)"
7244684ddb6SLionel Sambuc                             " failed to construct for " + name);
7254684ddb6SLionel Sambuc #endif  // _LIBCPP_NO_EXCEPTIONS
7264684ddb6SLionel Sambuc }
7274684ddb6SLionel Sambuc 
~collate_byname()7284684ddb6SLionel Sambuc collate_byname<wchar_t>::~collate_byname()
7294684ddb6SLionel Sambuc {
7304684ddb6SLionel Sambuc     freelocale(__l);
7314684ddb6SLionel Sambuc }
7324684ddb6SLionel Sambuc 
7334684ddb6SLionel Sambuc int
do_compare(const char_type * __lo1,const char_type * __hi1,const char_type * __lo2,const char_type * __hi2) const7344684ddb6SLionel Sambuc collate_byname<wchar_t>::do_compare(const char_type* __lo1, const char_type* __hi1,
7354684ddb6SLionel Sambuc                                  const char_type* __lo2, const char_type* __hi2) const
7364684ddb6SLionel Sambuc {
7374684ddb6SLionel Sambuc     string_type lhs(__lo1, __hi1);
7384684ddb6SLionel Sambuc     string_type rhs(__lo2, __hi2);
7394684ddb6SLionel Sambuc     int r = wcscoll_l(lhs.c_str(), rhs.c_str(), __l);
7404684ddb6SLionel Sambuc     if (r < 0)
7414684ddb6SLionel Sambuc         return -1;
7424684ddb6SLionel Sambuc     if (r > 0)
7434684ddb6SLionel Sambuc         return 1;
7444684ddb6SLionel Sambuc     return r;
7454684ddb6SLionel Sambuc }
7464684ddb6SLionel Sambuc 
7474684ddb6SLionel Sambuc collate_byname<wchar_t>::string_type
do_transform(const char_type * lo,const char_type * hi) const7484684ddb6SLionel Sambuc collate_byname<wchar_t>::do_transform(const char_type* lo, const char_type* hi) const
7494684ddb6SLionel Sambuc {
7504684ddb6SLionel Sambuc     const string_type in(lo, hi);
7514684ddb6SLionel Sambuc     string_type out(wcsxfrm_l(0, in.c_str(), 0, __l), wchar_t());
7524684ddb6SLionel Sambuc     wcsxfrm_l(const_cast<wchar_t*>(out.c_str()), in.c_str(), out.size()+1, __l);
7534684ddb6SLionel Sambuc     return out;
7544684ddb6SLionel Sambuc }
7554684ddb6SLionel Sambuc 
7564684ddb6SLionel Sambuc // template <> class ctype<wchar_t>;
7574684ddb6SLionel Sambuc 
7584684ddb6SLionel Sambuc const ctype_base::mask ctype_base::space;
7594684ddb6SLionel Sambuc const ctype_base::mask ctype_base::print;
7604684ddb6SLionel Sambuc const ctype_base::mask ctype_base::cntrl;
7614684ddb6SLionel Sambuc const ctype_base::mask ctype_base::upper;
7624684ddb6SLionel Sambuc const ctype_base::mask ctype_base::lower;
7634684ddb6SLionel Sambuc const ctype_base::mask ctype_base::alpha;
7644684ddb6SLionel Sambuc const ctype_base::mask ctype_base::digit;
7654684ddb6SLionel Sambuc const ctype_base::mask ctype_base::punct;
7664684ddb6SLionel Sambuc const ctype_base::mask ctype_base::xdigit;
7674684ddb6SLionel Sambuc const ctype_base::mask ctype_base::blank;
7684684ddb6SLionel Sambuc const ctype_base::mask ctype_base::alnum;
7694684ddb6SLionel Sambuc const ctype_base::mask ctype_base::graph;
7704684ddb6SLionel Sambuc 
7714684ddb6SLionel Sambuc locale::id ctype<wchar_t>::id;
7724684ddb6SLionel Sambuc 
~ctype()7734684ddb6SLionel Sambuc ctype<wchar_t>::~ctype()
7744684ddb6SLionel Sambuc {
7754684ddb6SLionel Sambuc }
7764684ddb6SLionel Sambuc 
7774684ddb6SLionel Sambuc bool
do_is(mask m,char_type c) const7784684ddb6SLionel Sambuc ctype<wchar_t>::do_is(mask m, char_type c) const
7794684ddb6SLionel Sambuc {
7804684ddb6SLionel Sambuc     return isascii(c) ? (ctype<char>::classic_table()[c] & m) != 0 : false;
7814684ddb6SLionel Sambuc }
7824684ddb6SLionel Sambuc 
7834684ddb6SLionel Sambuc const wchar_t*
do_is(const char_type * low,const char_type * high,mask * vec) const7844684ddb6SLionel Sambuc ctype<wchar_t>::do_is(const char_type* low, const char_type* high, mask* vec) const
7854684ddb6SLionel Sambuc {
7864684ddb6SLionel Sambuc     for (; low != high; ++low, ++vec)
7874684ddb6SLionel Sambuc         *vec = static_cast<mask>(isascii(*low) ?
7884684ddb6SLionel Sambuc                                    ctype<char>::classic_table()[*low] : 0);
7894684ddb6SLionel Sambuc     return low;
7904684ddb6SLionel Sambuc }
7914684ddb6SLionel Sambuc 
7924684ddb6SLionel Sambuc const wchar_t*
do_scan_is(mask m,const char_type * low,const char_type * high) const7934684ddb6SLionel Sambuc ctype<wchar_t>::do_scan_is(mask m, const char_type* low, const char_type* high) const
7944684ddb6SLionel Sambuc {
7954684ddb6SLionel Sambuc     for (; low != high; ++low)
7964684ddb6SLionel Sambuc         if (isascii(*low) && (ctype<char>::classic_table()[*low] & m))
7974684ddb6SLionel Sambuc             break;
7984684ddb6SLionel Sambuc     return low;
7994684ddb6SLionel Sambuc }
8004684ddb6SLionel Sambuc 
8014684ddb6SLionel Sambuc const wchar_t*
do_scan_not(mask m,const char_type * low,const char_type * high) const8024684ddb6SLionel Sambuc ctype<wchar_t>::do_scan_not(mask m, const char_type* low, const char_type* high) const
8034684ddb6SLionel Sambuc {
8044684ddb6SLionel Sambuc     for (; low != high; ++low)
8054684ddb6SLionel Sambuc         if (!(isascii(*low) && (ctype<char>::classic_table()[*low] & m)))
8064684ddb6SLionel Sambuc             break;
8074684ddb6SLionel Sambuc     return low;
8084684ddb6SLionel Sambuc }
8094684ddb6SLionel Sambuc 
8104684ddb6SLionel Sambuc wchar_t
do_toupper(char_type c) const8114684ddb6SLionel Sambuc ctype<wchar_t>::do_toupper(char_type c) const
8124684ddb6SLionel Sambuc {
8134684ddb6SLionel Sambuc #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
8144684ddb6SLionel Sambuc     return isascii(c) ? _DefaultRuneLocale.__mapupper[c] : c;
8154684ddb6SLionel Sambuc #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__) || defined(__minix)
8164684ddb6SLionel Sambuc     return isascii(c) ? ctype<char>::__classic_upper_table()[c] : c;
8174684ddb6SLionel Sambuc #else
818*0a6a1f1dSLionel Sambuc     return (isascii(c) && iswlower_l(c, _LIBCPP_GET_C_LOCALE)) ? c-L'a'+L'A' : c;
8194684ddb6SLionel Sambuc #endif
8204684ddb6SLionel Sambuc }
8214684ddb6SLionel Sambuc 
8224684ddb6SLionel Sambuc const wchar_t*
do_toupper(char_type * low,const char_type * high) const8234684ddb6SLionel Sambuc ctype<wchar_t>::do_toupper(char_type* low, const char_type* high) const
8244684ddb6SLionel Sambuc {
8254684ddb6SLionel Sambuc     for (; low != high; ++low)
8264684ddb6SLionel Sambuc #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
8274684ddb6SLionel Sambuc         *low = isascii(*low) ? _DefaultRuneLocale.__mapupper[*low] : *low;
8284684ddb6SLionel Sambuc #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__) || defined(__minix)
8294684ddb6SLionel Sambuc         *low = isascii(*low) ? ctype<char>::__classic_upper_table()[*low]
8304684ddb6SLionel Sambuc                              : *low;
8314684ddb6SLionel Sambuc #else
832*0a6a1f1dSLionel Sambuc         *low = (isascii(*low) && islower_l(*low, _LIBCPP_GET_C_LOCALE)) ? (*low-L'a'+L'A') : *low;
8334684ddb6SLionel Sambuc #endif
8344684ddb6SLionel Sambuc     return low;
8354684ddb6SLionel Sambuc }
8364684ddb6SLionel Sambuc 
8374684ddb6SLionel Sambuc wchar_t
do_tolower(char_type c) const8384684ddb6SLionel Sambuc ctype<wchar_t>::do_tolower(char_type c) const
8394684ddb6SLionel Sambuc {
8404684ddb6SLionel Sambuc #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
8414684ddb6SLionel Sambuc     return isascii(c) ? _DefaultRuneLocale.__maplower[c] : c;
8424684ddb6SLionel Sambuc #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__) || defined(__minix)
8434684ddb6SLionel Sambuc     return isascii(c) ? ctype<char>::__classic_lower_table()[c] : c;
8444684ddb6SLionel Sambuc #else
845*0a6a1f1dSLionel Sambuc     return (isascii(c) && isupper_l(c, _LIBCPP_GET_C_LOCALE)) ? c-L'A'+'a' : c;
8464684ddb6SLionel Sambuc #endif
8474684ddb6SLionel Sambuc }
8484684ddb6SLionel Sambuc 
8494684ddb6SLionel Sambuc const wchar_t*
do_tolower(char_type * low,const char_type * high) const8504684ddb6SLionel Sambuc ctype<wchar_t>::do_tolower(char_type* low, const char_type* high) const
8514684ddb6SLionel Sambuc {
8524684ddb6SLionel Sambuc     for (; low != high; ++low)
8534684ddb6SLionel Sambuc #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
8544684ddb6SLionel Sambuc         *low = isascii(*low) ? _DefaultRuneLocale.__maplower[*low] : *low;
8554684ddb6SLionel Sambuc #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__) || defined(__minix)
8564684ddb6SLionel Sambuc         *low = isascii(*low) ? ctype<char>::__classic_lower_table()[*low]
8574684ddb6SLionel Sambuc                              : *low;
8584684ddb6SLionel Sambuc #else
859*0a6a1f1dSLionel Sambuc         *low = (isascii(*low) && isupper_l(*low, _LIBCPP_GET_C_LOCALE)) ? *low-L'A'+L'a' : *low;
8604684ddb6SLionel Sambuc #endif
8614684ddb6SLionel Sambuc     return low;
8624684ddb6SLionel Sambuc }
8634684ddb6SLionel Sambuc 
8644684ddb6SLionel Sambuc wchar_t
do_widen(char c) const8654684ddb6SLionel Sambuc ctype<wchar_t>::do_widen(char c) const
8664684ddb6SLionel Sambuc {
8674684ddb6SLionel Sambuc     return c;
8684684ddb6SLionel Sambuc }
8694684ddb6SLionel Sambuc 
8704684ddb6SLionel Sambuc const char*
do_widen(const char * low,const char * high,char_type * dest) const8714684ddb6SLionel Sambuc ctype<wchar_t>::do_widen(const char* low, const char* high, char_type* dest) const
8724684ddb6SLionel Sambuc {
8734684ddb6SLionel Sambuc     for (; low != high; ++low, ++dest)
8744684ddb6SLionel Sambuc         *dest = *low;
8754684ddb6SLionel Sambuc     return low;
8764684ddb6SLionel Sambuc }
8774684ddb6SLionel Sambuc 
8784684ddb6SLionel Sambuc char
do_narrow(char_type c,char dfault) const8794684ddb6SLionel Sambuc ctype<wchar_t>::do_narrow(char_type c, char dfault) const
8804684ddb6SLionel Sambuc {
8814684ddb6SLionel Sambuc     if (isascii(c))
8824684ddb6SLionel Sambuc         return static_cast<char>(c);
8834684ddb6SLionel Sambuc     return dfault;
8844684ddb6SLionel Sambuc }
8854684ddb6SLionel Sambuc 
8864684ddb6SLionel Sambuc const wchar_t*
do_narrow(const char_type * low,const char_type * high,char dfault,char * dest) const8874684ddb6SLionel Sambuc ctype<wchar_t>::do_narrow(const char_type* low, const char_type* high, char dfault, char* dest) const
8884684ddb6SLionel Sambuc {
8894684ddb6SLionel Sambuc     for (; low != high; ++low, ++dest)
8904684ddb6SLionel Sambuc         if (isascii(*low))
8914684ddb6SLionel Sambuc             *dest = static_cast<char>(*low);
8924684ddb6SLionel Sambuc         else
8934684ddb6SLionel Sambuc             *dest = dfault;
8944684ddb6SLionel Sambuc     return low;
8954684ddb6SLionel Sambuc }
8964684ddb6SLionel Sambuc 
8974684ddb6SLionel Sambuc // template <> class ctype<char>;
8984684ddb6SLionel Sambuc 
8994684ddb6SLionel Sambuc locale::id ctype<char>::id;
9004684ddb6SLionel Sambuc 
ctype(const mask * tab,bool del,size_t refs)9014684ddb6SLionel Sambuc ctype<char>::ctype(const mask* tab, bool del, size_t refs)
9024684ddb6SLionel Sambuc     : locale::facet(refs),
9034684ddb6SLionel Sambuc       __tab_(tab),
9044684ddb6SLionel Sambuc       __del_(del)
9054684ddb6SLionel Sambuc {
9064684ddb6SLionel Sambuc   if (__tab_ == 0)
9074684ddb6SLionel Sambuc       __tab_ = classic_table();
9084684ddb6SLionel Sambuc }
9094684ddb6SLionel Sambuc 
~ctype()9104684ddb6SLionel Sambuc ctype<char>::~ctype()
9114684ddb6SLionel Sambuc {
9124684ddb6SLionel Sambuc     if (__tab_ && __del_)
9134684ddb6SLionel Sambuc         delete [] __tab_;
9144684ddb6SLionel Sambuc }
9154684ddb6SLionel Sambuc 
9164684ddb6SLionel Sambuc char
do_toupper(char_type c) const9174684ddb6SLionel Sambuc ctype<char>::do_toupper(char_type c) const
9184684ddb6SLionel Sambuc {
9194684ddb6SLionel Sambuc #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
9204684ddb6SLionel Sambuc     return isascii(c) ?
9214684ddb6SLionel Sambuc       static_cast<char>(_DefaultRuneLocale.__mapupper[static_cast<ptrdiff_t>(c)]) : c;
9224684ddb6SLionel Sambuc #elif defined(__NetBSD__) || defined(__minix)
9234684ddb6SLionel Sambuc     return static_cast<char>(__classic_upper_table()[static_cast<unsigned char>(c)]);
9244684ddb6SLionel Sambuc #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__)
9254684ddb6SLionel Sambuc     return isascii(c) ?
9264684ddb6SLionel Sambuc       static_cast<char>(__classic_upper_table()[static_cast<unsigned char>(c)]) : c;
9274684ddb6SLionel Sambuc #else
928*0a6a1f1dSLionel Sambuc     return (isascii(c) && islower_l(c, _LIBCPP_GET_C_LOCALE)) ? c-'a'+'A' : c;
9294684ddb6SLionel Sambuc #endif
9304684ddb6SLionel Sambuc }
9314684ddb6SLionel Sambuc 
9324684ddb6SLionel Sambuc const char*
do_toupper(char_type * low,const char_type * high) const9334684ddb6SLionel Sambuc ctype<char>::do_toupper(char_type* low, const char_type* high) const
9344684ddb6SLionel Sambuc {
9354684ddb6SLionel Sambuc     for (; low != high; ++low)
9364684ddb6SLionel Sambuc #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
9374684ddb6SLionel Sambuc         *low = isascii(*low) ?
9384684ddb6SLionel Sambuc           static_cast<char>(_DefaultRuneLocale.__mapupper[static_cast<ptrdiff_t>(*low)]) : *low;
939*0a6a1f1dSLionel Sambuc #elif defined(__NetBSD__)
9404684ddb6SLionel Sambuc         *low = static_cast<char>(__classic_upper_table()[static_cast<unsigned char>(*low)]);
9414684ddb6SLionel Sambuc #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__)
9424684ddb6SLionel Sambuc         *low = isascii(*low) ?
9434684ddb6SLionel Sambuc           static_cast<char>(__classic_upper_table()[static_cast<size_t>(*low)]) : *low;
9444684ddb6SLionel Sambuc #else
945*0a6a1f1dSLionel Sambuc         *low = (isascii(*low) && islower_l(*low, _LIBCPP_GET_C_LOCALE)) ? *low-'a'+'A' : *low;
9464684ddb6SLionel Sambuc #endif
9474684ddb6SLionel Sambuc     return low;
9484684ddb6SLionel Sambuc }
9494684ddb6SLionel Sambuc 
9504684ddb6SLionel Sambuc char
do_tolower(char_type c) const9514684ddb6SLionel Sambuc ctype<char>::do_tolower(char_type c) const
9524684ddb6SLionel Sambuc {
9534684ddb6SLionel Sambuc #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
9544684ddb6SLionel Sambuc     return isascii(c) ?
9554684ddb6SLionel Sambuc       static_cast<char>(_DefaultRuneLocale.__maplower[static_cast<ptrdiff_t>(c)]) : c;
9564684ddb6SLionel Sambuc #elif defined(__NetBSD__) || defined(__minix)
9574684ddb6SLionel Sambuc     return static_cast<char>(__classic_lower_table()[static_cast<unsigned char>(c)]);
9584684ddb6SLionel Sambuc #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__) || defined(__minix)
9594684ddb6SLionel Sambuc     return isascii(c) ?
9604684ddb6SLionel Sambuc       static_cast<char>(__classic_lower_table()[static_cast<size_t>(c)]) : c;
9614684ddb6SLionel Sambuc #else
962*0a6a1f1dSLionel Sambuc     return (isascii(c) && isupper_l(c, _LIBCPP_GET_C_LOCALE)) ? c-'A'+'a' : c;
9634684ddb6SLionel Sambuc #endif
9644684ddb6SLionel Sambuc }
9654684ddb6SLionel Sambuc 
9664684ddb6SLionel Sambuc const char*
do_tolower(char_type * low,const char_type * high) const9674684ddb6SLionel Sambuc ctype<char>::do_tolower(char_type* low, const char_type* high) const
9684684ddb6SLionel Sambuc {
9694684ddb6SLionel Sambuc     for (; low != high; ++low)
9704684ddb6SLionel Sambuc #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
9714684ddb6SLionel Sambuc         *low = isascii(*low) ? static_cast<char>(_DefaultRuneLocale.__maplower[static_cast<ptrdiff_t>(*low)]) : *low;
9724684ddb6SLionel Sambuc #elif defined(__NetBSD__) || defined(__minix)
9734684ddb6SLionel Sambuc         *low = static_cast<char>(__classic_lower_table()[static_cast<unsigned char>(*low)]);
9744684ddb6SLionel Sambuc #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__)
9754684ddb6SLionel Sambuc         *low = isascii(*low) ? static_cast<char>(__classic_lower_table()[static_cast<size_t>(*low)]) : *low;
9764684ddb6SLionel Sambuc #else
977*0a6a1f1dSLionel Sambuc         *low = (isascii(*low) && isupper_l(*low, _LIBCPP_GET_C_LOCALE)) ? *low-'A'+'a' : *low;
9784684ddb6SLionel Sambuc #endif
9794684ddb6SLionel Sambuc     return low;
9804684ddb6SLionel Sambuc }
9814684ddb6SLionel Sambuc 
9824684ddb6SLionel Sambuc char
do_widen(char c) const9834684ddb6SLionel Sambuc ctype<char>::do_widen(char c) const
9844684ddb6SLionel Sambuc {
9854684ddb6SLionel Sambuc     return c;
9864684ddb6SLionel Sambuc }
9874684ddb6SLionel Sambuc 
9884684ddb6SLionel Sambuc const char*
do_widen(const char * low,const char * high,char_type * dest) const9894684ddb6SLionel Sambuc ctype<char>::do_widen(const char* low, const char* high, char_type* dest) const
9904684ddb6SLionel Sambuc {
9914684ddb6SLionel Sambuc     for (; low != high; ++low, ++dest)
9924684ddb6SLionel Sambuc         *dest = *low;
9934684ddb6SLionel Sambuc     return low;
9944684ddb6SLionel Sambuc }
9954684ddb6SLionel Sambuc 
9964684ddb6SLionel Sambuc char
do_narrow(char_type c,char dfault) const9974684ddb6SLionel Sambuc ctype<char>::do_narrow(char_type c, char dfault) const
9984684ddb6SLionel Sambuc {
9994684ddb6SLionel Sambuc     if (isascii(c))
10004684ddb6SLionel Sambuc         return static_cast<char>(c);
10014684ddb6SLionel Sambuc     return dfault;
10024684ddb6SLionel Sambuc }
10034684ddb6SLionel Sambuc 
10044684ddb6SLionel Sambuc const char*
do_narrow(const char_type * low,const char_type * high,char dfault,char * dest) const10054684ddb6SLionel Sambuc ctype<char>::do_narrow(const char_type* low, const char_type* high, char dfault, char* dest) const
10064684ddb6SLionel Sambuc {
10074684ddb6SLionel Sambuc     for (; low != high; ++low, ++dest)
10084684ddb6SLionel Sambuc         if (isascii(*low))
10094684ddb6SLionel Sambuc             *dest = *low;
10104684ddb6SLionel Sambuc         else
10114684ddb6SLionel Sambuc             *dest = dfault;
10124684ddb6SLionel Sambuc     return low;
10134684ddb6SLionel Sambuc }
10144684ddb6SLionel Sambuc 
10154684ddb6SLionel Sambuc #ifdef __EMSCRIPTEN__
10164684ddb6SLionel Sambuc extern "C" const unsigned short ** __ctype_b_loc();
10174684ddb6SLionel Sambuc extern "C" const int ** __ctype_tolower_loc();
10184684ddb6SLionel Sambuc extern "C" const int ** __ctype_toupper_loc();
10194684ddb6SLionel Sambuc #endif
10204684ddb6SLionel Sambuc 
1021*0a6a1f1dSLionel Sambuc #ifdef _LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE
1022*0a6a1f1dSLionel Sambuc const ctype<char>::mask*
classic_table()1023*0a6a1f1dSLionel Sambuc ctype<char>::classic_table()  _NOEXCEPT
1024*0a6a1f1dSLionel Sambuc {
1025*0a6a1f1dSLionel Sambuc     static _LIBCPP_CONSTEXPR const ctype<char>::mask builtin_table[table_size] = {
1026*0a6a1f1dSLionel Sambuc         cntrl,                          cntrl,
1027*0a6a1f1dSLionel Sambuc         cntrl,                          cntrl,
1028*0a6a1f1dSLionel Sambuc         cntrl,                          cntrl,
1029*0a6a1f1dSLionel Sambuc         cntrl,                          cntrl,
1030*0a6a1f1dSLionel Sambuc         cntrl,                          cntrl | space | blank,
1031*0a6a1f1dSLionel Sambuc         cntrl | space,                  cntrl | space,
1032*0a6a1f1dSLionel Sambuc         cntrl | space,                  cntrl | space,
1033*0a6a1f1dSLionel Sambuc         cntrl,                          cntrl,
1034*0a6a1f1dSLionel Sambuc         cntrl,                          cntrl,
1035*0a6a1f1dSLionel Sambuc         cntrl,                          cntrl,
1036*0a6a1f1dSLionel Sambuc         cntrl,                          cntrl,
1037*0a6a1f1dSLionel Sambuc         cntrl,                          cntrl,
1038*0a6a1f1dSLionel Sambuc         cntrl,                          cntrl,
1039*0a6a1f1dSLionel Sambuc         cntrl,                          cntrl,
1040*0a6a1f1dSLionel Sambuc         cntrl,                          cntrl,
1041*0a6a1f1dSLionel Sambuc         cntrl,                          cntrl,
1042*0a6a1f1dSLionel Sambuc         space | blank | print,          punct | print,
1043*0a6a1f1dSLionel Sambuc         punct | print,                  punct | print,
1044*0a6a1f1dSLionel Sambuc         punct | print,                  punct | print,
1045*0a6a1f1dSLionel Sambuc         punct | print,                  punct | print,
1046*0a6a1f1dSLionel Sambuc         punct | print,                  punct | print,
1047*0a6a1f1dSLionel Sambuc         punct | print,                  punct | print,
1048*0a6a1f1dSLionel Sambuc         punct | print,                  punct | print,
1049*0a6a1f1dSLionel Sambuc         punct | print,                  punct | print,
1050*0a6a1f1dSLionel Sambuc         digit | print | xdigit,         digit | print | xdigit,
1051*0a6a1f1dSLionel Sambuc         digit | print | xdigit,         digit | print | xdigit,
1052*0a6a1f1dSLionel Sambuc         digit | print | xdigit,         digit | print | xdigit,
1053*0a6a1f1dSLionel Sambuc         digit | print | xdigit,         digit | print | xdigit,
1054*0a6a1f1dSLionel Sambuc         digit | print | xdigit,         digit | print | xdigit,
1055*0a6a1f1dSLionel Sambuc         punct | print,                  punct | print,
1056*0a6a1f1dSLionel Sambuc         punct | print,                  punct | print,
1057*0a6a1f1dSLionel Sambuc         punct | print,                  punct | print,
1058*0a6a1f1dSLionel Sambuc         punct | print,                  upper | xdigit | print | alpha,
1059*0a6a1f1dSLionel Sambuc         upper | xdigit | print | alpha, upper | xdigit | print | alpha,
1060*0a6a1f1dSLionel Sambuc         upper | xdigit | print | alpha, upper | xdigit | print | alpha,
1061*0a6a1f1dSLionel Sambuc         upper | xdigit | print | alpha, upper | print | alpha,
1062*0a6a1f1dSLionel Sambuc         upper | print | alpha,          upper | print | alpha,
1063*0a6a1f1dSLionel Sambuc         upper | print | alpha,          upper | print | alpha,
1064*0a6a1f1dSLionel Sambuc         upper | print | alpha,          upper | print | alpha,
1065*0a6a1f1dSLionel Sambuc         upper | print | alpha,          upper | print | alpha,
1066*0a6a1f1dSLionel Sambuc         upper | print | alpha,          upper | print | alpha,
1067*0a6a1f1dSLionel Sambuc         upper | print | alpha,          upper | print | alpha,
1068*0a6a1f1dSLionel Sambuc         upper | print | alpha,          upper | print | alpha,
1069*0a6a1f1dSLionel Sambuc         upper | print | alpha,          upper | print | alpha,
1070*0a6a1f1dSLionel Sambuc         upper | print | alpha,          upper | print | alpha,
1071*0a6a1f1dSLionel Sambuc         upper | print | alpha,          punct | print,
1072*0a6a1f1dSLionel Sambuc         punct | print,                  punct | print,
1073*0a6a1f1dSLionel Sambuc         punct | print,                  punct | print,
1074*0a6a1f1dSLionel Sambuc         punct | print,                  lower | xdigit | print | alpha,
1075*0a6a1f1dSLionel Sambuc         lower | xdigit | print | alpha, lower | xdigit | print | alpha,
1076*0a6a1f1dSLionel Sambuc         lower | xdigit | print | alpha, lower | xdigit | print | alpha,
1077*0a6a1f1dSLionel Sambuc         lower | xdigit | print | alpha, lower | print | alpha,
1078*0a6a1f1dSLionel Sambuc         lower | print | alpha,          lower | print | alpha,
1079*0a6a1f1dSLionel Sambuc         lower | print | alpha,          lower | print | alpha,
1080*0a6a1f1dSLionel Sambuc         lower | print | alpha,          lower | print | alpha,
1081*0a6a1f1dSLionel Sambuc         lower | print | alpha,          lower | print | alpha,
1082*0a6a1f1dSLionel Sambuc         lower | print | alpha,          lower | print | alpha,
1083*0a6a1f1dSLionel Sambuc         lower | print | alpha,          lower | print | alpha,
1084*0a6a1f1dSLionel Sambuc         lower | print | alpha,          lower | print | alpha,
1085*0a6a1f1dSLionel Sambuc         lower | print | alpha,          lower | print | alpha,
1086*0a6a1f1dSLionel Sambuc         lower | print | alpha,          lower | print | alpha,
1087*0a6a1f1dSLionel Sambuc         lower | print | alpha,          punct | print,
1088*0a6a1f1dSLionel Sambuc         punct | print,                  punct | print,
1089*0a6a1f1dSLionel Sambuc         punct | print,                  cntrl,
1090*0a6a1f1dSLionel Sambuc         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1091*0a6a1f1dSLionel Sambuc         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1092*0a6a1f1dSLionel Sambuc         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1093*0a6a1f1dSLionel Sambuc         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1094*0a6a1f1dSLionel Sambuc         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1095*0a6a1f1dSLionel Sambuc         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1096*0a6a1f1dSLionel Sambuc         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1097*0a6a1f1dSLionel Sambuc         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
1098*0a6a1f1dSLionel Sambuc     };
1099*0a6a1f1dSLionel Sambuc     return builtin_table;
1100*0a6a1f1dSLionel Sambuc }
1101*0a6a1f1dSLionel Sambuc #else
11024684ddb6SLionel Sambuc const ctype<char>::mask*
classic_table()11034684ddb6SLionel Sambuc ctype<char>::classic_table()  _NOEXCEPT
11044684ddb6SLionel Sambuc {
11054684ddb6SLionel Sambuc #if defined(__APPLE__) || defined(__FreeBSD__)
11064684ddb6SLionel Sambuc     return _DefaultRuneLocale.__runetype;
11074684ddb6SLionel Sambuc #elif defined(__NetBSD__) || defined(__minix)
11084684ddb6SLionel Sambuc     return _C_ctype_tab_ + 1;
11094684ddb6SLionel Sambuc #elif defined(__GLIBC__)
1110*0a6a1f1dSLionel Sambuc     return _LIBCPP_GET_C_LOCALE->__ctype_b;
11114684ddb6SLionel Sambuc #elif __sun__
11124684ddb6SLionel Sambuc     return __ctype_mask;
11134684ddb6SLionel Sambuc #elif defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
11144684ddb6SLionel Sambuc     return _ctype+1; // internal ctype mask table defined in msvcrt.dll
11154684ddb6SLionel Sambuc // This is assumed to be safe, which is a nonsense assumption because we're
11164684ddb6SLionel Sambuc // going to end up dereferencing it later...
11174684ddb6SLionel Sambuc #elif defined(__EMSCRIPTEN__)
11184684ddb6SLionel Sambuc     return *__ctype_b_loc();
1119*0a6a1f1dSLionel Sambuc #elif defined(_NEWLIB_VERSION)
1120*0a6a1f1dSLionel Sambuc     // Newlib has a 257-entry table in ctype_.c, where (char)0 starts at [1].
1121*0a6a1f1dSLionel Sambuc     return _ctype_ + 1;
11224684ddb6SLionel Sambuc #elif defined(_AIX)
11234684ddb6SLionel Sambuc     return (const unsigned int *)__lc_ctype_ptr->obj->mask;
11244684ddb6SLionel Sambuc #else
11254684ddb6SLionel Sambuc     // Platform not supported: abort so the person doing the port knows what to
11264684ddb6SLionel Sambuc     // fix
11274684ddb6SLionel Sambuc # warning  ctype<char>::classic_table() is not implemented
11284684ddb6SLionel Sambuc     printf("ctype<char>::classic_table() is not implemented\n");
11294684ddb6SLionel Sambuc     abort();
11304684ddb6SLionel Sambuc     return NULL;
11314684ddb6SLionel Sambuc #endif
11324684ddb6SLionel Sambuc }
1133*0a6a1f1dSLionel Sambuc #endif
11344684ddb6SLionel Sambuc 
11354684ddb6SLionel Sambuc #if defined(__GLIBC__)
11364684ddb6SLionel Sambuc const int*
__classic_lower_table()11374684ddb6SLionel Sambuc ctype<char>::__classic_lower_table() _NOEXCEPT
11384684ddb6SLionel Sambuc {
1139*0a6a1f1dSLionel Sambuc     return _LIBCPP_GET_C_LOCALE->__ctype_tolower;
11404684ddb6SLionel Sambuc }
11414684ddb6SLionel Sambuc 
11424684ddb6SLionel Sambuc const int*
__classic_upper_table()11434684ddb6SLionel Sambuc ctype<char>::__classic_upper_table() _NOEXCEPT
11444684ddb6SLionel Sambuc {
1145*0a6a1f1dSLionel Sambuc     return _LIBCPP_GET_C_LOCALE->__ctype_toupper;
11464684ddb6SLionel Sambuc }
11474684ddb6SLionel Sambuc #elif __NetBSD__ || defined(__minix)
11484684ddb6SLionel Sambuc const short*
__classic_lower_table()11494684ddb6SLionel Sambuc ctype<char>::__classic_lower_table() _NOEXCEPT
11504684ddb6SLionel Sambuc {
11514684ddb6SLionel Sambuc     return _C_tolower_tab_ + 1;
11524684ddb6SLionel Sambuc }
11534684ddb6SLionel Sambuc 
11544684ddb6SLionel Sambuc const short*
__classic_upper_table()11554684ddb6SLionel Sambuc ctype<char>::__classic_upper_table() _NOEXCEPT
11564684ddb6SLionel Sambuc {
11574684ddb6SLionel Sambuc     return _C_toupper_tab_ + 1;
11584684ddb6SLionel Sambuc }
11594684ddb6SLionel Sambuc 
11604684ddb6SLionel Sambuc #elif defined(__EMSCRIPTEN__)
11614684ddb6SLionel Sambuc const int*
__classic_lower_table()11624684ddb6SLionel Sambuc ctype<char>::__classic_lower_table() _NOEXCEPT
11634684ddb6SLionel Sambuc {
11644684ddb6SLionel Sambuc     return *__ctype_tolower_loc();
11654684ddb6SLionel Sambuc }
11664684ddb6SLionel Sambuc 
11674684ddb6SLionel Sambuc const int*
__classic_upper_table()11684684ddb6SLionel Sambuc ctype<char>::__classic_upper_table() _NOEXCEPT
11694684ddb6SLionel Sambuc {
11704684ddb6SLionel Sambuc     return *__ctype_toupper_loc();
11714684ddb6SLionel Sambuc }
11724684ddb6SLionel Sambuc #endif // __GLIBC__ || __EMSCRIPTEN__ || __NETBSD__
11734684ddb6SLionel Sambuc 
11744684ddb6SLionel Sambuc // template <> class ctype_byname<char>
11754684ddb6SLionel Sambuc 
ctype_byname(const char * name,size_t refs)11764684ddb6SLionel Sambuc ctype_byname<char>::ctype_byname(const char* name, size_t refs)
11774684ddb6SLionel Sambuc     : ctype<char>(0, false, refs),
11784684ddb6SLionel Sambuc       __l(newlocale(LC_ALL_MASK, name, 0))
11794684ddb6SLionel Sambuc {
11804684ddb6SLionel Sambuc #ifndef _LIBCPP_NO_EXCEPTIONS
11814684ddb6SLionel Sambuc     if (__l == 0)
11824684ddb6SLionel Sambuc         throw runtime_error("ctype_byname<char>::ctype_byname"
11834684ddb6SLionel Sambuc                             " failed to construct for " + string(name));
11844684ddb6SLionel Sambuc #endif  // _LIBCPP_NO_EXCEPTIONS
11854684ddb6SLionel Sambuc }
11864684ddb6SLionel Sambuc 
ctype_byname(const string & name,size_t refs)11874684ddb6SLionel Sambuc ctype_byname<char>::ctype_byname(const string& name, size_t refs)
11884684ddb6SLionel Sambuc     : ctype<char>(0, false, refs),
11894684ddb6SLionel Sambuc       __l(newlocale(LC_ALL_MASK, name.c_str(), 0))
11904684ddb6SLionel Sambuc {
11914684ddb6SLionel Sambuc #ifndef _LIBCPP_NO_EXCEPTIONS
11924684ddb6SLionel Sambuc     if (__l == 0)
11934684ddb6SLionel Sambuc         throw runtime_error("ctype_byname<char>::ctype_byname"
11944684ddb6SLionel Sambuc                             " failed to construct for " + name);
11954684ddb6SLionel Sambuc #endif  // _LIBCPP_NO_EXCEPTIONS
11964684ddb6SLionel Sambuc }
11974684ddb6SLionel Sambuc 
~ctype_byname()11984684ddb6SLionel Sambuc ctype_byname<char>::~ctype_byname()
11994684ddb6SLionel Sambuc {
12004684ddb6SLionel Sambuc     freelocale(__l);
12014684ddb6SLionel Sambuc }
12024684ddb6SLionel Sambuc 
12034684ddb6SLionel Sambuc char
do_toupper(char_type c) const12044684ddb6SLionel Sambuc ctype_byname<char>::do_toupper(char_type c) const
12054684ddb6SLionel Sambuc {
12064684ddb6SLionel Sambuc     return static_cast<char>(toupper_l(static_cast<unsigned char>(c), __l));
12074684ddb6SLionel Sambuc }
12084684ddb6SLionel Sambuc 
12094684ddb6SLionel Sambuc const char*
do_toupper(char_type * low,const char_type * high) const12104684ddb6SLionel Sambuc ctype_byname<char>::do_toupper(char_type* low, const char_type* high) const
12114684ddb6SLionel Sambuc {
12124684ddb6SLionel Sambuc     for (; low != high; ++low)
12134684ddb6SLionel Sambuc         *low = static_cast<char>(toupper_l(static_cast<unsigned char>(*low), __l));
12144684ddb6SLionel Sambuc     return low;
12154684ddb6SLionel Sambuc }
12164684ddb6SLionel Sambuc 
12174684ddb6SLionel Sambuc char
do_tolower(char_type c) const12184684ddb6SLionel Sambuc ctype_byname<char>::do_tolower(char_type c) const
12194684ddb6SLionel Sambuc {
12204684ddb6SLionel Sambuc     return static_cast<char>(tolower_l(static_cast<unsigned char>(c), __l));
12214684ddb6SLionel Sambuc }
12224684ddb6SLionel Sambuc 
12234684ddb6SLionel Sambuc const char*
do_tolower(char_type * low,const char_type * high) const12244684ddb6SLionel Sambuc ctype_byname<char>::do_tolower(char_type* low, const char_type* high) const
12254684ddb6SLionel Sambuc {
12264684ddb6SLionel Sambuc     for (; low != high; ++low)
12274684ddb6SLionel Sambuc         *low = static_cast<char>(tolower_l(static_cast<unsigned char>(*low), __l));
12284684ddb6SLionel Sambuc     return low;
12294684ddb6SLionel Sambuc }
12304684ddb6SLionel Sambuc 
12314684ddb6SLionel Sambuc // template <> class ctype_byname<wchar_t>
12324684ddb6SLionel Sambuc 
ctype_byname(const char * name,size_t refs)12334684ddb6SLionel Sambuc ctype_byname<wchar_t>::ctype_byname(const char* name, size_t refs)
12344684ddb6SLionel Sambuc     : ctype<wchar_t>(refs),
12354684ddb6SLionel Sambuc       __l(newlocale(LC_ALL_MASK, name, 0))
12364684ddb6SLionel Sambuc {
12374684ddb6SLionel Sambuc #ifndef _LIBCPP_NO_EXCEPTIONS
12384684ddb6SLionel Sambuc     if (__l == 0)
12394684ddb6SLionel Sambuc         throw runtime_error("ctype_byname<wchar_t>::ctype_byname"
12404684ddb6SLionel Sambuc                             " failed to construct for " + string(name));
12414684ddb6SLionel Sambuc #endif  // _LIBCPP_NO_EXCEPTIONS
12424684ddb6SLionel Sambuc }
12434684ddb6SLionel Sambuc 
ctype_byname(const string & name,size_t refs)12444684ddb6SLionel Sambuc ctype_byname<wchar_t>::ctype_byname(const string& name, size_t refs)
12454684ddb6SLionel Sambuc     : ctype<wchar_t>(refs),
12464684ddb6SLionel Sambuc       __l(newlocale(LC_ALL_MASK, name.c_str(), 0))
12474684ddb6SLionel Sambuc {
12484684ddb6SLionel Sambuc #ifndef _LIBCPP_NO_EXCEPTIONS
12494684ddb6SLionel Sambuc     if (__l == 0)
12504684ddb6SLionel Sambuc         throw runtime_error("ctype_byname<wchar_t>::ctype_byname"
12514684ddb6SLionel Sambuc                             " failed to construct for " + name);
12524684ddb6SLionel Sambuc #endif  // _LIBCPP_NO_EXCEPTIONS
12534684ddb6SLionel Sambuc }
12544684ddb6SLionel Sambuc 
~ctype_byname()12554684ddb6SLionel Sambuc ctype_byname<wchar_t>::~ctype_byname()
12564684ddb6SLionel Sambuc {
12574684ddb6SLionel Sambuc     freelocale(__l);
12584684ddb6SLionel Sambuc }
12594684ddb6SLionel Sambuc 
12604684ddb6SLionel Sambuc bool
do_is(mask m,char_type c) const12614684ddb6SLionel Sambuc ctype_byname<wchar_t>::do_is(mask m, char_type c) const
12624684ddb6SLionel Sambuc {
12634684ddb6SLionel Sambuc #ifdef _LIBCPP_WCTYPE_IS_MASK
12644684ddb6SLionel Sambuc     return static_cast<bool>(iswctype_l(c, m, __l));
12654684ddb6SLionel Sambuc #else
12664684ddb6SLionel Sambuc     bool result = false;
12674684ddb6SLionel Sambuc     wint_t ch = static_cast<wint_t>(c);
1268*0a6a1f1dSLionel Sambuc     if ((m & space) == space) result |= (iswspace_l(ch, __l) != 0);
1269*0a6a1f1dSLionel Sambuc     if ((m & print) == print) result |= (iswprint_l(ch, __l) != 0);
1270*0a6a1f1dSLionel Sambuc     if ((m & cntrl) == cntrl) result |= (iswcntrl_l(ch, __l) != 0);
1271*0a6a1f1dSLionel Sambuc     if ((m & upper) == upper) result |= (iswupper_l(ch, __l) != 0);
1272*0a6a1f1dSLionel Sambuc     if ((m & lower) == lower) result |= (iswlower_l(ch, __l) != 0);
1273*0a6a1f1dSLionel Sambuc     if ((m & alpha) == alpha) result |= (iswalpha_l(ch, __l) != 0);
1274*0a6a1f1dSLionel Sambuc     if ((m & digit) == digit) result |= (iswdigit_l(ch, __l) != 0);
1275*0a6a1f1dSLionel Sambuc     if ((m & punct) == punct) result |= (iswpunct_l(ch, __l) != 0);
1276*0a6a1f1dSLionel Sambuc     if ((m & xdigit) == xdigit) result |= (iswxdigit_l(ch, __l) != 0);
1277*0a6a1f1dSLionel Sambuc     if ((m & blank) == blank) result |= (iswblank_l(ch, __l) != 0);
12784684ddb6SLionel Sambuc     return result;
12794684ddb6SLionel Sambuc #endif
12804684ddb6SLionel Sambuc }
12814684ddb6SLionel Sambuc 
12824684ddb6SLionel Sambuc const wchar_t*
do_is(const char_type * low,const char_type * high,mask * vec) const12834684ddb6SLionel Sambuc ctype_byname<wchar_t>::do_is(const char_type* low, const char_type* high, mask* vec) const
12844684ddb6SLionel Sambuc {
12854684ddb6SLionel Sambuc     for (; low != high; ++low, ++vec)
12864684ddb6SLionel Sambuc     {
12874684ddb6SLionel Sambuc         if (isascii(*low))
12884684ddb6SLionel Sambuc             *vec = static_cast<mask>(ctype<char>::classic_table()[*low]);
12894684ddb6SLionel Sambuc         else
12904684ddb6SLionel Sambuc         {
12914684ddb6SLionel Sambuc             *vec = 0;
12924684ddb6SLionel Sambuc             wint_t ch = static_cast<wint_t>(*low);
12934684ddb6SLionel Sambuc             if (iswspace_l(ch, __l))
12944684ddb6SLionel Sambuc                 *vec |= space;
1295*0a6a1f1dSLionel Sambuc #ifndef _LIBCPP_CTYPE_MASK_IS_COMPOSITE_PRINT
12964684ddb6SLionel Sambuc             if (iswprint_l(ch, __l))
12974684ddb6SLionel Sambuc                 *vec |= print;
1298*0a6a1f1dSLionel Sambuc #endif
12994684ddb6SLionel Sambuc             if (iswcntrl_l(ch, __l))
13004684ddb6SLionel Sambuc                 *vec |= cntrl;
13014684ddb6SLionel Sambuc             if (iswupper_l(ch, __l))
13024684ddb6SLionel Sambuc                 *vec |= upper;
13034684ddb6SLionel Sambuc             if (iswlower_l(ch, __l))
13044684ddb6SLionel Sambuc                 *vec |= lower;
1305*0a6a1f1dSLionel Sambuc #ifndef _LIBCPP_CTYPE_MASK_IS_COMPOSITE_ALPHA
13064684ddb6SLionel Sambuc             if (iswalpha_l(ch, __l))
13074684ddb6SLionel Sambuc                 *vec |= alpha;
1308*0a6a1f1dSLionel Sambuc #endif
13094684ddb6SLionel Sambuc             if (iswdigit_l(ch, __l))
13104684ddb6SLionel Sambuc                 *vec |= digit;
13114684ddb6SLionel Sambuc             if (iswpunct_l(ch, __l))
13124684ddb6SLionel Sambuc                 *vec |= punct;
1313*0a6a1f1dSLionel Sambuc #ifndef _LIBCPP_CTYPE_MASK_IS_COMPOSITE_XDIGIT
13144684ddb6SLionel Sambuc             if (iswxdigit_l(ch, __l))
13154684ddb6SLionel Sambuc                 *vec |= xdigit;
1316*0a6a1f1dSLionel Sambuc #endif
1317*0a6a1f1dSLionel Sambuc #if !defined(__sun__)
1318*0a6a1f1dSLionel Sambuc             if (iswblank_l(ch, __l))
1319*0a6a1f1dSLionel Sambuc                 *vec |= blank;
1320*0a6a1f1dSLionel Sambuc #endif
13214684ddb6SLionel Sambuc         }
13224684ddb6SLionel Sambuc     }
13234684ddb6SLionel Sambuc     return low;
13244684ddb6SLionel Sambuc }
13254684ddb6SLionel Sambuc 
13264684ddb6SLionel Sambuc const wchar_t*
do_scan_is(mask m,const char_type * low,const char_type * high) const13274684ddb6SLionel Sambuc ctype_byname<wchar_t>::do_scan_is(mask m, const char_type* low, const char_type* high) const
13284684ddb6SLionel Sambuc {
13294684ddb6SLionel Sambuc     for (; low != high; ++low)
13304684ddb6SLionel Sambuc     {
13314684ddb6SLionel Sambuc #ifdef _LIBCPP_WCTYPE_IS_MASK
13324684ddb6SLionel Sambuc         if (iswctype_l(*low, m, __l))
13334684ddb6SLionel Sambuc             break;
13344684ddb6SLionel Sambuc #else
13354684ddb6SLionel Sambuc         wint_t ch = static_cast<wint_t>(*low);
1336*0a6a1f1dSLionel Sambuc         if ((m & space) == space && iswspace_l(ch, __l)) break;
1337*0a6a1f1dSLionel Sambuc         if ((m & print) == print && iswprint_l(ch, __l)) break;
1338*0a6a1f1dSLionel Sambuc         if ((m & cntrl) == cntrl && iswcntrl_l(ch, __l)) break;
1339*0a6a1f1dSLionel Sambuc         if ((m & upper) == upper && iswupper_l(ch, __l)) break;
1340*0a6a1f1dSLionel Sambuc         if ((m & lower) == lower && iswlower_l(ch, __l)) break;
1341*0a6a1f1dSLionel Sambuc         if ((m & alpha) == alpha && iswalpha_l(ch, __l)) break;
1342*0a6a1f1dSLionel Sambuc         if ((m & digit) == digit && iswdigit_l(ch, __l)) break;
1343*0a6a1f1dSLionel Sambuc         if ((m & punct) == punct && iswpunct_l(ch, __l)) break;
1344*0a6a1f1dSLionel Sambuc         if ((m & xdigit) == xdigit && iswxdigit_l(ch, __l)) break;
1345*0a6a1f1dSLionel Sambuc         if ((m & blank) == blank && iswblank_l(ch, __l)) break;
13464684ddb6SLionel Sambuc #endif
13474684ddb6SLionel Sambuc     }
13484684ddb6SLionel Sambuc     return low;
13494684ddb6SLionel Sambuc }
13504684ddb6SLionel Sambuc 
13514684ddb6SLionel Sambuc const wchar_t*
do_scan_not(mask m,const char_type * low,const char_type * high) const13524684ddb6SLionel Sambuc ctype_byname<wchar_t>::do_scan_not(mask m, const char_type* low, const char_type* high) const
13534684ddb6SLionel Sambuc {
13544684ddb6SLionel Sambuc     for (; low != high; ++low)
13554684ddb6SLionel Sambuc     {
13564684ddb6SLionel Sambuc #ifdef _LIBCPP_WCTYPE_IS_MASK
13574684ddb6SLionel Sambuc         if (!iswctype_l(*low, m, __l))
13584684ddb6SLionel Sambuc             break;
13594684ddb6SLionel Sambuc #else
13604684ddb6SLionel Sambuc         wint_t ch = static_cast<wint_t>(*low);
1361*0a6a1f1dSLionel Sambuc         if ((m & space) == space && iswspace_l(ch, __l)) continue;
1362*0a6a1f1dSLionel Sambuc         if ((m & print) == print && iswprint_l(ch, __l)) continue;
1363*0a6a1f1dSLionel Sambuc         if ((m & cntrl) == cntrl && iswcntrl_l(ch, __l)) continue;
1364*0a6a1f1dSLionel Sambuc         if ((m & upper) == upper && iswupper_l(ch, __l)) continue;
1365*0a6a1f1dSLionel Sambuc         if ((m & lower) == lower && iswlower_l(ch, __l)) continue;
1366*0a6a1f1dSLionel Sambuc         if ((m & alpha) == alpha && iswalpha_l(ch, __l)) continue;
1367*0a6a1f1dSLionel Sambuc         if ((m & digit) == digit && iswdigit_l(ch, __l)) continue;
1368*0a6a1f1dSLionel Sambuc         if ((m & punct) == punct && iswpunct_l(ch, __l)) continue;
1369*0a6a1f1dSLionel Sambuc         if ((m & xdigit) == xdigit && iswxdigit_l(ch, __l)) continue;
1370*0a6a1f1dSLionel Sambuc         if ((m & blank) == blank && iswblank_l(ch, __l)) continue;
13714684ddb6SLionel Sambuc         break;
13724684ddb6SLionel Sambuc #endif
13734684ddb6SLionel Sambuc     }
13744684ddb6SLionel Sambuc     return low;
13754684ddb6SLionel Sambuc }
13764684ddb6SLionel Sambuc 
13774684ddb6SLionel Sambuc wchar_t
do_toupper(char_type c) const13784684ddb6SLionel Sambuc ctype_byname<wchar_t>::do_toupper(char_type c) const
13794684ddb6SLionel Sambuc {
13804684ddb6SLionel Sambuc     return towupper_l(c, __l);
13814684ddb6SLionel Sambuc }
13824684ddb6SLionel Sambuc 
13834684ddb6SLionel Sambuc const wchar_t*
do_toupper(char_type * low,const char_type * high) const13844684ddb6SLionel Sambuc ctype_byname<wchar_t>::do_toupper(char_type* low, const char_type* high) const
13854684ddb6SLionel Sambuc {
13864684ddb6SLionel Sambuc     for (; low != high; ++low)
13874684ddb6SLionel Sambuc         *low = towupper_l(*low, __l);
13884684ddb6SLionel Sambuc     return low;
13894684ddb6SLionel Sambuc }
13904684ddb6SLionel Sambuc 
13914684ddb6SLionel Sambuc wchar_t
do_tolower(char_type c) const13924684ddb6SLionel Sambuc ctype_byname<wchar_t>::do_tolower(char_type c) const
13934684ddb6SLionel Sambuc {
13944684ddb6SLionel Sambuc     return towlower_l(c, __l);
13954684ddb6SLionel Sambuc }
13964684ddb6SLionel Sambuc 
13974684ddb6SLionel Sambuc const wchar_t*
do_tolower(char_type * low,const char_type * high) const13984684ddb6SLionel Sambuc ctype_byname<wchar_t>::do_tolower(char_type* low, const char_type* high) const
13994684ddb6SLionel Sambuc {
14004684ddb6SLionel Sambuc     for (; low != high; ++low)
14014684ddb6SLionel Sambuc         *low = towlower_l(*low, __l);
14024684ddb6SLionel Sambuc     return low;
14034684ddb6SLionel Sambuc }
14044684ddb6SLionel Sambuc 
14054684ddb6SLionel Sambuc wchar_t
do_widen(char c) const14064684ddb6SLionel Sambuc ctype_byname<wchar_t>::do_widen(char c) const
14074684ddb6SLionel Sambuc {
14084684ddb6SLionel Sambuc #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
14094684ddb6SLionel Sambuc     return btowc_l(c, __l);
14104684ddb6SLionel Sambuc #else
14114684ddb6SLionel Sambuc     return __btowc_l(c, __l);
14124684ddb6SLionel Sambuc #endif
14134684ddb6SLionel Sambuc }
14144684ddb6SLionel Sambuc 
14154684ddb6SLionel Sambuc const char*
do_widen(const char * low,const char * high,char_type * dest) const14164684ddb6SLionel Sambuc ctype_byname<wchar_t>::do_widen(const char* low, const char* high, char_type* dest) const
14174684ddb6SLionel Sambuc {
14184684ddb6SLionel Sambuc     for (; low != high; ++low, ++dest)
14194684ddb6SLionel Sambuc #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
14204684ddb6SLionel Sambuc         *dest = btowc_l(*low, __l);
14214684ddb6SLionel Sambuc #else
14224684ddb6SLionel Sambuc         *dest = __btowc_l(*low, __l);
14234684ddb6SLionel Sambuc #endif
14244684ddb6SLionel Sambuc     return low;
14254684ddb6SLionel Sambuc }
14264684ddb6SLionel Sambuc 
14274684ddb6SLionel Sambuc char
do_narrow(char_type c,char dfault) const14284684ddb6SLionel Sambuc ctype_byname<wchar_t>::do_narrow(char_type c, char dfault) const
14294684ddb6SLionel Sambuc {
14304684ddb6SLionel Sambuc #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
14314684ddb6SLionel Sambuc     int r = wctob_l(c, __l);
14324684ddb6SLionel Sambuc #else
14334684ddb6SLionel Sambuc     int r = __wctob_l(c, __l);
14344684ddb6SLionel Sambuc #endif
14354684ddb6SLionel Sambuc     return r != static_cast<int>(WEOF) ? static_cast<char>(r) : dfault;
14364684ddb6SLionel Sambuc }
14374684ddb6SLionel Sambuc 
14384684ddb6SLionel Sambuc const wchar_t*
do_narrow(const char_type * low,const char_type * high,char dfault,char * dest) const14394684ddb6SLionel Sambuc ctype_byname<wchar_t>::do_narrow(const char_type* low, const char_type* high, char dfault, char* dest) const
14404684ddb6SLionel Sambuc {
14414684ddb6SLionel Sambuc     for (; low != high; ++low, ++dest)
14424684ddb6SLionel Sambuc     {
14434684ddb6SLionel Sambuc #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
14444684ddb6SLionel Sambuc         int r = wctob_l(*low, __l);
14454684ddb6SLionel Sambuc #else
14464684ddb6SLionel Sambuc         int r = __wctob_l(*low, __l);
14474684ddb6SLionel Sambuc #endif
14484684ddb6SLionel Sambuc         *dest = r != static_cast<int>(WEOF) ? static_cast<char>(r) : dfault;
14494684ddb6SLionel Sambuc     }
14504684ddb6SLionel Sambuc     return low;
14514684ddb6SLionel Sambuc }
14524684ddb6SLionel Sambuc 
14534684ddb6SLionel Sambuc // template <> class codecvt<char, char, mbstate_t>
14544684ddb6SLionel Sambuc 
14554684ddb6SLionel Sambuc locale::id codecvt<char, char, mbstate_t>::id;
14564684ddb6SLionel Sambuc 
~codecvt()14574684ddb6SLionel Sambuc codecvt<char, char, mbstate_t>::~codecvt()
14584684ddb6SLionel Sambuc {
14594684ddb6SLionel Sambuc }
14604684ddb6SLionel Sambuc 
14614684ddb6SLionel Sambuc codecvt<char, char, mbstate_t>::result
do_out(state_type &,const intern_type * frm,const intern_type *,const intern_type * & frm_nxt,extern_type * to,extern_type *,extern_type * & to_nxt) const14624684ddb6SLionel Sambuc codecvt<char, char, mbstate_t>::do_out(state_type&,
14634684ddb6SLionel Sambuc     const intern_type* frm, const intern_type*, const intern_type*& frm_nxt,
14644684ddb6SLionel Sambuc     extern_type* to, extern_type*, extern_type*& to_nxt) const
14654684ddb6SLionel Sambuc {
14664684ddb6SLionel Sambuc     frm_nxt = frm;
14674684ddb6SLionel Sambuc     to_nxt = to;
14684684ddb6SLionel Sambuc     return noconv;
14694684ddb6SLionel Sambuc }
14704684ddb6SLionel Sambuc 
14714684ddb6SLionel Sambuc codecvt<char, char, mbstate_t>::result
do_in(state_type &,const extern_type * frm,const extern_type *,const extern_type * & frm_nxt,intern_type * to,intern_type *,intern_type * & to_nxt) const14724684ddb6SLionel Sambuc codecvt<char, char, mbstate_t>::do_in(state_type&,
14734684ddb6SLionel Sambuc     const extern_type* frm, const extern_type*, const extern_type*& frm_nxt,
14744684ddb6SLionel Sambuc     intern_type* to, intern_type*, intern_type*& to_nxt) const
14754684ddb6SLionel Sambuc {
14764684ddb6SLionel Sambuc     frm_nxt = frm;
14774684ddb6SLionel Sambuc     to_nxt = to;
14784684ddb6SLionel Sambuc     return noconv;
14794684ddb6SLionel Sambuc }
14804684ddb6SLionel Sambuc 
14814684ddb6SLionel Sambuc codecvt<char, char, mbstate_t>::result
do_unshift(state_type &,extern_type * to,extern_type *,extern_type * & to_nxt) const14824684ddb6SLionel Sambuc codecvt<char, char, mbstate_t>::do_unshift(state_type&,
14834684ddb6SLionel Sambuc     extern_type* to, extern_type*, extern_type*& to_nxt) const
14844684ddb6SLionel Sambuc {
14854684ddb6SLionel Sambuc     to_nxt = to;
14864684ddb6SLionel Sambuc     return noconv;
14874684ddb6SLionel Sambuc }
14884684ddb6SLionel Sambuc 
14894684ddb6SLionel Sambuc int
do_encoding() const14904684ddb6SLionel Sambuc codecvt<char, char, mbstate_t>::do_encoding() const  _NOEXCEPT
14914684ddb6SLionel Sambuc {
14924684ddb6SLionel Sambuc     return 1;
14934684ddb6SLionel Sambuc }
14944684ddb6SLionel Sambuc 
14954684ddb6SLionel Sambuc bool
do_always_noconv() const14964684ddb6SLionel Sambuc codecvt<char, char, mbstate_t>::do_always_noconv() const  _NOEXCEPT
14974684ddb6SLionel Sambuc {
14984684ddb6SLionel Sambuc     return true;
14994684ddb6SLionel Sambuc }
15004684ddb6SLionel Sambuc 
15014684ddb6SLionel Sambuc int
do_length(state_type &,const extern_type * frm,const extern_type * end,size_t mx) const15024684ddb6SLionel Sambuc codecvt<char, char, mbstate_t>::do_length(state_type&,
15034684ddb6SLionel Sambuc     const extern_type* frm, const extern_type* end, size_t mx) const
15044684ddb6SLionel Sambuc {
15054684ddb6SLionel Sambuc     return static_cast<int>(min<size_t>(mx, static_cast<size_t>(end-frm)));
15064684ddb6SLionel Sambuc }
15074684ddb6SLionel Sambuc 
15084684ddb6SLionel Sambuc int
do_max_length() const15094684ddb6SLionel Sambuc codecvt<char, char, mbstate_t>::do_max_length() const  _NOEXCEPT
15104684ddb6SLionel Sambuc {
15114684ddb6SLionel Sambuc     return 1;
15124684ddb6SLionel Sambuc }
15134684ddb6SLionel Sambuc 
15144684ddb6SLionel Sambuc // template <> class codecvt<wchar_t, char, mbstate_t>
15154684ddb6SLionel Sambuc 
15164684ddb6SLionel Sambuc locale::id codecvt<wchar_t, char, mbstate_t>::id;
15174684ddb6SLionel Sambuc 
codecvt(size_t refs)15184684ddb6SLionel Sambuc codecvt<wchar_t, char, mbstate_t>::codecvt(size_t refs)
15194684ddb6SLionel Sambuc     : locale::facet(refs),
15204684ddb6SLionel Sambuc       __l(_LIBCPP_GET_C_LOCALE)
15214684ddb6SLionel Sambuc {
15224684ddb6SLionel Sambuc }
15234684ddb6SLionel Sambuc 
codecvt(const char * nm,size_t refs)15244684ddb6SLionel Sambuc codecvt<wchar_t, char, mbstate_t>::codecvt(const char* nm, size_t refs)
15254684ddb6SLionel Sambuc     : locale::facet(refs),
15264684ddb6SLionel Sambuc       __l(newlocale(LC_ALL_MASK, nm, 0))
15274684ddb6SLionel Sambuc {
15284684ddb6SLionel Sambuc #ifndef _LIBCPP_NO_EXCEPTIONS
15294684ddb6SLionel Sambuc     if (__l == 0)
15304684ddb6SLionel Sambuc         throw runtime_error("codecvt_byname<wchar_t, char, mbstate_t>::codecvt_byname"
15314684ddb6SLionel Sambuc                             " failed to construct for " + string(nm));
15324684ddb6SLionel Sambuc #endif  // _LIBCPP_NO_EXCEPTIONS
15334684ddb6SLionel Sambuc }
15344684ddb6SLionel Sambuc 
~codecvt()15354684ddb6SLionel Sambuc codecvt<wchar_t, char, mbstate_t>::~codecvt()
15364684ddb6SLionel Sambuc {
15374684ddb6SLionel Sambuc     if (__l != _LIBCPP_GET_C_LOCALE)
15384684ddb6SLionel Sambuc         freelocale(__l);
15394684ddb6SLionel Sambuc }
15404684ddb6SLionel Sambuc 
15414684ddb6SLionel Sambuc codecvt<wchar_t, char, mbstate_t>::result
do_out(state_type & st,const intern_type * frm,const intern_type * frm_end,const intern_type * & frm_nxt,extern_type * to,extern_type * to_end,extern_type * & to_nxt) const15424684ddb6SLionel Sambuc codecvt<wchar_t, char, mbstate_t>::do_out(state_type& st,
15434684ddb6SLionel Sambuc     const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
15444684ddb6SLionel Sambuc     extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
15454684ddb6SLionel Sambuc {
15464684ddb6SLionel Sambuc     // look for first internal null in frm
15474684ddb6SLionel Sambuc     const intern_type* fend = frm;
15484684ddb6SLionel Sambuc     for (; fend != frm_end; ++fend)
15494684ddb6SLionel Sambuc         if (*fend == 0)
15504684ddb6SLionel Sambuc             break;
15514684ddb6SLionel Sambuc     // loop over all null-terminated sequences in frm
15524684ddb6SLionel Sambuc     to_nxt = to;
15534684ddb6SLionel Sambuc     for (frm_nxt = frm; frm != frm_end && to != to_end; frm = frm_nxt, to = to_nxt)
15544684ddb6SLionel Sambuc     {
15554684ddb6SLionel Sambuc         // save state in case it is needed to recover to_nxt on error
15564684ddb6SLionel Sambuc         mbstate_t save_state = st;
15574684ddb6SLionel Sambuc #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
15584684ddb6SLionel Sambuc         size_t n = wcsnrtombs_l(to, &frm_nxt, static_cast<size_t>(fend-frm),
15594684ddb6SLionel Sambuc                                 static_cast<size_t>(to_end-to), &st, __l);
15604684ddb6SLionel Sambuc #else
15614684ddb6SLionel Sambuc         size_t n = __wcsnrtombs_l(to, &frm_nxt, fend-frm, to_end-to, &st, __l);
15624684ddb6SLionel Sambuc #endif
15634684ddb6SLionel Sambuc         if (n == size_t(-1))
15644684ddb6SLionel Sambuc         {
15654684ddb6SLionel Sambuc             // need to recover to_nxt
15664684ddb6SLionel Sambuc             for (to_nxt = to; frm != frm_nxt; ++frm)
15674684ddb6SLionel Sambuc             {
15684684ddb6SLionel Sambuc #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
15694684ddb6SLionel Sambuc                 n = wcrtomb_l(to_nxt, *frm, &save_state, __l);
15704684ddb6SLionel Sambuc #else
15714684ddb6SLionel Sambuc                 n = __wcrtomb_l(to_nxt, *frm, &save_state, __l);
15724684ddb6SLionel Sambuc #endif
15734684ddb6SLionel Sambuc                 if (n == size_t(-1))
15744684ddb6SLionel Sambuc                     break;
15754684ddb6SLionel Sambuc                 to_nxt += n;
15764684ddb6SLionel Sambuc             }
15774684ddb6SLionel Sambuc             frm_nxt = frm;
15784684ddb6SLionel Sambuc             return error;
15794684ddb6SLionel Sambuc         }
15804684ddb6SLionel Sambuc         if (n == 0)
15814684ddb6SLionel Sambuc             return partial;
15824684ddb6SLionel Sambuc         to_nxt += n;
15834684ddb6SLionel Sambuc         if (to_nxt == to_end)
15844684ddb6SLionel Sambuc             break;
15854684ddb6SLionel Sambuc         if (fend != frm_end)  // set up next null terminated sequence
15864684ddb6SLionel Sambuc         {
15874684ddb6SLionel Sambuc             // Try to write the terminating null
15884684ddb6SLionel Sambuc             extern_type tmp[MB_LEN_MAX];
15894684ddb6SLionel Sambuc #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
15904684ddb6SLionel Sambuc             n = wcrtomb_l(tmp, intern_type(), &st, __l);
15914684ddb6SLionel Sambuc #else
15924684ddb6SLionel Sambuc             n = __wcrtomb_l(tmp, intern_type(), &st, __l);
15934684ddb6SLionel Sambuc #endif
15944684ddb6SLionel Sambuc             if (n == size_t(-1))  // on error
15954684ddb6SLionel Sambuc                 return error;
15964684ddb6SLionel Sambuc             if (n > static_cast<size_t>(to_end-to_nxt))  // is there room?
15974684ddb6SLionel Sambuc                 return partial;
15984684ddb6SLionel Sambuc             for (extern_type* p = tmp; n; --n)  // write it
15994684ddb6SLionel Sambuc                 *to_nxt++ = *p++;
16004684ddb6SLionel Sambuc             ++frm_nxt;
16014684ddb6SLionel Sambuc             // look for next null in frm
16024684ddb6SLionel Sambuc             for (fend = frm_nxt; fend != frm_end; ++fend)
16034684ddb6SLionel Sambuc                 if (*fend == 0)
16044684ddb6SLionel Sambuc                     break;
16054684ddb6SLionel Sambuc         }
16064684ddb6SLionel Sambuc     }
16074684ddb6SLionel Sambuc     return frm_nxt == frm_end ? ok : partial;
16084684ddb6SLionel Sambuc }
16094684ddb6SLionel Sambuc 
16104684ddb6SLionel Sambuc codecvt<wchar_t, char, mbstate_t>::result
do_in(state_type & st,const extern_type * frm,const extern_type * frm_end,const extern_type * & frm_nxt,intern_type * to,intern_type * to_end,intern_type * & to_nxt) const16114684ddb6SLionel Sambuc codecvt<wchar_t, char, mbstate_t>::do_in(state_type& st,
16124684ddb6SLionel Sambuc     const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
16134684ddb6SLionel Sambuc     intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
16144684ddb6SLionel Sambuc {
16154684ddb6SLionel Sambuc     // look for first internal null in frm
16164684ddb6SLionel Sambuc     const extern_type* fend = frm;
16174684ddb6SLionel Sambuc     for (; fend != frm_end; ++fend)
16184684ddb6SLionel Sambuc         if (*fend == 0)
16194684ddb6SLionel Sambuc             break;
16204684ddb6SLionel Sambuc     // loop over all null-terminated sequences in frm
16214684ddb6SLionel Sambuc     to_nxt = to;
16224684ddb6SLionel Sambuc     for (frm_nxt = frm; frm != frm_end && to != to_end; frm = frm_nxt, to = to_nxt)
16234684ddb6SLionel Sambuc     {
16244684ddb6SLionel Sambuc         // save state in case it is needed to recover to_nxt on error
16254684ddb6SLionel Sambuc         mbstate_t save_state = st;
16264684ddb6SLionel Sambuc #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
16274684ddb6SLionel Sambuc         size_t n = mbsnrtowcs_l(to, &frm_nxt, static_cast<size_t>(fend-frm),
16284684ddb6SLionel Sambuc                                 static_cast<size_t>(to_end-to), &st, __l);
16294684ddb6SLionel Sambuc #else
16304684ddb6SLionel Sambuc         size_t n = __mbsnrtowcs_l(to, &frm_nxt, fend-frm, to_end-to, &st, __l);
16314684ddb6SLionel Sambuc #endif
16324684ddb6SLionel Sambuc         if (n == size_t(-1))
16334684ddb6SLionel Sambuc         {
16344684ddb6SLionel Sambuc             // need to recover to_nxt
16354684ddb6SLionel Sambuc             for (to_nxt = to; frm != frm_nxt; ++to_nxt)
16364684ddb6SLionel Sambuc             {
16374684ddb6SLionel Sambuc #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
16384684ddb6SLionel Sambuc                 n = mbrtowc_l(to_nxt, frm, static_cast<size_t>(fend-frm),
16394684ddb6SLionel Sambuc                               &save_state, __l);
16404684ddb6SLionel Sambuc #else
16414684ddb6SLionel Sambuc                 n = __mbrtowc_l(to_nxt, frm, fend-frm, &save_state, __l);
16424684ddb6SLionel Sambuc #endif
16434684ddb6SLionel Sambuc                 switch (n)
16444684ddb6SLionel Sambuc                 {
16454684ddb6SLionel Sambuc                 case 0:
16464684ddb6SLionel Sambuc                     ++frm;
16474684ddb6SLionel Sambuc                     break;
16484684ddb6SLionel Sambuc                 case size_t(-1):
16494684ddb6SLionel Sambuc                     frm_nxt = frm;
16504684ddb6SLionel Sambuc                     return error;
16514684ddb6SLionel Sambuc                 case size_t(-2):
16524684ddb6SLionel Sambuc                     frm_nxt = frm;
16534684ddb6SLionel Sambuc                     return partial;
16544684ddb6SLionel Sambuc                 default:
16554684ddb6SLionel Sambuc                     frm += n;
16564684ddb6SLionel Sambuc                     break;
16574684ddb6SLionel Sambuc                 }
16584684ddb6SLionel Sambuc             }
16594684ddb6SLionel Sambuc             frm_nxt = frm;
16604684ddb6SLionel Sambuc             return frm_nxt == frm_end ? ok : partial;
16614684ddb6SLionel Sambuc         }
1662*0a6a1f1dSLionel Sambuc         if (n == size_t(-1))
16634684ddb6SLionel Sambuc             return error;
16644684ddb6SLionel Sambuc         to_nxt += n;
16654684ddb6SLionel Sambuc         if (to_nxt == to_end)
16664684ddb6SLionel Sambuc             break;
16674684ddb6SLionel Sambuc         if (fend != frm_end)  // set up next null terminated sequence
16684684ddb6SLionel Sambuc         {
16694684ddb6SLionel Sambuc             // Try to write the terminating null
16704684ddb6SLionel Sambuc #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
16714684ddb6SLionel Sambuc             n = mbrtowc_l(to_nxt, frm_nxt, 1, &st, __l);
16724684ddb6SLionel Sambuc #else
16734684ddb6SLionel Sambuc             n = __mbrtowc_l(to_nxt, frm_nxt, 1, &st, __l);
16744684ddb6SLionel Sambuc #endif
16754684ddb6SLionel Sambuc             if (n != 0)  // on error
16764684ddb6SLionel Sambuc                 return error;
16774684ddb6SLionel Sambuc             ++to_nxt;
16784684ddb6SLionel Sambuc             ++frm_nxt;
16794684ddb6SLionel Sambuc             // look for next null in frm
16804684ddb6SLionel Sambuc             for (fend = frm_nxt; fend != frm_end; ++fend)
16814684ddb6SLionel Sambuc                 if (*fend == 0)
16824684ddb6SLionel Sambuc                     break;
16834684ddb6SLionel Sambuc         }
16844684ddb6SLionel Sambuc     }
16854684ddb6SLionel Sambuc     return frm_nxt == frm_end ? ok : partial;
16864684ddb6SLionel Sambuc }
16874684ddb6SLionel Sambuc 
16884684ddb6SLionel Sambuc codecvt<wchar_t, char, mbstate_t>::result
do_unshift(state_type & st,extern_type * to,extern_type * to_end,extern_type * & to_nxt) const16894684ddb6SLionel Sambuc codecvt<wchar_t, char, mbstate_t>::do_unshift(state_type& st,
16904684ddb6SLionel Sambuc     extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
16914684ddb6SLionel Sambuc {
16924684ddb6SLionel Sambuc     to_nxt = to;
16934684ddb6SLionel Sambuc     extern_type tmp[MB_LEN_MAX];
16944684ddb6SLionel Sambuc #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
16954684ddb6SLionel Sambuc     size_t n = wcrtomb_l(tmp, intern_type(), &st, __l);
16964684ddb6SLionel Sambuc #else
16974684ddb6SLionel Sambuc     size_t n = __wcrtomb_l(tmp, intern_type(), &st, __l);
16984684ddb6SLionel Sambuc #endif
16994684ddb6SLionel Sambuc     if (n == size_t(-1) || n == 0)  // on error
17004684ddb6SLionel Sambuc         return error;
17014684ddb6SLionel Sambuc     --n;
17024684ddb6SLionel Sambuc     if (n > static_cast<size_t>(to_end-to_nxt))  // is there room?
17034684ddb6SLionel Sambuc         return partial;
17044684ddb6SLionel Sambuc     for (extern_type* p = tmp; n; --n)  // write it
17054684ddb6SLionel Sambuc         *to_nxt++ = *p++;
17064684ddb6SLionel Sambuc     return ok;
17074684ddb6SLionel Sambuc }
17084684ddb6SLionel Sambuc 
17094684ddb6SLionel Sambuc int
do_encoding() const17104684ddb6SLionel Sambuc codecvt<wchar_t, char, mbstate_t>::do_encoding() const  _NOEXCEPT
17114684ddb6SLionel Sambuc {
1712*0a6a1f1dSLionel Sambuc #ifndef __CloudABI__
17134684ddb6SLionel Sambuc #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1714*0a6a1f1dSLionel Sambuc     if (mbtowc_l(nullptr, nullptr, MB_LEN_MAX, __l) != 0)
17154684ddb6SLionel Sambuc #else
1716*0a6a1f1dSLionel Sambuc     if (__mbtowc_l(nullptr, nullptr, MB_LEN_MAX, __l) != 0)
17174684ddb6SLionel Sambuc #endif
1718*0a6a1f1dSLionel Sambuc         return -1;
1719*0a6a1f1dSLionel Sambuc #endif
1720*0a6a1f1dSLionel Sambuc 
17214684ddb6SLionel Sambuc     // stateless encoding
17224684ddb6SLionel Sambuc #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
17234684ddb6SLionel Sambuc     if (__l == 0 || MB_CUR_MAX_L(__l) == 1)  // there are no known constant length encodings
17244684ddb6SLionel Sambuc #else
17254684ddb6SLionel Sambuc     if (__l == 0 || __mb_cur_max_l(__l) == 1)  // there are no known constant length encodings
17264684ddb6SLionel Sambuc #endif
17274684ddb6SLionel Sambuc         return 1;                // which take more than 1 char to form a wchar_t
17284684ddb6SLionel Sambuc     return 0;
17294684ddb6SLionel Sambuc }
17304684ddb6SLionel Sambuc 
17314684ddb6SLionel Sambuc bool
do_always_noconv() const17324684ddb6SLionel Sambuc codecvt<wchar_t, char, mbstate_t>::do_always_noconv() const  _NOEXCEPT
17334684ddb6SLionel Sambuc {
17344684ddb6SLionel Sambuc     return false;
17354684ddb6SLionel Sambuc }
17364684ddb6SLionel Sambuc 
17374684ddb6SLionel Sambuc int
do_length(state_type & st,const extern_type * frm,const extern_type * frm_end,size_t mx) const17384684ddb6SLionel Sambuc codecvt<wchar_t, char, mbstate_t>::do_length(state_type& st,
17394684ddb6SLionel Sambuc     const extern_type* frm, const extern_type* frm_end, size_t mx) const
17404684ddb6SLionel Sambuc {
17414684ddb6SLionel Sambuc     int nbytes = 0;
17424684ddb6SLionel Sambuc     for (size_t nwchar_t = 0; nwchar_t < mx && frm != frm_end; ++nwchar_t)
17434684ddb6SLionel Sambuc     {
17444684ddb6SLionel Sambuc #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
17454684ddb6SLionel Sambuc         size_t n = mbrlen_l(frm, static_cast<size_t>(frm_end-frm), &st, __l);
17464684ddb6SLionel Sambuc #else
17474684ddb6SLionel Sambuc         size_t n = __mbrlen_l(frm, frm_end-frm, &st, __l);
17484684ddb6SLionel Sambuc #endif
17494684ddb6SLionel Sambuc         switch (n)
17504684ddb6SLionel Sambuc         {
17514684ddb6SLionel Sambuc         case 0:
17524684ddb6SLionel Sambuc             ++nbytes;
17534684ddb6SLionel Sambuc             ++frm;
17544684ddb6SLionel Sambuc             break;
17554684ddb6SLionel Sambuc         case size_t(-1):
17564684ddb6SLionel Sambuc         case size_t(-2):
17574684ddb6SLionel Sambuc             return nbytes;
17584684ddb6SLionel Sambuc         default:
17594684ddb6SLionel Sambuc             nbytes += n;
17604684ddb6SLionel Sambuc             frm += n;
17614684ddb6SLionel Sambuc             break;
17624684ddb6SLionel Sambuc         }
17634684ddb6SLionel Sambuc     }
17644684ddb6SLionel Sambuc     return nbytes;
17654684ddb6SLionel Sambuc }
17664684ddb6SLionel Sambuc 
17674684ddb6SLionel Sambuc int
do_max_length() const17684684ddb6SLionel Sambuc codecvt<wchar_t, char, mbstate_t>::do_max_length() const  _NOEXCEPT
17694684ddb6SLionel Sambuc {
17704684ddb6SLionel Sambuc #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
17714684ddb6SLionel Sambuc     return __l == 0 ? 1 : static_cast<int>(  MB_CUR_MAX_L(__l));
17724684ddb6SLionel Sambuc #else
17734684ddb6SLionel Sambuc     return __l == 0 ? 1 : static_cast<int>(__mb_cur_max_l(__l));
17744684ddb6SLionel Sambuc #endif
17754684ddb6SLionel Sambuc }
17764684ddb6SLionel Sambuc 
17774684ddb6SLionel Sambuc //                                     Valid UTF ranges
17784684ddb6SLionel Sambuc //     UTF-32               UTF-16                          UTF-8               # of code points
17794684ddb6SLionel Sambuc //                     first      second       first   second    third   fourth
17804684ddb6SLionel Sambuc // 000000 - 00007F  0000 - 007F               00 - 7F                                 127
17814684ddb6SLionel Sambuc // 000080 - 0007FF  0080 - 07FF               C2 - DF, 80 - BF                       1920
17824684ddb6SLionel Sambuc // 000800 - 000FFF  0800 - 0FFF               E0 - E0, A0 - BF, 80 - BF              2048
17834684ddb6SLionel Sambuc // 001000 - 00CFFF  1000 - CFFF               E1 - EC, 80 - BF, 80 - BF             49152
17844684ddb6SLionel Sambuc // 00D000 - 00D7FF  D000 - D7FF               ED - ED, 80 - 9F, 80 - BF              2048
17854684ddb6SLionel Sambuc // 00D800 - 00DFFF                invalid
17864684ddb6SLionel Sambuc // 00E000 - 00FFFF  E000 - FFFF               EE - EF, 80 - BF, 80 - BF              8192
17874684ddb6SLionel Sambuc // 010000 - 03FFFF  D800 - D8BF, DC00 - DFFF  F0 - F0, 90 - BF, 80 - BF, 80 - BF   196608
17884684ddb6SLionel Sambuc // 040000 - 0FFFFF  D8C0 - DBBF, DC00 - DFFF  F1 - F3, 80 - BF, 80 - BF, 80 - BF   786432
17894684ddb6SLionel Sambuc // 100000 - 10FFFF  DBC0 - DBFF, DC00 - DFFF  F4 - F4, 80 - 8F, 80 - BF, 80 - BF    65536
17904684ddb6SLionel Sambuc 
17914684ddb6SLionel Sambuc static
17924684ddb6SLionel Sambuc codecvt_base::result
utf16_to_utf8(const uint16_t * frm,const uint16_t * frm_end,const uint16_t * & frm_nxt,uint8_t * to,uint8_t * to_end,uint8_t * & to_nxt,unsigned long Maxcode=0x10FFFF,codecvt_mode mode=codecvt_mode (0))17934684ddb6SLionel Sambuc utf16_to_utf8(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt,
17944684ddb6SLionel Sambuc               uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
17954684ddb6SLionel Sambuc               unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
17964684ddb6SLionel Sambuc {
17974684ddb6SLionel Sambuc     frm_nxt = frm;
17984684ddb6SLionel Sambuc     to_nxt = to;
17994684ddb6SLionel Sambuc     if (mode & generate_header)
18004684ddb6SLionel Sambuc     {
18014684ddb6SLionel Sambuc         if (to_end-to_nxt < 3)
18024684ddb6SLionel Sambuc             return codecvt_base::partial;
18034684ddb6SLionel Sambuc         *to_nxt++ = static_cast<uint8_t>(0xEF);
18044684ddb6SLionel Sambuc         *to_nxt++ = static_cast<uint8_t>(0xBB);
18054684ddb6SLionel Sambuc         *to_nxt++ = static_cast<uint8_t>(0xBF);
18064684ddb6SLionel Sambuc     }
18074684ddb6SLionel Sambuc     for (; frm_nxt < frm_end; ++frm_nxt)
18084684ddb6SLionel Sambuc     {
18094684ddb6SLionel Sambuc         uint16_t wc1 = *frm_nxt;
18104684ddb6SLionel Sambuc         if (wc1 > Maxcode)
18114684ddb6SLionel Sambuc             return codecvt_base::error;
18124684ddb6SLionel Sambuc         if (wc1 < 0x0080)
18134684ddb6SLionel Sambuc         {
18144684ddb6SLionel Sambuc             if (to_end-to_nxt < 1)
18154684ddb6SLionel Sambuc                 return codecvt_base::partial;
18164684ddb6SLionel Sambuc             *to_nxt++ = static_cast<uint8_t>(wc1);
18174684ddb6SLionel Sambuc         }
18184684ddb6SLionel Sambuc         else if (wc1 < 0x0800)
18194684ddb6SLionel Sambuc         {
18204684ddb6SLionel Sambuc             if (to_end-to_nxt < 2)
18214684ddb6SLionel Sambuc                 return codecvt_base::partial;
18224684ddb6SLionel Sambuc             *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc1 >> 6));
18234684ddb6SLionel Sambuc             *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x03F));
18244684ddb6SLionel Sambuc         }
18254684ddb6SLionel Sambuc         else if (wc1 < 0xD800)
18264684ddb6SLionel Sambuc         {
18274684ddb6SLionel Sambuc             if (to_end-to_nxt < 3)
18284684ddb6SLionel Sambuc                 return codecvt_base::partial;
18294684ddb6SLionel Sambuc             *to_nxt++ = static_cast<uint8_t>(0xE0 |  (wc1 >> 12));
18304684ddb6SLionel Sambuc             *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));
18314684ddb6SLionel Sambuc             *to_nxt++ = static_cast<uint8_t>(0x80 |  (wc1 & 0x003F));
18324684ddb6SLionel Sambuc         }
18334684ddb6SLionel Sambuc         else if (wc1 < 0xDC00)
18344684ddb6SLionel Sambuc         {
18354684ddb6SLionel Sambuc             if (frm_end-frm_nxt < 2)
18364684ddb6SLionel Sambuc                 return codecvt_base::partial;
18374684ddb6SLionel Sambuc             uint16_t wc2 = frm_nxt[1];
18384684ddb6SLionel Sambuc             if ((wc2 & 0xFC00) != 0xDC00)
18394684ddb6SLionel Sambuc                 return codecvt_base::error;
18404684ddb6SLionel Sambuc             if (to_end-to_nxt < 4)
18414684ddb6SLionel Sambuc                 return codecvt_base::partial;
1842*0a6a1f1dSLionel Sambuc             if (((((wc1 & 0x03C0UL) >> 6) + 1) << 16) +
1843*0a6a1f1dSLionel Sambuc                 ((wc1 & 0x003FUL) << 10) + (wc2 & 0x03FF) > Maxcode)
18444684ddb6SLionel Sambuc                 return codecvt_base::error;
18454684ddb6SLionel Sambuc             ++frm_nxt;
18464684ddb6SLionel Sambuc             uint8_t z = ((wc1 & 0x03C0) >> 6) + 1;
18474684ddb6SLionel Sambuc             *to_nxt++ = static_cast<uint8_t>(0xF0 | (z >> 2));
18484684ddb6SLionel Sambuc             *to_nxt++ = static_cast<uint8_t>(0x80 | ((z & 0x03) << 4)     | ((wc1 & 0x003C) >> 2));
18494684ddb6SLionel Sambuc             *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0003) << 4) | ((wc2 & 0x03C0) >> 6));
18504684ddb6SLionel Sambuc             *to_nxt++ = static_cast<uint8_t>(0x80 |  (wc2 & 0x003F));
18514684ddb6SLionel Sambuc         }
18524684ddb6SLionel Sambuc         else if (wc1 < 0xE000)
18534684ddb6SLionel Sambuc         {
18544684ddb6SLionel Sambuc             return codecvt_base::error;
18554684ddb6SLionel Sambuc         }
18564684ddb6SLionel Sambuc         else
18574684ddb6SLionel Sambuc         {
18584684ddb6SLionel Sambuc             if (to_end-to_nxt < 3)
18594684ddb6SLionel Sambuc                 return codecvt_base::partial;
18604684ddb6SLionel Sambuc             *to_nxt++ = static_cast<uint8_t>(0xE0 |  (wc1 >> 12));
18614684ddb6SLionel Sambuc             *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));
18624684ddb6SLionel Sambuc             *to_nxt++ = static_cast<uint8_t>(0x80 |  (wc1 & 0x003F));
18634684ddb6SLionel Sambuc         }
18644684ddb6SLionel Sambuc     }
18654684ddb6SLionel Sambuc     return codecvt_base::ok;
18664684ddb6SLionel Sambuc }
18674684ddb6SLionel Sambuc 
18684684ddb6SLionel Sambuc static
18694684ddb6SLionel Sambuc codecvt_base::result
utf16_to_utf8(const uint32_t * frm,const uint32_t * frm_end,const uint32_t * & frm_nxt,uint8_t * to,uint8_t * to_end,uint8_t * & to_nxt,unsigned long Maxcode=0x10FFFF,codecvt_mode mode=codecvt_mode (0))18704684ddb6SLionel Sambuc utf16_to_utf8(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt,
18714684ddb6SLionel Sambuc               uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
18724684ddb6SLionel Sambuc               unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
18734684ddb6SLionel Sambuc {
18744684ddb6SLionel Sambuc     frm_nxt = frm;
18754684ddb6SLionel Sambuc     to_nxt = to;
18764684ddb6SLionel Sambuc     if (mode & generate_header)
18774684ddb6SLionel Sambuc     {
18784684ddb6SLionel Sambuc         if (to_end-to_nxt < 3)
18794684ddb6SLionel Sambuc             return codecvt_base::partial;
18804684ddb6SLionel Sambuc         *to_nxt++ = static_cast<uint8_t>(0xEF);
18814684ddb6SLionel Sambuc         *to_nxt++ = static_cast<uint8_t>(0xBB);
18824684ddb6SLionel Sambuc         *to_nxt++ = static_cast<uint8_t>(0xBF);
18834684ddb6SLionel Sambuc     }
18844684ddb6SLionel Sambuc     for (; frm_nxt < frm_end; ++frm_nxt)
18854684ddb6SLionel Sambuc     {
18864684ddb6SLionel Sambuc         uint16_t wc1 = static_cast<uint16_t>(*frm_nxt);
18874684ddb6SLionel Sambuc         if (wc1 > Maxcode)
18884684ddb6SLionel Sambuc             return codecvt_base::error;
18894684ddb6SLionel Sambuc         if (wc1 < 0x0080)
18904684ddb6SLionel Sambuc         {
18914684ddb6SLionel Sambuc             if (to_end-to_nxt < 1)
18924684ddb6SLionel Sambuc                 return codecvt_base::partial;
18934684ddb6SLionel Sambuc             *to_nxt++ = static_cast<uint8_t>(wc1);
18944684ddb6SLionel Sambuc         }
18954684ddb6SLionel Sambuc         else if (wc1 < 0x0800)
18964684ddb6SLionel Sambuc         {
18974684ddb6SLionel Sambuc             if (to_end-to_nxt < 2)
18984684ddb6SLionel Sambuc                 return codecvt_base::partial;
18994684ddb6SLionel Sambuc             *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc1 >> 6));
19004684ddb6SLionel Sambuc             *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x03F));
19014684ddb6SLionel Sambuc         }
19024684ddb6SLionel Sambuc         else if (wc1 < 0xD800)
19034684ddb6SLionel Sambuc         {
19044684ddb6SLionel Sambuc             if (to_end-to_nxt < 3)
19054684ddb6SLionel Sambuc                 return codecvt_base::partial;
19064684ddb6SLionel Sambuc             *to_nxt++ = static_cast<uint8_t>(0xE0 |  (wc1 >> 12));
19074684ddb6SLionel Sambuc             *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));
19084684ddb6SLionel Sambuc             *to_nxt++ = static_cast<uint8_t>(0x80 |  (wc1 & 0x003F));
19094684ddb6SLionel Sambuc         }
19104684ddb6SLionel Sambuc         else if (wc1 < 0xDC00)
19114684ddb6SLionel Sambuc         {
19124684ddb6SLionel Sambuc             if (frm_end-frm_nxt < 2)
19134684ddb6SLionel Sambuc                 return codecvt_base::partial;
19144684ddb6SLionel Sambuc             uint16_t wc2 = static_cast<uint16_t>(frm_nxt[1]);
19154684ddb6SLionel Sambuc             if ((wc2 & 0xFC00) != 0xDC00)
19164684ddb6SLionel Sambuc                 return codecvt_base::error;
19174684ddb6SLionel Sambuc             if (to_end-to_nxt < 4)
19184684ddb6SLionel Sambuc                 return codecvt_base::partial;
1919*0a6a1f1dSLionel Sambuc             if (((((wc1 & 0x03C0UL) >> 6) + 1) << 16) +
1920*0a6a1f1dSLionel Sambuc                 ((wc1 & 0x003FUL) << 10) + (wc2 & 0x03FF) > Maxcode)
19214684ddb6SLionel Sambuc                 return codecvt_base::error;
19224684ddb6SLionel Sambuc             ++frm_nxt;
19234684ddb6SLionel Sambuc             uint8_t z = ((wc1 & 0x03C0) >> 6) + 1;
19244684ddb6SLionel Sambuc             *to_nxt++ = static_cast<uint8_t>(0xF0 | (z >> 2));
19254684ddb6SLionel Sambuc             *to_nxt++ = static_cast<uint8_t>(0x80 | ((z & 0x03) << 4)     | ((wc1 & 0x003C) >> 2));
19264684ddb6SLionel Sambuc             *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0003) << 4) | ((wc2 & 0x03C0) >> 6));
19274684ddb6SLionel Sambuc             *to_nxt++ = static_cast<uint8_t>(0x80 |  (wc2 & 0x003F));
19284684ddb6SLionel Sambuc         }
19294684ddb6SLionel Sambuc         else if (wc1 < 0xE000)
19304684ddb6SLionel Sambuc         {
19314684ddb6SLionel Sambuc             return codecvt_base::error;
19324684ddb6SLionel Sambuc         }
19334684ddb6SLionel Sambuc         else
19344684ddb6SLionel Sambuc         {
19354684ddb6SLionel Sambuc             if (to_end-to_nxt < 3)
19364684ddb6SLionel Sambuc                 return codecvt_base::partial;
19374684ddb6SLionel Sambuc             *to_nxt++ = static_cast<uint8_t>(0xE0 |  (wc1 >> 12));
19384684ddb6SLionel Sambuc             *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));
19394684ddb6SLionel Sambuc             *to_nxt++ = static_cast<uint8_t>(0x80 |  (wc1 & 0x003F));
19404684ddb6SLionel Sambuc         }
19414684ddb6SLionel Sambuc     }
19424684ddb6SLionel Sambuc     return codecvt_base::ok;
19434684ddb6SLionel Sambuc }
19444684ddb6SLionel Sambuc 
19454684ddb6SLionel Sambuc static
19464684ddb6SLionel Sambuc codecvt_base::result
utf8_to_utf16(const uint8_t * frm,const uint8_t * frm_end,const uint8_t * & frm_nxt,uint16_t * to,uint16_t * to_end,uint16_t * & to_nxt,unsigned long Maxcode=0x10FFFF,codecvt_mode mode=codecvt_mode (0))19474684ddb6SLionel Sambuc utf8_to_utf16(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
19484684ddb6SLionel Sambuc               uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt,
19494684ddb6SLionel Sambuc               unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
19504684ddb6SLionel Sambuc {
19514684ddb6SLionel Sambuc     frm_nxt = frm;
19524684ddb6SLionel Sambuc     to_nxt = to;
19534684ddb6SLionel Sambuc     if (mode & consume_header)
19544684ddb6SLionel Sambuc     {
19554684ddb6SLionel Sambuc         if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
19564684ddb6SLionel Sambuc                                                           frm_nxt[2] == 0xBF)
19574684ddb6SLionel Sambuc             frm_nxt += 3;
19584684ddb6SLionel Sambuc     }
19594684ddb6SLionel Sambuc     for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt)
19604684ddb6SLionel Sambuc     {
19614684ddb6SLionel Sambuc         uint8_t c1 = *frm_nxt;
19624684ddb6SLionel Sambuc         if (c1 > Maxcode)
19634684ddb6SLionel Sambuc             return codecvt_base::error;
19644684ddb6SLionel Sambuc         if (c1 < 0x80)
19654684ddb6SLionel Sambuc         {
19664684ddb6SLionel Sambuc             *to_nxt = static_cast<uint16_t>(c1);
19674684ddb6SLionel Sambuc             ++frm_nxt;
19684684ddb6SLionel Sambuc         }
19694684ddb6SLionel Sambuc         else if (c1 < 0xC2)
19704684ddb6SLionel Sambuc         {
19714684ddb6SLionel Sambuc             return codecvt_base::error;
19724684ddb6SLionel Sambuc         }
19734684ddb6SLionel Sambuc         else if (c1 < 0xE0)
19744684ddb6SLionel Sambuc         {
19754684ddb6SLionel Sambuc             if (frm_end-frm_nxt < 2)
19764684ddb6SLionel Sambuc                 return codecvt_base::partial;
19774684ddb6SLionel Sambuc             uint8_t c2 = frm_nxt[1];
19784684ddb6SLionel Sambuc             if ((c2 & 0xC0) != 0x80)
19794684ddb6SLionel Sambuc                 return codecvt_base::error;
19804684ddb6SLionel Sambuc             uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) | (c2 & 0x3F));
19814684ddb6SLionel Sambuc             if (t > Maxcode)
19824684ddb6SLionel Sambuc                 return codecvt_base::error;
19834684ddb6SLionel Sambuc             *to_nxt = t;
19844684ddb6SLionel Sambuc             frm_nxt += 2;
19854684ddb6SLionel Sambuc         }
19864684ddb6SLionel Sambuc         else if (c1 < 0xF0)
19874684ddb6SLionel Sambuc         {
19884684ddb6SLionel Sambuc             if (frm_end-frm_nxt < 3)
19894684ddb6SLionel Sambuc                 return codecvt_base::partial;
19904684ddb6SLionel Sambuc             uint8_t c2 = frm_nxt[1];
19914684ddb6SLionel Sambuc             uint8_t c3 = frm_nxt[2];
19924684ddb6SLionel Sambuc             switch (c1)
19934684ddb6SLionel Sambuc             {
19944684ddb6SLionel Sambuc             case 0xE0:
19954684ddb6SLionel Sambuc                 if ((c2 & 0xE0) != 0xA0)
19964684ddb6SLionel Sambuc                     return codecvt_base::error;
19974684ddb6SLionel Sambuc                  break;
19984684ddb6SLionel Sambuc             case 0xED:
19994684ddb6SLionel Sambuc                 if ((c2 & 0xE0) != 0x80)
20004684ddb6SLionel Sambuc                     return codecvt_base::error;
20014684ddb6SLionel Sambuc                  break;
20024684ddb6SLionel Sambuc             default:
20034684ddb6SLionel Sambuc                 if ((c2 & 0xC0) != 0x80)
20044684ddb6SLionel Sambuc                     return codecvt_base::error;
20054684ddb6SLionel Sambuc                  break;
20064684ddb6SLionel Sambuc             }
20074684ddb6SLionel Sambuc             if ((c3 & 0xC0) != 0x80)
20084684ddb6SLionel Sambuc                 return codecvt_base::error;
20094684ddb6SLionel Sambuc             uint16_t t = static_cast<uint16_t>(((c1 & 0x0F) << 12)
20104684ddb6SLionel Sambuc                                              | ((c2 & 0x3F) << 6)
20114684ddb6SLionel Sambuc                                              |  (c3 & 0x3F));
20124684ddb6SLionel Sambuc             if (t > Maxcode)
20134684ddb6SLionel Sambuc                 return codecvt_base::error;
20144684ddb6SLionel Sambuc             *to_nxt = t;
20154684ddb6SLionel Sambuc             frm_nxt += 3;
20164684ddb6SLionel Sambuc         }
20174684ddb6SLionel Sambuc         else if (c1 < 0xF5)
20184684ddb6SLionel Sambuc         {
20194684ddb6SLionel Sambuc             if (frm_end-frm_nxt < 4)
20204684ddb6SLionel Sambuc                 return codecvt_base::partial;
20214684ddb6SLionel Sambuc             uint8_t c2 = frm_nxt[1];
20224684ddb6SLionel Sambuc             uint8_t c3 = frm_nxt[2];
20234684ddb6SLionel Sambuc             uint8_t c4 = frm_nxt[3];
20244684ddb6SLionel Sambuc             switch (c1)
20254684ddb6SLionel Sambuc             {
20264684ddb6SLionel Sambuc             case 0xF0:
20274684ddb6SLionel Sambuc                 if (!(0x90 <= c2 && c2 <= 0xBF))
20284684ddb6SLionel Sambuc                     return codecvt_base::error;
20294684ddb6SLionel Sambuc                  break;
20304684ddb6SLionel Sambuc             case 0xF4:
20314684ddb6SLionel Sambuc                 if ((c2 & 0xF0) != 0x80)
20324684ddb6SLionel Sambuc                     return codecvt_base::error;
20334684ddb6SLionel Sambuc                  break;
20344684ddb6SLionel Sambuc             default:
20354684ddb6SLionel Sambuc                 if ((c2 & 0xC0) != 0x80)
20364684ddb6SLionel Sambuc                     return codecvt_base::error;
20374684ddb6SLionel Sambuc                  break;
20384684ddb6SLionel Sambuc             }
20394684ddb6SLionel Sambuc             if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
20404684ddb6SLionel Sambuc                 return codecvt_base::error;
20414684ddb6SLionel Sambuc             if (to_end-to_nxt < 2)
20424684ddb6SLionel Sambuc                 return codecvt_base::partial;
2043*0a6a1f1dSLionel Sambuc             if ((((c1 & 7UL) << 18) +
2044*0a6a1f1dSLionel Sambuc                 ((c2 & 0x3FUL) << 12) +
2045*0a6a1f1dSLionel Sambuc                 ((c3 & 0x3FUL) << 6) + (c4 & 0x3F)) > Maxcode)
20464684ddb6SLionel Sambuc                 return codecvt_base::error;
20474684ddb6SLionel Sambuc             *to_nxt = static_cast<uint16_t>(
20484684ddb6SLionel Sambuc                     0xD800
20494684ddb6SLionel Sambuc                   | (((((c1 & 0x07) << 2) | ((c2 & 0x30) >> 4)) - 1) << 6)
20504684ddb6SLionel Sambuc                   | ((c2 & 0x0F) << 2)
20514684ddb6SLionel Sambuc                   | ((c3 & 0x30) >> 4));
20524684ddb6SLionel Sambuc             *++to_nxt = static_cast<uint16_t>(
20534684ddb6SLionel Sambuc                     0xDC00
20544684ddb6SLionel Sambuc                   | ((c3 & 0x0F) << 6)
20554684ddb6SLionel Sambuc                   |  (c4 & 0x3F));
20564684ddb6SLionel Sambuc             frm_nxt += 4;
20574684ddb6SLionel Sambuc         }
20584684ddb6SLionel Sambuc         else
20594684ddb6SLionel Sambuc         {
20604684ddb6SLionel Sambuc             return codecvt_base::error;
20614684ddb6SLionel Sambuc         }
20624684ddb6SLionel Sambuc     }
20634684ddb6SLionel Sambuc     return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
20644684ddb6SLionel Sambuc }
20654684ddb6SLionel Sambuc 
20664684ddb6SLionel Sambuc static
20674684ddb6SLionel Sambuc codecvt_base::result
utf8_to_utf16(const uint8_t * frm,const uint8_t * frm_end,const uint8_t * & frm_nxt,uint32_t * to,uint32_t * to_end,uint32_t * & to_nxt,unsigned long Maxcode=0x10FFFF,codecvt_mode mode=codecvt_mode (0))20684684ddb6SLionel Sambuc utf8_to_utf16(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
20694684ddb6SLionel Sambuc               uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt,
20704684ddb6SLionel Sambuc               unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
20714684ddb6SLionel Sambuc {
20724684ddb6SLionel Sambuc     frm_nxt = frm;
20734684ddb6SLionel Sambuc     to_nxt = to;
20744684ddb6SLionel Sambuc     if (mode & consume_header)
20754684ddb6SLionel Sambuc     {
20764684ddb6SLionel Sambuc         if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
20774684ddb6SLionel Sambuc                                                           frm_nxt[2] == 0xBF)
20784684ddb6SLionel Sambuc             frm_nxt += 3;
20794684ddb6SLionel Sambuc     }
20804684ddb6SLionel Sambuc     for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt)
20814684ddb6SLionel Sambuc     {
20824684ddb6SLionel Sambuc         uint8_t c1 = *frm_nxt;
20834684ddb6SLionel Sambuc         if (c1 > Maxcode)
20844684ddb6SLionel Sambuc             return codecvt_base::error;
20854684ddb6SLionel Sambuc         if (c1 < 0x80)
20864684ddb6SLionel Sambuc         {
20874684ddb6SLionel Sambuc             *to_nxt = static_cast<uint32_t>(c1);
20884684ddb6SLionel Sambuc             ++frm_nxt;
20894684ddb6SLionel Sambuc         }
20904684ddb6SLionel Sambuc         else if (c1 < 0xC2)
20914684ddb6SLionel Sambuc         {
20924684ddb6SLionel Sambuc             return codecvt_base::error;
20934684ddb6SLionel Sambuc         }
20944684ddb6SLionel Sambuc         else if (c1 < 0xE0)
20954684ddb6SLionel Sambuc         {
20964684ddb6SLionel Sambuc             if (frm_end-frm_nxt < 2)
20974684ddb6SLionel Sambuc                 return codecvt_base::partial;
20984684ddb6SLionel Sambuc             uint8_t c2 = frm_nxt[1];
20994684ddb6SLionel Sambuc             if ((c2 & 0xC0) != 0x80)
21004684ddb6SLionel Sambuc                 return codecvt_base::error;
21014684ddb6SLionel Sambuc             uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) | (c2 & 0x3F));
21024684ddb6SLionel Sambuc             if (t > Maxcode)
21034684ddb6SLionel Sambuc                 return codecvt_base::error;
21044684ddb6SLionel Sambuc             *to_nxt = static_cast<uint32_t>(t);
21054684ddb6SLionel Sambuc             frm_nxt += 2;
21064684ddb6SLionel Sambuc         }
21074684ddb6SLionel Sambuc         else if (c1 < 0xF0)
21084684ddb6SLionel Sambuc         {
21094684ddb6SLionel Sambuc             if (frm_end-frm_nxt < 3)
21104684ddb6SLionel Sambuc                 return codecvt_base::partial;
21114684ddb6SLionel Sambuc             uint8_t c2 = frm_nxt[1];
21124684ddb6SLionel Sambuc             uint8_t c3 = frm_nxt[2];
21134684ddb6SLionel Sambuc             switch (c1)
21144684ddb6SLionel Sambuc             {
21154684ddb6SLionel Sambuc             case 0xE0:
21164684ddb6SLionel Sambuc                 if ((c2 & 0xE0) != 0xA0)
21174684ddb6SLionel Sambuc                     return codecvt_base::error;
21184684ddb6SLionel Sambuc                  break;
21194684ddb6SLionel Sambuc             case 0xED:
21204684ddb6SLionel Sambuc                 if ((c2 & 0xE0) != 0x80)
21214684ddb6SLionel Sambuc                     return codecvt_base::error;
21224684ddb6SLionel Sambuc                  break;
21234684ddb6SLionel Sambuc             default:
21244684ddb6SLionel Sambuc                 if ((c2 & 0xC0) != 0x80)
21254684ddb6SLionel Sambuc                     return codecvt_base::error;
21264684ddb6SLionel Sambuc                  break;
21274684ddb6SLionel Sambuc             }
21284684ddb6SLionel Sambuc             if ((c3 & 0xC0) != 0x80)
21294684ddb6SLionel Sambuc                 return codecvt_base::error;
21304684ddb6SLionel Sambuc             uint16_t t = static_cast<uint16_t>(((c1 & 0x0F) << 12)
21314684ddb6SLionel Sambuc                                              | ((c2 & 0x3F) << 6)
21324684ddb6SLionel Sambuc                                              |  (c3 & 0x3F));
21334684ddb6SLionel Sambuc             if (t > Maxcode)
21344684ddb6SLionel Sambuc                 return codecvt_base::error;
21354684ddb6SLionel Sambuc             *to_nxt = static_cast<uint32_t>(t);
21364684ddb6SLionel Sambuc             frm_nxt += 3;
21374684ddb6SLionel Sambuc         }
21384684ddb6SLionel Sambuc         else if (c1 < 0xF5)
21394684ddb6SLionel Sambuc         {
21404684ddb6SLionel Sambuc             if (frm_end-frm_nxt < 4)
21414684ddb6SLionel Sambuc                 return codecvt_base::partial;
21424684ddb6SLionel Sambuc             uint8_t c2 = frm_nxt[1];
21434684ddb6SLionel Sambuc             uint8_t c3 = frm_nxt[2];
21444684ddb6SLionel Sambuc             uint8_t c4 = frm_nxt[3];
21454684ddb6SLionel Sambuc             switch (c1)
21464684ddb6SLionel Sambuc             {
21474684ddb6SLionel Sambuc             case 0xF0:
21484684ddb6SLionel Sambuc                 if (!(0x90 <= c2 && c2 <= 0xBF))
21494684ddb6SLionel Sambuc                     return codecvt_base::error;
21504684ddb6SLionel Sambuc                  break;
21514684ddb6SLionel Sambuc             case 0xF4:
21524684ddb6SLionel Sambuc                 if ((c2 & 0xF0) != 0x80)
21534684ddb6SLionel Sambuc                     return codecvt_base::error;
21544684ddb6SLionel Sambuc                  break;
21554684ddb6SLionel Sambuc             default:
21564684ddb6SLionel Sambuc                 if ((c2 & 0xC0) != 0x80)
21574684ddb6SLionel Sambuc                     return codecvt_base::error;
21584684ddb6SLionel Sambuc                  break;
21594684ddb6SLionel Sambuc             }
21604684ddb6SLionel Sambuc             if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
21614684ddb6SLionel Sambuc                 return codecvt_base::error;
21624684ddb6SLionel Sambuc             if (to_end-to_nxt < 2)
21634684ddb6SLionel Sambuc                 return codecvt_base::partial;
2164*0a6a1f1dSLionel Sambuc             if ((((c1 & 7UL) << 18) +
2165*0a6a1f1dSLionel Sambuc                 ((c2 & 0x3FUL) << 12) +
2166*0a6a1f1dSLionel Sambuc                 ((c3 & 0x3FUL) << 6) + (c4 & 0x3F)) > Maxcode)
21674684ddb6SLionel Sambuc                 return codecvt_base::error;
21684684ddb6SLionel Sambuc             *to_nxt = static_cast<uint32_t>(
21694684ddb6SLionel Sambuc                     0xD800
21704684ddb6SLionel Sambuc                   | (((((c1 & 0x07) << 2) | ((c2 & 0x30) >> 4)) - 1) << 6)
21714684ddb6SLionel Sambuc                   | ((c2 & 0x0F) << 2)
21724684ddb6SLionel Sambuc                   | ((c3 & 0x30) >> 4));
21734684ddb6SLionel Sambuc             *++to_nxt = static_cast<uint32_t>(
21744684ddb6SLionel Sambuc                     0xDC00
21754684ddb6SLionel Sambuc                   | ((c3 & 0x0F) << 6)
21764684ddb6SLionel Sambuc                   |  (c4 & 0x3F));
21774684ddb6SLionel Sambuc             frm_nxt += 4;
21784684ddb6SLionel Sambuc         }
21794684ddb6SLionel Sambuc         else
21804684ddb6SLionel Sambuc         {
21814684ddb6SLionel Sambuc             return codecvt_base::error;
21824684ddb6SLionel Sambuc         }
21834684ddb6SLionel Sambuc     }
21844684ddb6SLionel Sambuc     return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
21854684ddb6SLionel Sambuc }
21864684ddb6SLionel Sambuc 
21874684ddb6SLionel Sambuc static
21884684ddb6SLionel Sambuc int
utf8_to_utf16_length(const uint8_t * frm,const uint8_t * frm_end,size_t mx,unsigned long Maxcode=0x10FFFF,codecvt_mode mode=codecvt_mode (0))21894684ddb6SLionel Sambuc utf8_to_utf16_length(const uint8_t* frm, const uint8_t* frm_end,
21904684ddb6SLionel Sambuc                      size_t mx, unsigned long Maxcode = 0x10FFFF,
21914684ddb6SLionel Sambuc                      codecvt_mode mode = codecvt_mode(0))
21924684ddb6SLionel Sambuc {
21934684ddb6SLionel Sambuc     const uint8_t* frm_nxt = frm;
21944684ddb6SLionel Sambuc     if (mode & consume_header)
21954684ddb6SLionel Sambuc     {
21964684ddb6SLionel Sambuc         if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
21974684ddb6SLionel Sambuc                                                           frm_nxt[2] == 0xBF)
21984684ddb6SLionel Sambuc             frm_nxt += 3;
21994684ddb6SLionel Sambuc     }
22004684ddb6SLionel Sambuc     for (size_t nchar16_t = 0; frm_nxt < frm_end && nchar16_t < mx; ++nchar16_t)
22014684ddb6SLionel Sambuc     {
22024684ddb6SLionel Sambuc         uint8_t c1 = *frm_nxt;
22034684ddb6SLionel Sambuc         if (c1 > Maxcode)
22044684ddb6SLionel Sambuc             break;
22054684ddb6SLionel Sambuc         if (c1 < 0x80)
22064684ddb6SLionel Sambuc         {
22074684ddb6SLionel Sambuc             ++frm_nxt;
22084684ddb6SLionel Sambuc         }
22094684ddb6SLionel Sambuc         else if (c1 < 0xC2)
22104684ddb6SLionel Sambuc         {
22114684ddb6SLionel Sambuc             break;
22124684ddb6SLionel Sambuc         }
22134684ddb6SLionel Sambuc         else if (c1 < 0xE0)
22144684ddb6SLionel Sambuc         {
22154684ddb6SLionel Sambuc             if ((frm_end-frm_nxt < 2) || (frm_nxt[1] & 0xC0) != 0x80)
22164684ddb6SLionel Sambuc                 break;
22174684ddb6SLionel Sambuc             uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) | (frm_nxt[1] & 0x3F));
22184684ddb6SLionel Sambuc             if (t > Maxcode)
22194684ddb6SLionel Sambuc                 break;
22204684ddb6SLionel Sambuc             frm_nxt += 2;
22214684ddb6SLionel Sambuc         }
22224684ddb6SLionel Sambuc         else if (c1 < 0xF0)
22234684ddb6SLionel Sambuc         {
22244684ddb6SLionel Sambuc             if (frm_end-frm_nxt < 3)
22254684ddb6SLionel Sambuc                 break;
22264684ddb6SLionel Sambuc             uint8_t c2 = frm_nxt[1];
22274684ddb6SLionel Sambuc             uint8_t c3 = frm_nxt[2];
22284684ddb6SLionel Sambuc             switch (c1)
22294684ddb6SLionel Sambuc             {
22304684ddb6SLionel Sambuc             case 0xE0:
22314684ddb6SLionel Sambuc                 if ((c2 & 0xE0) != 0xA0)
22324684ddb6SLionel Sambuc                     return static_cast<int>(frm_nxt - frm);
22334684ddb6SLionel Sambuc                 break;
22344684ddb6SLionel Sambuc             case 0xED:
22354684ddb6SLionel Sambuc                 if ((c2 & 0xE0) != 0x80)
22364684ddb6SLionel Sambuc                     return static_cast<int>(frm_nxt - frm);
22374684ddb6SLionel Sambuc                  break;
22384684ddb6SLionel Sambuc             default:
22394684ddb6SLionel Sambuc                 if ((c2 & 0xC0) != 0x80)
22404684ddb6SLionel Sambuc                     return static_cast<int>(frm_nxt - frm);
22414684ddb6SLionel Sambuc                  break;
22424684ddb6SLionel Sambuc             }
22434684ddb6SLionel Sambuc             if ((c3 & 0xC0) != 0x80)
22444684ddb6SLionel Sambuc                 break;
22454684ddb6SLionel Sambuc             if ((((c1 & 0x0Fu) << 12) | ((c2 & 0x3Fu) << 6) | (c3 & 0x3Fu)) > Maxcode)
22464684ddb6SLionel Sambuc                 break;
22474684ddb6SLionel Sambuc             frm_nxt += 3;
22484684ddb6SLionel Sambuc         }
22494684ddb6SLionel Sambuc         else if (c1 < 0xF5)
22504684ddb6SLionel Sambuc         {
22514684ddb6SLionel Sambuc             if (frm_end-frm_nxt < 4 || mx-nchar16_t < 2)
22524684ddb6SLionel Sambuc                 break;
22534684ddb6SLionel Sambuc             uint8_t c2 = frm_nxt[1];
22544684ddb6SLionel Sambuc             uint8_t c3 = frm_nxt[2];
22554684ddb6SLionel Sambuc             uint8_t c4 = frm_nxt[3];
22564684ddb6SLionel Sambuc             switch (c1)
22574684ddb6SLionel Sambuc             {
22584684ddb6SLionel Sambuc             case 0xF0:
22594684ddb6SLionel Sambuc                 if (!(0x90 <= c2 && c2 <= 0xBF))
22604684ddb6SLionel Sambuc                     return static_cast<int>(frm_nxt - frm);
22614684ddb6SLionel Sambuc                  break;
22624684ddb6SLionel Sambuc             case 0xF4:
22634684ddb6SLionel Sambuc                 if ((c2 & 0xF0) != 0x80)
22644684ddb6SLionel Sambuc                     return static_cast<int>(frm_nxt - frm);
22654684ddb6SLionel Sambuc                  break;
22664684ddb6SLionel Sambuc             default:
22674684ddb6SLionel Sambuc                 if ((c2 & 0xC0) != 0x80)
22684684ddb6SLionel Sambuc                     return static_cast<int>(frm_nxt - frm);
22694684ddb6SLionel Sambuc                  break;
22704684ddb6SLionel Sambuc             }
22714684ddb6SLionel Sambuc             if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
22724684ddb6SLionel Sambuc                 break;
2273*0a6a1f1dSLionel Sambuc             if ((((c1 & 7UL) << 18) +
2274*0a6a1f1dSLionel Sambuc                 ((c2 & 0x3FUL) << 12) +
2275*0a6a1f1dSLionel Sambuc                 ((c3 & 0x3FUL) << 6) + (c4 & 0x3F)) > Maxcode)
22764684ddb6SLionel Sambuc                 break;
22774684ddb6SLionel Sambuc             ++nchar16_t;
22784684ddb6SLionel Sambuc             frm_nxt += 4;
22794684ddb6SLionel Sambuc         }
22804684ddb6SLionel Sambuc         else
22814684ddb6SLionel Sambuc         {
22824684ddb6SLionel Sambuc             break;
22834684ddb6SLionel Sambuc         }
22844684ddb6SLionel Sambuc     }
22854684ddb6SLionel Sambuc     return static_cast<int>(frm_nxt - frm);
22864684ddb6SLionel Sambuc }
22874684ddb6SLionel Sambuc 
22884684ddb6SLionel Sambuc static
22894684ddb6SLionel Sambuc codecvt_base::result
ucs4_to_utf8(const uint32_t * frm,const uint32_t * frm_end,const uint32_t * & frm_nxt,uint8_t * to,uint8_t * to_end,uint8_t * & to_nxt,unsigned long Maxcode=0x10FFFF,codecvt_mode mode=codecvt_mode (0))22904684ddb6SLionel Sambuc ucs4_to_utf8(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt,
22914684ddb6SLionel Sambuc              uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
22924684ddb6SLionel Sambuc              unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
22934684ddb6SLionel Sambuc {
22944684ddb6SLionel Sambuc     frm_nxt = frm;
22954684ddb6SLionel Sambuc     to_nxt = to;
22964684ddb6SLionel Sambuc     if (mode & generate_header)
22974684ddb6SLionel Sambuc     {
22984684ddb6SLionel Sambuc         if (to_end-to_nxt < 3)
22994684ddb6SLionel Sambuc             return codecvt_base::partial;
23004684ddb6SLionel Sambuc         *to_nxt++ = static_cast<uint8_t>(0xEF);
23014684ddb6SLionel Sambuc         *to_nxt++ = static_cast<uint8_t>(0xBB);
23024684ddb6SLionel Sambuc         *to_nxt++ = static_cast<uint8_t>(0xBF);
23034684ddb6SLionel Sambuc     }
23044684ddb6SLionel Sambuc     for (; frm_nxt < frm_end; ++frm_nxt)
23054684ddb6SLionel Sambuc     {
23064684ddb6SLionel Sambuc         uint32_t wc = *frm_nxt;
23074684ddb6SLionel Sambuc         if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode)
23084684ddb6SLionel Sambuc             return codecvt_base::error;
23094684ddb6SLionel Sambuc         if (wc < 0x000080)
23104684ddb6SLionel Sambuc         {
23114684ddb6SLionel Sambuc             if (to_end-to_nxt < 1)
23124684ddb6SLionel Sambuc                 return codecvt_base::partial;
23134684ddb6SLionel Sambuc             *to_nxt++ = static_cast<uint8_t>(wc);
23144684ddb6SLionel Sambuc         }
23154684ddb6SLionel Sambuc         else if (wc < 0x000800)
23164684ddb6SLionel Sambuc         {
23174684ddb6SLionel Sambuc             if (to_end-to_nxt < 2)
23184684ddb6SLionel Sambuc                 return codecvt_base::partial;
23194684ddb6SLionel Sambuc             *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc >> 6));
23204684ddb6SLionel Sambuc             *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x03F));
23214684ddb6SLionel Sambuc         }
23224684ddb6SLionel Sambuc         else if (wc < 0x010000)
23234684ddb6SLionel Sambuc         {
23244684ddb6SLionel Sambuc             if (to_end-to_nxt < 3)
23254684ddb6SLionel Sambuc                 return codecvt_base::partial;
23264684ddb6SLionel Sambuc             *to_nxt++ = static_cast<uint8_t>(0xE0 |  (wc >> 12));
23274684ddb6SLionel Sambuc             *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x0FC0) >> 6));
23284684ddb6SLionel Sambuc             *to_nxt++ = static_cast<uint8_t>(0x80 |  (wc & 0x003F));
23294684ddb6SLionel Sambuc         }
23304684ddb6SLionel Sambuc         else // if (wc < 0x110000)
23314684ddb6SLionel Sambuc         {
23324684ddb6SLionel Sambuc             if (to_end-to_nxt < 4)
23334684ddb6SLionel Sambuc                 return codecvt_base::partial;
23344684ddb6SLionel Sambuc             *to_nxt++ = static_cast<uint8_t>(0xF0 |  (wc >> 18));
23354684ddb6SLionel Sambuc             *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x03F000) >> 12));
23364684ddb6SLionel Sambuc             *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x000FC0) >> 6));
23374684ddb6SLionel Sambuc             *to_nxt++ = static_cast<uint8_t>(0x80 |  (wc & 0x00003F));
23384684ddb6SLionel Sambuc         }
23394684ddb6SLionel Sambuc     }
23404684ddb6SLionel Sambuc     return codecvt_base::ok;
23414684ddb6SLionel Sambuc }
23424684ddb6SLionel Sambuc 
23434684ddb6SLionel Sambuc static
23444684ddb6SLionel Sambuc codecvt_base::result
utf8_to_ucs4(const uint8_t * frm,const uint8_t * frm_end,const uint8_t * & frm_nxt,uint32_t * to,uint32_t * to_end,uint32_t * & to_nxt,unsigned long Maxcode=0x10FFFF,codecvt_mode mode=codecvt_mode (0))23454684ddb6SLionel Sambuc utf8_to_ucs4(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
23464684ddb6SLionel Sambuc              uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt,
23474684ddb6SLionel Sambuc              unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
23484684ddb6SLionel Sambuc {
23494684ddb6SLionel Sambuc     frm_nxt = frm;
23504684ddb6SLionel Sambuc     to_nxt = to;
23514684ddb6SLionel Sambuc     if (mode & consume_header)
23524684ddb6SLionel Sambuc     {
23534684ddb6SLionel Sambuc         if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
23544684ddb6SLionel Sambuc                                                           frm_nxt[2] == 0xBF)
23554684ddb6SLionel Sambuc             frm_nxt += 3;
23564684ddb6SLionel Sambuc     }
23574684ddb6SLionel Sambuc     for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt)
23584684ddb6SLionel Sambuc     {
23594684ddb6SLionel Sambuc         uint8_t c1 = static_cast<uint8_t>(*frm_nxt);
23604684ddb6SLionel Sambuc         if (c1 < 0x80)
23614684ddb6SLionel Sambuc         {
23624684ddb6SLionel Sambuc             if (c1 > Maxcode)
23634684ddb6SLionel Sambuc                 return codecvt_base::error;
23644684ddb6SLionel Sambuc             *to_nxt = static_cast<uint32_t>(c1);
23654684ddb6SLionel Sambuc             ++frm_nxt;
23664684ddb6SLionel Sambuc         }
23674684ddb6SLionel Sambuc         else if (c1 < 0xC2)
23684684ddb6SLionel Sambuc         {
23694684ddb6SLionel Sambuc             return codecvt_base::error;
23704684ddb6SLionel Sambuc         }
23714684ddb6SLionel Sambuc         else if (c1 < 0xE0)
23724684ddb6SLionel Sambuc         {
23734684ddb6SLionel Sambuc             if (frm_end-frm_nxt < 2)
23744684ddb6SLionel Sambuc                 return codecvt_base::partial;
23754684ddb6SLionel Sambuc             uint8_t c2 = frm_nxt[1];
23764684ddb6SLionel Sambuc             if ((c2 & 0xC0) != 0x80)
23774684ddb6SLionel Sambuc                 return codecvt_base::error;
23784684ddb6SLionel Sambuc             uint32_t t = static_cast<uint32_t>(((c1 & 0x1F) << 6)
23794684ddb6SLionel Sambuc                                               | (c2 & 0x3F));
23804684ddb6SLionel Sambuc             if (t > Maxcode)
23814684ddb6SLionel Sambuc                 return codecvt_base::error;
23824684ddb6SLionel Sambuc             *to_nxt = t;
23834684ddb6SLionel Sambuc             frm_nxt += 2;
23844684ddb6SLionel Sambuc         }
23854684ddb6SLionel Sambuc         else if (c1 < 0xF0)
23864684ddb6SLionel Sambuc         {
23874684ddb6SLionel Sambuc             if (frm_end-frm_nxt < 3)
23884684ddb6SLionel Sambuc                 return codecvt_base::partial;
23894684ddb6SLionel Sambuc             uint8_t c2 = frm_nxt[1];
23904684ddb6SLionel Sambuc             uint8_t c3 = frm_nxt[2];
23914684ddb6SLionel Sambuc             switch (c1)
23924684ddb6SLionel Sambuc             {
23934684ddb6SLionel Sambuc             case 0xE0:
23944684ddb6SLionel Sambuc                 if ((c2 & 0xE0) != 0xA0)
23954684ddb6SLionel Sambuc                     return codecvt_base::error;
23964684ddb6SLionel Sambuc                  break;
23974684ddb6SLionel Sambuc             case 0xED:
23984684ddb6SLionel Sambuc                 if ((c2 & 0xE0) != 0x80)
23994684ddb6SLionel Sambuc                     return codecvt_base::error;
24004684ddb6SLionel Sambuc                  break;
24014684ddb6SLionel Sambuc             default:
24024684ddb6SLionel Sambuc                 if ((c2 & 0xC0) != 0x80)
24034684ddb6SLionel Sambuc                     return codecvt_base::error;
24044684ddb6SLionel Sambuc                  break;
24054684ddb6SLionel Sambuc             }
24064684ddb6SLionel Sambuc             if ((c3 & 0xC0) != 0x80)
24074684ddb6SLionel Sambuc                 return codecvt_base::error;
24084684ddb6SLionel Sambuc             uint32_t t = static_cast<uint32_t>(((c1 & 0x0F) << 12)
24094684ddb6SLionel Sambuc                                              | ((c2 & 0x3F) << 6)
24104684ddb6SLionel Sambuc                                              |  (c3 & 0x3F));
24114684ddb6SLionel Sambuc             if (t > Maxcode)
24124684ddb6SLionel Sambuc                 return codecvt_base::error;
24134684ddb6SLionel Sambuc             *to_nxt = t;
24144684ddb6SLionel Sambuc             frm_nxt += 3;
24154684ddb6SLionel Sambuc         }
24164684ddb6SLionel Sambuc         else if (c1 < 0xF5)
24174684ddb6SLionel Sambuc         {
24184684ddb6SLionel Sambuc             if (frm_end-frm_nxt < 4)
24194684ddb6SLionel Sambuc                 return codecvt_base::partial;
24204684ddb6SLionel Sambuc             uint8_t c2 = frm_nxt[1];
24214684ddb6SLionel Sambuc             uint8_t c3 = frm_nxt[2];
24224684ddb6SLionel Sambuc             uint8_t c4 = frm_nxt[3];
24234684ddb6SLionel Sambuc             switch (c1)
24244684ddb6SLionel Sambuc             {
24254684ddb6SLionel Sambuc             case 0xF0:
24264684ddb6SLionel Sambuc                 if (!(0x90 <= c2 && c2 <= 0xBF))
24274684ddb6SLionel Sambuc                     return codecvt_base::error;
24284684ddb6SLionel Sambuc                  break;
24294684ddb6SLionel Sambuc             case 0xF4:
24304684ddb6SLionel Sambuc                 if ((c2 & 0xF0) != 0x80)
24314684ddb6SLionel Sambuc                     return codecvt_base::error;
24324684ddb6SLionel Sambuc                  break;
24334684ddb6SLionel Sambuc             default:
24344684ddb6SLionel Sambuc                 if ((c2 & 0xC0) != 0x80)
24354684ddb6SLionel Sambuc                     return codecvt_base::error;
24364684ddb6SLionel Sambuc                  break;
24374684ddb6SLionel Sambuc             }
24384684ddb6SLionel Sambuc             if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
24394684ddb6SLionel Sambuc                 return codecvt_base::error;
24404684ddb6SLionel Sambuc             uint32_t t = static_cast<uint32_t>(((c1 & 0x07) << 18)
24414684ddb6SLionel Sambuc                                              | ((c2 & 0x3F) << 12)
24424684ddb6SLionel Sambuc                                              | ((c3 & 0x3F) << 6)
24434684ddb6SLionel Sambuc                                              |  (c4 & 0x3F));
24444684ddb6SLionel Sambuc             if (t > Maxcode)
24454684ddb6SLionel Sambuc                 return codecvt_base::error;
24464684ddb6SLionel Sambuc             *to_nxt = t;
24474684ddb6SLionel Sambuc             frm_nxt += 4;
24484684ddb6SLionel Sambuc         }
24494684ddb6SLionel Sambuc         else
24504684ddb6SLionel Sambuc         {
24514684ddb6SLionel Sambuc             return codecvt_base::error;
24524684ddb6SLionel Sambuc         }
24534684ddb6SLionel Sambuc     }
24544684ddb6SLionel Sambuc     return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
24554684ddb6SLionel Sambuc }
24564684ddb6SLionel Sambuc 
24574684ddb6SLionel Sambuc static
24584684ddb6SLionel Sambuc int
utf8_to_ucs4_length(const uint8_t * frm,const uint8_t * frm_end,size_t mx,unsigned long Maxcode=0x10FFFF,codecvt_mode mode=codecvt_mode (0))24594684ddb6SLionel Sambuc utf8_to_ucs4_length(const uint8_t* frm, const uint8_t* frm_end,
24604684ddb6SLionel Sambuc                     size_t mx, unsigned long Maxcode = 0x10FFFF,
24614684ddb6SLionel Sambuc                     codecvt_mode mode = codecvt_mode(0))
24624684ddb6SLionel Sambuc {
24634684ddb6SLionel Sambuc     const uint8_t* frm_nxt = frm;
24644684ddb6SLionel Sambuc     if (mode & consume_header)
24654684ddb6SLionel Sambuc     {
24664684ddb6SLionel Sambuc         if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
24674684ddb6SLionel Sambuc                                                           frm_nxt[2] == 0xBF)
24684684ddb6SLionel Sambuc             frm_nxt += 3;
24694684ddb6SLionel Sambuc     }
24704684ddb6SLionel Sambuc     for (size_t nchar32_t = 0; frm_nxt < frm_end && nchar32_t < mx; ++nchar32_t)
24714684ddb6SLionel Sambuc     {
24724684ddb6SLionel Sambuc         uint8_t c1 = static_cast<uint8_t>(*frm_nxt);
24734684ddb6SLionel Sambuc         if (c1 < 0x80)
24744684ddb6SLionel Sambuc         {
24754684ddb6SLionel Sambuc             if (c1 > Maxcode)
24764684ddb6SLionel Sambuc                 break;
24774684ddb6SLionel Sambuc             ++frm_nxt;
24784684ddb6SLionel Sambuc         }
24794684ddb6SLionel Sambuc         else if (c1 < 0xC2)
24804684ddb6SLionel Sambuc         {
24814684ddb6SLionel Sambuc             break;
24824684ddb6SLionel Sambuc         }
24834684ddb6SLionel Sambuc         else if (c1 < 0xE0)
24844684ddb6SLionel Sambuc         {
24854684ddb6SLionel Sambuc             if ((frm_end-frm_nxt < 2) || ((frm_nxt[1] & 0xC0) != 0x80))
24864684ddb6SLionel Sambuc                 break;
24874684ddb6SLionel Sambuc             if ((((c1 & 0x1Fu) << 6) | (frm_nxt[1] & 0x3Fu)) > Maxcode)
24884684ddb6SLionel Sambuc                 break;
24894684ddb6SLionel Sambuc             frm_nxt += 2;
24904684ddb6SLionel Sambuc         }
24914684ddb6SLionel Sambuc         else if (c1 < 0xF0)
24924684ddb6SLionel Sambuc         {
24934684ddb6SLionel Sambuc             if (frm_end-frm_nxt < 3)
24944684ddb6SLionel Sambuc                 break;
24954684ddb6SLionel Sambuc             uint8_t c2 = frm_nxt[1];
24964684ddb6SLionel Sambuc             uint8_t c3 = frm_nxt[2];
24974684ddb6SLionel Sambuc             switch (c1)
24984684ddb6SLionel Sambuc             {
24994684ddb6SLionel Sambuc             case 0xE0:
25004684ddb6SLionel Sambuc                 if ((c2 & 0xE0) != 0xA0)
25014684ddb6SLionel Sambuc                     return static_cast<int>(frm_nxt - frm);
25024684ddb6SLionel Sambuc                 break;
25034684ddb6SLionel Sambuc             case 0xED:
25044684ddb6SLionel Sambuc                 if ((c2 & 0xE0) != 0x80)
25054684ddb6SLionel Sambuc                     return static_cast<int>(frm_nxt - frm);
25064684ddb6SLionel Sambuc                  break;
25074684ddb6SLionel Sambuc             default:
25084684ddb6SLionel Sambuc                 if ((c2 & 0xC0) != 0x80)
25094684ddb6SLionel Sambuc                     return static_cast<int>(frm_nxt - frm);
25104684ddb6SLionel Sambuc                  break;
25114684ddb6SLionel Sambuc             }
25124684ddb6SLionel Sambuc             if ((c3 & 0xC0) != 0x80)
25134684ddb6SLionel Sambuc                 break;
25144684ddb6SLionel Sambuc             if ((((c1 & 0x0Fu) << 12) | ((c2 & 0x3Fu) << 6) | (c3 & 0x3Fu)) > Maxcode)
25154684ddb6SLionel Sambuc                 break;
25164684ddb6SLionel Sambuc             frm_nxt += 3;
25174684ddb6SLionel Sambuc         }
25184684ddb6SLionel Sambuc         else if (c1 < 0xF5)
25194684ddb6SLionel Sambuc         {
25204684ddb6SLionel Sambuc             if (frm_end-frm_nxt < 4)
25214684ddb6SLionel Sambuc                 break;
25224684ddb6SLionel Sambuc             uint8_t c2 = frm_nxt[1];
25234684ddb6SLionel Sambuc             uint8_t c3 = frm_nxt[2];
25244684ddb6SLionel Sambuc             uint8_t c4 = frm_nxt[3];
25254684ddb6SLionel Sambuc             switch (c1)
25264684ddb6SLionel Sambuc             {
25274684ddb6SLionel Sambuc             case 0xF0:
25284684ddb6SLionel Sambuc                 if (!(0x90 <= c2 && c2 <= 0xBF))
25294684ddb6SLionel Sambuc                     return static_cast<int>(frm_nxt - frm);
25304684ddb6SLionel Sambuc                  break;
25314684ddb6SLionel Sambuc             case 0xF4:
25324684ddb6SLionel Sambuc                 if ((c2 & 0xF0) != 0x80)
25334684ddb6SLionel Sambuc                     return static_cast<int>(frm_nxt - frm);
25344684ddb6SLionel Sambuc                  break;
25354684ddb6SLionel Sambuc             default:
25364684ddb6SLionel Sambuc                 if ((c2 & 0xC0) != 0x80)
25374684ddb6SLionel Sambuc                     return static_cast<int>(frm_nxt - frm);
25384684ddb6SLionel Sambuc                  break;
25394684ddb6SLionel Sambuc             }
25404684ddb6SLionel Sambuc             if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
25414684ddb6SLionel Sambuc                 break;
25424684ddb6SLionel Sambuc             if ((((c1 & 0x07u) << 18) | ((c2 & 0x3Fu) << 12) |
25434684ddb6SLionel Sambuc                  ((c3 & 0x3Fu) << 6)  |  (c4 & 0x3Fu)) > Maxcode)
25444684ddb6SLionel Sambuc                 break;
25454684ddb6SLionel Sambuc             frm_nxt += 4;
25464684ddb6SLionel Sambuc         }
25474684ddb6SLionel Sambuc         else
25484684ddb6SLionel Sambuc         {
25494684ddb6SLionel Sambuc             break;
25504684ddb6SLionel Sambuc         }
25514684ddb6SLionel Sambuc     }
25524684ddb6SLionel Sambuc     return static_cast<int>(frm_nxt - frm);
25534684ddb6SLionel Sambuc }
25544684ddb6SLionel Sambuc 
25554684ddb6SLionel Sambuc static
25564684ddb6SLionel Sambuc codecvt_base::result
ucs2_to_utf8(const uint16_t * frm,const uint16_t * frm_end,const uint16_t * & frm_nxt,uint8_t * to,uint8_t * to_end,uint8_t * & to_nxt,unsigned long Maxcode=0x10FFFF,codecvt_mode mode=codecvt_mode (0))25574684ddb6SLionel Sambuc ucs2_to_utf8(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt,
25584684ddb6SLionel Sambuc              uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
25594684ddb6SLionel Sambuc              unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
25604684ddb6SLionel Sambuc {
25614684ddb6SLionel Sambuc     frm_nxt = frm;
25624684ddb6SLionel Sambuc     to_nxt = to;
25634684ddb6SLionel Sambuc     if (mode & generate_header)
25644684ddb6SLionel Sambuc     {
25654684ddb6SLionel Sambuc         if (to_end-to_nxt < 3)
25664684ddb6SLionel Sambuc             return codecvt_base::partial;
25674684ddb6SLionel Sambuc         *to_nxt++ = static_cast<uint8_t>(0xEF);
25684684ddb6SLionel Sambuc         *to_nxt++ = static_cast<uint8_t>(0xBB);
25694684ddb6SLionel Sambuc         *to_nxt++ = static_cast<uint8_t>(0xBF);
25704684ddb6SLionel Sambuc     }
25714684ddb6SLionel Sambuc     for (; frm_nxt < frm_end; ++frm_nxt)
25724684ddb6SLionel Sambuc     {
25734684ddb6SLionel Sambuc         uint16_t wc = *frm_nxt;
25744684ddb6SLionel Sambuc         if ((wc & 0xF800) == 0xD800 || wc > Maxcode)
25754684ddb6SLionel Sambuc             return codecvt_base::error;
25764684ddb6SLionel Sambuc         if (wc < 0x0080)
25774684ddb6SLionel Sambuc         {
25784684ddb6SLionel Sambuc             if (to_end-to_nxt < 1)
25794684ddb6SLionel Sambuc                 return codecvt_base::partial;
25804684ddb6SLionel Sambuc             *to_nxt++ = static_cast<uint8_t>(wc);
25814684ddb6SLionel Sambuc         }
25824684ddb6SLionel Sambuc         else if (wc < 0x0800)
25834684ddb6SLionel Sambuc         {
25844684ddb6SLionel Sambuc             if (to_end-to_nxt < 2)
25854684ddb6SLionel Sambuc                 return codecvt_base::partial;
25864684ddb6SLionel Sambuc             *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc >> 6));
25874684ddb6SLionel Sambuc             *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x03F));
25884684ddb6SLionel Sambuc         }
25894684ddb6SLionel Sambuc         else // if (wc <= 0xFFFF)
25904684ddb6SLionel Sambuc         {
25914684ddb6SLionel Sambuc             if (to_end-to_nxt < 3)
25924684ddb6SLionel Sambuc                 return codecvt_base::partial;
25934684ddb6SLionel Sambuc             *to_nxt++ = static_cast<uint8_t>(0xE0 |  (wc >> 12));
25944684ddb6SLionel Sambuc             *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x0FC0) >> 6));
25954684ddb6SLionel Sambuc             *to_nxt++ = static_cast<uint8_t>(0x80 |  (wc & 0x003F));
25964684ddb6SLionel Sambuc         }
25974684ddb6SLionel Sambuc     }
25984684ddb6SLionel Sambuc     return codecvt_base::ok;
25994684ddb6SLionel Sambuc }
26004684ddb6SLionel Sambuc 
26014684ddb6SLionel Sambuc static
26024684ddb6SLionel Sambuc codecvt_base::result
utf8_to_ucs2(const uint8_t * frm,const uint8_t * frm_end,const uint8_t * & frm_nxt,uint16_t * to,uint16_t * to_end,uint16_t * & to_nxt,unsigned long Maxcode=0x10FFFF,codecvt_mode mode=codecvt_mode (0))26034684ddb6SLionel Sambuc utf8_to_ucs2(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
26044684ddb6SLionel Sambuc              uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt,
26054684ddb6SLionel Sambuc              unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
26064684ddb6SLionel Sambuc {
26074684ddb6SLionel Sambuc     frm_nxt = frm;
26084684ddb6SLionel Sambuc     to_nxt = to;
26094684ddb6SLionel Sambuc     if (mode & consume_header)
26104684ddb6SLionel Sambuc     {
26114684ddb6SLionel Sambuc         if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
26124684ddb6SLionel Sambuc                                                           frm_nxt[2] == 0xBF)
26134684ddb6SLionel Sambuc             frm_nxt += 3;
26144684ddb6SLionel Sambuc     }
26154684ddb6SLionel Sambuc     for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt)
26164684ddb6SLionel Sambuc     {
26174684ddb6SLionel Sambuc         uint8_t c1 = static_cast<uint8_t>(*frm_nxt);
26184684ddb6SLionel Sambuc         if (c1 < 0x80)
26194684ddb6SLionel Sambuc         {
26204684ddb6SLionel Sambuc             if (c1 > Maxcode)
26214684ddb6SLionel Sambuc                 return codecvt_base::error;
26224684ddb6SLionel Sambuc             *to_nxt = static_cast<uint16_t>(c1);
26234684ddb6SLionel Sambuc             ++frm_nxt;
26244684ddb6SLionel Sambuc         }
26254684ddb6SLionel Sambuc         else if (c1 < 0xC2)
26264684ddb6SLionel Sambuc         {
26274684ddb6SLionel Sambuc             return codecvt_base::error;
26284684ddb6SLionel Sambuc         }
26294684ddb6SLionel Sambuc         else if (c1 < 0xE0)
26304684ddb6SLionel Sambuc         {
26314684ddb6SLionel Sambuc             if (frm_end-frm_nxt < 2)
26324684ddb6SLionel Sambuc                 return codecvt_base::partial;
26334684ddb6SLionel Sambuc             uint8_t c2 = frm_nxt[1];
26344684ddb6SLionel Sambuc             if ((c2 & 0xC0) != 0x80)
26354684ddb6SLionel Sambuc                 return codecvt_base::error;
26364684ddb6SLionel Sambuc             uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6)
26374684ddb6SLionel Sambuc                                               | (c2 & 0x3F));
26384684ddb6SLionel Sambuc             if (t > Maxcode)
26394684ddb6SLionel Sambuc                 return codecvt_base::error;
26404684ddb6SLionel Sambuc             *to_nxt = t;
26414684ddb6SLionel Sambuc             frm_nxt += 2;
26424684ddb6SLionel Sambuc         }
26434684ddb6SLionel Sambuc         else if (c1 < 0xF0)
26444684ddb6SLionel Sambuc         {
26454684ddb6SLionel Sambuc             if (frm_end-frm_nxt < 3)
26464684ddb6SLionel Sambuc                 return codecvt_base::partial;
26474684ddb6SLionel Sambuc             uint8_t c2 = frm_nxt[1];
26484684ddb6SLionel Sambuc             uint8_t c3 = frm_nxt[2];
26494684ddb6SLionel Sambuc             switch (c1)
26504684ddb6SLionel Sambuc             {
26514684ddb6SLionel Sambuc             case 0xE0:
26524684ddb6SLionel Sambuc                 if ((c2 & 0xE0) != 0xA0)
26534684ddb6SLionel Sambuc                     return codecvt_base::error;
26544684ddb6SLionel Sambuc                  break;
26554684ddb6SLionel Sambuc             case 0xED:
26564684ddb6SLionel Sambuc                 if ((c2 & 0xE0) != 0x80)
26574684ddb6SLionel Sambuc                     return codecvt_base::error;
26584684ddb6SLionel Sambuc                  break;
26594684ddb6SLionel Sambuc             default:
26604684ddb6SLionel Sambuc                 if ((c2 & 0xC0) != 0x80)
26614684ddb6SLionel Sambuc                     return codecvt_base::error;
26624684ddb6SLionel Sambuc                  break;
26634684ddb6SLionel Sambuc             }
26644684ddb6SLionel Sambuc             if ((c3 & 0xC0) != 0x80)
26654684ddb6SLionel Sambuc                 return codecvt_base::error;
26664684ddb6SLionel Sambuc             uint16_t t = static_cast<uint16_t>(((c1 & 0x0F) << 12)
26674684ddb6SLionel Sambuc                                              | ((c2 & 0x3F) << 6)
26684684ddb6SLionel Sambuc                                              |  (c3 & 0x3F));
26694684ddb6SLionel Sambuc             if (t > Maxcode)
26704684ddb6SLionel Sambuc                 return codecvt_base::error;
26714684ddb6SLionel Sambuc             *to_nxt = t;
26724684ddb6SLionel Sambuc             frm_nxt += 3;
26734684ddb6SLionel Sambuc         }
26744684ddb6SLionel Sambuc         else
26754684ddb6SLionel Sambuc         {
26764684ddb6SLionel Sambuc             return codecvt_base::error;
26774684ddb6SLionel Sambuc         }
26784684ddb6SLionel Sambuc     }
26794684ddb6SLionel Sambuc     return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
26804684ddb6SLionel Sambuc }
26814684ddb6SLionel Sambuc 
26824684ddb6SLionel Sambuc static
26834684ddb6SLionel Sambuc int
utf8_to_ucs2_length(const uint8_t * frm,const uint8_t * frm_end,size_t mx,unsigned long Maxcode=0x10FFFF,codecvt_mode mode=codecvt_mode (0))26844684ddb6SLionel Sambuc utf8_to_ucs2_length(const uint8_t* frm, const uint8_t* frm_end,
26854684ddb6SLionel Sambuc                     size_t mx, unsigned long Maxcode = 0x10FFFF,
26864684ddb6SLionel Sambuc                     codecvt_mode mode = codecvt_mode(0))
26874684ddb6SLionel Sambuc {
26884684ddb6SLionel Sambuc     const uint8_t* frm_nxt = frm;
26894684ddb6SLionel Sambuc     if (mode & consume_header)
26904684ddb6SLionel Sambuc     {
26914684ddb6SLionel Sambuc         if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
26924684ddb6SLionel Sambuc                                                           frm_nxt[2] == 0xBF)
26934684ddb6SLionel Sambuc             frm_nxt += 3;
26944684ddb6SLionel Sambuc     }
26954684ddb6SLionel Sambuc     for (size_t nchar32_t = 0; frm_nxt < frm_end && nchar32_t < mx; ++nchar32_t)
26964684ddb6SLionel Sambuc     {
26974684ddb6SLionel Sambuc         uint8_t c1 = static_cast<uint8_t>(*frm_nxt);
26984684ddb6SLionel Sambuc         if (c1 < 0x80)
26994684ddb6SLionel Sambuc         {
27004684ddb6SLionel Sambuc             if (c1 > Maxcode)
27014684ddb6SLionel Sambuc                 break;
27024684ddb6SLionel Sambuc             ++frm_nxt;
27034684ddb6SLionel Sambuc         }
27044684ddb6SLionel Sambuc         else if (c1 < 0xC2)
27054684ddb6SLionel Sambuc         {
27064684ddb6SLionel Sambuc             break;
27074684ddb6SLionel Sambuc         }
27084684ddb6SLionel Sambuc         else if (c1 < 0xE0)
27094684ddb6SLionel Sambuc         {
27104684ddb6SLionel Sambuc             if ((frm_end-frm_nxt < 2) || ((frm_nxt[1] & 0xC0) != 0x80))
27114684ddb6SLionel Sambuc                 break;
27124684ddb6SLionel Sambuc             if ((((c1 & 0x1Fu) << 6) | (frm_nxt[1] & 0x3Fu)) > Maxcode)
27134684ddb6SLionel Sambuc                 break;
27144684ddb6SLionel Sambuc             frm_nxt += 2;
27154684ddb6SLionel Sambuc         }
27164684ddb6SLionel Sambuc         else if (c1 < 0xF0)
27174684ddb6SLionel Sambuc         {
27184684ddb6SLionel Sambuc             if (frm_end-frm_nxt < 3)
27194684ddb6SLionel Sambuc                 break;
27204684ddb6SLionel Sambuc             uint8_t c2 = frm_nxt[1];
27214684ddb6SLionel Sambuc             uint8_t c3 = frm_nxt[2];
27224684ddb6SLionel Sambuc             switch (c1)
27234684ddb6SLionel Sambuc             {
27244684ddb6SLionel Sambuc             case 0xE0:
27254684ddb6SLionel Sambuc                 if ((c2 & 0xE0) != 0xA0)
27264684ddb6SLionel Sambuc                     return static_cast<int>(frm_nxt - frm);
27274684ddb6SLionel Sambuc                 break;
27284684ddb6SLionel Sambuc             case 0xED:
27294684ddb6SLionel Sambuc                 if ((c2 & 0xE0) != 0x80)
27304684ddb6SLionel Sambuc                     return static_cast<int>(frm_nxt - frm);
27314684ddb6SLionel Sambuc                  break;
27324684ddb6SLionel Sambuc             default:
27334684ddb6SLionel Sambuc                 if ((c2 & 0xC0) != 0x80)
27344684ddb6SLionel Sambuc                     return static_cast<int>(frm_nxt - frm);
27354684ddb6SLionel Sambuc                  break;
27364684ddb6SLionel Sambuc             }
27374684ddb6SLionel Sambuc             if ((c3 & 0xC0) != 0x80)
27384684ddb6SLionel Sambuc                 break;
27394684ddb6SLionel Sambuc             if ((((c1 & 0x0Fu) << 12) | ((c2 & 0x3Fu) << 6) | (c3 & 0x3Fu)) > Maxcode)
27404684ddb6SLionel Sambuc                 break;
27414684ddb6SLionel Sambuc             frm_nxt += 3;
27424684ddb6SLionel Sambuc         }
27434684ddb6SLionel Sambuc         else
27444684ddb6SLionel Sambuc         {
27454684ddb6SLionel Sambuc             break;
27464684ddb6SLionel Sambuc         }
27474684ddb6SLionel Sambuc     }
27484684ddb6SLionel Sambuc     return static_cast<int>(frm_nxt - frm);
27494684ddb6SLionel Sambuc }
27504684ddb6SLionel Sambuc 
27514684ddb6SLionel Sambuc static
27524684ddb6SLionel Sambuc codecvt_base::result
ucs4_to_utf16be(const uint32_t * frm,const uint32_t * frm_end,const uint32_t * & frm_nxt,uint8_t * to,uint8_t * to_end,uint8_t * & to_nxt,unsigned long Maxcode=0x10FFFF,codecvt_mode mode=codecvt_mode (0))27534684ddb6SLionel Sambuc ucs4_to_utf16be(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt,
27544684ddb6SLionel Sambuc                 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
27554684ddb6SLionel Sambuc                 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
27564684ddb6SLionel Sambuc {
27574684ddb6SLionel Sambuc     frm_nxt = frm;
27584684ddb6SLionel Sambuc     to_nxt = to;
27594684ddb6SLionel Sambuc     if (mode & generate_header)
27604684ddb6SLionel Sambuc     {
27614684ddb6SLionel Sambuc         if (to_end-to_nxt < 2)
27624684ddb6SLionel Sambuc             return codecvt_base::partial;
27634684ddb6SLionel Sambuc         *to_nxt++ = static_cast<uint8_t>(0xFE);
27644684ddb6SLionel Sambuc         *to_nxt++ = static_cast<uint8_t>(0xFF);
27654684ddb6SLionel Sambuc     }
27664684ddb6SLionel Sambuc     for (; frm_nxt < frm_end; ++frm_nxt)
27674684ddb6SLionel Sambuc     {
27684684ddb6SLionel Sambuc         uint32_t wc = *frm_nxt;
27694684ddb6SLionel Sambuc         if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode)
27704684ddb6SLionel Sambuc             return codecvt_base::error;
27714684ddb6SLionel Sambuc         if (wc < 0x010000)
27724684ddb6SLionel Sambuc         {
27734684ddb6SLionel Sambuc             if (to_end-to_nxt < 2)
27744684ddb6SLionel Sambuc                 return codecvt_base::partial;
27754684ddb6SLionel Sambuc             *to_nxt++ = static_cast<uint8_t>(wc >> 8);
27764684ddb6SLionel Sambuc             *to_nxt++ = static_cast<uint8_t>(wc);
27774684ddb6SLionel Sambuc         }
27784684ddb6SLionel Sambuc         else
27794684ddb6SLionel Sambuc         {
27804684ddb6SLionel Sambuc             if (to_end-to_nxt < 4)
27814684ddb6SLionel Sambuc                 return codecvt_base::partial;
27824684ddb6SLionel Sambuc             uint16_t t = static_cast<uint16_t>(
27834684ddb6SLionel Sambuc                     0xD800
27844684ddb6SLionel Sambuc                   | ((((wc & 0x1F0000) >> 16) - 1) << 6)
27854684ddb6SLionel Sambuc                   |   ((wc & 0x00FC00) >> 10));
27864684ddb6SLionel Sambuc             *to_nxt++ = static_cast<uint8_t>(t >> 8);
27874684ddb6SLionel Sambuc             *to_nxt++ = static_cast<uint8_t>(t);
27884684ddb6SLionel Sambuc             t = static_cast<uint16_t>(0xDC00 | (wc & 0x03FF));
27894684ddb6SLionel Sambuc             *to_nxt++ = static_cast<uint8_t>(t >> 8);
27904684ddb6SLionel Sambuc             *to_nxt++ = static_cast<uint8_t>(t);
27914684ddb6SLionel Sambuc         }
27924684ddb6SLionel Sambuc     }
27934684ddb6SLionel Sambuc     return codecvt_base::ok;
27944684ddb6SLionel Sambuc }
27954684ddb6SLionel Sambuc 
27964684ddb6SLionel Sambuc static
27974684ddb6SLionel Sambuc codecvt_base::result
utf16be_to_ucs4(const uint8_t * frm,const uint8_t * frm_end,const uint8_t * & frm_nxt,uint32_t * to,uint32_t * to_end,uint32_t * & to_nxt,unsigned long Maxcode=0x10FFFF,codecvt_mode mode=codecvt_mode (0))27984684ddb6SLionel Sambuc utf16be_to_ucs4(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
27994684ddb6SLionel Sambuc                 uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt,
28004684ddb6SLionel Sambuc                 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
28014684ddb6SLionel Sambuc {
28024684ddb6SLionel Sambuc     frm_nxt = frm;
28034684ddb6SLionel Sambuc     to_nxt = to;
28044684ddb6SLionel Sambuc     if (mode & consume_header)
28054684ddb6SLionel Sambuc     {
28064684ddb6SLionel Sambuc         if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)
28074684ddb6SLionel Sambuc             frm_nxt += 2;
28084684ddb6SLionel Sambuc     }
28094684ddb6SLionel Sambuc     for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)
28104684ddb6SLionel Sambuc     {
28114684ddb6SLionel Sambuc         uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]);
28124684ddb6SLionel Sambuc         if ((c1 & 0xFC00) == 0xDC00)
28134684ddb6SLionel Sambuc             return codecvt_base::error;
28144684ddb6SLionel Sambuc         if ((c1 & 0xFC00) != 0xD800)
28154684ddb6SLionel Sambuc         {
28164684ddb6SLionel Sambuc             if (c1 > Maxcode)
28174684ddb6SLionel Sambuc                 return codecvt_base::error;
28184684ddb6SLionel Sambuc             *to_nxt = static_cast<uint32_t>(c1);
28194684ddb6SLionel Sambuc             frm_nxt += 2;
28204684ddb6SLionel Sambuc         }
28214684ddb6SLionel Sambuc         else
28224684ddb6SLionel Sambuc         {
28234684ddb6SLionel Sambuc             if (frm_end-frm_nxt < 4)
28244684ddb6SLionel Sambuc                 return codecvt_base::partial;
28254684ddb6SLionel Sambuc             uint16_t c2 = static_cast<uint16_t>(frm_nxt[2] << 8 | frm_nxt[3]);
28264684ddb6SLionel Sambuc             if ((c2 & 0xFC00) != 0xDC00)
28274684ddb6SLionel Sambuc                 return codecvt_base::error;
28284684ddb6SLionel Sambuc             uint32_t t = static_cast<uint32_t>(
28294684ddb6SLionel Sambuc                     ((((c1 & 0x03C0) >> 6) + 1) << 16)
28304684ddb6SLionel Sambuc                   |   ((c1 & 0x003F) << 10)
28314684ddb6SLionel Sambuc                   |    (c2 & 0x03FF));
28324684ddb6SLionel Sambuc             if (t > Maxcode)
28334684ddb6SLionel Sambuc                 return codecvt_base::error;
28344684ddb6SLionel Sambuc             *to_nxt = t;
28354684ddb6SLionel Sambuc             frm_nxt += 4;
28364684ddb6SLionel Sambuc         }
28374684ddb6SLionel Sambuc     }
28384684ddb6SLionel Sambuc     return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
28394684ddb6SLionel Sambuc }
28404684ddb6SLionel Sambuc 
28414684ddb6SLionel Sambuc static
28424684ddb6SLionel Sambuc int
utf16be_to_ucs4_length(const uint8_t * frm,const uint8_t * frm_end,size_t mx,unsigned long Maxcode=0x10FFFF,codecvt_mode mode=codecvt_mode (0))28434684ddb6SLionel Sambuc utf16be_to_ucs4_length(const uint8_t* frm, const uint8_t* frm_end,
28444684ddb6SLionel Sambuc                        size_t mx, unsigned long Maxcode = 0x10FFFF,
28454684ddb6SLionel Sambuc                        codecvt_mode mode = codecvt_mode(0))
28464684ddb6SLionel Sambuc {
28474684ddb6SLionel Sambuc     const uint8_t* frm_nxt = frm;
28484684ddb6SLionel Sambuc     if (mode & consume_header)
28494684ddb6SLionel Sambuc     {
28504684ddb6SLionel Sambuc         if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)
28514684ddb6SLionel Sambuc             frm_nxt += 2;
28524684ddb6SLionel Sambuc     }
28534684ddb6SLionel Sambuc     for (size_t nchar32_t = 0; frm_nxt < frm_end - 1 && nchar32_t < mx; ++nchar32_t)
28544684ddb6SLionel Sambuc     {
28554684ddb6SLionel Sambuc         uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]);
28564684ddb6SLionel Sambuc         if ((c1 & 0xFC00) == 0xDC00)
28574684ddb6SLionel Sambuc             break;
28584684ddb6SLionel Sambuc         if ((c1 & 0xFC00) != 0xD800)
28594684ddb6SLionel Sambuc         {
28604684ddb6SLionel Sambuc             if (c1 > Maxcode)
28614684ddb6SLionel Sambuc                 break;
28624684ddb6SLionel Sambuc             frm_nxt += 2;
28634684ddb6SLionel Sambuc         }
28644684ddb6SLionel Sambuc         else
28654684ddb6SLionel Sambuc         {
28664684ddb6SLionel Sambuc             if (frm_end-frm_nxt < 4)
28674684ddb6SLionel Sambuc                 break;
28684684ddb6SLionel Sambuc             uint16_t c2 = static_cast<uint16_t>(frm_nxt[2] << 8 | frm_nxt[3]);
28694684ddb6SLionel Sambuc             if ((c2 & 0xFC00) != 0xDC00)
28704684ddb6SLionel Sambuc                 break;
28714684ddb6SLionel Sambuc             uint32_t t = static_cast<uint32_t>(
28724684ddb6SLionel Sambuc                     ((((c1 & 0x03C0) >> 6) + 1) << 16)
28734684ddb6SLionel Sambuc                   |   ((c1 & 0x003F) << 10)
28744684ddb6SLionel Sambuc                   |    (c2 & 0x03FF));
28754684ddb6SLionel Sambuc             if (t > Maxcode)
28764684ddb6SLionel Sambuc                 break;
28774684ddb6SLionel Sambuc             frm_nxt += 4;
28784684ddb6SLionel Sambuc         }
28794684ddb6SLionel Sambuc     }
28804684ddb6SLionel Sambuc     return static_cast<int>(frm_nxt - frm);
28814684ddb6SLionel Sambuc }
28824684ddb6SLionel Sambuc 
28834684ddb6SLionel Sambuc static
28844684ddb6SLionel Sambuc codecvt_base::result
ucs4_to_utf16le(const uint32_t * frm,const uint32_t * frm_end,const uint32_t * & frm_nxt,uint8_t * to,uint8_t * to_end,uint8_t * & to_nxt,unsigned long Maxcode=0x10FFFF,codecvt_mode mode=codecvt_mode (0))28854684ddb6SLionel Sambuc ucs4_to_utf16le(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt,
28864684ddb6SLionel Sambuc                 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
28874684ddb6SLionel Sambuc                 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
28884684ddb6SLionel Sambuc {
28894684ddb6SLionel Sambuc     frm_nxt = frm;
28904684ddb6SLionel Sambuc     to_nxt = to;
28914684ddb6SLionel Sambuc     if (mode & generate_header)
28924684ddb6SLionel Sambuc     {
28934684ddb6SLionel Sambuc         if (to_end-to_nxt < 2)
28944684ddb6SLionel Sambuc             return codecvt_base::partial;
28954684ddb6SLionel Sambuc             *to_nxt++ = static_cast<uint8_t>(0xFF);
28964684ddb6SLionel Sambuc             *to_nxt++ = static_cast<uint8_t>(0xFE);
28974684ddb6SLionel Sambuc     }
28984684ddb6SLionel Sambuc     for (; frm_nxt < frm_end; ++frm_nxt)
28994684ddb6SLionel Sambuc     {
29004684ddb6SLionel Sambuc         uint32_t wc = *frm_nxt;
29014684ddb6SLionel Sambuc         if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode)
29024684ddb6SLionel Sambuc             return codecvt_base::error;
29034684ddb6SLionel Sambuc         if (wc < 0x010000)
29044684ddb6SLionel Sambuc         {
29054684ddb6SLionel Sambuc             if (to_end-to_nxt < 2)
29064684ddb6SLionel Sambuc                 return codecvt_base::partial;
29074684ddb6SLionel Sambuc             *to_nxt++ = static_cast<uint8_t>(wc);
29084684ddb6SLionel Sambuc             *to_nxt++ = static_cast<uint8_t>(wc >> 8);
29094684ddb6SLionel Sambuc         }
29104684ddb6SLionel Sambuc         else
29114684ddb6SLionel Sambuc         {
29124684ddb6SLionel Sambuc             if (to_end-to_nxt < 4)
29134684ddb6SLionel Sambuc                 return codecvt_base::partial;
29144684ddb6SLionel Sambuc             uint16_t t = static_cast<uint16_t>(
29154684ddb6SLionel Sambuc                     0xD800
29164684ddb6SLionel Sambuc                   | ((((wc & 0x1F0000) >> 16) - 1) << 6)
29174684ddb6SLionel Sambuc                   |   ((wc & 0x00FC00) >> 10));
29184684ddb6SLionel Sambuc             *to_nxt++ = static_cast<uint8_t>(t);
29194684ddb6SLionel Sambuc             *to_nxt++ = static_cast<uint8_t>(t >> 8);
29204684ddb6SLionel Sambuc             t = static_cast<uint16_t>(0xDC00 | (wc & 0x03FF));
29214684ddb6SLionel Sambuc             *to_nxt++ = static_cast<uint8_t>(t);
29224684ddb6SLionel Sambuc             *to_nxt++ = static_cast<uint8_t>(t >> 8);
29234684ddb6SLionel Sambuc         }
29244684ddb6SLionel Sambuc     }
29254684ddb6SLionel Sambuc     return codecvt_base::ok;
29264684ddb6SLionel Sambuc }
29274684ddb6SLionel Sambuc 
29284684ddb6SLionel Sambuc static
29294684ddb6SLionel Sambuc codecvt_base::result
utf16le_to_ucs4(const uint8_t * frm,const uint8_t * frm_end,const uint8_t * & frm_nxt,uint32_t * to,uint32_t * to_end,uint32_t * & to_nxt,unsigned long Maxcode=0x10FFFF,codecvt_mode mode=codecvt_mode (0))29304684ddb6SLionel Sambuc utf16le_to_ucs4(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
29314684ddb6SLionel Sambuc                 uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt,
29324684ddb6SLionel Sambuc                 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
29334684ddb6SLionel Sambuc {
29344684ddb6SLionel Sambuc     frm_nxt = frm;
29354684ddb6SLionel Sambuc     to_nxt = to;
29364684ddb6SLionel Sambuc     if (mode & consume_header)
29374684ddb6SLionel Sambuc     {
29384684ddb6SLionel Sambuc         if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)
29394684ddb6SLionel Sambuc             frm_nxt += 2;
29404684ddb6SLionel Sambuc     }
29414684ddb6SLionel Sambuc     for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)
29424684ddb6SLionel Sambuc     {
29434684ddb6SLionel Sambuc         uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]);
29444684ddb6SLionel Sambuc         if ((c1 & 0xFC00) == 0xDC00)
29454684ddb6SLionel Sambuc             return codecvt_base::error;
29464684ddb6SLionel Sambuc         if ((c1 & 0xFC00) != 0xD800)
29474684ddb6SLionel Sambuc         {
29484684ddb6SLionel Sambuc             if (c1 > Maxcode)
29494684ddb6SLionel Sambuc                 return codecvt_base::error;
29504684ddb6SLionel Sambuc             *to_nxt = static_cast<uint32_t>(c1);
29514684ddb6SLionel Sambuc             frm_nxt += 2;
29524684ddb6SLionel Sambuc         }
29534684ddb6SLionel Sambuc         else
29544684ddb6SLionel Sambuc         {
29554684ddb6SLionel Sambuc             if (frm_end-frm_nxt < 4)
29564684ddb6SLionel Sambuc                 return codecvt_base::partial;
29574684ddb6SLionel Sambuc             uint16_t c2 = static_cast<uint16_t>(frm_nxt[3] << 8 | frm_nxt[2]);
29584684ddb6SLionel Sambuc             if ((c2 & 0xFC00) != 0xDC00)
29594684ddb6SLionel Sambuc                 return codecvt_base::error;
29604684ddb6SLionel Sambuc             uint32_t t = static_cast<uint32_t>(
29614684ddb6SLionel Sambuc                     ((((c1 & 0x03C0) >> 6) + 1) << 16)
29624684ddb6SLionel Sambuc                   |   ((c1 & 0x003F) << 10)
29634684ddb6SLionel Sambuc                   |    (c2 & 0x03FF));
29644684ddb6SLionel Sambuc             if (t > Maxcode)
29654684ddb6SLionel Sambuc                 return codecvt_base::error;
29664684ddb6SLionel Sambuc             *to_nxt = t;
29674684ddb6SLionel Sambuc             frm_nxt += 4;
29684684ddb6SLionel Sambuc         }
29694684ddb6SLionel Sambuc     }
29704684ddb6SLionel Sambuc     return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
29714684ddb6SLionel Sambuc }
29724684ddb6SLionel Sambuc 
29734684ddb6SLionel Sambuc static
29744684ddb6SLionel Sambuc int
utf16le_to_ucs4_length(const uint8_t * frm,const uint8_t * frm_end,size_t mx,unsigned long Maxcode=0x10FFFF,codecvt_mode mode=codecvt_mode (0))29754684ddb6SLionel Sambuc utf16le_to_ucs4_length(const uint8_t* frm, const uint8_t* frm_end,
29764684ddb6SLionel Sambuc                        size_t mx, unsigned long Maxcode = 0x10FFFF,
29774684ddb6SLionel Sambuc                        codecvt_mode mode = codecvt_mode(0))
29784684ddb6SLionel Sambuc {
29794684ddb6SLionel Sambuc     const uint8_t* frm_nxt = frm;
29804684ddb6SLionel Sambuc     if (mode & consume_header)
29814684ddb6SLionel Sambuc     {
29824684ddb6SLionel Sambuc         if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)
29834684ddb6SLionel Sambuc             frm_nxt += 2;
29844684ddb6SLionel Sambuc     }
29854684ddb6SLionel Sambuc     for (size_t nchar32_t = 0; frm_nxt < frm_end - 1 && nchar32_t < mx; ++nchar32_t)
29864684ddb6SLionel Sambuc     {
29874684ddb6SLionel Sambuc         uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]);
29884684ddb6SLionel Sambuc         if ((c1 & 0xFC00) == 0xDC00)
29894684ddb6SLionel Sambuc             break;
29904684ddb6SLionel Sambuc         if ((c1 & 0xFC00) != 0xD800)
29914684ddb6SLionel Sambuc         {
29924684ddb6SLionel Sambuc             if (c1 > Maxcode)
29934684ddb6SLionel Sambuc                 break;
29944684ddb6SLionel Sambuc             frm_nxt += 2;
29954684ddb6SLionel Sambuc         }
29964684ddb6SLionel Sambuc         else
29974684ddb6SLionel Sambuc         {
29984684ddb6SLionel Sambuc             if (frm_end-frm_nxt < 4)
29994684ddb6SLionel Sambuc                 break;
30004684ddb6SLionel Sambuc             uint16_t c2 = static_cast<uint16_t>(frm_nxt[3] << 8 | frm_nxt[2]);
30014684ddb6SLionel Sambuc             if ((c2 & 0xFC00) != 0xDC00)
30024684ddb6SLionel Sambuc                 break;
30034684ddb6SLionel Sambuc             uint32_t t = static_cast<uint32_t>(
30044684ddb6SLionel Sambuc                     ((((c1 & 0x03C0) >> 6) + 1) << 16)
30054684ddb6SLionel Sambuc                   |   ((c1 & 0x003F) << 10)
30064684ddb6SLionel Sambuc                   |    (c2 & 0x03FF));
30074684ddb6SLionel Sambuc             if (t > Maxcode)
30084684ddb6SLionel Sambuc                 break;
30094684ddb6SLionel Sambuc             frm_nxt += 4;
30104684ddb6SLionel Sambuc         }
30114684ddb6SLionel Sambuc     }
30124684ddb6SLionel Sambuc     return static_cast<int>(frm_nxt - frm);
30134684ddb6SLionel Sambuc }
30144684ddb6SLionel Sambuc 
30154684ddb6SLionel Sambuc static
30164684ddb6SLionel Sambuc codecvt_base::result
ucs2_to_utf16be(const uint16_t * frm,const uint16_t * frm_end,const uint16_t * & frm_nxt,uint8_t * to,uint8_t * to_end,uint8_t * & to_nxt,unsigned long Maxcode=0x10FFFF,codecvt_mode mode=codecvt_mode (0))30174684ddb6SLionel Sambuc ucs2_to_utf16be(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt,
30184684ddb6SLionel Sambuc                 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
30194684ddb6SLionel Sambuc                 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
30204684ddb6SLionel Sambuc {
30214684ddb6SLionel Sambuc     frm_nxt = frm;
30224684ddb6SLionel Sambuc     to_nxt = to;
30234684ddb6SLionel Sambuc     if (mode & generate_header)
30244684ddb6SLionel Sambuc     {
30254684ddb6SLionel Sambuc         if (to_end-to_nxt < 2)
30264684ddb6SLionel Sambuc             return codecvt_base::partial;
30274684ddb6SLionel Sambuc         *to_nxt++ = static_cast<uint8_t>(0xFE);
30284684ddb6SLionel Sambuc         *to_nxt++ = static_cast<uint8_t>(0xFF);
30294684ddb6SLionel Sambuc     }
30304684ddb6SLionel Sambuc     for (; frm_nxt < frm_end; ++frm_nxt)
30314684ddb6SLionel Sambuc     {
30324684ddb6SLionel Sambuc         uint16_t wc = *frm_nxt;
30334684ddb6SLionel Sambuc         if ((wc & 0xF800) == 0xD800 || wc > Maxcode)
30344684ddb6SLionel Sambuc             return codecvt_base::error;
30354684ddb6SLionel Sambuc         if (to_end-to_nxt < 2)
30364684ddb6SLionel Sambuc             return codecvt_base::partial;
30374684ddb6SLionel Sambuc         *to_nxt++ = static_cast<uint8_t>(wc >> 8);
30384684ddb6SLionel Sambuc         *to_nxt++ = static_cast<uint8_t>(wc);
30394684ddb6SLionel Sambuc     }
30404684ddb6SLionel Sambuc     return codecvt_base::ok;
30414684ddb6SLionel Sambuc }
30424684ddb6SLionel Sambuc 
30434684ddb6SLionel Sambuc static
30444684ddb6SLionel Sambuc codecvt_base::result
utf16be_to_ucs2(const uint8_t * frm,const uint8_t * frm_end,const uint8_t * & frm_nxt,uint16_t * to,uint16_t * to_end,uint16_t * & to_nxt,unsigned long Maxcode=0x10FFFF,codecvt_mode mode=codecvt_mode (0))30454684ddb6SLionel Sambuc utf16be_to_ucs2(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
30464684ddb6SLionel Sambuc                 uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt,
30474684ddb6SLionel Sambuc                 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
30484684ddb6SLionel Sambuc {
30494684ddb6SLionel Sambuc     frm_nxt = frm;
30504684ddb6SLionel Sambuc     to_nxt = to;
30514684ddb6SLionel Sambuc     if (mode & consume_header)
30524684ddb6SLionel Sambuc     {
30534684ddb6SLionel Sambuc         if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)
30544684ddb6SLionel Sambuc             frm_nxt += 2;
30554684ddb6SLionel Sambuc     }
30564684ddb6SLionel Sambuc     for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)
30574684ddb6SLionel Sambuc     {
30584684ddb6SLionel Sambuc         uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]);
30594684ddb6SLionel Sambuc         if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
30604684ddb6SLionel Sambuc             return codecvt_base::error;
30614684ddb6SLionel Sambuc         *to_nxt = c1;
30624684ddb6SLionel Sambuc         frm_nxt += 2;
30634684ddb6SLionel Sambuc     }
30644684ddb6SLionel Sambuc     return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
30654684ddb6SLionel Sambuc }
30664684ddb6SLionel Sambuc 
30674684ddb6SLionel Sambuc static
30684684ddb6SLionel Sambuc int
utf16be_to_ucs2_length(const uint8_t * frm,const uint8_t * frm_end,size_t mx,unsigned long Maxcode=0x10FFFF,codecvt_mode mode=codecvt_mode (0))30694684ddb6SLionel Sambuc utf16be_to_ucs2_length(const uint8_t* frm, const uint8_t* frm_end,
30704684ddb6SLionel Sambuc                        size_t mx, unsigned long Maxcode = 0x10FFFF,
30714684ddb6SLionel Sambuc                        codecvt_mode mode = codecvt_mode(0))
30724684ddb6SLionel Sambuc {
30734684ddb6SLionel Sambuc     const uint8_t* frm_nxt = frm;
30744684ddb6SLionel Sambuc     if (mode & consume_header)
30754684ddb6SLionel Sambuc     {
30764684ddb6SLionel Sambuc         if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)
30774684ddb6SLionel Sambuc             frm_nxt += 2;
30784684ddb6SLionel Sambuc     }
30794684ddb6SLionel Sambuc     for (size_t nchar16_t = 0; frm_nxt < frm_end - 1 && nchar16_t < mx; ++nchar16_t)
30804684ddb6SLionel Sambuc     {
30814684ddb6SLionel Sambuc         uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]);
30824684ddb6SLionel Sambuc         if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
30834684ddb6SLionel Sambuc             break;
30844684ddb6SLionel Sambuc         frm_nxt += 2;
30854684ddb6SLionel Sambuc     }
30864684ddb6SLionel Sambuc     return static_cast<int>(frm_nxt - frm);
30874684ddb6SLionel Sambuc }
30884684ddb6SLionel Sambuc 
30894684ddb6SLionel Sambuc static
30904684ddb6SLionel Sambuc codecvt_base::result
ucs2_to_utf16le(const uint16_t * frm,const uint16_t * frm_end,const uint16_t * & frm_nxt,uint8_t * to,uint8_t * to_end,uint8_t * & to_nxt,unsigned long Maxcode=0x10FFFF,codecvt_mode mode=codecvt_mode (0))30914684ddb6SLionel Sambuc ucs2_to_utf16le(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt,
30924684ddb6SLionel Sambuc                 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
30934684ddb6SLionel Sambuc                 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
30944684ddb6SLionel Sambuc {
30954684ddb6SLionel Sambuc     frm_nxt = frm;
30964684ddb6SLionel Sambuc     to_nxt = to;
30974684ddb6SLionel Sambuc     if (mode & generate_header)
30984684ddb6SLionel Sambuc     {
30994684ddb6SLionel Sambuc         if (to_end-to_nxt < 2)
31004684ddb6SLionel Sambuc             return codecvt_base::partial;
31014684ddb6SLionel Sambuc         *to_nxt++ = static_cast<uint8_t>(0xFF);
31024684ddb6SLionel Sambuc         *to_nxt++ = static_cast<uint8_t>(0xFE);
31034684ddb6SLionel Sambuc     }
31044684ddb6SLionel Sambuc     for (; frm_nxt < frm_end; ++frm_nxt)
31054684ddb6SLionel Sambuc     {
31064684ddb6SLionel Sambuc         uint16_t wc = *frm_nxt;
31074684ddb6SLionel Sambuc         if ((wc & 0xF800) == 0xD800 || wc > Maxcode)
31084684ddb6SLionel Sambuc             return codecvt_base::error;
31094684ddb6SLionel Sambuc         if (to_end-to_nxt < 2)
31104684ddb6SLionel Sambuc             return codecvt_base::partial;
31114684ddb6SLionel Sambuc         *to_nxt++ = static_cast<uint8_t>(wc);
31124684ddb6SLionel Sambuc         *to_nxt++ = static_cast<uint8_t>(wc >> 8);
31134684ddb6SLionel Sambuc     }
31144684ddb6SLionel Sambuc     return codecvt_base::ok;
31154684ddb6SLionel Sambuc }
31164684ddb6SLionel Sambuc 
31174684ddb6SLionel Sambuc static
31184684ddb6SLionel Sambuc codecvt_base::result
utf16le_to_ucs2(const uint8_t * frm,const uint8_t * frm_end,const uint8_t * & frm_nxt,uint16_t * to,uint16_t * to_end,uint16_t * & to_nxt,unsigned long Maxcode=0x10FFFF,codecvt_mode mode=codecvt_mode (0))31194684ddb6SLionel Sambuc utf16le_to_ucs2(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
31204684ddb6SLionel Sambuc                 uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt,
31214684ddb6SLionel Sambuc                 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
31224684ddb6SLionel Sambuc {
31234684ddb6SLionel Sambuc     frm_nxt = frm;
31244684ddb6SLionel Sambuc     to_nxt = to;
31254684ddb6SLionel Sambuc     if (mode & consume_header)
31264684ddb6SLionel Sambuc     {
31274684ddb6SLionel Sambuc         if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)
31284684ddb6SLionel Sambuc             frm_nxt += 2;
31294684ddb6SLionel Sambuc     }
31304684ddb6SLionel Sambuc     for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)
31314684ddb6SLionel Sambuc     {
31324684ddb6SLionel Sambuc         uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]);
31334684ddb6SLionel Sambuc         if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
31344684ddb6SLionel Sambuc             return codecvt_base::error;
31354684ddb6SLionel Sambuc         *to_nxt = c1;
31364684ddb6SLionel Sambuc         frm_nxt += 2;
31374684ddb6SLionel Sambuc     }
31384684ddb6SLionel Sambuc     return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
31394684ddb6SLionel Sambuc }
31404684ddb6SLionel Sambuc 
31414684ddb6SLionel Sambuc static
31424684ddb6SLionel Sambuc int
utf16le_to_ucs2_length(const uint8_t * frm,const uint8_t * frm_end,size_t mx,unsigned long Maxcode=0x10FFFF,codecvt_mode mode=codecvt_mode (0))31434684ddb6SLionel Sambuc utf16le_to_ucs2_length(const uint8_t* frm, const uint8_t* frm_end,
31444684ddb6SLionel Sambuc                        size_t mx, unsigned long Maxcode = 0x10FFFF,
31454684ddb6SLionel Sambuc                        codecvt_mode mode = codecvt_mode(0))
31464684ddb6SLionel Sambuc {
31474684ddb6SLionel Sambuc     const uint8_t* frm_nxt = frm;
31484684ddb6SLionel Sambuc     frm_nxt = frm;
31494684ddb6SLionel Sambuc     if (mode & consume_header)
31504684ddb6SLionel Sambuc     {
31514684ddb6SLionel Sambuc         if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)
31524684ddb6SLionel Sambuc             frm_nxt += 2;
31534684ddb6SLionel Sambuc     }
31544684ddb6SLionel Sambuc     for (size_t nchar16_t = 0; frm_nxt < frm_end - 1 && nchar16_t < mx; ++nchar16_t)
31554684ddb6SLionel Sambuc     {
31564684ddb6SLionel Sambuc         uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]);
31574684ddb6SLionel Sambuc         if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
31584684ddb6SLionel Sambuc             break;
31594684ddb6SLionel Sambuc         frm_nxt += 2;
31604684ddb6SLionel Sambuc     }
31614684ddb6SLionel Sambuc     return static_cast<int>(frm_nxt - frm);
31624684ddb6SLionel Sambuc }
31634684ddb6SLionel Sambuc 
31644684ddb6SLionel Sambuc // template <> class codecvt<char16_t, char, mbstate_t>
31654684ddb6SLionel Sambuc 
31664684ddb6SLionel Sambuc locale::id codecvt<char16_t, char, mbstate_t>::id;
31674684ddb6SLionel Sambuc 
~codecvt()31684684ddb6SLionel Sambuc codecvt<char16_t, char, mbstate_t>::~codecvt()
31694684ddb6SLionel Sambuc {
31704684ddb6SLionel Sambuc }
31714684ddb6SLionel Sambuc 
31724684ddb6SLionel Sambuc codecvt<char16_t, char, mbstate_t>::result
do_out(state_type &,const intern_type * frm,const intern_type * frm_end,const intern_type * & frm_nxt,extern_type * to,extern_type * to_end,extern_type * & to_nxt) const31734684ddb6SLionel Sambuc codecvt<char16_t, char, mbstate_t>::do_out(state_type&,
31744684ddb6SLionel Sambuc     const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
31754684ddb6SLionel Sambuc     extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
31764684ddb6SLionel Sambuc {
31774684ddb6SLionel Sambuc     const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
31784684ddb6SLionel Sambuc     const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
31794684ddb6SLionel Sambuc     const uint16_t* _frm_nxt = _frm;
31804684ddb6SLionel Sambuc     uint8_t* _to = reinterpret_cast<uint8_t*>(to);
31814684ddb6SLionel Sambuc     uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
31824684ddb6SLionel Sambuc     uint8_t* _to_nxt = _to;
31834684ddb6SLionel Sambuc     result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
31844684ddb6SLionel Sambuc     frm_nxt = frm + (_frm_nxt - _frm);
31854684ddb6SLionel Sambuc     to_nxt = to + (_to_nxt - _to);
31864684ddb6SLionel Sambuc     return r;
31874684ddb6SLionel Sambuc }
31884684ddb6SLionel Sambuc 
31894684ddb6SLionel Sambuc codecvt<char16_t, char, mbstate_t>::result
do_in(state_type &,const extern_type * frm,const extern_type * frm_end,const extern_type * & frm_nxt,intern_type * to,intern_type * to_end,intern_type * & to_nxt) const31904684ddb6SLionel Sambuc codecvt<char16_t, char, mbstate_t>::do_in(state_type&,
31914684ddb6SLionel Sambuc     const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
31924684ddb6SLionel Sambuc     intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
31934684ddb6SLionel Sambuc {
31944684ddb6SLionel Sambuc     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
31954684ddb6SLionel Sambuc     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
31964684ddb6SLionel Sambuc     const uint8_t* _frm_nxt = _frm;
31974684ddb6SLionel Sambuc     uint16_t* _to = reinterpret_cast<uint16_t*>(to);
31984684ddb6SLionel Sambuc     uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
31994684ddb6SLionel Sambuc     uint16_t* _to_nxt = _to;
32004684ddb6SLionel Sambuc     result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
32014684ddb6SLionel Sambuc     frm_nxt = frm + (_frm_nxt - _frm);
32024684ddb6SLionel Sambuc     to_nxt = to + (_to_nxt - _to);
32034684ddb6SLionel Sambuc     return r;
32044684ddb6SLionel Sambuc }
32054684ddb6SLionel Sambuc 
32064684ddb6SLionel Sambuc codecvt<char16_t, char, mbstate_t>::result
do_unshift(state_type &,extern_type * to,extern_type *,extern_type * & to_nxt) const32074684ddb6SLionel Sambuc codecvt<char16_t, char, mbstate_t>::do_unshift(state_type&,
32084684ddb6SLionel Sambuc     extern_type* to, extern_type*, extern_type*& to_nxt) const
32094684ddb6SLionel Sambuc {
32104684ddb6SLionel Sambuc     to_nxt = to;
32114684ddb6SLionel Sambuc     return noconv;
32124684ddb6SLionel Sambuc }
32134684ddb6SLionel Sambuc 
32144684ddb6SLionel Sambuc int
do_encoding() const32154684ddb6SLionel Sambuc codecvt<char16_t, char, mbstate_t>::do_encoding() const  _NOEXCEPT
32164684ddb6SLionel Sambuc {
32174684ddb6SLionel Sambuc     return 0;
32184684ddb6SLionel Sambuc }
32194684ddb6SLionel Sambuc 
32204684ddb6SLionel Sambuc bool
do_always_noconv() const32214684ddb6SLionel Sambuc codecvt<char16_t, char, mbstate_t>::do_always_noconv() const  _NOEXCEPT
32224684ddb6SLionel Sambuc {
32234684ddb6SLionel Sambuc     return false;
32244684ddb6SLionel Sambuc }
32254684ddb6SLionel Sambuc 
32264684ddb6SLionel Sambuc int
do_length(state_type &,const extern_type * frm,const extern_type * frm_end,size_t mx) const32274684ddb6SLionel Sambuc codecvt<char16_t, char, mbstate_t>::do_length(state_type&,
32284684ddb6SLionel Sambuc     const extern_type* frm, const extern_type* frm_end, size_t mx) const
32294684ddb6SLionel Sambuc {
32304684ddb6SLionel Sambuc     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
32314684ddb6SLionel Sambuc     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
32324684ddb6SLionel Sambuc     return utf8_to_utf16_length(_frm, _frm_end, mx);
32334684ddb6SLionel Sambuc }
32344684ddb6SLionel Sambuc 
32354684ddb6SLionel Sambuc int
do_max_length() const32364684ddb6SLionel Sambuc codecvt<char16_t, char, mbstate_t>::do_max_length() const  _NOEXCEPT
32374684ddb6SLionel Sambuc {
32384684ddb6SLionel Sambuc     return 4;
32394684ddb6SLionel Sambuc }
32404684ddb6SLionel Sambuc 
32414684ddb6SLionel Sambuc // template <> class codecvt<char32_t, char, mbstate_t>
32424684ddb6SLionel Sambuc 
32434684ddb6SLionel Sambuc locale::id codecvt<char32_t, char, mbstate_t>::id;
32444684ddb6SLionel Sambuc 
~codecvt()32454684ddb6SLionel Sambuc codecvt<char32_t, char, mbstate_t>::~codecvt()
32464684ddb6SLionel Sambuc {
32474684ddb6SLionel Sambuc }
32484684ddb6SLionel Sambuc 
32494684ddb6SLionel Sambuc codecvt<char32_t, char, mbstate_t>::result
do_out(state_type &,const intern_type * frm,const intern_type * frm_end,const intern_type * & frm_nxt,extern_type * to,extern_type * to_end,extern_type * & to_nxt) const32504684ddb6SLionel Sambuc codecvt<char32_t, char, mbstate_t>::do_out(state_type&,
32514684ddb6SLionel Sambuc     const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
32524684ddb6SLionel Sambuc     extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
32534684ddb6SLionel Sambuc {
32544684ddb6SLionel Sambuc     const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
32554684ddb6SLionel Sambuc     const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
32564684ddb6SLionel Sambuc     const uint32_t* _frm_nxt = _frm;
32574684ddb6SLionel Sambuc     uint8_t* _to = reinterpret_cast<uint8_t*>(to);
32584684ddb6SLionel Sambuc     uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
32594684ddb6SLionel Sambuc     uint8_t* _to_nxt = _to;
32604684ddb6SLionel Sambuc     result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
32614684ddb6SLionel Sambuc     frm_nxt = frm + (_frm_nxt - _frm);
32624684ddb6SLionel Sambuc     to_nxt = to + (_to_nxt - _to);
32634684ddb6SLionel Sambuc     return r;
32644684ddb6SLionel Sambuc }
32654684ddb6SLionel Sambuc 
32664684ddb6SLionel Sambuc codecvt<char32_t, char, mbstate_t>::result
do_in(state_type &,const extern_type * frm,const extern_type * frm_end,const extern_type * & frm_nxt,intern_type * to,intern_type * to_end,intern_type * & to_nxt) const32674684ddb6SLionel Sambuc codecvt<char32_t, char, mbstate_t>::do_in(state_type&,
32684684ddb6SLionel Sambuc     const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
32694684ddb6SLionel Sambuc     intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
32704684ddb6SLionel Sambuc {
32714684ddb6SLionel Sambuc     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
32724684ddb6SLionel Sambuc     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
32734684ddb6SLionel Sambuc     const uint8_t* _frm_nxt = _frm;
32744684ddb6SLionel Sambuc     uint32_t* _to = reinterpret_cast<uint32_t*>(to);
32754684ddb6SLionel Sambuc     uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
32764684ddb6SLionel Sambuc     uint32_t* _to_nxt = _to;
32774684ddb6SLionel Sambuc     result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
32784684ddb6SLionel Sambuc     frm_nxt = frm + (_frm_nxt - _frm);
32794684ddb6SLionel Sambuc     to_nxt = to + (_to_nxt - _to);
32804684ddb6SLionel Sambuc     return r;
32814684ddb6SLionel Sambuc }
32824684ddb6SLionel Sambuc 
32834684ddb6SLionel Sambuc codecvt<char32_t, char, mbstate_t>::result
do_unshift(state_type &,extern_type * to,extern_type *,extern_type * & to_nxt) const32844684ddb6SLionel Sambuc codecvt<char32_t, char, mbstate_t>::do_unshift(state_type&,
32854684ddb6SLionel Sambuc     extern_type* to, extern_type*, extern_type*& to_nxt) const
32864684ddb6SLionel Sambuc {
32874684ddb6SLionel Sambuc     to_nxt = to;
32884684ddb6SLionel Sambuc     return noconv;
32894684ddb6SLionel Sambuc }
32904684ddb6SLionel Sambuc 
32914684ddb6SLionel Sambuc int
do_encoding() const32924684ddb6SLionel Sambuc codecvt<char32_t, char, mbstate_t>::do_encoding() const  _NOEXCEPT
32934684ddb6SLionel Sambuc {
32944684ddb6SLionel Sambuc     return 0;
32954684ddb6SLionel Sambuc }
32964684ddb6SLionel Sambuc 
32974684ddb6SLionel Sambuc bool
do_always_noconv() const32984684ddb6SLionel Sambuc codecvt<char32_t, char, mbstate_t>::do_always_noconv() const  _NOEXCEPT
32994684ddb6SLionel Sambuc {
33004684ddb6SLionel Sambuc     return false;
33014684ddb6SLionel Sambuc }
33024684ddb6SLionel Sambuc 
33034684ddb6SLionel Sambuc int
do_length(state_type &,const extern_type * frm,const extern_type * frm_end,size_t mx) const33044684ddb6SLionel Sambuc codecvt<char32_t, char, mbstate_t>::do_length(state_type&,
33054684ddb6SLionel Sambuc     const extern_type* frm, const extern_type* frm_end, size_t mx) const
33064684ddb6SLionel Sambuc {
33074684ddb6SLionel Sambuc     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
33084684ddb6SLionel Sambuc     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
33094684ddb6SLionel Sambuc     return utf8_to_ucs4_length(_frm, _frm_end, mx);
33104684ddb6SLionel Sambuc }
33114684ddb6SLionel Sambuc 
33124684ddb6SLionel Sambuc int
do_max_length() const33134684ddb6SLionel Sambuc codecvt<char32_t, char, mbstate_t>::do_max_length() const  _NOEXCEPT
33144684ddb6SLionel Sambuc {
33154684ddb6SLionel Sambuc     return 4;
33164684ddb6SLionel Sambuc }
33174684ddb6SLionel Sambuc 
33184684ddb6SLionel Sambuc // __codecvt_utf8<wchar_t>
33194684ddb6SLionel Sambuc 
33204684ddb6SLionel Sambuc __codecvt_utf8<wchar_t>::result
do_out(state_type &,const intern_type * frm,const intern_type * frm_end,const intern_type * & frm_nxt,extern_type * to,extern_type * to_end,extern_type * & to_nxt) const33214684ddb6SLionel Sambuc __codecvt_utf8<wchar_t>::do_out(state_type&,
33224684ddb6SLionel Sambuc     const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
33234684ddb6SLionel Sambuc     extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
33244684ddb6SLionel Sambuc {
33254684ddb6SLionel Sambuc #if _WIN32
33264684ddb6SLionel Sambuc     const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
33274684ddb6SLionel Sambuc     const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
33284684ddb6SLionel Sambuc     const uint16_t* _frm_nxt = _frm;
33294684ddb6SLionel Sambuc #else
33304684ddb6SLionel Sambuc     const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
33314684ddb6SLionel Sambuc     const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
33324684ddb6SLionel Sambuc     const uint32_t* _frm_nxt = _frm;
33334684ddb6SLionel Sambuc #endif
33344684ddb6SLionel Sambuc     uint8_t* _to = reinterpret_cast<uint8_t*>(to);
33354684ddb6SLionel Sambuc     uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
33364684ddb6SLionel Sambuc     uint8_t* _to_nxt = _to;
33374684ddb6SLionel Sambuc #if _WIN32
33384684ddb6SLionel Sambuc     result r = ucs2_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
33394684ddb6SLionel Sambuc                             _Maxcode_, _Mode_);
33404684ddb6SLionel Sambuc #else
33414684ddb6SLionel Sambuc     result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
33424684ddb6SLionel Sambuc                             _Maxcode_, _Mode_);
33434684ddb6SLionel Sambuc #endif
33444684ddb6SLionel Sambuc     frm_nxt = frm + (_frm_nxt - _frm);
33454684ddb6SLionel Sambuc     to_nxt = to + (_to_nxt - _to);
33464684ddb6SLionel Sambuc     return r;
33474684ddb6SLionel Sambuc }
33484684ddb6SLionel Sambuc 
33494684ddb6SLionel Sambuc __codecvt_utf8<wchar_t>::result
do_in(state_type &,const extern_type * frm,const extern_type * frm_end,const extern_type * & frm_nxt,intern_type * to,intern_type * to_end,intern_type * & to_nxt) const33504684ddb6SLionel Sambuc __codecvt_utf8<wchar_t>::do_in(state_type&,
33514684ddb6SLionel Sambuc     const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
33524684ddb6SLionel Sambuc     intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
33534684ddb6SLionel Sambuc {
33544684ddb6SLionel Sambuc     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
33554684ddb6SLionel Sambuc     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
33564684ddb6SLionel Sambuc     const uint8_t* _frm_nxt = _frm;
33574684ddb6SLionel Sambuc #if _WIN32
33584684ddb6SLionel Sambuc     uint16_t* _to = reinterpret_cast<uint16_t*>(to);
33594684ddb6SLionel Sambuc     uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
33604684ddb6SLionel Sambuc     uint16_t* _to_nxt = _to;
33614684ddb6SLionel Sambuc     result r = utf8_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
33624684ddb6SLionel Sambuc                             _Maxcode_, _Mode_);
33634684ddb6SLionel Sambuc #else
33644684ddb6SLionel Sambuc     uint32_t* _to = reinterpret_cast<uint32_t*>(to);
33654684ddb6SLionel Sambuc     uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
33664684ddb6SLionel Sambuc     uint32_t* _to_nxt = _to;
33674684ddb6SLionel Sambuc     result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
33684684ddb6SLionel Sambuc                             _Maxcode_, _Mode_);
33694684ddb6SLionel Sambuc #endif
33704684ddb6SLionel Sambuc     frm_nxt = frm + (_frm_nxt - _frm);
33714684ddb6SLionel Sambuc     to_nxt = to + (_to_nxt - _to);
33724684ddb6SLionel Sambuc     return r;
33734684ddb6SLionel Sambuc }
33744684ddb6SLionel Sambuc 
33754684ddb6SLionel Sambuc __codecvt_utf8<wchar_t>::result
do_unshift(state_type &,extern_type * to,extern_type *,extern_type * & to_nxt) const33764684ddb6SLionel Sambuc __codecvt_utf8<wchar_t>::do_unshift(state_type&,
33774684ddb6SLionel Sambuc     extern_type* to, extern_type*, extern_type*& to_nxt) const
33784684ddb6SLionel Sambuc {
33794684ddb6SLionel Sambuc     to_nxt = to;
33804684ddb6SLionel Sambuc     return noconv;
33814684ddb6SLionel Sambuc }
33824684ddb6SLionel Sambuc 
33834684ddb6SLionel Sambuc int
do_encoding() const33844684ddb6SLionel Sambuc __codecvt_utf8<wchar_t>::do_encoding() const  _NOEXCEPT
33854684ddb6SLionel Sambuc {
33864684ddb6SLionel Sambuc     return 0;
33874684ddb6SLionel Sambuc }
33884684ddb6SLionel Sambuc 
33894684ddb6SLionel Sambuc bool
do_always_noconv() const33904684ddb6SLionel Sambuc __codecvt_utf8<wchar_t>::do_always_noconv() const  _NOEXCEPT
33914684ddb6SLionel Sambuc {
33924684ddb6SLionel Sambuc     return false;
33934684ddb6SLionel Sambuc }
33944684ddb6SLionel Sambuc 
33954684ddb6SLionel Sambuc int
do_length(state_type &,const extern_type * frm,const extern_type * frm_end,size_t mx) const33964684ddb6SLionel Sambuc __codecvt_utf8<wchar_t>::do_length(state_type&,
33974684ddb6SLionel Sambuc     const extern_type* frm, const extern_type* frm_end, size_t mx) const
33984684ddb6SLionel Sambuc {
33994684ddb6SLionel Sambuc     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
34004684ddb6SLionel Sambuc     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
34014684ddb6SLionel Sambuc     return utf8_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
34024684ddb6SLionel Sambuc }
34034684ddb6SLionel Sambuc 
34044684ddb6SLionel Sambuc int
do_max_length() const34054684ddb6SLionel Sambuc __codecvt_utf8<wchar_t>::do_max_length() const  _NOEXCEPT
34064684ddb6SLionel Sambuc {
34074684ddb6SLionel Sambuc     if (_Mode_ & consume_header)
34084684ddb6SLionel Sambuc         return 7;
34094684ddb6SLionel Sambuc     return 4;
34104684ddb6SLionel Sambuc }
34114684ddb6SLionel Sambuc 
34124684ddb6SLionel Sambuc // __codecvt_utf8<char16_t>
34134684ddb6SLionel Sambuc 
34144684ddb6SLionel Sambuc __codecvt_utf8<char16_t>::result
do_out(state_type &,const intern_type * frm,const intern_type * frm_end,const intern_type * & frm_nxt,extern_type * to,extern_type * to_end,extern_type * & to_nxt) const34154684ddb6SLionel Sambuc __codecvt_utf8<char16_t>::do_out(state_type&,
34164684ddb6SLionel Sambuc     const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
34174684ddb6SLionel Sambuc     extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
34184684ddb6SLionel Sambuc {
34194684ddb6SLionel Sambuc     const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
34204684ddb6SLionel Sambuc     const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
34214684ddb6SLionel Sambuc     const uint16_t* _frm_nxt = _frm;
34224684ddb6SLionel Sambuc     uint8_t* _to = reinterpret_cast<uint8_t*>(to);
34234684ddb6SLionel Sambuc     uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
34244684ddb6SLionel Sambuc     uint8_t* _to_nxt = _to;
34254684ddb6SLionel Sambuc     result r = ucs2_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
34264684ddb6SLionel Sambuc                             _Maxcode_, _Mode_);
34274684ddb6SLionel Sambuc     frm_nxt = frm + (_frm_nxt - _frm);
34284684ddb6SLionel Sambuc     to_nxt = to + (_to_nxt - _to);
34294684ddb6SLionel Sambuc     return r;
34304684ddb6SLionel Sambuc }
34314684ddb6SLionel Sambuc 
34324684ddb6SLionel Sambuc __codecvt_utf8<char16_t>::result
do_in(state_type &,const extern_type * frm,const extern_type * frm_end,const extern_type * & frm_nxt,intern_type * to,intern_type * to_end,intern_type * & to_nxt) const34334684ddb6SLionel Sambuc __codecvt_utf8<char16_t>::do_in(state_type&,
34344684ddb6SLionel Sambuc     const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
34354684ddb6SLionel Sambuc     intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
34364684ddb6SLionel Sambuc {
34374684ddb6SLionel Sambuc     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
34384684ddb6SLionel Sambuc     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
34394684ddb6SLionel Sambuc     const uint8_t* _frm_nxt = _frm;
34404684ddb6SLionel Sambuc     uint16_t* _to = reinterpret_cast<uint16_t*>(to);
34414684ddb6SLionel Sambuc     uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
34424684ddb6SLionel Sambuc     uint16_t* _to_nxt = _to;
34434684ddb6SLionel Sambuc     result r = utf8_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
34444684ddb6SLionel Sambuc                             _Maxcode_, _Mode_);
34454684ddb6SLionel Sambuc     frm_nxt = frm + (_frm_nxt - _frm);
34464684ddb6SLionel Sambuc     to_nxt = to + (_to_nxt - _to);
34474684ddb6SLionel Sambuc     return r;
34484684ddb6SLionel Sambuc }
34494684ddb6SLionel Sambuc 
34504684ddb6SLionel Sambuc __codecvt_utf8<char16_t>::result
do_unshift(state_type &,extern_type * to,extern_type *,extern_type * & to_nxt) const34514684ddb6SLionel Sambuc __codecvt_utf8<char16_t>::do_unshift(state_type&,
34524684ddb6SLionel Sambuc     extern_type* to, extern_type*, extern_type*& to_nxt) const
34534684ddb6SLionel Sambuc {
34544684ddb6SLionel Sambuc     to_nxt = to;
34554684ddb6SLionel Sambuc     return noconv;
34564684ddb6SLionel Sambuc }
34574684ddb6SLionel Sambuc 
34584684ddb6SLionel Sambuc int
do_encoding() const34594684ddb6SLionel Sambuc __codecvt_utf8<char16_t>::do_encoding() const  _NOEXCEPT
34604684ddb6SLionel Sambuc {
34614684ddb6SLionel Sambuc     return 0;
34624684ddb6SLionel Sambuc }
34634684ddb6SLionel Sambuc 
34644684ddb6SLionel Sambuc bool
do_always_noconv() const34654684ddb6SLionel Sambuc __codecvt_utf8<char16_t>::do_always_noconv() const  _NOEXCEPT
34664684ddb6SLionel Sambuc {
34674684ddb6SLionel Sambuc     return false;
34684684ddb6SLionel Sambuc }
34694684ddb6SLionel Sambuc 
34704684ddb6SLionel Sambuc int
do_length(state_type &,const extern_type * frm,const extern_type * frm_end,size_t mx) const34714684ddb6SLionel Sambuc __codecvt_utf8<char16_t>::do_length(state_type&,
34724684ddb6SLionel Sambuc     const extern_type* frm, const extern_type* frm_end, size_t mx) const
34734684ddb6SLionel Sambuc {
34744684ddb6SLionel Sambuc     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
34754684ddb6SLionel Sambuc     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
34764684ddb6SLionel Sambuc     return utf8_to_ucs2_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
34774684ddb6SLionel Sambuc }
34784684ddb6SLionel Sambuc 
34794684ddb6SLionel Sambuc int
do_max_length() const34804684ddb6SLionel Sambuc __codecvt_utf8<char16_t>::do_max_length() const  _NOEXCEPT
34814684ddb6SLionel Sambuc {
34824684ddb6SLionel Sambuc     if (_Mode_ & consume_header)
34834684ddb6SLionel Sambuc         return 6;
34844684ddb6SLionel Sambuc     return 3;
34854684ddb6SLionel Sambuc }
34864684ddb6SLionel Sambuc 
34874684ddb6SLionel Sambuc // __codecvt_utf8<char32_t>
34884684ddb6SLionel Sambuc 
34894684ddb6SLionel Sambuc __codecvt_utf8<char32_t>::result
do_out(state_type &,const intern_type * frm,const intern_type * frm_end,const intern_type * & frm_nxt,extern_type * to,extern_type * to_end,extern_type * & to_nxt) const34904684ddb6SLionel Sambuc __codecvt_utf8<char32_t>::do_out(state_type&,
34914684ddb6SLionel Sambuc     const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
34924684ddb6SLionel Sambuc     extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
34934684ddb6SLionel Sambuc {
34944684ddb6SLionel Sambuc     const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
34954684ddb6SLionel Sambuc     const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
34964684ddb6SLionel Sambuc     const uint32_t* _frm_nxt = _frm;
34974684ddb6SLionel Sambuc     uint8_t* _to = reinterpret_cast<uint8_t*>(to);
34984684ddb6SLionel Sambuc     uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
34994684ddb6SLionel Sambuc     uint8_t* _to_nxt = _to;
35004684ddb6SLionel Sambuc     result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
35014684ddb6SLionel Sambuc                             _Maxcode_, _Mode_);
35024684ddb6SLionel Sambuc     frm_nxt = frm + (_frm_nxt - _frm);
35034684ddb6SLionel Sambuc     to_nxt = to + (_to_nxt - _to);
35044684ddb6SLionel Sambuc     return r;
35054684ddb6SLionel Sambuc }
35064684ddb6SLionel Sambuc 
35074684ddb6SLionel Sambuc __codecvt_utf8<char32_t>::result
do_in(state_type &,const extern_type * frm,const extern_type * frm_end,const extern_type * & frm_nxt,intern_type * to,intern_type * to_end,intern_type * & to_nxt) const35084684ddb6SLionel Sambuc __codecvt_utf8<char32_t>::do_in(state_type&,
35094684ddb6SLionel Sambuc     const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
35104684ddb6SLionel Sambuc     intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
35114684ddb6SLionel Sambuc {
35124684ddb6SLionel Sambuc     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
35134684ddb6SLionel Sambuc     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
35144684ddb6SLionel Sambuc     const uint8_t* _frm_nxt = _frm;
35154684ddb6SLionel Sambuc     uint32_t* _to = reinterpret_cast<uint32_t*>(to);
35164684ddb6SLionel Sambuc     uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
35174684ddb6SLionel Sambuc     uint32_t* _to_nxt = _to;
35184684ddb6SLionel Sambuc     result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
35194684ddb6SLionel Sambuc                             _Maxcode_, _Mode_);
35204684ddb6SLionel Sambuc     frm_nxt = frm + (_frm_nxt - _frm);
35214684ddb6SLionel Sambuc     to_nxt = to + (_to_nxt - _to);
35224684ddb6SLionel Sambuc     return r;
35234684ddb6SLionel Sambuc }
35244684ddb6SLionel Sambuc 
35254684ddb6SLionel Sambuc __codecvt_utf8<char32_t>::result
do_unshift(state_type &,extern_type * to,extern_type *,extern_type * & to_nxt) const35264684ddb6SLionel Sambuc __codecvt_utf8<char32_t>::do_unshift(state_type&,
35274684ddb6SLionel Sambuc     extern_type* to, extern_type*, extern_type*& to_nxt) const
35284684ddb6SLionel Sambuc {
35294684ddb6SLionel Sambuc     to_nxt = to;
35304684ddb6SLionel Sambuc     return noconv;
35314684ddb6SLionel Sambuc }
35324684ddb6SLionel Sambuc 
35334684ddb6SLionel Sambuc int
do_encoding() const35344684ddb6SLionel Sambuc __codecvt_utf8<char32_t>::do_encoding() const  _NOEXCEPT
35354684ddb6SLionel Sambuc {
35364684ddb6SLionel Sambuc     return 0;
35374684ddb6SLionel Sambuc }
35384684ddb6SLionel Sambuc 
35394684ddb6SLionel Sambuc bool
do_always_noconv() const35404684ddb6SLionel Sambuc __codecvt_utf8<char32_t>::do_always_noconv() const  _NOEXCEPT
35414684ddb6SLionel Sambuc {
35424684ddb6SLionel Sambuc     return false;
35434684ddb6SLionel Sambuc }
35444684ddb6SLionel Sambuc 
35454684ddb6SLionel Sambuc int
do_length(state_type &,const extern_type * frm,const extern_type * frm_end,size_t mx) const35464684ddb6SLionel Sambuc __codecvt_utf8<char32_t>::do_length(state_type&,
35474684ddb6SLionel Sambuc     const extern_type* frm, const extern_type* frm_end, size_t mx) const
35484684ddb6SLionel Sambuc {
35494684ddb6SLionel Sambuc     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
35504684ddb6SLionel Sambuc     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
35514684ddb6SLionel Sambuc     return utf8_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
35524684ddb6SLionel Sambuc }
35534684ddb6SLionel Sambuc 
35544684ddb6SLionel Sambuc int
do_max_length() const35554684ddb6SLionel Sambuc __codecvt_utf8<char32_t>::do_max_length() const  _NOEXCEPT
35564684ddb6SLionel Sambuc {
35574684ddb6SLionel Sambuc     if (_Mode_ & consume_header)
35584684ddb6SLionel Sambuc         return 7;
35594684ddb6SLionel Sambuc     return 4;
35604684ddb6SLionel Sambuc }
35614684ddb6SLionel Sambuc 
35624684ddb6SLionel Sambuc // __codecvt_utf16<wchar_t, false>
35634684ddb6SLionel Sambuc 
35644684ddb6SLionel Sambuc __codecvt_utf16<wchar_t, false>::result
do_out(state_type &,const intern_type * frm,const intern_type * frm_end,const intern_type * & frm_nxt,extern_type * to,extern_type * to_end,extern_type * & to_nxt) const35654684ddb6SLionel Sambuc __codecvt_utf16<wchar_t, false>::do_out(state_type&,
35664684ddb6SLionel Sambuc     const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
35674684ddb6SLionel Sambuc     extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
35684684ddb6SLionel Sambuc {
35694684ddb6SLionel Sambuc     const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
35704684ddb6SLionel Sambuc     const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
35714684ddb6SLionel Sambuc     const uint32_t* _frm_nxt = _frm;
35724684ddb6SLionel Sambuc     uint8_t* _to = reinterpret_cast<uint8_t*>(to);
35734684ddb6SLionel Sambuc     uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
35744684ddb6SLionel Sambuc     uint8_t* _to_nxt = _to;
35754684ddb6SLionel Sambuc     result r = ucs4_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
35764684ddb6SLionel Sambuc                                _Maxcode_, _Mode_);
35774684ddb6SLionel Sambuc     frm_nxt = frm + (_frm_nxt - _frm);
35784684ddb6SLionel Sambuc     to_nxt = to + (_to_nxt - _to);
35794684ddb6SLionel Sambuc     return r;
35804684ddb6SLionel Sambuc }
35814684ddb6SLionel Sambuc 
35824684ddb6SLionel Sambuc __codecvt_utf16<wchar_t, false>::result
do_in(state_type &,const extern_type * frm,const extern_type * frm_end,const extern_type * & frm_nxt,intern_type * to,intern_type * to_end,intern_type * & to_nxt) const35834684ddb6SLionel Sambuc __codecvt_utf16<wchar_t, false>::do_in(state_type&,
35844684ddb6SLionel Sambuc     const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
35854684ddb6SLionel Sambuc     intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
35864684ddb6SLionel Sambuc {
35874684ddb6SLionel Sambuc     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
35884684ddb6SLionel Sambuc     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
35894684ddb6SLionel Sambuc     const uint8_t* _frm_nxt = _frm;
35904684ddb6SLionel Sambuc     uint32_t* _to = reinterpret_cast<uint32_t*>(to);
35914684ddb6SLionel Sambuc     uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
35924684ddb6SLionel Sambuc     uint32_t* _to_nxt = _to;
35934684ddb6SLionel Sambuc     result r = utf16be_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
35944684ddb6SLionel Sambuc                                _Maxcode_, _Mode_);
35954684ddb6SLionel Sambuc     frm_nxt = frm + (_frm_nxt - _frm);
35964684ddb6SLionel Sambuc     to_nxt = to + (_to_nxt - _to);
35974684ddb6SLionel Sambuc     return r;
35984684ddb6SLionel Sambuc }
35994684ddb6SLionel Sambuc 
36004684ddb6SLionel Sambuc __codecvt_utf16<wchar_t, false>::result
do_unshift(state_type &,extern_type * to,extern_type *,extern_type * & to_nxt) const36014684ddb6SLionel Sambuc __codecvt_utf16<wchar_t, false>::do_unshift(state_type&,
36024684ddb6SLionel Sambuc     extern_type* to, extern_type*, extern_type*& to_nxt) const
36034684ddb6SLionel Sambuc {
36044684ddb6SLionel Sambuc     to_nxt = to;
36054684ddb6SLionel Sambuc     return noconv;
36064684ddb6SLionel Sambuc }
36074684ddb6SLionel Sambuc 
36084684ddb6SLionel Sambuc int
do_encoding() const36094684ddb6SLionel Sambuc __codecvt_utf16<wchar_t, false>::do_encoding() const  _NOEXCEPT
36104684ddb6SLionel Sambuc {
36114684ddb6SLionel Sambuc     return 0;
36124684ddb6SLionel Sambuc }
36134684ddb6SLionel Sambuc 
36144684ddb6SLionel Sambuc bool
do_always_noconv() const36154684ddb6SLionel Sambuc __codecvt_utf16<wchar_t, false>::do_always_noconv() const  _NOEXCEPT
36164684ddb6SLionel Sambuc {
36174684ddb6SLionel Sambuc     return false;
36184684ddb6SLionel Sambuc }
36194684ddb6SLionel Sambuc 
36204684ddb6SLionel Sambuc int
do_length(state_type &,const extern_type * frm,const extern_type * frm_end,size_t mx) const36214684ddb6SLionel Sambuc __codecvt_utf16<wchar_t, false>::do_length(state_type&,
36224684ddb6SLionel Sambuc     const extern_type* frm, const extern_type* frm_end, size_t mx) const
36234684ddb6SLionel Sambuc {
36244684ddb6SLionel Sambuc     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
36254684ddb6SLionel Sambuc     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
36264684ddb6SLionel Sambuc     return utf16be_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
36274684ddb6SLionel Sambuc }
36284684ddb6SLionel Sambuc 
36294684ddb6SLionel Sambuc int
do_max_length() const36304684ddb6SLionel Sambuc __codecvt_utf16<wchar_t, false>::do_max_length() const  _NOEXCEPT
36314684ddb6SLionel Sambuc {
36324684ddb6SLionel Sambuc     if (_Mode_ & consume_header)
36334684ddb6SLionel Sambuc         return 6;
36344684ddb6SLionel Sambuc     return 4;
36354684ddb6SLionel Sambuc }
36364684ddb6SLionel Sambuc 
36374684ddb6SLionel Sambuc // __codecvt_utf16<wchar_t, true>
36384684ddb6SLionel Sambuc 
36394684ddb6SLionel Sambuc __codecvt_utf16<wchar_t, true>::result
do_out(state_type &,const intern_type * frm,const intern_type * frm_end,const intern_type * & frm_nxt,extern_type * to,extern_type * to_end,extern_type * & to_nxt) const36404684ddb6SLionel Sambuc __codecvt_utf16<wchar_t, true>::do_out(state_type&,
36414684ddb6SLionel Sambuc     const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
36424684ddb6SLionel Sambuc     extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
36434684ddb6SLionel Sambuc {
36444684ddb6SLionel Sambuc     const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
36454684ddb6SLionel Sambuc     const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
36464684ddb6SLionel Sambuc     const uint32_t* _frm_nxt = _frm;
36474684ddb6SLionel Sambuc     uint8_t* _to = reinterpret_cast<uint8_t*>(to);
36484684ddb6SLionel Sambuc     uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
36494684ddb6SLionel Sambuc     uint8_t* _to_nxt = _to;
36504684ddb6SLionel Sambuc     result r = ucs4_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
36514684ddb6SLionel Sambuc                                _Maxcode_, _Mode_);
36524684ddb6SLionel Sambuc     frm_nxt = frm + (_frm_nxt - _frm);
36534684ddb6SLionel Sambuc     to_nxt = to + (_to_nxt - _to);
36544684ddb6SLionel Sambuc     return r;
36554684ddb6SLionel Sambuc }
36564684ddb6SLionel Sambuc 
36574684ddb6SLionel Sambuc __codecvt_utf16<wchar_t, true>::result
do_in(state_type &,const extern_type * frm,const extern_type * frm_end,const extern_type * & frm_nxt,intern_type * to,intern_type * to_end,intern_type * & to_nxt) const36584684ddb6SLionel Sambuc __codecvt_utf16<wchar_t, true>::do_in(state_type&,
36594684ddb6SLionel Sambuc     const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
36604684ddb6SLionel Sambuc     intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
36614684ddb6SLionel Sambuc {
36624684ddb6SLionel Sambuc     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
36634684ddb6SLionel Sambuc     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
36644684ddb6SLionel Sambuc     const uint8_t* _frm_nxt = _frm;
36654684ddb6SLionel Sambuc     uint32_t* _to = reinterpret_cast<uint32_t*>(to);
36664684ddb6SLionel Sambuc     uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
36674684ddb6SLionel Sambuc     uint32_t* _to_nxt = _to;
36684684ddb6SLionel Sambuc     result r = utf16le_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
36694684ddb6SLionel Sambuc                                _Maxcode_, _Mode_);
36704684ddb6SLionel Sambuc     frm_nxt = frm + (_frm_nxt - _frm);
36714684ddb6SLionel Sambuc     to_nxt = to + (_to_nxt - _to);
36724684ddb6SLionel Sambuc     return r;
36734684ddb6SLionel Sambuc }
36744684ddb6SLionel Sambuc 
36754684ddb6SLionel Sambuc __codecvt_utf16<wchar_t, true>::result
do_unshift(state_type &,extern_type * to,extern_type *,extern_type * & to_nxt) const36764684ddb6SLionel Sambuc __codecvt_utf16<wchar_t, true>::do_unshift(state_type&,
36774684ddb6SLionel Sambuc     extern_type* to, extern_type*, extern_type*& to_nxt) const
36784684ddb6SLionel Sambuc {
36794684ddb6SLionel Sambuc     to_nxt = to;
36804684ddb6SLionel Sambuc     return noconv;
36814684ddb6SLionel Sambuc }
36824684ddb6SLionel Sambuc 
36834684ddb6SLionel Sambuc int
do_encoding() const36844684ddb6SLionel Sambuc __codecvt_utf16<wchar_t, true>::do_encoding() const  _NOEXCEPT
36854684ddb6SLionel Sambuc {
36864684ddb6SLionel Sambuc     return 0;
36874684ddb6SLionel Sambuc }
36884684ddb6SLionel Sambuc 
36894684ddb6SLionel Sambuc bool
do_always_noconv() const36904684ddb6SLionel Sambuc __codecvt_utf16<wchar_t, true>::do_always_noconv() const  _NOEXCEPT
36914684ddb6SLionel Sambuc {
36924684ddb6SLionel Sambuc     return false;
36934684ddb6SLionel Sambuc }
36944684ddb6SLionel Sambuc 
36954684ddb6SLionel Sambuc int
do_length(state_type &,const extern_type * frm,const extern_type * frm_end,size_t mx) const36964684ddb6SLionel Sambuc __codecvt_utf16<wchar_t, true>::do_length(state_type&,
36974684ddb6SLionel Sambuc     const extern_type* frm, const extern_type* frm_end, size_t mx) const
36984684ddb6SLionel Sambuc {
36994684ddb6SLionel Sambuc     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
37004684ddb6SLionel Sambuc     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
37014684ddb6SLionel Sambuc     return utf16le_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
37024684ddb6SLionel Sambuc }
37034684ddb6SLionel Sambuc 
37044684ddb6SLionel Sambuc int
do_max_length() const37054684ddb6SLionel Sambuc __codecvt_utf16<wchar_t, true>::do_max_length() const  _NOEXCEPT
37064684ddb6SLionel Sambuc {
37074684ddb6SLionel Sambuc     if (_Mode_ & consume_header)
37084684ddb6SLionel Sambuc         return 6;
37094684ddb6SLionel Sambuc     return 4;
37104684ddb6SLionel Sambuc }
37114684ddb6SLionel Sambuc 
37124684ddb6SLionel Sambuc // __codecvt_utf16<char16_t, false>
37134684ddb6SLionel Sambuc 
37144684ddb6SLionel Sambuc __codecvt_utf16<char16_t, false>::result
do_out(state_type &,const intern_type * frm,const intern_type * frm_end,const intern_type * & frm_nxt,extern_type * to,extern_type * to_end,extern_type * & to_nxt) const37154684ddb6SLionel Sambuc __codecvt_utf16<char16_t, false>::do_out(state_type&,
37164684ddb6SLionel Sambuc     const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
37174684ddb6SLionel Sambuc     extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
37184684ddb6SLionel Sambuc {
37194684ddb6SLionel Sambuc     const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
37204684ddb6SLionel Sambuc     const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
37214684ddb6SLionel Sambuc     const uint16_t* _frm_nxt = _frm;
37224684ddb6SLionel Sambuc     uint8_t* _to = reinterpret_cast<uint8_t*>(to);
37234684ddb6SLionel Sambuc     uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
37244684ddb6SLionel Sambuc     uint8_t* _to_nxt = _to;
37254684ddb6SLionel Sambuc     result r = ucs2_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
37264684ddb6SLionel Sambuc                                _Maxcode_, _Mode_);
37274684ddb6SLionel Sambuc     frm_nxt = frm + (_frm_nxt - _frm);
37284684ddb6SLionel Sambuc     to_nxt = to + (_to_nxt - _to);
37294684ddb6SLionel Sambuc     return r;
37304684ddb6SLionel Sambuc }
37314684ddb6SLionel Sambuc 
37324684ddb6SLionel Sambuc __codecvt_utf16<char16_t, false>::result
do_in(state_type &,const extern_type * frm,const extern_type * frm_end,const extern_type * & frm_nxt,intern_type * to,intern_type * to_end,intern_type * & to_nxt) const37334684ddb6SLionel Sambuc __codecvt_utf16<char16_t, false>::do_in(state_type&,
37344684ddb6SLionel Sambuc     const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
37354684ddb6SLionel Sambuc     intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
37364684ddb6SLionel Sambuc {
37374684ddb6SLionel Sambuc     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
37384684ddb6SLionel Sambuc     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
37394684ddb6SLionel Sambuc     const uint8_t* _frm_nxt = _frm;
37404684ddb6SLionel Sambuc     uint16_t* _to = reinterpret_cast<uint16_t*>(to);
37414684ddb6SLionel Sambuc     uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
37424684ddb6SLionel Sambuc     uint16_t* _to_nxt = _to;
37434684ddb6SLionel Sambuc     result r = utf16be_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
37444684ddb6SLionel Sambuc                                _Maxcode_, _Mode_);
37454684ddb6SLionel Sambuc     frm_nxt = frm + (_frm_nxt - _frm);
37464684ddb6SLionel Sambuc     to_nxt = to + (_to_nxt - _to);
37474684ddb6SLionel Sambuc     return r;
37484684ddb6SLionel Sambuc }
37494684ddb6SLionel Sambuc 
37504684ddb6SLionel Sambuc __codecvt_utf16<char16_t, false>::result
do_unshift(state_type &,extern_type * to,extern_type *,extern_type * & to_nxt) const37514684ddb6SLionel Sambuc __codecvt_utf16<char16_t, false>::do_unshift(state_type&,
37524684ddb6SLionel Sambuc     extern_type* to, extern_type*, extern_type*& to_nxt) const
37534684ddb6SLionel Sambuc {
37544684ddb6SLionel Sambuc     to_nxt = to;
37554684ddb6SLionel Sambuc     return noconv;
37564684ddb6SLionel Sambuc }
37574684ddb6SLionel Sambuc 
37584684ddb6SLionel Sambuc int
do_encoding() const37594684ddb6SLionel Sambuc __codecvt_utf16<char16_t, false>::do_encoding() const  _NOEXCEPT
37604684ddb6SLionel Sambuc {
37614684ddb6SLionel Sambuc     return 0;
37624684ddb6SLionel Sambuc }
37634684ddb6SLionel Sambuc 
37644684ddb6SLionel Sambuc bool
do_always_noconv() const37654684ddb6SLionel Sambuc __codecvt_utf16<char16_t, false>::do_always_noconv() const  _NOEXCEPT
37664684ddb6SLionel Sambuc {
37674684ddb6SLionel Sambuc     return false;
37684684ddb6SLionel Sambuc }
37694684ddb6SLionel Sambuc 
37704684ddb6SLionel Sambuc int
do_length(state_type &,const extern_type * frm,const extern_type * frm_end,size_t mx) const37714684ddb6SLionel Sambuc __codecvt_utf16<char16_t, false>::do_length(state_type&,
37724684ddb6SLionel Sambuc     const extern_type* frm, const extern_type* frm_end, size_t mx) const
37734684ddb6SLionel Sambuc {
37744684ddb6SLionel Sambuc     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
37754684ddb6SLionel Sambuc     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
37764684ddb6SLionel Sambuc     return utf16be_to_ucs2_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
37774684ddb6SLionel Sambuc }
37784684ddb6SLionel Sambuc 
37794684ddb6SLionel Sambuc int
do_max_length() const37804684ddb6SLionel Sambuc __codecvt_utf16<char16_t, false>::do_max_length() const  _NOEXCEPT
37814684ddb6SLionel Sambuc {
37824684ddb6SLionel Sambuc     if (_Mode_ & consume_header)
37834684ddb6SLionel Sambuc         return 4;
37844684ddb6SLionel Sambuc     return 2;
37854684ddb6SLionel Sambuc }
37864684ddb6SLionel Sambuc 
37874684ddb6SLionel Sambuc // __codecvt_utf16<char16_t, true>
37884684ddb6SLionel Sambuc 
37894684ddb6SLionel Sambuc __codecvt_utf16<char16_t, true>::result
do_out(state_type &,const intern_type * frm,const intern_type * frm_end,const intern_type * & frm_nxt,extern_type * to,extern_type * to_end,extern_type * & to_nxt) const37904684ddb6SLionel Sambuc __codecvt_utf16<char16_t, true>::do_out(state_type&,
37914684ddb6SLionel Sambuc     const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
37924684ddb6SLionel Sambuc     extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
37934684ddb6SLionel Sambuc {
37944684ddb6SLionel Sambuc     const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
37954684ddb6SLionel Sambuc     const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
37964684ddb6SLionel Sambuc     const uint16_t* _frm_nxt = _frm;
37974684ddb6SLionel Sambuc     uint8_t* _to = reinterpret_cast<uint8_t*>(to);
37984684ddb6SLionel Sambuc     uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
37994684ddb6SLionel Sambuc     uint8_t* _to_nxt = _to;
38004684ddb6SLionel Sambuc     result r = ucs2_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
38014684ddb6SLionel Sambuc                                _Maxcode_, _Mode_);
38024684ddb6SLionel Sambuc     frm_nxt = frm + (_frm_nxt - _frm);
38034684ddb6SLionel Sambuc     to_nxt = to + (_to_nxt - _to);
38044684ddb6SLionel Sambuc     return r;
38054684ddb6SLionel Sambuc }
38064684ddb6SLionel Sambuc 
38074684ddb6SLionel Sambuc __codecvt_utf16<char16_t, true>::result
do_in(state_type &,const extern_type * frm,const extern_type * frm_end,const extern_type * & frm_nxt,intern_type * to,intern_type * to_end,intern_type * & to_nxt) const38084684ddb6SLionel Sambuc __codecvt_utf16<char16_t, true>::do_in(state_type&,
38094684ddb6SLionel Sambuc     const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
38104684ddb6SLionel Sambuc     intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
38114684ddb6SLionel Sambuc {
38124684ddb6SLionel Sambuc     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
38134684ddb6SLionel Sambuc     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
38144684ddb6SLionel Sambuc     const uint8_t* _frm_nxt = _frm;
38154684ddb6SLionel Sambuc     uint16_t* _to = reinterpret_cast<uint16_t*>(to);
38164684ddb6SLionel Sambuc     uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
38174684ddb6SLionel Sambuc     uint16_t* _to_nxt = _to;
38184684ddb6SLionel Sambuc     result r = utf16le_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
38194684ddb6SLionel Sambuc                                _Maxcode_, _Mode_);
38204684ddb6SLionel Sambuc     frm_nxt = frm + (_frm_nxt - _frm);
38214684ddb6SLionel Sambuc     to_nxt = to + (_to_nxt - _to);
38224684ddb6SLionel Sambuc     return r;
38234684ddb6SLionel Sambuc }
38244684ddb6SLionel Sambuc 
38254684ddb6SLionel Sambuc __codecvt_utf16<char16_t, true>::result
do_unshift(state_type &,extern_type * to,extern_type *,extern_type * & to_nxt) const38264684ddb6SLionel Sambuc __codecvt_utf16<char16_t, true>::do_unshift(state_type&,
38274684ddb6SLionel Sambuc     extern_type* to, extern_type*, extern_type*& to_nxt) const
38284684ddb6SLionel Sambuc {
38294684ddb6SLionel Sambuc     to_nxt = to;
38304684ddb6SLionel Sambuc     return noconv;
38314684ddb6SLionel Sambuc }
38324684ddb6SLionel Sambuc 
38334684ddb6SLionel Sambuc int
do_encoding() const38344684ddb6SLionel Sambuc __codecvt_utf16<char16_t, true>::do_encoding() const  _NOEXCEPT
38354684ddb6SLionel Sambuc {
38364684ddb6SLionel Sambuc     return 0;
38374684ddb6SLionel Sambuc }
38384684ddb6SLionel Sambuc 
38394684ddb6SLionel Sambuc bool
do_always_noconv() const38404684ddb6SLionel Sambuc __codecvt_utf16<char16_t, true>::do_always_noconv() const  _NOEXCEPT
38414684ddb6SLionel Sambuc {
38424684ddb6SLionel Sambuc     return false;
38434684ddb6SLionel Sambuc }
38444684ddb6SLionel Sambuc 
38454684ddb6SLionel Sambuc int
do_length(state_type &,const extern_type * frm,const extern_type * frm_end,size_t mx) const38464684ddb6SLionel Sambuc __codecvt_utf16<char16_t, true>::do_length(state_type&,
38474684ddb6SLionel Sambuc     const extern_type* frm, const extern_type* frm_end, size_t mx) const
38484684ddb6SLionel Sambuc {
38494684ddb6SLionel Sambuc     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
38504684ddb6SLionel Sambuc     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
38514684ddb6SLionel Sambuc     return utf16le_to_ucs2_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
38524684ddb6SLionel Sambuc }
38534684ddb6SLionel Sambuc 
38544684ddb6SLionel Sambuc int
do_max_length() const38554684ddb6SLionel Sambuc __codecvt_utf16<char16_t, true>::do_max_length() const  _NOEXCEPT
38564684ddb6SLionel Sambuc {
38574684ddb6SLionel Sambuc     if (_Mode_ & consume_header)
38584684ddb6SLionel Sambuc         return 4;
38594684ddb6SLionel Sambuc     return 2;
38604684ddb6SLionel Sambuc }
38614684ddb6SLionel Sambuc 
38624684ddb6SLionel Sambuc // __codecvt_utf16<char32_t, false>
38634684ddb6SLionel Sambuc 
38644684ddb6SLionel Sambuc __codecvt_utf16<char32_t, false>::result
do_out(state_type &,const intern_type * frm,const intern_type * frm_end,const intern_type * & frm_nxt,extern_type * to,extern_type * to_end,extern_type * & to_nxt) const38654684ddb6SLionel Sambuc __codecvt_utf16<char32_t, false>::do_out(state_type&,
38664684ddb6SLionel Sambuc     const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
38674684ddb6SLionel Sambuc     extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
38684684ddb6SLionel Sambuc {
38694684ddb6SLionel Sambuc     const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
38704684ddb6SLionel Sambuc     const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
38714684ddb6SLionel Sambuc     const uint32_t* _frm_nxt = _frm;
38724684ddb6SLionel Sambuc     uint8_t* _to = reinterpret_cast<uint8_t*>(to);
38734684ddb6SLionel Sambuc     uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
38744684ddb6SLionel Sambuc     uint8_t* _to_nxt = _to;
38754684ddb6SLionel Sambuc     result r = ucs4_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
38764684ddb6SLionel Sambuc                                _Maxcode_, _Mode_);
38774684ddb6SLionel Sambuc     frm_nxt = frm + (_frm_nxt - _frm);
38784684ddb6SLionel Sambuc     to_nxt = to + (_to_nxt - _to);
38794684ddb6SLionel Sambuc     return r;
38804684ddb6SLionel Sambuc }
38814684ddb6SLionel Sambuc 
38824684ddb6SLionel Sambuc __codecvt_utf16<char32_t, false>::result
do_in(state_type &,const extern_type * frm,const extern_type * frm_end,const extern_type * & frm_nxt,intern_type * to,intern_type * to_end,intern_type * & to_nxt) const38834684ddb6SLionel Sambuc __codecvt_utf16<char32_t, false>::do_in(state_type&,
38844684ddb6SLionel Sambuc     const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
38854684ddb6SLionel Sambuc     intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
38864684ddb6SLionel Sambuc {
38874684ddb6SLionel Sambuc     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
38884684ddb6SLionel Sambuc     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
38894684ddb6SLionel Sambuc     const uint8_t* _frm_nxt = _frm;
38904684ddb6SLionel Sambuc     uint32_t* _to = reinterpret_cast<uint32_t*>(to);
38914684ddb6SLionel Sambuc     uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
38924684ddb6SLionel Sambuc     uint32_t* _to_nxt = _to;
38934684ddb6SLionel Sambuc     result r = utf16be_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
38944684ddb6SLionel Sambuc                                _Maxcode_, _Mode_);
38954684ddb6SLionel Sambuc     frm_nxt = frm + (_frm_nxt - _frm);
38964684ddb6SLionel Sambuc     to_nxt = to + (_to_nxt - _to);
38974684ddb6SLionel Sambuc     return r;
38984684ddb6SLionel Sambuc }
38994684ddb6SLionel Sambuc 
39004684ddb6SLionel Sambuc __codecvt_utf16<char32_t, false>::result
do_unshift(state_type &,extern_type * to,extern_type *,extern_type * & to_nxt) const39014684ddb6SLionel Sambuc __codecvt_utf16<char32_t, false>::do_unshift(state_type&,
39024684ddb6SLionel Sambuc     extern_type* to, extern_type*, extern_type*& to_nxt) const
39034684ddb6SLionel Sambuc {
39044684ddb6SLionel Sambuc     to_nxt = to;
39054684ddb6SLionel Sambuc     return noconv;
39064684ddb6SLionel Sambuc }
39074684ddb6SLionel Sambuc 
39084684ddb6SLionel Sambuc int
do_encoding() const39094684ddb6SLionel Sambuc __codecvt_utf16<char32_t, false>::do_encoding() const  _NOEXCEPT
39104684ddb6SLionel Sambuc {
39114684ddb6SLionel Sambuc     return 0;
39124684ddb6SLionel Sambuc }
39134684ddb6SLionel Sambuc 
39144684ddb6SLionel Sambuc bool
do_always_noconv() const39154684ddb6SLionel Sambuc __codecvt_utf16<char32_t, false>::do_always_noconv() const  _NOEXCEPT
39164684ddb6SLionel Sambuc {
39174684ddb6SLionel Sambuc     return false;
39184684ddb6SLionel Sambuc }
39194684ddb6SLionel Sambuc 
39204684ddb6SLionel Sambuc int
do_length(state_type &,const extern_type * frm,const extern_type * frm_end,size_t mx) const39214684ddb6SLionel Sambuc __codecvt_utf16<char32_t, false>::do_length(state_type&,
39224684ddb6SLionel Sambuc     const extern_type* frm, const extern_type* frm_end, size_t mx) const
39234684ddb6SLionel Sambuc {
39244684ddb6SLionel Sambuc     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
39254684ddb6SLionel Sambuc     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
39264684ddb6SLionel Sambuc     return utf16be_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
39274684ddb6SLionel Sambuc }
39284684ddb6SLionel Sambuc 
39294684ddb6SLionel Sambuc int
do_max_length() const39304684ddb6SLionel Sambuc __codecvt_utf16<char32_t, false>::do_max_length() const  _NOEXCEPT
39314684ddb6SLionel Sambuc {
39324684ddb6SLionel Sambuc     if (_Mode_ & consume_header)
39334684ddb6SLionel Sambuc         return 6;
39344684ddb6SLionel Sambuc     return 4;
39354684ddb6SLionel Sambuc }
39364684ddb6SLionel Sambuc 
39374684ddb6SLionel Sambuc // __codecvt_utf16<char32_t, true>
39384684ddb6SLionel Sambuc 
39394684ddb6SLionel Sambuc __codecvt_utf16<char32_t, true>::result
do_out(state_type &,const intern_type * frm,const intern_type * frm_end,const intern_type * & frm_nxt,extern_type * to,extern_type * to_end,extern_type * & to_nxt) const39404684ddb6SLionel Sambuc __codecvt_utf16<char32_t, true>::do_out(state_type&,
39414684ddb6SLionel Sambuc     const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
39424684ddb6SLionel Sambuc     extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
39434684ddb6SLionel Sambuc {
39444684ddb6SLionel Sambuc     const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
39454684ddb6SLionel Sambuc     const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
39464684ddb6SLionel Sambuc     const uint32_t* _frm_nxt = _frm;
39474684ddb6SLionel Sambuc     uint8_t* _to = reinterpret_cast<uint8_t*>(to);
39484684ddb6SLionel Sambuc     uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
39494684ddb6SLionel Sambuc     uint8_t* _to_nxt = _to;
39504684ddb6SLionel Sambuc     result r = ucs4_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
39514684ddb6SLionel Sambuc                                _Maxcode_, _Mode_);
39524684ddb6SLionel Sambuc     frm_nxt = frm + (_frm_nxt - _frm);
39534684ddb6SLionel Sambuc     to_nxt = to + (_to_nxt - _to);
39544684ddb6SLionel Sambuc     return r;
39554684ddb6SLionel Sambuc }
39564684ddb6SLionel Sambuc 
39574684ddb6SLionel Sambuc __codecvt_utf16<char32_t, true>::result
do_in(state_type &,const extern_type * frm,const extern_type * frm_end,const extern_type * & frm_nxt,intern_type * to,intern_type * to_end,intern_type * & to_nxt) const39584684ddb6SLionel Sambuc __codecvt_utf16<char32_t, true>::do_in(state_type&,
39594684ddb6SLionel Sambuc     const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
39604684ddb6SLionel Sambuc     intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
39614684ddb6SLionel Sambuc {
39624684ddb6SLionel Sambuc     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
39634684ddb6SLionel Sambuc     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
39644684ddb6SLionel Sambuc     const uint8_t* _frm_nxt = _frm;
39654684ddb6SLionel Sambuc     uint32_t* _to = reinterpret_cast<uint32_t*>(to);
39664684ddb6SLionel Sambuc     uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
39674684ddb6SLionel Sambuc     uint32_t* _to_nxt = _to;
39684684ddb6SLionel Sambuc     result r = utf16le_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
39694684ddb6SLionel Sambuc                                _Maxcode_, _Mode_);
39704684ddb6SLionel Sambuc     frm_nxt = frm + (_frm_nxt - _frm);
39714684ddb6SLionel Sambuc     to_nxt = to + (_to_nxt - _to);
39724684ddb6SLionel Sambuc     return r;
39734684ddb6SLionel Sambuc }
39744684ddb6SLionel Sambuc 
39754684ddb6SLionel Sambuc __codecvt_utf16<char32_t, true>::result
do_unshift(state_type &,extern_type * to,extern_type *,extern_type * & to_nxt) const39764684ddb6SLionel Sambuc __codecvt_utf16<char32_t, true>::do_unshift(state_type&,
39774684ddb6SLionel Sambuc     extern_type* to, extern_type*, extern_type*& to_nxt) const
39784684ddb6SLionel Sambuc {
39794684ddb6SLionel Sambuc     to_nxt = to;
39804684ddb6SLionel Sambuc     return noconv;
39814684ddb6SLionel Sambuc }
39824684ddb6SLionel Sambuc 
39834684ddb6SLionel Sambuc int
do_encoding() const39844684ddb6SLionel Sambuc __codecvt_utf16<char32_t, true>::do_encoding() const  _NOEXCEPT
39854684ddb6SLionel Sambuc {
39864684ddb6SLionel Sambuc     return 0;
39874684ddb6SLionel Sambuc }
39884684ddb6SLionel Sambuc 
39894684ddb6SLionel Sambuc bool
do_always_noconv() const39904684ddb6SLionel Sambuc __codecvt_utf16<char32_t, true>::do_always_noconv() const  _NOEXCEPT
39914684ddb6SLionel Sambuc {
39924684ddb6SLionel Sambuc     return false;
39934684ddb6SLionel Sambuc }
39944684ddb6SLionel Sambuc 
39954684ddb6SLionel Sambuc int
do_length(state_type &,const extern_type * frm,const extern_type * frm_end,size_t mx) const39964684ddb6SLionel Sambuc __codecvt_utf16<char32_t, true>::do_length(state_type&,
39974684ddb6SLionel Sambuc     const extern_type* frm, const extern_type* frm_end, size_t mx) const
39984684ddb6SLionel Sambuc {
39994684ddb6SLionel Sambuc     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
40004684ddb6SLionel Sambuc     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
40014684ddb6SLionel Sambuc     return utf16le_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
40024684ddb6SLionel Sambuc }
40034684ddb6SLionel Sambuc 
40044684ddb6SLionel Sambuc int
do_max_length() const40054684ddb6SLionel Sambuc __codecvt_utf16<char32_t, true>::do_max_length() const  _NOEXCEPT
40064684ddb6SLionel Sambuc {
40074684ddb6SLionel Sambuc     if (_Mode_ & consume_header)
40084684ddb6SLionel Sambuc         return 6;
40094684ddb6SLionel Sambuc     return 4;
40104684ddb6SLionel Sambuc }
40114684ddb6SLionel Sambuc 
40124684ddb6SLionel Sambuc // __codecvt_utf8_utf16<wchar_t>
40134684ddb6SLionel Sambuc 
40144684ddb6SLionel Sambuc __codecvt_utf8_utf16<wchar_t>::result
do_out(state_type &,const intern_type * frm,const intern_type * frm_end,const intern_type * & frm_nxt,extern_type * to,extern_type * to_end,extern_type * & to_nxt) const40154684ddb6SLionel Sambuc __codecvt_utf8_utf16<wchar_t>::do_out(state_type&,
40164684ddb6SLionel Sambuc     const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
40174684ddb6SLionel Sambuc     extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
40184684ddb6SLionel Sambuc {
40194684ddb6SLionel Sambuc     const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
40204684ddb6SLionel Sambuc     const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
40214684ddb6SLionel Sambuc     const uint32_t* _frm_nxt = _frm;
40224684ddb6SLionel Sambuc     uint8_t* _to = reinterpret_cast<uint8_t*>(to);
40234684ddb6SLionel Sambuc     uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
40244684ddb6SLionel Sambuc     uint8_t* _to_nxt = _to;
40254684ddb6SLionel Sambuc     result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
40264684ddb6SLionel Sambuc                              _Maxcode_, _Mode_);
40274684ddb6SLionel Sambuc     frm_nxt = frm + (_frm_nxt - _frm);
40284684ddb6SLionel Sambuc     to_nxt = to + (_to_nxt - _to);
40294684ddb6SLionel Sambuc     return r;
40304684ddb6SLionel Sambuc }
40314684ddb6SLionel Sambuc 
40324684ddb6SLionel Sambuc __codecvt_utf8_utf16<wchar_t>::result
do_in(state_type &,const extern_type * frm,const extern_type * frm_end,const extern_type * & frm_nxt,intern_type * to,intern_type * to_end,intern_type * & to_nxt) const40334684ddb6SLionel Sambuc __codecvt_utf8_utf16<wchar_t>::do_in(state_type&,
40344684ddb6SLionel Sambuc     const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
40354684ddb6SLionel Sambuc     intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
40364684ddb6SLionel Sambuc {
40374684ddb6SLionel Sambuc     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
40384684ddb6SLionel Sambuc     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
40394684ddb6SLionel Sambuc     const uint8_t* _frm_nxt = _frm;
40404684ddb6SLionel Sambuc     uint32_t* _to = reinterpret_cast<uint32_t*>(to);
40414684ddb6SLionel Sambuc     uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
40424684ddb6SLionel Sambuc     uint32_t* _to_nxt = _to;
40434684ddb6SLionel Sambuc     result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
40444684ddb6SLionel Sambuc                              _Maxcode_, _Mode_);
40454684ddb6SLionel Sambuc     frm_nxt = frm + (_frm_nxt - _frm);
40464684ddb6SLionel Sambuc     to_nxt = to + (_to_nxt - _to);
40474684ddb6SLionel Sambuc     return r;
40484684ddb6SLionel Sambuc }
40494684ddb6SLionel Sambuc 
40504684ddb6SLionel Sambuc __codecvt_utf8_utf16<wchar_t>::result
do_unshift(state_type &,extern_type * to,extern_type *,extern_type * & to_nxt) const40514684ddb6SLionel Sambuc __codecvt_utf8_utf16<wchar_t>::do_unshift(state_type&,
40524684ddb6SLionel Sambuc     extern_type* to, extern_type*, extern_type*& to_nxt) const
40534684ddb6SLionel Sambuc {
40544684ddb6SLionel Sambuc     to_nxt = to;
40554684ddb6SLionel Sambuc     return noconv;
40564684ddb6SLionel Sambuc }
40574684ddb6SLionel Sambuc 
40584684ddb6SLionel Sambuc int
do_encoding() const40594684ddb6SLionel Sambuc __codecvt_utf8_utf16<wchar_t>::do_encoding() const  _NOEXCEPT
40604684ddb6SLionel Sambuc {
40614684ddb6SLionel Sambuc     return 0;
40624684ddb6SLionel Sambuc }
40634684ddb6SLionel Sambuc 
40644684ddb6SLionel Sambuc bool
do_always_noconv() const40654684ddb6SLionel Sambuc __codecvt_utf8_utf16<wchar_t>::do_always_noconv() const  _NOEXCEPT
40664684ddb6SLionel Sambuc {
40674684ddb6SLionel Sambuc     return false;
40684684ddb6SLionel Sambuc }
40694684ddb6SLionel Sambuc 
40704684ddb6SLionel Sambuc int
do_length(state_type &,const extern_type * frm,const extern_type * frm_end,size_t mx) const40714684ddb6SLionel Sambuc __codecvt_utf8_utf16<wchar_t>::do_length(state_type&,
40724684ddb6SLionel Sambuc     const extern_type* frm, const extern_type* frm_end, size_t mx) const
40734684ddb6SLionel Sambuc {
40744684ddb6SLionel Sambuc     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
40754684ddb6SLionel Sambuc     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
40764684ddb6SLionel Sambuc     return utf8_to_utf16_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
40774684ddb6SLionel Sambuc }
40784684ddb6SLionel Sambuc 
40794684ddb6SLionel Sambuc int
do_max_length() const40804684ddb6SLionel Sambuc __codecvt_utf8_utf16<wchar_t>::do_max_length() const  _NOEXCEPT
40814684ddb6SLionel Sambuc {
40824684ddb6SLionel Sambuc     if (_Mode_ & consume_header)
40834684ddb6SLionel Sambuc         return 7;
40844684ddb6SLionel Sambuc     return 4;
40854684ddb6SLionel Sambuc }
40864684ddb6SLionel Sambuc 
40874684ddb6SLionel Sambuc // __codecvt_utf8_utf16<char16_t>
40884684ddb6SLionel Sambuc 
40894684ddb6SLionel Sambuc __codecvt_utf8_utf16<char16_t>::result
do_out(state_type &,const intern_type * frm,const intern_type * frm_end,const intern_type * & frm_nxt,extern_type * to,extern_type * to_end,extern_type * & to_nxt) const40904684ddb6SLionel Sambuc __codecvt_utf8_utf16<char16_t>::do_out(state_type&,
40914684ddb6SLionel Sambuc     const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
40924684ddb6SLionel Sambuc     extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
40934684ddb6SLionel Sambuc {
40944684ddb6SLionel Sambuc     const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
40954684ddb6SLionel Sambuc     const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
40964684ddb6SLionel Sambuc     const uint16_t* _frm_nxt = _frm;
40974684ddb6SLionel Sambuc     uint8_t* _to = reinterpret_cast<uint8_t*>(to);
40984684ddb6SLionel Sambuc     uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
40994684ddb6SLionel Sambuc     uint8_t* _to_nxt = _to;
41004684ddb6SLionel Sambuc     result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
41014684ddb6SLionel Sambuc                              _Maxcode_, _Mode_);
41024684ddb6SLionel Sambuc     frm_nxt = frm + (_frm_nxt - _frm);
41034684ddb6SLionel Sambuc     to_nxt = to + (_to_nxt - _to);
41044684ddb6SLionel Sambuc     return r;
41054684ddb6SLionel Sambuc }
41064684ddb6SLionel Sambuc 
41074684ddb6SLionel Sambuc __codecvt_utf8_utf16<char16_t>::result
do_in(state_type &,const extern_type * frm,const extern_type * frm_end,const extern_type * & frm_nxt,intern_type * to,intern_type * to_end,intern_type * & to_nxt) const41084684ddb6SLionel Sambuc __codecvt_utf8_utf16<char16_t>::do_in(state_type&,
41094684ddb6SLionel Sambuc     const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
41104684ddb6SLionel Sambuc     intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
41114684ddb6SLionel Sambuc {
41124684ddb6SLionel Sambuc     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
41134684ddb6SLionel Sambuc     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
41144684ddb6SLionel Sambuc     const uint8_t* _frm_nxt = _frm;
41154684ddb6SLionel Sambuc     uint16_t* _to = reinterpret_cast<uint16_t*>(to);
41164684ddb6SLionel Sambuc     uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
41174684ddb6SLionel Sambuc     uint16_t* _to_nxt = _to;
41184684ddb6SLionel Sambuc     result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
41194684ddb6SLionel Sambuc                              _Maxcode_, _Mode_);
41204684ddb6SLionel Sambuc     frm_nxt = frm + (_frm_nxt - _frm);
41214684ddb6SLionel Sambuc     to_nxt = to + (_to_nxt - _to);
41224684ddb6SLionel Sambuc     return r;
41234684ddb6SLionel Sambuc }
41244684ddb6SLionel Sambuc 
41254684ddb6SLionel Sambuc __codecvt_utf8_utf16<char16_t>::result
do_unshift(state_type &,extern_type * to,extern_type *,extern_type * & to_nxt) const41264684ddb6SLionel Sambuc __codecvt_utf8_utf16<char16_t>::do_unshift(state_type&,
41274684ddb6SLionel Sambuc     extern_type* to, extern_type*, extern_type*& to_nxt) const
41284684ddb6SLionel Sambuc {
41294684ddb6SLionel Sambuc     to_nxt = to;
41304684ddb6SLionel Sambuc     return noconv;
41314684ddb6SLionel Sambuc }
41324684ddb6SLionel Sambuc 
41334684ddb6SLionel Sambuc int
do_encoding() const41344684ddb6SLionel Sambuc __codecvt_utf8_utf16<char16_t>::do_encoding() const  _NOEXCEPT
41354684ddb6SLionel Sambuc {
41364684ddb6SLionel Sambuc     return 0;
41374684ddb6SLionel Sambuc }
41384684ddb6SLionel Sambuc 
41394684ddb6SLionel Sambuc bool
do_always_noconv() const41404684ddb6SLionel Sambuc __codecvt_utf8_utf16<char16_t>::do_always_noconv() const  _NOEXCEPT
41414684ddb6SLionel Sambuc {
41424684ddb6SLionel Sambuc     return false;
41434684ddb6SLionel Sambuc }
41444684ddb6SLionel Sambuc 
41454684ddb6SLionel Sambuc int
do_length(state_type &,const extern_type * frm,const extern_type * frm_end,size_t mx) const41464684ddb6SLionel Sambuc __codecvt_utf8_utf16<char16_t>::do_length(state_type&,
41474684ddb6SLionel Sambuc     const extern_type* frm, const extern_type* frm_end, size_t mx) const
41484684ddb6SLionel Sambuc {
41494684ddb6SLionel Sambuc     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
41504684ddb6SLionel Sambuc     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
41514684ddb6SLionel Sambuc     return utf8_to_utf16_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
41524684ddb6SLionel Sambuc }
41534684ddb6SLionel Sambuc 
41544684ddb6SLionel Sambuc int
do_max_length() const41554684ddb6SLionel Sambuc __codecvt_utf8_utf16<char16_t>::do_max_length() const  _NOEXCEPT
41564684ddb6SLionel Sambuc {
41574684ddb6SLionel Sambuc     if (_Mode_ & consume_header)
41584684ddb6SLionel Sambuc         return 7;
41594684ddb6SLionel Sambuc     return 4;
41604684ddb6SLionel Sambuc }
41614684ddb6SLionel Sambuc 
41624684ddb6SLionel Sambuc // __codecvt_utf8_utf16<char32_t>
41634684ddb6SLionel Sambuc 
41644684ddb6SLionel Sambuc __codecvt_utf8_utf16<char32_t>::result
do_out(state_type &,const intern_type * frm,const intern_type * frm_end,const intern_type * & frm_nxt,extern_type * to,extern_type * to_end,extern_type * & to_nxt) const41654684ddb6SLionel Sambuc __codecvt_utf8_utf16<char32_t>::do_out(state_type&,
41664684ddb6SLionel Sambuc     const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
41674684ddb6SLionel Sambuc     extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
41684684ddb6SLionel Sambuc {
41694684ddb6SLionel Sambuc     const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
41704684ddb6SLionel Sambuc     const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
41714684ddb6SLionel Sambuc     const uint32_t* _frm_nxt = _frm;
41724684ddb6SLionel Sambuc     uint8_t* _to = reinterpret_cast<uint8_t*>(to);
41734684ddb6SLionel Sambuc     uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
41744684ddb6SLionel Sambuc     uint8_t* _to_nxt = _to;
41754684ddb6SLionel Sambuc     result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
41764684ddb6SLionel Sambuc                              _Maxcode_, _Mode_);
41774684ddb6SLionel Sambuc     frm_nxt = frm + (_frm_nxt - _frm);
41784684ddb6SLionel Sambuc     to_nxt = to + (_to_nxt - _to);
41794684ddb6SLionel Sambuc     return r;
41804684ddb6SLionel Sambuc }
41814684ddb6SLionel Sambuc 
41824684ddb6SLionel Sambuc __codecvt_utf8_utf16<char32_t>::result
do_in(state_type &,const extern_type * frm,const extern_type * frm_end,const extern_type * & frm_nxt,intern_type * to,intern_type * to_end,intern_type * & to_nxt) const41834684ddb6SLionel Sambuc __codecvt_utf8_utf16<char32_t>::do_in(state_type&,
41844684ddb6SLionel Sambuc     const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
41854684ddb6SLionel Sambuc     intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
41864684ddb6SLionel Sambuc {
41874684ddb6SLionel Sambuc     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
41884684ddb6SLionel Sambuc     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
41894684ddb6SLionel Sambuc     const uint8_t* _frm_nxt = _frm;
41904684ddb6SLionel Sambuc     uint32_t* _to = reinterpret_cast<uint32_t*>(to);
41914684ddb6SLionel Sambuc     uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
41924684ddb6SLionel Sambuc     uint32_t* _to_nxt = _to;
41934684ddb6SLionel Sambuc     result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
41944684ddb6SLionel Sambuc                              _Maxcode_, _Mode_);
41954684ddb6SLionel Sambuc     frm_nxt = frm + (_frm_nxt - _frm);
41964684ddb6SLionel Sambuc     to_nxt = to + (_to_nxt - _to);
41974684ddb6SLionel Sambuc     return r;
41984684ddb6SLionel Sambuc }
41994684ddb6SLionel Sambuc 
42004684ddb6SLionel Sambuc __codecvt_utf8_utf16<char32_t>::result
do_unshift(state_type &,extern_type * to,extern_type *,extern_type * & to_nxt) const42014684ddb6SLionel Sambuc __codecvt_utf8_utf16<char32_t>::do_unshift(state_type&,
42024684ddb6SLionel Sambuc     extern_type* to, extern_type*, extern_type*& to_nxt) const
42034684ddb6SLionel Sambuc {
42044684ddb6SLionel Sambuc     to_nxt = to;
42054684ddb6SLionel Sambuc     return noconv;
42064684ddb6SLionel Sambuc }
42074684ddb6SLionel Sambuc 
42084684ddb6SLionel Sambuc int
do_encoding() const42094684ddb6SLionel Sambuc __codecvt_utf8_utf16<char32_t>::do_encoding() const  _NOEXCEPT
42104684ddb6SLionel Sambuc {
42114684ddb6SLionel Sambuc     return 0;
42124684ddb6SLionel Sambuc }
42134684ddb6SLionel Sambuc 
42144684ddb6SLionel Sambuc bool
do_always_noconv() const42154684ddb6SLionel Sambuc __codecvt_utf8_utf16<char32_t>::do_always_noconv() const  _NOEXCEPT
42164684ddb6SLionel Sambuc {
42174684ddb6SLionel Sambuc     return false;
42184684ddb6SLionel Sambuc }
42194684ddb6SLionel Sambuc 
42204684ddb6SLionel Sambuc int
do_length(state_type &,const extern_type * frm,const extern_type * frm_end,size_t mx) const42214684ddb6SLionel Sambuc __codecvt_utf8_utf16<char32_t>::do_length(state_type&,
42224684ddb6SLionel Sambuc     const extern_type* frm, const extern_type* frm_end, size_t mx) const
42234684ddb6SLionel Sambuc {
42244684ddb6SLionel Sambuc     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
42254684ddb6SLionel Sambuc     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
42264684ddb6SLionel Sambuc     return utf8_to_utf16_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
42274684ddb6SLionel Sambuc }
42284684ddb6SLionel Sambuc 
42294684ddb6SLionel Sambuc int
do_max_length() const42304684ddb6SLionel Sambuc __codecvt_utf8_utf16<char32_t>::do_max_length() const  _NOEXCEPT
42314684ddb6SLionel Sambuc {
42324684ddb6SLionel Sambuc     if (_Mode_ & consume_header)
42334684ddb6SLionel Sambuc         return 7;
42344684ddb6SLionel Sambuc     return 4;
42354684ddb6SLionel Sambuc }
42364684ddb6SLionel Sambuc 
42374684ddb6SLionel Sambuc // __narrow_to_utf8<16>
42384684ddb6SLionel Sambuc 
~__narrow_to_utf8()42394684ddb6SLionel Sambuc __narrow_to_utf8<16>::~__narrow_to_utf8()
42404684ddb6SLionel Sambuc {
42414684ddb6SLionel Sambuc }
42424684ddb6SLionel Sambuc 
42434684ddb6SLionel Sambuc // __narrow_to_utf8<32>
42444684ddb6SLionel Sambuc 
~__narrow_to_utf8()42454684ddb6SLionel Sambuc __narrow_to_utf8<32>::~__narrow_to_utf8()
42464684ddb6SLionel Sambuc {
42474684ddb6SLionel Sambuc }
42484684ddb6SLionel Sambuc 
42494684ddb6SLionel Sambuc // __widen_from_utf8<16>
42504684ddb6SLionel Sambuc 
~__widen_from_utf8()42514684ddb6SLionel Sambuc __widen_from_utf8<16>::~__widen_from_utf8()
42524684ddb6SLionel Sambuc {
42534684ddb6SLionel Sambuc }
42544684ddb6SLionel Sambuc 
42554684ddb6SLionel Sambuc // __widen_from_utf8<32>
42564684ddb6SLionel Sambuc 
~__widen_from_utf8()42574684ddb6SLionel Sambuc __widen_from_utf8<32>::~__widen_from_utf8()
42584684ddb6SLionel Sambuc {
42594684ddb6SLionel Sambuc }
42604684ddb6SLionel Sambuc 
42614684ddb6SLionel Sambuc // numpunct<char> && numpunct<wchar_t>
42624684ddb6SLionel Sambuc 
42634684ddb6SLionel Sambuc locale::id numpunct< char  >::id;
42644684ddb6SLionel Sambuc locale::id numpunct<wchar_t>::id;
42654684ddb6SLionel Sambuc 
numpunct(size_t refs)42664684ddb6SLionel Sambuc numpunct<char>::numpunct(size_t refs)
42674684ddb6SLionel Sambuc     : locale::facet(refs),
42684684ddb6SLionel Sambuc       __decimal_point_('.'),
42694684ddb6SLionel Sambuc       __thousands_sep_(',')
42704684ddb6SLionel Sambuc {
42714684ddb6SLionel Sambuc }
42724684ddb6SLionel Sambuc 
numpunct(size_t refs)42734684ddb6SLionel Sambuc numpunct<wchar_t>::numpunct(size_t refs)
42744684ddb6SLionel Sambuc     : locale::facet(refs),
42754684ddb6SLionel Sambuc       __decimal_point_(L'.'),
42764684ddb6SLionel Sambuc       __thousands_sep_(L',')
42774684ddb6SLionel Sambuc {
42784684ddb6SLionel Sambuc }
42794684ddb6SLionel Sambuc 
~numpunct()42804684ddb6SLionel Sambuc numpunct<char>::~numpunct()
42814684ddb6SLionel Sambuc {
42824684ddb6SLionel Sambuc }
42834684ddb6SLionel Sambuc 
~numpunct()42844684ddb6SLionel Sambuc numpunct<wchar_t>::~numpunct()
42854684ddb6SLionel Sambuc {
42864684ddb6SLionel Sambuc }
42874684ddb6SLionel Sambuc 
do_decimal_point() const42884684ddb6SLionel Sambuc  char   numpunct< char  >::do_decimal_point() const {return __decimal_point_;}
do_decimal_point() const42894684ddb6SLionel Sambuc wchar_t numpunct<wchar_t>::do_decimal_point() const {return __decimal_point_;}
42904684ddb6SLionel Sambuc 
do_thousands_sep() const42914684ddb6SLionel Sambuc  char   numpunct< char  >::do_thousands_sep() const {return __thousands_sep_;}
do_thousands_sep() const42924684ddb6SLionel Sambuc wchar_t numpunct<wchar_t>::do_thousands_sep() const {return __thousands_sep_;}
42934684ddb6SLionel Sambuc 
do_grouping() const42944684ddb6SLionel Sambuc string numpunct< char  >::do_grouping() const {return __grouping_;}
do_grouping() const42954684ddb6SLionel Sambuc string numpunct<wchar_t>::do_grouping() const {return __grouping_;}
42964684ddb6SLionel Sambuc 
do_truename() const42974684ddb6SLionel Sambuc  string numpunct< char  >::do_truename() const {return "true";}
do_truename() const42984684ddb6SLionel Sambuc wstring numpunct<wchar_t>::do_truename() const {return L"true";}
42994684ddb6SLionel Sambuc 
do_falsename() const43004684ddb6SLionel Sambuc  string numpunct< char  >::do_falsename() const {return "false";}
do_falsename() const43014684ddb6SLionel Sambuc wstring numpunct<wchar_t>::do_falsename() const {return L"false";}
43024684ddb6SLionel Sambuc 
43034684ddb6SLionel Sambuc // numpunct_byname<char>
43044684ddb6SLionel Sambuc 
numpunct_byname(const char * nm,size_t refs)43054684ddb6SLionel Sambuc numpunct_byname<char>::numpunct_byname(const char* nm, size_t refs)
43064684ddb6SLionel Sambuc     : numpunct<char>(refs)
43074684ddb6SLionel Sambuc {
43084684ddb6SLionel Sambuc     __init(nm);
43094684ddb6SLionel Sambuc }
43104684ddb6SLionel Sambuc 
numpunct_byname(const string & nm,size_t refs)43114684ddb6SLionel Sambuc numpunct_byname<char>::numpunct_byname(const string& nm, size_t refs)
43124684ddb6SLionel Sambuc     : numpunct<char>(refs)
43134684ddb6SLionel Sambuc {
43144684ddb6SLionel Sambuc     __init(nm.c_str());
43154684ddb6SLionel Sambuc }
43164684ddb6SLionel Sambuc 
~numpunct_byname()43174684ddb6SLionel Sambuc numpunct_byname<char>::~numpunct_byname()
43184684ddb6SLionel Sambuc {
43194684ddb6SLionel Sambuc }
43204684ddb6SLionel Sambuc 
43214684ddb6SLionel Sambuc void
__init(const char * nm)43224684ddb6SLionel Sambuc numpunct_byname<char>::__init(const char* nm)
43234684ddb6SLionel Sambuc {
43244684ddb6SLionel Sambuc     if (strcmp(nm, "C") != 0)
43254684ddb6SLionel Sambuc     {
43264684ddb6SLionel Sambuc         __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
43274684ddb6SLionel Sambuc #ifndef _LIBCPP_NO_EXCEPTIONS
43284684ddb6SLionel Sambuc         if (loc == nullptr)
43294684ddb6SLionel Sambuc             throw runtime_error("numpunct_byname<char>::numpunct_byname"
43304684ddb6SLionel Sambuc                                 " failed to construct for " + string(nm));
43314684ddb6SLionel Sambuc #endif  // _LIBCPP_NO_EXCEPTIONS
43324684ddb6SLionel Sambuc #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
43334684ddb6SLionel Sambuc         lconv* lc = localeconv_l(loc.get());
43344684ddb6SLionel Sambuc #else
43354684ddb6SLionel Sambuc         lconv* lc = __localeconv_l(loc.get());
43364684ddb6SLionel Sambuc #endif
43374684ddb6SLionel Sambuc         if (*lc->decimal_point)
43384684ddb6SLionel Sambuc             __decimal_point_ = *lc->decimal_point;
43394684ddb6SLionel Sambuc         if (*lc->thousands_sep)
43404684ddb6SLionel Sambuc             __thousands_sep_ = *lc->thousands_sep;
43414684ddb6SLionel Sambuc         __grouping_ = lc->grouping;
43424684ddb6SLionel Sambuc         // localization for truename and falsename is not available
43434684ddb6SLionel Sambuc     }
43444684ddb6SLionel Sambuc }
43454684ddb6SLionel Sambuc 
43464684ddb6SLionel Sambuc // numpunct_byname<wchar_t>
43474684ddb6SLionel Sambuc 
numpunct_byname(const char * nm,size_t refs)43484684ddb6SLionel Sambuc numpunct_byname<wchar_t>::numpunct_byname(const char* nm, size_t refs)
43494684ddb6SLionel Sambuc     : numpunct<wchar_t>(refs)
43504684ddb6SLionel Sambuc {
43514684ddb6SLionel Sambuc     __init(nm);
43524684ddb6SLionel Sambuc }
43534684ddb6SLionel Sambuc 
numpunct_byname(const string & nm,size_t refs)43544684ddb6SLionel Sambuc numpunct_byname<wchar_t>::numpunct_byname(const string& nm, size_t refs)
43554684ddb6SLionel Sambuc     : numpunct<wchar_t>(refs)
43564684ddb6SLionel Sambuc {
43574684ddb6SLionel Sambuc     __init(nm.c_str());
43584684ddb6SLionel Sambuc }
43594684ddb6SLionel Sambuc 
~numpunct_byname()43604684ddb6SLionel Sambuc numpunct_byname<wchar_t>::~numpunct_byname()
43614684ddb6SLionel Sambuc {
43624684ddb6SLionel Sambuc }
43634684ddb6SLionel Sambuc 
43644684ddb6SLionel Sambuc void
__init(const char * nm)43654684ddb6SLionel Sambuc numpunct_byname<wchar_t>::__init(const char* nm)
43664684ddb6SLionel Sambuc {
43674684ddb6SLionel Sambuc     if (strcmp(nm, "C") != 0)
43684684ddb6SLionel Sambuc     {
43694684ddb6SLionel Sambuc         __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
43704684ddb6SLionel Sambuc #ifndef _LIBCPP_NO_EXCEPTIONS
43714684ddb6SLionel Sambuc         if (loc == nullptr)
43724684ddb6SLionel Sambuc             throw runtime_error("numpunct_byname<char>::numpunct_byname"
43734684ddb6SLionel Sambuc                                 " failed to construct for " + string(nm));
43744684ddb6SLionel Sambuc #endif  // _LIBCPP_NO_EXCEPTIONS
43754684ddb6SLionel Sambuc #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
43764684ddb6SLionel Sambuc         lconv* lc = localeconv_l(loc.get());
43774684ddb6SLionel Sambuc #else
43784684ddb6SLionel Sambuc         lconv* lc = __localeconv_l(loc.get());
43794684ddb6SLionel Sambuc #endif
43804684ddb6SLionel Sambuc         if (*lc->decimal_point)
43814684ddb6SLionel Sambuc             __decimal_point_ = *lc->decimal_point;
43824684ddb6SLionel Sambuc         if (*lc->thousands_sep)
43834684ddb6SLionel Sambuc             __thousands_sep_ = *lc->thousands_sep;
43844684ddb6SLionel Sambuc         __grouping_ = lc->grouping;
43854684ddb6SLionel Sambuc         // locallization for truename and falsename is not available
43864684ddb6SLionel Sambuc     }
43874684ddb6SLionel Sambuc }
43884684ddb6SLionel Sambuc 
43894684ddb6SLionel Sambuc // num_get helpers
43904684ddb6SLionel Sambuc 
43914684ddb6SLionel Sambuc int
__get_base(ios_base & iob)43924684ddb6SLionel Sambuc __num_get_base::__get_base(ios_base& iob)
43934684ddb6SLionel Sambuc {
43944684ddb6SLionel Sambuc     ios_base::fmtflags __basefield = iob.flags() & ios_base::basefield;
43954684ddb6SLionel Sambuc     if (__basefield == ios_base::oct)
43964684ddb6SLionel Sambuc         return 8;
43974684ddb6SLionel Sambuc     else if (__basefield == ios_base::hex)
43984684ddb6SLionel Sambuc         return 16;
43994684ddb6SLionel Sambuc     else if (__basefield == 0)
44004684ddb6SLionel Sambuc         return 0;
44014684ddb6SLionel Sambuc     return 10;
44024684ddb6SLionel Sambuc }
44034684ddb6SLionel Sambuc 
44044684ddb6SLionel Sambuc const char __num_get_base::__src[33] = "0123456789abcdefABCDEFxX+-pPiInN";
44054684ddb6SLionel Sambuc 
44064684ddb6SLionel Sambuc void
__check_grouping(const string & __grouping,unsigned * __g,unsigned * __g_end,ios_base::iostate & __err)44074684ddb6SLionel Sambuc __check_grouping(const string& __grouping, unsigned* __g, unsigned* __g_end,
44084684ddb6SLionel Sambuc                  ios_base::iostate& __err)
44094684ddb6SLionel Sambuc {
44104684ddb6SLionel Sambuc     if (__grouping.size() != 0)
44114684ddb6SLionel Sambuc     {
44124684ddb6SLionel Sambuc         reverse(__g, __g_end);
44134684ddb6SLionel Sambuc         const char* __ig = __grouping.data();
44144684ddb6SLionel Sambuc         const char* __eg = __ig + __grouping.size();
44154684ddb6SLionel Sambuc         for (unsigned* __r = __g; __r < __g_end-1; ++__r)
44164684ddb6SLionel Sambuc         {
44174684ddb6SLionel Sambuc             if (0 < *__ig && *__ig < numeric_limits<char>::max())
44184684ddb6SLionel Sambuc             {
44194684ddb6SLionel Sambuc                 if (static_cast<unsigned>(*__ig) != *__r)
44204684ddb6SLionel Sambuc                 {
44214684ddb6SLionel Sambuc                     __err = ios_base::failbit;
44224684ddb6SLionel Sambuc                     return;
44234684ddb6SLionel Sambuc                 }
44244684ddb6SLionel Sambuc             }
44254684ddb6SLionel Sambuc             if (__eg - __ig > 1)
44264684ddb6SLionel Sambuc                 ++__ig;
44274684ddb6SLionel Sambuc         }
44284684ddb6SLionel Sambuc         if (0 < *__ig && *__ig < numeric_limits<char>::max())
44294684ddb6SLionel Sambuc         {
44304684ddb6SLionel Sambuc             if (static_cast<unsigned>(*__ig) < __g_end[-1] || __g_end[-1] == 0)
44314684ddb6SLionel Sambuc                 __err = ios_base::failbit;
44324684ddb6SLionel Sambuc         }
44334684ddb6SLionel Sambuc     }
44344684ddb6SLionel Sambuc }
44354684ddb6SLionel Sambuc 
44364684ddb6SLionel Sambuc void
__format_int(char * __fmtp,const char * __len,bool __signd,ios_base::fmtflags __flags)44374684ddb6SLionel Sambuc __num_put_base::__format_int(char* __fmtp, const char* __len, bool __signd,
44384684ddb6SLionel Sambuc                              ios_base::fmtflags __flags)
44394684ddb6SLionel Sambuc {
44404684ddb6SLionel Sambuc     if (__flags & ios_base::showpos)
44414684ddb6SLionel Sambuc         *__fmtp++ = '+';
44424684ddb6SLionel Sambuc     if (__flags & ios_base::showbase)
44434684ddb6SLionel Sambuc         *__fmtp++ = '#';
44444684ddb6SLionel Sambuc     while(*__len)
44454684ddb6SLionel Sambuc         *__fmtp++ = *__len++;
44464684ddb6SLionel Sambuc     if ((__flags & ios_base::basefield) == ios_base::oct)
44474684ddb6SLionel Sambuc         *__fmtp = 'o';
44484684ddb6SLionel Sambuc     else if ((__flags & ios_base::basefield) == ios_base::hex)
44494684ddb6SLionel Sambuc     {
44504684ddb6SLionel Sambuc         if (__flags & ios_base::uppercase)
44514684ddb6SLionel Sambuc             *__fmtp = 'X';
44524684ddb6SLionel Sambuc         else
44534684ddb6SLionel Sambuc             *__fmtp = 'x';
44544684ddb6SLionel Sambuc     }
44554684ddb6SLionel Sambuc     else if (__signd)
44564684ddb6SLionel Sambuc         *__fmtp = 'd';
44574684ddb6SLionel Sambuc     else
44584684ddb6SLionel Sambuc         *__fmtp = 'u';
44594684ddb6SLionel Sambuc }
44604684ddb6SLionel Sambuc 
44614684ddb6SLionel Sambuc bool
__format_float(char * __fmtp,const char * __len,ios_base::fmtflags __flags)44624684ddb6SLionel Sambuc __num_put_base::__format_float(char* __fmtp, const char* __len,
44634684ddb6SLionel Sambuc                                ios_base::fmtflags __flags)
44644684ddb6SLionel Sambuc {
44654684ddb6SLionel Sambuc     bool specify_precision = true;
44664684ddb6SLionel Sambuc     if (__flags & ios_base::showpos)
44674684ddb6SLionel Sambuc         *__fmtp++ = '+';
44684684ddb6SLionel Sambuc     if (__flags & ios_base::showpoint)
44694684ddb6SLionel Sambuc         *__fmtp++ = '#';
44704684ddb6SLionel Sambuc     ios_base::fmtflags floatfield = __flags & ios_base::floatfield;
44714684ddb6SLionel Sambuc     bool uppercase = (__flags & ios_base::uppercase) != 0;
44724684ddb6SLionel Sambuc     if (floatfield == (ios_base::fixed | ios_base::scientific))
44734684ddb6SLionel Sambuc         specify_precision = false;
44744684ddb6SLionel Sambuc     else
44754684ddb6SLionel Sambuc     {
44764684ddb6SLionel Sambuc         *__fmtp++ = '.';
44774684ddb6SLionel Sambuc         *__fmtp++ = '*';
44784684ddb6SLionel Sambuc     }
44794684ddb6SLionel Sambuc     while(*__len)
44804684ddb6SLionel Sambuc         *__fmtp++ = *__len++;
44814684ddb6SLionel Sambuc     if (floatfield == ios_base::fixed)
44824684ddb6SLionel Sambuc     {
44834684ddb6SLionel Sambuc         if (uppercase)
44844684ddb6SLionel Sambuc             *__fmtp = 'F';
44854684ddb6SLionel Sambuc         else
44864684ddb6SLionel Sambuc             *__fmtp = 'f';
44874684ddb6SLionel Sambuc     }
44884684ddb6SLionel Sambuc     else if (floatfield == ios_base::scientific)
44894684ddb6SLionel Sambuc     {
44904684ddb6SLionel Sambuc         if (uppercase)
44914684ddb6SLionel Sambuc             *__fmtp = 'E';
44924684ddb6SLionel Sambuc         else
44934684ddb6SLionel Sambuc             *__fmtp = 'e';
44944684ddb6SLionel Sambuc     }
44954684ddb6SLionel Sambuc     else if (floatfield == (ios_base::fixed | ios_base::scientific))
44964684ddb6SLionel Sambuc     {
44974684ddb6SLionel Sambuc         if (uppercase)
44984684ddb6SLionel Sambuc             *__fmtp = 'A';
44994684ddb6SLionel Sambuc         else
45004684ddb6SLionel Sambuc             *__fmtp = 'a';
45014684ddb6SLionel Sambuc     }
45024684ddb6SLionel Sambuc     else
45034684ddb6SLionel Sambuc     {
45044684ddb6SLionel Sambuc         if (uppercase)
45054684ddb6SLionel Sambuc             *__fmtp = 'G';
45064684ddb6SLionel Sambuc         else
45074684ddb6SLionel Sambuc             *__fmtp = 'g';
45084684ddb6SLionel Sambuc     }
45094684ddb6SLionel Sambuc     return specify_precision;
45104684ddb6SLionel Sambuc }
45114684ddb6SLionel Sambuc 
45124684ddb6SLionel Sambuc char*
__identify_padding(char * __nb,char * __ne,const ios_base & __iob)45134684ddb6SLionel Sambuc __num_put_base::__identify_padding(char* __nb, char* __ne,
45144684ddb6SLionel Sambuc                                    const ios_base& __iob)
45154684ddb6SLionel Sambuc {
45164684ddb6SLionel Sambuc     switch (__iob.flags() & ios_base::adjustfield)
45174684ddb6SLionel Sambuc     {
45184684ddb6SLionel Sambuc     case ios_base::internal:
45194684ddb6SLionel Sambuc         if (__nb[0] == '-' || __nb[0] == '+')
45204684ddb6SLionel Sambuc             return __nb+1;
45214684ddb6SLionel Sambuc         if (__ne - __nb >= 2 && __nb[0] == '0'
45224684ddb6SLionel Sambuc                             && (__nb[1] == 'x' || __nb[1] == 'X'))
45234684ddb6SLionel Sambuc             return __nb+2;
45244684ddb6SLionel Sambuc         break;
45254684ddb6SLionel Sambuc     case ios_base::left:
45264684ddb6SLionel Sambuc         return __ne;
45274684ddb6SLionel Sambuc     case ios_base::right:
45284684ddb6SLionel Sambuc     default:
45294684ddb6SLionel Sambuc         break;
45304684ddb6SLionel Sambuc     }
45314684ddb6SLionel Sambuc     return __nb;
45324684ddb6SLionel Sambuc }
45334684ddb6SLionel Sambuc 
45344684ddb6SLionel Sambuc // time_get
45354684ddb6SLionel Sambuc 
45364684ddb6SLionel Sambuc static
45374684ddb6SLionel Sambuc string*
init_weeks()45384684ddb6SLionel Sambuc init_weeks()
45394684ddb6SLionel Sambuc {
45404684ddb6SLionel Sambuc     static string weeks[14];
45414684ddb6SLionel Sambuc     weeks[0]  = "Sunday";
45424684ddb6SLionel Sambuc     weeks[1]  = "Monday";
45434684ddb6SLionel Sambuc     weeks[2]  = "Tuesday";
45444684ddb6SLionel Sambuc     weeks[3]  = "Wednesday";
45454684ddb6SLionel Sambuc     weeks[4]  = "Thursday";
45464684ddb6SLionel Sambuc     weeks[5]  = "Friday";
45474684ddb6SLionel Sambuc     weeks[6]  = "Saturday";
45484684ddb6SLionel Sambuc     weeks[7]  = "Sun";
45494684ddb6SLionel Sambuc     weeks[8]  = "Mon";
45504684ddb6SLionel Sambuc     weeks[9]  = "Tue";
45514684ddb6SLionel Sambuc     weeks[10] = "Wed";
45524684ddb6SLionel Sambuc     weeks[11] = "Thu";
45534684ddb6SLionel Sambuc     weeks[12] = "Fri";
45544684ddb6SLionel Sambuc     weeks[13] = "Sat";
45554684ddb6SLionel Sambuc     return weeks;
45564684ddb6SLionel Sambuc }
45574684ddb6SLionel Sambuc 
45584684ddb6SLionel Sambuc static
45594684ddb6SLionel Sambuc wstring*
init_wweeks()45604684ddb6SLionel Sambuc init_wweeks()
45614684ddb6SLionel Sambuc {
45624684ddb6SLionel Sambuc     static wstring weeks[14];
45634684ddb6SLionel Sambuc     weeks[0]  = L"Sunday";
45644684ddb6SLionel Sambuc     weeks[1]  = L"Monday";
45654684ddb6SLionel Sambuc     weeks[2]  = L"Tuesday";
45664684ddb6SLionel Sambuc     weeks[3]  = L"Wednesday";
45674684ddb6SLionel Sambuc     weeks[4]  = L"Thursday";
45684684ddb6SLionel Sambuc     weeks[5]  = L"Friday";
45694684ddb6SLionel Sambuc     weeks[6]  = L"Saturday";
45704684ddb6SLionel Sambuc     weeks[7]  = L"Sun";
45714684ddb6SLionel Sambuc     weeks[8]  = L"Mon";
45724684ddb6SLionel Sambuc     weeks[9]  = L"Tue";
45734684ddb6SLionel Sambuc     weeks[10] = L"Wed";
45744684ddb6SLionel Sambuc     weeks[11] = L"Thu";
45754684ddb6SLionel Sambuc     weeks[12] = L"Fri";
45764684ddb6SLionel Sambuc     weeks[13] = L"Sat";
45774684ddb6SLionel Sambuc     return weeks;
45784684ddb6SLionel Sambuc }
45794684ddb6SLionel Sambuc 
45804684ddb6SLionel Sambuc template <>
45814684ddb6SLionel Sambuc const string*
__weeks() const45824684ddb6SLionel Sambuc __time_get_c_storage<char>::__weeks() const
45834684ddb6SLionel Sambuc {
45844684ddb6SLionel Sambuc     static const string* weeks = init_weeks();
45854684ddb6SLionel Sambuc     return weeks;
45864684ddb6SLionel Sambuc }
45874684ddb6SLionel Sambuc 
45884684ddb6SLionel Sambuc template <>
45894684ddb6SLionel Sambuc const wstring*
__weeks() const45904684ddb6SLionel Sambuc __time_get_c_storage<wchar_t>::__weeks() const
45914684ddb6SLionel Sambuc {
45924684ddb6SLionel Sambuc     static const wstring* weeks = init_wweeks();
45934684ddb6SLionel Sambuc     return weeks;
45944684ddb6SLionel Sambuc }
45954684ddb6SLionel Sambuc 
45964684ddb6SLionel Sambuc static
45974684ddb6SLionel Sambuc string*
init_months()45984684ddb6SLionel Sambuc init_months()
45994684ddb6SLionel Sambuc {
46004684ddb6SLionel Sambuc     static string months[24];
46014684ddb6SLionel Sambuc     months[0]  = "January";
46024684ddb6SLionel Sambuc     months[1]  = "February";
46034684ddb6SLionel Sambuc     months[2]  = "March";
46044684ddb6SLionel Sambuc     months[3]  = "April";
46054684ddb6SLionel Sambuc     months[4]  = "May";
46064684ddb6SLionel Sambuc     months[5]  = "June";
46074684ddb6SLionel Sambuc     months[6]  = "July";
46084684ddb6SLionel Sambuc     months[7]  = "August";
46094684ddb6SLionel Sambuc     months[8]  = "September";
46104684ddb6SLionel Sambuc     months[9]  = "October";
46114684ddb6SLionel Sambuc     months[10] = "November";
46124684ddb6SLionel Sambuc     months[11] = "December";
46134684ddb6SLionel Sambuc     months[12] = "Jan";
46144684ddb6SLionel Sambuc     months[13] = "Feb";
46154684ddb6SLionel Sambuc     months[14] = "Mar";
46164684ddb6SLionel Sambuc     months[15] = "Apr";
46174684ddb6SLionel Sambuc     months[16] = "May";
46184684ddb6SLionel Sambuc     months[17] = "Jun";
46194684ddb6SLionel Sambuc     months[18] = "Jul";
46204684ddb6SLionel Sambuc     months[19] = "Aug";
46214684ddb6SLionel Sambuc     months[20] = "Sep";
46224684ddb6SLionel Sambuc     months[21] = "Oct";
46234684ddb6SLionel Sambuc     months[22] = "Nov";
46244684ddb6SLionel Sambuc     months[23] = "Dec";
46254684ddb6SLionel Sambuc     return months;
46264684ddb6SLionel Sambuc }
46274684ddb6SLionel Sambuc 
46284684ddb6SLionel Sambuc static
46294684ddb6SLionel Sambuc wstring*
init_wmonths()46304684ddb6SLionel Sambuc init_wmonths()
46314684ddb6SLionel Sambuc {
46324684ddb6SLionel Sambuc     static wstring months[24];
46334684ddb6SLionel Sambuc     months[0]  = L"January";
46344684ddb6SLionel Sambuc     months[1]  = L"February";
46354684ddb6SLionel Sambuc     months[2]  = L"March";
46364684ddb6SLionel Sambuc     months[3]  = L"April";
46374684ddb6SLionel Sambuc     months[4]  = L"May";
46384684ddb6SLionel Sambuc     months[5]  = L"June";
46394684ddb6SLionel Sambuc     months[6]  = L"July";
46404684ddb6SLionel Sambuc     months[7]  = L"August";
46414684ddb6SLionel Sambuc     months[8]  = L"September";
46424684ddb6SLionel Sambuc     months[9]  = L"October";
46434684ddb6SLionel Sambuc     months[10] = L"November";
46444684ddb6SLionel Sambuc     months[11] = L"December";
46454684ddb6SLionel Sambuc     months[12] = L"Jan";
46464684ddb6SLionel Sambuc     months[13] = L"Feb";
46474684ddb6SLionel Sambuc     months[14] = L"Mar";
46484684ddb6SLionel Sambuc     months[15] = L"Apr";
46494684ddb6SLionel Sambuc     months[16] = L"May";
46504684ddb6SLionel Sambuc     months[17] = L"Jun";
46514684ddb6SLionel Sambuc     months[18] = L"Jul";
46524684ddb6SLionel Sambuc     months[19] = L"Aug";
46534684ddb6SLionel Sambuc     months[20] = L"Sep";
46544684ddb6SLionel Sambuc     months[21] = L"Oct";
46554684ddb6SLionel Sambuc     months[22] = L"Nov";
46564684ddb6SLionel Sambuc     months[23] = L"Dec";
46574684ddb6SLionel Sambuc     return months;
46584684ddb6SLionel Sambuc }
46594684ddb6SLionel Sambuc 
46604684ddb6SLionel Sambuc template <>
46614684ddb6SLionel Sambuc const string*
__months() const46624684ddb6SLionel Sambuc __time_get_c_storage<char>::__months() const
46634684ddb6SLionel Sambuc {
46644684ddb6SLionel Sambuc     static const string* months = init_months();
46654684ddb6SLionel Sambuc     return months;
46664684ddb6SLionel Sambuc }
46674684ddb6SLionel Sambuc 
46684684ddb6SLionel Sambuc template <>
46694684ddb6SLionel Sambuc const wstring*
__months() const46704684ddb6SLionel Sambuc __time_get_c_storage<wchar_t>::__months() const
46714684ddb6SLionel Sambuc {
46724684ddb6SLionel Sambuc     static const wstring* months = init_wmonths();
46734684ddb6SLionel Sambuc     return months;
46744684ddb6SLionel Sambuc }
46754684ddb6SLionel Sambuc 
46764684ddb6SLionel Sambuc static
46774684ddb6SLionel Sambuc string*
init_am_pm()46784684ddb6SLionel Sambuc init_am_pm()
46794684ddb6SLionel Sambuc {
46804684ddb6SLionel Sambuc     static string am_pm[24];
46814684ddb6SLionel Sambuc     am_pm[0]  = "AM";
46824684ddb6SLionel Sambuc     am_pm[1]  = "PM";
46834684ddb6SLionel Sambuc     return am_pm;
46844684ddb6SLionel Sambuc }
46854684ddb6SLionel Sambuc 
46864684ddb6SLionel Sambuc static
46874684ddb6SLionel Sambuc wstring*
init_wam_pm()46884684ddb6SLionel Sambuc init_wam_pm()
46894684ddb6SLionel Sambuc {
46904684ddb6SLionel Sambuc     static wstring am_pm[24];
46914684ddb6SLionel Sambuc     am_pm[0]  = L"AM";
46924684ddb6SLionel Sambuc     am_pm[1]  = L"PM";
46934684ddb6SLionel Sambuc     return am_pm;
46944684ddb6SLionel Sambuc }
46954684ddb6SLionel Sambuc 
46964684ddb6SLionel Sambuc template <>
46974684ddb6SLionel Sambuc const string*
__am_pm() const46984684ddb6SLionel Sambuc __time_get_c_storage<char>::__am_pm() const
46994684ddb6SLionel Sambuc {
47004684ddb6SLionel Sambuc     static const string* am_pm = init_am_pm();
47014684ddb6SLionel Sambuc     return am_pm;
47024684ddb6SLionel Sambuc }
47034684ddb6SLionel Sambuc 
47044684ddb6SLionel Sambuc template <>
47054684ddb6SLionel Sambuc const wstring*
__am_pm() const47064684ddb6SLionel Sambuc __time_get_c_storage<wchar_t>::__am_pm() const
47074684ddb6SLionel Sambuc {
47084684ddb6SLionel Sambuc     static const wstring* am_pm = init_wam_pm();
47094684ddb6SLionel Sambuc     return am_pm;
47104684ddb6SLionel Sambuc }
47114684ddb6SLionel Sambuc 
47124684ddb6SLionel Sambuc template <>
47134684ddb6SLionel Sambuc const string&
__x() const47144684ddb6SLionel Sambuc __time_get_c_storage<char>::__x() const
47154684ddb6SLionel Sambuc {
47164684ddb6SLionel Sambuc     static string s("%m/%d/%y");
47174684ddb6SLionel Sambuc     return s;
47184684ddb6SLionel Sambuc }
47194684ddb6SLionel Sambuc 
47204684ddb6SLionel Sambuc template <>
47214684ddb6SLionel Sambuc const wstring&
__x() const47224684ddb6SLionel Sambuc __time_get_c_storage<wchar_t>::__x() const
47234684ddb6SLionel Sambuc {
47244684ddb6SLionel Sambuc     static wstring s(L"%m/%d/%y");
47254684ddb6SLionel Sambuc     return s;
47264684ddb6SLionel Sambuc }
47274684ddb6SLionel Sambuc 
47284684ddb6SLionel Sambuc template <>
47294684ddb6SLionel Sambuc const string&
__X() const47304684ddb6SLionel Sambuc __time_get_c_storage<char>::__X() const
47314684ddb6SLionel Sambuc {
47324684ddb6SLionel Sambuc     static string s("%H:%M:%S");
47334684ddb6SLionel Sambuc     return s;
47344684ddb6SLionel Sambuc }
47354684ddb6SLionel Sambuc 
47364684ddb6SLionel Sambuc template <>
47374684ddb6SLionel Sambuc const wstring&
__X() const47384684ddb6SLionel Sambuc __time_get_c_storage<wchar_t>::__X() const
47394684ddb6SLionel Sambuc {
47404684ddb6SLionel Sambuc     static wstring s(L"%H:%M:%S");
47414684ddb6SLionel Sambuc     return s;
47424684ddb6SLionel Sambuc }
47434684ddb6SLionel Sambuc 
47444684ddb6SLionel Sambuc template <>
47454684ddb6SLionel Sambuc const string&
__c() const47464684ddb6SLionel Sambuc __time_get_c_storage<char>::__c() const
47474684ddb6SLionel Sambuc {
47484684ddb6SLionel Sambuc     static string s("%a %b %d %H:%M:%S %Y");
47494684ddb6SLionel Sambuc     return s;
47504684ddb6SLionel Sambuc }
47514684ddb6SLionel Sambuc 
47524684ddb6SLionel Sambuc template <>
47534684ddb6SLionel Sambuc const wstring&
__c() const47544684ddb6SLionel Sambuc __time_get_c_storage<wchar_t>::__c() const
47554684ddb6SLionel Sambuc {
47564684ddb6SLionel Sambuc     static wstring s(L"%a %b %d %H:%M:%S %Y");
47574684ddb6SLionel Sambuc     return s;
47584684ddb6SLionel Sambuc }
47594684ddb6SLionel Sambuc 
47604684ddb6SLionel Sambuc template <>
47614684ddb6SLionel Sambuc const string&
__r() const47624684ddb6SLionel Sambuc __time_get_c_storage<char>::__r() const
47634684ddb6SLionel Sambuc {
47644684ddb6SLionel Sambuc     static string s("%I:%M:%S %p");
47654684ddb6SLionel Sambuc     return s;
47664684ddb6SLionel Sambuc }
47674684ddb6SLionel Sambuc 
47684684ddb6SLionel Sambuc template <>
47694684ddb6SLionel Sambuc const wstring&
__r() const47704684ddb6SLionel Sambuc __time_get_c_storage<wchar_t>::__r() const
47714684ddb6SLionel Sambuc {
47724684ddb6SLionel Sambuc     static wstring s(L"%I:%M:%S %p");
47734684ddb6SLionel Sambuc     return s;
47744684ddb6SLionel Sambuc }
47754684ddb6SLionel Sambuc 
47764684ddb6SLionel Sambuc // time_get_byname
47774684ddb6SLionel Sambuc 
__time_get(const char * nm)47784684ddb6SLionel Sambuc __time_get::__time_get(const char* nm)
47794684ddb6SLionel Sambuc     : __loc_(newlocale(LC_ALL_MASK, nm, 0))
47804684ddb6SLionel Sambuc {
47814684ddb6SLionel Sambuc #ifndef _LIBCPP_NO_EXCEPTIONS
47824684ddb6SLionel Sambuc     if (__loc_ == 0)
47834684ddb6SLionel Sambuc         throw runtime_error("time_get_byname"
47844684ddb6SLionel Sambuc                             " failed to construct for " + string(nm));
47854684ddb6SLionel Sambuc #endif  // _LIBCPP_NO_EXCEPTIONS
47864684ddb6SLionel Sambuc }
47874684ddb6SLionel Sambuc 
__time_get(const string & nm)47884684ddb6SLionel Sambuc __time_get::__time_get(const string& nm)
47894684ddb6SLionel Sambuc     : __loc_(newlocale(LC_ALL_MASK, nm.c_str(), 0))
47904684ddb6SLionel Sambuc {
47914684ddb6SLionel Sambuc #ifndef _LIBCPP_NO_EXCEPTIONS
47924684ddb6SLionel Sambuc     if (__loc_ == 0)
47934684ddb6SLionel Sambuc         throw runtime_error("time_get_byname"
47944684ddb6SLionel Sambuc                             " failed to construct for " + nm);
47954684ddb6SLionel Sambuc #endif  // _LIBCPP_NO_EXCEPTIONS
47964684ddb6SLionel Sambuc }
47974684ddb6SLionel Sambuc 
~__time_get()47984684ddb6SLionel Sambuc __time_get::~__time_get()
47994684ddb6SLionel Sambuc {
48004684ddb6SLionel Sambuc     freelocale(__loc_);
48014684ddb6SLionel Sambuc }
48024684ddb6SLionel Sambuc #if defined(__clang__)
48034684ddb6SLionel Sambuc #pragma clang diagnostic ignored "-Wmissing-field-initializers"
48044684ddb6SLionel Sambuc #endif
48054684ddb6SLionel Sambuc #if defined(__GNUG__)
48064684ddb6SLionel Sambuc #pragma GCC   diagnostic ignored "-Wmissing-field-initializers"
48074684ddb6SLionel Sambuc #endif
48084684ddb6SLionel Sambuc 
48094684ddb6SLionel Sambuc template <>
48104684ddb6SLionel Sambuc string
__analyze(char fmt,const ctype<char> & ct)48114684ddb6SLionel Sambuc __time_get_storage<char>::__analyze(char fmt, const ctype<char>& ct)
48124684ddb6SLionel Sambuc {
48134684ddb6SLionel Sambuc     tm t = {0};
48144684ddb6SLionel Sambuc     t.tm_sec = 59;
48154684ddb6SLionel Sambuc     t.tm_min = 55;
48164684ddb6SLionel Sambuc     t.tm_hour = 23;
48174684ddb6SLionel Sambuc     t.tm_mday = 31;
48184684ddb6SLionel Sambuc     t.tm_mon = 11;
48194684ddb6SLionel Sambuc     t.tm_year = 161;
48204684ddb6SLionel Sambuc     t.tm_wday = 6;
48214684ddb6SLionel Sambuc     t.tm_yday = 364;
48224684ddb6SLionel Sambuc     t.tm_isdst = -1;
48234684ddb6SLionel Sambuc     char buf[100];
48244684ddb6SLionel Sambuc     char f[3] = {0};
48254684ddb6SLionel Sambuc     f[0] = '%';
48264684ddb6SLionel Sambuc     f[1] = fmt;
48274684ddb6SLionel Sambuc     size_t n = strftime_l(buf, countof(buf), f, &t, __loc_);
48284684ddb6SLionel Sambuc     char* bb = buf;
48294684ddb6SLionel Sambuc     char* be = buf + n;
48304684ddb6SLionel Sambuc     string result;
48314684ddb6SLionel Sambuc     while (bb != be)
48324684ddb6SLionel Sambuc     {
48334684ddb6SLionel Sambuc         if (ct.is(ctype_base::space, *bb))
48344684ddb6SLionel Sambuc         {
48354684ddb6SLionel Sambuc             result.push_back(' ');
48364684ddb6SLionel Sambuc             for (++bb; bb != be && ct.is(ctype_base::space, *bb); ++bb)
48374684ddb6SLionel Sambuc                 ;
48384684ddb6SLionel Sambuc             continue;
48394684ddb6SLionel Sambuc         }
48404684ddb6SLionel Sambuc         char* w = bb;
48414684ddb6SLionel Sambuc         ios_base::iostate err = ios_base::goodbit;
48424684ddb6SLionel Sambuc         ptrdiff_t i = __scan_keyword(w, be, this->__weeks_, this->__weeks_+14,
48434684ddb6SLionel Sambuc                                ct, err, false)
48444684ddb6SLionel Sambuc                                - this->__weeks_;
48454684ddb6SLionel Sambuc         if (i < 14)
48464684ddb6SLionel Sambuc         {
48474684ddb6SLionel Sambuc             result.push_back('%');
48484684ddb6SLionel Sambuc             if (i < 7)
48494684ddb6SLionel Sambuc                 result.push_back('A');
48504684ddb6SLionel Sambuc             else
48514684ddb6SLionel Sambuc                 result.push_back('a');
48524684ddb6SLionel Sambuc             bb = w;
48534684ddb6SLionel Sambuc             continue;
48544684ddb6SLionel Sambuc         }
48554684ddb6SLionel Sambuc         w = bb;
48564684ddb6SLionel Sambuc         i = __scan_keyword(w, be, this->__months_, this->__months_+24,
48574684ddb6SLionel Sambuc                            ct, err, false)
48584684ddb6SLionel Sambuc                            - this->__months_;
48594684ddb6SLionel Sambuc         if (i < 24)
48604684ddb6SLionel Sambuc         {
48614684ddb6SLionel Sambuc             result.push_back('%');
48624684ddb6SLionel Sambuc             if (i < 12)
48634684ddb6SLionel Sambuc                 result.push_back('B');
48644684ddb6SLionel Sambuc             else
48654684ddb6SLionel Sambuc                 result.push_back('b');
48664684ddb6SLionel Sambuc             if (fmt == 'x' && ct.is(ctype_base::digit, this->__months_[i][0]))
48674684ddb6SLionel Sambuc                 result.back() = 'm';
48684684ddb6SLionel Sambuc             bb = w;
48694684ddb6SLionel Sambuc             continue;
48704684ddb6SLionel Sambuc         }
48714684ddb6SLionel Sambuc         if (this->__am_pm_[0].size() + this->__am_pm_[1].size() > 0)
48724684ddb6SLionel Sambuc         {
48734684ddb6SLionel Sambuc             w = bb;
48744684ddb6SLionel Sambuc             i = __scan_keyword(w, be, this->__am_pm_, this->__am_pm_+2,
48754684ddb6SLionel Sambuc                                ct, err, false) - this->__am_pm_;
48764684ddb6SLionel Sambuc             if (i < 2)
48774684ddb6SLionel Sambuc             {
48784684ddb6SLionel Sambuc                 result.push_back('%');
48794684ddb6SLionel Sambuc                 result.push_back('p');
48804684ddb6SLionel Sambuc                 bb = w;
48814684ddb6SLionel Sambuc                 continue;
48824684ddb6SLionel Sambuc             }
48834684ddb6SLionel Sambuc         }
48844684ddb6SLionel Sambuc         w = bb;
48854684ddb6SLionel Sambuc         if (ct.is(ctype_base::digit, *bb))
48864684ddb6SLionel Sambuc         {
48874684ddb6SLionel Sambuc             switch(__get_up_to_n_digits(bb, be, err, ct, 4))
48884684ddb6SLionel Sambuc             {
48894684ddb6SLionel Sambuc             case 6:
48904684ddb6SLionel Sambuc                 result.push_back('%');
48914684ddb6SLionel Sambuc                 result.push_back('w');
48924684ddb6SLionel Sambuc                 break;
48934684ddb6SLionel Sambuc             case 7:
48944684ddb6SLionel Sambuc                 result.push_back('%');
48954684ddb6SLionel Sambuc                 result.push_back('u');
48964684ddb6SLionel Sambuc                 break;
48974684ddb6SLionel Sambuc             case 11:
48984684ddb6SLionel Sambuc                 result.push_back('%');
48994684ddb6SLionel Sambuc                 result.push_back('I');
49004684ddb6SLionel Sambuc                 break;
49014684ddb6SLionel Sambuc             case 12:
49024684ddb6SLionel Sambuc                 result.push_back('%');
49034684ddb6SLionel Sambuc                 result.push_back('m');
49044684ddb6SLionel Sambuc                 break;
49054684ddb6SLionel Sambuc             case 23:
49064684ddb6SLionel Sambuc                 result.push_back('%');
49074684ddb6SLionel Sambuc                 result.push_back('H');
49084684ddb6SLionel Sambuc                 break;
49094684ddb6SLionel Sambuc             case 31:
49104684ddb6SLionel Sambuc                 result.push_back('%');
49114684ddb6SLionel Sambuc                 result.push_back('d');
49124684ddb6SLionel Sambuc                 break;
49134684ddb6SLionel Sambuc             case 55:
49144684ddb6SLionel Sambuc                 result.push_back('%');
49154684ddb6SLionel Sambuc                 result.push_back('M');
49164684ddb6SLionel Sambuc                 break;
49174684ddb6SLionel Sambuc             case 59:
49184684ddb6SLionel Sambuc                 result.push_back('%');
49194684ddb6SLionel Sambuc                 result.push_back('S');
49204684ddb6SLionel Sambuc                 break;
49214684ddb6SLionel Sambuc             case 61:
49224684ddb6SLionel Sambuc                 result.push_back('%');
49234684ddb6SLionel Sambuc                 result.push_back('y');
49244684ddb6SLionel Sambuc                 break;
49254684ddb6SLionel Sambuc             case 364:
49264684ddb6SLionel Sambuc                 result.push_back('%');
49274684ddb6SLionel Sambuc                 result.push_back('j');
49284684ddb6SLionel Sambuc                 break;
49294684ddb6SLionel Sambuc             case 2061:
49304684ddb6SLionel Sambuc                 result.push_back('%');
49314684ddb6SLionel Sambuc                 result.push_back('Y');
49324684ddb6SLionel Sambuc                 break;
49334684ddb6SLionel Sambuc             default:
49344684ddb6SLionel Sambuc                 for (; w != bb; ++w)
49354684ddb6SLionel Sambuc                     result.push_back(*w);
49364684ddb6SLionel Sambuc                 break;
49374684ddb6SLionel Sambuc             }
49384684ddb6SLionel Sambuc             continue;
49394684ddb6SLionel Sambuc         }
49404684ddb6SLionel Sambuc         if (*bb == '%')
49414684ddb6SLionel Sambuc         {
49424684ddb6SLionel Sambuc             result.push_back('%');
49434684ddb6SLionel Sambuc             result.push_back('%');
49444684ddb6SLionel Sambuc             ++bb;
49454684ddb6SLionel Sambuc             continue;
49464684ddb6SLionel Sambuc         }
49474684ddb6SLionel Sambuc         result.push_back(*bb);
49484684ddb6SLionel Sambuc         ++bb;
49494684ddb6SLionel Sambuc     }
49504684ddb6SLionel Sambuc     return result;
49514684ddb6SLionel Sambuc }
49524684ddb6SLionel Sambuc 
49534684ddb6SLionel Sambuc #if defined(__clang__)
49544684ddb6SLionel Sambuc #pragma clang diagnostic ignored "-Wmissing-braces"
49554684ddb6SLionel Sambuc #endif
49564684ddb6SLionel Sambuc 
49574684ddb6SLionel Sambuc template <>
49584684ddb6SLionel Sambuc wstring
__analyze(char fmt,const ctype<wchar_t> & ct)49594684ddb6SLionel Sambuc __time_get_storage<wchar_t>::__analyze(char fmt, const ctype<wchar_t>& ct)
49604684ddb6SLionel Sambuc {
49614684ddb6SLionel Sambuc     tm t = {0};
49624684ddb6SLionel Sambuc     t.tm_sec = 59;
49634684ddb6SLionel Sambuc     t.tm_min = 55;
49644684ddb6SLionel Sambuc     t.tm_hour = 23;
49654684ddb6SLionel Sambuc     t.tm_mday = 31;
49664684ddb6SLionel Sambuc     t.tm_mon = 11;
49674684ddb6SLionel Sambuc     t.tm_year = 161;
49684684ddb6SLionel Sambuc     t.tm_wday = 6;
49694684ddb6SLionel Sambuc     t.tm_yday = 364;
49704684ddb6SLionel Sambuc     t.tm_isdst = -1;
49714684ddb6SLionel Sambuc     char buf[100];
49724684ddb6SLionel Sambuc     char f[3] = {0};
49734684ddb6SLionel Sambuc     f[0] = '%';
49744684ddb6SLionel Sambuc     f[1] = fmt;
49754684ddb6SLionel Sambuc     strftime_l(buf, countof(buf), f, &t, __loc_);
49764684ddb6SLionel Sambuc     wchar_t wbuf[100];
49774684ddb6SLionel Sambuc     wchar_t* wbb = wbuf;
49784684ddb6SLionel Sambuc     mbstate_t mb = {0};
49794684ddb6SLionel Sambuc     const char* bb = buf;
49804684ddb6SLionel Sambuc #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
49814684ddb6SLionel Sambuc     size_t j = mbsrtowcs_l( wbb, &bb, countof(wbuf), &mb, __loc_);
49824684ddb6SLionel Sambuc #else
49834684ddb6SLionel Sambuc     size_t j = __mbsrtowcs_l( wbb, &bb, countof(wbuf), &mb, __loc_);
49844684ddb6SLionel Sambuc #endif
49854684ddb6SLionel Sambuc     if (j == size_t(-1))
49864684ddb6SLionel Sambuc         __throw_runtime_error("locale not supported");
49874684ddb6SLionel Sambuc     wchar_t* wbe = wbb + j;
49884684ddb6SLionel Sambuc     wstring result;
49894684ddb6SLionel Sambuc     while (wbb != wbe)
49904684ddb6SLionel Sambuc     {
49914684ddb6SLionel Sambuc         if (ct.is(ctype_base::space, *wbb))
49924684ddb6SLionel Sambuc         {
49934684ddb6SLionel Sambuc             result.push_back(L' ');
49944684ddb6SLionel Sambuc             for (++wbb; wbb != wbe && ct.is(ctype_base::space, *wbb); ++wbb)
49954684ddb6SLionel Sambuc                 ;
49964684ddb6SLionel Sambuc             continue;
49974684ddb6SLionel Sambuc         }
49984684ddb6SLionel Sambuc         wchar_t* w = wbb;
49994684ddb6SLionel Sambuc         ios_base::iostate err = ios_base::goodbit;
50004684ddb6SLionel Sambuc         ptrdiff_t i = __scan_keyword(w, wbe, this->__weeks_, this->__weeks_+14,
50014684ddb6SLionel Sambuc                                ct, err, false)
50024684ddb6SLionel Sambuc                                - this->__weeks_;
50034684ddb6SLionel Sambuc         if (i < 14)
50044684ddb6SLionel Sambuc         {
50054684ddb6SLionel Sambuc             result.push_back(L'%');
50064684ddb6SLionel Sambuc             if (i < 7)
50074684ddb6SLionel Sambuc                 result.push_back(L'A');
50084684ddb6SLionel Sambuc             else
50094684ddb6SLionel Sambuc                 result.push_back(L'a');
50104684ddb6SLionel Sambuc             wbb = w;
50114684ddb6SLionel Sambuc             continue;
50124684ddb6SLionel Sambuc         }
50134684ddb6SLionel Sambuc         w = wbb;
50144684ddb6SLionel Sambuc         i = __scan_keyword(w, wbe, this->__months_, this->__months_+24,
50154684ddb6SLionel Sambuc                            ct, err, false)
50164684ddb6SLionel Sambuc                            - this->__months_;
50174684ddb6SLionel Sambuc         if (i < 24)
50184684ddb6SLionel Sambuc         {
50194684ddb6SLionel Sambuc             result.push_back(L'%');
50204684ddb6SLionel Sambuc             if (i < 12)
50214684ddb6SLionel Sambuc                 result.push_back(L'B');
50224684ddb6SLionel Sambuc             else
50234684ddb6SLionel Sambuc                 result.push_back(L'b');
50244684ddb6SLionel Sambuc             if (fmt == 'x' && ct.is(ctype_base::digit, this->__months_[i][0]))
50254684ddb6SLionel Sambuc                 result.back() = L'm';
50264684ddb6SLionel Sambuc             wbb = w;
50274684ddb6SLionel Sambuc             continue;
50284684ddb6SLionel Sambuc         }
50294684ddb6SLionel Sambuc         if (this->__am_pm_[0].size() + this->__am_pm_[1].size() > 0)
50304684ddb6SLionel Sambuc         {
50314684ddb6SLionel Sambuc             w = wbb;
50324684ddb6SLionel Sambuc             i = __scan_keyword(w, wbe, this->__am_pm_, this->__am_pm_+2,
50334684ddb6SLionel Sambuc                                ct, err, false) - this->__am_pm_;
50344684ddb6SLionel Sambuc             if (i < 2)
50354684ddb6SLionel Sambuc             {
50364684ddb6SLionel Sambuc                 result.push_back(L'%');
50374684ddb6SLionel Sambuc                 result.push_back(L'p');
50384684ddb6SLionel Sambuc                 wbb = w;
50394684ddb6SLionel Sambuc                 continue;
50404684ddb6SLionel Sambuc             }
50414684ddb6SLionel Sambuc         }
50424684ddb6SLionel Sambuc         w = wbb;
50434684ddb6SLionel Sambuc         if (ct.is(ctype_base::digit, *wbb))
50444684ddb6SLionel Sambuc         {
50454684ddb6SLionel Sambuc             switch(__get_up_to_n_digits(wbb, wbe, err, ct, 4))
50464684ddb6SLionel Sambuc             {
50474684ddb6SLionel Sambuc             case 6:
50484684ddb6SLionel Sambuc                 result.push_back(L'%');
50494684ddb6SLionel Sambuc                 result.push_back(L'w');
50504684ddb6SLionel Sambuc                 break;
50514684ddb6SLionel Sambuc             case 7:
50524684ddb6SLionel Sambuc                 result.push_back(L'%');
50534684ddb6SLionel Sambuc                 result.push_back(L'u');
50544684ddb6SLionel Sambuc                 break;
50554684ddb6SLionel Sambuc             case 11:
50564684ddb6SLionel Sambuc                 result.push_back(L'%');
50574684ddb6SLionel Sambuc                 result.push_back(L'I');
50584684ddb6SLionel Sambuc                 break;
50594684ddb6SLionel Sambuc             case 12:
50604684ddb6SLionel Sambuc                 result.push_back(L'%');
50614684ddb6SLionel Sambuc                 result.push_back(L'm');
50624684ddb6SLionel Sambuc                 break;
50634684ddb6SLionel Sambuc             case 23:
50644684ddb6SLionel Sambuc                 result.push_back(L'%');
50654684ddb6SLionel Sambuc                 result.push_back(L'H');
50664684ddb6SLionel Sambuc                 break;
50674684ddb6SLionel Sambuc             case 31:
50684684ddb6SLionel Sambuc                 result.push_back(L'%');
50694684ddb6SLionel Sambuc                 result.push_back(L'd');
50704684ddb6SLionel Sambuc                 break;
50714684ddb6SLionel Sambuc             case 55:
50724684ddb6SLionel Sambuc                 result.push_back(L'%');
50734684ddb6SLionel Sambuc                 result.push_back(L'M');
50744684ddb6SLionel Sambuc                 break;
50754684ddb6SLionel Sambuc             case 59:
50764684ddb6SLionel Sambuc                 result.push_back(L'%');
50774684ddb6SLionel Sambuc                 result.push_back(L'S');
50784684ddb6SLionel Sambuc                 break;
50794684ddb6SLionel Sambuc             case 61:
50804684ddb6SLionel Sambuc                 result.push_back(L'%');
50814684ddb6SLionel Sambuc                 result.push_back(L'y');
50824684ddb6SLionel Sambuc                 break;
50834684ddb6SLionel Sambuc             case 364:
50844684ddb6SLionel Sambuc                 result.push_back(L'%');
50854684ddb6SLionel Sambuc                 result.push_back(L'j');
50864684ddb6SLionel Sambuc                 break;
50874684ddb6SLionel Sambuc             case 2061:
50884684ddb6SLionel Sambuc                 result.push_back(L'%');
50894684ddb6SLionel Sambuc                 result.push_back(L'Y');
50904684ddb6SLionel Sambuc                 break;
50914684ddb6SLionel Sambuc             default:
50924684ddb6SLionel Sambuc                 for (; w != wbb; ++w)
50934684ddb6SLionel Sambuc                     result.push_back(*w);
50944684ddb6SLionel Sambuc                 break;
50954684ddb6SLionel Sambuc             }
50964684ddb6SLionel Sambuc             continue;
50974684ddb6SLionel Sambuc         }
50984684ddb6SLionel Sambuc         if (ct.narrow(*wbb, 0) == '%')
50994684ddb6SLionel Sambuc         {
51004684ddb6SLionel Sambuc             result.push_back(L'%');
51014684ddb6SLionel Sambuc             result.push_back(L'%');
51024684ddb6SLionel Sambuc             ++wbb;
51034684ddb6SLionel Sambuc             continue;
51044684ddb6SLionel Sambuc         }
51054684ddb6SLionel Sambuc         result.push_back(*wbb);
51064684ddb6SLionel Sambuc         ++wbb;
51074684ddb6SLionel Sambuc     }
51084684ddb6SLionel Sambuc     return result;
51094684ddb6SLionel Sambuc }
51104684ddb6SLionel Sambuc 
51114684ddb6SLionel Sambuc template <>
51124684ddb6SLionel Sambuc void
init(const ctype<char> & ct)51134684ddb6SLionel Sambuc __time_get_storage<char>::init(const ctype<char>& ct)
51144684ddb6SLionel Sambuc {
51154684ddb6SLionel Sambuc     tm t = {0};
51164684ddb6SLionel Sambuc     char buf[100];
51174684ddb6SLionel Sambuc     // __weeks_
51184684ddb6SLionel Sambuc     for (int i = 0; i < 7; ++i)
51194684ddb6SLionel Sambuc     {
51204684ddb6SLionel Sambuc         t.tm_wday = i;
51214684ddb6SLionel Sambuc         strftime_l(buf, countof(buf), "%A", &t, __loc_);
51224684ddb6SLionel Sambuc         __weeks_[i] = buf;
51234684ddb6SLionel Sambuc         strftime_l(buf, countof(buf), "%a", &t, __loc_);
51244684ddb6SLionel Sambuc         __weeks_[i+7] = buf;
51254684ddb6SLionel Sambuc     }
51264684ddb6SLionel Sambuc     // __months_
51274684ddb6SLionel Sambuc     for (int i = 0; i < 12; ++i)
51284684ddb6SLionel Sambuc     {
51294684ddb6SLionel Sambuc         t.tm_mon = i;
51304684ddb6SLionel Sambuc         strftime_l(buf, countof(buf), "%B", &t, __loc_);
51314684ddb6SLionel Sambuc         __months_[i] = buf;
51324684ddb6SLionel Sambuc         strftime_l(buf, countof(buf), "%b", &t, __loc_);
51334684ddb6SLionel Sambuc         __months_[i+12] = buf;
51344684ddb6SLionel Sambuc     }
51354684ddb6SLionel Sambuc     // __am_pm_
51364684ddb6SLionel Sambuc     t.tm_hour = 1;
51374684ddb6SLionel Sambuc     strftime_l(buf, countof(buf), "%p", &t, __loc_);
51384684ddb6SLionel Sambuc     __am_pm_[0] = buf;
51394684ddb6SLionel Sambuc     t.tm_hour = 13;
51404684ddb6SLionel Sambuc     strftime_l(buf, countof(buf), "%p", &t, __loc_);
51414684ddb6SLionel Sambuc     __am_pm_[1] = buf;
51424684ddb6SLionel Sambuc     __c_ = __analyze('c', ct);
51434684ddb6SLionel Sambuc     __r_ = __analyze('r', ct);
51444684ddb6SLionel Sambuc     __x_ = __analyze('x', ct);
51454684ddb6SLionel Sambuc     __X_ = __analyze('X', ct);
51464684ddb6SLionel Sambuc }
51474684ddb6SLionel Sambuc 
51484684ddb6SLionel Sambuc template <>
51494684ddb6SLionel Sambuc void
init(const ctype<wchar_t> & ct)51504684ddb6SLionel Sambuc __time_get_storage<wchar_t>::init(const ctype<wchar_t>& ct)
51514684ddb6SLionel Sambuc {
51524684ddb6SLionel Sambuc     tm t = {0};
51534684ddb6SLionel Sambuc     char buf[100];
51544684ddb6SLionel Sambuc     wchar_t wbuf[100];
51554684ddb6SLionel Sambuc     wchar_t* wbe;
51564684ddb6SLionel Sambuc     mbstate_t mb = {0};
51574684ddb6SLionel Sambuc     // __weeks_
51584684ddb6SLionel Sambuc     for (int i = 0; i < 7; ++i)
51594684ddb6SLionel Sambuc     {
51604684ddb6SLionel Sambuc         t.tm_wday = i;
51614684ddb6SLionel Sambuc         strftime_l(buf, countof(buf), "%A", &t, __loc_);
51624684ddb6SLionel Sambuc         mb = mbstate_t();
51634684ddb6SLionel Sambuc         const char* bb = buf;
51644684ddb6SLionel Sambuc #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
51654684ddb6SLionel Sambuc         size_t j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
51664684ddb6SLionel Sambuc #else
51674684ddb6SLionel Sambuc         size_t j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
51684684ddb6SLionel Sambuc #endif
51694684ddb6SLionel Sambuc         if (j == size_t(-1))
51704684ddb6SLionel Sambuc             __throw_runtime_error("locale not supported");
51714684ddb6SLionel Sambuc         wbe = wbuf + j;
51724684ddb6SLionel Sambuc         __weeks_[i].assign(wbuf, wbe);
51734684ddb6SLionel Sambuc         strftime_l(buf, countof(buf), "%a", &t, __loc_);
51744684ddb6SLionel Sambuc         mb = mbstate_t();
51754684ddb6SLionel Sambuc         bb = buf;
51764684ddb6SLionel Sambuc #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
51774684ddb6SLionel Sambuc         j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
51784684ddb6SLionel Sambuc #else
51794684ddb6SLionel Sambuc         j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
51804684ddb6SLionel Sambuc #endif
51814684ddb6SLionel Sambuc         if (j == size_t(-1))
51824684ddb6SLionel Sambuc             __throw_runtime_error("locale not supported");
51834684ddb6SLionel Sambuc         wbe = wbuf + j;
51844684ddb6SLionel Sambuc         __weeks_[i+7].assign(wbuf, wbe);
51854684ddb6SLionel Sambuc     }
51864684ddb6SLionel Sambuc     // __months_
51874684ddb6SLionel Sambuc     for (int i = 0; i < 12; ++i)
51884684ddb6SLionel Sambuc     {
51894684ddb6SLionel Sambuc         t.tm_mon = i;
51904684ddb6SLionel Sambuc         strftime_l(buf, countof(buf), "%B", &t, __loc_);
51914684ddb6SLionel Sambuc         mb = mbstate_t();
51924684ddb6SLionel Sambuc         const char* bb = buf;
51934684ddb6SLionel Sambuc #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
51944684ddb6SLionel Sambuc         size_t j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
51954684ddb6SLionel Sambuc #else
51964684ddb6SLionel Sambuc         size_t j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
51974684ddb6SLionel Sambuc #endif
51984684ddb6SLionel Sambuc         if (j == size_t(-1))
51994684ddb6SLionel Sambuc             __throw_runtime_error("locale not supported");
52004684ddb6SLionel Sambuc         wbe = wbuf + j;
52014684ddb6SLionel Sambuc         __months_[i].assign(wbuf, wbe);
52024684ddb6SLionel Sambuc         strftime_l(buf, countof(buf), "%b", &t, __loc_);
52034684ddb6SLionel Sambuc         mb = mbstate_t();
52044684ddb6SLionel Sambuc         bb = buf;
52054684ddb6SLionel Sambuc #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
52064684ddb6SLionel Sambuc         j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
52074684ddb6SLionel Sambuc #else
52084684ddb6SLionel Sambuc         j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
52094684ddb6SLionel Sambuc #endif
52104684ddb6SLionel Sambuc         if (j == size_t(-1))
52114684ddb6SLionel Sambuc             __throw_runtime_error("locale not supported");
52124684ddb6SLionel Sambuc         wbe = wbuf + j;
52134684ddb6SLionel Sambuc         __months_[i+12].assign(wbuf, wbe);
52144684ddb6SLionel Sambuc     }
52154684ddb6SLionel Sambuc     // __am_pm_
52164684ddb6SLionel Sambuc     t.tm_hour = 1;
52174684ddb6SLionel Sambuc     strftime_l(buf, countof(buf), "%p", &t, __loc_);
52184684ddb6SLionel Sambuc     mb = mbstate_t();
52194684ddb6SLionel Sambuc     const char* bb = buf;
52204684ddb6SLionel Sambuc #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
52214684ddb6SLionel Sambuc     size_t j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
52224684ddb6SLionel Sambuc #else
52234684ddb6SLionel Sambuc     size_t j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
52244684ddb6SLionel Sambuc #endif
52254684ddb6SLionel Sambuc     if (j == size_t(-1))
52264684ddb6SLionel Sambuc         __throw_runtime_error("locale not supported");
52274684ddb6SLionel Sambuc     wbe = wbuf + j;
52284684ddb6SLionel Sambuc     __am_pm_[0].assign(wbuf, wbe);
52294684ddb6SLionel Sambuc     t.tm_hour = 13;
52304684ddb6SLionel Sambuc     strftime_l(buf, countof(buf), "%p", &t, __loc_);
52314684ddb6SLionel Sambuc     mb = mbstate_t();
52324684ddb6SLionel Sambuc     bb = buf;
52334684ddb6SLionel Sambuc #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
52344684ddb6SLionel Sambuc     j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
52354684ddb6SLionel Sambuc #else
52364684ddb6SLionel Sambuc     j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
52374684ddb6SLionel Sambuc #endif
52384684ddb6SLionel Sambuc     if (j == size_t(-1))
52394684ddb6SLionel Sambuc         __throw_runtime_error("locale not supported");
52404684ddb6SLionel Sambuc     wbe = wbuf + j;
52414684ddb6SLionel Sambuc     __am_pm_[1].assign(wbuf, wbe);
52424684ddb6SLionel Sambuc     __c_ = __analyze('c', ct);
52434684ddb6SLionel Sambuc     __r_ = __analyze('r', ct);
52444684ddb6SLionel Sambuc     __x_ = __analyze('x', ct);
52454684ddb6SLionel Sambuc     __X_ = __analyze('X', ct);
52464684ddb6SLionel Sambuc }
52474684ddb6SLionel Sambuc 
52484684ddb6SLionel Sambuc template <class CharT>
52494684ddb6SLionel Sambuc struct _LIBCPP_HIDDEN __time_get_temp
52504684ddb6SLionel Sambuc     : public ctype_byname<CharT>
52514684ddb6SLionel Sambuc {
__time_get_temp__time_get_temp52524684ddb6SLionel Sambuc     explicit __time_get_temp(const char* nm)
52534684ddb6SLionel Sambuc         : ctype_byname<CharT>(nm, 1) {}
__time_get_temp__time_get_temp52544684ddb6SLionel Sambuc     explicit __time_get_temp(const string& nm)
52554684ddb6SLionel Sambuc         : ctype_byname<CharT>(nm, 1) {}
52564684ddb6SLionel Sambuc };
52574684ddb6SLionel Sambuc 
52584684ddb6SLionel Sambuc template <>
__time_get_storage(const char * __nm)52594684ddb6SLionel Sambuc __time_get_storage<char>::__time_get_storage(const char* __nm)
52604684ddb6SLionel Sambuc     : __time_get(__nm)
52614684ddb6SLionel Sambuc {
52624684ddb6SLionel Sambuc     const __time_get_temp<char> ct(__nm);
52634684ddb6SLionel Sambuc     init(ct);
52644684ddb6SLionel Sambuc }
52654684ddb6SLionel Sambuc 
52664684ddb6SLionel Sambuc template <>
__time_get_storage(const string & __nm)52674684ddb6SLionel Sambuc __time_get_storage<char>::__time_get_storage(const string& __nm)
52684684ddb6SLionel Sambuc     : __time_get(__nm)
52694684ddb6SLionel Sambuc {
52704684ddb6SLionel Sambuc     const __time_get_temp<char> ct(__nm);
52714684ddb6SLionel Sambuc     init(ct);
52724684ddb6SLionel Sambuc }
52734684ddb6SLionel Sambuc 
52744684ddb6SLionel Sambuc template <>
__time_get_storage(const char * __nm)52754684ddb6SLionel Sambuc __time_get_storage<wchar_t>::__time_get_storage(const char* __nm)
52764684ddb6SLionel Sambuc     : __time_get(__nm)
52774684ddb6SLionel Sambuc {
52784684ddb6SLionel Sambuc     const __time_get_temp<wchar_t> ct(__nm);
52794684ddb6SLionel Sambuc     init(ct);
52804684ddb6SLionel Sambuc }
52814684ddb6SLionel Sambuc 
52824684ddb6SLionel Sambuc template <>
__time_get_storage(const string & __nm)52834684ddb6SLionel Sambuc __time_get_storage<wchar_t>::__time_get_storage(const string& __nm)
52844684ddb6SLionel Sambuc     : __time_get(__nm)
52854684ddb6SLionel Sambuc {
52864684ddb6SLionel Sambuc     const __time_get_temp<wchar_t> ct(__nm);
52874684ddb6SLionel Sambuc     init(ct);
52884684ddb6SLionel Sambuc }
52894684ddb6SLionel Sambuc 
52904684ddb6SLionel Sambuc template <>
52914684ddb6SLionel Sambuc time_base::dateorder
__do_date_order() const52924684ddb6SLionel Sambuc __time_get_storage<char>::__do_date_order() const
52934684ddb6SLionel Sambuc {
52944684ddb6SLionel Sambuc     unsigned i;
52954684ddb6SLionel Sambuc     for (i = 0; i < __x_.size(); ++i)
52964684ddb6SLionel Sambuc         if (__x_[i] == '%')
52974684ddb6SLionel Sambuc             break;
52984684ddb6SLionel Sambuc     ++i;
52994684ddb6SLionel Sambuc     switch (__x_[i])
53004684ddb6SLionel Sambuc     {
53014684ddb6SLionel Sambuc     case 'y':
53024684ddb6SLionel Sambuc     case 'Y':
53034684ddb6SLionel Sambuc         for (++i; i < __x_.size(); ++i)
53044684ddb6SLionel Sambuc             if (__x_[i] == '%')
53054684ddb6SLionel Sambuc                 break;
53064684ddb6SLionel Sambuc         if (i == __x_.size())
53074684ddb6SLionel Sambuc             break;
53084684ddb6SLionel Sambuc         ++i;
53094684ddb6SLionel Sambuc         switch (__x_[i])
53104684ddb6SLionel Sambuc         {
53114684ddb6SLionel Sambuc         case 'm':
53124684ddb6SLionel Sambuc             for (++i; i < __x_.size(); ++i)
53134684ddb6SLionel Sambuc                 if (__x_[i] == '%')
53144684ddb6SLionel Sambuc                     break;
53154684ddb6SLionel Sambuc             if (i == __x_.size())
53164684ddb6SLionel Sambuc                 break;
53174684ddb6SLionel Sambuc             ++i;
53184684ddb6SLionel Sambuc             if (__x_[i] == 'd')
53194684ddb6SLionel Sambuc                 return time_base::ymd;
53204684ddb6SLionel Sambuc             break;
53214684ddb6SLionel Sambuc         case 'd':
53224684ddb6SLionel Sambuc             for (++i; i < __x_.size(); ++i)
53234684ddb6SLionel Sambuc                 if (__x_[i] == '%')
53244684ddb6SLionel Sambuc                     break;
53254684ddb6SLionel Sambuc             if (i == __x_.size())
53264684ddb6SLionel Sambuc                 break;
53274684ddb6SLionel Sambuc             ++i;
53284684ddb6SLionel Sambuc             if (__x_[i] == 'm')
53294684ddb6SLionel Sambuc                 return time_base::ydm;
53304684ddb6SLionel Sambuc             break;
53314684ddb6SLionel Sambuc         }
53324684ddb6SLionel Sambuc         break;
53334684ddb6SLionel Sambuc     case 'm':
53344684ddb6SLionel Sambuc         for (++i; i < __x_.size(); ++i)
53354684ddb6SLionel Sambuc             if (__x_[i] == '%')
53364684ddb6SLionel Sambuc                 break;
53374684ddb6SLionel Sambuc         if (i == __x_.size())
53384684ddb6SLionel Sambuc             break;
53394684ddb6SLionel Sambuc         ++i;
53404684ddb6SLionel Sambuc         if (__x_[i] == 'd')
53414684ddb6SLionel Sambuc         {
53424684ddb6SLionel Sambuc             for (++i; i < __x_.size(); ++i)
53434684ddb6SLionel Sambuc                 if (__x_[i] == '%')
53444684ddb6SLionel Sambuc                     break;
53454684ddb6SLionel Sambuc             if (i == __x_.size())
53464684ddb6SLionel Sambuc                 break;
53474684ddb6SLionel Sambuc             ++i;
53484684ddb6SLionel Sambuc             if (__x_[i] == 'y' || __x_[i] == 'Y')
53494684ddb6SLionel Sambuc                 return time_base::mdy;
53504684ddb6SLionel Sambuc             break;
53514684ddb6SLionel Sambuc         }
53524684ddb6SLionel Sambuc         break;
53534684ddb6SLionel Sambuc     case 'd':
53544684ddb6SLionel Sambuc         for (++i; i < __x_.size(); ++i)
53554684ddb6SLionel Sambuc             if (__x_[i] == '%')
53564684ddb6SLionel Sambuc                 break;
53574684ddb6SLionel Sambuc         if (i == __x_.size())
53584684ddb6SLionel Sambuc             break;
53594684ddb6SLionel Sambuc         ++i;
53604684ddb6SLionel Sambuc         if (__x_[i] == 'm')
53614684ddb6SLionel Sambuc         {
53624684ddb6SLionel Sambuc             for (++i; i < __x_.size(); ++i)
53634684ddb6SLionel Sambuc                 if (__x_[i] == '%')
53644684ddb6SLionel Sambuc                     break;
53654684ddb6SLionel Sambuc             if (i == __x_.size())
53664684ddb6SLionel Sambuc                 break;
53674684ddb6SLionel Sambuc             ++i;
53684684ddb6SLionel Sambuc             if (__x_[i] == 'y' || __x_[i] == 'Y')
53694684ddb6SLionel Sambuc                 return time_base::dmy;
53704684ddb6SLionel Sambuc             break;
53714684ddb6SLionel Sambuc         }
53724684ddb6SLionel Sambuc         break;
53734684ddb6SLionel Sambuc     }
53744684ddb6SLionel Sambuc     return time_base::no_order;
53754684ddb6SLionel Sambuc }
53764684ddb6SLionel Sambuc 
53774684ddb6SLionel Sambuc template <>
53784684ddb6SLionel Sambuc time_base::dateorder
__do_date_order() const53794684ddb6SLionel Sambuc __time_get_storage<wchar_t>::__do_date_order() const
53804684ddb6SLionel Sambuc {
53814684ddb6SLionel Sambuc     unsigned i;
53824684ddb6SLionel Sambuc     for (i = 0; i < __x_.size(); ++i)
53834684ddb6SLionel Sambuc         if (__x_[i] == L'%')
53844684ddb6SLionel Sambuc             break;
53854684ddb6SLionel Sambuc     ++i;
53864684ddb6SLionel Sambuc     switch (__x_[i])
53874684ddb6SLionel Sambuc     {
53884684ddb6SLionel Sambuc     case L'y':
53894684ddb6SLionel Sambuc     case L'Y':
53904684ddb6SLionel Sambuc         for (++i; i < __x_.size(); ++i)
53914684ddb6SLionel Sambuc             if (__x_[i] == L'%')
53924684ddb6SLionel Sambuc                 break;
53934684ddb6SLionel Sambuc         if (i == __x_.size())
53944684ddb6SLionel Sambuc             break;
53954684ddb6SLionel Sambuc         ++i;
53964684ddb6SLionel Sambuc         switch (__x_[i])
53974684ddb6SLionel Sambuc         {
53984684ddb6SLionel Sambuc         case L'm':
53994684ddb6SLionel Sambuc             for (++i; i < __x_.size(); ++i)
54004684ddb6SLionel Sambuc                 if (__x_[i] == L'%')
54014684ddb6SLionel Sambuc                     break;
54024684ddb6SLionel Sambuc             if (i == __x_.size())
54034684ddb6SLionel Sambuc                 break;
54044684ddb6SLionel Sambuc             ++i;
54054684ddb6SLionel Sambuc             if (__x_[i] == L'd')
54064684ddb6SLionel Sambuc                 return time_base::ymd;
54074684ddb6SLionel Sambuc             break;
54084684ddb6SLionel Sambuc         case L'd':
54094684ddb6SLionel Sambuc             for (++i; i < __x_.size(); ++i)
54104684ddb6SLionel Sambuc                 if (__x_[i] == L'%')
54114684ddb6SLionel Sambuc                     break;
54124684ddb6SLionel Sambuc             if (i == __x_.size())
54134684ddb6SLionel Sambuc                 break;
54144684ddb6SLionel Sambuc             ++i;
54154684ddb6SLionel Sambuc             if (__x_[i] == L'm')
54164684ddb6SLionel Sambuc                 return time_base::ydm;
54174684ddb6SLionel Sambuc             break;
54184684ddb6SLionel Sambuc         }
54194684ddb6SLionel Sambuc         break;
54204684ddb6SLionel Sambuc     case L'm':
54214684ddb6SLionel Sambuc         for (++i; i < __x_.size(); ++i)
54224684ddb6SLionel Sambuc             if (__x_[i] == L'%')
54234684ddb6SLionel Sambuc                 break;
54244684ddb6SLionel Sambuc         if (i == __x_.size())
54254684ddb6SLionel Sambuc             break;
54264684ddb6SLionel Sambuc         ++i;
54274684ddb6SLionel Sambuc         if (__x_[i] == L'd')
54284684ddb6SLionel Sambuc         {
54294684ddb6SLionel Sambuc             for (++i; i < __x_.size(); ++i)
54304684ddb6SLionel Sambuc                 if (__x_[i] == L'%')
54314684ddb6SLionel Sambuc                     break;
54324684ddb6SLionel Sambuc             if (i == __x_.size())
54334684ddb6SLionel Sambuc                 break;
54344684ddb6SLionel Sambuc             ++i;
54354684ddb6SLionel Sambuc             if (__x_[i] == L'y' || __x_[i] == L'Y')
54364684ddb6SLionel Sambuc                 return time_base::mdy;
54374684ddb6SLionel Sambuc             break;
54384684ddb6SLionel Sambuc         }
54394684ddb6SLionel Sambuc         break;
54404684ddb6SLionel Sambuc     case L'd':
54414684ddb6SLionel Sambuc         for (++i; i < __x_.size(); ++i)
54424684ddb6SLionel Sambuc             if (__x_[i] == L'%')
54434684ddb6SLionel Sambuc                 break;
54444684ddb6SLionel Sambuc         if (i == __x_.size())
54454684ddb6SLionel Sambuc             break;
54464684ddb6SLionel Sambuc         ++i;
54474684ddb6SLionel Sambuc         if (__x_[i] == L'm')
54484684ddb6SLionel Sambuc         {
54494684ddb6SLionel Sambuc             for (++i; i < __x_.size(); ++i)
54504684ddb6SLionel Sambuc                 if (__x_[i] == L'%')
54514684ddb6SLionel Sambuc                     break;
54524684ddb6SLionel Sambuc             if (i == __x_.size())
54534684ddb6SLionel Sambuc                 break;
54544684ddb6SLionel Sambuc             ++i;
54554684ddb6SLionel Sambuc             if (__x_[i] == L'y' || __x_[i] == L'Y')
54564684ddb6SLionel Sambuc                 return time_base::dmy;
54574684ddb6SLionel Sambuc             break;
54584684ddb6SLionel Sambuc         }
54594684ddb6SLionel Sambuc         break;
54604684ddb6SLionel Sambuc     }
54614684ddb6SLionel Sambuc     return time_base::no_order;
54624684ddb6SLionel Sambuc }
54634684ddb6SLionel Sambuc 
54644684ddb6SLionel Sambuc // time_put
54654684ddb6SLionel Sambuc 
__time_put(const char * nm)54664684ddb6SLionel Sambuc __time_put::__time_put(const char* nm)
54674684ddb6SLionel Sambuc     : __loc_(newlocale(LC_ALL_MASK, nm, 0))
54684684ddb6SLionel Sambuc {
54694684ddb6SLionel Sambuc #ifndef _LIBCPP_NO_EXCEPTIONS
54704684ddb6SLionel Sambuc     if (__loc_ == 0)
54714684ddb6SLionel Sambuc         throw runtime_error("time_put_byname"
54724684ddb6SLionel Sambuc                             " failed to construct for " + string(nm));
54734684ddb6SLionel Sambuc #endif  // _LIBCPP_NO_EXCEPTIONS
54744684ddb6SLionel Sambuc }
54754684ddb6SLionel Sambuc 
__time_put(const string & nm)54764684ddb6SLionel Sambuc __time_put::__time_put(const string& nm)
54774684ddb6SLionel Sambuc     : __loc_(newlocale(LC_ALL_MASK, nm.c_str(), 0))
54784684ddb6SLionel Sambuc {
54794684ddb6SLionel Sambuc #ifndef _LIBCPP_NO_EXCEPTIONS
54804684ddb6SLionel Sambuc     if (__loc_ == 0)
54814684ddb6SLionel Sambuc         throw runtime_error("time_put_byname"
54824684ddb6SLionel Sambuc                             " failed to construct for " + nm);
54834684ddb6SLionel Sambuc #endif  // _LIBCPP_NO_EXCEPTIONS
54844684ddb6SLionel Sambuc }
54854684ddb6SLionel Sambuc 
~__time_put()54864684ddb6SLionel Sambuc __time_put::~__time_put()
54874684ddb6SLionel Sambuc {
54884684ddb6SLionel Sambuc     if (__loc_ != _LIBCPP_GET_C_LOCALE)
54894684ddb6SLionel Sambuc         freelocale(__loc_);
54904684ddb6SLionel Sambuc }
54914684ddb6SLionel Sambuc 
54924684ddb6SLionel Sambuc void
__do_put(char * __nb,char * & __ne,const tm * __tm,char __fmt,char __mod) const54934684ddb6SLionel Sambuc __time_put::__do_put(char* __nb, char*& __ne, const tm* __tm,
54944684ddb6SLionel Sambuc                      char __fmt, char __mod) const
54954684ddb6SLionel Sambuc {
54964684ddb6SLionel Sambuc     char fmt[] = {'%', __fmt, __mod, 0};
54974684ddb6SLionel Sambuc     if (__mod != 0)
54984684ddb6SLionel Sambuc         swap(fmt[1], fmt[2]);
54994684ddb6SLionel Sambuc     size_t n = strftime_l(__nb, countof(__nb, __ne), fmt, __tm, __loc_);
55004684ddb6SLionel Sambuc     __ne = __nb + n;
55014684ddb6SLionel Sambuc }
55024684ddb6SLionel Sambuc 
55034684ddb6SLionel Sambuc void
__do_put(wchar_t * __wb,wchar_t * & __we,const tm * __tm,char __fmt,char __mod) const55044684ddb6SLionel Sambuc __time_put::__do_put(wchar_t* __wb, wchar_t*& __we, const tm* __tm,
55054684ddb6SLionel Sambuc                      char __fmt, char __mod) const
55064684ddb6SLionel Sambuc {
55074684ddb6SLionel Sambuc     char __nar[100];
55084684ddb6SLionel Sambuc     char* __ne = __nar + 100;
55094684ddb6SLionel Sambuc     __do_put(__nar, __ne, __tm, __fmt, __mod);
55104684ddb6SLionel Sambuc     mbstate_t mb = {0};
55114684ddb6SLionel Sambuc     const char* __nb = __nar;
55124684ddb6SLionel Sambuc #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
55134684ddb6SLionel Sambuc     size_t j = mbsrtowcs_l(__wb, &__nb, countof(__wb, __we), &mb, __loc_);
55144684ddb6SLionel Sambuc #else
55154684ddb6SLionel Sambuc     size_t j = __mbsrtowcs_l(__wb, &__nb, countof(__wb, __we), &mb, __loc_);
55164684ddb6SLionel Sambuc #endif
55174684ddb6SLionel Sambuc     if (j == size_t(-1))
55184684ddb6SLionel Sambuc         __throw_runtime_error("locale not supported");
55194684ddb6SLionel Sambuc     __we = __wb + j;
55204684ddb6SLionel Sambuc }
55214684ddb6SLionel Sambuc 
55224684ddb6SLionel Sambuc // moneypunct_byname
55234684ddb6SLionel Sambuc 
55244684ddb6SLionel Sambuc template <class charT>
55254684ddb6SLionel Sambuc static
55264684ddb6SLionel Sambuc void
__init_pat(money_base::pattern & pat,basic_string<charT> & __curr_symbol_,bool intl,char cs_precedes,char sep_by_space,char sign_posn,charT space_char)55274684ddb6SLionel Sambuc __init_pat(money_base::pattern& pat, basic_string<charT>& __curr_symbol_,
55284684ddb6SLionel Sambuc            bool intl, char cs_precedes, char sep_by_space, char sign_posn,
55294684ddb6SLionel Sambuc            charT space_char)
55304684ddb6SLionel Sambuc {
55314684ddb6SLionel Sambuc     const char sign = static_cast<char>(money_base::sign);
55324684ddb6SLionel Sambuc     const char space = static_cast<char>(money_base::space);
55334684ddb6SLionel Sambuc     const char none = static_cast<char>(money_base::none);
55344684ddb6SLionel Sambuc     const char symbol = static_cast<char>(money_base::symbol);
55354684ddb6SLionel Sambuc     const char value = static_cast<char>(money_base::value);
55364684ddb6SLionel Sambuc     const bool symbol_contains_sep = intl && __curr_symbol_.size() == 4;
55374684ddb6SLionel Sambuc 
55384684ddb6SLionel Sambuc     // Comments on case branches reflect 'C11 7.11.2.1 The localeconv
55394684ddb6SLionel Sambuc     // function'. "Space between sign and symbol or value" means that
55404684ddb6SLionel Sambuc     // if the sign is adjacent to the symbol, there's a space between
55414684ddb6SLionel Sambuc     // them, and otherwise there's a space between the sign and value.
55424684ddb6SLionel Sambuc     //
55434684ddb6SLionel Sambuc     // C11's localeconv specifies that the fourth character of an
55444684ddb6SLionel Sambuc     // international curr_symbol is used to separate the sign and
55454684ddb6SLionel Sambuc     // value when sep_by_space says to do so. C++ can't represent
55464684ddb6SLionel Sambuc     // that, so we just use a space.  When sep_by_space says to
55474684ddb6SLionel Sambuc     // separate the symbol and value-or-sign with a space, we rearrange the
55484684ddb6SLionel Sambuc     // curr_symbol to put its spacing character on the correct side of
55494684ddb6SLionel Sambuc     // the symbol.
55504684ddb6SLionel Sambuc     //
55514684ddb6SLionel Sambuc     // We also need to avoid adding an extra space between the sign
55524684ddb6SLionel Sambuc     // and value when the currency symbol is suppressed (by not
55534684ddb6SLionel Sambuc     // setting showbase).  We match glibc's strfmon by interpreting
55544684ddb6SLionel Sambuc     // sep_by_space==1 as "omit the space when the currency symbol is
55554684ddb6SLionel Sambuc     // absent".
55564684ddb6SLionel Sambuc     //
55574684ddb6SLionel Sambuc     // Users who want to get this right should use ICU instead.
55584684ddb6SLionel Sambuc 
55594684ddb6SLionel Sambuc     switch (cs_precedes)
55604684ddb6SLionel Sambuc     {
55614684ddb6SLionel Sambuc     case 0:  // value before curr_symbol
55624684ddb6SLionel Sambuc         if (symbol_contains_sep) {
55634684ddb6SLionel Sambuc             // Move the separator to before the symbol, to place it
55644684ddb6SLionel Sambuc             // between the value and symbol.
55654684ddb6SLionel Sambuc             rotate(__curr_symbol_.begin(), __curr_symbol_.begin() + 3,
55664684ddb6SLionel Sambuc                    __curr_symbol_.end());
55674684ddb6SLionel Sambuc         }
55684684ddb6SLionel Sambuc         switch (sign_posn)
55694684ddb6SLionel Sambuc         {
55704684ddb6SLionel Sambuc         case 0:  // Parentheses surround the quantity and currency symbol.
55714684ddb6SLionel Sambuc             pat.field[0] = sign;
55724684ddb6SLionel Sambuc             pat.field[1] = value;
55734684ddb6SLionel Sambuc             pat.field[2] = none;  // Any space appears in the symbol.
55744684ddb6SLionel Sambuc             pat.field[3] = symbol;
55754684ddb6SLionel Sambuc             switch (sep_by_space)
55764684ddb6SLionel Sambuc             {
55774684ddb6SLionel Sambuc             case 0:  // No space separates the currency symbol and value.
55784684ddb6SLionel Sambuc                 // This case may have changed between C99 and C11;
55794684ddb6SLionel Sambuc                 // assume the currency symbol matches the intention.
55804684ddb6SLionel Sambuc             case 2:  // Space between sign and currency or value.
55814684ddb6SLionel Sambuc                 // The "sign" is two parentheses, so no space here either.
55824684ddb6SLionel Sambuc                 return;
55834684ddb6SLionel Sambuc             case 1:  // Space between currency-and-sign or currency and value.
55844684ddb6SLionel Sambuc                 if (!symbol_contains_sep) {
55854684ddb6SLionel Sambuc                     // We insert the space into the symbol instead of
55864684ddb6SLionel Sambuc                     // setting pat.field[2]=space so that when
55874684ddb6SLionel Sambuc                     // showbase is not set, the space goes away too.
55884684ddb6SLionel Sambuc                     __curr_symbol_.insert(0, 1, space_char);
55894684ddb6SLionel Sambuc                 }
55904684ddb6SLionel Sambuc                 return;
55914684ddb6SLionel Sambuc             default:
55924684ddb6SLionel Sambuc                 break;
55934684ddb6SLionel Sambuc             }
55944684ddb6SLionel Sambuc             break;
55954684ddb6SLionel Sambuc         case 1:  // The sign string precedes the quantity and currency symbol.
55964684ddb6SLionel Sambuc             pat.field[0] = sign;
55974684ddb6SLionel Sambuc             pat.field[3] = symbol;
55984684ddb6SLionel Sambuc             switch (sep_by_space)
55994684ddb6SLionel Sambuc             {
56004684ddb6SLionel Sambuc             case 0:  // No space separates the currency symbol and value.
56014684ddb6SLionel Sambuc                 pat.field[1] = value;
56024684ddb6SLionel Sambuc                 pat.field[2] = none;
56034684ddb6SLionel Sambuc                 return;
56044684ddb6SLionel Sambuc             case 1:  // Space between currency-and-sign or currency and value.
56054684ddb6SLionel Sambuc                 pat.field[1] = value;
56064684ddb6SLionel Sambuc                 pat.field[2] = none;
56074684ddb6SLionel Sambuc                 if (!symbol_contains_sep) {
56084684ddb6SLionel Sambuc                     // We insert the space into the symbol instead of
56094684ddb6SLionel Sambuc                     // setting pat.field[2]=space so that when
56104684ddb6SLionel Sambuc                     // showbase is not set, the space goes away too.
56114684ddb6SLionel Sambuc                     __curr_symbol_.insert(0, 1, space_char);
56124684ddb6SLionel Sambuc                 }
56134684ddb6SLionel Sambuc                 return;
56144684ddb6SLionel Sambuc             case 2:  // Space between sign and currency or value.
56154684ddb6SLionel Sambuc                 pat.field[1] = space;
56164684ddb6SLionel Sambuc                 pat.field[2] = value;
56174684ddb6SLionel Sambuc                 if (symbol_contains_sep) {
56184684ddb6SLionel Sambuc                     // Remove the separator from the symbol, since it
56194684ddb6SLionel Sambuc                     // has already appeared after the sign.
56204684ddb6SLionel Sambuc                     __curr_symbol_.erase(__curr_symbol_.begin());
56214684ddb6SLionel Sambuc                 }
56224684ddb6SLionel Sambuc                 return;
56234684ddb6SLionel Sambuc             default:
56244684ddb6SLionel Sambuc                 break;
56254684ddb6SLionel Sambuc             }
56264684ddb6SLionel Sambuc             break;
56274684ddb6SLionel Sambuc         case 2:  // The sign string succeeds the quantity and currency symbol.
56284684ddb6SLionel Sambuc             pat.field[0] = value;
56294684ddb6SLionel Sambuc             pat.field[3] = sign;
56304684ddb6SLionel Sambuc             switch (sep_by_space)
56314684ddb6SLionel Sambuc             {
56324684ddb6SLionel Sambuc             case 0:  // No space separates the currency symbol and value.
56334684ddb6SLionel Sambuc                 pat.field[1] = none;
56344684ddb6SLionel Sambuc                 pat.field[2] = symbol;
56354684ddb6SLionel Sambuc                 return;
56364684ddb6SLionel Sambuc             case 1:  // Space between currency-and-sign or currency and value.
56374684ddb6SLionel Sambuc                 if (!symbol_contains_sep) {
56384684ddb6SLionel Sambuc                     // We insert the space into the symbol instead of
56394684ddb6SLionel Sambuc                     // setting pat.field[1]=space so that when
56404684ddb6SLionel Sambuc                     // showbase is not set, the space goes away too.
56414684ddb6SLionel Sambuc                     __curr_symbol_.insert(0, 1, space_char);
56424684ddb6SLionel Sambuc                 }
56434684ddb6SLionel Sambuc                 pat.field[1] = none;
56444684ddb6SLionel Sambuc                 pat.field[2] = symbol;
56454684ddb6SLionel Sambuc                 return;
56464684ddb6SLionel Sambuc             case 2:  // Space between sign and currency or value.
56474684ddb6SLionel Sambuc                 pat.field[1] = symbol;
56484684ddb6SLionel Sambuc                 pat.field[2] = space;
56494684ddb6SLionel Sambuc                 if (symbol_contains_sep) {
56504684ddb6SLionel Sambuc                     // Remove the separator from the symbol, since it
56514684ddb6SLionel Sambuc                     // should not be removed if showbase is absent.
56524684ddb6SLionel Sambuc                     __curr_symbol_.erase(__curr_symbol_.begin());
56534684ddb6SLionel Sambuc                 }
56544684ddb6SLionel Sambuc                 return;
56554684ddb6SLionel Sambuc             default:
56564684ddb6SLionel Sambuc                 break;
56574684ddb6SLionel Sambuc             }
56584684ddb6SLionel Sambuc             break;
56594684ddb6SLionel Sambuc         case 3:  // The sign string immediately precedes the currency symbol.
56604684ddb6SLionel Sambuc             pat.field[0] = value;
56614684ddb6SLionel Sambuc             pat.field[3] = symbol;
56624684ddb6SLionel Sambuc             switch (sep_by_space)
56634684ddb6SLionel Sambuc             {
56644684ddb6SLionel Sambuc             case 0:  // No space separates the currency symbol and value.
56654684ddb6SLionel Sambuc                 pat.field[1] = none;
56664684ddb6SLionel Sambuc                 pat.field[2] = sign;
56674684ddb6SLionel Sambuc                 return;
56684684ddb6SLionel Sambuc             case 1:  // Space between currency-and-sign or currency and value.
56694684ddb6SLionel Sambuc                 pat.field[1] = space;
56704684ddb6SLionel Sambuc                 pat.field[2] = sign;
56714684ddb6SLionel Sambuc                 if (symbol_contains_sep) {
56724684ddb6SLionel Sambuc                     // Remove the separator from the symbol, since it
56734684ddb6SLionel Sambuc                     // has already appeared before the sign.
56744684ddb6SLionel Sambuc                     __curr_symbol_.erase(__curr_symbol_.begin());
56754684ddb6SLionel Sambuc                 }
56764684ddb6SLionel Sambuc                 return;
56774684ddb6SLionel Sambuc             case 2:  // Space between sign and currency or value.
56784684ddb6SLionel Sambuc                 pat.field[1] = sign;
56794684ddb6SLionel Sambuc                 pat.field[2] = none;
56804684ddb6SLionel Sambuc                 if (!symbol_contains_sep) {
56814684ddb6SLionel Sambuc                     // We insert the space into the symbol instead of
56824684ddb6SLionel Sambuc                     // setting pat.field[2]=space so that when
56834684ddb6SLionel Sambuc                     // showbase is not set, the space goes away too.
56844684ddb6SLionel Sambuc                     __curr_symbol_.insert(0, 1, space_char);
56854684ddb6SLionel Sambuc                 }
56864684ddb6SLionel Sambuc                 return;
56874684ddb6SLionel Sambuc             default:
56884684ddb6SLionel Sambuc                 break;
56894684ddb6SLionel Sambuc             }
56904684ddb6SLionel Sambuc             break;
56914684ddb6SLionel Sambuc         case 4:  // The sign string immediately succeeds the currency symbol.
56924684ddb6SLionel Sambuc             pat.field[0] = value;
56934684ddb6SLionel Sambuc             pat.field[3] = sign;
56944684ddb6SLionel Sambuc             switch (sep_by_space)
56954684ddb6SLionel Sambuc             {
56964684ddb6SLionel Sambuc             case 0:  // No space separates the currency symbol and value.
56974684ddb6SLionel Sambuc                 pat.field[1] = none;
56984684ddb6SLionel Sambuc                 pat.field[2] = symbol;
56994684ddb6SLionel Sambuc                 return;
57004684ddb6SLionel Sambuc             case 1:  // Space between currency-and-sign or currency and value.
57014684ddb6SLionel Sambuc                 pat.field[1] = none;
57024684ddb6SLionel Sambuc                 pat.field[2] = symbol;
57034684ddb6SLionel Sambuc                 if (!symbol_contains_sep) {
57044684ddb6SLionel Sambuc                     // We insert the space into the symbol instead of
57054684ddb6SLionel Sambuc                     // setting pat.field[1]=space so that when
57064684ddb6SLionel Sambuc                     // showbase is not set, the space goes away too.
57074684ddb6SLionel Sambuc                     __curr_symbol_.insert(0, 1, space_char);
57084684ddb6SLionel Sambuc                 }
57094684ddb6SLionel Sambuc                 return;
57104684ddb6SLionel Sambuc             case 2:  // Space between sign and currency or value.
57114684ddb6SLionel Sambuc                 pat.field[1] = symbol;
57124684ddb6SLionel Sambuc                 pat.field[2] = space;
57134684ddb6SLionel Sambuc                 if (symbol_contains_sep) {
57144684ddb6SLionel Sambuc                     // Remove the separator from the symbol, since it
57154684ddb6SLionel Sambuc                     // should not disappear when showbase is absent.
57164684ddb6SLionel Sambuc                     __curr_symbol_.erase(__curr_symbol_.begin());
57174684ddb6SLionel Sambuc                 }
57184684ddb6SLionel Sambuc                 return;
57194684ddb6SLionel Sambuc             default:
57204684ddb6SLionel Sambuc                 break;
57214684ddb6SLionel Sambuc             }
57224684ddb6SLionel Sambuc             break;
57234684ddb6SLionel Sambuc         default:
57244684ddb6SLionel Sambuc             break;
57254684ddb6SLionel Sambuc         }
57264684ddb6SLionel Sambuc         break;
57274684ddb6SLionel Sambuc     case 1:  // curr_symbol before value
57284684ddb6SLionel Sambuc         switch (sign_posn)
57294684ddb6SLionel Sambuc         {
57304684ddb6SLionel Sambuc         case 0:  // Parentheses surround the quantity and currency symbol.
57314684ddb6SLionel Sambuc             pat.field[0] = sign;
57324684ddb6SLionel Sambuc             pat.field[1] = symbol;
57334684ddb6SLionel Sambuc             pat.field[2] = none;  // Any space appears in the symbol.
57344684ddb6SLionel Sambuc             pat.field[3] = value;
57354684ddb6SLionel Sambuc             switch (sep_by_space)
57364684ddb6SLionel Sambuc             {
57374684ddb6SLionel Sambuc             case 0:  // No space separates the currency symbol and value.
57384684ddb6SLionel Sambuc                 // This case may have changed between C99 and C11;
57394684ddb6SLionel Sambuc                 // assume the currency symbol matches the intention.
57404684ddb6SLionel Sambuc             case 2:  // Space between sign and currency or value.
57414684ddb6SLionel Sambuc                 // The "sign" is two parentheses, so no space here either.
57424684ddb6SLionel Sambuc                 return;
57434684ddb6SLionel Sambuc             case 1:  // Space between currency-and-sign or currency and value.
57444684ddb6SLionel Sambuc                 if (!symbol_contains_sep) {
57454684ddb6SLionel Sambuc                     // We insert the space into the symbol instead of
57464684ddb6SLionel Sambuc                     // setting pat.field[2]=space so that when
57474684ddb6SLionel Sambuc                     // showbase is not set, the space goes away too.
57484684ddb6SLionel Sambuc                     __curr_symbol_.insert(0, 1, space_char);
57494684ddb6SLionel Sambuc                 }
57504684ddb6SLionel Sambuc                 return;
57514684ddb6SLionel Sambuc             default:
57524684ddb6SLionel Sambuc                 break;
57534684ddb6SLionel Sambuc             }
57544684ddb6SLionel Sambuc             break;
57554684ddb6SLionel Sambuc         case 1:  // The sign string precedes the quantity and currency symbol.
57564684ddb6SLionel Sambuc             pat.field[0] = sign;
57574684ddb6SLionel Sambuc             pat.field[3] = value;
57584684ddb6SLionel Sambuc             switch (sep_by_space)
57594684ddb6SLionel Sambuc             {
57604684ddb6SLionel Sambuc             case 0:  // No space separates the currency symbol and value.
57614684ddb6SLionel Sambuc                 pat.field[1] = symbol;
57624684ddb6SLionel Sambuc                 pat.field[2] = none;
57634684ddb6SLionel Sambuc                 return;
57644684ddb6SLionel Sambuc             case 1:  // Space between currency-and-sign or currency and value.
57654684ddb6SLionel Sambuc                 pat.field[1] = symbol;
57664684ddb6SLionel Sambuc                 pat.field[2] = none;
57674684ddb6SLionel Sambuc                 if (!symbol_contains_sep) {
57684684ddb6SLionel Sambuc                     // We insert the space into the symbol instead of
57694684ddb6SLionel Sambuc                     // setting pat.field[2]=space so that when
57704684ddb6SLionel Sambuc                     // showbase is not set, the space goes away too.
57714684ddb6SLionel Sambuc                     __curr_symbol_.push_back(space_char);
57724684ddb6SLionel Sambuc                 }
57734684ddb6SLionel Sambuc                 return;
57744684ddb6SLionel Sambuc             case 2:  // Space between sign and currency or value.
57754684ddb6SLionel Sambuc                 pat.field[1] = space;
57764684ddb6SLionel Sambuc                 pat.field[2] = symbol;
57774684ddb6SLionel Sambuc                 if (symbol_contains_sep) {
57784684ddb6SLionel Sambuc                     // Remove the separator from the symbol, since it
57794684ddb6SLionel Sambuc                     // has already appeared after the sign.
57804684ddb6SLionel Sambuc                     __curr_symbol_.pop_back();
57814684ddb6SLionel Sambuc                 }
57824684ddb6SLionel Sambuc                 return;
57834684ddb6SLionel Sambuc             default:
57844684ddb6SLionel Sambuc                 break;
57854684ddb6SLionel Sambuc             }
57864684ddb6SLionel Sambuc             break;
57874684ddb6SLionel Sambuc         case 2:  // The sign string succeeds the quantity and currency symbol.
57884684ddb6SLionel Sambuc             pat.field[0] = symbol;
57894684ddb6SLionel Sambuc             pat.field[3] = sign;
57904684ddb6SLionel Sambuc             switch (sep_by_space)
57914684ddb6SLionel Sambuc             {
57924684ddb6SLionel Sambuc             case 0:  // No space separates the currency symbol and value.
57934684ddb6SLionel Sambuc                 pat.field[1] = none;
57944684ddb6SLionel Sambuc                 pat.field[2] = value;
57954684ddb6SLionel Sambuc                 return;
57964684ddb6SLionel Sambuc             case 1:  // Space between currency-and-sign or currency and value.
57974684ddb6SLionel Sambuc                 pat.field[1] = none;
57984684ddb6SLionel Sambuc                 pat.field[2] = value;
57994684ddb6SLionel Sambuc                 if (!symbol_contains_sep) {
58004684ddb6SLionel Sambuc                     // We insert the space into the symbol instead of
58014684ddb6SLionel Sambuc                     // setting pat.field[1]=space so that when
58024684ddb6SLionel Sambuc                     // showbase is not set, the space goes away too.
58034684ddb6SLionel Sambuc                     __curr_symbol_.push_back(space_char);
58044684ddb6SLionel Sambuc                 }
58054684ddb6SLionel Sambuc                 return;
58064684ddb6SLionel Sambuc             case 2:  // Space between sign and currency or value.
58074684ddb6SLionel Sambuc                 pat.field[1] = value;
58084684ddb6SLionel Sambuc                 pat.field[2] = space;
58094684ddb6SLionel Sambuc                 if (symbol_contains_sep) {
58104684ddb6SLionel Sambuc                     // Remove the separator from the symbol, since it
58114684ddb6SLionel Sambuc                     // will appear before the sign.
58124684ddb6SLionel Sambuc                     __curr_symbol_.pop_back();
58134684ddb6SLionel Sambuc                 }
58144684ddb6SLionel Sambuc                 return;
58154684ddb6SLionel Sambuc             default:
58164684ddb6SLionel Sambuc                 break;
58174684ddb6SLionel Sambuc             }
58184684ddb6SLionel Sambuc             break;
58194684ddb6SLionel Sambuc         case 3:  // The sign string immediately precedes the currency symbol.
58204684ddb6SLionel Sambuc             pat.field[0] = sign;
58214684ddb6SLionel Sambuc             pat.field[3] = value;
58224684ddb6SLionel Sambuc             switch (sep_by_space)
58234684ddb6SLionel Sambuc             {
58244684ddb6SLionel Sambuc             case 0:  // No space separates the currency symbol and value.
58254684ddb6SLionel Sambuc                 pat.field[1] = symbol;
58264684ddb6SLionel Sambuc                 pat.field[2] = none;
58274684ddb6SLionel Sambuc                 return;
58284684ddb6SLionel Sambuc             case 1:  // Space between currency-and-sign or currency and value.
58294684ddb6SLionel Sambuc                 pat.field[1] = symbol;
58304684ddb6SLionel Sambuc                 pat.field[2] = none;
58314684ddb6SLionel Sambuc                 if (!symbol_contains_sep) {
58324684ddb6SLionel Sambuc                     // We insert the space into the symbol instead of
58334684ddb6SLionel Sambuc                     // setting pat.field[2]=space so that when
58344684ddb6SLionel Sambuc                     // showbase is not set, the space goes away too.
58354684ddb6SLionel Sambuc                     __curr_symbol_.push_back(space_char);
58364684ddb6SLionel Sambuc                 }
58374684ddb6SLionel Sambuc                 return;
58384684ddb6SLionel Sambuc             case 2:  // Space between sign and currency or value.
58394684ddb6SLionel Sambuc                 pat.field[1] = space;
58404684ddb6SLionel Sambuc                 pat.field[2] = symbol;
58414684ddb6SLionel Sambuc                 if (symbol_contains_sep) {
58424684ddb6SLionel Sambuc                     // Remove the separator from the symbol, since it
58434684ddb6SLionel Sambuc                     // has already appeared after the sign.
58444684ddb6SLionel Sambuc                     __curr_symbol_.pop_back();
58454684ddb6SLionel Sambuc                 }
58464684ddb6SLionel Sambuc                 return;
58474684ddb6SLionel Sambuc             default:
58484684ddb6SLionel Sambuc                 break;
58494684ddb6SLionel Sambuc             }
58504684ddb6SLionel Sambuc             break;
58514684ddb6SLionel Sambuc         case 4:  // The sign string immediately succeeds the currency symbol.
58524684ddb6SLionel Sambuc             pat.field[0] = symbol;
58534684ddb6SLionel Sambuc             pat.field[3] = value;
58544684ddb6SLionel Sambuc             switch (sep_by_space)
58554684ddb6SLionel Sambuc             {
58564684ddb6SLionel Sambuc             case 0:  // No space separates the currency symbol and value.
58574684ddb6SLionel Sambuc                 pat.field[1] = sign;
58584684ddb6SLionel Sambuc                 pat.field[2] = none;
58594684ddb6SLionel Sambuc                 return;
58604684ddb6SLionel Sambuc             case 1:  // Space between currency-and-sign or currency and value.
58614684ddb6SLionel Sambuc                 pat.field[1] = sign;
58624684ddb6SLionel Sambuc                 pat.field[2] = space;
58634684ddb6SLionel Sambuc                 if (symbol_contains_sep) {
58644684ddb6SLionel Sambuc                     // Remove the separator from the symbol, since it
58654684ddb6SLionel Sambuc                     // should not disappear when showbase is absent.
58664684ddb6SLionel Sambuc                     __curr_symbol_.pop_back();
58674684ddb6SLionel Sambuc                 }
58684684ddb6SLionel Sambuc                 return;
58694684ddb6SLionel Sambuc             case 2:  // Space between sign and currency or value.
58704684ddb6SLionel Sambuc                 pat.field[1] = none;
58714684ddb6SLionel Sambuc                 pat.field[2] = sign;
58724684ddb6SLionel Sambuc                 if (!symbol_contains_sep) {
58734684ddb6SLionel Sambuc                     // We insert the space into the symbol instead of
58744684ddb6SLionel Sambuc                     // setting pat.field[1]=space so that when
58754684ddb6SLionel Sambuc                     // showbase is not set, the space goes away too.
58764684ddb6SLionel Sambuc                     __curr_symbol_.push_back(space_char);
58774684ddb6SLionel Sambuc                 }
58784684ddb6SLionel Sambuc                 return;
58794684ddb6SLionel Sambuc            default:
58804684ddb6SLionel Sambuc                 break;
58814684ddb6SLionel Sambuc             }
58824684ddb6SLionel Sambuc             break;
58834684ddb6SLionel Sambuc         default:
58844684ddb6SLionel Sambuc             break;
58854684ddb6SLionel Sambuc         }
58864684ddb6SLionel Sambuc         break;
58874684ddb6SLionel Sambuc     default:
58884684ddb6SLionel Sambuc         break;
58894684ddb6SLionel Sambuc     }
58904684ddb6SLionel Sambuc     pat.field[0] = symbol;
58914684ddb6SLionel Sambuc     pat.field[1] = sign;
58924684ddb6SLionel Sambuc     pat.field[2] = none;
58934684ddb6SLionel Sambuc     pat.field[3] = value;
58944684ddb6SLionel Sambuc }
58954684ddb6SLionel Sambuc 
58964684ddb6SLionel Sambuc template<>
58974684ddb6SLionel Sambuc void
init(const char * nm)58984684ddb6SLionel Sambuc moneypunct_byname<char, false>::init(const char* nm)
58994684ddb6SLionel Sambuc {
59004684ddb6SLionel Sambuc     typedef moneypunct<char, false> base;
59014684ddb6SLionel Sambuc     __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
59024684ddb6SLionel Sambuc #ifndef _LIBCPP_NO_EXCEPTIONS
59034684ddb6SLionel Sambuc     if (loc == nullptr)
59044684ddb6SLionel Sambuc         throw runtime_error("moneypunct_byname"
59054684ddb6SLionel Sambuc                             " failed to construct for " + string(nm));
59064684ddb6SLionel Sambuc #endif  // _LIBCPP_NO_EXCEPTIONS
59074684ddb6SLionel Sambuc #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
59084684ddb6SLionel Sambuc     lconv* lc = localeconv_l(loc.get());
59094684ddb6SLionel Sambuc #else
59104684ddb6SLionel Sambuc     lconv* lc = __localeconv_l(loc.get());
59114684ddb6SLionel Sambuc #endif
59124684ddb6SLionel Sambuc     if (*lc->mon_decimal_point)
59134684ddb6SLionel Sambuc         __decimal_point_ = *lc->mon_decimal_point;
59144684ddb6SLionel Sambuc     else
59154684ddb6SLionel Sambuc         __decimal_point_ = base::do_decimal_point();
59164684ddb6SLionel Sambuc     if (*lc->mon_thousands_sep)
59174684ddb6SLionel Sambuc         __thousands_sep_ = *lc->mon_thousands_sep;
59184684ddb6SLionel Sambuc     else
59194684ddb6SLionel Sambuc         __thousands_sep_ = base::do_thousands_sep();
59204684ddb6SLionel Sambuc     __grouping_ = lc->mon_grouping;
59214684ddb6SLionel Sambuc     __curr_symbol_ = lc->currency_symbol;
59224684ddb6SLionel Sambuc     if (lc->frac_digits != CHAR_MAX)
59234684ddb6SLionel Sambuc         __frac_digits_ = lc->frac_digits;
59244684ddb6SLionel Sambuc     else
59254684ddb6SLionel Sambuc         __frac_digits_ = base::do_frac_digits();
59264684ddb6SLionel Sambuc     if (lc->p_sign_posn == 0)
59274684ddb6SLionel Sambuc         __positive_sign_ = "()";
59284684ddb6SLionel Sambuc     else
59294684ddb6SLionel Sambuc         __positive_sign_ = lc->positive_sign;
59304684ddb6SLionel Sambuc     if (lc->n_sign_posn == 0)
59314684ddb6SLionel Sambuc         __negative_sign_ = "()";
59324684ddb6SLionel Sambuc     else
59334684ddb6SLionel Sambuc         __negative_sign_ = lc->negative_sign;
59344684ddb6SLionel Sambuc     // Assume the positive and negative formats will want spaces in
59354684ddb6SLionel Sambuc     // the same places in curr_symbol since there's no way to
59364684ddb6SLionel Sambuc     // represent anything else.
59374684ddb6SLionel Sambuc     string_type __dummy_curr_symbol = __curr_symbol_;
59384684ddb6SLionel Sambuc     __init_pat(__pos_format_, __dummy_curr_symbol, false,
59394684ddb6SLionel Sambuc                lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, ' ');
59404684ddb6SLionel Sambuc     __init_pat(__neg_format_, __curr_symbol_, false,
59414684ddb6SLionel Sambuc                lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, ' ');
59424684ddb6SLionel Sambuc }
59434684ddb6SLionel Sambuc 
59444684ddb6SLionel Sambuc template<>
59454684ddb6SLionel Sambuc void
init(const char * nm)59464684ddb6SLionel Sambuc moneypunct_byname<char, true>::init(const char* nm)
59474684ddb6SLionel Sambuc {
59484684ddb6SLionel Sambuc     typedef moneypunct<char, true> base;
59494684ddb6SLionel Sambuc     __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
59504684ddb6SLionel Sambuc #ifndef _LIBCPP_NO_EXCEPTIONS
59514684ddb6SLionel Sambuc     if (loc == nullptr)
59524684ddb6SLionel Sambuc         throw runtime_error("moneypunct_byname"
59534684ddb6SLionel Sambuc                             " failed to construct for " + string(nm));
59544684ddb6SLionel Sambuc #endif  // _LIBCPP_NO_EXCEPTIONS
59554684ddb6SLionel Sambuc #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
59564684ddb6SLionel Sambuc     lconv* lc = localeconv_l(loc.get());
59574684ddb6SLionel Sambuc #else
59584684ddb6SLionel Sambuc     lconv* lc = __localeconv_l(loc.get());
59594684ddb6SLionel Sambuc #endif
59604684ddb6SLionel Sambuc     if (*lc->mon_decimal_point)
59614684ddb6SLionel Sambuc         __decimal_point_ = *lc->mon_decimal_point;
59624684ddb6SLionel Sambuc     else
59634684ddb6SLionel Sambuc         __decimal_point_ = base::do_decimal_point();
59644684ddb6SLionel Sambuc     if (*lc->mon_thousands_sep)
59654684ddb6SLionel Sambuc         __thousands_sep_ = *lc->mon_thousands_sep;
59664684ddb6SLionel Sambuc     else
59674684ddb6SLionel Sambuc         __thousands_sep_ = base::do_thousands_sep();
59684684ddb6SLionel Sambuc     __grouping_ = lc->mon_grouping;
59694684ddb6SLionel Sambuc     __curr_symbol_ = lc->int_curr_symbol;
59704684ddb6SLionel Sambuc     if (lc->int_frac_digits != CHAR_MAX)
59714684ddb6SLionel Sambuc         __frac_digits_ = lc->int_frac_digits;
59724684ddb6SLionel Sambuc     else
59734684ddb6SLionel Sambuc         __frac_digits_ = base::do_frac_digits();
59744684ddb6SLionel Sambuc #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
59754684ddb6SLionel Sambuc     if (lc->p_sign_posn == 0)
59764684ddb6SLionel Sambuc #else // _LIBCPP_MSVCRT
59774684ddb6SLionel Sambuc     if (lc->int_p_sign_posn == 0)
59784684ddb6SLionel Sambuc #endif // !_LIBCPP_MSVCRT
59794684ddb6SLionel Sambuc         __positive_sign_ = "()";
59804684ddb6SLionel Sambuc     else
59814684ddb6SLionel Sambuc         __positive_sign_ = lc->positive_sign;
59824684ddb6SLionel Sambuc #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
59834684ddb6SLionel Sambuc     if(lc->n_sign_posn == 0)
59844684ddb6SLionel Sambuc #else // _LIBCPP_MSVCRT
59854684ddb6SLionel Sambuc     if (lc->int_n_sign_posn == 0)
59864684ddb6SLionel Sambuc #endif // !_LIBCPP_MSVCRT
59874684ddb6SLionel Sambuc         __negative_sign_ = "()";
59884684ddb6SLionel Sambuc     else
59894684ddb6SLionel Sambuc         __negative_sign_ = lc->negative_sign;
59904684ddb6SLionel Sambuc     // Assume the positive and negative formats will want spaces in
59914684ddb6SLionel Sambuc     // the same places in curr_symbol since there's no way to
59924684ddb6SLionel Sambuc     // represent anything else.
59934684ddb6SLionel Sambuc     string_type __dummy_curr_symbol = __curr_symbol_;
59944684ddb6SLionel Sambuc #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
59954684ddb6SLionel Sambuc     __init_pat(__pos_format_, __dummy_curr_symbol, true,
59964684ddb6SLionel Sambuc                lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, ' ');
59974684ddb6SLionel Sambuc     __init_pat(__neg_format_, __curr_symbol_, true,
59984684ddb6SLionel Sambuc                lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, ' ');
59994684ddb6SLionel Sambuc #else // _LIBCPP_MSVCRT
60004684ddb6SLionel Sambuc     __init_pat(__pos_format_, __dummy_curr_symbol, true,
60014684ddb6SLionel Sambuc                lc->int_p_cs_precedes, lc->int_p_sep_by_space,
60024684ddb6SLionel Sambuc                lc->int_p_sign_posn, ' ');
60034684ddb6SLionel Sambuc     __init_pat(__neg_format_, __curr_symbol_, true,
60044684ddb6SLionel Sambuc                lc->int_n_cs_precedes, lc->int_n_sep_by_space,
60054684ddb6SLionel Sambuc                lc->int_n_sign_posn, ' ');
60064684ddb6SLionel Sambuc #endif // !_LIBCPP_MSVCRT
60074684ddb6SLionel Sambuc }
60084684ddb6SLionel Sambuc 
60094684ddb6SLionel Sambuc template<>
60104684ddb6SLionel Sambuc void
init(const char * nm)60114684ddb6SLionel Sambuc moneypunct_byname<wchar_t, false>::init(const char* nm)
60124684ddb6SLionel Sambuc {
60134684ddb6SLionel Sambuc     typedef moneypunct<wchar_t, false> base;
60144684ddb6SLionel Sambuc     __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
60154684ddb6SLionel Sambuc #ifndef _LIBCPP_NO_EXCEPTIONS
60164684ddb6SLionel Sambuc     if (loc == nullptr)
60174684ddb6SLionel Sambuc         throw runtime_error("moneypunct_byname"
60184684ddb6SLionel Sambuc                             " failed to construct for " + string(nm));
60194684ddb6SLionel Sambuc #endif  // _LIBCPP_NO_EXCEPTIONS
60204684ddb6SLionel Sambuc #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
60214684ddb6SLionel Sambuc     lconv* lc = localeconv_l(loc.get());
60224684ddb6SLionel Sambuc #else
60234684ddb6SLionel Sambuc     lconv* lc = __localeconv_l(loc.get());
60244684ddb6SLionel Sambuc #endif
60254684ddb6SLionel Sambuc     if (*lc->mon_decimal_point)
60264684ddb6SLionel Sambuc         __decimal_point_ = static_cast<wchar_t>(*lc->mon_decimal_point);
60274684ddb6SLionel Sambuc     else
60284684ddb6SLionel Sambuc         __decimal_point_ = base::do_decimal_point();
60294684ddb6SLionel Sambuc     if (*lc->mon_thousands_sep)
60304684ddb6SLionel Sambuc         __thousands_sep_ = static_cast<wchar_t>(*lc->mon_thousands_sep);
60314684ddb6SLionel Sambuc     else
60324684ddb6SLionel Sambuc         __thousands_sep_ = base::do_thousands_sep();
60334684ddb6SLionel Sambuc     __grouping_ = lc->mon_grouping;
60344684ddb6SLionel Sambuc     wchar_t wbuf[100];
60354684ddb6SLionel Sambuc     mbstate_t mb = {0};
60364684ddb6SLionel Sambuc     const char* bb = lc->currency_symbol;
60374684ddb6SLionel Sambuc #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
60384684ddb6SLionel Sambuc     size_t j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
60394684ddb6SLionel Sambuc #else
60404684ddb6SLionel Sambuc     size_t j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
60414684ddb6SLionel Sambuc #endif
60424684ddb6SLionel Sambuc     if (j == size_t(-1))
60434684ddb6SLionel Sambuc         __throw_runtime_error("locale not supported");
60444684ddb6SLionel Sambuc     wchar_t* wbe = wbuf + j;
60454684ddb6SLionel Sambuc     __curr_symbol_.assign(wbuf, wbe);
60464684ddb6SLionel Sambuc     if (lc->frac_digits != CHAR_MAX)
60474684ddb6SLionel Sambuc         __frac_digits_ = lc->frac_digits;
60484684ddb6SLionel Sambuc     else
60494684ddb6SLionel Sambuc         __frac_digits_ = base::do_frac_digits();
60504684ddb6SLionel Sambuc     if (lc->p_sign_posn == 0)
60514684ddb6SLionel Sambuc         __positive_sign_ = L"()";
60524684ddb6SLionel Sambuc     else
60534684ddb6SLionel Sambuc     {
60544684ddb6SLionel Sambuc         mb = mbstate_t();
60554684ddb6SLionel Sambuc         bb = lc->positive_sign;
60564684ddb6SLionel Sambuc #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
60574684ddb6SLionel Sambuc         j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
60584684ddb6SLionel Sambuc #else
60594684ddb6SLionel Sambuc         j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
60604684ddb6SLionel Sambuc #endif
60614684ddb6SLionel Sambuc         if (j == size_t(-1))
60624684ddb6SLionel Sambuc             __throw_runtime_error("locale not supported");
60634684ddb6SLionel Sambuc         wbe = wbuf + j;
60644684ddb6SLionel Sambuc         __positive_sign_.assign(wbuf, wbe);
60654684ddb6SLionel Sambuc     }
60664684ddb6SLionel Sambuc     if (lc->n_sign_posn == 0)
60674684ddb6SLionel Sambuc         __negative_sign_ = L"()";
60684684ddb6SLionel Sambuc     else
60694684ddb6SLionel Sambuc     {
60704684ddb6SLionel Sambuc         mb = mbstate_t();
60714684ddb6SLionel Sambuc         bb = lc->negative_sign;
60724684ddb6SLionel Sambuc #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
60734684ddb6SLionel Sambuc         j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
60744684ddb6SLionel Sambuc #else
60754684ddb6SLionel Sambuc         j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
60764684ddb6SLionel Sambuc #endif
60774684ddb6SLionel Sambuc         if (j == size_t(-1))
60784684ddb6SLionel Sambuc             __throw_runtime_error("locale not supported");
60794684ddb6SLionel Sambuc         wbe = wbuf + j;
60804684ddb6SLionel Sambuc         __negative_sign_.assign(wbuf, wbe);
60814684ddb6SLionel Sambuc     }
60824684ddb6SLionel Sambuc     // Assume the positive and negative formats will want spaces in
60834684ddb6SLionel Sambuc     // the same places in curr_symbol since there's no way to
60844684ddb6SLionel Sambuc     // represent anything else.
60854684ddb6SLionel Sambuc     string_type __dummy_curr_symbol = __curr_symbol_;
60864684ddb6SLionel Sambuc     __init_pat(__pos_format_, __dummy_curr_symbol, false,
60874684ddb6SLionel Sambuc                lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, L' ');
60884684ddb6SLionel Sambuc     __init_pat(__neg_format_, __curr_symbol_, false,
60894684ddb6SLionel Sambuc                lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, L' ');
60904684ddb6SLionel Sambuc }
60914684ddb6SLionel Sambuc 
60924684ddb6SLionel Sambuc template<>
60934684ddb6SLionel Sambuc void
init(const char * nm)60944684ddb6SLionel Sambuc moneypunct_byname<wchar_t, true>::init(const char* nm)
60954684ddb6SLionel Sambuc {
60964684ddb6SLionel Sambuc     typedef moneypunct<wchar_t, true> base;
60974684ddb6SLionel Sambuc     __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
60984684ddb6SLionel Sambuc #ifndef _LIBCPP_NO_EXCEPTIONS
60994684ddb6SLionel Sambuc     if (loc == nullptr)
61004684ddb6SLionel Sambuc         throw runtime_error("moneypunct_byname"
61014684ddb6SLionel Sambuc                             " failed to construct for " + string(nm));
61024684ddb6SLionel Sambuc #endif  // _LIBCPP_NO_EXCEPTIONS
61034684ddb6SLionel Sambuc #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
61044684ddb6SLionel Sambuc     lconv* lc = localeconv_l(loc.get());
61054684ddb6SLionel Sambuc #else
61064684ddb6SLionel Sambuc     lconv* lc = __localeconv_l(loc.get());
61074684ddb6SLionel Sambuc #endif
61084684ddb6SLionel Sambuc     if (*lc->mon_decimal_point)
61094684ddb6SLionel Sambuc         __decimal_point_ = static_cast<wchar_t>(*lc->mon_decimal_point);
61104684ddb6SLionel Sambuc     else
61114684ddb6SLionel Sambuc         __decimal_point_ = base::do_decimal_point();
61124684ddb6SLionel Sambuc     if (*lc->mon_thousands_sep)
61134684ddb6SLionel Sambuc         __thousands_sep_ = static_cast<wchar_t>(*lc->mon_thousands_sep);
61144684ddb6SLionel Sambuc     else
61154684ddb6SLionel Sambuc         __thousands_sep_ = base::do_thousands_sep();
61164684ddb6SLionel Sambuc     __grouping_ = lc->mon_grouping;
61174684ddb6SLionel Sambuc     wchar_t wbuf[100];
61184684ddb6SLionel Sambuc     mbstate_t mb = {0};
61194684ddb6SLionel Sambuc     const char* bb = lc->int_curr_symbol;
61204684ddb6SLionel Sambuc #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
61214684ddb6SLionel Sambuc     size_t j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
61224684ddb6SLionel Sambuc #else
61234684ddb6SLionel Sambuc     size_t j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
61244684ddb6SLionel Sambuc #endif
61254684ddb6SLionel Sambuc     if (j == size_t(-1))
61264684ddb6SLionel Sambuc         __throw_runtime_error("locale not supported");
61274684ddb6SLionel Sambuc     wchar_t* wbe = wbuf + j;
61284684ddb6SLionel Sambuc     __curr_symbol_.assign(wbuf, wbe);
61294684ddb6SLionel Sambuc     if (lc->int_frac_digits != CHAR_MAX)
61304684ddb6SLionel Sambuc         __frac_digits_ = lc->int_frac_digits;
61314684ddb6SLionel Sambuc     else
61324684ddb6SLionel Sambuc         __frac_digits_ = base::do_frac_digits();
61334684ddb6SLionel Sambuc #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
61344684ddb6SLionel Sambuc     if (lc->p_sign_posn == 0)
61354684ddb6SLionel Sambuc #else // _LIBCPP_MSVCRT
61364684ddb6SLionel Sambuc     if (lc->int_p_sign_posn == 0)
61374684ddb6SLionel Sambuc #endif // !_LIBCPP_MSVCRT
61384684ddb6SLionel Sambuc         __positive_sign_ = L"()";
61394684ddb6SLionel Sambuc     else
61404684ddb6SLionel Sambuc     {
61414684ddb6SLionel Sambuc         mb = mbstate_t();
61424684ddb6SLionel Sambuc         bb = lc->positive_sign;
61434684ddb6SLionel Sambuc #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
61444684ddb6SLionel Sambuc         j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
61454684ddb6SLionel Sambuc #else
61464684ddb6SLionel Sambuc         j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
61474684ddb6SLionel Sambuc #endif
61484684ddb6SLionel Sambuc         if (j == size_t(-1))
61494684ddb6SLionel Sambuc             __throw_runtime_error("locale not supported");
61504684ddb6SLionel Sambuc         wbe = wbuf + j;
61514684ddb6SLionel Sambuc         __positive_sign_.assign(wbuf, wbe);
61524684ddb6SLionel Sambuc     }
61534684ddb6SLionel Sambuc #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
61544684ddb6SLionel Sambuc     if (lc->n_sign_posn == 0)
61554684ddb6SLionel Sambuc #else // _LIBCPP_MSVCRT
61564684ddb6SLionel Sambuc     if (lc->int_n_sign_posn == 0)
61574684ddb6SLionel Sambuc #endif // !_LIBCPP_MSVCRT
61584684ddb6SLionel Sambuc         __negative_sign_ = L"()";
61594684ddb6SLionel Sambuc     else
61604684ddb6SLionel Sambuc     {
61614684ddb6SLionel Sambuc         mb = mbstate_t();
61624684ddb6SLionel Sambuc         bb = lc->negative_sign;
61634684ddb6SLionel Sambuc #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
61644684ddb6SLionel Sambuc         j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
61654684ddb6SLionel Sambuc #else
61664684ddb6SLionel Sambuc         j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
61674684ddb6SLionel Sambuc #endif
61684684ddb6SLionel Sambuc         if (j == size_t(-1))
61694684ddb6SLionel Sambuc             __throw_runtime_error("locale not supported");
61704684ddb6SLionel Sambuc         wbe = wbuf + j;
61714684ddb6SLionel Sambuc         __negative_sign_.assign(wbuf, wbe);
61724684ddb6SLionel Sambuc     }
61734684ddb6SLionel Sambuc     // Assume the positive and negative formats will want spaces in
61744684ddb6SLionel Sambuc     // the same places in curr_symbol since there's no way to
61754684ddb6SLionel Sambuc     // represent anything else.
61764684ddb6SLionel Sambuc     string_type __dummy_curr_symbol = __curr_symbol_;
61774684ddb6SLionel Sambuc #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
61784684ddb6SLionel Sambuc     __init_pat(__pos_format_, __dummy_curr_symbol, true,
61794684ddb6SLionel Sambuc                lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, L' ');
61804684ddb6SLionel Sambuc     __init_pat(__neg_format_, __curr_symbol_, true,
61814684ddb6SLionel Sambuc                lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, L' ');
61824684ddb6SLionel Sambuc #else // _LIBCPP_MSVCRT
61834684ddb6SLionel Sambuc     __init_pat(__pos_format_, __dummy_curr_symbol, true,
61844684ddb6SLionel Sambuc                lc->int_p_cs_precedes, lc->int_p_sep_by_space,
61854684ddb6SLionel Sambuc                lc->int_p_sign_posn, L' ');
61864684ddb6SLionel Sambuc     __init_pat(__neg_format_, __curr_symbol_, true,
61874684ddb6SLionel Sambuc                lc->int_n_cs_precedes, lc->int_n_sep_by_space,
61884684ddb6SLionel Sambuc                lc->int_n_sign_posn, L' ');
61894684ddb6SLionel Sambuc #endif // !_LIBCPP_MSVCRT
61904684ddb6SLionel Sambuc }
61914684ddb6SLionel Sambuc 
__do_nothing(void *)61924684ddb6SLionel Sambuc void __do_nothing(void*) {}
61934684ddb6SLionel Sambuc 
__throw_runtime_error(const char * msg)61944684ddb6SLionel Sambuc void __throw_runtime_error(const char* msg)
61954684ddb6SLionel Sambuc {
61964684ddb6SLionel Sambuc #ifndef _LIBCPP_NO_EXCEPTIONS
61974684ddb6SLionel Sambuc     throw runtime_error(msg);
61984684ddb6SLionel Sambuc #else
61994684ddb6SLionel Sambuc     (void)msg;
62004684ddb6SLionel Sambuc #endif
62014684ddb6SLionel Sambuc }
62024684ddb6SLionel Sambuc 
62034684ddb6SLionel Sambuc template class collate<char>;
62044684ddb6SLionel Sambuc template class collate<wchar_t>;
62054684ddb6SLionel Sambuc 
62064684ddb6SLionel Sambuc template class num_get<char>;
62074684ddb6SLionel Sambuc template class num_get<wchar_t>;
62084684ddb6SLionel Sambuc 
62094684ddb6SLionel Sambuc template struct __num_get<char>;
62104684ddb6SLionel Sambuc template struct __num_get<wchar_t>;
62114684ddb6SLionel Sambuc 
62124684ddb6SLionel Sambuc template class num_put<char>;
62134684ddb6SLionel Sambuc template class num_put<wchar_t>;
62144684ddb6SLionel Sambuc 
62154684ddb6SLionel Sambuc template struct __num_put<char>;
62164684ddb6SLionel Sambuc template struct __num_put<wchar_t>;
62174684ddb6SLionel Sambuc 
62184684ddb6SLionel Sambuc template class time_get<char>;
62194684ddb6SLionel Sambuc template class time_get<wchar_t>;
62204684ddb6SLionel Sambuc 
62214684ddb6SLionel Sambuc template class time_get_byname<char>;
62224684ddb6SLionel Sambuc template class time_get_byname<wchar_t>;
62234684ddb6SLionel Sambuc 
62244684ddb6SLionel Sambuc template class time_put<char>;
62254684ddb6SLionel Sambuc template class time_put<wchar_t>;
62264684ddb6SLionel Sambuc 
62274684ddb6SLionel Sambuc template class time_put_byname<char>;
62284684ddb6SLionel Sambuc template class time_put_byname<wchar_t>;
62294684ddb6SLionel Sambuc 
62304684ddb6SLionel Sambuc template class moneypunct<char, false>;
62314684ddb6SLionel Sambuc template class moneypunct<char, true>;
62324684ddb6SLionel Sambuc template class moneypunct<wchar_t, false>;
62334684ddb6SLionel Sambuc template class moneypunct<wchar_t, true>;
62344684ddb6SLionel Sambuc 
62354684ddb6SLionel Sambuc template class moneypunct_byname<char, false>;
62364684ddb6SLionel Sambuc template class moneypunct_byname<char, true>;
62374684ddb6SLionel Sambuc template class moneypunct_byname<wchar_t, false>;
62384684ddb6SLionel Sambuc template class moneypunct_byname<wchar_t, true>;
62394684ddb6SLionel Sambuc 
62404684ddb6SLionel Sambuc template class money_get<char>;
62414684ddb6SLionel Sambuc template class money_get<wchar_t>;
62424684ddb6SLionel Sambuc 
62434684ddb6SLionel Sambuc template class __money_get<char>;
62444684ddb6SLionel Sambuc template class __money_get<wchar_t>;
62454684ddb6SLionel Sambuc 
62464684ddb6SLionel Sambuc template class money_put<char>;
62474684ddb6SLionel Sambuc template class money_put<wchar_t>;
62484684ddb6SLionel Sambuc 
62494684ddb6SLionel Sambuc template class __money_put<char>;
62504684ddb6SLionel Sambuc template class __money_put<wchar_t>;
62514684ddb6SLionel Sambuc 
62524684ddb6SLionel Sambuc template class messages<char>;
62534684ddb6SLionel Sambuc template class messages<wchar_t>;
62544684ddb6SLionel Sambuc 
62554684ddb6SLionel Sambuc template class messages_byname<char>;
62564684ddb6SLionel Sambuc template class messages_byname<wchar_t>;
62574684ddb6SLionel Sambuc 
62584684ddb6SLionel Sambuc template class codecvt_byname<char, char, mbstate_t>;
62594684ddb6SLionel Sambuc template class codecvt_byname<wchar_t, char, mbstate_t>;
62604684ddb6SLionel Sambuc template class codecvt_byname<char16_t, char, mbstate_t>;
62614684ddb6SLionel Sambuc template class codecvt_byname<char32_t, char, mbstate_t>;
62624684ddb6SLionel Sambuc 
62634684ddb6SLionel Sambuc template class __vector_base_common<true>;
62644684ddb6SLionel Sambuc 
62654684ddb6SLionel Sambuc _LIBCPP_END_NAMESPACE_STD
6266