llvm-project

Форк
0
/
locale.cpp 
5717 строк · 187.7 Кб
1
//===----------------------------------------------------------------------===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8

9
#include <__utility/no_destroy.h>
10
#include <algorithm>
11
#include <clocale>
12
#include <codecvt>
13
#include <cstddef>
14
#include <cstdio>
15
#include <cstdlib>
16
#include <cstring>
17
#include <locale>
18
#include <new>
19
#include <string>
20
#include <type_traits>
21
#include <typeinfo>
22
#include <utility>
23
#include <vector>
24

25
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
26
#  include <cwctype>
27
#endif
28

29
#if defined(_AIX)
30
#  include <sys/localedef.h> // for __lc_ctype_ptr
31
#endif
32

33
#if defined(_LIBCPP_MSVCRT)
34
#  define _CTYPE_DISABLE_MACROS
35
#endif
36

37
#if !defined(_LIBCPP_MSVCRT) && !defined(__MINGW32__) && !defined(__BIONIC__) && !defined(__NuttX__)
38
#  include <langinfo.h>
39
#endif
40

41
#include "include/atomic_support.h"
42
#include "include/sso_allocator.h"
43

44
// On Linux, wint_t and wchar_t have different signed-ness, and this causes
45
// lots of noise in the build log, but no bugs that I know of.
46
_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wsign-conversion")
47

48
_LIBCPP_PUSH_MACROS
49
#include <__undef_macros>
50

51
_LIBCPP_BEGIN_NAMESPACE_STD
52

53
struct __libcpp_unique_locale {
54
  __libcpp_unique_locale(const char* nm) : __loc_(newlocale(LC_ALL_MASK, nm, 0)) {}
55

56
  ~__libcpp_unique_locale() {
57
    if (__loc_)
58
      freelocale(__loc_);
59
  }
60

61
  explicit operator bool() const { return __loc_; }
62

63
  locale_t& get() { return __loc_; }
64

65
  locale_t __loc_;
66

67
private:
68
  __libcpp_unique_locale(__libcpp_unique_locale const&);
69
  __libcpp_unique_locale& operator=(__libcpp_unique_locale const&);
70
};
71

72
#ifdef __cloc_defined
73
locale_t __cloc() {
74
  // In theory this could create a race condition. In practice
75
  // the race condition is non-fatal since it will just create
76
  // a little resource leak. Better approach would be appreciated.
77
  static locale_t result = newlocale(LC_ALL_MASK, "C", 0);
78
  return result;
79
}
80
#endif // __cloc_defined
81

82
namespace {
83

84
struct releaser {
85
  void operator()(locale::facet* p) { p->__release_shared(); }
86
};
87

88
template <class T, class... Args>
89
T& make(Args... args) {
90
  alignas(T) static std::byte buf[sizeof(T)];
91
  auto* obj = ::new (&buf) T(args...);
92
  return *obj;
93
}
94

95
template <typename T, size_t N>
96
inline constexpr size_t countof(const T (&)[N]) {
97
  return N;
98
}
99

100
template <typename T>
101
inline constexpr size_t countof(const T* const begin, const T* const end) {
102
  return static_cast<size_t>(end - begin);
103
}
104

105
string build_name(const string& other, const string& one, locale::category c) {
106
  if (other == "*" || one == "*")
107
    return "*";
108
  if (c == locale::none || other == one)
109
    return other;
110

111
  // FIXME: Handle the more complicated cases, such as when the locale has
112
  // different names for different categories.
113
  return "*";
114
}
115

116
} // namespace
117

118
const locale::category locale::none;
119
const locale::category locale::collate;
120
const locale::category locale::ctype;
121
const locale::category locale::monetary;
122
const locale::category locale::numeric;
123
const locale::category locale::time;
124
const locale::category locale::messages;
125
const locale::category locale::all;
126

127
class _LIBCPP_HIDDEN locale::__imp : public facet {
128
  enum { N = 30 };
129
  vector<facet*, __sso_allocator<facet*, N> > facets_;
130
  string name_;
131

132
public:
133
  explicit __imp(size_t refs = 0);
134
  explicit __imp(const string& name, size_t refs = 0);
135
  __imp(const __imp&);
136
  __imp(const __imp&, const string&, locale::category c);
137
  __imp(const __imp& other, const __imp& one, locale::category c);
138
  __imp(const __imp&, facet* f, long id);
139
  ~__imp();
140

141
  const string& name() const { return name_; }
142
  bool has_facet(long id) const { return static_cast<size_t>(id) < facets_.size() && facets_[static_cast<size_t>(id)]; }
143
  const locale::facet* use_facet(long id) const;
144

145
  void acquire();
146
  void release();
147
  static __no_destroy<__imp> classic_locale_imp_;
148

149
private:
150
  void install(facet* f, long id);
151
  template <class F>
152
  void install(F* f) {
153
    install(f, f->id.__get());
154
  }
155
  template <class F>
156
  void install_from(const __imp& other);
157
};
158

159
locale::__imp::__imp(size_t refs) : facet(refs), facets_(N), name_("C") {
160
  facets_.clear();
161
  install(&make<std::collate<char> >(1u));
162
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
163
  install(&make<std::collate<wchar_t> >(1u));
164
#endif
165
  install(&make<std::ctype<char> >(nullptr, false, 1u));
166
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
167
  install(&make<std::ctype<wchar_t> >(1u));
168
#endif
169
  install(&make<codecvt<char, char, mbstate_t> >(1u));
170
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
171
  install(&make<codecvt<wchar_t, char, mbstate_t> >(1u));
172
#endif
173
  _LIBCPP_SUPPRESS_DEPRECATED_PUSH
174
  install(&make<codecvt<char16_t, char, mbstate_t> >(1u));
175
  install(&make<codecvt<char32_t, char, mbstate_t> >(1u));
176
  _LIBCPP_SUPPRESS_DEPRECATED_POP
177
#ifndef _LIBCPP_HAS_NO_CHAR8_T
178
  install(&make<codecvt<char16_t, char8_t, mbstate_t> >(1u));
179
  install(&make<codecvt<char32_t, char8_t, mbstate_t> >(1u));
180
#endif
181
  install(&make<numpunct<char> >(1u));
182
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
183
  install(&make<numpunct<wchar_t> >(1u));
184
#endif
185
  install(&make<num_get<char> >(1u));
186
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
187
  install(&make<num_get<wchar_t> >(1u));
188
#endif
189
  install(&make<num_put<char> >(1u));
190
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
191
  install(&make<num_put<wchar_t> >(1u));
192
#endif
193
  install(&make<moneypunct<char, false> >(1u));
194
  install(&make<moneypunct<char, true> >(1u));
195
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
196
  install(&make<moneypunct<wchar_t, false> >(1u));
197
  install(&make<moneypunct<wchar_t, true> >(1u));
198
#endif
199
  install(&make<money_get<char> >(1u));
200
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
201
  install(&make<money_get<wchar_t> >(1u));
202
#endif
203
  install(&make<money_put<char> >(1u));
204
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
205
  install(&make<money_put<wchar_t> >(1u));
206
#endif
207
  install(&make<time_get<char> >(1u));
208
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
209
  install(&make<time_get<wchar_t> >(1u));
210
#endif
211
  install(&make<time_put<char> >(1u));
212
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
213
  install(&make<time_put<wchar_t> >(1u));
214
#endif
215
  install(&make<std::messages<char> >(1u));
216
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
217
  install(&make<std::messages<wchar_t> >(1u));
218
#endif
219
}
220

221
locale::__imp::__imp(const string& name, size_t refs) : facet(refs), facets_(N), name_(name) {
222
#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
223
  try {
224
#endif // _LIBCPP_HAS_NO_EXCEPTIONS
225
    facets_ = locale::classic().__locale_->facets_;
226
    for (unsigned i = 0; i < facets_.size(); ++i)
227
      if (facets_[i])
228
        facets_[i]->__add_shared();
229
    install(new collate_byname<char>(name_));
230
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
231
    install(new collate_byname<wchar_t>(name_));
232
#endif
233
    install(new ctype_byname<char>(name_));
234
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
235
    install(new ctype_byname<wchar_t>(name_));
236
#endif
237
    install(new codecvt_byname<char, char, mbstate_t>(name_));
238
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
239
    install(new codecvt_byname<wchar_t, char, mbstate_t>(name_));
240
#endif
241
    _LIBCPP_SUPPRESS_DEPRECATED_PUSH
242
    install(new codecvt_byname<char16_t, char, mbstate_t>(name_));
243
    install(new codecvt_byname<char32_t, char, mbstate_t>(name_));
244
    _LIBCPP_SUPPRESS_DEPRECATED_POP
245
#ifndef _LIBCPP_HAS_NO_CHAR8_T
246
    install(new codecvt_byname<char16_t, char8_t, mbstate_t>(name_));
247
    install(new codecvt_byname<char32_t, char8_t, mbstate_t>(name_));
248
#endif
249
    install(new numpunct_byname<char>(name_));
250
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
251
    install(new numpunct_byname<wchar_t>(name_));
252
#endif
253
    install(new moneypunct_byname<char, false>(name_));
254
    install(new moneypunct_byname<char, true>(name_));
255
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
256
    install(new moneypunct_byname<wchar_t, false>(name_));
257
    install(new moneypunct_byname<wchar_t, true>(name_));
258
#endif
259
    install(new time_get_byname<char>(name_));
260
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
261
    install(new time_get_byname<wchar_t>(name_));
262
#endif
263
    install(new time_put_byname<char>(name_));
264
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
265
    install(new time_put_byname<wchar_t>(name_));
266
#endif
267
    install(new messages_byname<char>(name_));
268
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
269
    install(new messages_byname<wchar_t>(name_));
270
#endif
271
#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
272
  } catch (...) {
273
    for (unsigned i = 0; i < facets_.size(); ++i)
274
      if (facets_[i])
275
        facets_[i]->__release_shared();
276
    throw;
277
  }
278
#endif // _LIBCPP_HAS_NO_EXCEPTIONS
279
}
280

281
locale::__imp::__imp(const __imp& other) : facets_(max<size_t>(N, other.facets_.size())), name_(other.name_) {
282
  facets_ = other.facets_;
283
  for (unsigned i = 0; i < facets_.size(); ++i)
284
    if (facets_[i])
285
      facets_[i]->__add_shared();
286
}
287

288
locale::__imp::__imp(const __imp& other, const string& name, locale::category c)
289
    : facets_(N), name_(build_name(other.name_, name, c)) {
290
  facets_ = other.facets_;
291
  for (unsigned i = 0; i < facets_.size(); ++i)
292
    if (facets_[i])
293
      facets_[i]->__add_shared();
294
#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
295
  try {
296
#endif // _LIBCPP_HAS_NO_EXCEPTIONS
297
    if (c & locale::collate) {
298
      install(new collate_byname<char>(name));
299
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
300
      install(new collate_byname<wchar_t>(name));
301
#endif
302
    }
303
    if (c & locale::ctype) {
304
      install(new ctype_byname<char>(name));
305
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
306
      install(new ctype_byname<wchar_t>(name));
307
#endif
308
      install(new codecvt_byname<char, char, mbstate_t>(name));
309
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
310
      install(new codecvt_byname<wchar_t, char, mbstate_t>(name));
311
#endif
312
      _LIBCPP_SUPPRESS_DEPRECATED_PUSH
313
      install(new codecvt_byname<char16_t, char, mbstate_t>(name));
314
      install(new codecvt_byname<char32_t, char, mbstate_t>(name));
315
      _LIBCPP_SUPPRESS_DEPRECATED_POP
316
#ifndef _LIBCPP_HAS_NO_CHAR8_T
317
      install(new codecvt_byname<char16_t, char8_t, mbstate_t>(name));
318
      install(new codecvt_byname<char32_t, char8_t, mbstate_t>(name));
319
#endif
320
    }
321
    if (c & locale::monetary) {
322
      install(new moneypunct_byname<char, false>(name));
323
      install(new moneypunct_byname<char, true>(name));
324
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
325
      install(new moneypunct_byname<wchar_t, false>(name));
326
      install(new moneypunct_byname<wchar_t, true>(name));
327
#endif
328
    }
329
    if (c & locale::numeric) {
330
      install(new numpunct_byname<char>(name));
331
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
332
      install(new numpunct_byname<wchar_t>(name));
333
#endif
334
    }
335
    if (c & locale::time) {
336
      install(new time_get_byname<char>(name));
337
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
338
      install(new time_get_byname<wchar_t>(name));
339
#endif
340
      install(new time_put_byname<char>(name));
341
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
342
      install(new time_put_byname<wchar_t>(name));
343
#endif
344
    }
345
    if (c & locale::messages) {
346
      install(new messages_byname<char>(name));
347
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
348
      install(new messages_byname<wchar_t>(name));
349
#endif
350
    }
351
#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
352
  } catch (...) {
353
    for (unsigned i = 0; i < facets_.size(); ++i)
354
      if (facets_[i])
355
        facets_[i]->__release_shared();
356
    throw;
357
  }
358
#endif // _LIBCPP_HAS_NO_EXCEPTIONS
359
}
360

361
template <class F>
362
inline void locale::__imp::install_from(const locale::__imp& one) {
363
  long id = F::id.__get();
364
  install(const_cast<F*>(static_cast<const F*>(one.use_facet(id))), id);
365
}
366

367
locale::__imp::__imp(const __imp& other, const __imp& one, locale::category c)
368
    : facets_(N), name_(build_name(other.name_, one.name_, c)) {
369
  facets_ = other.facets_;
370
  for (unsigned i = 0; i < facets_.size(); ++i)
371
    if (facets_[i])
372
      facets_[i]->__add_shared();
373
#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
374
  try {
375
#endif // _LIBCPP_HAS_NO_EXCEPTIONS
376
    if (c & locale::collate) {
377
      install_from<std::collate<char> >(one);
378
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
379
      install_from<std::collate<wchar_t> >(one);
380
#endif
381
    }
382
    if (c & locale::ctype) {
383
      install_from<std::ctype<char> >(one);
384
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
385
      install_from<std::ctype<wchar_t> >(one);
386
#endif
387
      install_from<std::codecvt<char, char, mbstate_t> >(one);
388
      _LIBCPP_SUPPRESS_DEPRECATED_PUSH
389
      install_from<std::codecvt<char16_t, char, mbstate_t> >(one);
390
      install_from<std::codecvt<char32_t, char, mbstate_t> >(one);
391
      _LIBCPP_SUPPRESS_DEPRECATED_POP
392
#ifndef _LIBCPP_HAS_NO_CHAR8_T
393
      install_from<std::codecvt<char16_t, char8_t, mbstate_t> >(one);
394
      install_from<std::codecvt<char32_t, char8_t, mbstate_t> >(one);
395
#endif
396
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
397
      install_from<std::codecvt<wchar_t, char, mbstate_t> >(one);
398
#endif
399
    }
400
    if (c & locale::monetary) {
401
      install_from<moneypunct<char, false> >(one);
402
      install_from<moneypunct<char, true> >(one);
403
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
404
      install_from<moneypunct<wchar_t, false> >(one);
405
      install_from<moneypunct<wchar_t, true> >(one);
406
#endif
407
      install_from<money_get<char> >(one);
408
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
409
      install_from<money_get<wchar_t> >(one);
410
#endif
411
      install_from<money_put<char> >(one);
412
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
413
      install_from<money_put<wchar_t> >(one);
414
#endif
415
    }
416
    if (c & locale::numeric) {
417
      install_from<numpunct<char> >(one);
418
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
419
      install_from<numpunct<wchar_t> >(one);
420
#endif
421
      install_from<num_get<char> >(one);
422
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
423
      install_from<num_get<wchar_t> >(one);
424
#endif
425
      install_from<num_put<char> >(one);
426
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
427
      install_from<num_put<wchar_t> >(one);
428
#endif
429
    }
430
    if (c & locale::time) {
431
      install_from<time_get<char> >(one);
432
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
433
      install_from<time_get<wchar_t> >(one);
434
#endif
435
      install_from<time_put<char> >(one);
436
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
437
      install_from<time_put<wchar_t> >(one);
438
#endif
439
    }
440
    if (c & locale::messages) {
441
      install_from<std::messages<char> >(one);
442
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
443
      install_from<std::messages<wchar_t> >(one);
444
#endif
445
    }
446
#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
447
  } catch (...) {
448
    for (unsigned i = 0; i < facets_.size(); ++i)
449
      if (facets_[i])
450
        facets_[i]->__release_shared();
451
    throw;
452
  }
453
#endif // _LIBCPP_HAS_NO_EXCEPTIONS
454
}
455

456
locale::__imp::__imp(const __imp& other, facet* f, long id)
457
    : facets_(max<size_t>(N, other.facets_.size() + 1)), name_("*") {
458
  f->__add_shared();
459
  unique_ptr<facet, releaser> hold(f);
460
  facets_ = other.facets_;
461
  for (unsigned i = 0; i < other.facets_.size(); ++i)
462
    if (facets_[i])
463
      facets_[i]->__add_shared();
464
  install(hold.get(), id);
465
}
466

467
locale::__imp::~__imp() {
468
  for (unsigned i = 0; i < facets_.size(); ++i)
469
    if (facets_[i])
470
      facets_[i]->__release_shared();
471
}
472

473
void locale::__imp::install(facet* f, long id) {
474
  f->__add_shared();
475
  unique_ptr<facet, releaser> hold(f);
476
  if (static_cast<size_t>(id) >= facets_.size())
477
    facets_.resize(static_cast<size_t>(id + 1));
478
  if (facets_[static_cast<size_t>(id)])
479
    facets_[static_cast<size_t>(id)]->__release_shared();
480
  facets_[static_cast<size_t>(id)] = hold.release();
481
}
482

483
const locale::facet* locale::__imp::use_facet(long id) const {
484
  if (!has_facet(id))
485
    __throw_bad_cast();
486
  return facets_[static_cast<size_t>(id)];
487
}
488

489
// locale
490

491
// We don't do reference counting on the classic locale.
492
// It's never destroyed anyway, but atomic reference counting may be very
493
// expensive in parallel applications. The classic locale is used by default
494
// in all streams. Note: if a new global locale is installed, then we lose
495
// the benefit of no reference counting.
496
constinit __no_destroy<locale::__imp>
497
    locale::__imp::classic_locale_imp_(__uninitialized_tag{}); // initialized below in classic()
498

499
const locale& locale::classic() {
500
  static const __no_destroy<locale> classic_locale(__private_constructor_tag{}, [] {
501
    // executed exactly once on first initialization of `classic_locale`
502
    locale::__imp::classic_locale_imp_.__emplace(1u);
503
    return &locale::__imp::classic_locale_imp_.__get();
504
  }());
505
  return classic_locale.__get();
506
}
507

508
locale& locale::__global() {
509
  static __no_destroy<locale> g(locale::classic());
510
  return g.__get();
511
}
512

513
void locale::__imp::acquire() {
514
  if (this != &locale::__imp::classic_locale_imp_.__get())
515
    __add_shared();
516
}
517

518
void locale::__imp::release() {
519
  if (this != &locale::__imp::classic_locale_imp_.__get())
520
    __release_shared();
521
}
522

523
locale::locale() noexcept : __locale_(__global().__locale_) { __locale_->acquire(); }
524

525
locale::locale(const locale& l) noexcept : __locale_(l.__locale_) { __locale_->acquire(); }
526

527
locale::~locale() { __locale_->release(); }
528

529
const locale& locale::operator=(const locale& other) noexcept {
530
  other.__locale_->acquire();
531
  __locale_->release();
532
  __locale_ = other.__locale_;
533
  return *this;
534
}
535

536
locale::locale(const char* name)
537
    : __locale_(name ? new __imp(name) : (__throw_runtime_error("locale constructed with null"), nullptr)) {
538
  __locale_->acquire();
539
}
540

541
locale::locale(const string& name) : __locale_(new __imp(name)) { __locale_->acquire(); }
542

543
locale::locale(const locale& other, const char* name, category c)
544
    : __locale_(name ? new __imp(*other.__locale_, name, c)
545
                     : (__throw_runtime_error("locale constructed with null"), nullptr)) {
546
  __locale_->acquire();
547
}
548

549
locale::locale(const locale& other, const string& name, category c) : __locale_(new __imp(*other.__locale_, name, c)) {
550
  __locale_->acquire();
551
}
552

553
locale::locale(const locale& other, const locale& one, category c)
554
    : __locale_(new __imp(*other.__locale_, *one.__locale_, c)) {
555
  __locale_->acquire();
556
}
557

558
string locale::name() const { return __locale_->name(); }
559

560
void locale::__install_ctor(const locale& other, facet* f, long facet_id) {
561
  if (f)
562
    __locale_ = new __imp(*other.__locale_, f, facet_id);
563
  else
564
    __locale_ = other.__locale_;
565
  __locale_->acquire();
566
}
567

568
locale locale::global(const locale& loc) {
569
  locale& g = __global();
570
  locale r  = g;
571
  g         = loc;
572
  if (g.name() != "*")
573
    setlocale(LC_ALL, g.name().c_str());
574
  return r;
575
}
576

577
bool locale::has_facet(id& x) const { return __locale_->has_facet(x.__get()); }
578

579
const locale::facet* locale::use_facet(id& x) const { return __locale_->use_facet(x.__get()); }
580

581
bool locale::operator==(const locale& y) const {
582
  return (__locale_ == y.__locale_) || (__locale_->name() != "*" && __locale_->name() == y.__locale_->name());
583
}
584

585
// locale::facet
586

587
locale::facet::~facet() {}
588

589
void locale::facet::__on_zero_shared() noexcept { delete this; }
590

591
// locale::id
592

593
constinit int32_t locale::id::__next_id = 0;
594

595
long locale::id::__get() {
596
  call_once(__flag_, [&] { __id_ = __libcpp_atomic_add(&__next_id, 1); });
597
  return __id_ - 1;
598
}
599

600
// template <> class collate_byname<char>
601

602
collate_byname<char>::collate_byname(const char* n, size_t refs)
603
    : collate<char>(refs), __l_(newlocale(LC_ALL_MASK, n, 0)) {
604
  if (__l_ == 0)
605
    __throw_runtime_error(
606
        ("collate_byname<char>::collate_byname"
607
         " failed to construct for " +
608
         string(n))
609
            .c_str());
610
}
611

612
collate_byname<char>::collate_byname(const string& name, size_t refs)
613
    : collate<char>(refs), __l_(newlocale(LC_ALL_MASK, name.c_str(), 0)) {
614
  if (__l_ == 0)
615
    __throw_runtime_error(
616
        ("collate_byname<char>::collate_byname"
617
         " failed to construct for " +
618
         name)
619
            .c_str());
620
}
621

622
collate_byname<char>::~collate_byname() { freelocale(__l_); }
623

624
int collate_byname<char>::do_compare(
625
    const char_type* __lo1, const char_type* __hi1, const char_type* __lo2, const char_type* __hi2) const {
626
  string_type lhs(__lo1, __hi1);
627
  string_type rhs(__lo2, __hi2);
628
  int r = strcoll_l(lhs.c_str(), rhs.c_str(), __l_);
629
  if (r < 0)
630
    return -1;
631
  if (r > 0)
632
    return 1;
633
  return r;
634
}
635

636
collate_byname<char>::string_type collate_byname<char>::do_transform(const char_type* lo, const char_type* hi) const {
637
  const string_type in(lo, hi);
638
  string_type out(strxfrm_l(0, in.c_str(), 0, __l_), char());
639
  strxfrm_l(const_cast<char*>(out.c_str()), in.c_str(), out.size() + 1, __l_);
640
  return out;
641
}
642

643
// template <> class collate_byname<wchar_t>
644

645
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
646
collate_byname<wchar_t>::collate_byname(const char* n, size_t refs)
647
    : collate<wchar_t>(refs), __l_(newlocale(LC_ALL_MASK, n, 0)) {
648
  if (__l_ == 0)
649
    __throw_runtime_error(
650
        ("collate_byname<wchar_t>::collate_byname(size_t refs)"
651
         " failed to construct for " +
652
         string(n))
653
            .c_str());
654
}
655

656
collate_byname<wchar_t>::collate_byname(const string& name, size_t refs)
657
    : collate<wchar_t>(refs), __l_(newlocale(LC_ALL_MASK, name.c_str(), 0)) {
658
  if (__l_ == 0)
659
    __throw_runtime_error(
660
        ("collate_byname<wchar_t>::collate_byname(size_t refs)"
661
         " failed to construct for " +
662
         name)
663
            .c_str());
664
}
665

666
collate_byname<wchar_t>::~collate_byname() { freelocale(__l_); }
667

668
int collate_byname<wchar_t>::do_compare(
669
    const char_type* __lo1, const char_type* __hi1, const char_type* __lo2, const char_type* __hi2) const {
670
  string_type lhs(__lo1, __hi1);
671
  string_type rhs(__lo2, __hi2);
672
  int r = wcscoll_l(lhs.c_str(), rhs.c_str(), __l_);
673
  if (r < 0)
674
    return -1;
675
  if (r > 0)
676
    return 1;
677
  return r;
678
}
679

680
collate_byname<wchar_t>::string_type
681
collate_byname<wchar_t>::do_transform(const char_type* lo, const char_type* hi) const {
682
  const string_type in(lo, hi);
683
  string_type out(wcsxfrm_l(0, in.c_str(), 0, __l_), wchar_t());
684
  wcsxfrm_l(const_cast<wchar_t*>(out.c_str()), in.c_str(), out.size() + 1, __l_);
685
  return out;
686
}
687
#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
688

689
const ctype_base::mask ctype_base::space;
690
const ctype_base::mask ctype_base::print;
691
const ctype_base::mask ctype_base::cntrl;
692
const ctype_base::mask ctype_base::upper;
693
const ctype_base::mask ctype_base::lower;
694
const ctype_base::mask ctype_base::alpha;
695
const ctype_base::mask ctype_base::digit;
696
const ctype_base::mask ctype_base::punct;
697
const ctype_base::mask ctype_base::xdigit;
698
const ctype_base::mask ctype_base::blank;
699
const ctype_base::mask ctype_base::alnum;
700
const ctype_base::mask ctype_base::graph;
701

702
// template <> class ctype<wchar_t>;
703

704
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
705
constinit locale::id ctype<wchar_t>::id;
706

707
ctype<wchar_t>::~ctype() {}
708

709
bool ctype<wchar_t>::do_is(mask m, char_type c) const {
710
  return isascii(c) ? (ctype<char>::classic_table()[c] & m) != 0 : false;
711
}
712

713
const wchar_t* ctype<wchar_t>::do_is(const char_type* low, const char_type* high, mask* vec) const {
714
  for (; low != high; ++low, ++vec)
715
    *vec = static_cast<mask>(isascii(*low) ? ctype<char>::classic_table()[*low] : 0);
716
  return low;
717
}
718

719
const wchar_t* ctype<wchar_t>::do_scan_is(mask m, const char_type* low, const char_type* high) const {
720
  for (; low != high; ++low)
721
    if (isascii(*low) && (ctype<char>::classic_table()[*low] & m))
722
      break;
723
  return low;
724
}
725

726
const wchar_t* ctype<wchar_t>::do_scan_not(mask m, const char_type* low, const char_type* high) const {
727
  for (; low != high; ++low)
728
    if (!(isascii(*low) && (ctype<char>::classic_table()[*low] & m)))
729
      break;
730
  return low;
731
}
732

733
wchar_t ctype<wchar_t>::do_toupper(char_type c) const {
734
#  ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
735
  return isascii(c) ? _DefaultRuneLocale.__mapupper[c] : c;
736
#  elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__) || defined(__MVS__)
737
  return isascii(c) ? ctype<char>::__classic_upper_table()[c] : c;
738
#  else
739
  return (isascii(c) && iswlower_l(c, _LIBCPP_GET_C_LOCALE)) ? c - L'a' + L'A' : c;
740
#  endif
741
}
742

743
const wchar_t* ctype<wchar_t>::do_toupper(char_type* low, const char_type* high) const {
744
  for (; low != high; ++low)
745
#  ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
746
    *low = isascii(*low) ? _DefaultRuneLocale.__mapupper[*low] : *low;
747
#  elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__) || defined(__MVS__)
748
    *low = isascii(*low) ? ctype<char>::__classic_upper_table()[*low] : *low;
749
#  else
750
    *low = (isascii(*low) && islower_l(*low, _LIBCPP_GET_C_LOCALE)) ? (*low - L'a' + L'A') : *low;
751
#  endif
752
  return low;
753
}
754

755
wchar_t ctype<wchar_t>::do_tolower(char_type c) const {
756
#  ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
757
  return isascii(c) ? _DefaultRuneLocale.__maplower[c] : c;
758
#  elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__) || defined(__MVS__)
759
  return isascii(c) ? ctype<char>::__classic_lower_table()[c] : c;
760
#  else
761
  return (isascii(c) && isupper_l(c, _LIBCPP_GET_C_LOCALE)) ? c - L'A' + 'a' : c;
762
#  endif
763
}
764

765
const wchar_t* ctype<wchar_t>::do_tolower(char_type* low, const char_type* high) const {
766
  for (; low != high; ++low)
767
#  ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
768
    *low = isascii(*low) ? _DefaultRuneLocale.__maplower[*low] : *low;
769
#  elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__) || defined(__MVS__)
770
    *low = isascii(*low) ? ctype<char>::__classic_lower_table()[*low] : *low;
771
#  else
772
    *low = (isascii(*low) && isupper_l(*low, _LIBCPP_GET_C_LOCALE)) ? *low - L'A' + L'a' : *low;
773
#  endif
774
  return low;
775
}
776

777
wchar_t ctype<wchar_t>::do_widen(char c) const { return c; }
778

779
const char* ctype<wchar_t>::do_widen(const char* low, const char* high, char_type* dest) const {
780
  for (; low != high; ++low, ++dest)
781
    *dest = *low;
782
  return low;
783
}
784

785
char ctype<wchar_t>::do_narrow(char_type c, char dfault) const {
786
  if (isascii(c))
787
    return static_cast<char>(c);
788
  return dfault;
789
}
790

791
const wchar_t* ctype<wchar_t>::do_narrow(const char_type* low, const char_type* high, char dfault, char* dest) const {
792
  for (; low != high; ++low, ++dest)
793
    if (isascii(*low))
794
      *dest = static_cast<char>(*low);
795
    else
796
      *dest = dfault;
797
  return low;
798
}
799
#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
800

