__locale revision 11624459ef27e06ef2d8e71ec2d35bdd334dbbd9
1bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// -*- C++ -*-
2bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant//===----------------------------------------------------------------------===//
3bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant//
4f5256e16dfc425c1d466f6308d4026d529ce9e0bHoward Hinnant//                     The LLVM Compiler Infrastructure
5bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant//
6b64f8b07c104c6cc986570ac8ee0ed16a9f23976Howard Hinnant// This file is dual licensed under the MIT and the University of Illinois Open
7b64f8b07c104c6cc986570ac8ee0ed16a9f23976Howard Hinnant// Source Licenses. See LICENSE.TXT for details.
8bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant//
9bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant//===----------------------------------------------------------------------===//
10bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
11bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant#ifndef _LIBCPP___LOCALE
12bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant#define _LIBCPP___LOCALE
13bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
14bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant#include <__config>
15bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant#include <string>
16bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant#include <memory>
17bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant#include <utility>
18bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant#include <mutex>
19bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant#include <cstdint>
20bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant#include <cctype>
21bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant#include <locale.h>
22bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant#if _WIN32
23bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant# include <support/win32/locale_win32.h>
24bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant#elif (__GLIBC__ || __APPLE__ || __FreeBSD__)
25bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant# include <xlocale.h>
26bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant#endif  // _WIN32 || __GLIBC__ || __APPLE__ || __FreeBSD_
27bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
28bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant#pragma GCC system_header
29bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
30bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant_LIBCPP_BEGIN_NAMESPACE_STD
31bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
32bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantclass locale;
33bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
34bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnanttemplate <class _Facet> bool has_facet(const locale&) _NOEXCEPT;
35bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnanttemplate <class _Facet> const _Facet& use_facet(const locale&);
36bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
37bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantclass _LIBCPP_VISIBLE locale
38bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant{
39bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantpublic:
40bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    // types:
41bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    class facet;
42bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    class id;
43bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
44bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    typedef int category;
45bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    static const category // values assigned here are for exposition only
46bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        none     = 0,
47bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        collate  = LC_COLLATE_MASK,
48bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        ctype    = LC_CTYPE_MASK,
49bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        monetary = LC_MONETARY_MASK,
50bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        numeric  = LC_NUMERIC_MASK,
51bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        time     = LC_TIME_MASK,
52bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        messages = LC_MESSAGES_MASK,
53bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        all = collate | ctype | monetary | numeric | time | messages;
54bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
55bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    // construct/copy/destroy:
56bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    locale()  _NOEXCEPT;
57bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    locale(const locale&)  _NOEXCEPT;
58bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    explicit locale(const char*);
59bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    explicit locale(const string&);
60bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    locale(const locale&, const char*, category);
61bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    locale(const locale&, const string&, category);
62bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    template <class _Facet>
63bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        _LIBCPP_INLINE_VISIBILITY locale(const locale&, _Facet*);
64bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    locale(const locale&, const locale&, category);
65bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
66bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    ~locale();
67bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
68bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    const locale& operator=(const locale&)  _NOEXCEPT;
69bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
70bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    template <class _Facet> locale combine(const locale&) const;
71bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
72bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    // locale operations:
73bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    string name() const;
74bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    bool operator==(const locale&) const;
75bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    bool operator!=(const locale& __y) const {return !(*this == __y);}
76bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    template <class _CharT, class _Traits, class _Allocator>
77bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant      bool operator()(const basic_string<_CharT, _Traits, _Allocator>&,
78bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant                      const basic_string<_CharT, _Traits, _Allocator>&) const;
79bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
80bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    // global locale objects:
81bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    static locale global(const locale&);
82bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    static const locale& classic();
83bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
84bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantprivate:
85bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    class __imp;
86bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    __imp* __locale_;
87bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
88bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    void __install_ctor(const locale&, facet*, long);
89bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    static locale& __global();
90bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    bool has_facet(id&) const;
91bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    const facet* use_facet(id&) const;
92bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
93bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    template <class _Facet> friend bool has_facet(const locale&)  _NOEXCEPT;
94bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    template <class _Facet> friend const _Facet& use_facet(const locale&);
95bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant};
96bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
97bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantclass _LIBCPP_VISIBLE locale::facet
98bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    : public __shared_count
99bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant{
1000949eedbd621bc1611266fb180d9a356ee1eaf9fHoward Hinnantprotected:
101bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    _LIBCPP_INLINE_VISIBILITY
102bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    explicit facet(size_t __refs = 0)
103bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        : __shared_count(static_cast<long>(__refs)-1) {}
104bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
105bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    virtual ~facet();
106bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
107bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant//    facet(const facet&) = delete;     // effectively done in __shared_count
108bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant//    void operator=(const facet&) = delete;
109bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantprivate:
110bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    virtual void __on_zero_shared() _NOEXCEPT;
111bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant};
112bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
113bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantclass _LIBCPP_VISIBLE locale::id
114bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant{
115bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    once_flag      __flag_;
116bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    int32_t        __id_;
117bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
118bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    static int32_t __next_id;
119bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantpublic:
120bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    _LIBCPP_INLINE_VISIBILITY id() {}
121bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantprivate:
122bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    void __init();
1230949eedbd621bc1611266fb180d9a356ee1eaf9fHoward Hinnant    void operator=(const id&); // = delete;
124bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    id(const id&); // = delete;
125bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantpublic:  // only needed for tests
126bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    long __get();
127bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
128bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    friend class locale;
129bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    friend class locale::__imp;
130bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant};
131bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
132bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnanttemplate <class _Facet>
133bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantinline _LIBCPP_INLINE_VISIBILITY
134bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantlocale::locale(const locale& __other, _Facet* __f)
135bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant{
136bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    __install_ctor(__other, __f, __f ? __f->id.__get() : 0);
137bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant}
138bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
1390949eedbd621bc1611266fb180d9a356ee1eaf9fHoward Hinnanttemplate <class _Facet>
140bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantlocale
141bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantlocale::combine(const locale& __other) const
142bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant{
1430949eedbd621bc1611266fb180d9a356ee1eaf9fHoward Hinnant#ifndef _LIBCPP_NO_EXCEPTIONS
144bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    if (!_VSTD::has_facet<_Facet>(__other))
145bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        throw runtime_error("locale::combine: locale missing facet");
146bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant#endif  // _LIBCPP_NO_EXCEPTIONS
147bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    return locale(*this, &const_cast<_Facet&>(_VSTD::use_facet<_Facet>(__other)));
148bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant}
149bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
150bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnanttemplate <class _Facet>
151bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantinline _LIBCPP_INLINE_VISIBILITY
152bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantbool
153bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnanthas_facet(const locale& __l)  _NOEXCEPT
154bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant{
155bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    return __l.has_facet(_Facet::id);
156bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant}
157bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
158bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnanttemplate <class _Facet>
159bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantinline _LIBCPP_INLINE_VISIBILITY
160bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantconst _Facet&
161bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantuse_facet(const locale& __l)
162bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant{
163bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    return static_cast<const _Facet&>(*__l.use_facet(_Facet::id));
164bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant}
165bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
166bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// template <class _CharT> class collate;
167bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
168bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnanttemplate <class _CharT>
1690949eedbd621bc1611266fb180d9a356ee1eaf9fHoward Hinnantclass _LIBCPP_VISIBLE collate
170bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    : public locale::facet
1710949eedbd621bc1611266fb180d9a356ee1eaf9fHoward Hinnant{
172bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantpublic:
173bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    typedef _CharT char_type;
174bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    typedef basic_string<char_type> string_type;
175bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
176bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    _LIBCPP_INLINE_VISIBILITY
177bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    explicit collate(size_t __refs = 0)
178bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        : locale::facet(__refs) {}
179bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
180bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    _LIBCPP_INLINE_VISIBILITY
181bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    int compare(const char_type* __lo1, const char_type* __hi1,
182f5256e16dfc425c1d466f6308d4026d529ce9e0bHoward Hinnant                const char_type* __lo2, const char_type* __hi2) const
183bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    {
184bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        return do_compare(__lo1, __hi1, __lo2, __hi2);
185bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    }
186bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
187bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    _LIBCPP_INLINE_VISIBILITY
188bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    string_type transform(const char_type* __lo, const char_type* __hi) const
189bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    {
190bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        return do_transform(__lo, __hi);
191bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    }
192bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
193bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    _LIBCPP_INLINE_VISIBILITY
194bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    long hash(const char_type* __lo, const char_type* __hi) const
195bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    {
196bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        return do_hash(__lo, __hi);
197bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    }
198bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
199bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    static locale::id id;
200bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
201bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantprotected:
202bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    ~collate();
203bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    virtual int do_compare(const char_type* __lo1, const char_type* __hi1,
204bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant                           const char_type* __lo2, const char_type* __hi2) const;
205bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    virtual string_type do_transform(const char_type* __lo, const char_type* __hi) const
206bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        {return string_type(__lo, __hi);}
207bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    virtual long do_hash(const char_type* __lo, const char_type* __hi) const;
208bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant};
209bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
210bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnanttemplate <class _CharT> locale::id collate<_CharT>::id;
211bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
212bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnanttemplate <class _CharT>
213bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantcollate<_CharT>::~collate()
214bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant{
215bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant}
216bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
217bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnanttemplate <class _CharT>
218bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantint
219bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantcollate<_CharT>::do_compare(const char_type* __lo1, const char_type* __hi1,
220bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant                            const char_type* __lo2, const char_type* __hi2) const
221bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant{
222bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    for (; __lo2 != __hi2; ++__lo1, ++__lo2)
223bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    {
224bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        if (__lo1 == __hi1 || *__lo1 < *__lo2)
225bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant            return -1;
226bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        if (*__lo2 < *__lo1)
227bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant            return 1;
228bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    }
229bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    return __lo1 != __hi1;
230bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant}
231bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
232bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnanttemplate <class _CharT>
233bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantlong
234bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantcollate<_CharT>::do_hash(const char_type* __lo, const char_type* __hi) const
235bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant{
236bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    size_t __h = 0;
237bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    const size_t __sr = __CHAR_BIT__ * sizeof(size_t) - 8;
238bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    const size_t __mask = size_t(0xF) << (__sr + 4);
239bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    for(const char_type* __p = __lo; __p != __hi; ++__p)
240bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    {
241bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        __h = (__h << 4) + *__p;
242bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        size_t __g = __h & __mask;
243bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        __h ^= __g | (__g >> __sr);
244bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    }
245bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    return static_cast<long>(__h);
246bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant}
247bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
248bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantextern template class _LIBCPP_VISIBLE collate<char>;
249bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantextern template class _LIBCPP_VISIBLE collate<wchar_t>;
250bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
251bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// template <class CharT> class collate_byname;
252bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
253bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnanttemplate <class _CharT> class _LIBCPP_VISIBLE collate_byname;
254bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
255bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnanttemplate <>
256bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantclass _LIBCPP_VISIBLE collate_byname<char>
257bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    : public collate<char>
258bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant{
259bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    locale_t __l;
260bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantpublic:
261bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    typedef char char_type;
262bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    typedef basic_string<char_type> string_type;
263bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
264bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    explicit collate_byname(const char* __n, size_t __refs = 0);
265bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    explicit collate_byname(const string& __n, size_t __refs = 0);
266bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
267bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantprotected:
268bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    ~collate_byname();
269bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    virtual int do_compare(const char_type* __lo1, const char_type* __hi1,
270bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant                           const char_type* __lo2, const char_type* __hi2) const;
271bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    virtual string_type do_transform(const char_type* __lo, const char_type* __hi) const;
272bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant};
273bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
274bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnanttemplate <>
275bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantclass _LIBCPP_VISIBLE collate_byname<wchar_t>
276bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    : public collate<wchar_t>
277bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant{
278bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    locale_t __l;
279bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantpublic:
280bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    typedef wchar_t char_type;
281bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    typedef basic_string<char_type> string_type;
282bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
283bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    explicit collate_byname(const char* __n, size_t __refs = 0);
284bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    explicit collate_byname(const string& __n, size_t __refs = 0);
285bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
286bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantprotected:
287bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    ~collate_byname();
288bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
289bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    virtual int do_compare(const char_type* __lo1, const char_type* __hi1,
290bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant                           const char_type* __lo2, const char_type* __hi2) const;
291bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    virtual string_type do_transform(const char_type* __lo, const char_type* __hi) const;
292bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant};
293bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
294bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnanttemplate <class _CharT, class _Traits, class _Allocator>
295bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantbool
296bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantlocale::operator()(const basic_string<_CharT, _Traits, _Allocator>& __x,
297bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant                   const basic_string<_CharT, _Traits, _Allocator>& __y) const
298bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant{
299bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    return _VSTD::use_facet<_VSTD::collate<_CharT> >(*this).compare(
300bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant                                       __x.data(), __x.data() + __x.size(),
301bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant                                       __y.data(), __y.data() + __y.size()) < 0;
302bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant}
303bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
304bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// template <class charT> class ctype
305bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
306bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantclass _LIBCPP_VISIBLE ctype_base
307bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant{
308bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantpublic:
309bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant#if __GLIBC__
310bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    typedef unsigned short mask;
311bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    static const mask space  = _ISspace;
312bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    static const mask print  = _ISprint;
313bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    static const mask cntrl  = _IScntrl;
314    static const mask upper  = _ISupper;
315    static const mask lower  = _ISlower;
316    static const mask alpha  = _ISalpha;
317    static const mask digit  = _ISdigit;
318    static const mask punct  = _ISpunct;
319    static const mask xdigit = _ISxdigit;
320    static const mask blank  = _ISblank;
321#elif _WIN32
322    typedef unsigned short mask;
323    static const mask space  = _SPACE;
324    static const mask print  = _BLANK|_PUNCT|_ALPHA|_DIGIT;
325    static const mask cntrl  = _CONTROL;
326    static const mask upper  = _UPPER;
327    static const mask lower  = _LOWER;
328    static const mask alpha  = _ALPHA;
329    static const mask digit  = _DIGIT;
330    static const mask punct  = _PUNCT;
331    static const mask xdigit = _HEX;
332    static const mask blank  = _BLANK;
333#elif (__APPLE__ || __FreeBSD__)
334#if __APPLE__
335    typedef __uint32_t mask;
336#elif __FreeBSD__
337    typedef unsigned long mask;
338#endif
339    static const mask space  = _CTYPE_S;
340    static const mask print  = _CTYPE_R;
341    static const mask cntrl  = _CTYPE_C;
342    static const mask upper  = _CTYPE_U;
343    static const mask lower  = _CTYPE_L;
344    static const mask alpha  = _CTYPE_A;
345    static const mask digit  = _CTYPE_D;
346    static const mask punct  = _CTYPE_P;
347    static const mask xdigit = _CTYPE_X;
348    static const mask blank  = _CTYPE_B;
349#else  // __GLIBC__ || _WIN32 || __APPLE__ || __FreeBSD__
350    typedef unsigned long mask;
351    static const mask space  = 1<<0;
352    static const mask print  = 1<<1;
353    static const mask cntrl  = 1<<2;
354    static const mask upper  = 1<<3;
355    static const mask lower  = 1<<4;
356    static const mask alpha  = 1<<5;
357    static const mask digit  = 1<<6;
358    static const mask punct  = 1<<7;
359    static const mask xdigit = 1<<8;
360    static const mask blank  = 1<<9;
361#endif  // __GLIBC__ || _WIN32 || __APPLE__ || __FreeBSD__
362    static const mask alnum  = alpha | digit;
363    static const mask graph  = alnum | punct;
364
365    _LIBCPP_ALWAYS_INLINE ctype_base() {}
366};
367
368template <class _CharT> class _LIBCPP_VISIBLE ctype;
369
370template <>
371class _LIBCPP_VISIBLE ctype<wchar_t>
372    : public locale::facet,
373      public ctype_base
374{
375public:
376    typedef wchar_t char_type;
377
378    _LIBCPP_ALWAYS_INLINE
379    explicit ctype(size_t __refs = 0)
380        : locale::facet(__refs) {}
381
382    _LIBCPP_ALWAYS_INLINE
383    bool is(mask __m, char_type __c) const
384    {
385        return do_is(__m, __c);
386    }
387
388    _LIBCPP_ALWAYS_INLINE
389    const char_type* is(const char_type* __low, const char_type* __high, mask* __vec) const
390    {
391        return do_is(__low, __high, __vec);
392    }
393
394    _LIBCPP_ALWAYS_INLINE
395    const char_type* scan_is(mask __m, const char_type* __low, const char_type* __high) const
396    {
397        return do_scan_is(__m, __low, __high);
398    }
399
400    _LIBCPP_ALWAYS_INLINE
401    const char_type* scan_not(mask __m, const char_type* __low, const char_type* __high) const
402    {
403        return do_scan_not(__m, __low, __high);
404    }
405
406    _LIBCPP_ALWAYS_INLINE
407    char_type toupper(char_type __c) const
408    {
409        return do_toupper(__c);
410    }
411
412    _LIBCPP_ALWAYS_INLINE
413    const char_type* toupper(char_type* __low, const char_type* __high) const
414    {
415        return do_toupper(__low, __high);
416    }
417
418    _LIBCPP_ALWAYS_INLINE
419    char_type tolower(char_type __c) const
420    {
421        return do_tolower(__c);
422    }
423
424    _LIBCPP_ALWAYS_INLINE
425    const char_type* tolower(char_type* __low, const char_type* __high) const
426    {
427        return do_tolower(__low, __high);
428    }
429
430    _LIBCPP_ALWAYS_INLINE
431    char_type widen(char __c) const
432    {
433        return do_widen(__c);
434    }
435
436    _LIBCPP_ALWAYS_INLINE
437    const char* widen(const char* __low, const char* __high, char_type* __to) const
438    {
439        return do_widen(__low, __high, __to);
440    }
441
442    _LIBCPP_ALWAYS_INLINE
443    char narrow(char_type __c, char __dfault) const
444    {
445        return do_narrow(__c, __dfault);
446    }
447
448    _LIBCPP_ALWAYS_INLINE
449    const char_type* narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const
450    {
451        return do_narrow(__low, __high, __dfault, __to);
452    }
453
454    static locale::id id;
455
456protected:
457    ~ctype();
458    virtual bool do_is(mask __m, char_type __c) const;
459    virtual const char_type* do_is(const char_type* __low, const char_type* __high, mask* __vec) const;
460    virtual const char_type* do_scan_is(mask __m, const char_type* __low, const char_type* __high) const;
461    virtual const char_type* do_scan_not(mask __m, const char_type* __low, const char_type* __high) const;
462    virtual char_type do_toupper(char_type) const;
463    virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const;
464    virtual char_type do_tolower(char_type) const;
465    virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const;
466    virtual char_type do_widen(char) const;
467    virtual const char* do_widen(const char* __low, const char* __high, char_type* __dest) const;
468    virtual char do_narrow(char_type, char __dfault) const;
469    virtual const char_type* do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __dest) const;
470};
471
472template <>
473class _LIBCPP_VISIBLE ctype<char>
474    : public locale::facet, public ctype_base
475{
476    const mask* __tab_;
477    bool        __del_;
478public:
479    typedef char char_type;
480
481    explicit ctype(const mask* __tab = 0, bool __del = false, size_t __refs = 0);
482
483    _LIBCPP_ALWAYS_INLINE
484    bool is(mask __m, char_type __c) const
485    {
486        return isascii(__c) ? __tab_[__c] & __m : false;
487    }
488
489    _LIBCPP_ALWAYS_INLINE
490    const char_type* is(const char_type* __low, const char_type* __high, mask* __vec) const
491    {
492        for (; __low != __high; ++__low, ++__vec)
493            *__vec = isascii(*__low) ? __tab_[*__low] : 0;
494        return __low;
495    }
496
497    _LIBCPP_ALWAYS_INLINE
498    const char_type* scan_is (mask __m, const char_type* __low, const char_type* __high) const
499    {
500        for (; __low != __high; ++__low)
501            if (isascii(*__low) && (__tab_[*__low] & __m))
502                break;
503        return __low;
504    }
505
506    _LIBCPP_ALWAYS_INLINE
507    const char_type* scan_not(mask __m, const char_type* __low, const char_type* __high) const
508    {
509        for (; __low != __high; ++__low)
510            if (!(isascii(*__low) && (__tab_[*__low] & __m)))
511                break;
512        return __low;
513    }
514
515    _LIBCPP_ALWAYS_INLINE
516    char_type toupper(char_type __c) const
517    {
518        return do_toupper(__c);
519    }
520
521    _LIBCPP_ALWAYS_INLINE
522    const char_type* toupper(char_type* __low, const char_type* __high) const
523    {
524        return do_toupper(__low, __high);
525    }
526
527    _LIBCPP_ALWAYS_INLINE
528    char_type tolower(char_type __c) const
529    {
530        return do_tolower(__c);
531    }
532
533    _LIBCPP_ALWAYS_INLINE
534    const char_type* tolower(char_type* __low, const char_type* __high) const
535    {
536        return do_tolower(__low, __high);
537    }
538
539    _LIBCPP_ALWAYS_INLINE
540    char_type widen(char __c) const
541    {
542        return do_widen(__c);
543    }
544
545    _LIBCPP_ALWAYS_INLINE
546    const char* widen(const char* __low, const char* __high, char_type* __to) const
547    {
548        return do_widen(__low, __high, __to);
549    }
550
551    _LIBCPP_ALWAYS_INLINE
552    char narrow(char_type __c, char __dfault) const
553    {
554        return do_narrow(__c, __dfault);
555    }
556
557    _LIBCPP_ALWAYS_INLINE
558    const char* narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const
559    {
560        return do_narrow(__low, __high, __dfault, __to);
561    }
562
563    static locale::id id;
564
565#ifdef _CACHED_RUNES
566    static const size_t table_size = _CACHED_RUNES;
567#else
568    static const size_t table_size = 256;  // FIXME: Don't hardcode this.
569#endif
570    _LIBCPP_ALWAYS_INLINE const mask* table() const  _NOEXCEPT {return __tab_;}
571    static const mask* classic_table()  _NOEXCEPT;
572#if defined(__GLIBC__)
573    static const int* __classic_upper_table() _NOEXCEPT;
574    static const int* __classic_lower_table() _NOEXCEPT;
575#endif
576
577protected:
578    ~ctype();
579    virtual char_type do_toupper(char_type __c) const;
580    virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const;
581    virtual char_type do_tolower(char_type __c) const;
582    virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const;
583    virtual char_type do_widen(char __c) const;
584    virtual const char* do_widen(const char* __low, const char* __high, char_type* __to) const;
585    virtual char do_narrow(char_type __c, char __dfault) const;
586    virtual const char* do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const;
587};
588
589// template <class CharT> class ctype_byname;
590
591template <class _CharT> class _LIBCPP_VISIBLE ctype_byname;
592
593template <>
594class _LIBCPP_VISIBLE ctype_byname<char>
595    : public ctype<char>
596{
597    locale_t __l;
598
599public:
600    explicit ctype_byname(const char*, size_t = 0);
601    explicit ctype_byname(const string&, size_t = 0);
602
603protected:
604    ~ctype_byname();
605    virtual char_type do_toupper(char_type) const;
606    virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const;
607    virtual char_type do_tolower(char_type) const;
608    virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const;
609};
610
611template <>
612class _LIBCPP_VISIBLE ctype_byname<wchar_t>
613    : public ctype<wchar_t>
614{
615    locale_t __l;
616
617public:
618    explicit ctype_byname(const char*, size_t = 0);
619    explicit ctype_byname(const string&, size_t = 0);
620
621protected:
622    ~ctype_byname();
623    virtual bool do_is(mask __m, char_type __c) const;
624    virtual const char_type* do_is(const char_type* __low, const char_type* __high, mask* __vec) const;
625    virtual const char_type* do_scan_is(mask __m, const char_type* __low, const char_type* __high) const;
626    virtual const char_type* do_scan_not(mask __m, const char_type* __low, const char_type* __high) const;
627    virtual char_type do_toupper(char_type) const;
628    virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const;
629    virtual char_type do_tolower(char_type) const;
630    virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const;
631    virtual char_type do_widen(char) const;
632    virtual const char* do_widen(const char* __low, const char* __high, char_type* __dest) const;
633    virtual char do_narrow(char_type, char __dfault) const;
634    virtual const char_type* do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __dest) const;
635};
636
637template <class _CharT>
638inline _LIBCPP_INLINE_VISIBILITY
639bool
640isspace(_CharT __c, const locale& __loc)
641{
642    return use_facet<ctype<_CharT> >(__loc).is(ctype_base::space, __c);
643}
644
645template <class _CharT>
646inline _LIBCPP_INLINE_VISIBILITY
647bool
648isprint(_CharT __c, const locale& __loc)
649{
650    return use_facet<ctype<_CharT> >(__loc).is(ctype_base::print, __c);
651}
652
653template <class _CharT>
654inline _LIBCPP_INLINE_VISIBILITY
655bool
656iscntrl(_CharT __c, const locale& __loc)
657{
658    return use_facet<ctype<_CharT> >(__loc).is(ctype_base::cntrl, __c);
659}
660
661template <class _CharT>
662inline _LIBCPP_INLINE_VISIBILITY
663bool
664isupper(_CharT __c, const locale& __loc)
665{
666    return use_facet<ctype<_CharT> >(__loc).is(ctype_base::upper, __c);
667}
668
669template <class _CharT>
670inline _LIBCPP_INLINE_VISIBILITY
671bool
672islower(_CharT __c, const locale& __loc)
673{
674    return use_facet<ctype<_CharT> >(__loc).is(ctype_base::lower, __c);
675}
676
677template <class _CharT>
678inline _LIBCPP_INLINE_VISIBILITY
679bool
680isalpha(_CharT __c, const locale& __loc)
681{
682    return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alpha, __c);
683}
684
685template <class _CharT>
686inline _LIBCPP_INLINE_VISIBILITY
687bool
688isdigit(_CharT __c, const locale& __loc)
689{
690    return use_facet<ctype<_CharT> >(__loc).is(ctype_base::digit, __c);
691}
692
693template <class _CharT>
694inline _LIBCPP_INLINE_VISIBILITY
695bool
696ispunct(_CharT __c, const locale& __loc)
697{
698    return use_facet<ctype<_CharT> >(__loc).is(ctype_base::punct, __c);
699}
700
701template <class _CharT>
702inline _LIBCPP_INLINE_VISIBILITY
703bool
704isxdigit(_CharT __c, const locale& __loc)
705{
706    return use_facet<ctype<_CharT> >(__loc).is(ctype_base::xdigit, __c);
707}
708
709template <class _CharT>
710inline _LIBCPP_INLINE_VISIBILITY
711bool
712isalnum(_CharT __c, const locale& __loc)
713{
714    return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alnum, __c);
715}
716
717template <class _CharT>
718inline _LIBCPP_INLINE_VISIBILITY
719bool
720isgraph(_CharT __c, const locale& __loc)
721{
722    return use_facet<ctype<_CharT> >(__loc).is(ctype_base::graph, __c);
723}
724
725template <class _CharT>
726inline _LIBCPP_INLINE_VISIBILITY
727_CharT
728toupper(_CharT __c, const locale& __loc)
729{
730    return use_facet<ctype<_CharT> >(__loc).toupper(__c);
731}
732
733template <class _CharT>
734inline _LIBCPP_INLINE_VISIBILITY
735_CharT
736tolower(_CharT __c, const locale& __loc)
737{
738    return use_facet<ctype<_CharT> >(__loc).tolower(__c);
739}
740
741// codecvt_base
742
743class _LIBCPP_VISIBLE codecvt_base
744{
745public:
746    _LIBCPP_ALWAYS_INLINE codecvt_base() {}
747    enum result {ok, partial, error, noconv};
748};
749
750// template <class internT, class externT, class stateT> class codecvt;
751
752template <class _InternT, class _ExternT, class _StateT> class _LIBCPP_VISIBLE codecvt;
753
754// template <> class codecvt<char, char, mbstate_t>
755
756template <>
757class _LIBCPP_VISIBLE codecvt<char, char, mbstate_t>
758    : public locale::facet,
759      public codecvt_base
760{
761public:
762    typedef char      intern_type;
763    typedef char      extern_type;
764    typedef mbstate_t state_type;
765
766    _LIBCPP_ALWAYS_INLINE
767    explicit codecvt(size_t __refs = 0)
768        : locale::facet(__refs) {}
769
770    _LIBCPP_ALWAYS_INLINE
771    result out(state_type& __st,
772               const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
773               extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
774    {
775        return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
776    }
777
778    _LIBCPP_ALWAYS_INLINE
779    result unshift(state_type& __st,
780                   extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
781    {
782        return do_unshift(__st, __to, __to_end, __to_nxt);
783    }
784
785    _LIBCPP_ALWAYS_INLINE
786    result in(state_type& __st,
787              const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
788              intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
789    {
790        return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
791    }
792
793    _LIBCPP_ALWAYS_INLINE
794    int encoding() const  _NOEXCEPT
795    {
796        return do_encoding();
797    }
798
799    _LIBCPP_ALWAYS_INLINE
800    bool always_noconv() const  _NOEXCEPT
801    {
802        return do_always_noconv();
803    }
804
805    _LIBCPP_ALWAYS_INLINE
806    int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
807    {
808        return do_length(__st, __frm, __end, __mx);
809    }
810
811    _LIBCPP_ALWAYS_INLINE
812    int max_length() const  _NOEXCEPT
813    {
814        return do_max_length();
815    }
816
817    static locale::id id;
818
819protected:
820    _LIBCPP_ALWAYS_INLINE
821    explicit codecvt(const char*, size_t __refs = 0)
822        : locale::facet(__refs) {}
823
824    ~codecvt();
825
826    virtual result do_out(state_type& __st,
827                          const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
828                          extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
829    virtual result do_in(state_type& __st,
830                         const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
831                         intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
832    virtual result do_unshift(state_type& __st,
833                              extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
834    virtual int do_encoding() const  _NOEXCEPT;
835    virtual bool do_always_noconv() const  _NOEXCEPT;
836    virtual int do_length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const;
837    virtual int do_max_length() const  _NOEXCEPT;
838};
839
840// template <> class codecvt<wchar_t, char, mbstate_t>
841
842template <>
843class _LIBCPP_VISIBLE codecvt<wchar_t, char, mbstate_t>
844    : public locale::facet,
845      public codecvt_base
846{
847    locale_t __l;
848public:
849    typedef wchar_t   intern_type;
850    typedef char      extern_type;
851    typedef mbstate_t state_type;
852
853    explicit codecvt(size_t __refs = 0);
854
855    _LIBCPP_ALWAYS_INLINE
856    result out(state_type& __st,
857               const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
858               extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
859    {
860        return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
861    }
862
863    _LIBCPP_ALWAYS_INLINE
864    result unshift(state_type& __st,
865                   extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
866    {
867        return do_unshift(__st, __to, __to_end, __to_nxt);
868    }
869
870    _LIBCPP_ALWAYS_INLINE
871    result in(state_type& __st,
872              const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
873              intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
874    {
875        return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
876    }
877
878    _LIBCPP_ALWAYS_INLINE
879    int encoding() const  _NOEXCEPT
880    {
881        return do_encoding();
882    }
883
884    _LIBCPP_ALWAYS_INLINE
885    bool always_noconv() const  _NOEXCEPT
886    {
887        return do_always_noconv();
888    }
889
890    _LIBCPP_ALWAYS_INLINE
891    int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
892    {
893        return do_length(__st, __frm, __end, __mx);
894    }
895
896    _LIBCPP_ALWAYS_INLINE
897    int max_length() const  _NOEXCEPT
898    {
899        return do_max_length();
900    }
901
902    static locale::id id;
903
904protected:
905    explicit codecvt(const char*, size_t __refs = 0);
906
907    ~codecvt();
908
909    virtual result do_out(state_type& __st,
910                          const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
911                          extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
912    virtual result do_in(state_type& __st,
913                         const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
914                         intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
915    virtual result do_unshift(state_type& __st,
916                              extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
917    virtual int do_encoding() const  _NOEXCEPT;
918    virtual bool do_always_noconv() const  _NOEXCEPT;
919    virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const;
920    virtual int do_max_length() const  _NOEXCEPT;
921};
922
923// template <> class codecvt<char16_t, char, mbstate_t>
924
925template <>
926class _LIBCPP_VISIBLE codecvt<char16_t, char, mbstate_t>
927    : public locale::facet,
928      public codecvt_base
929{
930public:
931    typedef char16_t  intern_type;
932    typedef char      extern_type;
933    typedef mbstate_t state_type;
934
935    _LIBCPP_ALWAYS_INLINE
936    explicit codecvt(size_t __refs = 0)
937        : locale::facet(__refs) {}
938
939    _LIBCPP_ALWAYS_INLINE
940    result out(state_type& __st,
941               const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
942               extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
943    {
944        return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
945    }
946
947    _LIBCPP_ALWAYS_INLINE
948    result unshift(state_type& __st,
949                   extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
950    {
951        return do_unshift(__st, __to, __to_end, __to_nxt);
952    }
953
954    _LIBCPP_ALWAYS_INLINE
955    result in(state_type& __st,
956              const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
957              intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
958    {
959        return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
960    }
961
962    _LIBCPP_ALWAYS_INLINE
963    int encoding() const  _NOEXCEPT
964    {
965        return do_encoding();
966    }
967
968    _LIBCPP_ALWAYS_INLINE
969    bool always_noconv() const  _NOEXCEPT
970    {
971        return do_always_noconv();
972    }
973
974    _LIBCPP_ALWAYS_INLINE
975    int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
976    {
977        return do_length(__st, __frm, __end, __mx);
978    }
979
980    _LIBCPP_ALWAYS_INLINE
981    int max_length() const  _NOEXCEPT
982    {
983        return do_max_length();
984    }
985
986    static locale::id id;
987
988protected:
989    _LIBCPP_ALWAYS_INLINE
990    explicit codecvt(const char*, size_t __refs = 0)
991        : locale::facet(__refs) {}
992
993    ~codecvt();
994
995    virtual result do_out(state_type& __st,
996                          const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
997                          extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
998    virtual result do_in(state_type& __st,
999                         const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
1000                         intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
1001    virtual result do_unshift(state_type& __st,
1002                              extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
1003    virtual int do_encoding() const  _NOEXCEPT;
1004    virtual bool do_always_noconv() const  _NOEXCEPT;
1005    virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const;
1006    virtual int do_max_length() const  _NOEXCEPT;
1007};
1008
1009// template <> class codecvt<char32_t, char, mbstate_t>
1010
1011template <>
1012class _LIBCPP_VISIBLE codecvt<char32_t, char, mbstate_t>
1013    : public locale::facet,
1014      public codecvt_base
1015{
1016public:
1017    typedef char32_t  intern_type;
1018    typedef char      extern_type;
1019    typedef mbstate_t state_type;
1020
1021    _LIBCPP_ALWAYS_INLINE
1022    explicit codecvt(size_t __refs = 0)
1023        : locale::facet(__refs) {}
1024
1025    _LIBCPP_ALWAYS_INLINE
1026    result out(state_type& __st,
1027               const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
1028               extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
1029    {
1030        return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
1031    }
1032
1033    _LIBCPP_ALWAYS_INLINE
1034    result unshift(state_type& __st,
1035                   extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
1036    {
1037        return do_unshift(__st, __to, __to_end, __to_nxt);
1038    }
1039
1040    _LIBCPP_ALWAYS_INLINE
1041    result in(state_type& __st,
1042              const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
1043              intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
1044    {
1045        return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
1046    }
1047
1048    _LIBCPP_ALWAYS_INLINE
1049    int encoding() const  _NOEXCEPT
1050    {
1051        return do_encoding();
1052    }
1053
1054    _LIBCPP_ALWAYS_INLINE
1055    bool always_noconv() const  _NOEXCEPT
1056    {
1057        return do_always_noconv();
1058    }
1059
1060    _LIBCPP_ALWAYS_INLINE
1061    int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
1062    {
1063        return do_length(__st, __frm, __end, __mx);
1064    }
1065
1066    _LIBCPP_ALWAYS_INLINE
1067    int max_length() const  _NOEXCEPT
1068    {
1069        return do_max_length();
1070    }
1071
1072    static locale::id id;
1073
1074protected:
1075    _LIBCPP_ALWAYS_INLINE
1076    explicit codecvt(const char*, size_t __refs = 0)
1077        : locale::facet(__refs) {}
1078
1079    ~codecvt();
1080
1081    virtual result do_out(state_type& __st,
1082                          const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
1083                          extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
1084    virtual result do_in(state_type& __st,
1085                         const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
1086                         intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
1087    virtual result do_unshift(state_type& __st,
1088                              extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
1089    virtual int do_encoding() const  _NOEXCEPT;
1090    virtual bool do_always_noconv() const  _NOEXCEPT;
1091    virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const;
1092    virtual int do_max_length() const  _NOEXCEPT;
1093};
1094
1095// template <class _InternT, class _ExternT, class _StateT> class codecvt_byname
1096
1097template <class _InternT, class _ExternT, class _StateT>
1098class _LIBCPP_VISIBLE codecvt_byname
1099    : public codecvt<_InternT, _ExternT, _StateT>
1100{
1101public:
1102    _LIBCPP_ALWAYS_INLINE
1103    explicit codecvt_byname(const char* __nm, size_t __refs = 0)
1104        : codecvt<_InternT, _ExternT, _StateT>(__nm, __refs) {}
1105    _LIBCPP_ALWAYS_INLINE
1106    explicit codecvt_byname(const string& __nm, size_t __refs = 0)
1107        : codecvt<_InternT, _ExternT, _StateT>(__nm.c_str(), __refs) {}
1108protected:
1109    ~codecvt_byname();
1110};
1111
1112template <class _InternT, class _ExternT, class _StateT>
1113codecvt_byname<_InternT, _ExternT, _StateT>::~codecvt_byname()
1114{
1115}
1116
1117extern template class codecvt_byname<char, char, mbstate_t>;
1118extern template class codecvt_byname<wchar_t, char, mbstate_t>;
1119extern template class codecvt_byname<char16_t, char, mbstate_t>;
1120extern template class codecvt_byname<char32_t, char, mbstate_t>;
1121
1122_LIBCPP_VISIBLE void __throw_runtime_error(const char*);
1123
1124template <size_t _N>
1125struct __narrow_to_utf8
1126{
1127    template <class _OutputIterator, class _CharT>
1128    _OutputIterator
1129    operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const;
1130};
1131
1132template <>
1133struct __narrow_to_utf8<8>
1134{
1135    template <class _OutputIterator, class _CharT>
1136    _LIBCPP_ALWAYS_INLINE
1137    _OutputIterator
1138    operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const
1139    {
1140        for (; __wb < __we; ++__wb, ++__s)
1141            *__s = *__wb;
1142        return __s;
1143    }
1144};
1145
1146template <>
1147struct __narrow_to_utf8<16>
1148    : public codecvt<char16_t, char, mbstate_t>
1149{
1150    _LIBCPP_ALWAYS_INLINE
1151    __narrow_to_utf8() : codecvt<char16_t, char, mbstate_t>(1) {}
1152
1153    ~__narrow_to_utf8();
1154
1155    template <class _OutputIterator, class _CharT>
1156    _LIBCPP_ALWAYS_INLINE
1157    _OutputIterator
1158    operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const
1159    {
1160        result __r = ok;
1161        mbstate_t __mb;
1162        while (__wb < __we && __r != error)
1163        {
1164            const int __sz = 32;
1165            char __buf[__sz];
1166            char* __bn;
1167            const char16_t* __wn = (const char16_t*)__wb;
1168            __r = do_out(__mb, (const char16_t*)__wb, (const char16_t*)__we, __wn,
1169                         __buf, __buf+__sz, __bn);
1170            if (__r == codecvt_base::error || __wn == (const char16_t*)__wb)
1171                __throw_runtime_error("locale not supported");
1172            for (const char* __p = __buf; __p < __bn; ++__p, ++__s)
1173                *__s = *__p;
1174            __wb = (const _CharT*)__wn;
1175        }
1176        return __s;
1177    }
1178};
1179
1180template <>
1181struct __narrow_to_utf8<32>
1182    : public codecvt<char32_t, char, mbstate_t>
1183{
1184    _LIBCPP_ALWAYS_INLINE
1185    __narrow_to_utf8() : codecvt<char32_t, char, mbstate_t>(1) {}
1186
1187    ~__narrow_to_utf8();
1188
1189    template <class _OutputIterator, class _CharT>
1190    _LIBCPP_ALWAYS_INLINE
1191    _OutputIterator
1192    operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const
1193    {
1194        result __r = ok;
1195        mbstate_t __mb;
1196        while (__wb < __we && __r != error)
1197        {
1198            const int __sz = 32;
1199            char __buf[__sz];
1200            char* __bn;
1201            const char32_t* __wn = (const char32_t*)__wb;
1202            __r = do_out(__mb, (const char32_t*)__wb, (const char32_t*)__we, __wn,
1203                         __buf, __buf+__sz, __bn);
1204            if (__r == codecvt_base::error || __wn == (const char32_t*)__wb)
1205                __throw_runtime_error("locale not supported");
1206            for (const char* __p = __buf; __p < __bn; ++__p, ++__s)
1207                *__s = *__p;
1208            __wb = (const _CharT*)__wn;
1209        }
1210        return __s;
1211    }
1212};
1213
1214template <size_t _N>
1215struct __widen_from_utf8
1216{
1217    template <class _OutputIterator>
1218    _OutputIterator
1219    operator()(_OutputIterator __s, const char* __nb, const char* __ne) const;
1220};
1221
1222template <>
1223struct __widen_from_utf8<8>
1224{
1225    template <class _OutputIterator>
1226    _LIBCPP_ALWAYS_INLINE
1227    _OutputIterator
1228    operator()(_OutputIterator __s, const char* __nb, const char* __ne) const
1229    {
1230        for (; __nb < __ne; ++__nb, ++__s)
1231            *__s = *__nb;
1232        return __s;
1233    }
1234};
1235
1236template <>
1237struct __widen_from_utf8<16>
1238    : public codecvt<char16_t, char, mbstate_t>
1239{
1240    _LIBCPP_ALWAYS_INLINE
1241    __widen_from_utf8() : codecvt<char16_t, char, mbstate_t>(1) {}
1242
1243    ~__widen_from_utf8();
1244
1245    template <class _OutputIterator>
1246    _LIBCPP_ALWAYS_INLINE
1247    _OutputIterator
1248    operator()(_OutputIterator __s, const char* __nb, const char* __ne) const
1249    {
1250        result __r = ok;
1251        mbstate_t __mb;
1252        while (__nb < __ne && __r != error)
1253        {
1254            const int __sz = 32;
1255            char16_t __buf[__sz];
1256            char16_t* __bn;
1257            const char* __nn = __nb;
1258            __r = do_in(__mb, __nb, __ne - __nb > __sz ? __nb+__sz : __ne, __nn,
1259                        __buf, __buf+__sz, __bn);
1260            if (__r == codecvt_base::error || __nn == __nb)
1261                __throw_runtime_error("locale not supported");
1262            for (const char16_t* __p = __buf; __p < __bn; ++__p, ++__s)
1263                *__s = (wchar_t)*__p;
1264            __nb = __nn;
1265        }
1266        return __s;
1267    }
1268};
1269
1270template <>
1271struct __widen_from_utf8<32>
1272    : public codecvt<char32_t, char, mbstate_t>
1273{
1274    _LIBCPP_ALWAYS_INLINE
1275    __widen_from_utf8() : codecvt<char32_t, char, mbstate_t>(1) {}
1276
1277    ~__widen_from_utf8();
1278
1279    template <class _OutputIterator>
1280    _LIBCPP_ALWAYS_INLINE
1281    _OutputIterator
1282    operator()(_OutputIterator __s, const char* __nb, const char* __ne) const
1283    {
1284        result __r = ok;
1285        mbstate_t __mb;
1286        while (__nb < __ne && __r != error)
1287        {
1288            const int __sz = 32;
1289            char32_t __buf[__sz];
1290            char32_t* __bn;
1291            const char* __nn = __nb;
1292            __r = do_in(__mb, __nb, __ne - __nb > __sz ? __nb+__sz : __ne, __nn,
1293                        __buf, __buf+__sz, __bn);
1294            if (__r == codecvt_base::error || __nn == __nb)
1295                __throw_runtime_error("locale not supported");
1296            for (const char32_t* __p = __buf; __p < __bn; ++__p, ++__s)
1297                *__s = (wchar_t)*__p;
1298            __nb = __nn;
1299        }
1300        return __s;
1301    }
1302};
1303
1304// template <class charT> class numpunct
1305
1306template <class _CharT> class _LIBCPP_VISIBLE numpunct;
1307
1308template <>
1309class _LIBCPP_VISIBLE numpunct<char>
1310    : public locale::facet
1311{
1312public:
1313    typedef char char_type;
1314    typedef basic_string<char_type> string_type;
1315
1316    explicit numpunct(size_t __refs = 0);
1317
1318    _LIBCPP_ALWAYS_INLINE char_type decimal_point() const {return do_decimal_point();}
1319    _LIBCPP_ALWAYS_INLINE char_type thousands_sep() const {return do_thousands_sep();}
1320    _LIBCPP_ALWAYS_INLINE string grouping() const         {return do_grouping();}
1321    _LIBCPP_ALWAYS_INLINE string_type truename() const    {return do_truename();}
1322    _LIBCPP_ALWAYS_INLINE string_type falsename() const   {return do_falsename();}
1323
1324    static locale::id id;
1325
1326protected:
1327    ~numpunct();
1328    virtual char_type do_decimal_point() const;
1329    virtual char_type do_thousands_sep() const;
1330    virtual string do_grouping() const;
1331    virtual string_type do_truename() const;
1332    virtual string_type do_falsename() const;
1333
1334    char_type __decimal_point_;
1335    char_type __thousands_sep_;
1336    string __grouping_;
1337};
1338
1339template <>
1340class _LIBCPP_VISIBLE numpunct<wchar_t>
1341    : public locale::facet
1342{
1343public:
1344    typedef wchar_t char_type;
1345    typedef basic_string<char_type> string_type;
1346
1347    explicit numpunct(size_t __refs = 0);
1348
1349    _LIBCPP_ALWAYS_INLINE char_type decimal_point() const {return do_decimal_point();}
1350    _LIBCPP_ALWAYS_INLINE char_type thousands_sep() const {return do_thousands_sep();}
1351    _LIBCPP_ALWAYS_INLINE string grouping() const         {return do_grouping();}
1352    _LIBCPP_ALWAYS_INLINE string_type truename() const    {return do_truename();}
1353    _LIBCPP_ALWAYS_INLINE string_type falsename() const   {return do_falsename();}
1354
1355    static locale::id id;
1356
1357protected:
1358    ~numpunct();
1359    virtual char_type do_decimal_point() const;
1360    virtual char_type do_thousands_sep() const;
1361    virtual string do_grouping() const;
1362    virtual string_type do_truename() const;
1363    virtual string_type do_falsename() const;
1364
1365    char_type __decimal_point_;
1366    char_type __thousands_sep_;
1367    string __grouping_;
1368};
1369
1370// template <class charT> class numpunct_byname
1371
1372template <class charT> class _LIBCPP_VISIBLE numpunct_byname;
1373
1374template <>
1375class _LIBCPP_VISIBLE numpunct_byname<char>
1376: public numpunct<char>
1377{
1378public:
1379    typedef char char_type;
1380    typedef basic_string<char_type> string_type;
1381
1382    explicit numpunct_byname(const char* __nm, size_t __refs = 0);
1383    explicit numpunct_byname(const string& __nm, size_t __refs = 0);
1384
1385protected:
1386    ~numpunct_byname();
1387
1388private:
1389    void __init(const char*);
1390};
1391
1392template <>
1393class _LIBCPP_VISIBLE numpunct_byname<wchar_t>
1394: public numpunct<wchar_t>
1395{
1396public:
1397    typedef wchar_t char_type;
1398    typedef basic_string<char_type> string_type;
1399
1400    explicit numpunct_byname(const char* __nm, size_t __refs = 0);
1401    explicit numpunct_byname(const string& __nm, size_t __refs = 0);
1402
1403protected:
1404    ~numpunct_byname();
1405
1406private:
1407    void __init(const char*);
1408};
1409
1410_LIBCPP_END_NAMESPACE_STD
1411
1412#endif  // _LIBCPP___LOCALE
1413