801
// template <> class ctype<char>;
802

803
constinit locale::id ctype<char>::id;
804

805
const size_t ctype<char>::table_size;
806

807
ctype<char>::ctype(const mask* tab, bool del, size_t refs) : locale::facet(refs), __tab_(tab), __del_(del) {
808
  if (__tab_ == 0)
809
    __tab_ = classic_table();
810
}
811

812
ctype<char>::~ctype() {
813
  if (__tab_ && __del_)
814
    delete[] __tab_;
815
}
816

817
char ctype<char>::do_toupper(char_type c) const {
818
#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
819
  return isascii(c) ? static_cast<char>(_DefaultRuneLocale.__mapupper[static_cast<ptrdiff_t>(c)]) : c;
820
#elif defined(__NetBSD__)
821
  return static_cast<char>(__classic_upper_table()[static_cast<unsigned char>(c)]);
822
#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__MVS__)
823
  return isascii(c) ? static_cast<char>(__classic_upper_table()[static_cast<unsigned char>(c)]) : c;
824
#else
825
  return (isascii(c) && islower_l(c, _LIBCPP_GET_C_LOCALE)) ? c - 'a' + 'A' : c;
826
#endif
827
}
828

829
const char* ctype<char>::do_toupper(char_type* low, const char_type* high) const {
830
  for (; low != high; ++low)
831
#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
832
    *low = isascii(*low) ? static_cast<char>(_DefaultRuneLocale.__mapupper[static_cast<ptrdiff_t>(*low)]) : *low;
833
#elif defined(__NetBSD__)
834
    *low = static_cast<char>(__classic_upper_table()[static_cast<unsigned char>(*low)]);
835
#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__MVS__)
836
    *low = isascii(*low) ? static_cast<char>(__classic_upper_table()[static_cast<size_t>(*low)]) : *low;
837
#else
838
    *low = (isascii(*low) && islower_l(*low, _LIBCPP_GET_C_LOCALE)) ? *low - 'a' + 'A' : *low;
839
#endif
840
  return low;
841
}
842

843
char ctype<char>::do_tolower(char_type c) const {
844
#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
845
  return isascii(c) ? static_cast<char>(_DefaultRuneLocale.__maplower[static_cast<ptrdiff_t>(c)]) : c;
846
#elif defined(__NetBSD__)
847
  return static_cast<char>(__classic_lower_table()[static_cast<unsigned char>(c)]);
848
#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__MVS__)
849
  return isascii(c) ? static_cast<char>(__classic_lower_table()[static_cast<size_t>(c)]) : c;
850
#else
851
  return (isascii(c) && isupper_l(c, _LIBCPP_GET_C_LOCALE)) ? c - 'A' + 'a' : c;
852
#endif
853
}
854

855
const char* ctype<char>::do_tolower(char_type* low, const char_type* high) const {
856
  for (; low != high; ++low)
857
#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
858
    *low = isascii(*low) ? static_cast<char>(_DefaultRuneLocale.__maplower[static_cast<ptrdiff_t>(*low)]) : *low;
859
#elif defined(__NetBSD__)
860
    *low = static_cast<char>(__classic_lower_table()[static_cast<unsigned char>(*low)]);
861
#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__MVS__)
862
    *low = isascii(*low) ? static_cast<char>(__classic_lower_table()[static_cast<size_t>(*low)]) : *low;
863
#else
864
    *low = (isascii(*low) && isupper_l(*low, _LIBCPP_GET_C_LOCALE)) ? *low - 'A' + 'a' : *low;
865
#endif
866
  return low;
867
}
868

869
char ctype<char>::do_widen(char c) const { return c; }
870

871
const char* ctype<char>::do_widen(const char* low, const char* high, char_type* dest) const {
872
  for (; low != high; ++low, ++dest)
873
    *dest = *low;
874
  return low;
875
}
876

877
char ctype<char>::do_narrow(char_type c, char dfault) const {
878
  if (isascii(c))
879
    return static_cast<char>(c);
880
  return dfault;
881
}
882

883
const char* ctype<char>::do_narrow(const char_type* low, const char_type* high, char dfault, char* dest) const {
884
  for (; low != high; ++low, ++dest)
885
    if (isascii(*low))
886
      *dest = *low;
887
    else
888
      *dest = dfault;
889
  return low;
890
}
891

892
#if defined(__EMSCRIPTEN__)
893
extern "C" const unsigned short** __ctype_b_loc();
894
extern "C" const int** __ctype_tolower_loc();
895
extern "C" const int** __ctype_toupper_loc();
896
#endif
897

898
#ifdef _LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE
899
const ctype<char>::mask* ctype<char>::classic_table() noexcept {
900
  // clang-format off
901
    static constexpr const ctype<char>::mask builtin_table[table_size] = {
902
        cntrl,                          cntrl,
903
        cntrl,                          cntrl,
904
        cntrl,                          cntrl,
905
        cntrl,                          cntrl,
906
        cntrl,                          cntrl | space | blank,
907
        cntrl | space,                  cntrl | space,
908
        cntrl | space,                  cntrl | space,
909
        cntrl,                          cntrl,
910
        cntrl,                          cntrl,
911
        cntrl,                          cntrl,
912
        cntrl,                          cntrl,
913
        cntrl,                          cntrl,
914
        cntrl,                          cntrl,
915
        cntrl,                          cntrl,
916
        cntrl,                          cntrl,
917
        cntrl,                          cntrl,
918
        space | blank | print,          punct | print,
919
        punct | print,                  punct | print,
920
        punct | print,                  punct | print,
921
        punct | print,                  punct | print,
922
        punct | print,                  punct | print,
923
        punct | print,                  punct | print,
924
        punct | print,                  punct | print,
925
        punct | print,                  punct | print,
926
        digit | print | xdigit,         digit | print | xdigit,
927
        digit | print | xdigit,         digit | print | xdigit,
928
        digit | print | xdigit,         digit | print | xdigit,
929
        digit | print | xdigit,         digit | print | xdigit,
930
        digit | print | xdigit,         digit | print | xdigit,
931
        punct | print,                  punct | print,
932
        punct | print,                  punct | print,
933
        punct | print,                  punct | print,
934
        punct | print,                  upper | xdigit | print | alpha,
935
        upper | xdigit | print | alpha, upper | xdigit | print | alpha,
936
        upper | xdigit | print | alpha, upper | xdigit | print | alpha,
937
        upper | xdigit | print | alpha, upper | print | alpha,
938
        upper | print | alpha,          upper | print | alpha,
939
        upper | print | alpha,          upper | print | alpha,
940
        upper | print | alpha,          upper | print | alpha,
941
        upper | print | alpha,          upper | print | alpha,
942
        upper | print | alpha,          upper | print | alpha,
943
        upper | print | alpha,          upper | print | alpha,
944
        upper | print | alpha,          upper | print | alpha,
945
        upper | print | alpha,          upper | print | alpha,
946
        upper | print | alpha,          upper | print | alpha,
947
        upper | print | alpha,          punct | print,
948
        punct | print,                  punct | print,
949
        punct | print,                  punct | print,
950
        punct | print,                  lower | xdigit | print | alpha,
951
        lower | xdigit | print | alpha, lower | xdigit | print | alpha,
952
        lower | xdigit | print | alpha, lower | xdigit | print | alpha,
953
        lower | xdigit | print | alpha, lower | print | alpha,
954
        lower | print | alpha,          lower | print | alpha,
955
        lower | print | alpha,          lower | print | alpha,
956
        lower | print | alpha,          lower | print | alpha,
957
        lower | print | alpha,          lower | print | alpha,
958
        lower | print | alpha,          lower | print | alpha,
959
        lower | print | alpha,          lower | print | alpha,
960
        lower | print | alpha,          lower | print | alpha,
961
        lower | print | alpha,          lower | print | alpha,
962
        lower | print | alpha,          lower | print | alpha,
963
        lower | print | alpha,          punct | print,
964
        punct | print,                  punct | print,
965
        punct | print,                  cntrl,
966
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
967
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
968
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
969
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
970
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
971
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
972
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
973
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
974
    };
975
  // clang-format on
976
  return builtin_table;
977
}
978
#else
979
const ctype<char>::mask* ctype<char>::classic_table() noexcept {
980
#  if defined(__APPLE__) || defined(__FreeBSD__)
981
  return _DefaultRuneLocale.__runetype;
982
#  elif defined(__NetBSD__)
983
  return _C_ctype_tab_ + 1;
984
#  elif defined(__GLIBC__)
985
  return _LIBCPP_GET_C_LOCALE->__ctype_b;
986
#  elif defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
987
  return __pctype_func();
988
#  elif defined(__EMSCRIPTEN__)
989
  return *__ctype_b_loc();
990
#  elif defined(_NEWLIB_VERSION)
991
  // Newlib has a 257-entry table in ctype_.c, where (char)0 starts at [1].
992
  return _ctype_ + 1;
993
#  elif defined(_AIX)
994
  return (const unsigned int*)__lc_ctype_ptr->obj->mask;
995
#  elif defined(__MVS__)
996
#    if defined(__NATIVE_ASCII_F)
997
  return const_cast<const ctype<char>::mask*>(__OBJ_DATA(__lc_ctype_a)->mask);
998
#    else
999
  return const_cast<const ctype<char>::mask*>(__ctypec);
1000
#    endif
1001
#  else
1002
  // Platform not supported: abort so the person doing the port knows what to
1003
  // fix
1004
#    warning ctype<char>::classic_table() is not implemented
1005
  printf("ctype<char>::classic_table() is not implemented\n");
1006
  abort();
1007
  return NULL;
1008
#  endif
1009
}
1010
#endif
1011

1012
#if defined(__GLIBC__)
1013
const int* ctype<char>::__classic_lower_table() noexcept { return _LIBCPP_GET_C_LOCALE->__ctype_tolower; }
1014

1015
const int* ctype<char>::__classic_upper_table() noexcept { return _LIBCPP_GET_C_LOCALE->__ctype_toupper; }
1016
#elif defined(__NetBSD__)
1017
const short* ctype<char>::__classic_lower_table() noexcept { return _C_tolower_tab_ + 1; }
1018

1019
const short* ctype<char>::__classic_upper_table() noexcept { return _C_toupper_tab_ + 1; }
1020

1021
#elif defined(__EMSCRIPTEN__)
1022
const int* ctype<char>::__classic_lower_table() noexcept { return *__ctype_tolower_loc(); }
1023

1024
const int* ctype<char>::__classic_upper_table() noexcept { return *__ctype_toupper_loc(); }
1025
#elif defined(__MVS__)
1026
const unsigned short* ctype<char>::__classic_lower_table() _NOEXCEPT {
1027
#  if defined(__NATIVE_ASCII_F)
1028
  return const_cast<const unsigned short*>(__OBJ_DATA(__lc_ctype_a)->lower);
1029
#  else
1030
  return const_cast<const unsigned short*>(__ctype + __TOLOWER_INDEX);
1031
#  endif
1032
}
1033
const unsigned short* ctype<char>::__classic_upper_table() _NOEXCEPT {
1034
#  if defined(__NATIVE_ASCII_F)
1035
  return const_cast<const unsigned short*>(__OBJ_DATA(__lc_ctype_a)->upper);
1036
#  else
1037
  return const_cast<const unsigned short*>(__ctype + __TOUPPER_INDEX);
1038
#  endif
1039
}
1040
#endif // __GLIBC__ || __NETBSD__ || __EMSCRIPTEN__ || __MVS__
1041

1042
// template <> class ctype_byname<char>
1043

1044
ctype_byname<char>::ctype_byname(const char* name, size_t refs)
1045
    : ctype<char>(0, false, refs), __l_(newlocale(LC_ALL_MASK, name, 0)) {
1046
  if (__l_ == 0)
1047
    __throw_runtime_error(
1048
        ("ctype_byname<char>::ctype_byname"
1049
         " failed to construct for " +
1050
         string(name))
1051
            .c_str());
1052
}
1053

1054
ctype_byname<char>::ctype_byname(const string& name, size_t refs)
1055
    : ctype<char>(0, false, refs), __l_(newlocale(LC_ALL_MASK, name.c_str(), 0)) {
1056
  if (__l_ == 0)
1057
    __throw_runtime_error(
1058
        ("ctype_byname<char>::ctype_byname"
1059
         " failed to construct for " +
1060
         name)
1061
            .c_str());
1062
}
1063

1064
ctype_byname<char>::~ctype_byname() { freelocale(__l_); }
1065

1066
char ctype_byname<char>::do_toupper(char_type c) const {
1067
  return static_cast<char>(toupper_l(static_cast<unsigned char>(c), __l_));
1068
}
1069

1070
const char* ctype_byname<char>::do_toupper(char_type* low, const char_type* high) const {
1071
  for (; low != high; ++low)
1072
    *low = static_cast<char>(toupper_l(static_cast<unsigned char>(*low), __l_));
1073
  return low;
1074
}
1075

1076
char ctype_byname<char>::do_tolower(char_type c) const {
1077
  return static_cast<char>(tolower_l(static_cast<unsigned char>(c), __l_));
1078
}
1079

1080
const char* ctype_byname<char>::do_tolower(char_type* low, const char_type* high) const {
1081
  for (; low != high; ++low)
1082
    *low = static_cast<char>(tolower_l(static_cast<unsigned char>(*low), __l_));
1083
  return low;
1084
}
1085

1086
// template <> class ctype_byname<wchar_t>
1087

1088
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
1089
ctype_byname<wchar_t>::ctype_byname(const char* name, size_t refs)
1090
    : ctype<wchar_t>(refs), __l_(newlocale(LC_ALL_MASK, name, 0)) {
1091
  if (__l_ == 0)
1092
    __throw_runtime_error(
1093
        ("ctype_byname<wchar_t>::ctype_byname"
1094
         " failed to construct for " +
1095
         string(name))
1096
            .c_str());
1097
}
1098

1099
ctype_byname<wchar_t>::ctype_byname(const string& name, size_t refs)
1100
    : ctype<wchar_t>(refs), __l_(newlocale(LC_ALL_MASK, name.c_str(), 0)) {
1101
  if (__l_ == 0)
1102
    __throw_runtime_error(
1103
        ("ctype_byname<wchar_t>::ctype_byname"
1104
         " failed to construct for " +
1105
         name)
1106
            .c_str());
1107
}
1108

1109
ctype_byname<wchar_t>::~ctype_byname() { freelocale(__l_); }
1110

1111
bool ctype_byname<wchar_t>::do_is(mask m, char_type c) const {
1112
#  ifdef _LIBCPP_WCTYPE_IS_MASK
1113
  return static_cast<bool>(iswctype_l(c, m, __l_));
1114
#  else
1115
  bool result = false;
1116
  wint_t ch   = static_cast<wint_t>(c);
1117
  if ((m & space) == space)
1118
    result |= (iswspace_l(ch, __l_) != 0);
1119
  if ((m & print) == print)
1120
    result |= (iswprint_l(ch, __l_) != 0);
1121
  if ((m & cntrl) == cntrl)
1122
    result |= (iswcntrl_l(ch, __l_) != 0);
1123
  if ((m & upper) == upper)
1124
    result |= (iswupper_l(ch, __l_) != 0);
1125
  if ((m & lower) == lower)
1126
    result |= (iswlower_l(ch, __l_) != 0);
1127
  if ((m & alpha) == alpha)
1128
    result |= (iswalpha_l(ch, __l_) != 0);
1129
  if ((m & digit) == digit)
1130
    result |= (iswdigit_l(ch, __l_) != 0);
1131
  if ((m & punct) == punct)
1132
    result |= (iswpunct_l(ch, __l_) != 0);
1133
  if ((m & xdigit) == xdigit)
1134
    result |= (iswxdigit_l(ch, __l_) != 0);
1135
  if ((m & blank) == blank)
1136
    result |= (iswblank_l(ch, __l_) != 0);
1137
  return result;
1138
#  endif
1139
}
1140

1141
const wchar_t* ctype_byname<wchar_t>::do_is(const char_type* low, const char_type* high, mask* vec) const {
1142
  for (; low != high; ++low, ++vec) {
1143
    if (isascii(*low))
1144
      *vec = static_cast<mask>(ctype<char>::classic_table()[*low]);
1145
    else {
1146
      *vec      = 0;
1147
      wint_t ch = static_cast<wint_t>(*low);
1148
      if (iswspace_l(ch, __l_))
1149
        *vec |= space;
1150
#  ifndef _LIBCPP_CTYPE_MASK_IS_COMPOSITE_PRINT
1151
      if (iswprint_l(ch, __l_))
1152
        *vec |= print;
1153
#  endif
1154
      if (iswcntrl_l(ch, __l_))
1155
        *vec |= cntrl;
1156
      if (iswupper_l(ch, __l_))
1157
        *vec |= upper;
1158
      if (iswlower_l(ch, __l_))
1159
        *vec |= lower;
1160
#  ifndef _LIBCPP_CTYPE_MASK_IS_COMPOSITE_ALPHA
1161
      if (iswalpha_l(ch, __l_))
1162
        *vec |= alpha;
1163
#  endif
1164
      if (iswdigit_l(ch, __l_))
1165
        *vec |= digit;
1166
      if (iswpunct_l(ch, __l_))
1167
        *vec |= punct;
1168
#  ifndef _LIBCPP_CTYPE_MASK_IS_COMPOSITE_XDIGIT
1169
      if (iswxdigit_l(ch, __l_))
1170
        *vec |= xdigit;
1171
#  endif
1172
      if (iswblank_l(ch, __l_))
1173
        *vec |= blank;
1174
    }
1175
  }
1176
  return low;
1177
}
1178

1179
const wchar_t* ctype_byname<wchar_t>::do_scan_is(mask m, const char_type* low, const char_type* high) const {
1180
  for (; low != high; ++low) {
1181
#  ifdef _LIBCPP_WCTYPE_IS_MASK
1182
    if (iswctype_l(*low, m, __l_))
1183
      break;
1184
#  else
1185
    wint_t ch = static_cast<wint_t>(*low);
1186
    if ((m & space) == space && iswspace_l(ch, __l_))
1187
      break;
1188
    if ((m & print) == print && iswprint_l(ch, __l_))
1189
      break;
1190
    if ((m & cntrl) == cntrl && iswcntrl_l(ch, __l_))
1191
      break;
1192
    if ((m & upper) == upper && iswupper_l(ch, __l_))
1193
      break;
1194
    if ((m & lower) == lower && iswlower_l(ch, __l_))
1195
      break;
1196
    if ((m & alpha) == alpha && iswalpha_l(ch, __l_))
1197
      break;
1198
    if ((m & digit) == digit && iswdigit_l(ch, __l_))
1199
      break;
1200
    if ((m & punct) == punct && iswpunct_l(ch, __l_))
1201
      break;
1202
    if ((m & xdigit) == xdigit && iswxdigit_l(ch, __l_))
1203
      break;
1204
    if ((m & blank) == blank && iswblank_l(ch, __l_))
1205
      break;
1206
#  endif
1207
  }
1208
  return low;
1209
}
1210

1211
const wchar_t* ctype_byname<wchar_t>::do_scan_not(mask m, const char_type* low, const char_type* high) const {
1212
  for (; low != high; ++low) {
1213
#  ifdef _LIBCPP_WCTYPE_IS_MASK
1214
    if (!iswctype_l(*low, m, __l_))
1215
      break;
1216
#  else
1217
    wint_t ch = static_cast<wint_t>(*low);
1218
    if ((m & space) == space && iswspace_l(ch, __l_))
1219
      continue;
1220
    if ((m & print) == print && iswprint_l(ch, __l_))
1221
      continue;
1222
    if ((m & cntrl) == cntrl && iswcntrl_l(ch, __l_))
1223
      continue;
1224
    if ((m & upper) == upper && iswupper_l(ch, __l_))
1225
      continue;
1226
    if ((m & lower) == lower && iswlower_l(ch, __l_))
1227
      continue;
1228
    if ((m & alpha) == alpha && iswalpha_l(ch, __l_))
1229
      continue;
1230
    if ((m & digit) == digit && iswdigit_l(ch, __l_))
1231
      continue;
1232
    if ((m & punct) == punct && iswpunct_l(ch, __l_))
1233
      continue;
1234
    if ((m & xdigit) == xdigit && iswxdigit_l(ch, __l_))
1235
      continue;
1236
    if ((m & blank) == blank && iswblank_l(ch, __l_))
1237
      continue;
1238
    break;
1239
#  endif
1240
  }
1241
  return low;
1242
}
1243

1244
wchar_t ctype_byname<wchar_t>::do_toupper(char_type c) const { return towupper_l(c, __l_); }
1245

1246
const wchar_t* ctype_byname<wchar_t>::do_toupper(char_type* low, const char_type* high) const {
1247
  for (; low != high; ++low)
1248
    *low = towupper_l(*low, __l_);
1249
  return low;
1250
}
1251

1252
wchar_t ctype_byname<wchar_t>::do_tolower(char_type c) const { return towlower_l(c, __l_); }
1253

1254
const wchar_t* ctype_byname<wchar_t>::do_tolower(char_type* low, const char_type* high) const {
1255
  for (; low != high; ++low)
1256
    *low = towlower_l(*low, __l_);
1257
  return low;
1258
}
1259

1260
wchar_t ctype_byname<wchar_t>::do_widen(char c) const { return __libcpp_btowc_l(c, __l_); }
1261

1262
const char* ctype_byname<wchar_t>::do_widen(const char* low, const char* high, char_type* dest) const {
1263
  for (; low != high; ++low, ++dest)
1264
    *dest = __libcpp_btowc_l(*low, __l_);
1265
  return low;
1266
}
1267

1268
char ctype_byname<wchar_t>::do_narrow(char_type c, char dfault) const {
1269
  int r = __libcpp_wctob_l(c, __l_);
1270
  return (r != EOF) ? static_cast<char>(r) : dfault;
1271
}
1272

1273
const wchar_t*
1274
ctype_byname<wchar_t>::do_narrow(const char_type* low, const char_type* high, char dfault, char* dest) const {
1275
  for (; low != high; ++low, ++dest) {
1276
    int r = __libcpp_wctob_l(*low, __l_);
1277
    *dest = (r != EOF) ? static_cast<char>(r) : dfault;
1278
  }
1279
  return low;
1280
}
1281
#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
1282

1283
// template <> class codecvt<char, char, mbstate_t>
1284

1285
constinit locale::id codecvt<char, char, mbstate_t>::id;
1286

1287
codecvt<char, char, mbstate_t>::~codecvt() {}
1288

1289
codecvt<char, char, mbstate_t>::result codecvt<char, char, mbstate_t>::do_out(
1290
    state_type&,
1291
    const intern_type* frm,
1292
    const intern_type*,
1293
    const intern_type*& frm_nxt,
1294
    extern_type* to,
1295
    extern_type*,
1296
    extern_type*& to_nxt) const {
1297
  frm_nxt = frm;
1298
  to_nxt  = to;
1299
  return noconv;
1300
}
1301

1302
codecvt<char, char, mbstate_t>::result codecvt<char, char, mbstate_t>::do_in(
1303
    state_type&,
1304
    const extern_type* frm,
1305
    const extern_type*,
1306
    const extern_type*& frm_nxt,
1307
    intern_type* to,
1308
    intern_type*,
1309
    intern_type*& to_nxt) const {
1310
  frm_nxt = frm;
1311
  to_nxt  = to;
1312
  return noconv;
1313
}
1314

1315
codecvt<char, char, mbstate_t>::result
1316
codecvt<char, char, mbstate_t>::do_unshift(state_type&, extern_type* to, extern_type*, extern_type*& to_nxt) const {
1317
  to_nxt = to;
1318
  return noconv;
1319
}
1320

1321
int codecvt<char, char, mbstate_t>::do_encoding() const noexcept { return 1; }
1322

1323
bool codecvt<char, char, mbstate_t>::do_always_noconv() const noexcept { return true; }
1324

1325
int codecvt<char, char, mbstate_t>::do_length(
1326
    state_type&, const extern_type* frm, const extern_type* end, size_t mx) const {
1327
  return static_cast<int>(min<size_t>(mx, static_cast<size_t>(end - frm)));
1328
}
1329

1330
int codecvt<char, char, mbstate_t>::do_max_length() const noexcept { return 1; }
1331

1332
// template <> class codecvt<wchar_t, char, mbstate_t>
1333

1334
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
1335
constinit locale::id codecvt<wchar_t, char, mbstate_t>::id;
1336

1337
codecvt<wchar_t, char, mbstate_t>::codecvt(size_t refs) : locale::facet(refs), __l_(_LIBCPP_GET_C_LOCALE) {}
1338

1339
codecvt<wchar_t, char, mbstate_t>::codecvt(const char* nm, size_t refs)
1340
    : locale::facet(refs), __l_(newlocale(LC_ALL_MASK, nm, 0)) {
1341
  if (__l_ == 0)
1342
    __throw_runtime_error(
1343
        ("codecvt_byname<wchar_t, char, mbstate_t>::codecvt_byname"
1344
         " failed to construct for " +
1345
         string(nm))
1346
            .c_str());
1347
}
1348

1349
codecvt<wchar_t, char, mbstate_t>::~codecvt() {
1350
  if (__l_ != _LIBCPP_GET_C_LOCALE)
1351
    freelocale(__l_);
1352
}
1353

1354
codecvt<wchar_t, char, mbstate_t>::result codecvt<wchar_t, char, mbstate_t>::do_out(
1355
    state_type& st,
1356
    const intern_type* frm,
1357
    const intern_type* frm_end,
1358
    const intern_type*& frm_nxt,
1359
    extern_type* to,
1360
    extern_type* to_end,
1361
    extern_type*& to_nxt) const {
1362
  // look for first internal null in frm
1363
  const intern_type* fend = frm;
1364
  for (; fend != frm_end; ++fend)
1365
    if (*fend == 0)
1366
      break;
1367
  // loop over all null-terminated sequences in frm
1368
  to_nxt = to;
1369
  for (frm_nxt = frm; frm != frm_end && to != to_end; frm = frm_nxt, to = to_nxt) {
1370
    // save state in case it is needed to recover to_nxt on error
1371
    mbstate_t save_state = st;
1372
    size_t n             = __libcpp_wcsnrtombs_l(
1373
        to, &frm_nxt, static_cast<size_t>(fend - frm), static_cast<size_t>(to_end - to), &st, __l_);
1374
    if (n == size_t(-1)) {
1375
      // need to recover to_nxt
1376
      for (to_nxt = to; frm != frm_nxt; ++frm) {
1377
        n = __libcpp_wcrtomb_l(to_nxt, *frm, &save_state, __l_);
1378
        if (n == size_t(-1))
1379
          break;
1380
        to_nxt += n;
1381
      }
1382
      frm_nxt = frm;
1383
      return error;
1384
    }
1385
    if (n == 0)
1386
      return partial;
1387
    to_nxt += n;
1388
    if (to_nxt == to_end)
1389
      break;
1390
    if (fend != frm_end) // set up next null terminated sequence
1391
    {
1392
      // Try to write the terminating null
1393
      extern_type tmp[MB_LEN_MAX];
1394
      n = __libcpp_wcrtomb_l(tmp, intern_type(), &st, __l_);
1395
      if (n == size_t(-1)) // on error
1396
        return error;
1397
      if (n > static_cast<size_t>(to_end - to_nxt)) // is there room?
1398
        return partial;
1399
      for (extern_type* p = tmp; n; --n) // write it
1400
        *to_nxt++ = *p++;
1401
      ++frm_nxt;
1402
      // look for next null in frm
1403
      for (fend = frm_nxt; fend != frm_end; ++fend)
1404
        if (*fend == 0)
1405
          break;
1406
    }
1407
  }
1408
  return frm_nxt == frm_end ? ok : partial;
1409
}
1410

1411
codecvt<wchar_t, char, mbstate_t>::result codecvt<wchar_t, char, mbstate_t>::do_in(
1412
    state_type& st,
1413
    const extern_type* frm,
1414
    const extern_type* frm_end,
1415
    const extern_type*& frm_nxt,
1416
    intern_type* to,
1417
    intern_type* to_end,
1418
    intern_type*& to_nxt) const {
1419
  // look for first internal null in frm
1420
  const extern_type* fend = frm;
1421
  for (; fend != frm_end; ++fend)
1422
    if (*fend == 0)
1423
      break;
1424
  // loop over all null-terminated sequences in frm
1425
  to_nxt = to;
1426
  for (frm_nxt = frm; frm != frm_end && to != to_end; frm = frm_nxt, to = to_nxt) {
1427
    // save state in case it is needed to recover to_nxt on error
1428
    mbstate_t save_state = st;
1429
    size_t n             = __libcpp_mbsnrtowcs_l(
1430
        to, &frm_nxt, static_cast<size_t>(fend - frm), static_cast<size_t>(to_end - to), &st, __l_);
1431
    if (n == size_t(-1)) {
1432
      // need to recover to_nxt
1433
      for (to_nxt = to; frm != frm_nxt; ++to_nxt) {
1434
        n = __libcpp_mbrtowc_l(to_nxt, frm, static_cast<size_t>(fend - frm), &save_state, __l_);
1435
        switch (n) {
1436
        case 0:
1437
          ++frm;
1438
          break;
1439
        case size_t(-1):
1440
          frm_nxt = frm;
1441
          return error;
1442
        case size_t(-2):
1443
          frm_nxt = frm;
1444
          return partial;
1445
        default:
1446
          frm += n;
1447
          break;
1448
        }
1449
      }
1450
      frm_nxt = frm;
1451
      return frm_nxt == frm_end ? ok : partial;
1452
    }
1453
    if (n == size_t(-1))
1454
      return error;
1455
    to_nxt += n;
1456
    if (to_nxt == to_end)
1457
      break;
1458
    if (fend != frm_end) // set up next null terminated sequence
1459
    {
1460
      // Try to write the terminating null
1461
      n = __libcpp_mbrtowc_l(to_nxt, frm_nxt, 1, &st, __l_);
1462
      if (n != 0) // on error
1463
        return error;
1464
      ++to_nxt;
1465
      ++frm_nxt;
1466
      // look for next null in frm
1467
      for (fend = frm_nxt; fend != frm_end; ++fend)
1468
        if (*fend == 0)
1469
          break;
1470
    }
1471
  }
1472
  return frm_nxt == frm_end ? ok : partial;
1473
}
1474

1475
codecvt<wchar_t, char, mbstate_t>::result codecvt<wchar_t, char, mbstate_t>::do_unshift(
1476
    state_type& st, extern_type* to, extern_type* to_end, extern_type*& to_nxt) const {
1477
  to_nxt = to;
1478
  extern_type tmp[MB_LEN_MAX];
1479
  size_t n = __libcpp_wcrtomb_l(tmp, intern_type(), &st, __l_);
1480
  if (n == size_t(-1) || n == 0) // on error
1481
    return error;
1482
  --n;
1483
  if (n > static_cast<size_t>(to_end - to_nxt)) // is there room?
1484
    return partial;
1485
  for (extern_type* p = tmp; n; --n) // write it
1486
    *to_nxt++ = *p++;
1487
  return ok;
1488
}
1489

1490
int codecvt<wchar_t, char, mbstate_t>::do_encoding() const noexcept {
1491
  if (__libcpp_mbtowc_l(nullptr, nullptr, MB_LEN_MAX, __l_) != 0)
1492
    return -1;
1493

1494
  // stateless encoding
1495
  if (__l_ == 0 || __libcpp_mb_cur_max_l(__l_) == 1) // there are no known constant length encodings
1496
    return 1;                                        // which take more than 1 char to form a wchar_t
1497
  return 0;
1498
}
1499

1500
bool codecvt<wchar_t, char, mbstate_t>::do_always_noconv() const noexcept { return false; }
1501

1502
int codecvt<wchar_t, char, mbstate_t>::do_length(
1503
    state_type& st, const extern_type* frm, const extern_type* frm_end, size_t mx) const {
1504
  int nbytes = 0;
1505
  for (size_t nwchar_t = 0; nwchar_t < mx && frm != frm_end; ++nwchar_t) {
1506
    size_t n = __libcpp_mbrlen_l(frm, static_cast<size_t>(frm_end - frm), &st, __l_);
1507
    switch (n) {
1508
    case 0:
1509
      ++nbytes;
1510
      ++frm;
1511
      break;
1512
    case size_t(-1):
1513
    case size_t(-2):
1514
      return nbytes;
1515
    default:
1516
      nbytes += n;
1517
      frm += n;
1518
      break;
1519
    }
1520
  }
1521
  return nbytes;
1522
}
1523

1524
int codecvt<wchar_t, char, mbstate_t>::do_max_length() const noexcept {
1525
  return __l_ == 0 ? 1 : static_cast<int>(__libcpp_mb_cur_max_l(__l_));
1526
}
1527
#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
1528

1529
//                                     Valid UTF ranges
1530
//     UTF-32               UTF-16                          UTF-8               # of code points
1531
//                     first      second       first   second    third   fourth
1532
// 000000 - 00007F  0000 - 007F               00 - 7F                                 127
1533
// 000080 - 0007FF  0080 - 07FF               C2 - DF, 80 - BF                       1920
1534
// 000800 - 000FFF  0800 - 0FFF               E0 - E0, A0 - BF, 80 - BF              2048
1535
// 001000 - 00CFFF  1000 - CFFF               E1 - EC, 80 - BF, 80 - BF             49152
1536
// 00D000 - 00D7FF  D000 - D7FF               ED - ED, 80 - 9F, 80 - BF              2048
1537
// 00D800 - 00DFFF                invalid
1538
// 00E000 - 00FFFF  E000 - FFFF               EE - EF, 80 - BF, 80 - BF              8192
1539
// 010000 - 03FFFF  D800 - D8BF, DC00 - DFFF  F0 - F0, 90 - BF, 80 - BF, 80 - BF   196608
1540
// 040000 - 0FFFFF  D8C0 - DBBF, DC00 - DFFF  F1 - F3, 80 - BF, 80 - BF, 80 - BF   786432
1541
// 100000 - 10FFFF  DBC0 - DBFF, DC00 - DFFF  F4 - F4, 80 - 8F, 80 - BF, 80 - BF    65536
1542

1543
_LIBCPP_SUPPRESS_DEPRECATED_PUSH
1544
static codecvt_base::result utf16_to_utf8(
1545
    const uint16_t* frm,
1546
    const uint16_t* frm_end,
1547
    const uint16_t*& frm_nxt,
1548
    uint8_t* to,
1549
    uint8_t* to_end,
1550
    uint8_t*& to_nxt,
1551
    unsigned long Maxcode = 0x10FFFF,
1552
    codecvt_mode mode     = codecvt_mode(0)) {
1553
  frm_nxt = frm;
1554
  to_nxt  = to;
1555
  if (mode & generate_header) {
1556
    if (to_end - to_nxt < 3)
1557
      return codecvt_base::partial;
1558
    *to_nxt++ = static_cast<uint8_t>(0xEF);
1559
    *to_nxt++ = static_cast<uint8_t>(0xBB);
1560
    *to_nxt++ = static_cast<uint8_t>(0xBF);
1561
  }
1562
  for (; frm_nxt < frm_end; ++frm_nxt) {
1563
    uint16_t wc1 = *frm_nxt;
1564
    if (wc1 > Maxcode)
1565
      return codecvt_base::error;
1566
    if (wc1 < 0x0080) {
1567
      if (to_end - to_nxt < 1)
1568
        return codecvt_base::partial;
1569
      *to_nxt++ = static_cast<uint8_t>(wc1);
1570
    } else if (wc1 < 0x0800) {
1571
      if (to_end - to_nxt < 2)
1572
        return codecvt_base::partial;
1573
      *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc1 >> 6));
1574
      *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x03F));
1575
    } else if (wc1 < 0xD800) {
1576
      if (to_end - to_nxt < 3)
1577
        return codecvt_base::partial;
1578
      *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12));
1579
      *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));
1580
      *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F));
1581
    } else if (wc1 < 0xDC00) {
1582
      if (frm_end - frm_nxt < 2)
1583
        return codecvt_base::partial;
1584
      uint16_t wc2 = frm_nxt[1];
1585
      if ((wc2 & 0xFC00) != 0xDC00)
1586
        return codecvt_base::error;
1587
      if (to_end - to_nxt < 4)
1588
        return codecvt_base::partial;
1589
      if (((((wc1 & 0x03C0UL) >> 6) + 1) << 16) + ((wc1 & 0x003FUL) << 10) + (wc2 & 0x03FF) > Maxcode)
1590
        return codecvt_base::error;
1591
      ++frm_nxt;
1592
      uint8_t z = ((wc1 & 0x03C0) >> 6) + 1;
1593
      *to_nxt++ = static_cast<uint8_t>(0xF0 | (z >> 2));
1594
      *to_nxt++ = static_cast<uint8_t>(0x80 | ((z & 0x03) << 4) | ((wc1 & 0x003C) >> 2));
1595
      *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0003) << 4) | ((wc2 & 0x03C0) >> 6));
1596
      *to_nxt++ = static_cast<uint8_t>(0x80 | (wc2 & 0x003F));
1597
    } else if (wc1 < 0xE000) {
1598
      return codecvt_base::error;
1599
    } else {
1600
      if (to_end - to_nxt < 3)
1601
        return codecvt_base::partial;
1602
      *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12));
1603
      *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));
1604
      *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F));
1605
    }
1606
  }
1607
  return codecvt_base::ok;
1608
}
1609

1610
static codecvt_base::result utf16_to_utf8(
1611
    const uint32_t* frm,
1612
    const uint32_t* frm_end,
1613
    const uint32_t*& frm_nxt,
1614
    uint8_t* to,
1615
    uint8_t* to_end,
1616
    uint8_t*& to_nxt,
1617
    unsigned long Maxcode = 0x10FFFF,
1618
    codecvt_mode mode     = codecvt_mode(0)) {
1619
  frm_nxt = frm;
1620
  to_nxt  = to;
1621
  if (mode & generate_header) {
1622
    if (to_end - to_nxt < 3)
1623
      return codecvt_base::partial;
1624
    *to_nxt++ = static_cast<uint8_t>(0xEF);
1625
    *to_nxt++ = static_cast<uint8_t>(0xBB);
1626
    *to_nxt++ = static_cast<uint8_t>(0xBF);
1627
  }
1628
  for (; frm_nxt < frm_end; ++frm_nxt) {
1629
    uint16_t wc1 = static_cast<uint16_t>(*frm_nxt);
1630
    if (wc1 > Maxcode)
1631
      return codecvt_base::error;
1632
    if (wc1 < 0x0080) {
1633
      if (to_end - to_nxt < 1)
1634
        return codecvt_base::partial;
1635
      *to_nxt++ = static_cast<uint8_t>(wc1);
1636
    } else if (wc1 < 0x0800) {
1637
      if (to_end - to_nxt < 2)
1638
        return codecvt_base::partial;
1639
      *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc1 >> 6));
1640
      *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x03F));
1641
    } else if (wc1 < 0xD800) {
1642
      if (to_end - to_nxt < 3)
1643
        return codecvt_base::partial;
1644
      *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12));
1645
      *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));
1646
      *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F));
1647
    } else if (wc1 < 0xDC00) {
1648
      if (frm_end - frm_nxt < 2)
1649
        return codecvt_base::partial;
1650
      uint16_t wc2 = static_cast<uint16_t>(frm_nxt[1]);
1651
      if ((wc2 & 0xFC00) != 0xDC00)
1652
        return codecvt_base::error;
1653
      if (to_end - to_nxt < 4)
1654
        return codecvt_base::partial;
1655
      if (((((wc1 & 0x03C0UL) >> 6) + 1) << 16) + ((wc1 & 0x003FUL) << 10) + (wc2 & 0x03FF) > Maxcode)
1656
        return codecvt_base::error;
1657
      ++frm_nxt;
1658
      uint8_t z = ((wc1 & 0x03C0) >> 6) + 1;
1659
      *to_nxt++ = static_cast<uint8_t>(0xF0 | (z >> 2));
1660
      *to_nxt++ = static_cast<uint8_t>(0x80 | ((z & 0x03) << 4) | ((wc1 & 0x003C) >> 2));
1661
      *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0003) << 4) | ((wc2 & 0x03C0) >> 6));
1662
      *to_nxt++ = static_cast<uint8_t>(0x80 | (wc2 & 0x003F));
1663
    } else if (wc1 < 0xE000) {
1664
      return codecvt_base::error;
1665
    } else {
1666
      if (to_end - to_nxt < 3)
1667
        return codecvt_base::partial;
1668
      *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12));
1669
      *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));
1670
      *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F));
1671
    }
1672
  }
1673
  return codecvt_base::ok;
1674
}
1675

1676
static codecvt_base::result utf8_to_utf16(
1677
    const uint8_t* frm,
1678
    const uint8_t* frm_end,
1679
    const uint8_t*& frm_nxt,
1680
    uint16_t* to,
1681
    uint16_t* to_end,
1682
    uint16_t*& to_nxt,
1683
    unsigned long Maxcode = 0x10FFFF,
1684
    codecvt_mode mode     = codecvt_mode(0)) {
1685
  frm_nxt = frm;
1686
  to_nxt  = to;
1687
  if (mode & consume_header) {
1688
    if (frm_end - frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB && frm_nxt[2] == 0xBF)
1689
      frm_nxt += 3;
1690
  }
1691
  for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt) {
1692
    uint8_t c1 = *frm_nxt;
1693
    if (c1 > Maxcode)
1694
      return codecvt_base::error;
1695
    if (c1 < 0x80) {
1696
      *to_nxt = static_cast<uint16_t>(c1);
1697
      ++frm_nxt;
1698
    } else if (c1 < 0xC2) {
1699
      return codecvt_base::error;
1700
    } else if (c1 < 0xE0) {
1701
      if (frm_end - frm_nxt < 2)
1702
        return codecvt_base::partial;
1703
      uint8_t c2 = frm_nxt[1];
1704
      if ((c2 & 0xC0) != 0x80)
1705
        return codecvt_base::error;
1706
      uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) | (c2 & 0x3F));
1707
      if (t > Maxcode)
1708
        return codecvt_base::error;
1709
      *to_nxt = t;
1710
      frm_nxt += 2;
1711
    } else if (c1 < 0xF0) {
1712
      if (frm_end - frm_nxt < 2)
1713
        return codecvt_base::partial;
1714
      uint8_t c2 = frm_nxt[1];
1715
      switch (c1) {
1716
      case 0xE0:
1717
        if ((c2 & 0xE0) != 0xA0)
1718
          return codecvt_base::error;
1719
        break;
1720
      case 0xED:
1721
        if ((c2 & 0xE0) != 0x80)
1722
          return codecvt_base::error;
1723
        break;
1724
      default:
1725
        if ((c2 & 0xC0) != 0x80)
1726
          return codecvt_base::error;
1727
        break;
1728
      }
1729
      if (frm_end - frm_nxt < 3)
1730
        return codecvt_base::partial;
1731
      uint8_t c3 = frm_nxt[2];
1732
      if ((c3 & 0xC0) != 0x80)
1733
        return codecvt_base::error;
1734
      uint16_t t = static_cast<uint16_t>(((c1 & 0x0F) << 12) | ((c2 & 0x3F) << 6) | (c3 & 0x3F));
1735
      if (t > Maxcode)
1736
        return codecvt_base::error;
1737
      *to_nxt = t;
1738
      frm_nxt += 3;
1739
    } else if (c1 < 0xF5) {
1740
      if (frm_end - frm_nxt < 2)
1741
        return codecvt_base::partial;
1742
      uint8_t c2 = frm_nxt[1];
1743
      switch (c1) {
1744
      case 0xF0:
1745
        if (!(0x90 <= c2 && c2 <= 0xBF))
1746
          return codecvt_base::error;
1747
        break;
1748
      case 0xF4:
1749
        if ((c2 & 0xF0) != 0x80)
1750
          return codecvt_base::error;
1751
        break;
1752
      default:
1753
        if ((c2 & 0xC0) != 0x80)
1754
          return codecvt_base::error;
1755
        break;
1756
      }
1757
      if (frm_end - frm_nxt < 3)
1758
        return codecvt_base::partial;
1759
      uint8_t c3 = frm_nxt[2];
1760
      if ((c3 & 0xC0) != 0x80)
1761
        return codecvt_base::error;
1762
      if (frm_end - frm_nxt < 4)
1763
        return codecvt_base::partial;
1764
      uint8_t c4 = frm_nxt[3];
1765
      if ((c4 & 0xC0) != 0x80)
1766
        return codecvt_base::error;
1767
      if (to_end - to_nxt < 2)
1768
        return codecvt_base::partial;
1769
      if ((((c1 & 7UL) << 18) + ((c2 & 0x3FUL) << 12) + ((c3 & 0x3FUL) << 6) + (c4 & 0x3F)) > Maxcode)
1770
        return codecvt_base::error;
1771
      *to_nxt = static_cast<uint16_t>(
1772
          0xD800 | (((((c1 & 0x07) << 2) | ((c2 & 0x30) >> 4)) - 1) << 6) | ((c2 & 0x0F) << 2) | ((c3 & 0x30) >> 4));
1773
      *++to_nxt = static_cast<uint16_t>(0xDC00 | ((c3 & 0x0F) << 6) | (c4 & 0x3F));
1774
      frm_nxt += 4;
1775
    } else {
1776
      return codecvt_base::error;
1777
    }
1778
  }
1779
  return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
1780
}
1781

1782
static codecvt_base::result utf8_to_utf16(
1783
    const uint8_t* frm,
1784
    const uint8_t* frm_end,
1785
    const uint8_t*& frm_nxt,
1786
    uint32_t* to,
1787
    uint32_t* to_end,
1788
    uint32_t*& to_nxt,
1789
    unsigned long Maxcode = 0x10FFFF,
1790
    codecvt_mode mode     = codecvt_mode(0)) {
1791
  frm_nxt = frm;
1792
  to_nxt  = to;
1793
  if (mode & consume_header) {
1794
    if (frm_end - frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB && frm_nxt[2] == 0xBF)
1795
      frm_nxt += 3;
1796
  }
1797
  for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt) {
1798
    uint8_t c1 = *frm_nxt;
1799
    if (c1 > Maxcode)
1800
      return codecvt_base::error;
1801
    if (c1 < 0x80) {
1802
      *to_nxt = static_cast<uint32_t>(c1);
1803
      ++frm_nxt;
1804
    } else if (c1 < 0xC2) {
1805
      return codecvt_base::error;
1806
    } else if (c1 < 0xE0) {
1807
      if (frm_end - frm_nxt < 2)
1808
        return codecvt_base::partial;
1809
      uint8_t c2 = frm_nxt[1];
1810
      if ((c2 & 0xC0) != 0x80)
1811
        return codecvt_base::error;
1812
      uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) | (c2 & 0x3F));
1813
      if (t > Maxcode)
1814
        return codecvt_base::error;
1815
      *to_nxt = static_cast<uint32_t>(t);
1816
      frm_nxt += 2;
1817
    } else if (c1 < 0xF0) {
1818
      if (frm_end - frm_nxt < 2)
1819
        return codecvt_base::partial;
1820
      uint8_t c2 = frm_nxt[1];
1821
      switch (c1) {
1822
      case 0xE0:
1823
        if ((c2 & 0xE0) != 0xA0)
1824
          return codecvt_base::error;
1825
        break;
1826
      case 0xED:
1827
        if ((c2 & 0xE0) != 0x80)
1828
          return codecvt_base::error;
1829
        break;
1830
      default:
1831
        if ((c2 & 0xC0) != 0x80)
1832
          return codecvt_base::error;
1833
        break;
1834
      }
1835
      if (frm_end - frm_nxt < 3)
1836
        return codecvt_base::partial;
1837
      uint8_t c3 = frm_nxt[2];
1838
      if ((c3 & 0xC0) != 0x80)
1839
        return codecvt_base::error;
1840
      uint16_t t = static_cast<uint16_t>(((c1 & 0x0F) << 12) | ((c2 & 0x3F) << 6) | (c3 & 0x3F));
1841
      if (t > Maxcode)
1842
        return codecvt_base::error;
1843
      *to_nxt = static_cast<uint32_t>(t);
1844
      frm_nxt += 3;
1845
    } else if (c1 < 0xF5) {
1846
      if (frm_end - frm_nxt < 2)
1847
        return codecvt_base::partial;
1848
      uint8_t c2 = frm_nxt[1];
1849
      switch (c1) {
1850
      case 0xF0:
1851
        if (!(0x90 <= c2 && c2 <= 0xBF))
1852
          return codecvt_base::error;
1853
        break;
1854
      case 0xF4:
1855
        if ((c2 & 0xF0) != 0x80)
1856
          return codecvt_base::error;
1857
        break;
1858
      default:
1859
        if ((c2 & 0xC0) != 0x80)
1860
          return codecvt_base::error;
1861
        break;
1862
      }
1863
      if (frm_end - frm_nxt < 3)
1864
        return codecvt_base::partial;
1865
      uint8_t c3 = frm_nxt[2];
1866
      if ((c3 & 0xC0) != 0x80)
1867
        return codecvt_base::error;
1868
      if (frm_end - frm_nxt < 4)
1869
        return codecvt_base::partial;
1870
      uint8_t c4 = frm_nxt[3];
1871
      if ((c4 & 0xC0) != 0x80)
1872
        return codecvt_base::error;
1873
      if (to_end - to_nxt < 2)
1874
        return codecvt_base::partial;
1875
      if ((((c1 & 7UL) << 18) + ((c2 & 0x3FUL) << 12) + ((c3 & 0x3FUL) << 6) + (c4 & 0x3F)) > Maxcode)
1876
        return codecvt_base::error;
1877
      *to_nxt = static_cast<uint32_t>(
1878
          0xD800 | (((((c1 & 0x07) << 2) | ((c2 & 0x30) >> 4)) - 1) << 6) | ((c2 & 0x0F) << 2) | ((c3 & 0x30) >> 4));
1879
      *++to_nxt = static_cast<uint32_t>(0xDC00 | ((c3 & 0x0F) << 6) | (c4 & 0x3F));
1880
      frm_nxt += 4;
1881
    } else {
1882
      return codecvt_base::error;
1883
    }
1884
  }
1885
  return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
1886
}
1887

1888
static int utf8_to_utf16_length(
1889
    const uint8_t* frm,
1890
    const uint8_t* frm_end,
1891
    size_t mx,
1892
    unsigned long Maxcode = 0x10FFFF,
1893
    codecvt_mode mode     = codecvt_mode(0)) {
1894
  const uint8_t* frm_nxt = frm;
1895
  if (mode & consume_header) {
1896
    if (frm_end - frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB && frm_nxt[2] == 0xBF)
1897
      frm_nxt += 3;
1898
  }
1899
  for (size_t nchar16_t = 0; frm_nxt < frm_end && nchar16_t < mx; ++nchar16_t) {
1900
    uint8_t c1 = *frm_nxt;
1901
    if (c1 > Maxcode)
1902
      break;
1903
    if (c1 < 0x80) {
1904
      ++frm_nxt;
1905
    } else if (c1 < 0xC2) {
1906
      break;
1907
    } else if (c1 < 0xE0) {
1908
      if ((frm_end - frm_nxt < 2) || (frm_nxt[1] & 0xC0) != 0x80)
1909
        break;
1910
      uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) | (frm_nxt[1] & 0x3F));
1911
      if (t > Maxcode)
1912
        break;
1913
      frm_nxt += 2;
1914
    } else if (c1 < 0xF0) {
1915
      if (frm_end - frm_nxt < 3)
1916
        break;
1917
      uint8_t c2 = frm_nxt[1];
1918
      uint8_t c3 = frm_nxt[2];
1919
      switch (c1) {
1920
      case 0xE0:
1921
        if ((c2 & 0xE0) != 0xA0)
1922
          return static_cast<int>(frm_nxt - frm);
1923
        break;
1924
      case 0xED:
1925
        if ((c2 & 0xE0) != 0x80)
1926
          return static_cast<int>(frm_nxt - frm);
1927
        break;
1928
      default:
1929
        if ((c2 & 0xC0) != 0x80)
1930
          return static_cast<int>(frm_nxt - frm);
1931
        break;
1932
      }
1933
      if ((c3 & 0xC0) != 0x80)
1934
        break;
1935
      if ((((c1 & 0x0Fu) << 12) | ((c2 & 0x3Fu) << 6) | (c3 & 0x3Fu)) > Maxcode)
1936
        break;
1937
      frm_nxt += 3;
1938
    } else if (c1 < 0xF5) {
1939
      if (frm_end - frm_nxt < 4 || mx - nchar16_t < 2)
1940
        break;
1941
      uint8_t c2 = frm_nxt[1];
1942
      uint8_t c3 = frm_nxt[2];
1943
      uint8_t c4 = frm_nxt[3];
1944
      switch (c1) {
1945
      case 0xF0:
1946
        if (!(0x90 <= c2 && c2 <= 0xBF))
1947
          return static_cast<int>(frm_nxt - frm);
1948
        break;
1949
      case 0xF4:
1950
        if ((c2 & 0xF0) != 0x80)
1951
          return static_cast<int>(frm_nxt - frm);
1952
        break;
1953
      default:
1954
        if ((c2 & 0xC0) != 0x80)
1955
          return static_cast<int>(frm_nxt - frm);
1956
        break;
1957
      }
1958
      if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
1959
        break;
1960
      if ((((c1 & 7UL) << 18) + ((c2 & 0x3FUL) << 12) + ((c3 & 0x3FUL) << 6) + (c4 & 0x3F)) > Maxcode)
1961
        break;
1962
      ++nchar16_t;
1963
      frm_nxt += 4;
1964
    } else {
1965
      break;
1966
    }
1967
  }
1968
  return static_cast<int>(frm_nxt - frm);
1969
}
1970

1971
static codecvt_base::result ucs4_to_utf8(
1972
    const uint32_t* frm,
1973
    const uint32_t* frm_end,
1974
    const uint32_t*& frm_nxt,
1975
    uint8_t* to,
1976
    uint8_t* to_end,
1977
    uint8_t*& to_nxt,
1978
    unsigned long Maxcode = 0x10FFFF,
1979
    codecvt_mode mode     = codecvt_mode(0)) {
1980
  frm_nxt = frm;
1981
  to_nxt  = to;
1982
  if (mode & generate_header) {
1983
    if (to_end - to_nxt < 3)
1984
      return codecvt_base::partial;
1985
    *to_nxt++ = static_cast<uint8_t>(0xEF);
1986
    *to_nxt++ = static_cast<uint8_t>(0xBB);
1987
    *to_nxt++ = static_cast<uint8_t>(0xBF);
1988
  }
1989
  for (; frm_nxt < frm_end; ++frm_nxt) {
1990
    uint32_t wc = *frm_nxt;
1991
    if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode)
1992
      return codecvt_base::error;
1993
    if (wc < 0x000080) {
1994
      if (to_end - to_nxt < 1)
1995
        return codecvt_base::partial;
1996
      *to_nxt++ = static_cast<uint8_t>(wc);
1997
    } else if (wc < 0x000800) {
1998
      if (to_end - to_nxt < 2)
1999
        return codecvt_base::partial;
2000
      *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc >> 6));
2001
      *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x03F));
2002
    } else if (wc < 0x010000) {
2003
      if (to_end - to_nxt < 3)
2004
        return codecvt_base::partial;
2005
      *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc >> 12));
2006
      *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x0FC0) >> 6));
2007
      *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x003F));
2008
    } else // if (wc < 0x110000)
2009
    {
2010
      if (to_end - to_nxt < 4)
2011
        return codecvt_base::partial;
2012
      *to_nxt++ = static_cast<uint8_t>(0xF0 | (wc >> 18));
2013
      *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x03F000) >> 12));
2014
      *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x000FC0) >> 6));
2015
      *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x00003F));
2016
    }
2017
  }
2018
  return codecvt_base::ok;
2019
}
2020

2021
static codecvt_base::result utf8_to_ucs4(
2022
    const uint8_t* frm,
2023
    const uint8_t* frm_end,
2024
    const uint8_t*& frm_nxt,
2025
    uint32_t* to,
2026
    uint32_t* to_end,
2027
    uint32_t*& to_nxt,
2028
    unsigned long Maxcode = 0x10FFFF,
2029
    codecvt_mode mode     = codecvt_mode(0)) {
2030
  frm_nxt = frm;
2031
  to_nxt  = to;
2032
  if (mode & consume_header) {
2033
    if (frm_end - frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB && frm_nxt[2] == 0xBF)
2034
      frm_nxt += 3;
2035
  }
2036
  for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt) {
2037
    uint8_t c1 = static_cast<uint8_t>(*frm_nxt);
2038
    if (c1 < 0x80) {
2039
      if (c1 > Maxcode)
2040
        return codecvt_base::error;
2041
      *to_nxt = static_cast<uint32_t>(c1);
2042
      ++frm_nxt;
2043
    } else if (c1 < 0xC2) {
2044
      return codecvt_base::error;
2045
    } else if (c1 < 0xE0) {
2046
      if (frm_end - frm_nxt < 2)
2047
        return codecvt_base::partial;
2048
      uint8_t c2 = frm_nxt[1];
2049
      if ((c2 & 0xC0) != 0x80)
2050
        return codecvt_base::error;
2051
      uint32_t t = static_cast<uint32_t>(((c1 & 0x1F) << 6) | (c2 & 0x3F));
2052
      if (t > Maxcode)
2053
        return codecvt_base::error;
2054
      *to_nxt = t;
2055
      frm_nxt += 2;
2056
    } else if (c1 < 0xF0) {
2057
      if (frm_end - frm_nxt < 2)
2058
        return codecvt_base::partial;
2059
      uint8_t c2 = frm_nxt[1];
2060
      switch (c1) {
2061
      case 0xE0:
2062
        if ((c2 & 0xE0) != 0xA0)
2063
          return codecvt_base::error;
2064
        break;
2065
      case 0xED:
2066
        if ((c2 & 0xE0) != 0x80)
2067
          return codecvt_base::error;
2068
        break;
2069
      default:
2070
        if ((c2 & 0xC0) != 0x80)
2071
          return codecvt_base::error;
2072
        break;
2073
      }
2074
      if (frm_end - frm_nxt < 3)
2075
        return codecvt_base::partial;
2076
      uint8_t c3 = frm_nxt[2];
2077
      if ((c3 & 0xC0) != 0x80)
2078
        return codecvt_base::error;
2079
      uint32_t t = static_cast<uint32_t>(((c1 & 0x0F) << 12) | ((c2 & 0x3F) << 6) | (c3 & 0x3F));
2080
      if (t > Maxcode)
2081
        return codecvt_base::error;
2082
      *to_nxt = t;
2083
      frm_nxt += 3;
2084
    } else if (c1 < 0xF5) {
2085
      if (frm_end - frm_nxt < 2)
2086
        return codecvt_base::partial;
2087
      uint8_t c2 = frm_nxt[1];
2088
      switch (c1) {
2089
      case 0xF0:
2090
        if (!(0x90 <= c2 && c2 <= 0xBF))
2091
          return codecvt_base::error;
2092
        break;
2093
      case 0xF4:
2094
        if ((c2 & 0xF0) != 0x80)
2095
          return codecvt_base::error;
2096
        break;
2097
      default:
2098
        if ((c2 & 0xC0) != 0x80)
2099
          return codecvt_base::error;
2100
        break;
2101
      }
2102
      if (frm_end - frm_nxt < 3)
2103
        return codecvt_base::partial;
2104
      uint8_t c3 = frm_nxt[2];
2105
      if ((c3 & 0xC0) != 0x80)
2106
        return codecvt_base::error;
2107
      if (frm_end - frm_nxt < 4)
2108
        return codecvt_base::partial;
2109
      uint8_t c4 = frm_nxt[3];
2110
      if ((c4 & 0xC0) != 0x80)
2111
        return codecvt_base::error;
2112
      uint32_t t = static_cast<uint32_t>(((c1 & 0x07) << 18) | ((c2 & 0x3F) << 12) | ((c3 & 0x3F) << 6) | (c4 & 0x3F));
2113
      if (t > Maxcode)
2114
        return codecvt_base::error;
2115
      *to_nxt = t;
2116
      frm_nxt += 4;
2117
    } else {
2118
      return codecvt_base::error;
2119
    }
2120
  }
2121
  return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2122
}
2123

2124
static int utf8_to_ucs4_length(
2125
    const uint8_t* frm,
2126
    const uint8_t* frm_end,
2127
    size_t mx,
2128
    unsigned long Maxcode = 0x10FFFF,
2129
    codecvt_mode mode     = codecvt_mode(0)) {
2130
  const uint8_t* frm_nxt = frm;
2131
  if (mode & consume_header) {
2132
    if (frm_end - frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB && frm_nxt[2] == 0xBF)
2133
      frm_nxt += 3;
2134
  }
2135
  for (size_t nchar32_t = 0; frm_nxt < frm_end && nchar32_t < mx; ++nchar32_t) {
2136
    uint8_t c1 = static_cast<uint8_t>(*frm_nxt);
2137
    if (c1 < 0x80) {
2138
      if (c1 > Maxcode)
2139
        break;
2140
      ++frm_nxt;
2141
    } else if (c1 < 0xC2) {
2142
      break;
2143
    } else if (c1 < 0xE0) {
2144
      if ((frm_end - frm_nxt < 2) || ((frm_nxt[1] & 0xC0) != 0x80))
2145
        break;
2146
      if ((((c1 & 0x1Fu) << 6) | (frm_nxt[1] & 0x3Fu)) > Maxcode)
2147
        break;
2148
      frm_nxt += 2;
2149
    } else if (c1 < 0xF0) {
2150
      if (frm_end - frm_nxt < 3)
2151
        break;
2152
      uint8_t c2 = frm_nxt[1];
2153
      uint8_t c3 = frm_nxt[2];
2154
      switch (c1) {
2155
      case 0xE0:
2156
        if ((c2 & 0xE0) != 0xA0)
2157
          return static_cast<int>(frm_nxt - frm);
2158
        break;
2159
      case 0xED:
2160
        if ((c2 & 0xE0) != 0x80)
2161
          return static_cast<int>(frm_nxt - frm);
2162
        break;
2163
      default:
2164
        if ((c2 & 0xC0) != 0x80)
2165
          return static_cast<int>(frm_nxt - frm);
2166
        break;
2167
      }
2168
      if ((c3 & 0xC0) != 0x80)
2169
        break;
2170
      if ((((c1 & 0x0Fu) << 12) | ((c2 & 0x3Fu) << 6) | (c3 & 0x3Fu)) > Maxcode)
2171
        break;
2172
      frm_nxt += 3;
2173
    } else if (c1 < 0xF5) {
2174
      if (frm_end - frm_nxt < 4)
2175
        break;
2176
      uint8_t c2 = frm_nxt[1];
2177
      uint8_t c3 = frm_nxt[2];
2178
      uint8_t c4 = frm_nxt[3];
2179
      switch (c1) {
2180
      case 0xF0:
2181
        if (!(0x90 <= c2 && c2 <= 0xBF))
2182
          return static_cast<int>(frm_nxt - frm);
2183
        break;
2184
      case 0xF4:
2185
        if ((c2 & 0xF0) != 0x80)
2186
          return static_cast<int>(frm_nxt - frm);
2187
        break;
2188
      default:
2189
        if ((c2 & 0xC0) != 0x80)
2190
          return static_cast<int>(frm_nxt - frm);
2191
        break;
2192
      }
2193
      if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
2194
        break;
2195
      if ((((c1 & 0x07u) << 18) | ((c2 & 0x3Fu) << 12) | ((c3 & 0x3Fu) << 6) | (c4 & 0x3Fu)) > Maxcode)
2196
        break;
2197
      frm_nxt += 4;
2198
    } else {
2199
      break;
2200
    }
2201
  }
2202
  return static_cast<int>(frm_nxt - frm);
2203
}
2204

2205
static codecvt_base::result ucs2_to_utf8(
2206
    const uint16_t* frm,
2207
    const uint16_t* frm_end,
2208
    const uint16_t*& frm_nxt,
2209
    uint8_t* to,
2210
    uint8_t* to_end,
2211
    uint8_t*& to_nxt,
2212
    unsigned long Maxcode = 0x10FFFF,
2213
    codecvt_mode mode     = codecvt_mode(0)) {
2214
  frm_nxt = frm;
2215
  to_nxt  = to;
2216
  if (mode & generate_header) {
2217
    if (to_end - to_nxt < 3)
2218
      return codecvt_base::partial;
2219
    *to_nxt++ = static_cast<uint8_t>(0xEF);
2220
    *to_nxt++ = static_cast<uint8_t>(0xBB);
2221
    *to_nxt++ = static_cast<uint8_t>(0xBF);
2222
  }
2223
  for (; frm_nxt < frm_end; ++frm_nxt) {
2224
    uint16_t wc = *frm_nxt;
2225
    if ((wc & 0xF800) == 0xD800 || wc > Maxcode)
2226
      return codecvt_base::error;
2227
    if (wc < 0x0080) {
2228
      if (to_end - to_nxt < 1)
2229
        return codecvt_base::partial;
2230
      *to_nxt++ = static_cast<uint8_t>(wc);
2231
    } else if (wc < 0x0800) {
2232
      if (to_end - to_nxt < 2)
2233
        return codecvt_base::partial;
2234
      *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc >> 6));
2235
      *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x03F));
2236
    } else // if (wc <= 0xFFFF)
2237
    {
2238
      if (to_end - to_nxt < 3)
2239
        return codecvt_base::partial;
2240
      *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc >> 12));
2241
      *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x0FC0) >> 6));
2242
      *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x003F));
2243
    }
2244
  }
2245
  return codecvt_base::ok;
2246
}
2247

2248
static codecvt_base::result utf8_to_ucs2(
2249
    const uint8_t* frm,
2250
    const uint8_t* frm_end,
2251
    const uint8_t*& frm_nxt,
2252
    uint16_t* to,
2253
    uint16_t* to_end,
2254
    uint16_t*& to_nxt,
2255
    unsigned long Maxcode = 0x10FFFF,
2256
    codecvt_mode mode     = codecvt_mode(0)) {
2257
  frm_nxt = frm;
2258
  to_nxt  = to;
2259
  if (mode & consume_header) {
2260
    if (frm_end - frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB && frm_nxt[2] == 0xBF)
2261
      frm_nxt += 3;
2262
  }
2263
  for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt) {
2264
    uint8_t c1 = static_cast<uint8_t>(*frm_nxt);
2265
    if (c1 < 0x80) {
2266
      if (c1 > Maxcode)
2267
        return codecvt_base::error;
2268
      *to_nxt = static_cast<uint16_t>(c1);
2269
      ++frm_nxt;
2270
    } else if (c1 < 0xC2) {
2271
      return codecvt_base::error;
2272
    } else if (c1 < 0xE0) {
2273
      if (frm_end - frm_nxt < 2)
2274
        return codecvt_base::partial;
2275
      uint8_t c2 = frm_nxt[1];
2276
      if ((c2 & 0xC0) != 0x80)
2277
        return codecvt_base::error;
2278
      uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) | (c2 & 0x3F));
2279
      if (t > Maxcode)
2280
        return codecvt_base::error;
2281
      *to_nxt = t;
2282
      frm_nxt += 2;
2283
    } else if (c1 < 0xF0) {
2284
      if (frm_end - frm_nxt < 2)
2285
        return codecvt_base::partial;
2286
      uint8_t c2 = frm_nxt[1];
2287
      switch (c1) {
2288
      case 0xE0:
2289
        if ((c2 & 0xE0) != 0xA0)
2290
          return codecvt_base::error;
2291
        break;
2292
      case 0xED:
2293
        if ((c2 & 0xE0) != 0x80)
2294
          return codecvt_base::error;
2295
        break;
2296
      default:
2297
        if ((c2 & 0xC0) != 0x80)
2298
          return codecvt_base::error;
2299
        break;
2300
      }
2301
      if (frm_end - frm_nxt < 3)
2302
        return codecvt_base::partial;
2303
      uint8_t c3 = frm_nxt[2];
2304
      if ((c3 & 0xC0) != 0x80)
2305
        return codecvt_base::error;
2306
      uint16_t t = static_cast<uint16_t>(((c1 & 0x0F) << 12) | ((c2 & 0x3F) << 6) | (c3 & 0x3F));
2307
      if (t > Maxcode)
2308
        return codecvt_base::error;
2309
      *to_nxt = t;
2310
      frm_nxt += 3;
2311
    } else {
2312
      return codecvt_base::error;
2313
    }
2314
  }
2315
  return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2316
}
2317

2318
static int utf8_to_ucs2_length(
2319
    const uint8_t* frm,
2320
    const uint8_t* frm_end,
2321
    size_t mx,
2322
    unsigned long Maxcode = 0x10FFFF,
2323
    codecvt_mode mode     = codecvt_mode(0)) {
2324
  const uint8_t* frm_nxt = frm;
2325
  if (mode & consume_header) {
2326
    if (frm_end - frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB && frm_nxt[2] == 0xBF)
2327
      frm_nxt += 3;
2328
  }
2329
  for (size_t nchar32_t = 0; frm_nxt < frm_end && nchar32_t < mx; ++nchar32_t) {
2330
    uint8_t c1 = static_cast<uint8_t>(*frm_nxt);
2331
    if (c1 < 0x80) {
2332
      if (c1 > Maxcode)
2333
        break;
2334
      ++frm_nxt;
2335
    } else if (c1 < 0xC2) {
2336
      break;
2337
    } else if (c1 < 0xE0) {
2338
      if ((frm_end - frm_nxt < 2) || ((frm_nxt[1] & 0xC0) != 0x80))
2339
        break;
2340
      if ((((c1 & 0x1Fu) << 6) | (frm_nxt[1] & 0x3Fu)) > Maxcode)
2341
        break;
2342
      frm_nxt += 2;
2343
    } else if (c1 < 0xF0) {
2344
      if (frm_end - frm_nxt < 3)
2345
        break;
2346
      uint8_t c2 = frm_nxt[1];
2347
      uint8_t c3 = frm_nxt[2];
2348
      switch (c1) {
2349
      case 0xE0:
2350
        if ((c2 & 0xE0) != 0xA0)
2351
          return static_cast<int>(frm_nxt - frm);
2352
        break;
2353
      case 0xED:
2354
        if ((c2 & 0xE0) != 0x80)
2355
          return static_cast<int>(frm_nxt - frm);
2356
        break;
2357
      default:
2358
        if ((c2 & 0xC0) != 0x80)
2359
          return static_cast<int>(frm_nxt - frm);
2360
        break;
2361
      }
2362
      if ((c3 & 0xC0) != 0x80)
2363
        break;
2364
      if ((((c1 & 0x0Fu) << 12) | ((c2 & 0x3Fu) << 6) | (c3 & 0x3Fu)) > Maxcode)
2365
        break;
2366
      frm_nxt += 3;
2367
    } else {
2368
      break;
2369
    }
2370
  }
2371
  return static_cast<int>(frm_nxt - frm);
2372
}
2373

2374
static codecvt_base::result ucs4_to_utf16be(
2375
    const uint32_t* frm,
2376
    const uint32_t* frm_end,
2377
    const uint32_t*& frm_nxt,
2378
    uint8_t* to,
2379
    uint8_t* to_end,
2380
    uint8_t*& to_nxt,
2381
    unsigned long Maxcode = 0x10FFFF,
2382
    codecvt_mode mode     = codecvt_mode(0)) {
2383
  frm_nxt = frm;
2384
  to_nxt  = to;
2385
  if (mode & generate_header) {
2386
    if (to_end - to_nxt < 2)
2387
      return codecvt_base::partial;
2388
    *to_nxt++ = static_cast<uint8_t>(0xFE);
2389
    *to_nxt++ = static_cast<uint8_t>(0xFF);
2390
  }
2391
  for (; frm_nxt < frm_end; ++frm_nxt) {
2392
    uint32_t wc = *frm_nxt;
2393
    if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode)
2394
      return codecvt_base::error;
2395
    if (wc < 0x010000) {
2396
      if (to_end - to_nxt < 2)
2397
        return codecvt_base::partial;
2398
      *to_nxt++ = static_cast<uint8_t>(wc >> 8);
2399
      *to_nxt++ = static_cast<uint8_t>(wc);
2400
    } else {
2401
      if (to_end - to_nxt < 4)
2402
        return codecvt_base::partial;
2403
      uint16_t t = static_cast<uint16_t>(0xD800 | ((((wc & 0x1F0000) >> 16) - 1) << 6) | ((wc & 0x00FC00) >> 10));
2404
      *to_nxt++  = static_cast<uint8_t>(t >> 8);
2405
      *to_nxt++  = static_cast<uint8_t>(t);
2406
      t          = static_cast<uint16_t>(0xDC00 | (wc & 0x03FF));
2407
      *to_nxt++  = static_cast<uint8_t>(t >> 8);
2408
      *to_nxt++  = static_cast<uint8_t>(t);
2409
    }
2410
  }
2411
  return codecvt_base::ok;
2412
}
2413

2414
static codecvt_base::result utf16be_to_ucs4(
2415
    const uint8_t* frm,
2416
    const uint8_t* frm_end,
2417
    const uint8_t*& frm_nxt,
2418
    uint32_t* to,
2419
    uint32_t* to_end,
2420
    uint32_t*& to_nxt,
2421
    unsigned long Maxcode = 0x10FFFF,
2422
    codecvt_mode mode     = codecvt_mode(0)) {
2423
  frm_nxt = frm;
2424
  to_nxt  = to;
2425
  if (mode & consume_header) {
2426
    if (frm_end - frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)
2427
      frm_nxt += 2;
2428
  }
2429
  for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt) {
2430
    uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]);
2431
    if ((c1 & 0xFC00) == 0xDC00)
2432
      return codecvt_base::error;
2433
    if ((c1 & 0xFC00) != 0xD800) {
2434
      if (c1 > Maxcode)
2435
        return codecvt_base::error;
2436
      *to_nxt = static_cast<uint32_t>(c1);
2437
      frm_nxt += 2;
2438
    } else {
2439
      if (frm_end - frm_nxt < 4)
2440
        return codecvt_base::partial;
2441
      uint16_t c2 = static_cast<uint16_t>(frm_nxt[2] << 8 | frm_nxt[3]);
2442
      if ((c2 & 0xFC00) != 0xDC00)
2443
        return codecvt_base::error;
2444
      uint32_t t = static_cast<uint32_t>(((((c1 & 0x03C0) >> 6) + 1) << 16) | ((c1 & 0x003F) << 10) | (c2 & 0x03FF));
2445
      if (t > Maxcode)
2446
        return codecvt_base::error;
2447
      *to_nxt = t;
2448
      frm_nxt += 4;
2449
    }
2450
  }
2451
  return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2452
}
2453

2454
static int utf16be_to_ucs4_length(
2455
    const uint8_t* frm,
2456
    const uint8_t* frm_end,
2457
    size_t mx,
2458
    unsigned long Maxcode = 0x10FFFF,
2459
    codecvt_mode mode     = codecvt_mode(0)) {
2460
  const uint8_t* frm_nxt = frm;
2461
  if (mode & consume_header) {
2462
    if (frm_end - frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)
2463
      frm_nxt += 2;
2464
  }
2465
  for (size_t nchar32_t = 0; frm_nxt < frm_end - 1 && nchar32_t < mx; ++nchar32_t) {
2466
    uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]);
2467
    if ((c1 & 0xFC00) == 0xDC00)
2468
      break;
2469
    if ((c1 & 0xFC00) != 0xD800) {
2470
      if (c1 > Maxcode)
2471
        break;
2472
      frm_nxt += 2;
2473
    } else {
2474
      if (frm_end - frm_nxt < 4)
2475
        break;
2476
      uint16_t c2 = static_cast<uint16_t>(frm_nxt[2] << 8 | frm_nxt[3]);
2477
      if ((c2 & 0xFC00) != 0xDC00)
2478
        break;
2479
      uint32_t t = static_cast<uint32_t>(((((c1 & 0x03C0) >> 6) + 1) << 16) | ((c1 & 0x003F) << 10) | (c2 & 0x03FF));
2480
      if (t > Maxcode)
2481
        break;
2482
      frm_nxt += 4;
2483
    }
2484
  }
2485
  return static_cast<int>(frm_nxt - frm);
2486
}
2487

2488
static codecvt_base::result ucs4_to_utf16le(
2489
    const uint32_t* frm,
2490
    const uint32_t* frm_end,
2491
    const uint32_t*& frm_nxt,
2492
    uint8_t* to,
2493
    uint8_t* to_end,
2494
    uint8_t*& to_nxt,
2495
    unsigned long Maxcode = 0x10FFFF,
2496
    codecvt_mode mode     = codecvt_mode(0)) {
2497
  frm_nxt = frm;
2498
  to_nxt  = to;
2499
  if (mode & generate_header) {
2500
    if (to_end - to_nxt < 2)
2501
      return codecvt_base::partial;
2502
    *to_nxt++ = static_cast<uint8_t>(0xFF);
2503
    *to_nxt++ = static_cast<uint8_t>(0xFE);
2504
  }
2505
  for (; frm_nxt < frm_end; ++frm_nxt) {
2506
    uint32_t wc = *frm_nxt;
2507
    if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode)
2508
      return codecvt_base::error;
2509
    if (wc < 0x010000) {
2510
      if (to_end - to_nxt < 2)
2511
        return codecvt_base::partial;
2512
      *to_nxt++ = static_cast<uint8_t>(wc);
2513
      *to_nxt++ = static_cast<uint8_t>(wc >> 8);
2514
    } else {
2515
      if (to_end - to_nxt < 4)
2516
        return codecvt_base::partial;
2517
      uint16_t t = static_cast<uint16_t>(0xD800 | ((((wc & 0x1F0000) >> 16) - 1) << 6) | ((wc & 0x00FC00) >> 10));
2518
      *to_nxt++  = static_cast<uint8_t>(t);
2519
      *to_nxt++  = static_cast<uint8_t>(t >> 8);
2520
      t          = static_cast<uint16_t>(0xDC00 | (wc & 0x03FF));
2521
      *to_nxt++  = static_cast<uint8_t>(t);
2522
      *to_nxt++  = static_cast<uint8_t>(t >> 8);
2523
    }
2524
  }
2525
  return codecvt_base::ok;
2526
}
2527

2528
static codecvt_base::result utf16le_to_ucs4(
2529
    const uint8_t* frm,
2530
    const uint8_t* frm_end,
2531
    const uint8_t*& frm_nxt,
2532
    uint32_t* to,
2533
    uint32_t* to_end,
2534
    uint32_t*& to_nxt,
2535
    unsigned long Maxcode = 0x10FFFF,
2536
    codecvt_mode mode     = codecvt_mode(0)) {
2537
  frm_nxt = frm;
2538
  to_nxt  = to;
2539
  if (mode & consume_header) {
2540
    if (frm_end - frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)
2541
      frm_nxt += 2;
2542
  }
2543
  for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt) {
2544
    uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]);
2545
    if ((c1 & 0xFC00) == 0xDC00)
2546
      return codecvt_base::error;
2547
    if ((c1 & 0xFC00) != 0xD800) {
2548
      if (c1 > Maxcode)
2549
        return codecvt_base::error;
2550
      *to_nxt = static_cast<uint32_t>(c1);
2551
      frm_nxt += 2;
2552
    } else {
2553
      if (frm_end - frm_nxt < 4)
2554
        return codecvt_base::partial;
2555
      uint16_t c2 = static_cast<uint16_t>(frm_nxt[3] << 8 | frm_nxt[2]);
2556
      if ((c2 & 0xFC00) != 0xDC00)
2557
        return codecvt_base::error;
2558
      uint32_t t = static_cast<uint32_t>(((((c1 & 0x03C0) >> 6) + 1) << 16) | ((c1 & 0x003F) << 10) | (c2 & 0x03FF));
2559
      if (t > Maxcode)
2560
        return codecvt_base::error;
2561
      *to_nxt = t;
2562
      frm_nxt += 4;
2563
    }
2564
  }
2565
  return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2566
}
2567

2568
static int utf16le_to_ucs4_length(
2569
    const uint8_t* frm,
2570
    const uint8_t* frm_end,
2571
    size_t mx,
2572
    unsigned long Maxcode = 0x10FFFF,
2573
    codecvt_mode mode     = codecvt_mode(0)) {
2574
  const uint8_t* frm_nxt = frm;
2575
  if (mode & consume_header) {
2576
    if (frm_end - frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)
2577
      frm_nxt += 2;
2578
  }
2579
  for (size_t nchar32_t = 0; frm_nxt < frm_end - 1 && nchar32_t < mx; ++nchar32_t) {
2580
    uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]);
2581
    if ((c1 & 0xFC00) == 0xDC00)
2582
      break;
2583
    if ((c1 & 0xFC00) != 0xD800) {
2584
      if (c1 > Maxcode)
2585
        break;
2586
      frm_nxt += 2;
2587
    } else {
2588
      if (frm_end - frm_nxt < 4)
2589
        break;
2590
      uint16_t c2 = static_cast<uint16_t>(frm_nxt[3] << 8 | frm_nxt[2]);
2591
      if ((c2 & 0xFC00) != 0xDC00)
2592
        break;
2593
      uint32_t t = static_cast<uint32_t>(((((c1 & 0x03C0) >> 6) + 1) << 16) | ((c1 & 0x003F) << 10) | (c2 & 0x03FF));
2594
      if (t > Maxcode)
2595
        break;
2596
      frm_nxt += 4;
2597
    }
2598
  }
2599
  return static_cast<int>(frm_nxt - frm);
2600
}
2601

2602
static codecvt_base::result ucs2_to_utf16be(
2603
    const uint16_t* frm,
2604
    const uint16_t* frm_end,
2605
    const uint16_t*& frm_nxt,
2606
    uint8_t* to,
2607
    uint8_t* to_end,
2608
    uint8_t*& to_nxt,
2609
    unsigned long Maxcode = 0x10FFFF,
2610
    codecvt_mode mode     = codecvt_mode(0)) {
2611
  frm_nxt = frm;
2612
  to_nxt  = to;
2613
  if (mode & generate_header) {
2614
    if (to_end - to_nxt < 2)
2615
      return codecvt_base::partial;
2616
    *to_nxt++ = static_cast<uint8_t>(0xFE);
2617
    *to_nxt++ = static_cast<uint8_t>(0xFF);
2618
  }
2619
  for (; frm_nxt < frm_end; ++frm_nxt) {
2620
    uint16_t wc = *frm_nxt;
2621
    if ((wc & 0xF800) == 0xD800 || wc > Maxcode)
2622
      return codecvt_base::error;
2623
    if (to_end - to_nxt < 2)
2624
      return codecvt_base::partial;
2625
    *to_nxt++ = static_cast<uint8_t>(wc >> 8);
2626
    *to_nxt++ = static_cast<uint8_t>(wc);
2627
  }
2628
  return codecvt_base::ok;
2629
}
2630

2631
static codecvt_base::result utf16be_to_ucs2(
2632
    const uint8_t* frm,
2633
    const uint8_t* frm_end,
2634
    const uint8_t*& frm_nxt,
2635
    uint16_t* to,
2636
    uint16_t* to_end,
2637
    uint16_t*& to_nxt,
2638
    unsigned long Maxcode = 0x10FFFF,
2639
    codecvt_mode mode     = codecvt_mode(0)) {
2640
  frm_nxt = frm;
2641
  to_nxt  = to;
2642
  if (mode & consume_header) {
2643
    if (frm_end - frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)
2644
      frm_nxt += 2;
2645
  }
2646
  for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt) {
2647
    uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]);
2648
    if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
2649
      return codecvt_base::error;
2650
    *to_nxt = c1;
2651
    frm_nxt += 2;
2652
  }
2653
  return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2654
}
2655

2656
static int utf16be_to_ucs2_length(
2657
    const uint8_t* frm,
2658
    const uint8_t* frm_end,
2659
    size_t mx,
2660
    unsigned long Maxcode = 0x10FFFF,
2661
    codecvt_mode mode     = codecvt_mode(0)) {
2662
  const uint8_t* frm_nxt = frm;
2663
  if (mode & consume_header) {
2664
    if (frm_end - frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)
2665
      frm_nxt += 2;
2666
  }
2667
  for (size_t nchar16_t = 0; frm_nxt < frm_end - 1 && nchar16_t < mx; ++nchar16_t) {
2668
    uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]);
2669
    if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
2670
      break;
2671
    frm_nxt += 2;
2672
  }
2673
  return static_cast<int>(frm_nxt - frm);
2674
}
2675

2676
static codecvt_base::result ucs2_to_utf16le(
2677
    const uint16_t* frm,
2678
    const uint16_t* frm_end,
2679
    const uint16_t*& frm_nxt,
2680
    uint8_t* to,
2681
    uint8_t* to_end,
2682
    uint8_t*& to_nxt,
2683
    unsigned long Maxcode = 0x10FFFF,
2684
    codecvt_mode mode     = codecvt_mode(0)) {
2685
  frm_nxt = frm;
2686
  to_nxt  = to;
2687
  if (mode & generate_header) {
2688
    if (to_end - to_nxt < 2)
2689
      return codecvt_base::partial;
2690
    *to_nxt++ = static_cast<uint8_t>(0xFF);
2691
    *to_nxt++ = static_cast<uint8_t>(0xFE);
2692
  }
2693
  for (; frm_nxt < frm_end; ++frm_nxt) {
2694
    uint16_t wc = *frm_nxt;
2695
    if ((wc & 0xF800) == 0xD800 || wc > Maxcode)
2696
      return codecvt_base::error;
2697
    if (to_end - to_nxt < 2)
2698
      return codecvt_base::partial;
2699
    *to_nxt++ = static_cast<uint8_t>(wc);
2700
    *to_nxt++ = static_cast<uint8_t>(wc >> 8);
2701
  }
2702
  return codecvt_base::ok;
2703
}
2704

2705
static codecvt_base::result utf16le_to_ucs2(
2706
    const uint8_t* frm,
2707
    const uint8_t* frm_end,
2708
    const uint8_t*& frm_nxt,
2709
    uint16_t* to,
2710
    uint16_t* to_end,
2711
    uint16_t*& to_nxt,
2712
    unsigned long Maxcode = 0x10FFFF,
2713
    codecvt_mode mode     = codecvt_mode(0)) {
2714
  frm_nxt = frm;
2715
  to_nxt  = to;
2716
  if (mode & consume_header) {
2717
    if (frm_end - frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)
2718
      frm_nxt += 2;
2719
  }
2720
  for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt) {
2721
    uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]);
2722
    if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
2723
      return codecvt_base::error;
2724
    *to_nxt = c1;
2725
    frm_nxt += 2;
2726
  }
2727
  return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2728
}
2729

2730
static int utf16le_to_ucs2_length(
2731
    const uint8_t* frm,
2732
    const uint8_t* frm_end,
2733
    size_t mx,
2734
    unsigned long Maxcode = 0x10FFFF,
2735
    codecvt_mode mode     = codecvt_mode(0)) {
2736
  const uint8_t* frm_nxt = frm;
2737
  frm_nxt                = frm;
2738
  if (mode & consume_header) {
2739
    if (frm_end - frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)
2740
      frm_nxt += 2;
2741
  }
2742
  for (size_t nchar16_t = 0; frm_nxt < frm_end - 1 && nchar16_t < mx; ++nchar16_t) {
2743
    uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]);
2744
    if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
2745
      break;
2746
    frm_nxt += 2;
2747
  }
2748
  return static_cast<int>(frm_nxt - frm);
2749
}
2750

2751
_LIBCPP_SUPPRESS_DEPRECATED_POP
2752

2753
// template <> class codecvt<char16_t, char, mbstate_t>
2754

2755
constinit locale::id codecvt<char16_t, char, mbstate_t>::id;
2756

2757
codecvt<char16_t, char, mbstate_t>::~codecvt() {}
2758

2759
codecvt<char16_t, char, mbstate_t>::result codecvt<char16_t, char, mbstate_t>::do_out(
2760
    state_type&,
2761
    const intern_type* frm,
2762
    const intern_type* frm_end,
2763
    const intern_type*& frm_nxt,
2764
    extern_type* to,
2765
    extern_type* to_end,
2766
    extern_type*& to_nxt) const {
2767
  const uint16_t* _frm     = reinterpret_cast<const uint16_t*>(frm);
2768
  const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
2769
  const uint16_t* _frm_nxt = _frm;
2770
  uint8_t* _to             = reinterpret_cast<uint8_t*>(to);
2771
  uint8_t* _to_end         = reinterpret_cast<uint8_t*>(to_end);
2772
  uint8_t* _to_nxt         = _to;
2773
  result r                 = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
2774
  frm_nxt                  = frm + (_frm_nxt - _frm);
2775
  to_nxt                   = to + (_to_nxt - _to);
2776
  return r;
2777
}
2778

2779
codecvt<char16_t, char, mbstate_t>::result codecvt<char16_t, char, mbstate_t>::do_in(
2780
    state_type&,
2781
    const extern_type* frm,
2782
    const extern_type* frm_end,
2783
    const extern_type*& frm_nxt,
2784
    intern_type* to,
2785
    intern_type* to_end,
2786
    intern_type*& to_nxt) const {
2787
  const uint8_t* _frm     = reinterpret_cast<const uint8_t*>(frm);
2788
  const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
2789
  const uint8_t* _frm_nxt = _frm;
2790
  uint16_t* _to           = reinterpret_cast<uint16_t*>(to);
2791
  uint16_t* _to_end       = reinterpret_cast<uint16_t*>(to_end);
2792
  uint16_t* _to_nxt       = _to;
2793
  result r                = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
2794
  frm_nxt                 = frm + (_frm_nxt - _frm);
2795
  to_nxt                  = to + (_to_nxt - _to);
2796
  return r;
2797
}
2798

2799
codecvt<char16_t, char, mbstate_t>::result
2800
codecvt<char16_t, char, mbstate_t>::do_unshift(state_type&, extern_type* to, extern_type*, extern_type*& to_nxt) const {
2801
  to_nxt = to;
2802
  return noconv;
2803
}
2804

2805
int codecvt<char16_t, char, mbstate_t>::do_encoding() const noexcept { return 0; }
2806

2807
bool codecvt<char16_t, char, mbstate_t>::do_always_noconv() const noexcept { return false; }
2808

2809
int codecvt<char16_t, char, mbstate_t>::do_length(
2810
    state_type&, const extern_type* frm, const extern_type* frm_end, size_t mx) const {
2811
  const uint8_t* _frm     = reinterpret_cast<const uint8_t*>(frm);
2812
  const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
2813
  return utf8_to_utf16_length(_frm, _frm_end, mx);
2814
}
2815

2816
int codecvt<char16_t, char, mbstate_t>::do_max_length() const noexcept { return 4; }
2817

2818
#ifndef _LIBCPP_HAS_NO_CHAR8_T
2819

2820
// template <> class codecvt<char16_t, char8_t, mbstate_t>
2821

2822
constinit locale::id codecvt<char16_t, char8_t, mbstate_t>::id;
2823

2824
codecvt<char16_t, char8_t, mbstate_t>::~codecvt() {}
2825

2826
codecvt<char16_t, char8_t, mbstate_t>::result codecvt<char16_t, char8_t, mbstate_t>::do_out(
2827
    state_type&,
2828
    const intern_type* frm,
2829
    const intern_type* frm_end,
2830
    const intern_type*& frm_nxt,
2831
    extern_type* to,
2832
    extern_type* to_end,
2833
    extern_type*& to_nxt) const {
2834
  const uint16_t* _frm     = reinterpret_cast<const uint16_t*>(frm);
2835
  const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
2836
  const uint16_t* _frm_nxt = _frm;
2837
  uint8_t* _to             = reinterpret_cast<uint8_t*>(to);
2838
  uint8_t* _to_end         = reinterpret_cast<uint8_t*>(to_end);
2839
  uint8_t* _to_nxt         = _to;
2840
  result r                 = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
2841
  frm_nxt                  = frm + (_frm_nxt - _frm);
2842
  to_nxt                   = to + (_to_nxt - _to);
2843
  return r;
2844
}
2845

2846
codecvt<char16_t, char8_t, mbstate_t>::result codecvt<char16_t, char8_t, mbstate_t>::do_in(
2847
    state_type&,
2848
    const extern_type* frm,
2849
    const extern_type* frm_end,
2850
    const extern_type*& frm_nxt,
2851
    intern_type* to,
2852
    intern_type* to_end,
2853
    intern_type*& to_nxt) const {
2854
  const uint8_t* _frm     = reinterpret_cast<const uint8_t*>(frm);
2855
  const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
2856
  const uint8_t* _frm_nxt = _frm;
2857
  uint16_t* _to           = reinterpret_cast<uint16_t*>(to);
2858
  uint16_t* _to_end       = reinterpret_cast<uint16_t*>(to_end);
2859
  uint16_t* _to_nxt       = _to;
2860
  result r                = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
2861
  frm_nxt                 = frm + (_frm_nxt - _frm);
2862
  to_nxt                  = to + (_to_nxt - _to);
2863
  return r;
2864
}
2865

2866
codecvt<char16_t, char8_t, mbstate_t>::result codecvt<char16_t, char8_t, mbstate_t>::do_unshift(
2867
    state_type&, extern_type* to, extern_type*, extern_type*& to_nxt) const {
2868
  to_nxt = to;
2869
  return noconv;
2870
}
2871

2872
int codecvt<char16_t, char8_t, mbstate_t>::do_encoding() const noexcept { return 0; }
2873

2874
bool codecvt<char16_t, char8_t, mbstate_t>::do_always_noconv() const noexcept { return false; }
2875

2876
int codecvt<char16_t, char8_t, mbstate_t>::do_length(
2877
    state_type&, const extern_type* frm, const extern_type* frm_end, size_t mx) const {
2878
  const uint8_t* _frm     = reinterpret_cast<const uint8_t*>(frm);
2879
  const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
2880
  return utf8_to_utf16_length(_frm, _frm_end, mx);
2881
}
2882

2883
int codecvt<char16_t, char8_t, mbstate_t>::do_max_length() const noexcept { return 4; }
2884

2885
#endif
2886

2887
// template <> class codecvt<char32_t, char, mbstate_t>
2888

2889
constinit locale::id codecvt<char32_t, char, mbstate_t>::id;
2890

2891
codecvt<char32_t, char, mbstate_t>::~codecvt() {}
2892

2893
codecvt<char32_t, char, mbstate_t>::result codecvt<char32_t, char, mbstate_t>::do_out(
2894
    state_type&,
2895
    const intern_type* frm,
2896
    const intern_type* frm_end,
2897
    const intern_type*& frm_nxt,
2898
    extern_type* to,
2899
    extern_type* to_end,
2900
    extern_type*& to_nxt) const {
2901
  const uint32_t* _frm     = reinterpret_cast<const uint32_t*>(frm);
2902
  const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
2903
  const uint32_t* _frm_nxt = _frm;
2904
  uint8_t* _to             = reinterpret_cast<uint8_t*>(to);
2905
  uint8_t* _to_end         = reinterpret_cast<uint8_t*>(to_end);
2906
  uint8_t* _to_nxt         = _to;
2907
  result r                 = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
2908
  frm_nxt                  = frm + (_frm_nxt - _frm);
2909
  to_nxt                   = to + (_to_nxt - _to);
2910
  return r;
2911
}
2912

2913
codecvt<char32_t, char, mbstate_t>::result codecvt<char32_t, char, mbstate_t>::do_in(
2914
    state_type&,
2915
    const extern_type* frm,
2916
    const extern_type* frm_end,
2917
    const extern_type*& frm_nxt,
2918
    intern_type* to,
2919
    intern_type* to_end,
2920
    intern_type*& to_nxt) const {
2921
  const uint8_t* _frm     = reinterpret_cast<const uint8_t*>(frm);
2922
  const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
2923
  const uint8_t* _frm_nxt = _frm;
2924
  uint32_t* _to           = reinterpret_cast<uint32_t*>(to);
2925
  uint32_t* _to_end       = reinterpret_cast<uint32_t*>(to_end);
2926
  uint32_t* _to_nxt       = _to;
2927
  result r                = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
2928
  frm_nxt                 = frm + (_frm_nxt - _frm);
2929
  to_nxt                  = to + (_to_nxt - _to);
2930
  return r;
2931
}
2932

2933
codecvt<char32_t, char, mbstate_t>::result
2934
codecvt<char32_t, char, mbstate_t>::do_unshift(state_type&, extern_type* to, extern_type*, extern_type*& to_nxt) const {
2935
  to_nxt = to;
2936
  return noconv;
2937
}
2938

2939
int codecvt<char32_t, char, mbstate_t>::do_encoding() const noexcept { return 0; }
2940

2941
bool codecvt<char32_t, char, mbstate_t>::do_always_noconv() const noexcept { return false; }
2942

2943
int codecvt<char32_t, char, mbstate_t>::do_length(
2944
    state_type&, const extern_type* frm, const extern_type* frm_end, size_t mx) const {
2945
  const uint8_t* _frm     = reinterpret_cast<const uint8_t*>(frm);
2946
  const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
2947
  return utf8_to_ucs4_length(_frm, _frm_end, mx);
2948
}
2949

2950
int codecvt<char32_t, char, mbstate_t>::do_max_length() const noexcept { return 4; }
2951

2952
#ifndef _LIBCPP_HAS_NO_CHAR8_T
2953

2954
// template <> class codecvt<char32_t, char8_t, mbstate_t>
2955

2956
constinit locale::id codecvt<char32_t, char8_t, mbstate_t>::id;
2957

2958
codecvt<char32_t, char8_t, mbstate_t>::~codecvt() {}
2959

2960
codecvt<char32_t, char8_t, mbstate_t>::result codecvt<char32_t, char8_t, mbstate_t>::do_out(
2961
    state_type&,
2962
    const intern_type* frm,
2963
    const intern_type* frm_end,
2964
    const intern_type*& frm_nxt,
2965
    extern_type* to,
2966
    extern_type* to_end,
2967
    extern_type*& to_nxt) const {
2968
  const uint32_t* _frm     = reinterpret_cast<const uint32_t*>(frm);
2969
  const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
2970
  const uint32_t* _frm_nxt = _frm;
2971
  uint8_t* _to             = reinterpret_cast<uint8_t*>(to);
2972
  uint8_t* _to_end         = reinterpret_cast<uint8_t*>(to_end);
2973
  uint8_t* _to_nxt         = _to;
2974
  result r                 = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
2975
  frm_nxt                  = frm + (_frm_nxt - _frm);
2976
  to_nxt                   = to + (_to_nxt - _to);
2977
  return r;
2978
}
2979

2980
codecvt<char32_t, char8_t, mbstate_t>::result codecvt<char32_t, char8_t, mbstate_t>::do_in(
2981
    state_type&,
2982
    const extern_type* frm,
2983
    const extern_type* frm_end,
2984
    const extern_type*& frm_nxt,
2985
    intern_type* to,
2986
    intern_type* to_end,
2987
    intern_type*& to_nxt) const {
2988
  const uint8_t* _frm     = reinterpret_cast<const uint8_t*>(frm);
2989
  const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
2990
  const uint8_t* _frm_nxt = _frm;
2991
  uint32_t* _to           = reinterpret_cast<uint32_t*>(to);
2992
  uint32_t* _to_end       = reinterpret_cast<uint32_t*>(to_end);
2993
  uint32_t* _to_nxt       = _to;
2994
  result r                = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
2995
  frm_nxt                 = frm + (_frm_nxt - _frm);
2996
  to_nxt                  = to + (_to_nxt - _to);
2997
  return r;
2998
}
2999

3000
codecvt<char32_t, char8_t, mbstate_t>::result codecvt<char32_t, char8_t, mbstate_t>::do_unshift(
3001
    state_type&, extern_type* to, extern_type*, extern_type*& to_nxt) const {
3002
  to_nxt = to;
3003
  return noconv;
3004
}
3005

3006
int codecvt<char32_t, char8_t, mbstate_t>::do_encoding() const noexcept { return 0; }
3007

3008
bool codecvt<char32_t, char8_t, mbstate_t>::do_always_noconv() const noexcept { return false; }
3009

3010
int codecvt<char32_t, char8_t, mbstate_t>::do_length(
3011
    state_type&, const extern_type* frm, const extern_type* frm_end, size_t mx) const {
3012
  const uint8_t* _frm     = reinterpret_cast<const uint8_t*>(frm);
3013
  const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3014
  return utf8_to_ucs4_length(_frm, _frm_end, mx);
3015
}
3016

3017
int codecvt<char32_t, char8_t, mbstate_t>::do_max_length() const noexcept { return 4; }
3018

3019
#endif
3020

3021
// __codecvt_utf8<wchar_t>
3022

3023
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
3024
__codecvt_utf8<wchar_t>::result __codecvt_utf8<wchar_t>::do_out(
3025
    state_type&,
3026
    const intern_type* frm,
3027
    const intern_type* frm_end,
3028
    const intern_type*& frm_nxt,
3029
    extern_type* to,
3030
    extern_type* to_end,
3031
    extern_type*& to_nxt) const {
3032
#  if defined(_LIBCPP_SHORT_WCHAR)
3033
  const uint16_t* _frm     = reinterpret_cast<const uint16_t*>(frm);
3034
  const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3035
  const uint16_t* _frm_nxt = _frm;
3036
#  else
3037
  const uint32_t* _frm     = reinterpret_cast<const uint32_t*>(frm);
3038
  const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3039
  const uint32_t* _frm_nxt = _frm;
3040
#  endif
3041
  uint8_t* _to     = reinterpret_cast<uint8_t*>(to);
3042
  uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3043
  uint8_t* _to_nxt = _to;
3044
#  if defined(_LIBCPP_SHORT_WCHAR)
3045
  result r = ucs2_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);
3046
#  else
3047
  result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);
3048
#  endif
3049
  frm_nxt = frm + (_frm_nxt - _frm);
3050
  to_nxt  = to + (_to_nxt - _to);
3051
  return r;
3052
}
3053

3054
__codecvt_utf8<wchar_t>::result __codecvt_utf8<wchar_t>::do_in(
3055
    state_type&,
3056
    const extern_type* frm,
3057
    const extern_type* frm_end,
3058
    const extern_type*& frm_nxt,
3059
    intern_type* to,
3060
    intern_type* to_end,
3061
    intern_type*& to_nxt) const {
3062
  const uint8_t* _frm     = reinterpret_cast<const uint8_t*>(frm);
3063
  const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3064
  const uint8_t* _frm_nxt = _frm;
3065
#  if defined(_LIBCPP_SHORT_WCHAR)
3066
  uint16_t* _to     = reinterpret_cast<uint16_t*>(to);
3067
  uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3068
  uint16_t* _to_nxt = _to;
3069
  result r          = utf8_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);
3070
#  else
3071
  uint32_t* _to     = reinterpret_cast<uint32_t*>(to);
3072
  uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3073
  uint32_t* _to_nxt = _to;
3074
  result r          = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);
3075
#  endif
3076
  frm_nxt = frm + (_frm_nxt - _frm);
3077
  to_nxt  = to + (_to_nxt - _to);
3078
  return r;
3079
}
3080

3081
__codecvt_utf8<wchar_t>::result
3082
__codecvt_utf8<wchar_t>::do_unshift(state_type&, extern_type* to, extern_type*, extern_type*& to_nxt) const {
3083
  to_nxt = to;
3084
  return noconv;
3085
}
3086

3087
int __codecvt_utf8<wchar_t>::do_encoding() const noexcept { return 0; }
3088

3089
bool __codecvt_utf8<wchar_t>::do_always_noconv() const noexcept { return false; }
3090

3091
int __codecvt_utf8<wchar_t>::do_length(
3092
    state_type&, const extern_type* frm, const extern_type* frm_end, size_t mx) const {
3093
  const uint8_t* _frm     = reinterpret_cast<const uint8_t*>(frm);
3094
  const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3095
#  if defined(_LIBCPP_SHORT_WCHAR)
3096
  return utf8_to_ucs2_length(_frm, _frm_end, mx, __maxcode_, __mode_);
3097
#  else
3098
  return utf8_to_ucs4_length(_frm, _frm_end, mx, __maxcode_, __mode_);
3099
#  endif
3100
}
3101

3102
_LIBCPP_SUPPRESS_DEPRECATED_PUSH
3103
int __codecvt_utf8<wchar_t>::do_max_length() const noexcept {
3104
#  if defined(_LIBCPP_SHORT_WCHAR)
3105
  if (__mode_ & consume_header)
3106
    return 6;
3107
  return 3;
3108
#  else
3109
  if (__mode_ & consume_header)
3110
    return 7;
3111
  return 4;
3112
#  endif
3113
}
3114
#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
3115

3116
// __codecvt_utf8<char16_t>
3117

3118
__codecvt_utf8<char16_t>::result __codecvt_utf8<char16_t>::do_out(
3119
    state_type&,
3120
    const intern_type* frm,
3121
    const intern_type* frm_end,
3122
    const intern_type*& frm_nxt,
3123
    extern_type* to,
3124
    extern_type* to_end,
3125
    extern_type*& to_nxt) const {
3126
  const uint16_t* _frm     = reinterpret_cast<const uint16_t*>(frm);
3127
  const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3128
  const uint16_t* _frm_nxt = _frm;
3129
  uint8_t* _to             = reinterpret_cast<uint8_t*>(to);
3130
  uint8_t* _to_end         = reinterpret_cast<uint8_t*>(to_end);
3131
  uint8_t* _to_nxt         = _to;
3132
  result r                 = ucs2_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);
3133
  frm_nxt                  = frm + (_frm_nxt - _frm);
3134
  to_nxt                   = to + (_to_nxt - _to);
3135
  return r;
3136
}
3137

3138
__codecvt_utf8<char16_t>::result __codecvt_utf8<char16_t>::do_in(
3139
    state_type&,
3140
    const extern_type* frm,
3141
    const extern_type* frm_end,
3142
    const extern_type*& frm_nxt,
3143
    intern_type* to,
3144
    intern_type* to_end,
3145
    intern_type*& to_nxt) const {
3146
  const uint8_t* _frm     = reinterpret_cast<const uint8_t*>(frm);
3147
  const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3148
  const uint8_t* _frm_nxt = _frm;
3149
  uint16_t* _to           = reinterpret_cast<uint16_t*>(to);
3150
  uint16_t* _to_end       = reinterpret_cast<uint16_t*>(to_end);
3151
  uint16_t* _to_nxt       = _to;
3152
  result r                = utf8_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);
3153
  frm_nxt                 = frm + (_frm_nxt - _frm);
3154
  to_nxt                  = to + (_to_nxt - _to);
3155
  return r;
3156
}
3157

3158
__codecvt_utf8<char16_t>::result
3159
__codecvt_utf8<char16_t>::do_unshift(state_type&, extern_type* to, extern_type*, extern_type*& to_nxt) const {
3160
  to_nxt = to;
3161
  return noconv;
3162
}
3163

3164
int __codecvt_utf8<char16_t>::do_encoding() const noexcept { return 0; }
3165

3166
bool __codecvt_utf8<char16_t>::do_always_noconv() const noexcept { return false; }
3167

3168
int __codecvt_utf8<char16_t>::do_length(
3169
    state_type&, const extern_type* frm, const extern_type* frm_end, size_t mx) const {
3170
  const uint8_t* _frm     = reinterpret_cast<const uint8_t*>(frm);
3171
  const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3172
  return utf8_to_ucs2_length(_frm, _frm_end, mx, __maxcode_, __mode_);
3173
}
3174

3175
_LIBCPP_SUPPRESS_DEPRECATED_PUSH
3176
int __codecvt_utf8<char16_t>::do_max_length() const noexcept {
3177
  if (__mode_ & consume_header)
3178
    return 6;
3179
  return 3;
3180
}
3181
_LIBCPP_SUPPRESS_DEPRECATED_POP
3182

3183
// __codecvt_utf8<char32_t>
3184

3185
__codecvt_utf8<char32_t>::result __codecvt_utf8<char32_t>::do_out(
3186
    state_type&,
3187
    const intern_type* frm,
3188
    const intern_type* frm_end,
3189
    const intern_type*& frm_nxt,
3190
    extern_type* to,
3191
    extern_type* to_end,
3192
    extern_type*& to_nxt) const {
3193
  const uint32_t* _frm     = reinterpret_cast<const uint32_t*>(frm);
3194
  const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3195
  const uint32_t* _frm_nxt = _frm;
3196
  uint8_t* _to             = reinterpret_cast<uint8_t*>(to);
3197
  uint8_t* _to_end         = reinterpret_cast<uint8_t*>(to_end);
3198
  uint8_t* _to_nxt         = _to;
3199
  result r                 = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);
3200
  frm_nxt                  = frm + (_frm_nxt - _frm);
3201
  to_nxt                   = to + (_to_nxt - _to);
3202
  return r;
3203
}
3204

3205
__codecvt_utf8<char32_t>::result __codecvt_utf8<char32_t>::do_in(
3206
    state_type&,
3207
    const extern_type* frm,
3208
    const extern_type* frm_end,
3209
    const extern_type*& frm_nxt,
3210
    intern_type* to,
3211
    intern_type* to_end,
3212
    intern_type*& to_nxt) const {
3213
  const uint8_t* _frm     = reinterpret_cast<const uint8_t*>(frm);
3214
  const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3215
  const uint8_t* _frm_nxt = _frm;
3216
  uint32_t* _to           = reinterpret_cast<uint32_t*>(to);
3217
  uint32_t* _to_end       = reinterpret_cast<uint32_t*>(to_end);
3218
  uint32_t* _to_nxt       = _to;
3219
  result r                = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);
3220
  frm_nxt                 = frm + (_frm_nxt - _frm);
3221
  to_nxt                  = to + (_to_nxt - _to);
3222
  return r;
3223
}
3224

3225
__codecvt_utf8<char32_t>::result
3226
__codecvt_utf8<char32_t>::do_unshift(state_type&, extern_type* to, extern_type*, extern_type*& to_nxt) const {
3227
  to_nxt = to;
3228
  return noconv;
3229
}
3230

3231
int __codecvt_utf8<char32_t>::do_encoding() const noexcept { return 0; }
3232

3233
bool __codecvt_utf8<char32_t>::do_always_noconv() const noexcept { return false; }
3234

3235
int __codecvt_utf8<char32_t>::do_length(
3236
    state_type&, const extern_type* frm, const extern_type* frm_end, size_t mx) const {
3237
  const uint8_t* _frm     = reinterpret_cast<const uint8_t*>(frm);
3238
  const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3239
  return utf8_to_ucs4_length(_frm, _frm_end, mx, __maxcode_, __mode_);
3240
}
3241

3242
_LIBCPP_SUPPRESS_DEPRECATED_PUSH
3243
int __codecvt_utf8<char32_t>::do_max_length() const noexcept {
3244
  if (__mode_ & consume_header)
3245
    return 7;
3246
  return 4;
3247
}
3248
_LIBCPP_SUPPRESS_DEPRECATED_POP
3249

3250
// __codecvt_utf16<wchar_t, false>
3251

3252
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
3253
__codecvt_utf16<wchar_t, false>::result __codecvt_utf16<wchar_t, false>::do_out(
3254
    state_type&,
3255
    const intern_type* frm,
3256
    const intern_type* frm_end,
3257
    const intern_type*& frm_nxt,
3258
    extern_type* to,
3259
    extern_type* to_end,
3260
    extern_type*& to_nxt) const {
3261
#  if defined(_LIBCPP_SHORT_WCHAR)
3262
  const uint16_t* _frm     = reinterpret_cast<const uint16_t*>(frm);
3263
  const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3264
  const uint16_t* _frm_nxt = _frm;
3265
#  else
3266
  const uint32_t* _frm     = reinterpret_cast<const uint32_t*>(frm);
3267
  const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3268
  const uint32_t* _frm_nxt = _frm;
3269
#  endif
3270
  uint8_t* _to     = reinterpret_cast<uint8_t*>(to);
3271
  uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3272
  uint8_t* _to_nxt = _to;
3273
#  if defined(_LIBCPP_SHORT_WCHAR)
3274
  result r = ucs2_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);
3275
#  else
3276
  result r = ucs4_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);
3277
#  endif
3278
  frm_nxt = frm + (_frm_nxt - _frm);
3279
  to_nxt  = to + (_to_nxt - _to);
3280
  return r;
3281
}
3282

3283
__codecvt_utf16<wchar_t, false>::result __codecvt_utf16<wchar_t, false>::do_in(
3284
    state_type&,
3285
    const extern_type* frm,
3286
    const extern_type* frm_end,
3287
    const extern_type*& frm_nxt,
3288
    intern_type* to,
3289
    intern_type* to_end,
3290
    intern_type*& to_nxt) const {
3291
  const uint8_t* _frm     = reinterpret_cast<const uint8_t*>(frm);
3292
  const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3293
  const uint8_t* _frm_nxt = _frm;
3294
#  if defined(_LIBCPP_SHORT_WCHAR)
3295
  uint16_t* _to     = reinterpret_cast<uint16_t*>(to);
3296
  uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3297
  uint16_t* _to_nxt = _to;
3298
  result r          = utf16be_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);
3299
#  else
3300
  uint32_t* _to     = reinterpret_cast<uint32_t*>(to);
3301
  uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3302
  uint32_t* _to_nxt = _to;
3303
  result r          = utf16be_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);
3304
#  endif
3305
  frm_nxt = frm + (_frm_nxt - _frm);
3306
  to_nxt  = to + (_to_nxt - _to);
3307
  return r;
3308
}
3309

3310
__codecvt_utf16<wchar_t, false>::result
3311
__codecvt_utf16<wchar_t, false>::do_unshift(state_type&, extern_type* to, extern_type*, extern_type*& to_nxt) const {
3312
  to_nxt = to;
3313
  return noconv;
3314
}
3315

3316
int __codecvt_utf16<wchar_t, false>::do_encoding() const noexcept { return 0; }
3317

3318
bool __codecvt_utf16<wchar_t, false>::do_always_noconv() const noexcept { return false; }
3319

3320
int __codecvt_utf16<wchar_t, false>::do_length(
3321
    state_type&, const extern_type* frm, const extern_type* frm_end, size_t mx) const {
3322
  const uint8_t* _frm     = reinterpret_cast<const uint8_t*>(frm);
3323
  const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3324
#  if defined(_LIBCPP_SHORT_WCHAR)
3325
  return utf16be_to_ucs2_length(_frm, _frm_end, mx, __maxcode_, __mode_);
3326
#  else
3327
  return utf16be_to_ucs4_length(_frm, _frm_end, mx, __maxcode_, __mode_);
3328
#  endif
3329
}
3330

3331
int __codecvt_utf16<wchar_t, false>::do_max_length() const noexcept {
3332
#  if defined(_LIBCPP_SHORT_WCHAR)
3333
  if (__mode_ & consume_header)
3334
    return 4;
3335
  return 2;
3336
#  else
3337
  if (__mode_ & consume_header)
3338
    return 6;
3339
  return 4;
3340
#  endif
3341
}
3342

3343
// __codecvt_utf16<wchar_t, true>
3344

3345
__codecvt_utf16<wchar_t, true>::result __codecvt_utf16<wchar_t, true>::do_out(
3346
    state_type&,
3347
    const intern_type* frm,
3348
    const intern_type* frm_end,
3349
    const intern_type*& frm_nxt,
3350
    extern_type* to,
3351
    extern_type* to_end,
3352
    extern_type*& to_nxt) const {
3353
#  if defined(_LIBCPP_SHORT_WCHAR)
3354
  const uint16_t* _frm     = reinterpret_cast<const uint16_t*>(frm);
3355
  const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3356
  const uint16_t* _frm_nxt = _frm;
3357
#  else
3358
  const uint32_t* _frm     = reinterpret_cast<const uint32_t*>(frm);
3359
  const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3360
  const uint32_t* _frm_nxt = _frm;
3361
#  endif
3362
  uint8_t* _to     = reinterpret_cast<uint8_t*>(to);
3363
  uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3364
  uint8_t* _to_nxt = _to;
3365
#  if defined(_LIBCPP_SHORT_WCHAR)
3366
  result r = ucs2_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);
3367
#  else
3368
  result r = ucs4_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);
3369
#  endif
3370
  frm_nxt = frm + (_frm_nxt - _frm);
3371
  to_nxt  = to + (_to_nxt - _to);
3372
  return r;
3373
}
3374

3375
__codecvt_utf16<wchar_t, true>::result __codecvt_utf16<wchar_t, true>::do_in(
3376
    state_type&,
3377
    const extern_type* frm,
3378
    const extern_type* frm_end,
3379
    const extern_type*& frm_nxt,
3380
    intern_type* to,
3381
    intern_type* to_end,
3382
    intern_type*& to_nxt) const {
3383
  const uint8_t* _frm     = reinterpret_cast<const uint8_t*>(frm);
3384
  const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3385
  const uint8_t* _frm_nxt = _frm;
3386
#  if defined(_LIBCPP_SHORT_WCHAR)
3387
  uint16_t* _to     = reinterpret_cast<uint16_t*>(to);
3388
  uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3389
  uint16_t* _to_nxt = _to;
3390
  result r          = utf16le_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);
3391
#  else
3392
  uint32_t* _to     = reinterpret_cast<uint32_t*>(to);
3393
  uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3394
  uint32_t* _to_nxt = _to;
3395
  result r          = utf16le_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);
3396
#  endif
3397
  frm_nxt = frm + (_frm_nxt - _frm);
3398
  to_nxt  = to + (_to_nxt - _to);
3399
  return r;
3400
}
3401

3402
__codecvt_utf16<wchar_t, true>::result
3403
__codecvt_utf16<wchar_t, true>::do_unshift(state_type&, extern_type* to, extern_type*, extern_type*& to_nxt) const {
3404
  to_nxt = to;
3405
  return noconv;
3406
}
3407

3408
int __codecvt_utf16<wchar_t, true>::do_encoding() const noexcept { return 0; }
3409

3410
bool __codecvt_utf16<wchar_t, true>::do_always_noconv() const noexcept { return false; }
3411

3412
int __codecvt_utf16<wchar_t, true>::do_length(
3413
    state_type&, const extern_type* frm, const extern_type* frm_end, size_t mx) const {
3414
  const uint8_t* _frm     = reinterpret_cast<const uint8_t*>(frm);
3415
  const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3416
#  if defined(_LIBCPP_SHORT_WCHAR)
3417
  return utf16le_to_ucs2_length(_frm, _frm_end, mx, __maxcode_, __mode_);
3418
#  else
3419
  return utf16le_to_ucs4_length(_frm, _frm_end, mx, __maxcode_, __mode_);
3420
#  endif
3421
}
3422

3423
int __codecvt_utf16<wchar_t, true>::do_max_length() const noexcept {
3424
#  if defined(_LIBCPP_SHORT_WCHAR)
3425
  if (__mode_ & consume_header)
3426
    return 4;
3427
  return 2;
3428
#  else
3429
  if (__mode_ & consume_header)
3430
    return 6;
3431
  return 4;
3432
#  endif
3433
}
3434
#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
3435

3436
// __codecvt_utf16<char16_t, false>
3437

3438
__codecvt_utf16<char16_t, false>::result __codecvt_utf16<char16_t, false>::do_out(
3439
    state_type&,
3440
    const intern_type* frm,
3441
    const intern_type* frm_end,
3442
    const intern_type*& frm_nxt,
3443
    extern_type* to,
3444
    extern_type* to_end,
3445
    extern_type*& to_nxt) const {
3446
  const uint16_t* _frm     = reinterpret_cast<const uint16_t*>(frm);
3447
  const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3448
  const uint16_t* _frm_nxt = _frm;
3449
  uint8_t* _to             = reinterpret_cast<uint8_t*>(to);
3450
  uint8_t* _to_end         = reinterpret_cast<uint8_t*>(to_end);
3451
  uint8_t* _to_nxt         = _to;
3452
  result r                 = ucs2_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);
3453
  frm_nxt                  = frm + (_frm_nxt - _frm);
3454
  to_nxt                   = to + (_to_nxt - _to);
3455
  return r;
3456
}
3457

3458
__codecvt_utf16<char16_t, false>::result __codecvt_utf16<char16_t, false>::do_in(
3459
    state_type&,
3460
    const extern_type* frm,
3461
    const extern_type* frm_end,
3462
    const extern_type*& frm_nxt,
3463
    intern_type* to,
3464
    intern_type* to_end,
3465
    intern_type*& to_nxt) const {
3466
  const uint8_t* _frm     = reinterpret_cast<const uint8_t*>(frm);
3467
  const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3468
  const uint8_t* _frm_nxt = _frm;
3469
  uint16_t* _to           = reinterpret_cast<uint16_t*>(to);
3470
  uint16_t* _to_end       = reinterpret_cast<uint16_t*>(to_end);
3471
  uint16_t* _to_nxt       = _to;
3472
  result r                = utf16be_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);
3473
  frm_nxt                 = frm + (_frm_nxt - _frm);
3474
  to_nxt                  = to + (_to_nxt - _to);
3475
  return r;
3476
}
3477

3478
__codecvt_utf16<char16_t, false>::result
3479
__codecvt_utf16<char16_t, false>::do_unshift(state_type&, extern_type* to, extern_type*, extern_type*& to_nxt) const {
3480
  to_nxt = to;
3481
  return noconv;
3482
}
3483

3484
int __codecvt_utf16<char16_t, false>::do_encoding() const noexcept { return 0; }
3485

3486
bool __codecvt_utf16<char16_t, false>::do_always_noconv() const noexcept { return false; }
3487

3488
int __codecvt_utf16<char16_t, false>::do_length(
3489
    state_type&, const extern_type* frm, const extern_type* frm_end, size_t mx) const {
3490
  const uint8_t* _frm     = reinterpret_cast<const uint8_t*>(frm);
3491
  const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3492
  return utf16be_to_ucs2_length(_frm, _frm_end, mx, __maxcode_, __mode_);
3493
}
3494

3495
_LIBCPP_SUPPRESS_DEPRECATED_PUSH
3496
int __codecvt_utf16<char16_t, false>::do_max_length() const noexcept {
3497
  if (__mode_ & consume_header)
3498
    return 4;
3499
  return 2;
3500
}
3501
_LIBCPP_SUPPRESS_DEPRECATED_POP
3502

3503
// __codecvt_utf16<char16_t, true>
3504

3505
__codecvt_utf16<char16_t, true>::result __codecvt_utf16<char16_t, true>::do_out(
3506
    state_type&,
3507
    const intern_type* frm,
3508
    const intern_type* frm_end,
3509
    const intern_type*& frm_nxt,
3510
    extern_type* to,
3511
    extern_type* to_end,
3512
    extern_type*& to_nxt) const {
3513
  const uint16_t* _frm     = reinterpret_cast<const uint16_t*>(frm);
3514
  const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3515
  const uint16_t* _frm_nxt = _frm;
3516
  uint8_t* _to             = reinterpret_cast<uint8_t*>(to);
3517
  uint8_t* _to_end         = reinterpret_cast<uint8_t*>(to_end);
3518
  uint8_t* _to_nxt         = _to;
3519
  result r                 = ucs2_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);
3520
  frm_nxt                  = frm + (_frm_nxt - _frm);
3521
  to_nxt                   = to + (_to_nxt - _to);
3522
  return r;
3523
}
3524

3525
__codecvt_utf16<char16_t, true>::result __codecvt_utf16<char16_t, true>::do_in(
3526
    state_type&,
3527
    const extern_type* frm,
3528
    const extern_type* frm_end,
3529
    const extern_type*& frm_nxt,
3530
    intern_type* to,
3531
    intern_type* to_end,
3532
    intern_type*& to_nxt) const {
3533
  const uint8_t* _frm     = reinterpret_cast<const uint8_t*>(frm);
3534
  const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3535
  const uint8_t* _frm_nxt = _frm;
3536
  uint16_t* _to           = reinterpret_cast<uint16_t*>(to);
3537
  uint16_t* _to_end       = reinterpret_cast<uint16_t*>(to_end);
3538
  uint16_t* _to_nxt       = _to;
3539
  result r                = utf16le_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);
3540
  frm_nxt                 = frm + (_frm_nxt - _frm);
3541
  to_nxt                  = to + (_to_nxt - _to);
3542
  return r;
3543
}
3544

3545
__codecvt_utf16<char16_t, true>::result
3546
__codecvt_utf16<char16_t, true>::do_unshift(state_type&, extern_type* to, extern_type*, extern_type*& to_nxt) const {
3547
  to_nxt = to;
3548
  return noconv;
3549
}
3550

3551
int __codecvt_utf16<char16_t, true>::do_encoding() const noexcept { return 0; }
3552

3553
bool __codecvt_utf16<char16_t, true>::do_always_noconv() const noexcept { return false; }
3554

3555
int __codecvt_utf16<char16_t, true>::do_length(
3556
    state_type&, const extern_type* frm, const extern_type* frm_end, size_t mx) const {
3557
  const uint8_t* _frm     = reinterpret_cast<const uint8_t*>(frm);
3558
  const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3559
  return utf16le_to_ucs2_length(_frm, _frm_end, mx, __maxcode_, __mode_);
3560
}
3561

3562
_LIBCPP_SUPPRESS_DEPRECATED_PUSH
3563
int __codecvt_utf16<char16_t, true>::do_max_length() const noexcept {
3564
  if (__mode_ & consume_header)
3565
    return 4;
3566
  return 2;
3567
}
3568
_LIBCPP_SUPPRESS_DEPRECATED_POP
3569

3570
// __codecvt_utf16<char32_t, false>
3571

3572
__codecvt_utf16<char32_t, false>::result __codecvt_utf16<char32_t, false>::do_out(
3573
    state_type&,
3574
    const intern_type* frm,
3575
    const intern_type* frm_end,
3576
    const intern_type*& frm_nxt,
3577
    extern_type* to,
3578
    extern_type* to_end,
3579
    extern_type*& to_nxt) const {
3580
  const uint32_t* _frm     = reinterpret_cast<const uint32_t*>(frm);
3581
  const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3582
  const uint32_t* _frm_nxt = _frm;
3583
  uint8_t* _to             = reinterpret_cast<uint8_t*>(to);
3584
  uint8_t* _to_end         = reinterpret_cast<uint8_t*>(to_end);
3585
  uint8_t* _to_nxt         = _to;
3586
  result r                 = ucs4_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);
3587
  frm_nxt                  = frm + (_frm_nxt - _frm);
3588
  to_nxt                   = to + (_to_nxt - _to);
3589
  return r;
3590
}
3591

3592
__codecvt_utf16<char32_t, false>::result __codecvt_utf16<char32_t, false>::do_in(
3593
    state_type&,
3594
    const extern_type* frm,
3595
    const extern_type* frm_end,
3596
    const extern_type*& frm_nxt,
3597
    intern_type* to,
3598
    intern_type* to_end,
3599
    intern_type*& to_nxt) const {
3600
  const uint8_t* _frm     = reinterpret_cast<const uint8_t*>(frm);
3601
  const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3602
  const uint8_t* _frm_nxt = _frm;
3603
  uint32_t* _to           = reinterpret_cast<uint32_t*>(to);
3604
  uint32_t* _to_end       = reinterpret_cast<uint32_t*>(to_end);
3605
  uint32_t* _to_nxt       = _to;
3606
  result r                = utf16be_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);
3607
  frm_nxt                 = frm + (_frm_nxt - _frm);
3608
  to_nxt                  = to + (_to_nxt - _to);
3609
  return r;
3610
}
3611

3612
__codecvt_utf16<char32_t, false>::result
3613
__codecvt_utf16<char32_t, false>::do_unshift(state_type&, extern_type* to, extern_type*, extern_type*& to_nxt) const {
3614
  to_nxt = to;
3615
  return noconv;
3616
}
3617

3618
int __codecvt_utf16<char32_t, false>::do_encoding() const noexcept { return 0; }
3619

3620
bool __codecvt_utf16<char32_t, false>::do_always_noconv() const noexcept { return false; }
3621

3622
int __codecvt_utf16<char32_t, false>::do_length(
3623
    state_type&, const extern_type* frm, const extern_type* frm_end, size_t mx) const {
3624
  const uint8_t* _frm     = reinterpret_cast<const uint8_t*>(frm);
3625
  const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3626
  return utf16be_to_ucs4_length(_frm, _frm_end, mx, __maxcode_, __mode_);
3627
}
3628

3629
_LIBCPP_SUPPRESS_DEPRECATED_PUSH
3630
int __codecvt_utf16<char32_t, false>::do_max_length() const noexcept {
3631
  if (__mode_ & consume_header)
3632
    return 6;
3633
  return 4;
3634
}
3635
_LIBCPP_SUPPRESS_DEPRECATED_POP
3636

3637
// __codecvt_utf16<char32_t, true>
3638

3639
__codecvt_utf16<char32_t, true>::result __codecvt_utf16<char32_t, true>::do_out(
3640
    state_type&,
3641
    const intern_type* frm,
3642
    const intern_type* frm_end,
3643
    const intern_type*& frm_nxt,
3644
    extern_type* to,
3645
    extern_type* to_end,
3646
    extern_type*& to_nxt) const {
3647
  const uint32_t* _frm     = reinterpret_cast<const uint32_t*>(frm);
3648
  const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3649
  const uint32_t* _frm_nxt = _frm;
3650
  uint8_t* _to             = reinterpret_cast<uint8_t*>(to);
3651
  uint8_t* _to_end         = reinterpret_cast<uint8_t*>(to_end);
3652
  uint8_t* _to_nxt         = _to;
3653
  result r                 = ucs4_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);
3654
  frm_nxt                  = frm + (_frm_nxt - _frm);
3655
  to_nxt                   = to + (_to_nxt - _to);
3656
  return r;
3657
}
3658

3659
__codecvt_utf16<char32_t, true>::result __codecvt_utf16<char32_t, true>::do_in(
3660
    state_type&,
3661
    const extern_type* frm,
3662
    const extern_type* frm_end,
3663
    const extern_type*& frm_nxt,
3664
    intern_type* to,
3665
    intern_type* to_end,
3666
    intern_type*& to_nxt) const {
3667
  const uint8_t* _frm     = reinterpret_cast<const uint8_t*>(frm);
3668
  const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3669
  const uint8_t* _frm_nxt = _frm;
3670
  uint32_t* _to           = reinterpret_cast<uint32_t*>(to);
3671
  uint32_t* _to_end       = reinterpret_cast<uint32_t*>(to_end);
3672
  uint32_t* _to_nxt       = _to;
3673
  result r                = utf16le_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);
3674
  frm_nxt                 = frm + (_frm_nxt - _frm);
3675
  to_nxt                  = to + (_to_nxt - _to);
3676
  return r;
3677
}
3678

3679
__codecvt_utf16<char32_t, true>::result
3680
__codecvt_utf16<char32_t, true>::do_unshift(state_type&, extern_type* to, extern_type*, extern_type*& to_nxt) const {
3681
  to_nxt = to;
3682
  return noconv;
3683
}
3684

3685
int __codecvt_utf16<char32_t, true>::do_encoding() const noexcept { return 0; }
3686

3687
bool __codecvt_utf16<char32_t, true>::do_always_noconv() const noexcept { return false; }
3688

3689
int __codecvt_utf16<char32_t, true>::do_length(
3690
    state_type&, const extern_type* frm, const extern_type* frm_end, size_t mx) const {
3691
  const uint8_t* _frm     = reinterpret_cast<const uint8_t*>(frm);
3692
  const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3693
  return utf16le_to_ucs4_length(_frm, _frm_end, mx, __maxcode_, __mode_);
3694
}
3695

3696
_LIBCPP_SUPPRESS_DEPRECATED_PUSH
3697
int __codecvt_utf16<char32_t, true>::do_max_length() const noexcept {
3698
  if (__mode_ & consume_header)
3699
    return 6;
3700
  return 4;
3701
}
3702
_LIBCPP_SUPPRESS_DEPRECATED_POP
3703

3704
// __codecvt_utf8_utf16<wchar_t>
3705

3706
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
3707
__codecvt_utf8_utf16<wchar_t>::result __codecvt_utf8_utf16<wchar_t>::do_out(
3708
    state_type&,
3709
    const intern_type* frm,
3710
    const intern_type* frm_end,
3711
    const intern_type*& frm_nxt,
3712
    extern_type* to,
3713
    extern_type* to_end,
3714
    extern_type*& to_nxt) const {
3715
#  if defined(_LIBCPP_SHORT_WCHAR)
3716
  const uint16_t* _frm     = reinterpret_cast<const uint16_t*>(frm);
3717
  const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3718
  const uint16_t* _frm_nxt = _frm;
3719
#  else
3720
  const uint32_t* _frm     = reinterpret_cast<const uint32_t*>(frm);
3721
  const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3722
  const uint32_t* _frm_nxt = _frm;
3723
#  endif
3724
  uint8_t* _to     = reinterpret_cast<uint8_t*>(to);
3725
  uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3726
  uint8_t* _to_nxt = _to;
3727
  result r         = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);
3728
  frm_nxt          = frm + (_frm_nxt - _frm);
3729
  to_nxt           = to + (_to_nxt - _to);
3730
  return r;
3731
}
3732

3733
__codecvt_utf8_utf16<wchar_t>::result __codecvt_utf8_utf16<wchar_t>::do_in(
3734
    state_type&,
3735
    const extern_type* frm,
3736
    const extern_type* frm_end,
3737
    const extern_type*& frm_nxt,
3738
    intern_type* to,
3739
    intern_type* to_end,
3740
    intern_type*& to_nxt) const {
3741
  const uint8_t* _frm     = reinterpret_cast<const uint8_t*>(frm);
3742
  const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3743
  const uint8_t* _frm_nxt = _frm;
3744
#  if defined(_LIBCPP_SHORT_WCHAR)
3745
  uint16_t* _to     = reinterpret_cast<uint16_t*>(to);
3746
  uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3747
  uint16_t* _to_nxt = _to;
3748
#  else
3749
  uint32_t* _to     = reinterpret_cast<uint32_t*>(to);
3750
  uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3751
  uint32_t* _to_nxt = _to;
3752
#  endif
3753
  result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);
3754
  frm_nxt  = frm + (_frm_nxt - _frm);
3755
  to_nxt   = to + (_to_nxt - _to);
3756
  return r;
3757
}
3758

3759
__codecvt_utf8_utf16<wchar_t>::result
3760
__codecvt_utf8_utf16<wchar_t>::do_unshift(state_type&, extern_type* to, extern_type*, extern_type*& to_nxt) const {
3761
  to_nxt = to;
3762
  return noconv;
3763
}
3764

3765
int __codecvt_utf8_utf16<wchar_t>::do_encoding() const noexcept { return 0; }
3766

3767
bool __codecvt_utf8_utf16<wchar_t>::do_always_noconv() const noexcept { return false; }
3768

3769
int __codecvt_utf8_utf16<wchar_t>::do_length(
3770
    state_type&, const extern_type* frm, const extern_type* frm_end, size_t mx) const {
3771
  const uint8_t* _frm     = reinterpret_cast<const uint8_t*>(frm);
3772
  const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3773
  return utf8_to_utf16_length(_frm, _frm_end, mx, __maxcode_, __mode_);
3774
}
3775

3776
int __codecvt_utf8_utf16<wchar_t>::do_max_length() const noexcept {
3777
  if (__mode_ & consume_header)
3778
    return 7;
3779
  return 4;
3780
}
3781
#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
3782

3783
// __codecvt_utf8_utf16<char16_t>
3784

3785
__codecvt_utf8_utf16<char16_t>::result __codecvt_utf8_utf16<char16_t>::do_out(
3786
    state_type&,
3787
    const intern_type* frm,
3788
    const intern_type* frm_end,
3789
    const intern_type*& frm_nxt,
3790
    extern_type* to,
3791
    extern_type* to_end,
3792
    extern_type*& to_nxt) const {
3793
  const uint16_t* _frm     = reinterpret_cast<const uint16_t*>(frm);
3794
  const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3795
  const uint16_t* _frm_nxt = _frm;
3796
  uint8_t* _to             = reinterpret_cast<uint8_t*>(to);
3797
  uint8_t* _to_end         = reinterpret_cast<uint8_t*>(to_end);
3798
  uint8_t* _to_nxt         = _to;
3799
  result r                 = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);
3800
  frm_nxt                  = frm + (_frm_nxt - _frm);
3801
  to_nxt                   = to + (_to_nxt - _to);
3802
  return r;
3803
}
3804

3805
__codecvt_utf8_utf16<char16_t>::result __codecvt_utf8_utf16<char16_t>::do_in(
3806
    state_type&,
3807
    const extern_type* frm,
3808
    const extern_type* frm_end,
3809
    const extern_type*& frm_nxt,
3810
    intern_type* to,
3811
    intern_type* to_end,
3812
    intern_type*& to_nxt) const {
3813
  const uint8_t* _frm     = reinterpret_cast<const uint8_t*>(frm);
3814
  const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3815
  const uint8_t* _frm_nxt = _frm;
3816
  uint16_t* _to           = reinterpret_cast<uint16_t*>(to);
3817
  uint16_t* _to_end       = reinterpret_cast<uint16_t*>(to_end);
3818
  uint16_t* _to_nxt       = _to;
3819
  result r                = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);
3820
  frm_nxt                 = frm + (_frm_nxt - _frm);
3821
  to_nxt                  = to + (_to_nxt - _to);
3822
  return r;
3823
}
3824

3825
__codecvt_utf8_utf16<char16_t>::result
3826
__codecvt_utf8_utf16<char16_t>::do_unshift(state_type&, extern_type* to, extern_type*, extern_type*& to_nxt) const {
3827
  to_nxt = to;
3828
  return noconv;
3829
}
3830

3831
int __codecvt_utf8_utf16<char16_t>::do_encoding() const noexcept { return 0; }
3832

3833
bool __codecvt_utf8_utf16<char16_t>::do_always_noconv() const noexcept { return false; }
3834

3835
int __codecvt_utf8_utf16<char16_t>::do_length(
3836
    state_type&, const extern_type* frm, const extern_type* frm_end, size_t mx) const {
3837
  const uint8_t* _frm     = reinterpret_cast<const uint8_t*>(frm);
3838
  const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3839
  return utf8_to_utf16_length(_frm, _frm_end, mx, __maxcode_, __mode_);
3840
}
3841

3842
_LIBCPP_SUPPRESS_DEPRECATED_PUSH
3843
int __codecvt_utf8_utf16<char16_t>::do_max_length() const noexcept {
3844
  if (__mode_ & consume_header)
3845
    return 7;
3846
  return 4;
3847
}
3848
_LIBCPP_SUPPRESS_DEPRECATED_POP
3849

3850
// __codecvt_utf8_utf16<char32_t>
3851

3852
__codecvt_utf8_utf16<char32_t>::result __codecvt_utf8_utf16<char32_t>::do_out(
3853
    state_type&,
3854
    const intern_type* frm,
3855
    const intern_type* frm_end,
3856
    const intern_type*& frm_nxt,
3857
    extern_type* to,
3858
    extern_type* to_end,
3859
    extern_type*& to_nxt) const {
3860
  const uint32_t* _frm     = reinterpret_cast<const uint32_t*>(frm);
3861
  const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3862
  const uint32_t* _frm_nxt = _frm;
3863
  uint8_t* _to             = reinterpret_cast<uint8_t*>(to);
3864
  uint8_t* _to_end         = reinterpret_cast<uint8_t*>(to_end);
3865
  uint8_t* _to_nxt         = _to;
3866
  result r                 = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);
3867
  frm_nxt                  = frm + (_frm_nxt - _frm);
3868
  to_nxt                   = to + (_to_nxt - _to);
3869
  return r;
3870
}
3871

3872
__codecvt_utf8_utf16<char32_t>::result __codecvt_utf8_utf16<char32_t>::do_in(
3873
    state_type&,
3874
    const extern_type* frm,
3875
    const extern_type* frm_end,
3876
    const extern_type*& frm_nxt,
3877
    intern_type* to,
3878
    intern_type* to_end,
3879
    intern_type*& to_nxt) const {
3880
  const uint8_t* _frm     = reinterpret_cast<const uint8_t*>(frm);
3881
  const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3882
  const uint8_t* _frm_nxt = _frm;
3883
  uint32_t* _to           = reinterpret_cast<uint32_t*>(to);
3884
  uint32_t* _to_end       = reinterpret_cast<uint32_t*>(to_end);
3885
  uint32_t* _to_nxt       = _to;
3886
  result r                = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);
3887
  frm_nxt                 = frm + (_frm_nxt - _frm);
3888
  to_nxt                  = to + (_to_nxt - _to);
3889
  return r;
3890
}
3891

3892
__codecvt_utf8_utf16<char32_t>::result
3893
__codecvt_utf8_utf16<char32_t>::do_unshift(state_type&, extern_type* to, extern_type*, extern_type*& to_nxt) const {
3894
  to_nxt = to;
3895
  return noconv;
3896
}
3897

3898
int __codecvt_utf8_utf16<char32_t>::do_encoding() const noexcept { return 0; }
3899

3900
bool __codecvt_utf8_utf16<char32_t>::do_always_noconv() const noexcept { return false; }
3901

3902
int __codecvt_utf8_utf16<char32_t>::do_length(
3903
    state_type&, const extern_type* frm, const extern_type* frm_end, size_t mx) const {
3904
  const uint8_t* _frm     = reinterpret_cast<const uint8_t*>(frm);
3905
  const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3906
  return utf8_to_utf16_length(_frm, _frm_end, mx, __maxcode_, __mode_);
3907
}
3908

3909
_LIBCPP_SUPPRESS_DEPRECATED_PUSH
3910
int __codecvt_utf8_utf16<char32_t>::do_max_length() const noexcept {
3911
  if (__mode_ & consume_header)
3912
    return 7;
3913
  return 4;
3914
}
3915
_LIBCPP_SUPPRESS_DEPRECATED_POP
3916

3917
// __narrow_to_utf8<16>
3918

3919
__narrow_to_utf8<16>::~__narrow_to_utf8() {}
3920

3921
// __narrow_to_utf8<32>
3922

3923
__narrow_to_utf8<32>::~__narrow_to_utf8() {}
3924

3925
// __widen_from_utf8<16>
3926

3927
__widen_from_utf8<16>::~__widen_from_utf8() {}
3928

3929
// __widen_from_utf8<32>
3930

3931
__widen_from_utf8<32>::~__widen_from_utf8() {}
3932

3933
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
3934
static bool checked_string_to_wchar_convert(wchar_t& dest, const char* ptr, locale_t loc) {
3935
  if (*ptr == '\0')
3936
    return false;
3937
  mbstate_t mb = {};
3938
  wchar_t out;
3939
  size_t ret = __libcpp_mbrtowc_l(&out, ptr, strlen(ptr), &mb, loc);
3940
  if (ret == static_cast<size_t>(-1) || ret == static_cast<size_t>(-2)) {
3941
    return false;
3942
  }
3943
  dest = out;
3944
  return true;
3945
}
3946
#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
3947

3948
#ifdef _LIBCPP_HAS_NO_WIDE_CHARACTERS
3949
static bool is_narrow_non_breaking_space(const char* ptr) {
3950
  // https://www.fileformat.info/info/unicode/char/202f/index.htm
3951
  return ptr[0] == '\xe2' && ptr[1] == '\x80' && ptr[2] == '\xaf';
3952
}
3953

3954
static bool is_non_breaking_space(const char* ptr) {
3955
  // https://www.fileformat.info/info/unicode/char/0a/index.htm
3956
  return ptr[0] == '\xc2' && ptr[1] == '\xa0';
3957
}
3958
#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
3959

3960
static bool checked_string_to_char_convert(char& dest, const char* ptr, locale_t __loc) {
3961
  if (*ptr == '\0')
3962
    return false;
3963
  if (!ptr[1]) {
3964
    dest = *ptr;
3965
    return true;
3966
  }
3967

3968
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
3969
  // First convert the MBS into a wide char then attempt to narrow it using
3970
  // wctob_l.
3971
  wchar_t wout;
3972
  if (!checked_string_to_wchar_convert(wout, ptr, __loc))
3973
    return false;
3974
  int res;
3975
  if ((res = __libcpp_wctob_l(wout, __loc)) != char_traits<char>::eof()) {
3976
    dest = res;
3977
    return true;
3978
  }
3979
  // FIXME: Work around specific multibyte sequences that we can reasonably
3980
  // translate into a different single byte.
3981
  switch (wout) {
3982
  case L'\u202F': // narrow non-breaking space
3983
  case L'\u00A0': // non-breaking space
3984
    dest = ' ';
3985
    return true;
3986
  default:
3987
    return false;
3988
  }
3989
#else  // _LIBCPP_HAS_NO_WIDE_CHARACTERS
3990
  // FIXME: Work around specific multibyte sequences that we can reasonably
3991
  // translate into a different single byte.
3992
  if (is_narrow_non_breaking_space(ptr) || is_non_breaking_space(ptr)) {
3993
    dest = ' ';
3994
    return true;
3995
  }
3996

3997
  return false;
3998
#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
3999
  __libcpp_unreachable();
4000
}
4001

4002
// numpunct<char> && numpunct<wchar_t>
4003

4004
constinit locale::id numpunct<char>::id;
4005
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4006
constinit locale::id numpunct<wchar_t>::id;
4007
#endif
4008

4009
numpunct<char>::numpunct(size_t refs) : locale::facet(refs), __decimal_point_('.'), __thousands_sep_(',') {}
4010

4011
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4012
numpunct<wchar_t>::numpunct(size_t refs) : locale::facet(refs), __decimal_point_(L'.'), __thousands_sep_(L',') {}
4013
#endif
4014

4015
numpunct<char>::~numpunct() {}
4016

4017
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4018
numpunct<wchar_t>::~numpunct() {}
4019
#endif
4020

4021
char numpunct< char >::do_decimal_point() const { return __decimal_point_; }
4022
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4023
wchar_t numpunct<wchar_t>::do_decimal_point() const { return __decimal_point_; }
4024
#endif
4025

4026
char numpunct< char >::do_thousands_sep() const { return __thousands_sep_; }
4027
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4028
wchar_t numpunct<wchar_t>::do_thousands_sep() const { return __thousands_sep_; }
4029
#endif
4030

4031
string numpunct< char >::do_grouping() const { return __grouping_; }
4032
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4033
string numpunct<wchar_t>::do_grouping() const { return __grouping_; }
4034
#endif
4035

4036
string numpunct< char >::do_truename() const { return "true"; }
4037
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4038
wstring numpunct<wchar_t>::do_truename() const { return L"true"; }
4039
#endif
4040

4041
string numpunct< char >::do_falsename() const { return "false"; }
4042
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4043
wstring numpunct<wchar_t>::do_falsename() const { return L"false"; }
4044
#endif
4045

4046
// numpunct_byname<char>
4047

4048
numpunct_byname<char>::numpunct_byname(const char* nm, size_t refs) : numpunct<char>(refs) { __init(nm); }
4049

4050
numpunct_byname<char>::numpunct_byname(const string& nm, size_t refs) : numpunct<char>(refs) { __init(nm.c_str()); }
4051

4052
numpunct_byname<char>::~numpunct_byname() {}
4053

4054
void numpunct_byname<char>::__init(const char* nm) {
4055
  typedef numpunct<char> base;
4056
  if (strcmp(nm, "C") != 0) {
4057
    __libcpp_unique_locale loc(nm);
4058
    if (!loc)
4059
      __throw_runtime_error(
4060
          ("numpunct_byname<char>::numpunct_byname"
4061
           " failed to construct for " +
4062
           string(nm))
4063
              .c_str());
4064

4065
    lconv* lc = __libcpp_localeconv_l(loc.get());
4066
    if (!checked_string_to_char_convert(__decimal_point_, lc->decimal_point, loc.get()))
4067
      __decimal_point_ = base::do_decimal_point();
4068
    if (!checked_string_to_char_convert(__thousands_sep_, lc->thousands_sep, loc.get()))
4069
      __thousands_sep_ = base::do_thousands_sep();
4070
    __grouping_ = lc->grouping;
4071
    // localization for truename and falsename is not available
4072
  }
4073
}
4074

4075
// numpunct_byname<wchar_t>
4076

4077
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4078
numpunct_byname<wchar_t>::numpunct_byname(const char* nm, size_t refs) : numpunct<wchar_t>(refs) { __init(nm); }
4079

4080
numpunct_byname<wchar_t>::numpunct_byname(const string& nm, size_t refs) : numpunct<wchar_t>(refs) {
4081
  __init(nm.c_str());
4082
}
4083

4084
numpunct_byname<wchar_t>::~numpunct_byname() {}
4085

4086
void numpunct_byname<wchar_t>::__init(const char* nm) {
4087
  if (strcmp(nm, "C") != 0) {
4088
    __libcpp_unique_locale loc(nm);
4089
    if (!loc)
4090
      __throw_runtime_error(
4091
          ("numpunct_byname<wchar_t>::numpunct_byname"
4092
           " failed to construct for " +
4093
           string(nm))
4094
              .c_str());
4095

4096
    lconv* lc = __libcpp_localeconv_l(loc.get());
4097
    checked_string_to_wchar_convert(__decimal_point_, lc->decimal_point, loc.get());
4098
    checked_string_to_wchar_convert(__thousands_sep_, lc->thousands_sep, loc.get());
4099
    __grouping_ = lc->grouping;
4100
    // localization for truename and falsename is not available
4101
  }
4102
}
4103
#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
4104

4105
// num_get helpers
4106

4107
int __num_get_base::__get_base(ios_base& iob) {
4108
  ios_base::fmtflags __basefield = iob.flags() & ios_base::basefield;
4109
  if (__basefield == ios_base::oct)
4110
    return 8;
4111
  else if (__basefield == ios_base::hex)
4112
    return 16;
4113
  else if (__basefield == 0)
4114
    return 0;
4115
  return 10;
4116
}
4117

4118
const char __num_get_base::__src[33] = "0123456789abcdefABCDEFxX+-pPiInN";
4119

4120
void __check_grouping(const string& __grouping, unsigned* __g, unsigned* __g_end, ios_base::iostate& __err) {
4121
  //  if the grouping pattern is empty _or_ there are no grouping bits, then do nothing
4122
  //  we always have at least a single entry in [__g, __g_end); the end of the input sequence
4123
  if (__grouping.size() != 0 && __g_end - __g > 1) {
4124
    reverse(__g, __g_end);
4125
    const char* __ig = __grouping.data();
4126
    const char* __eg = __ig + __grouping.size();
4127
    for (unsigned* __r = __g; __r < __g_end - 1; ++__r) {
4128
      if (0 < *__ig && *__ig < numeric_limits<char>::max()) {
4129
        if (static_cast<unsigned>(*__ig) != *__r) {
4130
          __err = ios_base::failbit;
4131
          return;
4132
        }
4133
      }
4134
      if (__eg - __ig > 1)
4135
        ++__ig;
4136
    }
4137
    if (0 < *__ig && *__ig < numeric_limits<char>::max()) {
4138
      if (static_cast<unsigned>(*__ig) < __g_end[-1] || __g_end[-1] == 0)
4139
        __err = ios_base::failbit;
4140
    }
4141
  }
4142
}
4143

4144
void __num_put_base::__format_int(char* __fmtp, const char* __len, bool __signd, ios_base::fmtflags __flags) {
4145
  if ((__flags & ios_base::showpos) && (__flags & ios_base::basefield) != ios_base::oct &&
4146
      (__flags & ios_base::basefield) != ios_base::hex && __signd)
4147
    *__fmtp++ = '+';
4148
  if (__flags & ios_base::showbase)
4149
    *__fmtp++ = '#';
4150
  while (*__len)
4151
    *__fmtp++ = *__len++;
4152
  if ((__flags & ios_base::basefield) == ios_base::oct)
4153
    *__fmtp = 'o';
4154
  else if ((__flags & ios_base::basefield) == ios_base::hex) {
4155
    if (__flags & ios_base::uppercase)
4156
      *__fmtp = 'X';
4157
    else
4158
      *__fmtp = 'x';
4159
  } else if (__signd)
4160
    *__fmtp = 'd';
4161
  else
4162
    *__fmtp = 'u';
4163
}
4164

4165
bool __num_put_base::__format_float(char* __fmtp, const char* __len, ios_base::fmtflags __flags) {
4166
  bool specify_precision = true;
4167
  if (__flags & ios_base::showpos)
4168
    *__fmtp++ = '+';
4169
  if (__flags & ios_base::showpoint)
4170
    *__fmtp++ = '#';
4171
  ios_base::fmtflags floatfield = __flags & ios_base::floatfield;
4172
  bool uppercase                = (__flags & ios_base::uppercase) != 0;
4173
  if (floatfield == (ios_base::fixed | ios_base::scientific))
4174
    specify_precision = false;
4175
  else {
4176
    *__fmtp++ = '.';
4177
    *__fmtp++ = '*';
4178
  }
4179
  while (*__len)
4180
    *__fmtp++ = *__len++;
4181
  if (floatfield == ios_base::fixed) {
4182
    if (uppercase)
4183
      *__fmtp = 'F';
4184
    else
4185
      *__fmtp = 'f';
4186
  } else if (floatfield == ios_base::scientific) {
4187
    if (uppercase)
4188
      *__fmtp = 'E';
4189
    else
4190
      *__fmtp = 'e';
4191
  } else if (floatfield == (ios_base::fixed | ios_base::scientific)) {
4192
    if (uppercase)
4193
      *__fmtp = 'A';
4194
    else
4195
      *__fmtp = 'a';
4196
  } else {
4197
    if (uppercase)
4198
      *__fmtp = 'G';
4199
    else
4200
      *__fmtp = 'g';
4201
  }
4202
  return specify_precision;
4203
}
4204

4205
char* __num_put_base::__identify_padding(char* __nb, char* __ne, const ios_base& __iob) {
4206
  switch (__iob.flags() & ios_base::adjustfield) {
4207
  case ios_base::internal:
4208
    if (__nb[0] == '-' || __nb[0] == '+')
4209
      return __nb + 1;
4210
    if (__ne - __nb >= 2 && __nb[0] == '0' && (__nb[1] == 'x' || __nb[1] == 'X'))
4211
      return __nb + 2;
4212
    break;
4213
  case ios_base::left:
4214
    return __ne;
4215
  case ios_base::right:
4216
  default:
4217
    break;
4218
  }
4219
  return __nb;
4220
}
4221

4222
// time_get
4223

4224
static string* init_weeks() {
4225
  static string weeks[14];
4226
  weeks[0]  = "Sunday";
4227
  weeks[1]  = "Monday";
4228
  weeks[2]  = "Tuesday";
4229
  weeks[3]  = "Wednesday";
4230
  weeks[4]  = "Thursday";
4231
  weeks[5]  = "Friday";
4232
  weeks[6]  = "Saturday";
4233
  weeks[7]  = "Sun";
4234
  weeks[8]  = "Mon";
4235
  weeks[9]  = "Tue";
4236
  weeks[10] = "Wed";
4237
  weeks[11] = "Thu";
4238
  weeks[12] = "Fri";
4239
  weeks[13] = "Sat";
4240
  return weeks;
4241
}
4242

4243
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4244
static wstring* init_wweeks() {
4245
  static wstring weeks[14];
4246
  weeks[0]  = L"Sunday";
4247
  weeks[1]  = L"Monday";
4248
  weeks[2]  = L"Tuesday";
4249
  weeks[3]  = L"Wednesday";
4250
  weeks[4]  = L"Thursday";
4251
  weeks[5]  = L"Friday";
4252
  weeks[6]  = L"Saturday";
4253
  weeks[7]  = L"Sun";
4254
  weeks[8]  = L"Mon";
4255
  weeks[9]  = L"Tue";
4256
  weeks[10] = L"Wed";
4257
  weeks[11] = L"Thu";
4258
  weeks[12] = L"Fri";
4259
  weeks[13] = L"Sat";
4260
  return weeks;
4261
}
4262
#endif
4263

4264
template <>
4265
const string* __time_get_c_storage<char>::__weeks() const {
4266
  static const string* weeks = init_weeks();
4267
  return weeks;
4268
}
4269

4270
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4271
template <>
4272
const wstring* __time_get_c_storage<wchar_t>::__weeks() const {
4273
  static const wstring* weeks = init_wweeks();
4274
  return weeks;
4275
}
4276
#endif
4277

4278
static string* init_months() {
4279
  static string months[24];
4280
  months[0]  = "January";
4281
  months[1]  = "February";
4282
  months[2]  = "March";
4283
  months[3]  = "April";
4284
  months[4]  = "May";
4285
  months[5]  = "June";
4286
  months[6]  = "July";
4287
  months[7]  = "August";
4288
  months[8]  = "September";
4289
  months[9]  = "October";
4290
  months[10] = "November";
4291
  months[11] = "December";
4292
  months[12] = "Jan";
4293
  months[13] = "Feb";
4294
  months[14] = "Mar";
4295
  months[15] = "Apr";
4296
  months[16] = "May";
4297
  months[17] = "Jun";
4298
  months[18] = "Jul";
4299
  months[19] = "Aug";
4300
  months[20] = "Sep";
4301
  months[21] = "Oct";
4302
  months[22] = "Nov";
4303
  months[23] = "Dec";
4304
  return months;
4305
}
4306

4307
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4308
static wstring* init_wmonths() {
4309
  static wstring months[24];
4310
  months[0]  = L"January";
4311
  months[1]  = L"February";
4312
  months[2]  = L"March";
4313
  months[3]  = L"April";
4314
  months[4]  = L"May";
4315
  months[5]  = L"June";
4316
  months[6]  = L"July";
4317
  months[7]  = L"August";
4318
  months[8]  = L"September";
4319
  months[9]  = L"October";
4320
  months[10] = L"November";
4321
  months[11] = L"December";
4322
  months[12] = L"Jan";
4323
  months[13] = L"Feb";
4324
  months[14] = L"Mar";
4325
  months[15] = L"Apr";
4326
  months[16] = L"May";
4327
  months[17] = L"Jun";
4328
  months[18] = L"Jul";
4329
  months[19] = L"Aug";
4330
  months[20] = L"Sep";
4331
  months[21] = L"Oct";
4332
  months[22] = L"Nov";
4333
  months[23] = L"Dec";
4334
  return months;
4335
}
4336
#endif
4337

4338
template <>
4339
const string* __time_get_c_storage<char>::__months() const {
4340
  static const string* months = init_months();
4341
  return months;
4342
}
4343

4344
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4345
template <>
4346
const wstring* __time_get_c_storage<wchar_t>::__months() const {
4347
  static const wstring* months = init_wmonths();
4348
  return months;
4349
}
4350
#endif
4351

4352
static string* init_am_pm() {
4353
  static string am_pm[2];
4354
  am_pm[0] = "AM";
4355
  am_pm[1] = "PM";
4356
  return am_pm;
4357
}
4358

4359
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4360
static wstring* init_wam_pm() {
4361
  static wstring am_pm[2];
4362
  am_pm[0] = L"AM";
4363
  am_pm[1] = L"PM";
4364
  return am_pm;
4365
}
4366
#endif
4367

4368
template <>
4369
const string* __time_get_c_storage<char>::__am_pm() const {
4370
  static const string* am_pm = init_am_pm();
4371
  return am_pm;
4372
}
4373

4374
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4375
template <>
4376
const wstring* __time_get_c_storage<wchar_t>::__am_pm() const {
4377
  static const wstring* am_pm = init_wam_pm();
4378
  return am_pm;
4379
}
4380
#endif
4381

4382
template <>
4383
const string& __time_get_c_storage<char>::__x() const {
4384
  static string s("%m/%d/%y");
4385
  return s;
4386
}
4387

4388
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4389
template <>
4390
const wstring& __time_get_c_storage<wchar_t>::__x() const {
4391
  static wstring s(L"%m/%d/%y");
4392
  return s;
4393
}
4394
#endif
4395

4396
template <>
4397
const string& __time_get_c_storage<char>::__X() const {
4398
  static string s("%H:%M:%S");
4399
  return s;
4400
}
4401

4402
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4403
template <>
4404
const wstring& __time_get_c_storage<wchar_t>::__X() const {
4405
  static wstring s(L"%H:%M:%S");
4406
  return s;
4407
}
4408
#endif
4409

4410
template <>
4411
const string& __time_get_c_storage<char>::__c() const {
4412
  static string s("%a %b %d %H:%M:%S %Y");
4413
  return s;
4414
}
4415

4416
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4417
template <>
4418
const wstring& __time_get_c_storage<wchar_t>::__c() const {
4419
  static wstring s(L"%a %b %d %H:%M:%S %Y");
4420
  return s;
4421
}
4422
#endif
4423

4424
template <>
4425
const string& __time_get_c_storage<char>::__r() const {
4426
  static string s("%I:%M:%S %p");
4427
  return s;
4428
}
4429

4430
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4431
template <>
4432
const wstring& __time_get_c_storage<wchar_t>::__r() const {
4433
  static wstring s(L"%I:%M:%S %p");
4434
  return s;
4435
}
4436
#endif
4437

4438
// time_get_byname
4439

4440
__time_get::__time_get(const char* nm) : __loc_(newlocale(LC_ALL_MASK, nm, 0)) {
4441
  if (__loc_ == 0)
4442
    __throw_runtime_error(("time_get_byname failed to construct for " + string(nm)).c_str());
4443
}
4444

4445
__time_get::__time_get(const string& nm) : __loc_(newlocale(LC_ALL_MASK, nm.c_str(), 0)) {
4446
  if (__loc_ == 0)
4447
    __throw_runtime_error(("time_get_byname failed to construct for " + nm).c_str());
4448
}
4449

4450
__time_get::~__time_get() { freelocale(__loc_); }
4451

4452
_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wmissing-field-initializers")
4453

4454
template <>
4455
string __time_get_storage<char>::__analyze(char fmt, const ctype<char>& ct) {
4456
  tm t       = {0};
4457
  t.tm_sec   = 59;
4458
  t.tm_min   = 55;
4459
  t.tm_hour  = 23;
4460
  t.tm_mday  = 31;
4461
  t.tm_mon   = 11;
4462
  t.tm_year  = 161;
4463
  t.tm_wday  = 6;
4464
  t.tm_yday  = 364;
4465
  t.tm_isdst = -1;
4466
  char buf[100];
4467
  char f[3] = {0};
4468
  f[0]      = '%';
4469
  f[1]      = fmt;
4470
  size_t n  = strftime_l(buf, countof(buf), f, &t, __loc_);
4471
  char* bb  = buf;
4472
  char* be  = buf + n;
4473
  string result;
4474
  while (bb != be) {
4475
    if (ct.is(ctype_base::space, *bb)) {
4476
      result.push_back(' ');
4477
      for (++bb; bb != be && ct.is(ctype_base::space, *bb); ++bb)
4478
        ;
4479
      continue;
4480
    }
4481
    char* w               = bb;
4482
    ios_base::iostate err = ios_base::goodbit;
4483
    ptrdiff_t i           = __scan_keyword(w, be, this->__weeks_, this->__weeks_ + 14, ct, err, false) - this->__weeks_;
4484
    if (i < 14) {
4485
      result.push_back('%');
4486
      if (i < 7)
4487
        result.push_back('A');
4488
      else
4489
        result.push_back('a');
4490
      bb = w;
4491
      continue;
4492
    }
4493
    w = bb;
4494
    i = __scan_keyword(w, be, this->__months_, this->__months_ + 24, ct, err, false) - this->__months_;
4495
    if (i < 24) {
4496
      result.push_back('%');
4497
      if (i < 12)
4498
        result.push_back('B');
4499
      else
4500
        result.push_back('b');
4501
      if (fmt == 'x' && ct.is(ctype_base::digit, this->__months_[i][0]))
4502
        result.back() = 'm';
4503
      bb = w;
4504
      continue;
4505
    }
4506
    if (this->__am_pm_[0].size() + this->__am_pm_[1].size() > 0) {
4507
      w = bb;
4508
      i = __scan_keyword(w, be, this->__am_pm_, this->__am_pm_ + 2, ct, err, false) - this->__am_pm_;
4509
      if (i < 2) {
4510
        result.push_back('%');
4511
        result.push_back('p');
4512
        bb = w;
4513
        continue;
4514
      }
4515
    }
4516
    w = bb;
4517
    if (ct.is(ctype_base::digit, *bb)) {
4518
      switch (__get_up_to_n_digits(bb, be, err, ct, 4)) {
4519
      case 6:
4520
        result.push_back('%');
4521
        result.push_back('w');
4522
        break;
4523
      case 7:
4524
        result.push_back('%');
4525
        result.push_back('u');
4526
        break;
4527
      case 11:
4528
        result.push_back('%');
4529
        result.push_back('I');
4530
        break;
4531
      case 12:
4532
        result.push_back('%');
4533
        result.push_back('m');
4534
        break;
4535
      case 23:
4536
        result.push_back('%');
4537
        result.push_back('H');
4538
        break;
4539
      case 31:
4540
        result.push_back('%');
4541
        result.push_back('d');
4542
        break;
4543
      case 55:
4544
        result.push_back('%');
4545
        result.push_back('M');
4546
        break;
4547
      case 59:
4548
        result.push_back('%');
4549
        result.push_back('S');
4550
        break;
4551
      case 61:
4552
        result.push_back('%');
4553
        result.push_back('y');
4554
        break;
4555
      case 364:
4556
        result.push_back('%');
4557
        result.push_back('j');
4558
        break;
4559
      case 2061:
4560
        result.push_back('%');
4561
        result.push_back('Y');
4562
        break;
4563
      default:
4564
        for (; w != bb; ++w)
4565
          result.push_back(*w);
4566
        break;
4567
      }
4568
      continue;
4569
    }
4570
    if (*bb == '%') {
4571
      result.push_back('%');
4572
      result.push_back('%');
4573
      ++bb;
4574
      continue;
4575
    }
4576
    result.push_back(*bb);
4577
    ++bb;
4578
  }
4579
  return result;
4580
}
4581

4582
_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wmissing-braces")
4583

4584
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4585
template <>
4586
wstring __time_get_storage<wchar_t>::__analyze(char fmt, const ctype<wchar_t>& ct) {
4587
  tm t       = {0};
4588
  t.tm_sec   = 59;
4589
  t.tm_min   = 55;
4590
  t.tm_hour  = 23;
4591
  t.tm_mday  = 31;
4592
  t.tm_mon   = 11;
4593
  t.tm_year  = 161;
4594
  t.tm_wday  = 6;
4595
  t.tm_yday  = 364;
4596
  t.tm_isdst = -1;
4597
  char buf[100];
4598
  char f[3] = {0};
4599
  f[0]      = '%';
4600
  f[1]      = fmt;
4601
  strftime_l(buf, countof(buf), f, &t, __loc_);
4602
  wchar_t wbuf[100];
4603
  wchar_t* wbb   = wbuf;
4604
  mbstate_t mb   = {0};
4605
  const char* bb = buf;
4606
  size_t j       = __libcpp_mbsrtowcs_l(wbb, &bb, countof(wbuf), &mb, __loc_);
4607
  if (j == size_t(-1))
4608
    __throw_runtime_error("locale not supported");
4609
  wchar_t* wbe = wbb + j;
4610
  wstring result;
4611
  while (wbb != wbe) {
4612
    if (ct.is(ctype_base::space, *wbb)) {
4613
      result.push_back(L' ');
4614
      for (++wbb; wbb != wbe && ct.is(ctype_base::space, *wbb); ++wbb)
4615
        ;
4616
      continue;
4617
    }
4618
    wchar_t* w            = wbb;
4619
    ios_base::iostate err = ios_base::goodbit;
4620
    ptrdiff_t i = __scan_keyword(w, wbe, this->__weeks_, this->__weeks_ + 14, ct, err, false) - this->__weeks_;
4621
    if (i < 14) {
4622
      result.push_back(L'%');
4623
      if (i < 7)
4624
        result.push_back(L'A');
4625
      else
4626
        result.push_back(L'a');
4627
      wbb = w;
4628
      continue;
4629
    }
4630
    w = wbb;
4631
    i = __scan_keyword(w, wbe, this->__months_, this->__months_ + 24, ct, err, false) - this->__months_;
4632
    if (i < 24) {
4633
      result.push_back(L'%');
4634
      if (i < 12)
4635
        result.push_back(L'B');
4636
      else
4637
        result.push_back(L'b');
4638
      if (fmt == 'x' && ct.is(ctype_base::digit, this->__months_[i][0]))
4639
        result.back() = L'm';
4640
      wbb = w;
4641
      continue;
4642
    }
4643
    if (this->__am_pm_[0].size() + this->__am_pm_[1].size() > 0) {
4644
      w = wbb;
4645
      i = __scan_keyword(w, wbe, this->__am_pm_, this->__am_pm_ + 2, ct, err, false) - this->__am_pm_;
4646
      if (i < 2) {
4647
        result.push_back(L'%');
4648
        result.push_back(L'p');
4649
        wbb = w;
4650
        continue;
4651
      }
4652
    }
4653
    w = wbb;
4654
    if (ct.is(ctype_base::digit, *wbb)) {
4655
      switch (__get_up_to_n_digits(wbb, wbe, err, ct, 4)) {
4656
      case 6:
4657
        result.push_back(L'%');
4658
        result.push_back(L'w');
4659
        break;
4660
      case 7:
4661
        result.push_back(L'%');
4662
        result.push_back(L'u');
4663
        break;
4664
      case 11:
4665
        result.push_back(L'%');
4666
        result.push_back(L'I');
4667
        break;
4668
      case 12:
4669
        result.push_back(L'%');
4670
        result.push_back(L'm');
4671
        break;
4672
      case 23:
4673
        result.push_back(L'%');
4674
        result.push_back(L'H');
4675
        break;
4676
      case 31:
4677
        result.push_back(L'%');
4678
        result.push_back(L'd');
4679
        break;
4680
      case 55:
4681
        result.push_back(L'%');
4682
        result.push_back(L'M');
4683
        break;
4684
      case 59:
4685
        result.push_back(L'%');
4686
        result.push_back(L'S');
4687
        break;
4688
      case 61:
4689
        result.push_back(L'%');
4690
        result.push_back(L'y');
4691
        break;
4692
      case 364:
4693
        result.push_back(L'%');
4694
        result.push_back(L'j');
4695
        break;
4696
      case 2061:
4697
        result.push_back(L'%');
4698
        result.push_back(L'Y');
4699
        break;
4700
      default:
4701
        for (; w != wbb; ++w)
4702
          result.push_back(*w);
4703
        break;
4704
      }
4705
      continue;
4706
    }
4707
    if (ct.narrow(*wbb, 0) == '%') {
4708
      result.push_back(L'%');
4709
      result.push_back(L'%');
4710
      ++wbb;
4711
      continue;
4712
    }
4713
    result.push_back(*wbb);
4714
    ++wbb;
4715
  }
4716
  return result;
4717
}
4718
#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
4719

4720
template <>
4721
void __time_get_storage<char>::init(const ctype<char>& ct) {
4722
  tm t = {0};
4723
  char buf[100];
4724
  // __weeks_
4725
  for (int i = 0; i < 7; ++i) {
4726
    t.tm_wday = i;
4727
    strftime_l(buf, countof(buf), "%A", &t, __loc_);
4728
    __weeks_[i] = buf;
4729
    strftime_l(buf, countof(buf), "%a", &t, __loc_);
4730
    __weeks_[i + 7] = buf;
4731
  }
4732
  // __months_
4733
  for (int i = 0; i < 12; ++i) {
4734
    t.tm_mon = i;
4735
    strftime_l(buf, countof(buf), "%B", &t, __loc_);
4736
    __months_[i] = buf;
4737
    strftime_l(buf, countof(buf), "%b", &t, __loc_);
4738
    __months_[i + 12] = buf;
4739
  }
4740
  // __am_pm_
4741
  t.tm_hour = 1;
4742
  strftime_l(buf, countof(buf), "%p", &t, __loc_);
4743
  __am_pm_[0] = buf;
4744
  t.tm_hour   = 13;
4745
  strftime_l(buf, countof(buf), "%p", &t, __loc_);
4746
  __am_pm_[1] = buf;
4747
  __c_        = __analyze('c', ct);
4748
  __r_        = __analyze('r', ct);
4749
  __x_        = __analyze('x', ct);
4750
  __X_        = __analyze('X', ct);
4751
}
4752

4753
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4754
template <>
4755
void __time_get_storage<wchar_t>::init(const ctype<wchar_t>& ct) {
4756
  tm t = {0};
4757
  char buf[100];
4758
  wchar_t wbuf[100];
4759
  wchar_t* wbe;
4760
  mbstate_t mb = {0};
4761
  // __weeks_
4762
  for (int i = 0; i < 7; ++i) {
4763
    t.tm_wday = i;
4764
    strftime_l(buf, countof(buf), "%A", &t, __loc_);
4765
    mb             = mbstate_t();
4766
    const char* bb = buf;
4767
    size_t j       = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
4768
    if (j == size_t(-1) || j == 0)
4769
      __throw_runtime_error("locale not supported");
4770
    wbe = wbuf + j;
4771
    __weeks_[i].assign(wbuf, wbe);
4772
    strftime_l(buf, countof(buf), "%a", &t, __loc_);
4773
    mb = mbstate_t();
4774
    bb = buf;
4775
    j  = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
4776
    if (j == size_t(-1) || j == 0)
4777
      __throw_runtime_error("locale not supported");
4778
    wbe = wbuf + j;
4779
    __weeks_[i + 7].assign(wbuf, wbe);
4780
  }
4781
  // __months_
4782
  for (int i = 0; i < 12; ++i) {
4783
    t.tm_mon = i;
4784
    strftime_l(buf, countof(buf), "%B", &t, __loc_);
4785
    mb             = mbstate_t();
4786
    const char* bb = buf;
4787
    size_t j       = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
4788
    if (j == size_t(-1) || j == 0)
4789
      __throw_runtime_error("locale not supported");
4790
    wbe = wbuf + j;
4791
    __months_[i].assign(wbuf, wbe);
4792
    strftime_l(buf, countof(buf), "%b", &t, __loc_);
4793
    mb = mbstate_t();
4794
    bb = buf;
4795
    j  = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
4796
    if (j == size_t(-1) || j == 0)
4797
      __throw_runtime_error("locale not supported");
4798
    wbe = wbuf + j;
4799
    __months_[i + 12].assign(wbuf, wbe);
4800
  }
4801
  // __am_pm_
4802
  t.tm_hour = 1;
4803
  strftime_l(buf, countof(buf), "%p", &t, __loc_);
4804
  mb             = mbstate_t();
4805
  const char* bb = buf;
4806
  size_t j       = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
4807
  if (j == size_t(-1))
4808
    __throw_runtime_error("locale not supported");
4809
  wbe = wbuf + j;
4810
  __am_pm_[0].assign(wbuf, wbe);
4811
  t.tm_hour = 13;
4812
  strftime_l(buf, countof(buf), "%p", &t, __loc_);
4813
  mb = mbstate_t();
4814
  bb = buf;
4815
  j  = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
4816
  if (j == size_t(-1))
4817
    __throw_runtime_error("locale not supported");
4818
  wbe = wbuf + j;
4819
  __am_pm_[1].assign(wbuf, wbe);
4820
  __c_ = __analyze('c', ct);
4821
  __r_ = __analyze('r', ct);
4822
  __x_ = __analyze('x', ct);
4823
  __X_ = __analyze('X', ct);
4824
}
4825
#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
4826

4827
template <class CharT>
4828
struct _LIBCPP_HIDDEN __time_get_temp : public ctype_byname<CharT> {
4829
  explicit __time_get_temp(const char* nm) : ctype_byname<CharT>(nm, 1) {}
4830
  explicit __time_get_temp(const string& nm) : ctype_byname<CharT>(nm, 1) {}
4831
};
4832

4833
template <>
4834
__time_get_storage<char>::__time_get_storage(const char* __nm) : __time_get(__nm) {
4835
  const __time_get_temp<char> ct(__nm);
4836
  init(ct);
4837
}
4838

4839
template <>
4840
__time_get_storage<char>::__time_get_storage(const string& __nm) : __time_get(__nm) {
4841
  const __time_get_temp<char> ct(__nm);
4842
  init(ct);
4843
}
4844

4845
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4846
template <>
4847
__time_get_storage<wchar_t>::__time_get_storage(const char* __nm) : __time_get(__nm) {
4848
  const __time_get_temp<wchar_t> ct(__nm);
4849
  init(ct);
4850
}
4851

4852
template <>
4853
__time_get_storage<wchar_t>::__time_get_storage(const string& __nm) : __time_get(__nm) {
4854
  const __time_get_temp<wchar_t> ct(__nm);
4855
  init(ct);
4856
}
4857
#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
4858

4859
template <>
4860
time_base::dateorder __time_get_storage<char>::__do_date_order() const {
4861
  unsigned i;
4862
  for (i = 0; i < __x_.size(); ++i)
4863
    if (__x_[i] == '%')
4864
      break;
4865
  ++i;
4866
  switch (__x_[i]) {
4867
  case 'y':
4868
  case 'Y':
4869
    for (++i; i < __x_.size(); ++i)
4870
      if (__x_[i] == '%')
4871
        break;
4872
    if (i == __x_.size())
4873
      break;
4874
    ++i;
4875
    switch (__x_[i]) {
4876
    case 'm':
4877
      for (++i; i < __x_.size(); ++i)
4878
        if (__x_[i] == '%')
4879
          break;
4880
      if (i == __x_.size())
4881
        break;
4882
      ++i;
4883
      if (__x_[i] == 'd')
4884
        return time_base::ymd;
4885
      break;
4886
    case 'd':
4887
      for (++i; i < __x_.size(); ++i)
4888
        if (__x_[i] == '%')
4889
          break;
4890
      if (i == __x_.size())
4891
        break;
4892
      ++i;
4893
      if (__x_[i] == 'm')
4894
        return time_base::ydm;
4895
      break;
4896
    }
4897
    break;
4898
  case 'm':
4899
    for (++i; i < __x_.size(); ++i)
4900
      if (__x_[i] == '%')
4901
        break;
4902
    if (i == __x_.size())
4903
      break;
4904
    ++i;
4905
    if (__x_[i] == 'd') {
4906
      for (++i; i < __x_.size(); ++i)
4907
        if (__x_[i] == '%')
4908
          break;
4909
      if (i == __x_.size())
4910
        break;
4911
      ++i;
4912
      if (__x_[i] == 'y' || __x_[i] == 'Y')
4913
        return time_base::mdy;
4914
      break;
4915
    }
4916
    break;
4917
  case 'd':
4918
    for (++i; i < __x_.size(); ++i)
4919
      if (__x_[i] == '%')
4920
        break;
4921
    if (i == __x_.size())
4922
      break;
4923
    ++i;
4924
    if (__x_[i] == 'm') {
4925
      for (++i; i < __x_.size(); ++i)
4926
        if (__x_[i] == '%')
4927
          break;
4928
      if (i == __x_.size())
4929
        break;
4930
      ++i;
4931
      if (__x_[i] == 'y' || __x_[i] == 'Y')
4932
        return time_base::dmy;
4933
      break;
4934
    }
4935
    break;
4936
  }
4937
  return time_base::no_order;
4938
}
4939

4940
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4941
template <>
4942
time_base::dateorder __time_get_storage<wchar_t>::__do_date_order() const {
4943
  unsigned i;
4944
  for (i = 0; i < __x_.size(); ++i)
4945
    if (__x_[i] == L'%')
4946
      break;
4947
  ++i;
4948
  switch (__x_[i]) {
4949
  case L'y':
4950
  case L'Y':
4951
    for (++i; i < __x_.size(); ++i)
4952
      if (__x_[i] == L'%')
4953
        break;
4954
    if (i == __x_.size())
4955
      break;
4956
    ++i;
4957
    switch (__x_[i]) {
4958
    case L'm':
4959
      for (++i; i < __x_.size(); ++i)
4960
        if (__x_[i] == L'%')
4961
          break;
4962
      if (i == __x_.size())
4963
        break;
4964
      ++i;
4965
      if (__x_[i] == L'd')
4966
        return time_base::ymd;
4967
      break;
4968
    case L'd':
4969
      for (++i; i < __x_.size(); ++i)
4970
        if (__x_[i] == L'%')
4971
          break;
4972
      if (i == __x_.size())
4973
        break;
4974
      ++i;
4975
      if (__x_[i] == L'm')
4976
        return time_base::ydm;
4977
      break;
4978
    }
4979
    break;
4980
  case L'm':
4981
    for (++i; i < __x_.size(); ++i)
4982
      if (__x_[i] == L'%')
4983
        break;
4984
    if (i == __x_.size())
4985
      break;
4986
    ++i;
4987
    if (__x_[i] == L'd') {
4988
      for (++i; i < __x_.size(); ++i)
4989
        if (__x_[i] == L'%')
4990
          break;
4991
      if (i == __x_.size())
4992
        break;
4993
      ++i;
4994
      if (__x_[i] == L'y' || __x_[i] == L'Y')
4995
        return time_base::mdy;
4996
      break;
4997
    }
4998
    break;
4999
  case L'd':
5000
    for (++i; i < __x_.size(); ++i)
5001
      if (__x_[i] == L'%')
5002
        break;
5003
    if (i == __x_.size())
5004
      break;
5005
    ++i;
5006
    if (__x_[i] == L'm') {
5007
      for (++i; i < __x_.size(); ++i)
5008
        if (__x_[i] == L'%')
5009
          break;
5010
      if (i == __x_.size())
5011
        break;
5012
      ++i;
5013
      if (__x_[i] == L'y' || __x_[i] == L'Y')
5014
        return time_base::dmy;
5015
      break;
5016
    }
5017
    break;
5018
  }
5019
  return time_base::no_order;
5020
}
5021
#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
5022

5023
// time_put
5024

5025
__time_put::__time_put(const char* nm) : __loc_(newlocale(LC_ALL_MASK, nm, 0)) {
5026
  if (__loc_ == 0)
5027
    __throw_runtime_error(("time_put_byname failed to construct for " + string(nm)).c_str());
5028
}
5029

5030
__time_put::__time_put(const string& nm) : __loc_(newlocale(LC_ALL_MASK, nm.c_str(), 0)) {
5031
  if (__loc_ == 0)
5032
    __throw_runtime_error(("time_put_byname failed to construct for " + nm).c_str());
5033
}
5034

5035
__time_put::~__time_put() {
5036
  if (__loc_ != _LIBCPP_GET_C_LOCALE)
5037
    freelocale(__loc_);
5038
}
5039

5040
void __time_put::__do_put(char* __nb, char*& __ne, const tm* __tm, char __fmt, char __mod) const {
5041
  char fmt[] = {'%', __fmt, __mod, 0};
5042
  if (__mod != 0)
5043
    swap(fmt[1], fmt[2]);
5044
  size_t n = strftime_l(__nb, countof(__nb, __ne), fmt, __tm, __loc_);
5045
  __ne     = __nb + n;
5046
}
5047

5048
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5049
void __time_put::__do_put(wchar_t* __wb, wchar_t*& __we, const tm* __tm, char __fmt, char __mod) const {
5050
  char __nar[100];
5051
  char* __ne = __nar + 100;
5052
  __do_put(__nar, __ne, __tm, __fmt, __mod);
5053
  mbstate_t mb     = {0};
5054
  const char* __nb = __nar;
5055
  size_t j         = __libcpp_mbsrtowcs_l(__wb, &__nb, countof(__wb, __we), &mb, __loc_);
5056
  if (j == size_t(-1))
5057
    __throw_runtime_error("locale not supported");
5058
  __we = __wb + j;
5059
}
5060
#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
5061

5062
// moneypunct_byname
5063

5064
template <class charT>
5065
static void __init_pat(
5066
    money_base::pattern& pat,
5067
    basic_string<charT>& __curr_symbol_,
5068
    bool intl,
5069
    char cs_precedes,
5070
    char sep_by_space,
5071
    char sign_posn,
5072
    charT space_char) {
5073
  const char sign                = static_cast<char>(money_base::sign);
5074
  const char space               = static_cast<char>(money_base::space);
5075
  const char none                = static_cast<char>(money_base::none);
5076
  const char symbol              = static_cast<char>(money_base::symbol);
5077
  const char value               = static_cast<char>(money_base::value);
5078
  const bool symbol_contains_sep = intl && __curr_symbol_.size() == 4;
5079

5080
  // Comments on case branches reflect 'C11 7.11.2.1 The localeconv
5081
  // function'. "Space between sign and symbol or value" means that
5082
  // if the sign is adjacent to the symbol, there's a space between
5083
  // them, and otherwise there's a space between the sign and value.
5084
  //
5085
  // C11's localeconv specifies that the fourth character of an
5086
  // international curr_symbol is used to separate the sign and
5087
  // value when sep_by_space says to do so. C++ can't represent
5088
  // that, so we just use a space.  When sep_by_space says to
5089
  // separate the symbol and value-or-sign with a space, we rearrange the
5090
  // curr_symbol to put its spacing character on the correct side of
5091
  // the symbol.
5092
  //
5093
  // We also need to avoid adding an extra space between the sign
5094
  // and value when the currency symbol is suppressed (by not
5095
  // setting showbase).  We match glibc's strfmon by interpreting
5096
  // sep_by_space==1 as "omit the space when the currency symbol is
5097
  // absent".
5098
  //
5099
  // Users who want to get this right should use ICU instead.
5100

5101
  switch (cs_precedes) {
5102
  case 0: // value before curr_symbol
5103
    if (symbol_contains_sep) {
5104
      // Move the separator to before the symbol, to place it
5105
      // between the value and symbol.
5106
      rotate(__curr_symbol_.begin(), __curr_symbol_.begin() + 3, __curr_symbol_.end());
5107
    }
5108
    switch (sign_posn) {
5109
    case 0: // Parentheses surround the quantity and currency symbol.
5110
      pat.field[0] = sign;
5111
      pat.field[1] = value;
5112
      pat.field[2] = none; // Any space appears in the symbol.
5113
      pat.field[3] = symbol;
5114
      switch (sep_by_space) {
5115
      case 0: // No space separates the currency symbol and value.
5116
              // This case may have changed between C99 and C11;
5117
              // assume the currency symbol matches the intention.
5118
      case 2: // Space between sign and currency or value.
5119
        // The "sign" is two parentheses, so no space here either.
5120
        return;
5121
      case 1: // Space between currency-and-sign or currency and value.
5122
        if (!symbol_contains_sep) {
5123
          // We insert the space into the symbol instead of
5124
          // setting pat.field[2]=space so that when
5125
          // showbase is not set, the space goes away too.
5126
          __curr_symbol_.insert(0, 1, space_char);
5127
        }
5128
        return;
5129
      default:
5130
        break;
5131
      }
5132
      break;
5133
    case 1: // The sign string precedes the quantity and currency symbol.
5134
      pat.field[0] = sign;
5135
      pat.field[3] = symbol;
5136
      switch (sep_by_space) {
5137
      case 0: // No space separates the currency symbol and value.
5138
        pat.field[1] = value;
5139
        pat.field[2] = none;
5140
        return;
5141
      case 1: // Space between currency-and-sign or currency and value.
5142
        pat.field[1] = value;
5143
        pat.field[2] = none;
5144
        if (!symbol_contains_sep) {
5145
          // We insert the space into the symbol instead of
5146
          // setting pat.field[2]=space so that when
5147
          // showbase is not set, the space goes away too.
5148
          __curr_symbol_.insert(0, 1, space_char);
5149
        }
5150
        return;
5151
      case 2: // Space between sign and currency or value.
5152
        pat.field[1] = space;
5153
        pat.field[2] = value;
5154
        if (symbol_contains_sep) {
5155
          // Remove the separator from the symbol, since it
5156
          // has already appeared after the sign.
5157
          __curr_symbol_.erase(__curr_symbol_.begin());
5158
        }
5159
        return;
5160
      default:
5161
        break;
5162
      }
5163
      break;
5164
    case 2: // The sign string succeeds the quantity and currency symbol.
5165
      pat.field[0] = value;
5166
      pat.field[3] = sign;
5167
      switch (sep_by_space) {
5168
      case 0: // No space separates the currency symbol and value.
5169
        pat.field[1] = none;
5170
        pat.field[2] = symbol;
5171
        return;
5172
      case 1: // Space between currency-and-sign or currency and value.
5173
        if (!symbol_contains_sep) {
5174
          // We insert the space into the symbol instead of
5175
          // setting pat.field[1]=space so that when
5176
          // showbase is not set, the space goes away too.
5177
          __curr_symbol_.insert(0, 1, space_char);
5178
        }
5179
        pat.field[1] = none;
5180
        pat.field[2] = symbol;
5181
        return;
5182
      case 2: // Space between sign and currency or value.
5183
        pat.field[1] = symbol;
5184
        pat.field[2] = space;
5185
        if (symbol_contains_sep) {
5186
          // Remove the separator from the symbol, since it
5187
          // should not be removed if showbase is absent.
5188
          __curr_symbol_.erase(__curr_symbol_.begin());
5189
        }
5190
        return;
5191
      default:
5192
        break;
5193
      }
5194
      break;
5195
    case 3: // The sign string immediately precedes the currency symbol.
5196
      pat.field[0] = value;
5197
      pat.field[3] = symbol;
5198
      switch (sep_by_space) {
5199
      case 0: // No space separates the currency symbol and value.
5200
        pat.field[1] = none;
5201
        pat.field[2] = sign;
5202
        return;
5203
      case 1: // Space between currency-and-sign or currency and value.
5204
        pat.field[1] = space;
5205
        pat.field[2] = sign;
5206
        if (symbol_contains_sep) {
5207
          // Remove the separator from the symbol, since it
5208
          // has already appeared before the sign.
5209
          __curr_symbol_.erase(__curr_symbol_.begin());
5210
        }
5211
        return;
5212
      case 2: // Space between sign and currency or value.
5213
        pat.field[1] = sign;
5214
        pat.field[2] = none;
5215
        if (!symbol_contains_sep) {
5216
          // We insert the space into the symbol instead of
5217
          // setting pat.field[2]=space so that when
5218
          // showbase is not set, the space goes away too.
5219
          __curr_symbol_.insert(0, 1, space_char);
5220
        }
5221
        return;
5222
      default:
5223
        break;
5224
      }
5225
      break;
5226
    case 4: // The sign string immediately succeeds the currency symbol.
5227
      pat.field[0] = value;
5228
      pat.field[3] = sign;
5229
      switch (sep_by_space) {
5230
      case 0: // No space separates the currency symbol and value.
5231
        pat.field[1] = none;
5232
        pat.field[2] = symbol;
5233
        return;
5234
      case 1: // Space between currency-and-sign or currency and value.
5235
        pat.field[1] = none;
5236
        pat.field[2] = symbol;
5237
        if (!symbol_contains_sep) {
5238
          // We insert the space into the symbol instead of
5239
          // setting pat.field[1]=space so that when
5240
          // showbase is not set, the space goes away too.
5241
          __curr_symbol_.insert(0, 1, space_char);
5242
        }
5243
        return;
5244
      case 2: // Space between sign and currency or value.
5245
        pat.field[1] = symbol;
5246
        pat.field[2] = space;
5247
        if (symbol_contains_sep) {
5248
          // Remove the separator from the symbol, since it
5249
          // should not disappear when showbase is absent.
5250
          __curr_symbol_.erase(__curr_symbol_.begin());
5251
        }
5252
        return;
5253
      default:
5254
        break;
5255
      }
5256
      break;
5257
    default:
5258
      break;
5259
    }
5260
    break;
5261
  case 1: // curr_symbol before value
5262
    switch (sign_posn) {
5263
    case 0: // Parentheses surround the quantity and currency symbol.
5264
      pat.field[0] = sign;
5265
      pat.field[1] = symbol;
5266
      pat.field[2] = none; // Any space appears in the symbol.
5267
      pat.field[3] = value;
5268
      switch (sep_by_space) {
5269
      case 0: // No space separates the currency symbol and value.
5270
              // This case may have changed between C99 and C11;
5271
              // assume the currency symbol matches the intention.
5272
      case 2: // Space between sign and currency or value.
5273
        // The "sign" is two parentheses, so no space here either.
5274
        return;
5275
      case 1: // Space between currency-and-sign or currency and value.
5276
        if (!symbol_contains_sep) {
5277
          // We insert the space into the symbol instead of
5278
          // setting pat.field[2]=space so that when
5279
          // showbase is not set, the space goes away too.
5280
          __curr_symbol_.insert(0, 1, space_char);
5281
        }
5282
        return;
5283
      default:
5284
        break;
5285
      }
5286
      break;
5287
    case 1: // The sign string precedes the quantity and currency symbol.
5288
      pat.field[0] = sign;
5289
      pat.field[3] = value;
5290
      switch (sep_by_space) {
5291
      case 0: // No space separates the currency symbol and value.
5292
        pat.field[1] = symbol;
5293
        pat.field[2] = none;
5294
        return;
5295
      case 1: // Space between currency-and-sign or currency and value.
5296
        pat.field[1] = symbol;
5297
        pat.field[2] = none;
5298
        if (!symbol_contains_sep) {
5299
          // We insert the space into the symbol instead of
5300
          // setting pat.field[2]=space so that when
5301
          // showbase is not set, the space goes away too.
5302
          __curr_symbol_.push_back(space_char);
5303
        }
5304
        return;
5305
      case 2: // Space between sign and currency or value.
5306
        pat.field[1] = space;
5307
        pat.field[2] = symbol;
5308
        if (symbol_contains_sep) {
5309
          // Remove the separator from the symbol, since it
5310
          // has already appeared after the sign.
5311
          __curr_symbol_.pop_back();
5312
        }
5313
        return;
5314
      default:
5315
        break;
5316
      }
5317
      break;
5318
    case 2: // The sign string succeeds the quantity and currency symbol.
5319
      pat.field[0] = symbol;
5320
      pat.field[3] = sign;
5321
      switch (sep_by_space) {
5322
      case 0: // No space separates the currency symbol and value.
5323
        pat.field[1] = none;
5324
        pat.field[2] = value;
5325
        return;
5326
      case 1: // Space between currency-and-sign or currency and value.
5327
        pat.field[1] = none;
5328
        pat.field[2] = value;
5329
        if (!symbol_contains_sep) {
5330
          // We insert the space into the symbol instead of
5331
          // setting pat.field[1]=space so that when
5332
          // showbase is not set, the space goes away too.
5333
          __curr_symbol_.push_back(space_char);
5334
        }
5335
        return;
5336
      case 2: // Space between sign and currency or value.
5337
        pat.field[1] = value;
5338
        pat.field[2] = space;
5339
        if (symbol_contains_sep) {
5340
          // Remove the separator from the symbol, since it
5341
          // will appear before the sign.
5342
          __curr_symbol_.pop_back();
5343
        }
5344
        return;
5345
      default:
5346
        break;
5347
      }
5348
      break;
5349
    case 3: // The sign string immediately precedes the currency symbol.
5350
      pat.field[0] = sign;
5351
      pat.field[3] = value;
5352
      switch (sep_by_space) {
5353
      case 0: // No space separates the currency symbol and value.
5354
        pat.field[1] = symbol;
5355
        pat.field[2] = none;
5356
        return;
5357
      case 1: // Space between currency-and-sign or currency and value.
5358
        pat.field[1] = symbol;
5359
        pat.field[2] = none;
5360
        if (!symbol_contains_sep) {
5361
          // We insert the space into the symbol instead of
5362
          // setting pat.field[2]=space so that when
5363
          // showbase is not set, the space goes away too.
5364
          __curr_symbol_.push_back(space_char);
5365
        }
5366
        return;
5367
      case 2: // Space between sign and currency or value.
5368
        pat.field[1] = space;
5369
        pat.field[2] = symbol;
5370
        if (symbol_contains_sep) {
5371
          // Remove the separator from the symbol, since it
5372
          // has already appeared after the sign.
5373
          __curr_symbol_.pop_back();
5374
        }
5375
        return;
5376
      default:
5377
        break;
5378
      }
5379
      break;
5380
    case 4: // The sign string immediately succeeds the currency symbol.
5381
      pat.field[0] = symbol;
5382
      pat.field[3] = value;
5383
      switch (sep_by_space) {
5384
      case 0: // No space separates the currency symbol and value.
5385
        pat.field[1] = sign;
5386
        pat.field[2] = none;
5387
        return;
5388
      case 1: // Space between currency-and-sign or currency and value.
5389
        pat.field[1] = sign;
5390
        pat.field[2] = space;
5391
        if (symbol_contains_sep) {
5392
          // Remove the separator from the symbol, since it
5393
          // should not disappear when showbase is absent.
5394
          __curr_symbol_.pop_back();
5395
        }
5396
        return;
5397
      case 2: // Space between sign and currency or value.
5398
        pat.field[1] = none;
5399
        pat.field[2] = sign;
5400
        if (!symbol_contains_sep) {
5401
          // We insert the space into the symbol instead of
5402
          // setting pat.field[1]=space so that when
5403
          // showbase is not set, the space goes away too.
5404
          __curr_symbol_.push_back(space_char);
5405
        }
5406
        return;
5407
      default:
5408
        break;
5409
      }
5410
      break;
5411
    default:
5412
      break;
5413
    }
5414
    break;
5415
  default:
5416
    break;
5417
  }
5418
  pat.field[0] = symbol;
5419
  pat.field[1] = sign;
5420
  pat.field[2] = none;
5421
  pat.field[3] = value;
5422
}
5423

5424
template <>
5425
void moneypunct_byname<char, false>::init(const char* nm) {
5426
  typedef moneypunct<char, false> base;
5427
  __libcpp_unique_locale loc(nm);
5428
  if (!loc)
5429
    __throw_runtime_error(("moneypunct_byname failed to construct for " + string(nm)).c_str());
5430

5431
  lconv* lc = __libcpp_localeconv_l(loc.get());
5432
  if (!checked_string_to_char_convert(__decimal_point_, lc->mon_decimal_point, loc.get()))
5433
    __decimal_point_ = base::do_decimal_point();
5434
  if (!checked_string_to_char_convert(__thousands_sep_, lc->mon_thousands_sep, loc.get()))
5435
    __thousands_sep_ = base::do_thousands_sep();
5436

5437
  __grouping_    = lc->mon_grouping;
5438
  __curr_symbol_ = lc->currency_symbol;
5439
  if (lc->frac_digits != CHAR_MAX)
5440
    __frac_digits_ = lc->frac_digits;
5441
  else
5442
    __frac_digits_ = base::do_frac_digits();
5443
  if (lc->p_sign_posn == 0)
5444
    __positive_sign_ = "()";
5445
  else
5446
    __positive_sign_ = lc->positive_sign;
5447
  if (lc->n_sign_posn == 0)
5448
    __negative_sign_ = "()";
5449
  else
5450
    __negative_sign_ = lc->negative_sign;
5451
  // Assume the positive and negative formats will want spaces in
5452
  // the same places in curr_symbol since there's no way to
5453
  // represent anything else.
5454
  string_type __dummy_curr_symbol = __curr_symbol_;
5455
  __init_pat(__pos_format_, __dummy_curr_symbol, false, lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, ' ');
5456
  __init_pat(__neg_format_, __curr_symbol_, false, lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, ' ');
5457
}
5458

5459
template <>
5460
void moneypunct_byname<char, true>::init(const char* nm) {
5461
  typedef moneypunct<char, true> base;
5462
  __libcpp_unique_locale loc(nm);
5463
  if (!loc)
5464
    __throw_runtime_error(("moneypunct_byname failed to construct for " + string(nm)).c_str());
5465

5466
  lconv* lc = __libcpp_localeconv_l(loc.get());
5467
  if (!checked_string_to_char_convert(__decimal_point_, lc->mon_decimal_point, loc.get()))
5468
    __decimal_point_ = base::do_decimal_point();
5469
  if (!checked_string_to_char_convert(__thousands_sep_, lc->mon_thousands_sep, loc.get()))
5470
    __thousands_sep_ = base::do_thousands_sep();
5471
  __grouping_    = lc->mon_grouping;
5472
  __curr_symbol_ = lc->int_curr_symbol;
5473
  if (lc->int_frac_digits != CHAR_MAX)
5474
    __frac_digits_ = lc->int_frac_digits;
5475
  else
5476
    __frac_digits_ = base::do_frac_digits();
5477
#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
5478
  if (lc->p_sign_posn == 0)
5479
#else  // _LIBCPP_MSVCRT
5480
  if (lc->int_p_sign_posn == 0)
5481
#endif // !_LIBCPP_MSVCRT
5482
    __positive_sign_ = "()";
5483
  else
5484
    __positive_sign_ = lc->positive_sign;
5485
#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
5486
  if (lc->n_sign_posn == 0)
5487
#else  // _LIBCPP_MSVCRT
5488
  if (lc->int_n_sign_posn == 0)
5489
#endif // !_LIBCPP_MSVCRT
5490
    __negative_sign_ = "()";
5491
  else
5492
    __negative_sign_ = lc->negative_sign;
5493
  // Assume the positive and negative formats will want spaces in
5494
  // the same places in curr_symbol since there's no way to
5495
  // represent anything else.
5496
  string_type __dummy_curr_symbol = __curr_symbol_;
5497
#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
5498
  __init_pat(__pos_format_, __dummy_curr_symbol, true, lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, ' ');
5499
  __init_pat(__neg_format_, __curr_symbol_, true, lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, ' ');
5500
#else  // _LIBCPP_MSVCRT
5501
  __init_pat(
5502
      __pos_format_,
5503
      __dummy_curr_symbol,
5504
      true,
5505
      lc->int_p_cs_precedes,
5506
      lc->int_p_sep_by_space,
5507
      lc->int_p_sign_posn,
5508
      ' ');
5509
  __init_pat(
5510
      __neg_format_, __curr_symbol_, true, lc->int_n_cs_precedes, lc->int_n_sep_by_space, lc->int_n_sign_posn, ' ');
5511
#endif // !_LIBCPP_MSVCRT
5512
}
5513

5514
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5515
template <>
5516
void moneypunct_byname<wchar_t, false>::init(const char* nm) {
5517
  typedef moneypunct<wchar_t, false> base;
5518
  __libcpp_unique_locale loc(nm);
5519
  if (!loc)
5520
    __throw_runtime_error(("moneypunct_byname failed to construct for " + string(nm)).c_str());
5521
  lconv* lc = __libcpp_localeconv_l(loc.get());
5522
  if (!checked_string_to_wchar_convert(__decimal_point_, lc->mon_decimal_point, loc.get()))
5523
    __decimal_point_ = base::do_decimal_point();
5524
  if (!checked_string_to_wchar_convert(__thousands_sep_, lc->mon_thousands_sep, loc.get()))
5525
    __thousands_sep_ = base::do_thousands_sep();
5526
  __grouping_ = lc->mon_grouping;
5527
  wchar_t wbuf[100];
5528
  mbstate_t mb   = {0};
5529
  const char* bb = lc->currency_symbol;
5530
  size_t j       = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
5531
  if (j == size_t(-1))
5532
    __throw_runtime_error("locale not supported");
5533
  wchar_t* wbe = wbuf + j;
5534
  __curr_symbol_.assign(wbuf, wbe);
5535
  if (lc->frac_digits != CHAR_MAX)
5536
    __frac_digits_ = lc->frac_digits;
5537
  else
5538
    __frac_digits_ = base::do_frac_digits();
5539
  if (lc->p_sign_posn == 0)
5540
    __positive_sign_ = L"()";
5541
  else {
5542
    mb = mbstate_t();
5543
    bb = lc->positive_sign;
5544
    j  = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
5545
    if (j == size_t(-1))
5546
      __throw_runtime_error("locale not supported");
5547
    wbe = wbuf + j;
5548
    __positive_sign_.assign(wbuf, wbe);
5549
  }
5550
  if (lc->n_sign_posn == 0)
5551
    __negative_sign_ = L"()";
5552
  else {
5553
    mb = mbstate_t();
5554
    bb = lc->negative_sign;
5555
    j  = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
5556
    if (j == size_t(-1))
5557
      __throw_runtime_error("locale not supported");
5558
    wbe = wbuf + j;
5559
    __negative_sign_.assign(wbuf, wbe);
5560
  }
5561
  // Assume the positive and negative formats will want spaces in
5562
  // the same places in curr_symbol since there's no way to
5563
  // represent anything else.
5564
  string_type __dummy_curr_symbol = __curr_symbol_;
5565
  __init_pat(__pos_format_, __dummy_curr_symbol, false, lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, L' ');
5566
  __init_pat(__neg_format_, __curr_symbol_, false, lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, L' ');
5567
}
5568

5569
template <>
5570
void moneypunct_byname<wchar_t, true>::init(const char* nm) {
5571
  typedef moneypunct<wchar_t, true> base;
5572
  __libcpp_unique_locale loc(nm);
5573
  if (!loc)
5574
    __throw_runtime_error(("moneypunct_byname failed to construct for " + string(nm)).c_str());
5575

5576
  lconv* lc = __libcpp_localeconv_l(loc.get());
5577
  if (!checked_string_to_wchar_convert(__decimal_point_, lc->mon_decimal_point, loc.get()))
5578
    __decimal_point_ = base::do_decimal_point();
5579
  if (!checked_string_to_wchar_convert(__thousands_sep_, lc->mon_thousands_sep, loc.get()))
5580
    __thousands_sep_ = base::do_thousands_sep();
5581
  __grouping_ = lc->mon_grouping;
5582
  wchar_t wbuf[100];
5583
  mbstate_t mb   = {0};
5584
  const char* bb = lc->int_curr_symbol;
5585
  size_t j       = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
5586
  if (j == size_t(-1))
5587
    __throw_runtime_error("locale not supported");
5588
  wchar_t* wbe = wbuf + j;
5589
  __curr_symbol_.assign(wbuf, wbe);
5590
  if (lc->int_frac_digits != CHAR_MAX)
5591
    __frac_digits_ = lc->int_frac_digits;
5592
  else
5593
    __frac_digits_ = base::do_frac_digits();
5594
#  if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
5595
  if (lc->p_sign_posn == 0)
5596
#  else  // _LIBCPP_MSVCRT
5597
  if (lc->int_p_sign_posn == 0)
5598
#  endif // !_LIBCPP_MSVCRT
5599
    __positive_sign_ = L"()";
5600
  else {
5601
    mb = mbstate_t();
5602
    bb = lc->positive_sign;
5603
    j  = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
5604
    if (j == size_t(-1))
5605
      __throw_runtime_error("locale not supported");
5606
    wbe = wbuf + j;
5607
    __positive_sign_.assign(wbuf, wbe);
5608
  }
5609
#  if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
5610
  if (lc->n_sign_posn == 0)
5611
#  else  // _LIBCPP_MSVCRT
5612
  if (lc->int_n_sign_posn == 0)
5613
#  endif // !_LIBCPP_MSVCRT
5614
    __negative_sign_ = L"()";
5615
  else {
5616
    mb = mbstate_t();
5617
    bb = lc->negative_sign;
5618
    j  = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
5619
    if (j == size_t(-1))
5620
      __throw_runtime_error("locale not supported");
5621
    wbe = wbuf + j;
5622
    __negative_sign_.assign(wbuf, wbe);
5623
  }
5624
  // Assume the positive and negative formats will want spaces in
5625
  // the same places in curr_symbol since there's no way to
5626
  // represent anything else.
5627
  string_type __dummy_curr_symbol = __curr_symbol_;
5628
#  if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
5629
  __init_pat(__pos_format_, __dummy_curr_symbol, true, lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, L' ');
5630
  __init_pat(__neg_format_, __curr_symbol_, true, lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, L' ');
5631
#  else  // _LIBCPP_MSVCRT
5632
  __init_pat(
5633
      __pos_format_,
5634
      __dummy_curr_symbol,
5635
      true,
5636
      lc->int_p_cs_precedes,
5637
      lc->int_p_sep_by_space,
5638
      lc->int_p_sign_posn,
5639
      L' ');
5640
  __init_pat(
5641
      __neg_format_, __curr_symbol_, true, lc->int_n_cs_precedes, lc->int_n_sep_by_space, lc->int_n_sign_posn, L' ');
5642
#  endif // !_LIBCPP_MSVCRT
5643
}
5644
#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
5645

5646
void __do_nothing(void*) {}
5647

5648
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS collate<char>;
5649
_LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS collate<wchar_t>;)
5650

5651
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS num_get<char>;
5652
_LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS num_get<wchar_t>;)
5653

5654
template struct _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __num_get<char>;
5655
_LIBCPP_IF_WIDE_CHARACTERS(template struct _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __num_get<wchar_t>;)
5656

5657
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS num_put<char>;
5658
_LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS num_put<wchar_t>;)
5659

5660
template struct _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __num_put<char>;
5661
_LIBCPP_IF_WIDE_CHARACTERS(template struct _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __num_put<wchar_t>;)
5662

5663
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_get<char>;
5664
_LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_get<wchar_t>;)
5665

5666
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_get_byname<char>;
5667
_LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_get_byname<wchar_t>;)
5668

5669
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_put<char>;
5670
_LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_put<wchar_t>;)
5671

5672
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_put_byname<char>;
5673
_LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_put_byname<wchar_t>;)
5674

5675
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct<char, false>;
5676
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct<char, true>;
5677
_LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct<wchar_t, false>;)
5678
_LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct<wchar_t, true>;)
5679

5680
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname<char, false>;
5681
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname<char, true>;
5682
_LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname<wchar_t, false>;)
5683
_LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname<wchar_t, true>;)
5684

5685
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_get<char>;
5686
_LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_get<wchar_t>;)
5687

5688
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_get<char>;
5689
_LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_get<wchar_t>;)
5690

5691
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_put<char>;
5692
_LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_put<wchar_t>;)
5693

5694
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_put<char>;
5695
_LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_put<wchar_t>;)
5696

5697
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages<char>;
5698
_LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages<wchar_t>;)
5699

5700
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages_byname<char>;
5701
_LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages_byname<wchar_t>;)
5702

5703
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<char, char, mbstate_t>;
5704
_LIBCPP_IF_WIDE_CHARACTERS(
5705
    template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<wchar_t, char, mbstate_t>;)
5706
template class _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS
5707
    codecvt_byname<char16_t, char, mbstate_t>;
5708
template class _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS
5709
    codecvt_byname<char32_t, char, mbstate_t>;
5710
#ifndef _LIBCPP_HAS_NO_CHAR8_T
5711
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<char16_t, char8_t, mbstate_t>;
5712
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<char32_t, char8_t, mbstate_t>;
5713
#endif
5714

5715
_LIBCPP_END_NAMESPACE_STD
5716

5717
_LIBCPP_POP_MACROS
5718

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.