From 8dd4ec68d06406671e2574aac780427fab3c5ca8 Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Sun, 4 Sep 2022 04:53:52 -0700 Subject: [PATCH] Add more missing C / C++ headers --- dsp/mpeg/buffer.c | 4 +- dsp/mpeg/mp2.c | 2 +- libc/integral/c.inc | 1 - libc/intrin/asan.c | 4 +- libc/iso646.internal.h | 18 + libc/isystem/algorithm | 4 + libc/isystem/any | 4 + libc/isystem/array | 4 + libc/isystem/atomic | 4 + libc/isystem/bit | 4 + libc/isystem/bitset | 4 + libc/isystem/cassert | 4 + libc/isystem/ccomplex | 4 + libc/isystem/cctype | 4 + libc/isystem/cerrno | 4 + libc/isystem/cfenv | 4 + libc/isystem/cfloat | 4 + libc/isystem/charconv | 4 + libc/isystem/chrono | 4 + libc/isystem/cinttypes | 4 + libc/isystem/ciso646 | 4 + libc/isystem/climits | 4 + libc/isystem/clocale | 4 + libc/isystem/cmath | 4 + libc/isystem/codecvt | 4 + libc/isystem/compare | 4 + libc/isystem/complex | 4 + libc/isystem/condition_variable | 4 + libc/isystem/csetjmp | 4 + libc/isystem/csignal | 4 + libc/isystem/cstdarg | 4 + libc/isystem/cstdbool | 4 + libc/isystem/cstddef | 4 + libc/isystem/cstdint | 4 + libc/isystem/cstdio | 4 + libc/isystem/cstdlib | 4 + libc/isystem/cstring | 4 + libc/isystem/ctgmath | 4 + libc/isystem/ctime | 4 + libc/isystem/cwchar | 4 + libc/isystem/cwctype | 4 + libc/isystem/deque | 4 + libc/isystem/exception | 4 + libc/isystem/execution | 4 + libc/isystem/fenv.h | 4 + libc/isystem/filesystem | 4 + libc/isystem/forward_list | 4 + libc/isystem/fstream | 4 + libc/isystem/functional | 4 + libc/isystem/initializer_list | 4 + libc/isystem/inttypes.h | 1 + libc/isystem/iomanip | 4 + libc/isystem/ios | 4 + libc/isystem/iosfwd | 4 + libc/isystem/iostream | 4 + libc/isystem/iso646.h | 14 +- libc/isystem/istream | 4 + libc/isystem/iterator | 4 + libc/isystem/limits | 4 + libc/isystem/list | 4 + libc/isystem/locale | 4 + libc/isystem/map | 4 + libc/isystem/memory | 4 + libc/isystem/mutex | 4 + libc/isystem/new | 4 + libc/isystem/numeric | 4 + libc/isystem/optional | 4 + libc/isystem/ostream | 4 + libc/isystem/queue | 4 + libc/isystem/random | 4 + libc/isystem/ratio | 4 + libc/isystem/regex | 4 + libc/isystem/scoped_allocator | 4 + libc/isystem/set | 4 + libc/isystem/sstream | 4 + libc/isystem/stack | 4 + libc/isystem/stdalign.h | 4 + libc/isystem/stdexcept | 4 + libc/isystem/streambuf | 4 + libc/isystem/string | 4 + libc/isystem/string_view | 4 + libc/isystem/strstream | 4 + libc/isystem/system_error | 4 + libc/isystem/thread | 4 + libc/isystem/tuple | 4 + libc/isystem/type_traits | 4 + libc/isystem/typeindex | 4 + libc/isystem/typeinfo | 4 + libc/isystem/uchar.h | 4 + libc/isystem/unordered_map | 4 + libc/isystem/unordered_set | 4 + libc/isystem/utility | 4 + libc/isystem/valarray | 4 + libc/isystem/variant | 4 + libc/isystem/vector | 4 + libc/isystem/version | 4 + libc/macros.internal.h | 2 - libc/nexgen32e/nexgen32e.h | 1 - libc/runtime/clone.c | 1 + libc/runtime/enable_tls.c | 1 + libc/stdalign.internal.h | 12 + libc/str/insertionsort.greg.c | 38 - libc/str/str.h | 2 +- libc/str/str.mk | 2 + libc/str/wmemcmp.c | 50 +- libc/str/wmemcpy.c | 4 +- libc/str/wmemmove.c | 4 +- libc/str/wmempcpy.c | 4 +- libc/str/wmemrchr.c | 8 +- libc/str/wmemset.c | 12 +- libc/thread/mktls.c | 2 +- libc/thread/spawn.c | 1 + test/libc/intrin/memset_test.c | 9 +- test/libc/mem/djbsort_test.c | 18 +- test/libc/str/wmemrchr_test.c | 2 - third_party/libcxx/README.cosmo | 18 +- third_party/libcxx/__config | 1 + third_party/libcxx/any | 672 +++ third_party/libcxx/ccomplex | 29 + third_party/libcxx/cfenv | 82 + third_party/libcxx/cfloat | 81 + third_party/libcxx/cinttypes | 259 + third_party/libcxx/ciso646 | 25 + third_party/libcxx/compare | 679 +++ third_party/libcxx/complex | 1496 ++++++ third_party/libcxx/countof.internal.hh | 20 + third_party/libcxx/csetjmp | 48 + third_party/libcxx/csignal | 62 + third_party/libcxx/cstdbool | 32 + third_party/libcxx/ctgmath | 29 + third_party/libcxx/execution | 20 + third_party/libcxx/filesystem | 2645 ++++++++++ third_party/libcxx/forward_list | 1782 +++++++ third_party/libcxx/fstream | 1764 +++++++ third_party/libcxx/iomanip | 671 +++ third_party/libcxx/libcxx.mk | 35 +- third_party/libcxx/locale.cc | 6146 ---------------------- third_party/libcxx/locale1.cc | 1660 ++++++ third_party/libcxx/locale2.cc | 2904 +++++++++++ third_party/libcxx/locale3.cc | 723 +++ third_party/libcxx/locale4.cc | 1010 ++++ third_party/libcxx/regex | 6663 ++++++++++++++++++++++++ third_party/libcxx/regex.cc | 315 ++ third_party/libcxx/scoped_allocator | 684 +++ third_party/libcxx/strstream | 400 ++ third_party/libcxx/strstream.cc | 336 ++ third_party/libcxx/typeindex | 103 + third_party/libcxx/valarray | 4943 ++++++++++++++++++ third_party/libcxx/valarray.cc | 58 + tool/build/lib/elfwriter.c | 1 + tool/build/lib/memorymalloc.c | 2 +- tool/emacs/cosmo-stuff.el | 7 +- 152 files changed, 30711 insertions(+), 6267 deletions(-) create mode 100644 libc/iso646.internal.h create mode 100644 libc/isystem/algorithm create mode 100644 libc/isystem/any create mode 100644 libc/isystem/array create mode 100644 libc/isystem/atomic create mode 100644 libc/isystem/bit create mode 100644 libc/isystem/bitset create mode 100644 libc/isystem/cassert create mode 100644 libc/isystem/ccomplex create mode 100644 libc/isystem/cctype create mode 100644 libc/isystem/cerrno create mode 100644 libc/isystem/cfenv create mode 100644 libc/isystem/cfloat create mode 100644 libc/isystem/charconv create mode 100644 libc/isystem/chrono create mode 100644 libc/isystem/cinttypes create mode 100644 libc/isystem/ciso646 create mode 100644 libc/isystem/climits create mode 100644 libc/isystem/clocale create mode 100644 libc/isystem/cmath create mode 100644 libc/isystem/codecvt create mode 100644 libc/isystem/compare create mode 100644 libc/isystem/complex create mode 100644 libc/isystem/condition_variable create mode 100644 libc/isystem/csetjmp create mode 100644 libc/isystem/csignal create mode 100644 libc/isystem/cstdarg create mode 100644 libc/isystem/cstdbool create mode 100644 libc/isystem/cstddef create mode 100644 libc/isystem/cstdint create mode 100644 libc/isystem/cstdio create mode 100644 libc/isystem/cstdlib create mode 100644 libc/isystem/cstring create mode 100644 libc/isystem/ctgmath create mode 100644 libc/isystem/ctime create mode 100644 libc/isystem/cwchar create mode 100644 libc/isystem/cwctype create mode 100644 libc/isystem/deque create mode 100644 libc/isystem/exception create mode 100644 libc/isystem/execution create mode 100644 libc/isystem/fenv.h create mode 100644 libc/isystem/filesystem create mode 100644 libc/isystem/forward_list create mode 100644 libc/isystem/fstream create mode 100644 libc/isystem/functional create mode 100644 libc/isystem/initializer_list create mode 100644 libc/isystem/iomanip create mode 100644 libc/isystem/ios create mode 100644 libc/isystem/iosfwd create mode 100644 libc/isystem/iostream create mode 100644 libc/isystem/istream create mode 100644 libc/isystem/iterator create mode 100644 libc/isystem/limits create mode 100644 libc/isystem/list create mode 100644 libc/isystem/locale create mode 100644 libc/isystem/map create mode 100644 libc/isystem/memory create mode 100644 libc/isystem/mutex create mode 100644 libc/isystem/new create mode 100644 libc/isystem/numeric create mode 100644 libc/isystem/optional create mode 100644 libc/isystem/ostream create mode 100644 libc/isystem/queue create mode 100644 libc/isystem/random create mode 100644 libc/isystem/ratio create mode 100644 libc/isystem/regex create mode 100644 libc/isystem/scoped_allocator create mode 100644 libc/isystem/set create mode 100644 libc/isystem/sstream create mode 100644 libc/isystem/stack create mode 100644 libc/isystem/stdalign.h create mode 100644 libc/isystem/stdexcept create mode 100644 libc/isystem/streambuf create mode 100644 libc/isystem/string create mode 100644 libc/isystem/string_view create mode 100644 libc/isystem/strstream create mode 100644 libc/isystem/system_error create mode 100644 libc/isystem/thread create mode 100644 libc/isystem/tuple create mode 100644 libc/isystem/type_traits create mode 100644 libc/isystem/typeindex create mode 100644 libc/isystem/typeinfo create mode 100644 libc/isystem/uchar.h create mode 100644 libc/isystem/unordered_map create mode 100644 libc/isystem/unordered_set create mode 100644 libc/isystem/utility create mode 100644 libc/isystem/valarray create mode 100644 libc/isystem/variant create mode 100644 libc/isystem/vector create mode 100644 libc/isystem/version create mode 100644 libc/stdalign.internal.h delete mode 100644 libc/str/insertionsort.greg.c create mode 100644 third_party/libcxx/any create mode 100644 third_party/libcxx/ccomplex create mode 100644 third_party/libcxx/cfenv create mode 100644 third_party/libcxx/cfloat create mode 100644 third_party/libcxx/cinttypes create mode 100644 third_party/libcxx/ciso646 create mode 100644 third_party/libcxx/compare create mode 100644 third_party/libcxx/complex create mode 100644 third_party/libcxx/countof.internal.hh create mode 100644 third_party/libcxx/csetjmp create mode 100644 third_party/libcxx/csignal create mode 100644 third_party/libcxx/cstdbool create mode 100644 third_party/libcxx/ctgmath create mode 100644 third_party/libcxx/execution create mode 100644 third_party/libcxx/filesystem create mode 100644 third_party/libcxx/forward_list create mode 100644 third_party/libcxx/fstream create mode 100644 third_party/libcxx/iomanip delete mode 100644 third_party/libcxx/locale.cc create mode 100644 third_party/libcxx/locale1.cc create mode 100644 third_party/libcxx/locale2.cc create mode 100644 third_party/libcxx/locale3.cc create mode 100644 third_party/libcxx/locale4.cc create mode 100644 third_party/libcxx/regex create mode 100644 third_party/libcxx/regex.cc create mode 100644 third_party/libcxx/scoped_allocator create mode 100644 third_party/libcxx/strstream create mode 100644 third_party/libcxx/strstream.cc create mode 100644 third_party/libcxx/typeindex create mode 100644 third_party/libcxx/valarray create mode 100644 third_party/libcxx/valarray.cc diff --git a/dsp/mpeg/buffer.c b/dsp/mpeg/buffer.c index d383de753..533dd9486 100644 --- a/dsp/mpeg/buffer.c +++ b/dsp/mpeg/buffer.c @@ -67,7 +67,7 @@ plm_buffer_t *plm_buffer_create_with_file(FILE *fh, int close_when_done) { plm_buffer_t *plm_buffer_create_with_memory(unsigned char *bytes, size_t length, int free_when_done) { plm_buffer_t *b; - b = memalign(alignof(plm_buffer_t), sizeof(plm_buffer_t)); + b = memalign(_Alignof(plm_buffer_t), sizeof(plm_buffer_t)); memset(b, 0, sizeof(plm_buffer_t)); b->capacity = length; b->length = length; @@ -79,7 +79,7 @@ plm_buffer_t *plm_buffer_create_with_memory(unsigned char *bytes, size_t length, plm_buffer_t * plm_buffer_create_with_capacity(size_t capacity) { plm_buffer_t *b; - b = memalign(alignof(plm_buffer_t), sizeof(plm_buffer_t)); + b = memalign(_Alignof(plm_buffer_t), sizeof(plm_buffer_t)); memset(b, 0, sizeof(plm_buffer_t)); b->capacity = capacity; b->free_when_done = true; diff --git a/dsp/mpeg/mp2.c b/dsp/mpeg/mp2.c index 405082d06..d40c9158f 100644 --- a/dsp/mpeg/mp2.c +++ b/dsp/mpeg/mp2.c @@ -277,7 +277,7 @@ void plm_audio_read_samples(plm_audio_t *self, int ch, int sb, int part); void plm_audio_matrix_transform(int s[32][3], int ss, float *d, int dp); plm_audio_t *plm_audio_create_with_buffer(plm_buffer_t *buffer, int destroy_when_done) { - plm_audio_t *self = (plm_audio_t *)memalign(alignof(plm_audio_t), sizeof(plm_audio_t)); + plm_audio_t *self = (plm_audio_t *)memalign(_Alignof(plm_audio_t), sizeof(plm_audio_t)); memset(self, 0, sizeof(plm_audio_t)); self->samples.count = PLM_AUDIO_SAMPLES_PER_FRAME; diff --git a/libc/integral/c.inc b/libc/integral/c.inc index fe1839805..f37ae177a 100644 --- a/libc/integral/c.inc +++ b/libc/integral/c.inc @@ -26,7 +26,6 @@ #define _Alignof(x) alignof(x) #endif /* C++11 */ #else /* __cplusplus */ -#define alignof(x) _Alignof(x) #if __STDC_VERSION__ + 0 < 201112 #if __GNUC__ + _MSC_VER + 0 && !defined(__STRICT_ANSI__) #define _Alignof(x) __alignof(x) diff --git a/libc/intrin/asan.c b/libc/intrin/asan.c index 810834912..ef29990a2 100644 --- a/libc/intrin/asan.c +++ b/libc/intrin/asan.c @@ -898,7 +898,7 @@ static size_t __asan_user_size(size_t n) { static size_t __asan_heap_size(size_t n) { if (n < 0x7fffffff0000) { - n = ROUNDUP(n, alignof(struct AsanExtra)); + n = ROUNDUP(n, _Alignof(struct AsanExtra)); return __asan_roundup2pow(n + sizeof(struct AsanExtra)); } else { return -1; @@ -990,7 +990,7 @@ static struct AsanExtra *__asan_get_extra(const void *p, size_t *c) { (LIKELY(f == (int)((x - 1) >> 16)) || !kisdangerous((void *)(x - 1))) && (LIKELY(f == (int)((x = x - sizeof(*e)) >> 16)) || __asan_is_mapped(x >> 16)) && - !(x & (alignof(struct AsanExtra) - 1))) { + !(x & (_Alignof(struct AsanExtra) - 1))) { *c = n; return (struct AsanExtra *)x; } else { diff --git a/libc/iso646.internal.h b/libc/iso646.internal.h new file mode 100644 index 000000000..e96f85389 --- /dev/null +++ b/libc/iso646.internal.h @@ -0,0 +1,18 @@ +#ifndef COSMOPOLITAN_LIBC_ISO646_H_ +#define COSMOPOLITAN_LIBC_ISO646_H_ + +#ifndef __cplusplus +#define and && +#define and_eq &= +#define bitand & +#define bitor | +#define compl ~ +#define not ! +#define not_eq != +#define or || +#define or_eq |= +#define xor ^ +#define xor_eq ^= +#endif /* __cplusplus */ + +#endif /* COSMOPOLITAN_LIBC_ISO646_H_ */ diff --git a/libc/isystem/algorithm b/libc/isystem/algorithm new file mode 100644 index 000000000..aee595c89 --- /dev/null +++ b/libc/isystem/algorithm @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_ALGORITHM_ +#define COSMOPOLITAN_LIBC_ISYSTEM_ALGORITHM_ +#include "third_party/libcxx/algorithm" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_ALGORITHM_ */ diff --git a/libc/isystem/any b/libc/isystem/any new file mode 100644 index 000000000..338966d53 --- /dev/null +++ b/libc/isystem/any @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_ANY_ +#define COSMOPOLITAN_LIBC_ISYSTEM_ANY_ +#include "third_party/libcxx/any" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_ANY_ */ diff --git a/libc/isystem/array b/libc/isystem/array new file mode 100644 index 000000000..875dc271e --- /dev/null +++ b/libc/isystem/array @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_ARRAY_ +#define COSMOPOLITAN_LIBC_ISYSTEM_ARRAY_ +#include "third_party/libcxx/array" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_ARRAY_ */ diff --git a/libc/isystem/atomic b/libc/isystem/atomic new file mode 100644 index 000000000..e2ebebde8 --- /dev/null +++ b/libc/isystem/atomic @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_ATOMIC_ +#define COSMOPOLITAN_LIBC_ISYSTEM_ATOMIC_ +#include "third_party/libcxx/atomic" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_ATOMIC_ */ diff --git a/libc/isystem/bit b/libc/isystem/bit new file mode 100644 index 000000000..0ad9a28c5 --- /dev/null +++ b/libc/isystem/bit @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_BIT_ +#define COSMOPOLITAN_LIBC_ISYSTEM_BIT_ +#include "third_party/libcxx/bit" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_BIT_ */ diff --git a/libc/isystem/bitset b/libc/isystem/bitset new file mode 100644 index 000000000..4b5aa6dfa --- /dev/null +++ b/libc/isystem/bitset @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_BITSET_ +#define COSMOPOLITAN_LIBC_ISYSTEM_BITSET_ +#include "third_party/libcxx/bitset" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_BITSET_ */ diff --git a/libc/isystem/cassert b/libc/isystem/cassert new file mode 100644 index 000000000..85e5ca920 --- /dev/null +++ b/libc/isystem/cassert @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_CASSERT_ +#define COSMOPOLITAN_LIBC_ISYSTEM_CASSERT_ +#include "third_party/libcxx/cassert" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_CASSERT_ */ diff --git a/libc/isystem/ccomplex b/libc/isystem/ccomplex new file mode 100644 index 000000000..b7b24916e --- /dev/null +++ b/libc/isystem/ccomplex @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_CCOMPLEX_ +#define COSMOPOLITAN_LIBC_ISYSTEM_CCOMPLEX_ +#include "third_party/libcxx/ccomplex" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_CCOMPLEX_ */ diff --git a/libc/isystem/cctype b/libc/isystem/cctype new file mode 100644 index 000000000..2c7aa4ca6 --- /dev/null +++ b/libc/isystem/cctype @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_CCTYPE_ +#define COSMOPOLITAN_LIBC_ISYSTEM_CCTYPE_ +#include "third_party/libcxx/cctype" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_CCTYPE_ */ diff --git a/libc/isystem/cerrno b/libc/isystem/cerrno new file mode 100644 index 000000000..d370b3e6e --- /dev/null +++ b/libc/isystem/cerrno @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_CERRNO_ +#define COSMOPOLITAN_LIBC_ISYSTEM_CERRNO_ +#include "third_party/libcxx/cerrno" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_CERRNO_ */ diff --git a/libc/isystem/cfenv b/libc/isystem/cfenv new file mode 100644 index 000000000..18e07fa28 --- /dev/null +++ b/libc/isystem/cfenv @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_CFENV_ +#define COSMOPOLITAN_LIBC_ISYSTEM_CFENV_ +#include "third_party/libcxx/cfenv" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_CFENV_ */ diff --git a/libc/isystem/cfloat b/libc/isystem/cfloat new file mode 100644 index 000000000..86ffc45e7 --- /dev/null +++ b/libc/isystem/cfloat @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_CFLOAT_ +#define COSMOPOLITAN_LIBC_ISYSTEM_CFLOAT_ +#include "third_party/libcxx/cfloat" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_CFLOAT_ */ diff --git a/libc/isystem/charconv b/libc/isystem/charconv new file mode 100644 index 000000000..171e84f0a --- /dev/null +++ b/libc/isystem/charconv @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_CHARCONV_ +#define COSMOPOLITAN_LIBC_ISYSTEM_CHARCONV_ +#include "third_party/libcxx/charconv" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_CHARCONV_ */ diff --git a/libc/isystem/chrono b/libc/isystem/chrono new file mode 100644 index 000000000..e3a37f160 --- /dev/null +++ b/libc/isystem/chrono @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_CHRONO_ +#define COSMOPOLITAN_LIBC_ISYSTEM_CHRONO_ +#include "third_party/libcxx/chrono" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_CHRONO_ */ diff --git a/libc/isystem/cinttypes b/libc/isystem/cinttypes new file mode 100644 index 000000000..6545c7246 --- /dev/null +++ b/libc/isystem/cinttypes @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_CINTTYPES_ +#define COSMOPOLITAN_LIBC_ISYSTEM_CINTTYPES_ +#include "third_party/libcxx/cinttypes" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_CINTTYPES_ */ diff --git a/libc/isystem/ciso646 b/libc/isystem/ciso646 new file mode 100644 index 000000000..a36495a41 --- /dev/null +++ b/libc/isystem/ciso646 @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_CISO646_ +#define COSMOPOLITAN_LIBC_ISYSTEM_CISO646_ +#include "third_party/libcxx/ciso646" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_CISO646_ */ diff --git a/libc/isystem/climits b/libc/isystem/climits new file mode 100644 index 000000000..ae833708c --- /dev/null +++ b/libc/isystem/climits @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_CLIMITS_ +#define COSMOPOLITAN_LIBC_ISYSTEM_CLIMITS_ +#include "third_party/libcxx/climits" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_CLIMITS_ */ diff --git a/libc/isystem/clocale b/libc/isystem/clocale new file mode 100644 index 000000000..90cf94010 --- /dev/null +++ b/libc/isystem/clocale @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_CLOCALE_ +#define COSMOPOLITAN_LIBC_ISYSTEM_CLOCALE_ +#include "third_party/libcxx/clocale" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_CLOCALE_ */ diff --git a/libc/isystem/cmath b/libc/isystem/cmath new file mode 100644 index 000000000..5eabfe934 --- /dev/null +++ b/libc/isystem/cmath @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_CMATH_ +#define COSMOPOLITAN_LIBC_ISYSTEM_CMATH_ +#include "third_party/libcxx/cmath" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_CMATH_ */ diff --git a/libc/isystem/codecvt b/libc/isystem/codecvt new file mode 100644 index 000000000..809a5e905 --- /dev/null +++ b/libc/isystem/codecvt @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_CODECVT_ +#define COSMOPOLITAN_LIBC_ISYSTEM_CODECVT_ +#include "third_party/libcxx/codecvt" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_CODECVT_ */ diff --git a/libc/isystem/compare b/libc/isystem/compare new file mode 100644 index 000000000..ef2d37d31 --- /dev/null +++ b/libc/isystem/compare @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_COMPARE_ +#define COSMOPOLITAN_LIBC_ISYSTEM_COMPARE_ +#include "third_party/libcxx/compare" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_COMPARE_ */ diff --git a/libc/isystem/complex b/libc/isystem/complex new file mode 100644 index 000000000..7f4c838fc --- /dev/null +++ b/libc/isystem/complex @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_COMPLEX_ +#define COSMOPOLITAN_LIBC_ISYSTEM_COMPLEX_ +#include "third_party/libcxx/complex" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_COMPLEX_ */ diff --git a/libc/isystem/condition_variable b/libc/isystem/condition_variable new file mode 100644 index 000000000..fdb82070a --- /dev/null +++ b/libc/isystem/condition_variable @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_CONDITION_VARIABLE_ +#define COSMOPOLITAN_LIBC_ISYSTEM_CONDITION_VARIABLE_ +#include "third_party/libcxx/condition_variable" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_CONDITION_VARIABLE_ */ diff --git a/libc/isystem/csetjmp b/libc/isystem/csetjmp new file mode 100644 index 000000000..d4fb16d7c --- /dev/null +++ b/libc/isystem/csetjmp @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_CSETJMP_ +#define COSMOPOLITAN_LIBC_ISYSTEM_CSETJMP_ +#include "third_party/libcxx/csetjmp" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_CSETJMP_ */ diff --git a/libc/isystem/csignal b/libc/isystem/csignal new file mode 100644 index 000000000..abaa7ea33 --- /dev/null +++ b/libc/isystem/csignal @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_CSIGNAL_ +#define COSMOPOLITAN_LIBC_ISYSTEM_CSIGNAL_ +#include "third_party/libcxx/csignal" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_CSIGNAL_ */ diff --git a/libc/isystem/cstdarg b/libc/isystem/cstdarg new file mode 100644 index 000000000..3f8e5089e --- /dev/null +++ b/libc/isystem/cstdarg @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_CSTDARG_ +#define COSMOPOLITAN_LIBC_ISYSTEM_CSTDARG_ +#include "third_party/libcxx/cstdarg" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_CSTDARG_ */ diff --git a/libc/isystem/cstdbool b/libc/isystem/cstdbool new file mode 100644 index 000000000..0206be437 --- /dev/null +++ b/libc/isystem/cstdbool @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_CSTDBOOL_ +#define COSMOPOLITAN_LIBC_ISYSTEM_CSTDBOOL_ +#include "third_party/libcxx/cstdbool" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_CSTDBOOL_ */ diff --git a/libc/isystem/cstddef b/libc/isystem/cstddef new file mode 100644 index 000000000..a76c45ed1 --- /dev/null +++ b/libc/isystem/cstddef @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_CSTDDEF_ +#define COSMOPOLITAN_LIBC_ISYSTEM_CSTDDEF_ +#include "third_party/libcxx/cstddef" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_CSTDDEF_ */ diff --git a/libc/isystem/cstdint b/libc/isystem/cstdint new file mode 100644 index 000000000..1dfa6e245 --- /dev/null +++ b/libc/isystem/cstdint @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_CSTDINT_ +#define COSMOPOLITAN_LIBC_ISYSTEM_CSTDINT_ +#include "third_party/libcxx/cstdint" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_CSTDINT_ */ diff --git a/libc/isystem/cstdio b/libc/isystem/cstdio new file mode 100644 index 000000000..ace9c50f6 --- /dev/null +++ b/libc/isystem/cstdio @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_CSTDIO_ +#define COSMOPOLITAN_LIBC_ISYSTEM_CSTDIO_ +#include "third_party/libcxx/cstdio" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_CSTDIO_ */ diff --git a/libc/isystem/cstdlib b/libc/isystem/cstdlib new file mode 100644 index 000000000..121e924a9 --- /dev/null +++ b/libc/isystem/cstdlib @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_CSTDLIB_ +#define COSMOPOLITAN_LIBC_ISYSTEM_CSTDLIB_ +#include "third_party/libcxx/cstdlib" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_CSTDLIB_ */ diff --git a/libc/isystem/cstring b/libc/isystem/cstring new file mode 100644 index 000000000..c5b409a77 --- /dev/null +++ b/libc/isystem/cstring @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_CSTRING_ +#define COSMOPOLITAN_LIBC_ISYSTEM_CSTRING_ +#include "third_party/libcxx/cstring" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_CSTRING_ */ diff --git a/libc/isystem/ctgmath b/libc/isystem/ctgmath new file mode 100644 index 000000000..6ab9d9f57 --- /dev/null +++ b/libc/isystem/ctgmath @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_CTGMATH_ +#define COSMOPOLITAN_LIBC_ISYSTEM_CTGMATH_ +#include "third_party/libcxx/ctgmath" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_CTGMATH_ */ diff --git a/libc/isystem/ctime b/libc/isystem/ctime new file mode 100644 index 000000000..ddbca6fdb --- /dev/null +++ b/libc/isystem/ctime @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_CTIME_ +#define COSMOPOLITAN_LIBC_ISYSTEM_CTIME_ +#include "third_party/libcxx/ctime" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_CTIME_ */ diff --git a/libc/isystem/cwchar b/libc/isystem/cwchar new file mode 100644 index 000000000..4bb6523de --- /dev/null +++ b/libc/isystem/cwchar @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_CWCHAR_ +#define COSMOPOLITAN_LIBC_ISYSTEM_CWCHAR_ +#include "third_party/libcxx/cwchar" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_CWCHAR_ */ diff --git a/libc/isystem/cwctype b/libc/isystem/cwctype new file mode 100644 index 000000000..cfd683b44 --- /dev/null +++ b/libc/isystem/cwctype @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_CWCTYPE_ +#define COSMOPOLITAN_LIBC_ISYSTEM_CWCTYPE_ +#include "third_party/libcxx/cwctype" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_CWCTYPE_ */ diff --git a/libc/isystem/deque b/libc/isystem/deque new file mode 100644 index 000000000..2a15681c4 --- /dev/null +++ b/libc/isystem/deque @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_DEQUE_ +#define COSMOPOLITAN_LIBC_ISYSTEM_DEQUE_ +#include "third_party/libcxx/deque" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_DEQUE_ */ diff --git a/libc/isystem/exception b/libc/isystem/exception new file mode 100644 index 000000000..ebb8f4651 --- /dev/null +++ b/libc/isystem/exception @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_EXCEPTION_ +#define COSMOPOLITAN_LIBC_ISYSTEM_EXCEPTION_ +#include "third_party/libcxx/exception" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_EXCEPTION_ */ diff --git a/libc/isystem/execution b/libc/isystem/execution new file mode 100644 index 000000000..2d55597e0 --- /dev/null +++ b/libc/isystem/execution @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_EXECUTION_ +#define COSMOPOLITAN_LIBC_ISYSTEM_EXECUTION_ +#include "third_party/libcxx/execution" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_EXECUTION_ */ diff --git a/libc/isystem/fenv.h b/libc/isystem/fenv.h new file mode 100644 index 000000000..7eb86051e --- /dev/null +++ b/libc/isystem/fenv.h @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_FENV_H_ +#define COSMOPOLITAN_LIBC_ISYSTEM_FENV_H_ +#include "libc/runtime/fenv.h" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_FENV_H_ */ diff --git a/libc/isystem/filesystem b/libc/isystem/filesystem new file mode 100644 index 000000000..0264d2352 --- /dev/null +++ b/libc/isystem/filesystem @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_FILESYSTEM_ +#define COSMOPOLITAN_LIBC_ISYSTEM_FILESYSTEM_ +#include "third_party/libcxx/filesystem" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_FILESYSTEM_ */ diff --git a/libc/isystem/forward_list b/libc/isystem/forward_list new file mode 100644 index 000000000..48c438456 --- /dev/null +++ b/libc/isystem/forward_list @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_FORWARD_LIST_ +#define COSMOPOLITAN_LIBC_ISYSTEM_FORWARD_LIST_ +#include "third_party/libcxx/forward_list" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_FORWARD_LIST_ */ diff --git a/libc/isystem/fstream b/libc/isystem/fstream new file mode 100644 index 000000000..bb2a55129 --- /dev/null +++ b/libc/isystem/fstream @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_FSTREAM_ +#define COSMOPOLITAN_LIBC_ISYSTEM_FSTREAM_ +#include "third_party/libcxx/fstream" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_FSTREAM_ */ diff --git a/libc/isystem/functional b/libc/isystem/functional new file mode 100644 index 000000000..c1a6afed8 --- /dev/null +++ b/libc/isystem/functional @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_FUNCTIONAL_ +#define COSMOPOLITAN_LIBC_ISYSTEM_FUNCTIONAL_ +#include "third_party/libcxx/functional" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_FUNCTIONAL_ */ diff --git a/libc/isystem/initializer_list b/libc/isystem/initializer_list new file mode 100644 index 000000000..7436d259b --- /dev/null +++ b/libc/isystem/initializer_list @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_INITIALIZER_LIST_ +#define COSMOPOLITAN_LIBC_ISYSTEM_INITIALIZER_LIST_ +#include "third_party/libcxx/initializer_list" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_INITIALIZER_LIST_ */ diff --git a/libc/isystem/inttypes.h b/libc/isystem/inttypes.h index 2daec1ad9..f95642209 100644 --- a/libc/isystem/inttypes.h +++ b/libc/isystem/inttypes.h @@ -1,4 +1,5 @@ #ifndef LIBC_ISYSTEM_INTTYPES_H_ #define LIBC_ISYSTEM_INTTYPES_H_ +#include "libc/fmt/conv.h" #include "libc/inttypes.h" #endif /* LIBC_ISYSTEM_INTTYPES_H_ */ diff --git a/libc/isystem/iomanip b/libc/isystem/iomanip new file mode 100644 index 000000000..54197c449 --- /dev/null +++ b/libc/isystem/iomanip @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_IOMANIP_ +#define COSMOPOLITAN_LIBC_ISYSTEM_IOMANIP_ +#include "third_party/libcxx/iomanip" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_IOMANIP_ */ diff --git a/libc/isystem/ios b/libc/isystem/ios new file mode 100644 index 000000000..529e5f2f6 --- /dev/null +++ b/libc/isystem/ios @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_IOS_ +#define COSMOPOLITAN_LIBC_ISYSTEM_IOS_ +#include "third_party/libcxx/ios" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_IOS_ */ diff --git a/libc/isystem/iosfwd b/libc/isystem/iosfwd new file mode 100644 index 000000000..49d6534e7 --- /dev/null +++ b/libc/isystem/iosfwd @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_IOSFWD_ +#define COSMOPOLITAN_LIBC_ISYSTEM_IOSFWD_ +#include "third_party/libcxx/iosfwd" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_IOSFWD_ */ diff --git a/libc/isystem/iostream b/libc/isystem/iostream new file mode 100644 index 000000000..c0bf15db0 --- /dev/null +++ b/libc/isystem/iostream @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_IOSTREAM_ +#define COSMOPOLITAN_LIBC_ISYSTEM_IOSTREAM_ +#include "third_party/libcxx/iostream" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_IOSTREAM_ */ diff --git a/libc/isystem/iso646.h b/libc/isystem/iso646.h index 23b124b48..ecac914e2 100644 --- a/libc/isystem/iso646.h +++ b/libc/isystem/iso646.h @@ -1,16 +1,4 @@ #ifndef COSMOPOLITAN_LIBC_ISYSTEM_ISO646_H_ #define COSMOPOLITAN_LIBC_ISYSTEM_ISO646_H_ - -#define and && -#define and_eq &= -#define bitand & -#define bitor | -#define compl ~ -#define not ! -#define not_eq != -#define or || -#define or_eq |= -#define xor ^ -#define xor_eq ^= - +#include "libc/iso646.internal.h" #endif diff --git a/libc/isystem/istream b/libc/isystem/istream new file mode 100644 index 000000000..d1409789d --- /dev/null +++ b/libc/isystem/istream @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_ISTREAM_ +#define COSMOPOLITAN_LIBC_ISYSTEM_ISTREAM_ +#include "third_party/libcxx/istream" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_ISTREAM_ */ diff --git a/libc/isystem/iterator b/libc/isystem/iterator new file mode 100644 index 000000000..c7106a8b5 --- /dev/null +++ b/libc/isystem/iterator @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_ITERATOR_ +#define COSMOPOLITAN_LIBC_ISYSTEM_ITERATOR_ +#include "third_party/libcxx/iterator" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_ITERATOR_ */ diff --git a/libc/isystem/limits b/libc/isystem/limits new file mode 100644 index 000000000..d9645d611 --- /dev/null +++ b/libc/isystem/limits @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_LIMITS_ +#define COSMOPOLITAN_LIBC_ISYSTEM_LIMITS_ +#include "third_party/libcxx/limits" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_LIMITS_ */ diff --git a/libc/isystem/list b/libc/isystem/list new file mode 100644 index 000000000..ed4e7dc77 --- /dev/null +++ b/libc/isystem/list @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_LIST_ +#define COSMOPOLITAN_LIBC_ISYSTEM_LIST_ +#include "third_party/libcxx/list" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_LIST_ */ diff --git a/libc/isystem/locale b/libc/isystem/locale new file mode 100644 index 000000000..320336586 --- /dev/null +++ b/libc/isystem/locale @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_LOCALE_ +#define COSMOPOLITAN_LIBC_ISYSTEM_LOCALE_ +#include "third_party/libcxx/locale" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_LOCALE_ */ diff --git a/libc/isystem/map b/libc/isystem/map new file mode 100644 index 000000000..9f16a156f --- /dev/null +++ b/libc/isystem/map @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_MAP_ +#define COSMOPOLITAN_LIBC_ISYSTEM_MAP_ +#include "third_party/libcxx/map" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_MAP_ */ diff --git a/libc/isystem/memory b/libc/isystem/memory new file mode 100644 index 000000000..46682efe5 --- /dev/null +++ b/libc/isystem/memory @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_MEMORY_ +#define COSMOPOLITAN_LIBC_ISYSTEM_MEMORY_ +#include "third_party/libcxx/memory" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_MEMORY_ */ diff --git a/libc/isystem/mutex b/libc/isystem/mutex new file mode 100644 index 000000000..4cb91bfe6 --- /dev/null +++ b/libc/isystem/mutex @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_MUTEX_ +#define COSMOPOLITAN_LIBC_ISYSTEM_MUTEX_ +#include "third_party/libcxx/mutex" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_MUTEX_ */ diff --git a/libc/isystem/new b/libc/isystem/new new file mode 100644 index 000000000..545eb6ed2 --- /dev/null +++ b/libc/isystem/new @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_NEW_ +#define COSMOPOLITAN_LIBC_ISYSTEM_NEW_ +#include "third_party/libcxx/new" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_NEW_ */ diff --git a/libc/isystem/numeric b/libc/isystem/numeric new file mode 100644 index 000000000..b6c3663c5 --- /dev/null +++ b/libc/isystem/numeric @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_NUMERIC_ +#define COSMOPOLITAN_LIBC_ISYSTEM_NUMERIC_ +#include "third_party/libcxx/numeric" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_NUMERIC_ */ diff --git a/libc/isystem/optional b/libc/isystem/optional new file mode 100644 index 000000000..1c14e7eea --- /dev/null +++ b/libc/isystem/optional @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_OPTIONAL_ +#define COSMOPOLITAN_LIBC_ISYSTEM_OPTIONAL_ +#include "third_party/libcxx/optional" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_OPTIONAL_ */ diff --git a/libc/isystem/ostream b/libc/isystem/ostream new file mode 100644 index 000000000..72ca69dea --- /dev/null +++ b/libc/isystem/ostream @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_OSTREAM_ +#define COSMOPOLITAN_LIBC_ISYSTEM_OSTREAM_ +#include "third_party/libcxx/ostream" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_OSTREAM_ */ diff --git a/libc/isystem/queue b/libc/isystem/queue new file mode 100644 index 000000000..4c6db1873 --- /dev/null +++ b/libc/isystem/queue @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_QUEUE_ +#define COSMOPOLITAN_LIBC_ISYSTEM_QUEUE_ +#include "third_party/libcxx/queue" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_QUEUE_ */ diff --git a/libc/isystem/random b/libc/isystem/random new file mode 100644 index 000000000..c558b62ba --- /dev/null +++ b/libc/isystem/random @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_RANDOM_ +#define COSMOPOLITAN_LIBC_ISYSTEM_RANDOM_ +#include "third_party/libcxx/random" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_RANDOM_ */ diff --git a/libc/isystem/ratio b/libc/isystem/ratio new file mode 100644 index 000000000..0a01c6e1c --- /dev/null +++ b/libc/isystem/ratio @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_RATIO_ +#define COSMOPOLITAN_LIBC_ISYSTEM_RATIO_ +#include "third_party/libcxx/ratio" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_RATIO_ */ diff --git a/libc/isystem/regex b/libc/isystem/regex new file mode 100644 index 000000000..06ef75e4d --- /dev/null +++ b/libc/isystem/regex @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_REGEX_ +#define COSMOPOLITAN_LIBC_ISYSTEM_REGEX_ +#include "third_party/libcxx/regex" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_REGEX_ */ diff --git a/libc/isystem/scoped_allocator b/libc/isystem/scoped_allocator new file mode 100644 index 000000000..b197a90ec --- /dev/null +++ b/libc/isystem/scoped_allocator @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_SCOPED_ALLOCATOR_ +#define COSMOPOLITAN_LIBC_ISYSTEM_SCOPED_ALLOCATOR_ +#include "third_party/libcxx/scoped_allocator" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_SCOPED_ALLOCATOR_ */ diff --git a/libc/isystem/set b/libc/isystem/set new file mode 100644 index 000000000..7e22b881f --- /dev/null +++ b/libc/isystem/set @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_SET_ +#define COSMOPOLITAN_LIBC_ISYSTEM_SET_ +#include "third_party/libcxx/set" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_SET_ */ diff --git a/libc/isystem/sstream b/libc/isystem/sstream new file mode 100644 index 000000000..4979e11a1 --- /dev/null +++ b/libc/isystem/sstream @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_SSTREAM_ +#define COSMOPOLITAN_LIBC_ISYSTEM_SSTREAM_ +#include "third_party/libcxx/sstream" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_SSTREAM_ */ diff --git a/libc/isystem/stack b/libc/isystem/stack new file mode 100644 index 000000000..a5fecfc9a --- /dev/null +++ b/libc/isystem/stack @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_STACK_ +#define COSMOPOLITAN_LIBC_ISYSTEM_STACK_ +#include "third_party/libcxx/stack" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_STACK_ */ diff --git a/libc/isystem/stdalign.h b/libc/isystem/stdalign.h new file mode 100644 index 000000000..c35db49b1 --- /dev/null +++ b/libc/isystem/stdalign.h @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_STDALIGN_H_ +#define COSMOPOLITAN_LIBC_ISYSTEM_STDALIGN_H_ +#include "libc/stdalign.internal.h" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_STDALIGN_H_ */ diff --git a/libc/isystem/stdexcept b/libc/isystem/stdexcept new file mode 100644 index 000000000..2607109c9 --- /dev/null +++ b/libc/isystem/stdexcept @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_STDEXCEPT_ +#define COSMOPOLITAN_LIBC_ISYSTEM_STDEXCEPT_ +#include "third_party/libcxx/stdexcept" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_STDEXCEPT_ */ diff --git a/libc/isystem/streambuf b/libc/isystem/streambuf new file mode 100644 index 000000000..d533b0e8e --- /dev/null +++ b/libc/isystem/streambuf @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_STREAMBUF_ +#define COSMOPOLITAN_LIBC_ISYSTEM_STREAMBUF_ +#include "third_party/libcxx/streambuf" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_STREAMBUF_ */ diff --git a/libc/isystem/string b/libc/isystem/string new file mode 100644 index 000000000..7d933bb65 --- /dev/null +++ b/libc/isystem/string @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_STRING_ +#define COSMOPOLITAN_LIBC_ISYSTEM_STRING_ +#include "third_party/libcxx/string" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_STRING_ */ diff --git a/libc/isystem/string_view b/libc/isystem/string_view new file mode 100644 index 000000000..13ff5c2d0 --- /dev/null +++ b/libc/isystem/string_view @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_STRING_VIEW_ +#define COSMOPOLITAN_LIBC_ISYSTEM_STRING_VIEW_ +#include "third_party/libcxx/string_view" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_STRING_VIEW_ */ diff --git a/libc/isystem/strstream b/libc/isystem/strstream new file mode 100644 index 000000000..550f5fe84 --- /dev/null +++ b/libc/isystem/strstream @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_STRSTREAM_ +#define COSMOPOLITAN_LIBC_ISYSTEM_STRSTREAM_ +#include "third_party/libcxx/strstream" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_STRSTREAM_ */ diff --git a/libc/isystem/system_error b/libc/isystem/system_error new file mode 100644 index 000000000..f46605cbc --- /dev/null +++ b/libc/isystem/system_error @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_SYSTEM_ERROR_ +#define COSMOPOLITAN_LIBC_ISYSTEM_SYSTEM_ERROR_ +#include "third_party/libcxx/system_error" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_SYSTEM_ERROR_ */ diff --git a/libc/isystem/thread b/libc/isystem/thread new file mode 100644 index 000000000..42d83e0ee --- /dev/null +++ b/libc/isystem/thread @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_THREAD_ +#define COSMOPOLITAN_LIBC_ISYSTEM_THREAD_ +#include "third_party/libcxx/thread" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_THREAD_ */ diff --git a/libc/isystem/tuple b/libc/isystem/tuple new file mode 100644 index 000000000..53fbdee29 --- /dev/null +++ b/libc/isystem/tuple @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_TUPLE_ +#define COSMOPOLITAN_LIBC_ISYSTEM_TUPLE_ +#include "third_party/libcxx/tuple" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_TUPLE_ */ diff --git a/libc/isystem/type_traits b/libc/isystem/type_traits new file mode 100644 index 000000000..3a8b56df6 --- /dev/null +++ b/libc/isystem/type_traits @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_TYPE_TRAITS_ +#define COSMOPOLITAN_LIBC_ISYSTEM_TYPE_TRAITS_ +#include "third_party/libcxx/type_traits" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_TYPE_TRAITS_ */ diff --git a/libc/isystem/typeindex b/libc/isystem/typeindex new file mode 100644 index 000000000..7e808f30f --- /dev/null +++ b/libc/isystem/typeindex @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_TYPEINDEX_ +#define COSMOPOLITAN_LIBC_ISYSTEM_TYPEINDEX_ +#include "third_party/libcxx/typeindex" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_TYPEINDEX_ */ diff --git a/libc/isystem/typeinfo b/libc/isystem/typeinfo new file mode 100644 index 000000000..3b67be340 --- /dev/null +++ b/libc/isystem/typeinfo @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_TYPEINFO_ +#define COSMOPOLITAN_LIBC_ISYSTEM_TYPEINFO_ +#include "third_party/libcxx/typeinfo" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_TYPEINFO_ */ diff --git a/libc/isystem/uchar.h b/libc/isystem/uchar.h new file mode 100644 index 000000000..89564a3db --- /dev/null +++ b/libc/isystem/uchar.h @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_UCHAR_H_ +#define COSMOPOLITAN_LIBC_ISYSTEM_UCHAR_H_ +#include "libc/str/str.h" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_UCHAR_H_ */ diff --git a/libc/isystem/unordered_map b/libc/isystem/unordered_map new file mode 100644 index 000000000..e1d11c7f7 --- /dev/null +++ b/libc/isystem/unordered_map @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_UNORDERED_MAP_ +#define COSMOPOLITAN_LIBC_ISYSTEM_UNORDERED_MAP_ +#include "third_party/libcxx/unordered_map" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_UNORDERED_MAP_ */ diff --git a/libc/isystem/unordered_set b/libc/isystem/unordered_set new file mode 100644 index 000000000..e98f209f9 --- /dev/null +++ b/libc/isystem/unordered_set @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_UNORDERED_SET_ +#define COSMOPOLITAN_LIBC_ISYSTEM_UNORDERED_SET_ +#include "third_party/libcxx/unordered_set" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_UNORDERED_SET_ */ diff --git a/libc/isystem/utility b/libc/isystem/utility new file mode 100644 index 000000000..cef92388f --- /dev/null +++ b/libc/isystem/utility @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_UTILITY_ +#define COSMOPOLITAN_LIBC_ISYSTEM_UTILITY_ +#include "third_party/libcxx/utility" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_UTILITY_ */ diff --git a/libc/isystem/valarray b/libc/isystem/valarray new file mode 100644 index 000000000..4103c13bf --- /dev/null +++ b/libc/isystem/valarray @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_VALARRAY_ +#define COSMOPOLITAN_LIBC_ISYSTEM_VALARRAY_ +#include "third_party/libcxx/valarray" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_VALARRAY_ */ diff --git a/libc/isystem/variant b/libc/isystem/variant new file mode 100644 index 000000000..1958970e1 --- /dev/null +++ b/libc/isystem/variant @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_VARIANT_ +#define COSMOPOLITAN_LIBC_ISYSTEM_VARIANT_ +#include "third_party/libcxx/variant" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_VARIANT_ */ diff --git a/libc/isystem/vector b/libc/isystem/vector new file mode 100644 index 000000000..ea6720f04 --- /dev/null +++ b/libc/isystem/vector @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_VECTOR_ +#define COSMOPOLITAN_LIBC_ISYSTEM_VECTOR_ +#include "third_party/libcxx/vector" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_VECTOR_ */ diff --git a/libc/isystem/version b/libc/isystem/version new file mode 100644 index 000000000..f87861ee9 --- /dev/null +++ b/libc/isystem/version @@ -0,0 +1,4 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_VERSION_ +#define COSMOPOLITAN_LIBC_ISYSTEM_VERSION_ +#include "third_party/libcxx/version" +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_VERSION_ */ diff --git a/libc/macros.internal.h b/libc/macros.internal.h index bb442e93e..9c5099dc8 100644 --- a/libc/macros.internal.h +++ b/libc/macros.internal.h @@ -13,8 +13,6 @@ #define TRUE 1 #define FALSE 0 -#define alignas(x) _Alignas(x) - #define IS2POW(X) (!((X) & ((X)-1))) #define ROUNDUP(X, K) (((X) + (K)-1) & -(K)) #define ROUNDDOWN(X, K) ((X) & -(K)) diff --git a/libc/nexgen32e/nexgen32e.h b/libc/nexgen32e/nexgen32e.h index ea8efa135..829cbbedd 100644 --- a/libc/nexgen32e/nexgen32e.h +++ b/libc/nexgen32e/nexgen32e.h @@ -10,7 +10,6 @@ extern const uint64_t kSha512[80]; extern const unsigned char kTensIndex[64]; void imapxlatab(void *); -void insertionsort(int32_t *, size_t); void CheckStackIsAligned(void); COSMOPOLITAN_C_END_ diff --git a/libc/runtime/clone.c b/libc/runtime/clone.c index 41e1ad5e3..d3123700f 100644 --- a/libc/runtime/clone.c +++ b/libc/runtime/clone.c @@ -33,6 +33,7 @@ #include "libc/nt/thunk/msabi.h" #include "libc/runtime/internal.h" #include "libc/runtime/runtime.h" +#include "libc/stdalign.internal.h" #include "libc/str/str.h" #include "libc/sysv/consts/clone.h" #include "libc/sysv/consts/futex.h" diff --git a/libc/runtime/enable_tls.c b/libc/runtime/enable_tls.c index f16f8793f..d0ec56509 100644 --- a/libc/runtime/enable_tls.c +++ b/libc/runtime/enable_tls.c @@ -31,6 +31,7 @@ #include "libc/nt/thread.h" #include "libc/runtime/internal.h" #include "libc/runtime/runtime.h" +#include "libc/stdalign.internal.h" #include "libc/str/str.h" #include "libc/sysv/consts/nrlinux.h" #include "libc/thread/thread.h" diff --git a/libc/stdalign.internal.h b/libc/stdalign.internal.h new file mode 100644 index 000000000..9b4d39de4 --- /dev/null +++ b/libc/stdalign.internal.h @@ -0,0 +1,12 @@ +#ifndef COSMOPOLITAN_LIBC_STDALIGN_INTERNAL_H_ +#define COSMOPOLITAN_LIBC_STDALIGN_INTERNAL_H_ + +#ifndef __cplusplus +#define alignas _Alignas +#define alignof _Alignof +#endif /* __cplusplus */ + +#define __alignas_is_defined 1 +#define __alignof_is_defined 1 + +#endif /* COSMOPOLITAN_LIBC_STDALIGN_INTERNAL_H_ */ diff --git a/libc/str/insertionsort.greg.c b/libc/str/insertionsort.greg.c deleted file mode 100644 index 6e924a60a..000000000 --- a/libc/str/insertionsort.greg.c +++ /dev/null @@ -1,38 +0,0 @@ -/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ -│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ -╞══════════════════════════════════════════════════════════════════════════════╡ -│ Copyright 2020 Justine Alexandra Roberts Tunney │ -│ │ -│ Permission to use, copy, modify, and/or distribute this software for │ -│ any purpose with or without fee is hereby granted, provided that the │ -│ above copyright notice and this permission notice appear in all copies. │ -│ │ -│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │ -│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │ -│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │ -│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │ -│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │ -│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │ -│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ -│ PERFORMANCE OF THIS SOFTWARE. │ -╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/log/log.h" -#include "libc/nexgen32e/nexgen32e.h" - -/** - * Sorts array of signed 32-bit integers. - * @see djbsort() - */ -textreal void insertionsort(int32_t *a, size_t n) { - int t; - unsigned i, j; - for (i = 1; i < n; ++i) { - j = i; - t = a[i]; - while (j > 0 && t < a[j - 1]) { - a[j] = a[j - 1]; - --j; - } - a[j] = t; - } -} diff --git a/libc/str/str.h b/libc/str/str.h index 6e9c08eea..0f995da3c 100644 --- a/libc/str/str.h +++ b/libc/str/str.h @@ -106,7 +106,7 @@ void *memrchr(const void *, int, size_t) strlenesque; char16_t *strrchr16(const char16_t *, int) strlenesque; void *memrchr16(const void *, int, size_t) strlenesque; wchar_t *wcsrchr(const wchar_t *, int) strlenesque; -void *wmemrchr(const void *, wchar_t, size_t) strlenesque; +void *wmemrchr(const wchar_t *, wchar_t, size_t) strlenesque; char *strpbrk(const char *, const char *) strlenesque; char16_t *strpbrk16(const char16_t *, const char16_t *) strlenesque; wchar_t *wcspbrk(const wchar_t *, const wchar_t *) strlenesque; diff --git a/libc/str/str.mk b/libc/str/str.mk index a7e418fab..823992e5a 100644 --- a/libc/str/str.mk +++ b/libc/str/str.mk @@ -49,6 +49,8 @@ o/$(MODE)/libc/str/memmem.o: private \ OVERRIDE_CPPFLAGS += \ -DSTACK_FRAME_UNLIMITED +o/$(MODE)/libc/str/wmemset.o \ +o/$(MODE)/libc/str/memset16.o \ o/$(MODE)/libc/str/dosdatetimetounix.o: private \ OVERRIDE_CFLAGS += \ -O3 diff --git a/libc/str/wmemcmp.c b/libc/str/wmemcmp.c index cae978ac7..1c993548b 100644 --- a/libc/str/wmemcmp.c +++ b/libc/str/wmemcmp.c @@ -1,40 +1,38 @@ /*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ │vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ ╞══════════════════════════════════════════════════════════════════════════════╡ -│ This is free and unencumbered software released into the public domain. │ +│ Copyright 2022 Justine Alexandra Roberts Tunney │ │ │ -│ Anyone is free to copy, modify, publish, use, compile, sell, or │ -│ distribute this software, either in source code form or as a compiled │ -│ binary, for any purpose, commercial or non-commercial, and by any │ -│ means. │ -│ │ -│ In jurisdictions that recognize copyright laws, the author or authors │ -│ of this software dedicate any and all copyright interest in the │ -│ software to the public domain. We make this dedication for the benefit │ -│ of the public at large and to the detriment of our heirs and │ -│ successors. We intend this dedication to be an overt act of │ -│ relinquishment in perpetuity of all present and future rights to this │ -│ software under copyright law. │ -│ │ -│ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, │ -│ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF │ -│ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. │ -│ IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR │ -│ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │ -│ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR │ -│ OTHER DEALINGS IN THE SOFTWARE. │ +│ Permission to use, copy, modify, and/or distribute this software for │ +│ any purpose with or without fee is hereby granted, provided that the │ +│ above copyright notice and this permission notice appear in all copies. │ │ │ +│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │ +│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │ +│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │ +│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │ +│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │ +│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │ +│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ +│ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/str/str.h" /** - * Compares NUL-terminated wide strings w/ limit. + * Compares arrays of 32-bit signed integers. * - * @param a is first non-null NUL-terminated string pointer - * @param b is second non-null NUL-terminated string pointer - * @return is <0, 0, or >0 based on uint8_t comparison + * @param a is first memory array + * @param b is second memory array + * @param n is number of elements in `a` and `b` to consider + * @return is <0, 0, or >0 based on int32_t comparison * @asyncsignalsafe */ int wmemcmp(const wchar_t *a, const wchar_t *b, size_t n) { - return wcsncmp(a, b, n); + size_t i; + for (i = 0; i < n; ++i) { + if (a[i] != b[i]) { + return a[i] - b[i]; + } + } + return 0; } diff --git a/libc/str/wmemcpy.c b/libc/str/wmemcpy.c index cdb34fe04..aa7b4f187 100644 --- a/libc/str/wmemcpy.c +++ b/libc/str/wmemcpy.c @@ -19,5 +19,7 @@ #include "libc/str/str.h" wchar_t *wmemcpy(wchar_t *dest, const wchar_t *src, size_t count) { - return memcpy(dest, src, count * sizeof(wchar_t)); + size_t bytes; + if (__builtin_mul_overflow(count, sizeof(wchar_t), &bytes)) bytes = -1; + return memcpy(dest, src, bytes); } diff --git a/libc/str/wmemmove.c b/libc/str/wmemmove.c index b90a7b0fc..3b1305502 100644 --- a/libc/str/wmemmove.c +++ b/libc/str/wmemmove.c @@ -19,5 +19,7 @@ #include "libc/str/str.h" wchar_t *wmemmove(wchar_t *dest, const wchar_t *src, size_t count) { - return memmove(dest, src, count * sizeof(wchar_t)); + size_t bytes; + if (__builtin_mul_overflow(count, sizeof(wchar_t), &bytes)) bytes = -1; + return memmove(dest, src, bytes); } diff --git a/libc/str/wmempcpy.c b/libc/str/wmempcpy.c index d72a24300..da7dc0e20 100644 --- a/libc/str/wmempcpy.c +++ b/libc/str/wmempcpy.c @@ -19,5 +19,7 @@ #include "libc/str/str.h" wchar_t *wmempcpy(wchar_t *dest, const wchar_t *src, size_t count) { - return mempcpy(dest, src, count * sizeof(wchar_t)); + size_t bytes; + if (__builtin_mul_overflow(count, sizeof(wchar_t), &bytes)) bytes = -1; + return mempcpy(dest, src, bytes); } diff --git a/libc/str/wmemrchr.c b/libc/str/wmemrchr.c index af45f8c57..b2881ba33 100644 --- a/libc/str/wmemrchr.c +++ b/libc/str/wmemrchr.c @@ -64,10 +64,14 @@ noasan static inline const wchar_t *wmemrchr_sse(const wchar_t *s, wchar_t c, * @return is pointer to first instance of c or NULL if not found * @asyncsignalsafe */ -void *wmemrchr(const void *s, wchar_t c, size_t n) { +void *wmemrchr(const wchar_t *s, wchar_t c, size_t n) { + size_t bytes; const void *r; if (!IsTiny() && X86_HAVE(SSE)) { - if (IsAsan()) __asan_verify(s, n * 4); + if (IsAsan()) { + if (__builtin_mul_overflow(n, sizeof(wchar_t), &bytes)) bytes = -1; + __asan_verify(s, bytes); + } r = wmemrchr_sse(s, c, n); } else { r = wmemrchr_pure(s, c, n); diff --git a/libc/str/wmemset.c b/libc/str/wmemset.c index 950458a16..a79ecff2f 100644 --- a/libc/str/wmemset.c +++ b/libc/str/wmemset.c @@ -23,15 +23,9 @@ * @asyncsignalsafe */ wchar_t *wmemset(wchar_t *p, wchar_t c, size_t n) { - size_t i = 0; - if (n >= 4) { - wchar_t v __attribute__((__vector_size__(16))) = {c, c, c, c}; - do { - __builtin_memcpy(p + i, &v, 16); - } while ((i += 4) + 4 <= n); - } - while (i < n) { - p[i++] = c; + size_t i; + for (i = 0; i < n; ++i) { + p[i] = c; } return p; } diff --git a/libc/thread/mktls.c b/libc/thread/mktls.c index d527b4f0f..911c2a18e 100644 --- a/libc/thread/mktls.c +++ b/libc/thread/mktls.c @@ -27,7 +27,7 @@ #define _TLSZ ((intptr_t)_tls_size) #define _TLDZ ((intptr_t)_tdata_size) #define _TIBZ sizeof(struct cthread_descriptor_t) -#define _MEMZ ROUNDUP(_TLSZ + _TIBZ, alignof(struct cthread_descriptor_t)) +#define _MEMZ ROUNDUP(_TLSZ + _TIBZ, _Alignof(struct cthread_descriptor_t)) /** * Allocates thread-local storage memory for new thread. diff --git a/libc/thread/spawn.c b/libc/thread/spawn.c index 98788cc25..66b851259 100644 --- a/libc/thread/spawn.c +++ b/libc/thread/spawn.c @@ -25,6 +25,7 @@ #include "libc/runtime/internal.h" #include "libc/runtime/runtime.h" #include "libc/runtime/stack.h" +#include "libc/stdalign.internal.h" #include "libc/str/str.h" #include "libc/sysv/consts/clone.h" #include "libc/sysv/consts/map.h" diff --git a/test/libc/intrin/memset_test.c b/test/libc/intrin/memset_test.c index fcc03b456..38e25db19 100644 --- a/test/libc/intrin/memset_test.c +++ b/test/libc/intrin/memset_test.c @@ -19,8 +19,8 @@ #include "libc/dce.h" #include "libc/intrin/asan.internal.h" #include "libc/mem/mem.h" -#include "libc/stdio/rand.h" #include "libc/runtime/gc.internal.h" +#include "libc/stdio/rand.h" #include "libc/str/str.h" #include "libc/testlib/ezbench.h" #include "libc/testlib/testlib.h" @@ -68,11 +68,18 @@ TEST(bzero, hug) { BENCH(memset, bench) { int n, max = 8 * 1024 * 1024; char *volatile p = gc(malloc(max)); + EZBENCH_N("memset", 0, memset(p, -1, 0)); for (n = 2; n <= max; n *= 2) { EZBENCH_N("memset", n - 1, memset(p, -1, n - 1)); EZBENCH_N("memset", n, memset(p, -1, n)); } + + EZBENCH_N("memset16", 0, memset16((char16_t *)p, -1, 0)); + for (n = 2; n <= max; n *= 2) { + EZBENCH_N("memset16", n, memset16((char16_t *)p, -1, n / 2)); + } + EZBENCH_N("bzero", 0, bzero(p, 0)); for (n = 2; n <= max; n *= 2) { EZBENCH_N("bzero", n - 1, bzero(p, n - 1)); diff --git a/test/libc/mem/djbsort_test.c b/test/libc/mem/djbsort_test.c index 394ea8635..9b2e04bbd 100644 --- a/test/libc/mem/djbsort_test.c +++ b/test/libc/mem/djbsort_test.c @@ -16,15 +16,15 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/mem/alg.h" #include "libc/limits.h" #include "libc/log/log.h" #include "libc/macros.internal.h" +#include "libc/mem/alg.h" #include "libc/mem/mem.h" #include "libc/nexgen32e/nexgen32e.h" #include "libc/nexgen32e/x86feature.h" -#include "libc/stdio/rand.h" #include "libc/runtime/gc.internal.h" +#include "libc/stdio/rand.h" #include "libc/stdio/stdio.h" #include "libc/str/str.h" #include "libc/testlib/ezbench.h" @@ -35,6 +35,20 @@ void djbsort_avx2(int32_t *, long); size_t n; int32_t *a, *b, *c; +void insertionsort(int32_t *a, size_t n) { + int t; + unsigned i, j; + for (i = 1; i < n; ++i) { + j = i; + t = a[i]; + while (j > 0 && t < a[j - 1]) { + a[j] = a[j - 1]; + --j; + } + a[j] = t; + } +} + TEST(djbsort, test4) { static const int kA[] = {4, 3, 2, 1}; n = ARRAYLEN(kA); diff --git a/test/libc/str/wmemrchr_test.c b/test/libc/str/wmemrchr_test.c index d0bcc6250..9e39ae657 100644 --- a/test/libc/str/wmemrchr_test.c +++ b/test/libc/str/wmemrchr_test.c @@ -31,6 +31,4 @@ TEST(wmemrchr, test) { BENCH(wmemrchr, bench) { EZBENCH2("wmemrchr", donothing, EXPROPRIATE(wmemrchr(L"yo.hi.there", '.', 11))); - EZBENCH2("wmemrchr hyperion", donothing, - EXPROPRIATE(wmemrchr(kHyperion, '.', kHyperionSize / 4))); } diff --git a/third_party/libcxx/README.cosmo b/third_party/libcxx/README.cosmo index 1b62899d4..4de2da7e7 100644 --- a/third_party/libcxx/README.cosmo +++ b/third_party/libcxx/README.cosmo @@ -1,6 +1,14 @@ -Upstream origin +DESCRIPTION - git@github.com:llvm-mirror/libcxx.git - commit 78d6a7767ed57b50122a161b91f59f19c9bd0d19 - Author: Zoe Carver - Date: Tue Oct 22 15:16:49 2019 +0000 + LLVM's C++ Standard Template Library + +ORIGIN + + git@github.com:llvm-mirror/libcxx.git + commit 78d6a7767ed57b50122a161b91f59f19c9bd0d19 + Author: Zoe Carver + Date: Tue Oct 22 15:16:49 2019 +0000 + +LOCAL CHANGES + + - Break apart locale.cpp due to its outrageous build times diff --git a/third_party/libcxx/__config b/third_party/libcxx/__config index 1f839256e..69e181b90 100644 --- a/third_party/libcxx/__config +++ b/third_party/libcxx/__config @@ -14,6 +14,7 @@ #define _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER #define _LIBCPP_HAS_NO_THREADS #define _LIBCPP_ABI_UNSTABLE +#define _LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS // #define _LIBCPP_NO_EXCEPTIONS #if defined(_MSC_VER) && !defined(__clang__) diff --git a/third_party/libcxx/any b/third_party/libcxx/any new file mode 100644 index 000000000..8593a2fb2 --- /dev/null +++ b/third_party/libcxx/any @@ -0,0 +1,672 @@ +// -*- C++ -*- +// clang-format off +//===------------------------------ any -----------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_ANY +#define _LIBCPP_ANY + +/* + any synopsis + +namespace std { + + class bad_any_cast : public bad_cast + { + public: + virtual const char* what() const noexcept; + }; + + class any + { + public: + + // 6.3.1 any construct/destruct + any() noexcept; + + any(const any& other); + any(any&& other) noexcept; + + template + any(ValueType&& value); + + ~any(); + + // 6.3.2 any assignments + any& operator=(const any& rhs); + any& operator=(any&& rhs) noexcept; + + template + any& operator=(ValueType&& rhs); + + // 6.3.3 any modifiers + template + decay_t& emplace(Args&&... args); + template + decay_t& emplace(initializer_list, Args&&...); + void reset() noexcept; + void swap(any& rhs) noexcept; + + // 6.3.4 any observers + bool has_value() const noexcept; + const type_info& type() const noexcept; + }; + + // 6.4 Non-member functions + void swap(any& x, any& y) noexcept; + + template + any make_any(Args&& ...args); + template + any make_any(initializer_list, Args&& ...args); + + template + ValueType any_cast(const any& operand); + template + ValueType any_cast(any& operand); + template + ValueType any_cast(any&& operand); + + template + const ValueType* any_cast(const any* operand) noexcept; + template + ValueType* any_cast(any* operand) noexcept; + +} // namespace std + +*/ + +#include "third_party/libcxx/experimental/__config" +#include "third_party/libcxx/memory" +#include "third_party/libcxx/new" +#include "third_party/libcxx/typeinfo" +#include "third_party/libcxx/type_traits" +#include "third_party/libcxx/cstdlib" +#include "third_party/libcxx/version" + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +namespace std { +class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_BAD_ANY_CAST bad_any_cast : public bad_cast +{ +public: + virtual const char* what() const _NOEXCEPT; +}; +} // namespace std + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 14 + +_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST +void __throw_bad_any_cast() +{ +#ifndef _LIBCPP_NO_EXCEPTIONS + throw bad_any_cast(); +#else + _VSTD::abort(); +#endif +} + +// Forward declarations +class _LIBCPP_TEMPLATE_VIS any; + +template +_LIBCPP_INLINE_VISIBILITY +add_pointer_t> +any_cast(any const *) _NOEXCEPT; + +template +_LIBCPP_INLINE_VISIBILITY +add_pointer_t<_ValueType> any_cast(any *) _NOEXCEPT; + +namespace __any_imp +{ + using _Buffer = aligned_storage_t<3*sizeof(void*), alignment_of::value>; + + template + using _IsSmallObject = integral_constant::value + % alignment_of<_Tp>::value == 0 + && is_nothrow_move_constructible<_Tp>::value + >; + + enum class _Action { + _Destroy, + _Copy, + _Move, + _Get, + _TypeInfo + }; + + template struct _SmallHandler; + template struct _LargeHandler; + + template + struct _LIBCPP_TEMPLATE_VIS __unique_typeinfo { static constexpr int __id = 0; }; + template constexpr int __unique_typeinfo<_Tp>::__id; + + template + inline _LIBCPP_INLINE_VISIBILITY + constexpr const void* __get_fallback_typeid() { + return &__unique_typeinfo>::__id; + } + + template + inline _LIBCPP_INLINE_VISIBILITY + bool __compare_typeid(type_info const* __id, const void* __fallback_id) + { +#if !defined(_LIBCPP_NO_RTTI) + if (__id && *__id == typeid(_Tp)) + return true; +#endif + if (!__id && __fallback_id == __any_imp::__get_fallback_typeid<_Tp>()) + return true; + return false; + } + + template + using _Handler = conditional_t< + _IsSmallObject<_Tp>::value, _SmallHandler<_Tp>, _LargeHandler<_Tp>>; + +} // namespace __any_imp + +class _LIBCPP_TEMPLATE_VIS any +{ +public: + // construct/destruct + _LIBCPP_INLINE_VISIBILITY + constexpr any() _NOEXCEPT : __h(nullptr) {} + + _LIBCPP_INLINE_VISIBILITY + any(any const & __other) : __h(nullptr) + { + if (__other.__h) __other.__call(_Action::_Copy, this); + } + + _LIBCPP_INLINE_VISIBILITY + any(any && __other) _NOEXCEPT : __h(nullptr) + { + if (__other.__h) __other.__call(_Action::_Move, this); + } + + template < + class _ValueType + , class _Tp = decay_t<_ValueType> + , class = enable_if_t< + !is_same<_Tp, any>::value && + !__is_inplace_type<_ValueType>::value && + is_copy_constructible<_Tp>::value> + > + _LIBCPP_INLINE_VISIBILITY + any(_ValueType && __value); + + template , + class = enable_if_t< + is_constructible<_Tp, _Args...>::value && + is_copy_constructible<_Tp>::value + > + > + _LIBCPP_INLINE_VISIBILITY + explicit any(in_place_type_t<_ValueType>, _Args&&... __args); + + template , + class = enable_if_t< + is_constructible<_Tp, initializer_list<_Up>&, _Args...>::value && + is_copy_constructible<_Tp>::value> + > + _LIBCPP_INLINE_VISIBILITY + explicit any(in_place_type_t<_ValueType>, initializer_list<_Up>, _Args&&... __args); + + _LIBCPP_INLINE_VISIBILITY + ~any() { this->reset(); } + + // assignments + _LIBCPP_INLINE_VISIBILITY + any & operator=(any const & __rhs) { + any(__rhs).swap(*this); + return *this; + } + + _LIBCPP_INLINE_VISIBILITY + any & operator=(any && __rhs) _NOEXCEPT { + any(_VSTD::move(__rhs)).swap(*this); + return *this; + } + + template < + class _ValueType + , class _Tp = decay_t<_ValueType> + , class = enable_if_t< + !is_same<_Tp, any>::value + && is_copy_constructible<_Tp>::value> + > + _LIBCPP_INLINE_VISIBILITY + any & operator=(_ValueType && __rhs); + + template , + class = enable_if_t< + is_constructible<_Tp, _Args...>::value && + is_copy_constructible<_Tp>::value> + > + _LIBCPP_INLINE_VISIBILITY + _Tp& emplace(_Args&&... args); + + template , + class = enable_if_t< + is_constructible<_Tp, initializer_list<_Up>&, _Args...>::value && + is_copy_constructible<_Tp>::value> + > + _LIBCPP_INLINE_VISIBILITY + _Tp& emplace(initializer_list<_Up>, _Args&&...); + + // 6.3.3 any modifiers + _LIBCPP_INLINE_VISIBILITY + void reset() _NOEXCEPT { if (__h) this->__call(_Action::_Destroy); } + + _LIBCPP_INLINE_VISIBILITY + void swap(any & __rhs) _NOEXCEPT; + + // 6.3.4 any observers + _LIBCPP_INLINE_VISIBILITY + bool has_value() const _NOEXCEPT { return __h != nullptr; } + +#if !defined(_LIBCPP_NO_RTTI) + _LIBCPP_INLINE_VISIBILITY + const type_info & type() const _NOEXCEPT { + if (__h) { + return *static_cast(this->__call(_Action::_TypeInfo)); + } else { + return typeid(void); + } + } +#endif + +private: + typedef __any_imp::_Action _Action; + using _HandleFuncPtr = void* (*)(_Action, any const *, any *, const type_info *, + const void* __fallback_info); + + union _Storage { + constexpr _Storage() : __ptr(nullptr) {} + void * __ptr; + __any_imp::_Buffer __buf; + }; + + _LIBCPP_INLINE_VISIBILITY + void * __call(_Action __a, any * __other = nullptr, + type_info const * __info = nullptr, + const void* __fallback_info = nullptr) const + { + return __h(__a, this, __other, __info, __fallback_info); + } + + _LIBCPP_INLINE_VISIBILITY + void * __call(_Action __a, any * __other = nullptr, + type_info const * __info = nullptr, + const void* __fallback_info = nullptr) + { + return __h(__a, this, __other, __info, __fallback_info); + } + + template + friend struct __any_imp::_SmallHandler; + template + friend struct __any_imp::_LargeHandler; + + template + friend add_pointer_t> + any_cast(any const *) _NOEXCEPT; + + template + friend add_pointer_t<_ValueType> + any_cast(any *) _NOEXCEPT; + + _HandleFuncPtr __h = nullptr; + _Storage __s; +}; + +namespace __any_imp +{ + template + struct _LIBCPP_TEMPLATE_VIS _SmallHandler + { + _LIBCPP_INLINE_VISIBILITY + static void* __handle(_Action __act, any const * __this, any * __other, + type_info const * __info, const void* __fallback_info) + { + switch (__act) + { + case _Action::_Destroy: + __destroy(const_cast(*__this)); + return nullptr; + case _Action::_Copy: + __copy(*__this, *__other); + return nullptr; + case _Action::_Move: + __move(const_cast(*__this), *__other); + return nullptr; + case _Action::_Get: + return __get(const_cast(*__this), __info, __fallback_info); + case _Action::_TypeInfo: + return __type_info(); + } + } + + template + _LIBCPP_INLINE_VISIBILITY + static _Tp& __create(any & __dest, _Args&&... __args) { + _Tp* __ret = ::new (static_cast(&__dest.__s.__buf)) _Tp(_VSTD::forward<_Args>(__args)...); + __dest.__h = &_SmallHandler::__handle; + return *__ret; + } + + private: + _LIBCPP_INLINE_VISIBILITY + static void __destroy(any & __this) { + _Tp & __value = *static_cast<_Tp *>(static_cast(&__this.__s.__buf)); + __value.~_Tp(); + __this.__h = nullptr; + } + + _LIBCPP_INLINE_VISIBILITY + static void __copy(any const & __this, any & __dest) { + _SmallHandler::__create(__dest, *static_cast<_Tp const *>( + static_cast(&__this.__s.__buf))); + } + + _LIBCPP_INLINE_VISIBILITY + static void __move(any & __this, any & __dest) { + _SmallHandler::__create(__dest, _VSTD::move( + *static_cast<_Tp*>(static_cast(&__this.__s.__buf)))); + __destroy(__this); + } + + _LIBCPP_INLINE_VISIBILITY + static void* __get(any & __this, + type_info const * __info, + const void* __fallback_id) + { + if (__any_imp::__compare_typeid<_Tp>(__info, __fallback_id)) + return static_cast(&__this.__s.__buf); + return nullptr; + } + + _LIBCPP_INLINE_VISIBILITY + static void* __type_info() + { +#if !defined(_LIBCPP_NO_RTTI) + return const_cast(static_cast(&typeid(_Tp))); +#else + return nullptr; +#endif + } + }; + + template + struct _LIBCPP_TEMPLATE_VIS _LargeHandler + { + _LIBCPP_INLINE_VISIBILITY + static void* __handle(_Action __act, any const * __this, + any * __other, type_info const * __info, + void const* __fallback_info) + { + switch (__act) + { + case _Action::_Destroy: + __destroy(const_cast(*__this)); + return nullptr; + case _Action::_Copy: + __copy(*__this, *__other); + return nullptr; + case _Action::_Move: + __move(const_cast(*__this), *__other); + return nullptr; + case _Action::_Get: + return __get(const_cast(*__this), __info, __fallback_info); + case _Action::_TypeInfo: + return __type_info(); + } + } + + template + _LIBCPP_INLINE_VISIBILITY + static _Tp& __create(any & __dest, _Args&&... __args) { + typedef allocator<_Tp> _Alloc; + typedef __allocator_destructor<_Alloc> _Dp; + _Alloc __a; + unique_ptr<_Tp, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); + _Tp* __ret = ::new ((void*)__hold.get()) _Tp(_VSTD::forward<_Args>(__args)...); + __dest.__s.__ptr = __hold.release(); + __dest.__h = &_LargeHandler::__handle; + return *__ret; + } + + private: + + _LIBCPP_INLINE_VISIBILITY + static void __destroy(any & __this){ + delete static_cast<_Tp*>(__this.__s.__ptr); + __this.__h = nullptr; + } + + _LIBCPP_INLINE_VISIBILITY + static void __copy(any const & __this, any & __dest) { + _LargeHandler::__create(__dest, *static_cast<_Tp const *>(__this.__s.__ptr)); + } + + _LIBCPP_INLINE_VISIBILITY + static void __move(any & __this, any & __dest) { + __dest.__s.__ptr = __this.__s.__ptr; + __dest.__h = &_LargeHandler::__handle; + __this.__h = nullptr; + } + + _LIBCPP_INLINE_VISIBILITY + static void* __get(any & __this, type_info const * __info, + void const* __fallback_info) + { + if (__any_imp::__compare_typeid<_Tp>(__info, __fallback_info)) + return static_cast(__this.__s.__ptr); + return nullptr; + + } + + _LIBCPP_INLINE_VISIBILITY + static void* __type_info() + { +#if !defined(_LIBCPP_NO_RTTI) + return const_cast(static_cast(&typeid(_Tp))); +#else + return nullptr; +#endif + } + }; + +} // namespace __any_imp + + +template +any::any(_ValueType && __v) : __h(nullptr) +{ + __any_imp::_Handler<_Tp>::__create(*this, _VSTD::forward<_ValueType>(__v)); +} + +template +any::any(in_place_type_t<_ValueType>, _Args&&... __args) { + __any_imp::_Handler<_Tp>::__create(*this, _VSTD::forward<_Args>(__args)...); +} + +template +any::any(in_place_type_t<_ValueType>, initializer_list<_Up> __il, _Args&&... __args) { + __any_imp::_Handler<_Tp>::__create(*this, __il, _VSTD::forward<_Args>(__args)...); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +any & any::operator=(_ValueType && __v) +{ + any(_VSTD::forward<_ValueType>(__v)).swap(*this); + return *this; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_Tp& any::emplace(_Args&&... __args) { + reset(); + return __any_imp::_Handler<_Tp>::__create(*this, _VSTD::forward<_Args>(__args)...); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_Tp& any::emplace(initializer_list<_Up> __il, _Args&&... __args) { + reset(); + return __any_imp::_Handler<_Tp>::__create(*this, __il, _VSTD::forward<_Args>(__args)...); +} + +inline _LIBCPP_INLINE_VISIBILITY +void any::swap(any & __rhs) _NOEXCEPT +{ + if (this == &__rhs) + return; + if (__h && __rhs.__h) { + any __tmp; + __rhs.__call(_Action::_Move, &__tmp); + this->__call(_Action::_Move, &__rhs); + __tmp.__call(_Action::_Move, this); + } + else if (__h) { + this->__call(_Action::_Move, &__rhs); + } + else if (__rhs.__h) { + __rhs.__call(_Action::_Move, this); + } +} + +// 6.4 Non-member functions + +inline _LIBCPP_INLINE_VISIBILITY +void swap(any & __lhs, any & __rhs) _NOEXCEPT +{ + __lhs.swap(__rhs); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +any make_any(_Args&&... __args) { + return any(in_place_type<_Tp>, _VSTD::forward<_Args>(__args)...); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +any make_any(initializer_list<_Up> __il, _Args&&... __args) { + return any(in_place_type<_Tp>, __il, _VSTD::forward<_Args>(__args)...); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST +_ValueType any_cast(any const & __v) +{ + using _RawValueType = __uncvref_t<_ValueType>; + static_assert(is_constructible<_ValueType, _RawValueType const &>::value, + "ValueType is required to be a const lvalue reference " + "or a CopyConstructible type"); + auto __tmp = _VSTD::any_cast>(&__v); + if (__tmp == nullptr) + __throw_bad_any_cast(); + return static_cast<_ValueType>(*__tmp); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST +_ValueType any_cast(any & __v) +{ + using _RawValueType = __uncvref_t<_ValueType>; + static_assert(is_constructible<_ValueType, _RawValueType &>::value, + "ValueType is required to be an lvalue reference " + "or a CopyConstructible type"); + auto __tmp = _VSTD::any_cast<_RawValueType>(&__v); + if (__tmp == nullptr) + __throw_bad_any_cast(); + return static_cast<_ValueType>(*__tmp); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST +_ValueType any_cast(any && __v) +{ + using _RawValueType = __uncvref_t<_ValueType>; + static_assert(is_constructible<_ValueType, _RawValueType>::value, + "ValueType is required to be an rvalue reference " + "or a CopyConstructible type"); + auto __tmp = _VSTD::any_cast<_RawValueType>(&__v); + if (__tmp == nullptr) + __throw_bad_any_cast(); + return static_cast<_ValueType>(_VSTD::move(*__tmp)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +add_pointer_t> +any_cast(any const * __any) _NOEXCEPT +{ + static_assert(!is_reference<_ValueType>::value, + "_ValueType may not be a reference."); + return _VSTD::any_cast<_ValueType>(const_cast(__any)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_RetType __pointer_or_func_cast(void* __p, /*IsFunction*/false_type) noexcept { + return static_cast<_RetType>(__p); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_RetType __pointer_or_func_cast(void*, /*IsFunction*/true_type) noexcept { + return nullptr; +} + +template +add_pointer_t<_ValueType> +any_cast(any * __any) _NOEXCEPT +{ + using __any_imp::_Action; + static_assert(!is_reference<_ValueType>::value, + "_ValueType may not be a reference."); + typedef typename add_pointer<_ValueType>::type _ReturnType; + if (__any && __any->__h) { + void *__p = __any->__call(_Action::_Get, nullptr, +#if !defined(_LIBCPP_NO_RTTI) + &typeid(_ValueType), +#else + nullptr, +#endif + __any_imp::__get_fallback_typeid<_ValueType>()); + return _VSTD::__pointer_or_func_cast<_ReturnType>( + __p, is_function<_ValueType>{}); + } + return nullptr; +} + +#endif // _LIBCPP_STD_VER > 14 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_ANY diff --git a/third_party/libcxx/ccomplex b/third_party/libcxx/ccomplex new file mode 100644 index 000000000..c916e7df0 --- /dev/null +++ b/third_party/libcxx/ccomplex @@ -0,0 +1,29 @@ +// -*- C++ -*- +// clang-format off +//===--------------------------- ccomplex ---------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_CCOMPLEX +#define _LIBCPP_CCOMPLEX + +/* + ccomplex synopsis + +#include "third_party/libcxx/complex" + +*/ + +#include "third_party/libcxx/complex" + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +// hh 080623 Created + +#endif // _LIBCPP_CCOMPLEX diff --git a/third_party/libcxx/cfenv b/third_party/libcxx/cfenv new file mode 100644 index 000000000..346266d77 --- /dev/null +++ b/third_party/libcxx/cfenv @@ -0,0 +1,82 @@ +// -*- C++ -*- +// clang-format off +//===---------------------------- cfenv -----------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_CFENV +#define _LIBCPP_CFENV + +/* + cfenv synopsis + +This entire header is C99 / C++0X + +Macros: + + FE_DIVBYZERO + FE_INEXACT + FE_INVALID + FE_OVERFLOW + FE_UNDERFLOW + FE_ALL_EXCEPT + FE_DOWNWARD + FE_TONEAREST + FE_TOWARDZERO + FE_UPWARD + FE_DFL_ENV + +namespace std +{ + +Types: + + fenv_t + fexcept_t + +int feclearexcept(int excepts); +int fegetexceptflag(fexcept_t* flagp, int excepts); +int feraiseexcept(int excepts); +int fesetexceptflag(const fexcept_t* flagp, int excepts); +int fetestexcept(int excepts); +int fegetround(); +int fesetround(int round); +int fegetenv(fenv_t* envp); +int feholdexcept(fenv_t* envp); +int fesetenv(const fenv_t* envp); +int feupdateenv(const fenv_t* envp); + +} // std +*/ + +#include "third_party/libcxx/__config" +#include "libc/runtime/fenv.h" + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +using ::fenv_t; +using ::fexcept_t; + +using ::feclearexcept; +using ::fegetexceptflag; +using ::feraiseexcept; +using ::fesetexceptflag; +using ::fetestexcept; +using ::fegetround; +using ::fesetround; +using ::fegetenv; +using ::feholdexcept; +using ::fesetenv; +using ::feupdateenv; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_CFENV diff --git a/third_party/libcxx/cfloat b/third_party/libcxx/cfloat new file mode 100644 index 000000000..aa6bcdabd --- /dev/null +++ b/third_party/libcxx/cfloat @@ -0,0 +1,81 @@ +// -*- C++ -*- +// clang-format off +//===--------------------------- cfloat -----------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_CFLOAT +#define _LIBCPP_CFLOAT + +/* + cfloat synopsis + +Macros: + + FLT_ROUNDS + FLT_EVAL_METHOD // C99 + FLT_RADIX + + FLT_HAS_SUBNORM // C11 + DBL_HAS_SUBNORM // C11 + LDBL_HAS_SUBNORM // C11 + + FLT_MANT_DIG + DBL_MANT_DIG + LDBL_MANT_DIG + + DECIMAL_DIG // C99 + FLT_DECIMAL_DIG // C11 + DBL_DECIMAL_DIG // C11 + LDBL_DECIMAL_DIG // C11 + + FLT_DIG + DBL_DIG + LDBL_DIG + + FLT_MIN_EXP + DBL_MIN_EXP + LDBL_MIN_EXP + + FLT_MIN_10_EXP + DBL_MIN_10_EXP + LDBL_MIN_10_EXP + + FLT_MAX_EXP + DBL_MAX_EXP + LDBL_MAX_EXP + + FLT_MAX_10_EXP + DBL_MAX_10_EXP + LDBL_MAX_10_EXP + + FLT_MAX + DBL_MAX + LDBL_MAX + + FLT_EPSILON + DBL_EPSILON + LDBL_EPSILON + + FLT_MIN + DBL_MIN + LDBL_MIN + + FLT_TRUE_MIN // C11 + DBL_TRUE_MIN // C11 + LDBL_TRUE_MIN // C11 +*/ + +#include "third_party/libcxx/__config" +#include "libc/math.h" +#include "libc/runtime/fenv.h" + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +#endif // _LIBCPP_CFLOAT diff --git a/third_party/libcxx/cinttypes b/third_party/libcxx/cinttypes new file mode 100644 index 000000000..8bec5fdf4 --- /dev/null +++ b/third_party/libcxx/cinttypes @@ -0,0 +1,259 @@ +// -*- C++ -*- +// clang-format off +//===--------------------------- cinttypes --------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_CINTTYPES +#define _LIBCPP_CINTTYPES + +/* + cinttypes synopsis + +This entire header is C99 / C++0X + +#include "third_party/libcxx/cstdint" // includes + +Macros: + + PRId8 + PRId16 + PRId32 + PRId64 + + PRIdLEAST8 + PRIdLEAST16 + PRIdLEAST32 + PRIdLEAST64 + + PRIdFAST8 + PRIdFAST16 + PRIdFAST32 + PRIdFAST64 + + PRIdMAX + PRIdPTR + + PRIi8 + PRIi16 + PRIi32 + PRIi64 + + PRIiLEAST8 + PRIiLEAST16 + PRIiLEAST32 + PRIiLEAST64 + + PRIiFAST8 + PRIiFAST16 + PRIiFAST32 + PRIiFAST64 + + PRIiMAX + PRIiPTR + + PRIo8 + PRIo16 + PRIo32 + PRIo64 + + PRIoLEAST8 + PRIoLEAST16 + PRIoLEAST32 + PRIoLEAST64 + + PRIoFAST8 + PRIoFAST16 + PRIoFAST32 + PRIoFAST64 + + PRIoMAX + PRIoPTR + + PRIu8 + PRIu16 + PRIu32 + PRIu64 + + PRIuLEAST8 + PRIuLEAST16 + PRIuLEAST32 + PRIuLEAST64 + + PRIuFAST8 + PRIuFAST16 + PRIuFAST32 + PRIuFAST64 + + PRIuMAX + PRIuPTR + + PRIx8 + PRIx16 + PRIx32 + PRIx64 + + PRIxLEAST8 + PRIxLEAST16 + PRIxLEAST32 + PRIxLEAST64 + + PRIxFAST8 + PRIxFAST16 + PRIxFAST32 + PRIxFAST64 + + PRIxMAX + PRIxPTR + + PRIX8 + PRIX16 + PRIX32 + PRIX64 + + PRIXLEAST8 + PRIXLEAST16 + PRIXLEAST32 + PRIXLEAST64 + + PRIXFAST8 + PRIXFAST16 + PRIXFAST32 + PRIXFAST64 + + PRIXMAX + PRIXPTR + + SCNd8 + SCNd16 + SCNd32 + SCNd64 + + SCNdLEAST8 + SCNdLEAST16 + SCNdLEAST32 + SCNdLEAST64 + + SCNdFAST8 + SCNdFAST16 + SCNdFAST32 + SCNdFAST64 + + SCNdMAX + SCNdPTR + + SCNi8 + SCNi16 + SCNi32 + SCNi64 + + SCNiLEAST8 + SCNiLEAST16 + SCNiLEAST32 + SCNiLEAST64 + + SCNiFAST8 + SCNiFAST16 + SCNiFAST32 + SCNiFAST64 + + SCNiMAX + SCNiPTR + + SCNo8 + SCNo16 + SCNo32 + SCNo64 + + SCNoLEAST8 + SCNoLEAST16 + SCNoLEAST32 + SCNoLEAST64 + + SCNoFAST8 + SCNoFAST16 + SCNoFAST32 + SCNoFAST64 + + SCNoMAX + SCNoPTR + + SCNu8 + SCNu16 + SCNu32 + SCNu64 + + SCNuLEAST8 + SCNuLEAST16 + SCNuLEAST32 + SCNuLEAST64 + + SCNuFAST8 + SCNuFAST16 + SCNuFAST32 + SCNuFAST64 + + SCNuMAX + SCNuPTR + + SCNx8 + SCNx16 + SCNx32 + SCNx64 + + SCNxLEAST8 + SCNxLEAST16 + SCNxLEAST32 + SCNxLEAST64 + + SCNxFAST8 + SCNxFAST16 + SCNxFAST32 + SCNxFAST64 + + SCNxMAX + SCNxPTR + +namespace std +{ + +Types: + + imaxdiv_t + +intmax_t imaxabs(intmax_t j); +imaxdiv_t imaxdiv(intmax_t numer, intmax_t denom); +intmax_t strtoimax(const char* restrict nptr, char** restrict endptr, int base); +uintmax_t strtoumax(const char* restrict nptr, char** restrict endptr, int base); +intmax_t wcstoimax(const wchar_t* restrict nptr, wchar_t** restrict endptr, int base); +uintmax_t wcstoumax(const wchar_t* restrict nptr, wchar_t** restrict endptr, int base); + +} // std +*/ + +#include "third_party/libcxx/__config" +#include "third_party/libcxx/cstdint" +#include "libc/inttypes.h" +#include "libc/fmt/conv.h" + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +using::imaxdiv_t; +using::imaxabs; +using::imaxdiv; +using::strtoimax; +using::strtoumax; +using::wcstoimax; +using::wcstoumax; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_CINTTYPES diff --git a/third_party/libcxx/ciso646 b/third_party/libcxx/ciso646 new file mode 100644 index 000000000..da5811403 --- /dev/null +++ b/third_party/libcxx/ciso646 @@ -0,0 +1,25 @@ +// -*- C++ -*- +// clang-format off +//===--------------------------- ciso646 ----------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_CISO646 +#define _LIBCPP_CISO646 + +/* + ciso646 synopsis + +*/ + +#include "third_party/libcxx/__config" + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +#endif // _LIBCPP_CISO646 diff --git a/third_party/libcxx/compare b/third_party/libcxx/compare new file mode 100644 index 000000000..03981697b --- /dev/null +++ b/third_party/libcxx/compare @@ -0,0 +1,679 @@ +// -*- C++ -*- +// clang-format off +//===-------------------------- compare -----------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_COMPARE +#define _LIBCPP_COMPARE + +/* + compare synopsis + +namespace std { + // [cmp.categories], comparison category types + class weak_equality; + class strong_equality; + class partial_ordering; + class weak_ordering; + class strong_ordering; + + // named comparison functions + constexpr bool is_eq (weak_equality cmp) noexcept { return cmp == 0; } + constexpr bool is_neq (weak_equality cmp) noexcept { return cmp != 0; } + constexpr bool is_lt (partial_ordering cmp) noexcept { return cmp < 0; } + constexpr bool is_lteq(partial_ordering cmp) noexcept { return cmp <= 0; } + constexpr bool is_gt (partial_ordering cmp) noexcept { return cmp > 0; } + constexpr bool is_gteq(partial_ordering cmp) noexcept { return cmp >= 0; } + + // [cmp.common], common comparison category type + template + struct common_comparison_category { + using type = see below; + }; + template + using common_comparison_category_t = typename common_comparison_category::type; + + // [cmp.alg], comparison algorithms + template constexpr strong_ordering strong_order(const T& a, const T& b); + template constexpr weak_ordering weak_order(const T& a, const T& b); + template constexpr partial_ordering partial_order(const T& a, const T& b); + template constexpr strong_equality strong_equal(const T& a, const T& b); + template constexpr weak_equality weak_equal(const T& a, const T& b); +} +*/ + +#include "third_party/libcxx/__config" +#include "third_party/libcxx/type_traits" +#include "third_party/libcxx/array" + +#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +// exposition only +enum class _LIBCPP_ENUM_VIS _EqResult : unsigned char { + __zero = 0, + __equal = __zero, + __equiv = __equal, + __nonequal = 1, + __nonequiv = __nonequal +}; + +enum class _LIBCPP_ENUM_VIS _OrdResult : signed char { + __less = -1, + __greater = 1 +}; + +enum class _LIBCPP_ENUM_VIS _NCmpResult : signed char { + __unordered = -127 +}; + +struct _CmpUnspecifiedType; +using _CmpUnspecifiedParam = void (_CmpUnspecifiedType::*)(); + +class weak_equality { + _LIBCPP_INLINE_VISIBILITY + constexpr explicit weak_equality(_EqResult __val) noexcept : __value_(__val) {} + +public: + static const weak_equality equivalent; + static const weak_equality nonequivalent; + + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(weak_equality __v, _CmpUnspecifiedParam) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(_CmpUnspecifiedParam, weak_equality __v) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(weak_equality __v, _CmpUnspecifiedParam) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(_CmpUnspecifiedParam, weak_equality __v) noexcept; + +#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR + _LIBCPP_INLINE_VISIBILITY friend constexpr weak_equality operator<=>(weak_equality __v, _CmpUnspecifiedParam) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr weak_equality operator<=>(_CmpUnspecifiedParam, weak_equality __v) noexcept; +#endif + +private: + _EqResult __value_; +}; + +_LIBCPP_INLINE_VAR constexpr weak_equality weak_equality::equivalent(_EqResult::__equiv); +_LIBCPP_INLINE_VAR constexpr weak_equality weak_equality::nonequivalent(_EqResult::__nonequiv); + +_LIBCPP_INLINE_VISIBILITY +inline constexpr bool operator==(weak_equality __v, _CmpUnspecifiedParam) noexcept { + return __v.__value_ == _EqResult::__zero; +} + +_LIBCPP_INLINE_VISIBILITY +inline constexpr bool operator==(_CmpUnspecifiedParam, weak_equality __v) noexcept { + return __v.__value_ == _EqResult::__zero; +} + +_LIBCPP_INLINE_VISIBILITY +inline constexpr bool operator!=(weak_equality __v, _CmpUnspecifiedParam) noexcept { + return __v.__value_ != _EqResult::__zero; +} + +_LIBCPP_INLINE_VISIBILITY +inline constexpr bool operator!=(_CmpUnspecifiedParam, weak_equality __v) noexcept { + return __v.__value_ != _EqResult::__zero; +} + +#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR +_LIBCPP_INLINE_VISIBILITY +inline constexpr weak_equality operator<=>(weak_equality __v, _CmpUnspecifiedParam) noexcept { + return __v; +} + +_LIBCPP_INLINE_VISIBILITY +inline constexpr weak_equality operator<=>(_CmpUnspecifiedParam, weak_equality __v) noexcept { + return __v; +} +#endif + +class strong_equality { + _LIBCPP_INLINE_VISIBILITY + explicit constexpr strong_equality(_EqResult __val) noexcept : __value_(__val) {} + +public: + static const strong_equality equal; + static const strong_equality nonequal; + static const strong_equality equivalent; + static const strong_equality nonequivalent; + + // conversion + _LIBCPP_INLINE_VISIBILITY constexpr operator weak_equality() const noexcept { + return __value_ == _EqResult::__zero ? weak_equality::equivalent + : weak_equality::nonequivalent; + } + + // comparisons + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(strong_equality __v, _CmpUnspecifiedParam) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(strong_equality __v, _CmpUnspecifiedParam) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(_CmpUnspecifiedParam, strong_equality __v) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(_CmpUnspecifiedParam, strong_equality __v) noexcept; + +#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR + _LIBCPP_INLINE_VISIBILITY friend constexpr strong_equality operator<=>(strong_equality __v, _CmpUnspecifiedParam) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr strong_equality operator<=>(_CmpUnspecifiedParam, strong_equality __v) noexcept; +#endif +private: + _EqResult __value_; +}; + +_LIBCPP_INLINE_VAR constexpr strong_equality strong_equality::equal(_EqResult::__equal); +_LIBCPP_INLINE_VAR constexpr strong_equality strong_equality::nonequal(_EqResult::__nonequal); +_LIBCPP_INLINE_VAR constexpr strong_equality strong_equality::equivalent(_EqResult::__equiv); +_LIBCPP_INLINE_VAR constexpr strong_equality strong_equality::nonequivalent(_EqResult::__nonequiv); + +_LIBCPP_INLINE_VISIBILITY +constexpr bool operator==(strong_equality __v, _CmpUnspecifiedParam) noexcept { + return __v.__value_ == _EqResult::__zero; +} + +_LIBCPP_INLINE_VISIBILITY +constexpr bool operator==(_CmpUnspecifiedParam, strong_equality __v) noexcept { + return __v.__value_ == _EqResult::__zero; +} + +_LIBCPP_INLINE_VISIBILITY +constexpr bool operator!=(strong_equality __v, _CmpUnspecifiedParam) noexcept { + return __v.__value_ != _EqResult::__zero; +} + +_LIBCPP_INLINE_VISIBILITY +constexpr bool operator!=(_CmpUnspecifiedParam, strong_equality __v) noexcept { + return __v.__value_ != _EqResult::__zero; +} + +#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR +_LIBCPP_INLINE_VISIBILITY +constexpr strong_equality operator<=>(strong_equality __v, _CmpUnspecifiedParam) noexcept { + return __v; +} + +_LIBCPP_INLINE_VISIBILITY +constexpr strong_equality operator<=>(_CmpUnspecifiedParam, strong_equality __v) noexcept { + return __v; +} +#endif // _LIBCPP_HAS_NO_SPACESHIP_OPERATOR + +class partial_ordering { + using _ValueT = signed char; + + _LIBCPP_INLINE_VISIBILITY + explicit constexpr partial_ordering(_EqResult __v) noexcept + : __value_(_ValueT(__v)) {} + + _LIBCPP_INLINE_VISIBILITY + explicit constexpr partial_ordering(_OrdResult __v) noexcept + : __value_(_ValueT(__v)) {} + + _LIBCPP_INLINE_VISIBILITY + explicit constexpr partial_ordering(_NCmpResult __v) noexcept + : __value_(_ValueT(__v)) {} + + constexpr bool __is_ordered() const noexcept { + return __value_ != _ValueT(_NCmpResult::__unordered); + } +public: + // valid values + static const partial_ordering less; + static const partial_ordering equivalent; + static const partial_ordering greater; + static const partial_ordering unordered; + + // conversion + constexpr operator weak_equality() const noexcept { + return __value_ == 0 ? weak_equality::equivalent : weak_equality::nonequivalent; + } + + // comparisons + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(partial_ordering __v, _CmpUnspecifiedParam) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(partial_ordering __v, _CmpUnspecifiedParam) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator< (partial_ordering __v, _CmpUnspecifiedParam) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(partial_ordering __v, _CmpUnspecifiedParam) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (partial_ordering __v, _CmpUnspecifiedParam) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(partial_ordering __v, _CmpUnspecifiedParam) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(_CmpUnspecifiedParam, partial_ordering __v) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(_CmpUnspecifiedParam, partial_ordering __v) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator< (_CmpUnspecifiedParam, partial_ordering __v) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(_CmpUnspecifiedParam, partial_ordering __v) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (_CmpUnspecifiedParam, partial_ordering __v) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(_CmpUnspecifiedParam, partial_ordering __v) noexcept; + +#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR + _LIBCPP_INLINE_VISIBILITY friend constexpr partial_ordering operator<=>(partial_ordering __v, _CmpUnspecifiedParam) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr partial_ordering operator<=>(_CmpUnspecifiedParam, partial_ordering __v) noexcept; +#endif + +private: + _ValueT __value_; +}; + +_LIBCPP_INLINE_VAR constexpr partial_ordering partial_ordering::less(_OrdResult::__less); +_LIBCPP_INLINE_VAR constexpr partial_ordering partial_ordering::equivalent(_EqResult::__equiv); +_LIBCPP_INLINE_VAR constexpr partial_ordering partial_ordering::greater(_OrdResult::__greater); +_LIBCPP_INLINE_VAR constexpr partial_ordering partial_ordering::unordered(_NCmpResult ::__unordered); + +_LIBCPP_INLINE_VISIBILITY +constexpr bool operator==(partial_ordering __v, _CmpUnspecifiedParam) noexcept { + return __v.__is_ordered() && __v.__value_ == 0; +} +_LIBCPP_INLINE_VISIBILITY +constexpr bool operator< (partial_ordering __v, _CmpUnspecifiedParam) noexcept { + return __v.__is_ordered() && __v.__value_ < 0; +} +_LIBCPP_INLINE_VISIBILITY +constexpr bool operator<=(partial_ordering __v, _CmpUnspecifiedParam) noexcept { + return __v.__is_ordered() && __v.__value_ <= 0; +} +_LIBCPP_INLINE_VISIBILITY +constexpr bool operator> (partial_ordering __v, _CmpUnspecifiedParam) noexcept { + return __v.__is_ordered() && __v.__value_ > 0; +} +_LIBCPP_INLINE_VISIBILITY +constexpr bool operator>=(partial_ordering __v, _CmpUnspecifiedParam) noexcept { + return __v.__is_ordered() && __v.__value_ >= 0; +} + +_LIBCPP_INLINE_VISIBILITY +constexpr bool operator==(_CmpUnspecifiedParam, partial_ordering __v) noexcept { + return __v.__is_ordered() && 0 == __v.__value_; +} +_LIBCPP_INLINE_VISIBILITY +constexpr bool operator< (_CmpUnspecifiedParam, partial_ordering __v) noexcept { + return __v.__is_ordered() && 0 < __v.__value_; +} +_LIBCPP_INLINE_VISIBILITY +constexpr bool operator<=(_CmpUnspecifiedParam, partial_ordering __v) noexcept { + return __v.__is_ordered() && 0 <= __v.__value_; +} +_LIBCPP_INLINE_VISIBILITY +constexpr bool operator> (_CmpUnspecifiedParam, partial_ordering __v) noexcept { + return __v.__is_ordered() && 0 > __v.__value_; +} +_LIBCPP_INLINE_VISIBILITY +constexpr bool operator>=(_CmpUnspecifiedParam, partial_ordering __v) noexcept { + return __v.__is_ordered() && 0 >= __v.__value_; +} + +_LIBCPP_INLINE_VISIBILITY +constexpr bool operator!=(partial_ordering __v, _CmpUnspecifiedParam) noexcept { + return !__v.__is_ordered() || __v.__value_ != 0; +} +_LIBCPP_INLINE_VISIBILITY +constexpr bool operator!=(_CmpUnspecifiedParam, partial_ordering __v) noexcept { + return !__v.__is_ordered() || __v.__value_ != 0; +} + +#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR +_LIBCPP_INLINE_VISIBILITY +constexpr partial_ordering operator<=>(partial_ordering __v, _CmpUnspecifiedParam) noexcept { + return __v; +} +_LIBCPP_INLINE_VISIBILITY +constexpr partial_ordering operator<=>(_CmpUnspecifiedParam, partial_ordering __v) noexcept { + return __v < 0 ? partial_ordering::greater : (__v > 0 ? partial_ordering::less : __v); +} +#endif // _LIBCPP_HAS_NO_SPACESHIP_OPERATOR + +class weak_ordering { + using _ValueT = signed char; + + _LIBCPP_INLINE_VISIBILITY + explicit constexpr weak_ordering(_EqResult __v) noexcept : __value_(_ValueT(__v)) {} + _LIBCPP_INLINE_VISIBILITY + explicit constexpr weak_ordering(_OrdResult __v) noexcept : __value_(_ValueT(__v)) {} + +public: + static const weak_ordering less; + static const weak_ordering equivalent; + static const weak_ordering greater; + + // conversions + _LIBCPP_INLINE_VISIBILITY + constexpr operator weak_equality() const noexcept { + return __value_ == 0 ? weak_equality::equivalent + : weak_equality::nonequivalent; + } + + _LIBCPP_INLINE_VISIBILITY + constexpr operator partial_ordering() const noexcept { + return __value_ == 0 ? partial_ordering::equivalent + : (__value_ < 0 ? partial_ordering::less : partial_ordering::greater); + } + + // comparisons + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(weak_ordering __v, _CmpUnspecifiedParam) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(weak_ordering __v, _CmpUnspecifiedParam) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator< (weak_ordering __v, _CmpUnspecifiedParam) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(weak_ordering __v, _CmpUnspecifiedParam) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (weak_ordering __v, _CmpUnspecifiedParam) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(weak_ordering __v, _CmpUnspecifiedParam) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(_CmpUnspecifiedParam, weak_ordering __v) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(_CmpUnspecifiedParam, weak_ordering __v) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator< (_CmpUnspecifiedParam, weak_ordering __v) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(_CmpUnspecifiedParam, weak_ordering __v) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (_CmpUnspecifiedParam, weak_ordering __v) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(_CmpUnspecifiedParam, weak_ordering __v) noexcept; + +#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR + _LIBCPP_INLINE_VISIBILITY friend constexpr weak_ordering operator<=>(weak_ordering __v, _CmpUnspecifiedParam) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr weak_ordering operator<=>(_CmpUnspecifiedParam, weak_ordering __v) noexcept; +#endif + +private: + _ValueT __value_; +}; + +_LIBCPP_INLINE_VAR constexpr weak_ordering weak_ordering::less(_OrdResult::__less); +_LIBCPP_INLINE_VAR constexpr weak_ordering weak_ordering::equivalent(_EqResult::__equiv); +_LIBCPP_INLINE_VAR constexpr weak_ordering weak_ordering::greater(_OrdResult::__greater); + +_LIBCPP_INLINE_VISIBILITY +constexpr bool operator==(weak_ordering __v, _CmpUnspecifiedParam) noexcept { + return __v.__value_ == 0; +} +_LIBCPP_INLINE_VISIBILITY +constexpr bool operator!=(weak_ordering __v, _CmpUnspecifiedParam) noexcept { + return __v.__value_ != 0; +} +_LIBCPP_INLINE_VISIBILITY +constexpr bool operator< (weak_ordering __v, _CmpUnspecifiedParam) noexcept { + return __v.__value_ < 0; +} +_LIBCPP_INLINE_VISIBILITY +constexpr bool operator<=(weak_ordering __v, _CmpUnspecifiedParam) noexcept { + return __v.__value_ <= 0; +} +_LIBCPP_INLINE_VISIBILITY +constexpr bool operator> (weak_ordering __v, _CmpUnspecifiedParam) noexcept { + return __v.__value_ > 0; +} +_LIBCPP_INLINE_VISIBILITY +constexpr bool operator>=(weak_ordering __v, _CmpUnspecifiedParam) noexcept { + return __v.__value_ >= 0; +} +_LIBCPP_INLINE_VISIBILITY +constexpr bool operator==(_CmpUnspecifiedParam, weak_ordering __v) noexcept { + return 0 == __v.__value_; +} +_LIBCPP_INLINE_VISIBILITY +constexpr bool operator!=(_CmpUnspecifiedParam, weak_ordering __v) noexcept { + return 0 != __v.__value_; +} +_LIBCPP_INLINE_VISIBILITY +constexpr bool operator< (_CmpUnspecifiedParam, weak_ordering __v) noexcept { + return 0 < __v.__value_; +} +_LIBCPP_INLINE_VISIBILITY +constexpr bool operator<=(_CmpUnspecifiedParam, weak_ordering __v) noexcept { + return 0 <= __v.__value_; +} +_LIBCPP_INLINE_VISIBILITY +constexpr bool operator> (_CmpUnspecifiedParam, weak_ordering __v) noexcept { + return 0 > __v.__value_; +} +_LIBCPP_INLINE_VISIBILITY +constexpr bool operator>=(_CmpUnspecifiedParam, weak_ordering __v) noexcept { + return 0 >= __v.__value_; +} + +#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR +_LIBCPP_INLINE_VISIBILITY +constexpr weak_ordering operator<=>(weak_ordering __v, _CmpUnspecifiedParam) noexcept { + return __v; +} +_LIBCPP_INLINE_VISIBILITY +constexpr weak_ordering operator<=>(_CmpUnspecifiedParam, weak_ordering __v) noexcept { + return __v < 0 ? weak_ordering::greater : (__v > 0 ? weak_ordering::less : __v); +} +#endif // _LIBCPP_HAS_NO_SPACESHIP_OPERATOR + +class strong_ordering { + using _ValueT = signed char; + + _LIBCPP_INLINE_VISIBILITY + explicit constexpr strong_ordering(_EqResult __v) noexcept : __value_(_ValueT(__v)) {} + _LIBCPP_INLINE_VISIBILITY + explicit constexpr strong_ordering(_OrdResult __v) noexcept : __value_(_ValueT(__v)) {} + +public: + static const strong_ordering less; + static const strong_ordering equal; + static const strong_ordering equivalent; + static const strong_ordering greater; + + // conversions + _LIBCPP_INLINE_VISIBILITY + constexpr operator weak_equality() const noexcept { + return __value_ == 0 ? weak_equality::equivalent + : weak_equality::nonequivalent; + } + + _LIBCPP_INLINE_VISIBILITY + constexpr operator strong_equality() const noexcept { + return __value_ == 0 ? strong_equality::equal + : strong_equality::nonequal; + } + + _LIBCPP_INLINE_VISIBILITY + constexpr operator partial_ordering() const noexcept { + return __value_ == 0 ? partial_ordering::equivalent + : (__value_ < 0 ? partial_ordering::less : partial_ordering::greater); + } + + _LIBCPP_INLINE_VISIBILITY + constexpr operator weak_ordering() const noexcept { + return __value_ == 0 ? weak_ordering::equivalent + : (__value_ < 0 ? weak_ordering::less : weak_ordering::greater); + } + + // comparisons + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(strong_ordering __v, _CmpUnspecifiedParam) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(strong_ordering __v, _CmpUnspecifiedParam) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator< (strong_ordering __v, _CmpUnspecifiedParam) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(strong_ordering __v, _CmpUnspecifiedParam) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (strong_ordering __v, _CmpUnspecifiedParam) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(strong_ordering __v, _CmpUnspecifiedParam) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(_CmpUnspecifiedParam, strong_ordering __v) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(_CmpUnspecifiedParam, strong_ordering __v) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator< (_CmpUnspecifiedParam, strong_ordering __v) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(_CmpUnspecifiedParam, strong_ordering __v) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (_CmpUnspecifiedParam, strong_ordering __v) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(_CmpUnspecifiedParam, strong_ordering __v) noexcept; + +#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR + _LIBCPP_INLINE_VISIBILITY friend constexpr strong_ordering operator<=>(strong_ordering __v, _CmpUnspecifiedParam) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr strong_ordering operator<=>(_CmpUnspecifiedParam, strong_ordering __v) noexcept; +#endif + +private: + _ValueT __value_; +}; + +_LIBCPP_INLINE_VAR constexpr strong_ordering strong_ordering::less(_OrdResult::__less); +_LIBCPP_INLINE_VAR constexpr strong_ordering strong_ordering::equal(_EqResult::__equal); +_LIBCPP_INLINE_VAR constexpr strong_ordering strong_ordering::equivalent(_EqResult::__equiv); +_LIBCPP_INLINE_VAR constexpr strong_ordering strong_ordering::greater(_OrdResult::__greater); + +_LIBCPP_INLINE_VISIBILITY +constexpr bool operator==(strong_ordering __v, _CmpUnspecifiedParam) noexcept { + return __v.__value_ == 0; +} +_LIBCPP_INLINE_VISIBILITY +constexpr bool operator!=(strong_ordering __v, _CmpUnspecifiedParam) noexcept { + return __v.__value_ != 0; +} +_LIBCPP_INLINE_VISIBILITY +constexpr bool operator< (strong_ordering __v, _CmpUnspecifiedParam) noexcept { + return __v.__value_ < 0; +} +_LIBCPP_INLINE_VISIBILITY +constexpr bool operator<=(strong_ordering __v, _CmpUnspecifiedParam) noexcept { + return __v.__value_ <= 0; +} +_LIBCPP_INLINE_VISIBILITY +constexpr bool operator> (strong_ordering __v, _CmpUnspecifiedParam) noexcept { + return __v.__value_ > 0; +} +_LIBCPP_INLINE_VISIBILITY +constexpr bool operator>=(strong_ordering __v, _CmpUnspecifiedParam) noexcept { + return __v.__value_ >= 0; +} +_LIBCPP_INLINE_VISIBILITY +constexpr bool operator==(_CmpUnspecifiedParam, strong_ordering __v) noexcept { + return 0 == __v.__value_; +} +_LIBCPP_INLINE_VISIBILITY +constexpr bool operator!=(_CmpUnspecifiedParam, strong_ordering __v) noexcept { + return 0 != __v.__value_; +} +_LIBCPP_INLINE_VISIBILITY +constexpr bool operator< (_CmpUnspecifiedParam, strong_ordering __v) noexcept { + return 0 < __v.__value_; +} +_LIBCPP_INLINE_VISIBILITY +constexpr bool operator<=(_CmpUnspecifiedParam, strong_ordering __v) noexcept { + return 0 <= __v.__value_; +} +_LIBCPP_INLINE_VISIBILITY +constexpr bool operator> (_CmpUnspecifiedParam, strong_ordering __v) noexcept { + return 0 > __v.__value_; +} +_LIBCPP_INLINE_VISIBILITY +constexpr bool operator>=(_CmpUnspecifiedParam, strong_ordering __v) noexcept { + return 0 >= __v.__value_; +} + +#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR +_LIBCPP_INLINE_VISIBILITY +constexpr strong_ordering operator<=>(strong_ordering __v, _CmpUnspecifiedParam) noexcept { + return __v; +} +_LIBCPP_INLINE_VISIBILITY +constexpr strong_ordering operator<=>(_CmpUnspecifiedParam, strong_ordering __v) noexcept { + return __v < 0 ? strong_ordering::greater : (__v > 0 ? strong_ordering::less : __v); +} +#endif // _LIBCPP_HAS_NO_SPACESHIP_OPERATOR + +// named comparison functions +_LIBCPP_INLINE_VISIBILITY +constexpr bool is_eq(weak_equality __cmp) noexcept { return __cmp == 0; } + +_LIBCPP_INLINE_VISIBILITY +constexpr bool is_neq(weak_equality __cmp) noexcept { return __cmp != 0; } + +_LIBCPP_INLINE_VISIBILITY +constexpr bool is_lt(partial_ordering __cmp) noexcept { return __cmp < 0; } + +_LIBCPP_INLINE_VISIBILITY +constexpr bool is_lteq(partial_ordering __cmp) noexcept { return __cmp <= 0; } + +_LIBCPP_INLINE_VISIBILITY +constexpr bool is_gt(partial_ordering __cmp) noexcept { return __cmp > 0; } + +_LIBCPP_INLINE_VISIBILITY +constexpr bool is_gteq(partial_ordering __cmp) noexcept { return __cmp >= 0; } + +namespace __comp_detail { + +enum _ClassifyCompCategory : unsigned{ + _None, + _WeakEq, + _StrongEq, + _PartialOrd, + _WeakOrd, + _StrongOrd, + _CCC_Size +}; + +template +_LIBCPP_INLINE_VISIBILITY +constexpr _ClassifyCompCategory __type_to_enum() noexcept { + if (is_same_v<_Tp, weak_equality>) + return _WeakEq; + if (is_same_v<_Tp, strong_equality>) + return _StrongEq; + if (is_same_v<_Tp, partial_ordering>) + return _PartialOrd; + if (is_same_v<_Tp, weak_ordering>) + return _WeakOrd; + if (is_same_v<_Tp, strong_ordering>) + return _StrongOrd; + return _None; +} + +template +constexpr _ClassifyCompCategory +__compute_comp_type(std::array<_ClassifyCompCategory, _Size> __types) { + std::array __seen = {}; + for (auto __type : __types) + ++__seen[__type]; + if (__seen[_None]) + return _None; + if (__seen[_WeakEq]) + return _WeakEq; + if (__seen[_StrongEq] && (__seen[_PartialOrd] || __seen[_WeakOrd])) + return _WeakEq; + if (__seen[_StrongEq]) + return _StrongEq; + if (__seen[_PartialOrd]) + return _PartialOrd; + if (__seen[_WeakOrd]) + return _WeakOrd; + return _StrongOrd; +} + +template +constexpr auto __get_comp_type() { + using _CCC = _ClassifyCompCategory; + constexpr array<_CCC, sizeof...(_Ts)> __type_kinds{{__comp_detail::__type_to_enum<_Ts>()...}}; + constexpr _CCC _Cat = sizeof...(_Ts) == 0 ? _StrongOrd + : __compute_comp_type(__type_kinds); + if constexpr (_Cat == _None) + return void(); + else if constexpr (_Cat == _WeakEq) + return weak_equality::equivalent; + else if constexpr (_Cat == _StrongEq) + return strong_equality::equivalent; + else if constexpr (_Cat == _PartialOrd) + return partial_ordering::equivalent; + else if constexpr (_Cat == _WeakOrd) + return weak_ordering::equivalent; + else if constexpr (_Cat == _StrongOrd) + return strong_ordering::equivalent; + else + static_assert(_Cat != _Cat, "unhandled case"); +} +} // namespace __comp_detail + +// [cmp.common], common comparison category type +template +struct _LIBCPP_TEMPLATE_VIS common_comparison_category { + using type = decltype(__comp_detail::__get_comp_type<_Ts...>()); +}; + +template +using common_comparison_category_t = typename common_comparison_category<_Ts...>::type; + +// [cmp.alg], comparison algorithms +// TODO: unimplemented +template constexpr strong_ordering strong_order(const _Tp& __lhs, const _Tp& __rhs); +template constexpr weak_ordering weak_order(const _Tp& __lhs, const _Tp& __rhs); +template constexpr partial_ordering partial_order(const _Tp& __lhs, const _Tp& __rhs); +template constexpr strong_equality strong_equal(const _Tp& __lhs, const _Tp& __rhs); +template constexpr weak_equality weak_equal(const _Tp& __lhs, const _Tp& __rhs); + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_COMPARE diff --git a/third_party/libcxx/complex b/third_party/libcxx/complex new file mode 100644 index 000000000..764e54a0f --- /dev/null +++ b/third_party/libcxx/complex @@ -0,0 +1,1496 @@ +// -*- C++ -*- +// clang-format off +//===--------------------------- complex ----------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_COMPLEX +#define _LIBCPP_COMPLEX + +/* + complex synopsis + +namespace std +{ + +template +class complex +{ +public: + typedef T value_type; + + complex(const T& re = T(), const T& im = T()); // constexpr in C++14 + complex(const complex&); // constexpr in C++14 + template complex(const complex&); // constexpr in C++14 + + T real() const; // constexpr in C++14 + T imag() const; // constexpr in C++14 + + void real(T); + void imag(T); + + complex& operator= (const T&); + complex& operator+=(const T&); + complex& operator-=(const T&); + complex& operator*=(const T&); + complex& operator/=(const T&); + + complex& operator=(const complex&); + template complex& operator= (const complex&); + template complex& operator+=(const complex&); + template complex& operator-=(const complex&); + template complex& operator*=(const complex&); + template complex& operator/=(const complex&); +}; + +template<> +class complex +{ +public: + typedef float value_type; + + constexpr complex(float re = 0.0f, float im = 0.0f); + explicit constexpr complex(const complex&); + explicit constexpr complex(const complex&); + + constexpr float real() const; + void real(float); + constexpr float imag() const; + void imag(float); + + complex& operator= (float); + complex& operator+=(float); + complex& operator-=(float); + complex& operator*=(float); + complex& operator/=(float); + + complex& operator=(const complex&); + template complex& operator= (const complex&); + template complex& operator+=(const complex&); + template complex& operator-=(const complex&); + template complex& operator*=(const complex&); + template complex& operator/=(const complex&); +}; + +template<> +class complex +{ +public: + typedef double value_type; + + constexpr complex(double re = 0.0, double im = 0.0); + constexpr complex(const complex&); + explicit constexpr complex(const complex&); + + constexpr double real() const; + void real(double); + constexpr double imag() const; + void imag(double); + + complex& operator= (double); + complex& operator+=(double); + complex& operator-=(double); + complex& operator*=(double); + complex& operator/=(double); + complex& operator=(const complex&); + + template complex& operator= (const complex&); + template complex& operator+=(const complex&); + template complex& operator-=(const complex&); + template complex& operator*=(const complex&); + template complex& operator/=(const complex&); +}; + +template<> +class complex +{ +public: + typedef long double value_type; + + constexpr complex(long double re = 0.0L, long double im = 0.0L); + constexpr complex(const complex&); + constexpr complex(const complex&); + + constexpr long double real() const; + void real(long double); + constexpr long double imag() const; + void imag(long double); + + complex& operator=(const complex&); + complex& operator= (long double); + complex& operator+=(long double); + complex& operator-=(long double); + complex& operator*=(long double); + complex& operator/=(long double); + + template complex& operator= (const complex&); + template complex& operator+=(const complex&); + template complex& operator-=(const complex&); + template complex& operator*=(const complex&); + template complex& operator/=(const complex&); +}; + +// 26.3.6 operators: +template complex operator+(const complex&, const complex&); +template complex operator+(const complex&, const T&); +template complex operator+(const T&, const complex&); +template complex operator-(const complex&, const complex&); +template complex operator-(const complex&, const T&); +template complex operator-(const T&, const complex&); +template complex operator*(const complex&, const complex&); +template complex operator*(const complex&, const T&); +template complex operator*(const T&, const complex&); +template complex operator/(const complex&, const complex&); +template complex operator/(const complex&, const T&); +template complex operator/(const T&, const complex&); +template complex operator+(const complex&); +template complex operator-(const complex&); +template bool operator==(const complex&, const complex&); // constexpr in C++14 +template bool operator==(const complex&, const T&); // constexpr in C++14 +template bool operator==(const T&, const complex&); // constexpr in C++14 +template bool operator!=(const complex&, const complex&); // constexpr in C++14 +template bool operator!=(const complex&, const T&); // constexpr in C++14 +template bool operator!=(const T&, const complex&); // constexpr in C++14 + +template + basic_istream& + operator>>(basic_istream&, complex&); +template + basic_ostream& + operator<<(basic_ostream&, const complex&); + +// 26.3.7 values: + +template T real(const complex&); // constexpr in C++14 + long double real(long double); // constexpr in C++14 + double real(double); // constexpr in C++14 +template double real(T); // constexpr in C++14 + float real(float); // constexpr in C++14 + +template T imag(const complex&); // constexpr in C++14 + long double imag(long double); // constexpr in C++14 + double imag(double); // constexpr in C++14 +template double imag(T); // constexpr in C++14 + float imag(float); // constexpr in C++14 + +template T abs(const complex&); + +template T arg(const complex&); + long double arg(long double); + double arg(double); +template double arg(T); + float arg(float); + +template T norm(const complex&); + long double norm(long double); + double norm(double); +template double norm(T); + float norm(float); + +template complex conj(const complex&); + complex conj(long double); + complex conj(double); +template complex conj(T); + complex conj(float); + +template complex proj(const complex&); + complex proj(long double); + complex proj(double); +template complex proj(T); + complex proj(float); + +template complex polar(const T&, const T& = T()); + +// 26.3.8 transcendentals: +template complex acos(const complex&); +template complex asin(const complex&); +template complex atan(const complex&); +template complex acosh(const complex&); +template complex asinh(const complex&); +template complex atanh(const complex&); +template complex cos (const complex&); +template complex cosh (const complex&); +template complex exp (const complex&); +template complex log (const complex&); +template complex log10(const complex&); + +template complex pow(const complex&, const T&); +template complex pow(const complex&, const complex&); +template complex pow(const T&, const complex&); + +template complex sin (const complex&); +template complex sinh (const complex&); +template complex sqrt (const complex&); +template complex tan (const complex&); +template complex tanh (const complex&); + +template + basic_istream& + operator>>(basic_istream& is, complex& x); + +template + basic_ostream& + operator<<(basic_ostream& o, const complex& x); + +} // std + +*/ + +#include "third_party/libcxx/__config" +#include "third_party/libcxx/type_traits" +#include "third_party/libcxx/stdexcept" +#include "third_party/libcxx/cmath" +#include "third_party/libcxx/sstream" +#include "third_party/libcxx/version" + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template class _LIBCPP_TEMPLATE_VIS complex; + +template complex<_Tp> operator*(const complex<_Tp>& __z, const complex<_Tp>& __w); +template complex<_Tp> operator/(const complex<_Tp>& __x, const complex<_Tp>& __y); + +template +class _LIBCPP_TEMPLATE_VIS complex +{ +public: + typedef _Tp value_type; +private: + value_type __re_; + value_type __im_; +public: + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 + complex(const value_type& __re = value_type(), const value_type& __im = value_type()) + : __re_(__re), __im_(__im) {} + template _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 + complex(const complex<_Xp>& __c) + : __re_(__c.real()), __im_(__c.imag()) {} + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 value_type real() const {return __re_;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 value_type imag() const {return __im_;} + + _LIBCPP_INLINE_VISIBILITY void real(value_type __re) {__re_ = __re;} + _LIBCPP_INLINE_VISIBILITY void imag(value_type __im) {__im_ = __im;} + + _LIBCPP_INLINE_VISIBILITY complex& operator= (const value_type& __re) + {__re_ = __re; __im_ = value_type(); return *this;} + _LIBCPP_INLINE_VISIBILITY complex& operator+=(const value_type& __re) {__re_ += __re; return *this;} + _LIBCPP_INLINE_VISIBILITY complex& operator-=(const value_type& __re) {__re_ -= __re; return *this;} + _LIBCPP_INLINE_VISIBILITY complex& operator*=(const value_type& __re) {__re_ *= __re; __im_ *= __re; return *this;} + _LIBCPP_INLINE_VISIBILITY complex& operator/=(const value_type& __re) {__re_ /= __re; __im_ /= __re; return *this;} + + template _LIBCPP_INLINE_VISIBILITY complex& operator= (const complex<_Xp>& __c) + { + __re_ = __c.real(); + __im_ = __c.imag(); + return *this; + } + template _LIBCPP_INLINE_VISIBILITY complex& operator+=(const complex<_Xp>& __c) + { + __re_ += __c.real(); + __im_ += __c.imag(); + return *this; + } + template _LIBCPP_INLINE_VISIBILITY complex& operator-=(const complex<_Xp>& __c) + { + __re_ -= __c.real(); + __im_ -= __c.imag(); + return *this; + } + template _LIBCPP_INLINE_VISIBILITY complex& operator*=(const complex<_Xp>& __c) + { + *this = *this * complex(__c.real(), __c.imag()); + return *this; + } + template _LIBCPP_INLINE_VISIBILITY complex& operator/=(const complex<_Xp>& __c) + { + *this = *this / complex(__c.real(), __c.imag()); + return *this; + } +}; + +template<> class _LIBCPP_TEMPLATE_VIS complex; +template<> class _LIBCPP_TEMPLATE_VIS complex; + +template<> +class _LIBCPP_TEMPLATE_VIS complex +{ + float __re_; + float __im_; +public: + typedef float value_type; + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR complex(float __re = 0.0f, float __im = 0.0f) + : __re_(__re), __im_(__im) {} + _LIBCPP_INLINE_VISIBILITY + explicit _LIBCPP_CONSTEXPR complex(const complex& __c); + _LIBCPP_INLINE_VISIBILITY + explicit _LIBCPP_CONSTEXPR complex(const complex& __c); + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR float real() const {return __re_;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR float imag() const {return __im_;} + + _LIBCPP_INLINE_VISIBILITY void real(value_type __re) {__re_ = __re;} + _LIBCPP_INLINE_VISIBILITY void imag(value_type __im) {__im_ = __im;} + + _LIBCPP_INLINE_VISIBILITY complex& operator= (float __re) + {__re_ = __re; __im_ = value_type(); return *this;} + _LIBCPP_INLINE_VISIBILITY complex& operator+=(float __re) {__re_ += __re; return *this;} + _LIBCPP_INLINE_VISIBILITY complex& operator-=(float __re) {__re_ -= __re; return *this;} + _LIBCPP_INLINE_VISIBILITY complex& operator*=(float __re) {__re_ *= __re; __im_ *= __re; return *this;} + _LIBCPP_INLINE_VISIBILITY complex& operator/=(float __re) {__re_ /= __re; __im_ /= __re; return *this;} + + template _LIBCPP_INLINE_VISIBILITY complex& operator= (const complex<_Xp>& __c) + { + __re_ = __c.real(); + __im_ = __c.imag(); + return *this; + } + template _LIBCPP_INLINE_VISIBILITY complex& operator+=(const complex<_Xp>& __c) + { + __re_ += __c.real(); + __im_ += __c.imag(); + return *this; + } + template _LIBCPP_INLINE_VISIBILITY complex& operator-=(const complex<_Xp>& __c) + { + __re_ -= __c.real(); + __im_ -= __c.imag(); + return *this; + } + template _LIBCPP_INLINE_VISIBILITY complex& operator*=(const complex<_Xp>& __c) + { + *this = *this * complex(__c.real(), __c.imag()); + return *this; + } + template _LIBCPP_INLINE_VISIBILITY complex& operator/=(const complex<_Xp>& __c) + { + *this = *this / complex(__c.real(), __c.imag()); + return *this; + } +}; + +template<> +class _LIBCPP_TEMPLATE_VIS complex +{ + double __re_; + double __im_; +public: + typedef double value_type; + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR complex(double __re = 0.0, double __im = 0.0) + : __re_(__re), __im_(__im) {} + _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR complex(const complex& __c); + _LIBCPP_INLINE_VISIBILITY + explicit _LIBCPP_CONSTEXPR complex(const complex& __c); + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR double real() const {return __re_;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR double imag() const {return __im_;} + + _LIBCPP_INLINE_VISIBILITY void real(value_type __re) {__re_ = __re;} + _LIBCPP_INLINE_VISIBILITY void imag(value_type __im) {__im_ = __im;} + + _LIBCPP_INLINE_VISIBILITY complex& operator= (double __re) + {__re_ = __re; __im_ = value_type(); return *this;} + _LIBCPP_INLINE_VISIBILITY complex& operator+=(double __re) {__re_ += __re; return *this;} + _LIBCPP_INLINE_VISIBILITY complex& operator-=(double __re) {__re_ -= __re; return *this;} + _LIBCPP_INLINE_VISIBILITY complex& operator*=(double __re) {__re_ *= __re; __im_ *= __re; return *this;} + _LIBCPP_INLINE_VISIBILITY complex& operator/=(double __re) {__re_ /= __re; __im_ /= __re; return *this;} + + template _LIBCPP_INLINE_VISIBILITY complex& operator= (const complex<_Xp>& __c) + { + __re_ = __c.real(); + __im_ = __c.imag(); + return *this; + } + template _LIBCPP_INLINE_VISIBILITY complex& operator+=(const complex<_Xp>& __c) + { + __re_ += __c.real(); + __im_ += __c.imag(); + return *this; + } + template _LIBCPP_INLINE_VISIBILITY complex& operator-=(const complex<_Xp>& __c) + { + __re_ -= __c.real(); + __im_ -= __c.imag(); + return *this; + } + template _LIBCPP_INLINE_VISIBILITY complex& operator*=(const complex<_Xp>& __c) + { + *this = *this * complex(__c.real(), __c.imag()); + return *this; + } + template _LIBCPP_INLINE_VISIBILITY complex& operator/=(const complex<_Xp>& __c) + { + *this = *this / complex(__c.real(), __c.imag()); + return *this; + } +}; + +template<> +class _LIBCPP_TEMPLATE_VIS complex +{ + long double __re_; + long double __im_; +public: + typedef long double value_type; + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR complex(long double __re = 0.0L, long double __im = 0.0L) + : __re_(__re), __im_(__im) {} + _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR complex(const complex& __c); + _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR complex(const complex& __c); + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR long double real() const {return __re_;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR long double imag() const {return __im_;} + + _LIBCPP_INLINE_VISIBILITY void real(value_type __re) {__re_ = __re;} + _LIBCPP_INLINE_VISIBILITY void imag(value_type __im) {__im_ = __im;} + + _LIBCPP_INLINE_VISIBILITY complex& operator= (long double __re) + {__re_ = __re; __im_ = value_type(); return *this;} + _LIBCPP_INLINE_VISIBILITY complex& operator+=(long double __re) {__re_ += __re; return *this;} + _LIBCPP_INLINE_VISIBILITY complex& operator-=(long double __re) {__re_ -= __re; return *this;} + _LIBCPP_INLINE_VISIBILITY complex& operator*=(long double __re) {__re_ *= __re; __im_ *= __re; return *this;} + _LIBCPP_INLINE_VISIBILITY complex& operator/=(long double __re) {__re_ /= __re; __im_ /= __re; return *this;} + + template _LIBCPP_INLINE_VISIBILITY complex& operator= (const complex<_Xp>& __c) + { + __re_ = __c.real(); + __im_ = __c.imag(); + return *this; + } + template _LIBCPP_INLINE_VISIBILITY complex& operator+=(const complex<_Xp>& __c) + { + __re_ += __c.real(); + __im_ += __c.imag(); + return *this; + } + template _LIBCPP_INLINE_VISIBILITY complex& operator-=(const complex<_Xp>& __c) + { + __re_ -= __c.real(); + __im_ -= __c.imag(); + return *this; + } + template _LIBCPP_INLINE_VISIBILITY complex& operator*=(const complex<_Xp>& __c) + { + *this = *this * complex(__c.real(), __c.imag()); + return *this; + } + template _LIBCPP_INLINE_VISIBILITY complex& operator/=(const complex<_Xp>& __c) + { + *this = *this / complex(__c.real(), __c.imag()); + return *this; + } +}; + +inline +_LIBCPP_CONSTEXPR +complex::complex(const complex& __c) + : __re_(__c.real()), __im_(__c.imag()) {} + +inline +_LIBCPP_CONSTEXPR +complex::complex(const complex& __c) + : __re_(__c.real()), __im_(__c.imag()) {} + +inline +_LIBCPP_CONSTEXPR +complex::complex(const complex& __c) + : __re_(__c.real()), __im_(__c.imag()) {} + +inline +_LIBCPP_CONSTEXPR +complex::complex(const complex& __c) + : __re_(__c.real()), __im_(__c.imag()) {} + +inline +_LIBCPP_CONSTEXPR +complex::complex(const complex& __c) + : __re_(__c.real()), __im_(__c.imag()) {} + +inline +_LIBCPP_CONSTEXPR +complex::complex(const complex& __c) + : __re_(__c.real()), __im_(__c.imag()) {} + +// 26.3.6 operators: + +template +inline _LIBCPP_INLINE_VISIBILITY +complex<_Tp> +operator+(const complex<_Tp>& __x, const complex<_Tp>& __y) +{ + complex<_Tp> __t(__x); + __t += __y; + return __t; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +complex<_Tp> +operator+(const complex<_Tp>& __x, const _Tp& __y) +{ + complex<_Tp> __t(__x); + __t += __y; + return __t; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +complex<_Tp> +operator+(const _Tp& __x, const complex<_Tp>& __y) +{ + complex<_Tp> __t(__y); + __t += __x; + return __t; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +complex<_Tp> +operator-(const complex<_Tp>& __x, const complex<_Tp>& __y) +{ + complex<_Tp> __t(__x); + __t -= __y; + return __t; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +complex<_Tp> +operator-(const complex<_Tp>& __x, const _Tp& __y) +{ + complex<_Tp> __t(__x); + __t -= __y; + return __t; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +complex<_Tp> +operator-(const _Tp& __x, const complex<_Tp>& __y) +{ + complex<_Tp> __t(-__y); + __t += __x; + return __t; +} + +template +complex<_Tp> +operator*(const complex<_Tp>& __z, const complex<_Tp>& __w) +{ + _Tp __a = __z.real(); + _Tp __b = __z.imag(); + _Tp __c = __w.real(); + _Tp __d = __w.imag(); + _Tp __ac = __a * __c; + _Tp __bd = __b * __d; + _Tp __ad = __a * __d; + _Tp __bc = __b * __c; + _Tp __x = __ac - __bd; + _Tp __y = __ad + __bc; + if (__libcpp_isnan_or_builtin(__x) && __libcpp_isnan_or_builtin(__y)) + { + bool __recalc = false; + if (__libcpp_isinf_or_builtin(__a) || __libcpp_isinf_or_builtin(__b)) + { + __a = copysign(__libcpp_isinf_or_builtin(__a) ? _Tp(1) : _Tp(0), __a); + __b = copysign(__libcpp_isinf_or_builtin(__b) ? _Tp(1) : _Tp(0), __b); + if (__libcpp_isnan_or_builtin(__c)) + __c = copysign(_Tp(0), __c); + if (__libcpp_isnan_or_builtin(__d)) + __d = copysign(_Tp(0), __d); + __recalc = true; + } + if (__libcpp_isinf_or_builtin(__c) || __libcpp_isinf_or_builtin(__d)) + { + __c = copysign(__libcpp_isinf_or_builtin(__c) ? _Tp(1) : _Tp(0), __c); + __d = copysign(__libcpp_isinf_or_builtin(__d) ? _Tp(1) : _Tp(0), __d); + if (__libcpp_isnan_or_builtin(__a)) + __a = copysign(_Tp(0), __a); + if (__libcpp_isnan_or_builtin(__b)) + __b = copysign(_Tp(0), __b); + __recalc = true; + } + if (!__recalc && (__libcpp_isinf_or_builtin(__ac) || __libcpp_isinf_or_builtin(__bd) || + __libcpp_isinf_or_builtin(__ad) || __libcpp_isinf_or_builtin(__bc))) + { + if (__libcpp_isnan_or_builtin(__a)) + __a = copysign(_Tp(0), __a); + if (__libcpp_isnan_or_builtin(__b)) + __b = copysign(_Tp(0), __b); + if (__libcpp_isnan_or_builtin(__c)) + __c = copysign(_Tp(0), __c); + if (__libcpp_isnan_or_builtin(__d)) + __d = copysign(_Tp(0), __d); + __recalc = true; + } + if (__recalc) + { + __x = _Tp(INFINITY) * (__a * __c - __b * __d); + __y = _Tp(INFINITY) * (__a * __d + __b * __c); + } + } + return complex<_Tp>(__x, __y); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +complex<_Tp> +operator*(const complex<_Tp>& __x, const _Tp& __y) +{ + complex<_Tp> __t(__x); + __t *= __y; + return __t; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +complex<_Tp> +operator*(const _Tp& __x, const complex<_Tp>& __y) +{ + complex<_Tp> __t(__y); + __t *= __x; + return __t; +} + +template +complex<_Tp> +operator/(const complex<_Tp>& __z, const complex<_Tp>& __w) +{ + int __ilogbw = 0; + _Tp __a = __z.real(); + _Tp __b = __z.imag(); + _Tp __c = __w.real(); + _Tp __d = __w.imag(); + _Tp __logbw = logb(fmax(fabs(__c), fabs(__d))); + if (__libcpp_isfinite_or_builtin(__logbw)) + { + __ilogbw = static_cast(__logbw); + __c = scalbn(__c, -__ilogbw); + __d = scalbn(__d, -__ilogbw); + } + _Tp __denom = __c * __c + __d * __d; + _Tp __x = scalbn((__a * __c + __b * __d) / __denom, -__ilogbw); + _Tp __y = scalbn((__b * __c - __a * __d) / __denom, -__ilogbw); + if (__libcpp_isnan_or_builtin(__x) && __libcpp_isnan_or_builtin(__y)) + { + if ((__denom == _Tp(0)) && (!__libcpp_isnan_or_builtin(__a) || !__libcpp_isnan_or_builtin(__b))) + { + __x = copysign(_Tp(INFINITY), __c) * __a; + __y = copysign(_Tp(INFINITY), __c) * __b; + } + else if ((__libcpp_isinf_or_builtin(__a) || __libcpp_isinf_or_builtin(__b)) && __libcpp_isfinite_or_builtin(__c) && __libcpp_isfinite_or_builtin(__d)) + { + __a = copysign(__libcpp_isinf_or_builtin(__a) ? _Tp(1) : _Tp(0), __a); + __b = copysign(__libcpp_isinf_or_builtin(__b) ? _Tp(1) : _Tp(0), __b); + __x = _Tp(INFINITY) * (__a * __c + __b * __d); + __y = _Tp(INFINITY) * (__b * __c - __a * __d); + } + else if (__libcpp_isinf_or_builtin(__logbw) && __logbw > _Tp(0) && __libcpp_isfinite_or_builtin(__a) && __libcpp_isfinite_or_builtin(__b)) + { + __c = copysign(__libcpp_isinf_or_builtin(__c) ? _Tp(1) : _Tp(0), __c); + __d = copysign(__libcpp_isinf_or_builtin(__d) ? _Tp(1) : _Tp(0), __d); + __x = _Tp(0) * (__a * __c + __b * __d); + __y = _Tp(0) * (__b * __c - __a * __d); + } + } + return complex<_Tp>(__x, __y); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +complex<_Tp> +operator/(const complex<_Tp>& __x, const _Tp& __y) +{ + return complex<_Tp>(__x.real() / __y, __x.imag() / __y); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +complex<_Tp> +operator/(const _Tp& __x, const complex<_Tp>& __y) +{ + complex<_Tp> __t(__x); + __t /= __y; + return __t; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +complex<_Tp> +operator+(const complex<_Tp>& __x) +{ + return __x; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +complex<_Tp> +operator-(const complex<_Tp>& __x) +{ + return complex<_Tp>(-__x.real(), -__x.imag()); +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +bool +operator==(const complex<_Tp>& __x, const complex<_Tp>& __y) +{ + return __x.real() == __y.real() && __x.imag() == __y.imag(); +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +bool +operator==(const complex<_Tp>& __x, const _Tp& __y) +{ + return __x.real() == __y && __x.imag() == 0; +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +bool +operator==(const _Tp& __x, const complex<_Tp>& __y) +{ + return __x == __y.real() && 0 == __y.imag(); +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +bool +operator!=(const complex<_Tp>& __x, const complex<_Tp>& __y) +{ + return !(__x == __y); +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +bool +operator!=(const complex<_Tp>& __x, const _Tp& __y) +{ + return !(__x == __y); +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +bool +operator!=(const _Tp& __x, const complex<_Tp>& __y) +{ + return !(__x == __y); +} + +// 26.3.7 values: + +template ::value, + bool = is_floating_point<_Tp>::value + > +struct __libcpp_complex_overload_traits {}; + +// Integral Types +template +struct __libcpp_complex_overload_traits<_Tp, true, false> +{ + typedef double _ValueType; + typedef complex _ComplexType; +}; + +// Floating point types +template +struct __libcpp_complex_overload_traits<_Tp, false, true> +{ + typedef _Tp _ValueType; + typedef complex<_Tp> _ComplexType; +}; + +// real + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +_Tp +real(const complex<_Tp>& __c) +{ + return __c.real(); +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +typename __libcpp_complex_overload_traits<_Tp>::_ValueType +real(_Tp __re) +{ + return __re; +} + +// imag + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +_Tp +imag(const complex<_Tp>& __c) +{ + return __c.imag(); +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +typename __libcpp_complex_overload_traits<_Tp>::_ValueType +imag(_Tp) +{ + return 0; +} + +// abs + +template +inline _LIBCPP_INLINE_VISIBILITY +_Tp +abs(const complex<_Tp>& __c) +{ + return hypot(__c.real(), __c.imag()); +} + +// arg + +template +inline _LIBCPP_INLINE_VISIBILITY +_Tp +arg(const complex<_Tp>& __c) +{ + return atan2(__c.imag(), __c.real()); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if< + is_same<_Tp, long double>::value, + long double +>::type +arg(_Tp __re) +{ + return atan2l(0.L, __re); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + is_integral<_Tp>::value || is_same<_Tp, double>::value, + double +>::type +arg(_Tp __re) +{ + return atan2(0., __re); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if< + is_same<_Tp, float>::value, + float +>::type +arg(_Tp __re) +{ + return atan2f(0.F, __re); +} + +// norm + +template +inline _LIBCPP_INLINE_VISIBILITY +_Tp +norm(const complex<_Tp>& __c) +{ + if (__libcpp_isinf_or_builtin(__c.real())) + return abs(__c.real()); + if (__libcpp_isinf_or_builtin(__c.imag())) + return abs(__c.imag()); + return __c.real() * __c.real() + __c.imag() * __c.imag(); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename __libcpp_complex_overload_traits<_Tp>::_ValueType +norm(_Tp __re) +{ + typedef typename __libcpp_complex_overload_traits<_Tp>::_ValueType _ValueType; + return static_cast<_ValueType>(__re) * __re; +} + +// conj + +template +inline _LIBCPP_INLINE_VISIBILITY +complex<_Tp> +conj(const complex<_Tp>& __c) +{ + return complex<_Tp>(__c.real(), -__c.imag()); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename __libcpp_complex_overload_traits<_Tp>::_ComplexType +conj(_Tp __re) +{ + typedef typename __libcpp_complex_overload_traits<_Tp>::_ComplexType _ComplexType; + return _ComplexType(__re); +} + + + +// proj + +template +inline _LIBCPP_INLINE_VISIBILITY +complex<_Tp> +proj(const complex<_Tp>& __c) +{ + std::complex<_Tp> __r = __c; + if (__libcpp_isinf_or_builtin(__c.real()) || __libcpp_isinf_or_builtin(__c.imag())) + __r = complex<_Tp>(INFINITY, copysign(_Tp(0), __c.imag())); + return __r; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + is_floating_point<_Tp>::value, + typename __libcpp_complex_overload_traits<_Tp>::_ComplexType +>::type +proj(_Tp __re) +{ + if (__libcpp_isinf_or_builtin(__re)) + __re = abs(__re); + return complex<_Tp>(__re); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + is_integral<_Tp>::value, + typename __libcpp_complex_overload_traits<_Tp>::_ComplexType +>::type +proj(_Tp __re) +{ + typedef typename __libcpp_complex_overload_traits<_Tp>::_ComplexType _ComplexType; + return _ComplexType(__re); +} + +// polar + +template +complex<_Tp> +polar(const _Tp& __rho, const _Tp& __theta = _Tp()) +{ + if (__libcpp_isnan_or_builtin(__rho) || signbit(__rho)) + return complex<_Tp>(_Tp(NAN), _Tp(NAN)); + if (__libcpp_isnan_or_builtin(__theta)) + { + if (__libcpp_isinf_or_builtin(__rho)) + return complex<_Tp>(__rho, __theta); + return complex<_Tp>(__theta, __theta); + } + if (__libcpp_isinf_or_builtin(__theta)) + { + if (__libcpp_isinf_or_builtin(__rho)) + return complex<_Tp>(__rho, _Tp(NAN)); + return complex<_Tp>(_Tp(NAN), _Tp(NAN)); + } + _Tp __x = __rho * cos(__theta); + if (__libcpp_isnan_or_builtin(__x)) + __x = 0; + _Tp __y = __rho * sin(__theta); + if (__libcpp_isnan_or_builtin(__y)) + __y = 0; + return complex<_Tp>(__x, __y); +} + +// log + +template +inline _LIBCPP_INLINE_VISIBILITY +complex<_Tp> +log(const complex<_Tp>& __x) +{ + return complex<_Tp>(log(abs(__x)), arg(__x)); +} + +// log10 + +template +inline _LIBCPP_INLINE_VISIBILITY +complex<_Tp> +log10(const complex<_Tp>& __x) +{ + return log(__x) / log(_Tp(10)); +} + +// sqrt + +template +complex<_Tp> +sqrt(const complex<_Tp>& __x) +{ + if (__libcpp_isinf_or_builtin(__x.imag())) + return complex<_Tp>(_Tp(INFINITY), __x.imag()); + if (__libcpp_isinf_or_builtin(__x.real())) + { + if (__x.real() > _Tp(0)) + return complex<_Tp>(__x.real(), __libcpp_isnan_or_builtin(__x.imag()) ? __x.imag() : copysign(_Tp(0), __x.imag())); + return complex<_Tp>(__libcpp_isnan_or_builtin(__x.imag()) ? __x.imag() : _Tp(0), copysign(__x.real(), __x.imag())); + } + return polar(sqrt(abs(__x)), arg(__x) / _Tp(2)); +} + +// exp + +template +complex<_Tp> +exp(const complex<_Tp>& __x) +{ + _Tp __i = __x.imag(); + if (__libcpp_isinf_or_builtin(__x.real())) + { + if (__x.real() < _Tp(0)) + { + if (!__libcpp_isfinite_or_builtin(__i)) + __i = _Tp(1); + } + else if (__i == 0 || !__libcpp_isfinite_or_builtin(__i)) + { + if (__libcpp_isinf_or_builtin(__i)) + __i = _Tp(NAN); + return complex<_Tp>(__x.real(), __i); + } + } + else if (__libcpp_isnan_or_builtin(__x.real()) && __x.imag() == 0) + return __x; + _Tp __e = exp(__x.real()); + return complex<_Tp>(__e * cos(__i), __e * sin(__i)); +} + +// pow + +template +inline _LIBCPP_INLINE_VISIBILITY +complex<_Tp> +pow(const complex<_Tp>& __x, const complex<_Tp>& __y) +{ + return exp(__y * log(__x)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +complex::type> +pow(const complex<_Tp>& __x, const complex<_Up>& __y) +{ + typedef complex::type> result_type; + return _VSTD::pow(result_type(__x), result_type(__y)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + is_arithmetic<_Up>::value, + complex::type> +>::type +pow(const complex<_Tp>& __x, const _Up& __y) +{ + typedef complex::type> result_type; + return _VSTD::pow(result_type(__x), result_type(__y)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + is_arithmetic<_Tp>::value, + complex::type> +>::type +pow(const _Tp& __x, const complex<_Up>& __y) +{ + typedef complex::type> result_type; + return _VSTD::pow(result_type(__x), result_type(__y)); +} + +// __sqr, computes pow(x, 2) + +template +inline _LIBCPP_INLINE_VISIBILITY +complex<_Tp> +__sqr(const complex<_Tp>& __x) +{ + return complex<_Tp>((__x.real() - __x.imag()) * (__x.real() + __x.imag()), + _Tp(2) * __x.real() * __x.imag()); +} + +// asinh + +template +complex<_Tp> +asinh(const complex<_Tp>& __x) +{ + const _Tp __pi(atan2(+0., -0.)); + if (__libcpp_isinf_or_builtin(__x.real())) + { + if (__libcpp_isnan_or_builtin(__x.imag())) + return __x; + if (__libcpp_isinf_or_builtin(__x.imag())) + return complex<_Tp>(__x.real(), copysign(__pi * _Tp(0.25), __x.imag())); + return complex<_Tp>(__x.real(), copysign(_Tp(0), __x.imag())); + } + if (__libcpp_isnan_or_builtin(__x.real())) + { + if (__libcpp_isinf_or_builtin(__x.imag())) + return complex<_Tp>(__x.imag(), __x.real()); + if (__x.imag() == 0) + return __x; + return complex<_Tp>(__x.real(), __x.real()); + } + if (__libcpp_isinf_or_builtin(__x.imag())) + return complex<_Tp>(copysign(__x.imag(), __x.real()), copysign(__pi/_Tp(2), __x.imag())); + complex<_Tp> __z = log(__x + sqrt(__sqr(__x) + _Tp(1))); + return complex<_Tp>(copysign(__z.real(), __x.real()), copysign(__z.imag(), __x.imag())); +} + +// acosh + +template +complex<_Tp> +acosh(const complex<_Tp>& __x) +{ + const _Tp __pi(atan2(+0., -0.)); + if (__libcpp_isinf_or_builtin(__x.real())) + { + if (__libcpp_isnan_or_builtin(__x.imag())) + return complex<_Tp>(abs(__x.real()), __x.imag()); + if (__libcpp_isinf_or_builtin(__x.imag())) + { + if (__x.real() > 0) + return complex<_Tp>(__x.real(), copysign(__pi * _Tp(0.25), __x.imag())); + else + return complex<_Tp>(-__x.real(), copysign(__pi * _Tp(0.75), __x.imag())); + } + if (__x.real() < 0) + return complex<_Tp>(-__x.real(), copysign(__pi, __x.imag())); + return complex<_Tp>(__x.real(), copysign(_Tp(0), __x.imag())); + } + if (__libcpp_isnan_or_builtin(__x.real())) + { + if (__libcpp_isinf_or_builtin(__x.imag())) + return complex<_Tp>(abs(__x.imag()), __x.real()); + return complex<_Tp>(__x.real(), __x.real()); + } + if (__libcpp_isinf_or_builtin(__x.imag())) + return complex<_Tp>(abs(__x.imag()), copysign(__pi/_Tp(2), __x.imag())); + complex<_Tp> __z = log(__x + sqrt(__sqr(__x) - _Tp(1))); + return complex<_Tp>(copysign(__z.real(), _Tp(0)), copysign(__z.imag(), __x.imag())); +} + +// atanh + +template +complex<_Tp> +atanh(const complex<_Tp>& __x) +{ + const _Tp __pi(atan2(+0., -0.)); + if (__libcpp_isinf_or_builtin(__x.imag())) + { + return complex<_Tp>(copysign(_Tp(0), __x.real()), copysign(__pi/_Tp(2), __x.imag())); + } + if (__libcpp_isnan_or_builtin(__x.imag())) + { + if (__libcpp_isinf_or_builtin(__x.real()) || __x.real() == 0) + return complex<_Tp>(copysign(_Tp(0), __x.real()), __x.imag()); + return complex<_Tp>(__x.imag(), __x.imag()); + } + if (__libcpp_isnan_or_builtin(__x.real())) + { + return complex<_Tp>(__x.real(), __x.real()); + } + if (__libcpp_isinf_or_builtin(__x.real())) + { + return complex<_Tp>(copysign(_Tp(0), __x.real()), copysign(__pi/_Tp(2), __x.imag())); + } + if (abs(__x.real()) == _Tp(1) && __x.imag() == _Tp(0)) + { + return complex<_Tp>(copysign(_Tp(INFINITY), __x.real()), copysign(_Tp(0), __x.imag())); + } + complex<_Tp> __z = log((_Tp(1) + __x) / (_Tp(1) - __x)) / _Tp(2); + return complex<_Tp>(copysign(__z.real(), __x.real()), copysign(__z.imag(), __x.imag())); +} + +// sinh + +template +complex<_Tp> +sinh(const complex<_Tp>& __x) +{ + if (__libcpp_isinf_or_builtin(__x.real()) && !__libcpp_isfinite_or_builtin(__x.imag())) + return complex<_Tp>(__x.real(), _Tp(NAN)); + if (__x.real() == 0 && !__libcpp_isfinite_or_builtin(__x.imag())) + return complex<_Tp>(__x.real(), _Tp(NAN)); + if (__x.imag() == 0 && !__libcpp_isfinite_or_builtin(__x.real())) + return __x; + return complex<_Tp>(sinh(__x.real()) * cos(__x.imag()), cosh(__x.real()) * sin(__x.imag())); +} + +// cosh + +template +complex<_Tp> +cosh(const complex<_Tp>& __x) +{ + if (__libcpp_isinf_or_builtin(__x.real()) && !__libcpp_isfinite_or_builtin(__x.imag())) + return complex<_Tp>(abs(__x.real()), _Tp(NAN)); + if (__x.real() == 0 && !__libcpp_isfinite_or_builtin(__x.imag())) + return complex<_Tp>(_Tp(NAN), __x.real()); + if (__x.real() == 0 && __x.imag() == 0) + return complex<_Tp>(_Tp(1), __x.imag()); + if (__x.imag() == 0 && !__libcpp_isfinite_or_builtin(__x.real())) + return complex<_Tp>(abs(__x.real()), __x.imag()); + return complex<_Tp>(cosh(__x.real()) * cos(__x.imag()), sinh(__x.real()) * sin(__x.imag())); +} + +// tanh + +template +complex<_Tp> +tanh(const complex<_Tp>& __x) +{ + if (__libcpp_isinf_or_builtin(__x.real())) + { + if (!__libcpp_isfinite_or_builtin(__x.imag())) + return complex<_Tp>(_Tp(1), _Tp(0)); + return complex<_Tp>(_Tp(1), copysign(_Tp(0), sin(_Tp(2) * __x.imag()))); + } + if (__libcpp_isnan_or_builtin(__x.real()) && __x.imag() == 0) + return __x; + _Tp __2r(_Tp(2) * __x.real()); + _Tp __2i(_Tp(2) * __x.imag()); + _Tp __d(cosh(__2r) + cos(__2i)); + _Tp __2rsh(sinh(__2r)); + if (__libcpp_isinf_or_builtin(__2rsh) && __libcpp_isinf_or_builtin(__d)) + return complex<_Tp>(__2rsh > _Tp(0) ? _Tp(1) : _Tp(-1), + __2i > _Tp(0) ? _Tp(0) : _Tp(-0.)); + return complex<_Tp>(__2rsh/__d, sin(__2i)/__d); +} + +// asin + +template +complex<_Tp> +asin(const complex<_Tp>& __x) +{ + complex<_Tp> __z = asinh(complex<_Tp>(-__x.imag(), __x.real())); + return complex<_Tp>(__z.imag(), -__z.real()); +} + +// acos + +template +complex<_Tp> +acos(const complex<_Tp>& __x) +{ + const _Tp __pi(atan2(+0., -0.)); + if (__libcpp_isinf_or_builtin(__x.real())) + { + if (__libcpp_isnan_or_builtin(__x.imag())) + return complex<_Tp>(__x.imag(), __x.real()); + if (__libcpp_isinf_or_builtin(__x.imag())) + { + if (__x.real() < _Tp(0)) + return complex<_Tp>(_Tp(0.75) * __pi, -__x.imag()); + return complex<_Tp>(_Tp(0.25) * __pi, -__x.imag()); + } + if (__x.real() < _Tp(0)) + return complex<_Tp>(__pi, signbit(__x.imag()) ? -__x.real() : __x.real()); + return complex<_Tp>(_Tp(0), signbit(__x.imag()) ? __x.real() : -__x.real()); + } + if (__libcpp_isnan_or_builtin(__x.real())) + { + if (__libcpp_isinf_or_builtin(__x.imag())) + return complex<_Tp>(__x.real(), -__x.imag()); + return complex<_Tp>(__x.real(), __x.real()); + } + if (__libcpp_isinf_or_builtin(__x.imag())) + return complex<_Tp>(__pi/_Tp(2), -__x.imag()); + if (__x.real() == 0 && (__x.imag() == 0 || isnan(__x.imag()))) + return complex<_Tp>(__pi/_Tp(2), -__x.imag()); + complex<_Tp> __z = log(__x + sqrt(__sqr(__x) - _Tp(1))); + if (signbit(__x.imag())) + return complex<_Tp>(abs(__z.imag()), abs(__z.real())); + return complex<_Tp>(abs(__z.imag()), -abs(__z.real())); +} + +// atan + +template +complex<_Tp> +atan(const complex<_Tp>& __x) +{ + complex<_Tp> __z = atanh(complex<_Tp>(-__x.imag(), __x.real())); + return complex<_Tp>(__z.imag(), -__z.real()); +} + +// sin + +template +complex<_Tp> +sin(const complex<_Tp>& __x) +{ + complex<_Tp> __z = sinh(complex<_Tp>(-__x.imag(), __x.real())); + return complex<_Tp>(__z.imag(), -__z.real()); +} + +// cos + +template +inline _LIBCPP_INLINE_VISIBILITY +complex<_Tp> +cos(const complex<_Tp>& __x) +{ + return cosh(complex<_Tp>(-__x.imag(), __x.real())); +} + +// tan + +template +complex<_Tp> +tan(const complex<_Tp>& __x) +{ + complex<_Tp> __z = tanh(complex<_Tp>(-__x.imag(), __x.real())); + return complex<_Tp>(__z.imag(), -__z.real()); +} + +template +basic_istream<_CharT, _Traits>& +operator>>(basic_istream<_CharT, _Traits>& __is, complex<_Tp>& __x) +{ + if (__is.good()) + { + ws(__is); + if (__is.peek() == _CharT('(')) + { + __is.get(); + _Tp __r; + __is >> __r; + if (!__is.fail()) + { + ws(__is); + _CharT __c = __is.peek(); + if (__c == _CharT(',')) + { + __is.get(); + _Tp __i; + __is >> __i; + if (!__is.fail()) + { + ws(__is); + __c = __is.peek(); + if (__c == _CharT(')')) + { + __is.get(); + __x = complex<_Tp>(__r, __i); + } + else + __is.setstate(ios_base::failbit); + } + else + __is.setstate(ios_base::failbit); + } + else if (__c == _CharT(')')) + { + __is.get(); + __x = complex<_Tp>(__r, _Tp(0)); + } + else + __is.setstate(ios_base::failbit); + } + else + __is.setstate(ios_base::failbit); + } + else + { + _Tp __r; + __is >> __r; + if (!__is.fail()) + __x = complex<_Tp>(__r, _Tp(0)); + else + __is.setstate(ios_base::failbit); + } + } + else + __is.setstate(ios_base::failbit); + return __is; +} + +template +basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, const complex<_Tp>& __x) +{ + basic_ostringstream<_CharT, _Traits> __s; + __s.flags(__os.flags()); + __s.imbue(__os.getloc()); + __s.precision(__os.precision()); + __s << '(' << __x.real() << ',' << __x.imag() << ')'; + return __os << __s.str(); +} + +#if _LIBCPP_STD_VER > 11 +// Literal suffix for complex number literals [complex.literals] +inline namespace literals +{ + inline namespace complex_literals + { + constexpr complex operator""il(long double __im) + { + return { 0.0l, __im }; + } + + constexpr complex operator""il(unsigned long long __im) + { + return { 0.0l, static_cast(__im) }; + } + + + constexpr complex operator""i(long double __im) + { + return { 0.0, static_cast(__im) }; + } + + constexpr complex operator""i(unsigned long long __im) + { + return { 0.0, static_cast(__im) }; + } + + + constexpr complex operator""if(long double __im) + { + return { 0.0f, static_cast(__im) }; + } + + constexpr complex operator""if(unsigned long long __im) + { + return { 0.0f, static_cast(__im) }; + } + } +} +#endif + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_COMPLEX diff --git a/third_party/libcxx/countof.internal.hh b/third_party/libcxx/countof.internal.hh new file mode 100644 index 000000000..90e892318 --- /dev/null +++ b/third_party/libcxx/countof.internal.hh @@ -0,0 +1,20 @@ +#ifndef COSMOPOLITAN_THIRD_PARTY_LIBCXX_COUNTOF_H_ +#define COSMOPOLITAN_THIRD_PARTY_LIBCXX_COUNTOF_H_ +#include "third_party/libcxx/__config" + +namespace { + +template +inline _LIBCPP_CONSTEXPR size_t countof(const T (&)[N]) { + return N; +} + +template +inline _LIBCPP_CONSTEXPR size_t countof(const T* const begin, + const T* const end) { + return static_cast(end - begin); +} + +} // namespace + +#endif /* COSMOPOLITAN_THIRD_PARTY_LIBCXX_COUNTOF_H_ */ diff --git a/third_party/libcxx/csetjmp b/third_party/libcxx/csetjmp new file mode 100644 index 000000000..3888e7e1e --- /dev/null +++ b/third_party/libcxx/csetjmp @@ -0,0 +1,48 @@ +// -*- C++ -*- +// clang-format off +//===--------------------------- csetjmp ----------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_CSETJMP +#define _LIBCPP_CSETJMP + +/* + csetjmp synopsis + +Macros: + + setjmp + +namespace std +{ + +Types: + + jmp_buf + +void longjmp(jmp_buf env, int val); + +} // std + +*/ + +#include "third_party/libcxx/__config" +#include "libc/runtime/runtime.h" + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +using ::jmp_buf; +using ::longjmp; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_CSETJMP diff --git a/third_party/libcxx/csignal b/third_party/libcxx/csignal new file mode 100644 index 000000000..fc251fd49 --- /dev/null +++ b/third_party/libcxx/csignal @@ -0,0 +1,62 @@ +// -*- C++ -*- +// clang-format off +//===--------------------------- csignal ----------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_CSIGNAL +#define _LIBCPP_CSIGNAL + +/* + csignal synopsis + +Macros: + + SIG_DFL + SIG_ERR + SIG_IGN + SIGABRT + SIGFPE + SIGILL + SIGINT + SIGSEGV + SIGTERM + +namespace std +{ + +Types: + + sig_atomic_t + +void (*signal(int sig, void (*func)(int)))(int); +int raise(int sig); + +} // std + +*/ + +#include "third_party/libcxx/__config" +#include "libc/calls/calls.h" +#include "libc/calls/struct/sigaction.h" +#include "libc/calls/struct/siginfo.h" +#include "libc/sysv/consts/sa.h" +#include "libc/sysv/consts/sicode.h" + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +using ::sig_atomic_t; +using ::signal; +using ::raise; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_CSIGNAL diff --git a/third_party/libcxx/cstdbool b/third_party/libcxx/cstdbool new file mode 100644 index 000000000..d5ac7ee36 --- /dev/null +++ b/third_party/libcxx/cstdbool @@ -0,0 +1,32 @@ +// -*- C++ -*- +// clang-format off +//===--------------------------- cstdbool ---------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_CSTDBOOL +#define _LIBCPP_CSTDBOOL + +/* + cstdbool synopsis + +Macros: + + __bool_true_false_are_defined + +*/ + +#include "third_party/libcxx/__config" + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +#undef __bool_true_false_are_defined +#define __bool_true_false_are_defined 1 + +#endif // _LIBCPP_CSTDBOOL diff --git a/third_party/libcxx/ctgmath b/third_party/libcxx/ctgmath new file mode 100644 index 000000000..3561bdd3d --- /dev/null +++ b/third_party/libcxx/ctgmath @@ -0,0 +1,29 @@ +// -*- C++ -*- +// clang-format off +//===-------------------------- ctgmath -----------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_CTGMATH +#define _LIBCPP_CTGMATH + +/* + ctgmath synopsis + +#include "third_party/libcxx/ccomplex" +#include "third_party/libcxx/cmath" + +*/ + +#include "third_party/libcxx/ccomplex" +#include "third_party/libcxx/cmath" + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +#endif // _LIBCPP_CTGMATH diff --git a/third_party/libcxx/execution b/third_party/libcxx/execution new file mode 100644 index 000000000..c9ef9edde --- /dev/null +++ b/third_party/libcxx/execution @@ -0,0 +1,20 @@ +// -*- C++ -*- +// clang-format off +//===------------------------- execution ---------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_EXECUTION +#define _LIBCPP_EXECUTION + +#include "third_party/libcxx/__config" + +#if defined(_LIBCPP_HAS_PARALLEL_ALGORITHMS) && _LIBCPP_STD_VER >= 17 +# include "third_party/libcxx/__pstl_execution" +#endif + +#endif // _LIBCPP_EXECUTION diff --git a/third_party/libcxx/filesystem b/third_party/libcxx/filesystem new file mode 100644 index 000000000..01c255537 --- /dev/null +++ b/third_party/libcxx/filesystem @@ -0,0 +1,2645 @@ +// -*- C++ -*- +// clang-format off +//===--------------------------- filesystem -------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +#ifndef _LIBCPP_FILESYSTEM +#define _LIBCPP_FILESYSTEM +/* + filesystem synopsis + + namespace std { namespace filesystem { + + class path; + + void swap(path& lhs, path& rhs) noexcept; + size_t hash_value(const path& p) noexcept; + + bool operator==(const path& lhs, const path& rhs) noexcept; + bool operator!=(const path& lhs, const path& rhs) noexcept; + bool operator< (const path& lhs, const path& rhs) noexcept; + bool operator<=(const path& lhs, const path& rhs) noexcept; + bool operator> (const path& lhs, const path& rhs) noexcept; + bool operator>=(const path& lhs, const path& rhs) noexcept; + + path operator/ (const path& lhs, const path& rhs); + + // fs.path.io operators are friends of path. + template + friend basic_ostream& + operator<<(basic_ostream& os, const path& p); + + template + friend basic_istream& + operator>>(basic_istream& is, path& p); + + template + path u8path(const Source& source); + template + path u8path(InputIterator first, InputIterator last); + + class filesystem_error; + class directory_entry; + + class directory_iterator; + + // enable directory_iterator range-based for statements + directory_iterator begin(directory_iterator iter) noexcept; + directory_iterator end(const directory_iterator&) noexcept; + + class recursive_directory_iterator; + + // enable recursive_directory_iterator range-based for statements + recursive_directory_iterator begin(recursive_directory_iterator iter) noexcept; + recursive_directory_iterator end(const recursive_directory_iterator&) noexcept; + + class file_status; + + struct space_info + { + uintmax_t capacity; + uintmax_t free; + uintmax_t available; + }; + + enum class file_type; + enum class perms; + enum class perm_options; + enum class copy_options; + enum class directory_options; + + typedef chrono::time_point file_time_type; + + // operational functions + + path absolute(const path& p); + path absolute(const path& p, error_code &ec); + + path canonical(const path& p); + path canonical(const path& p, error_code& ec); + + void copy(const path& from, const path& to); + void copy(const path& from, const path& to, error_code& ec); + void copy(const path& from, const path& to, copy_options options); + void copy(const path& from, const path& to, copy_options options, + error_code& ec); + + bool copy_file(const path& from, const path& to); + bool copy_file(const path& from, const path& to, error_code& ec); + bool copy_file(const path& from, const path& to, copy_options option); + bool copy_file(const path& from, const path& to, copy_options option, + error_code& ec); + + void copy_symlink(const path& existing_symlink, const path& new_symlink); + void copy_symlink(const path& existing_symlink, const path& new_symlink, + error_code& ec) noexcept; + + bool create_directories(const path& p); + bool create_directories(const path& p, error_code& ec); + + bool create_directory(const path& p); + bool create_directory(const path& p, error_code& ec) noexcept; + + bool create_directory(const path& p, const path& attributes); + bool create_directory(const path& p, const path& attributes, + error_code& ec) noexcept; + + void create_directory_symlink(const path& to, const path& new_symlink); + void create_directory_symlink(const path& to, const path& new_symlink, + error_code& ec) noexcept; + + void create_hard_link(const path& to, const path& new_hard_link); + void create_hard_link(const path& to, const path& new_hard_link, + error_code& ec) noexcept; + + void create_symlink(const path& to, const path& new_symlink); + void create_symlink(const path& to, const path& new_symlink, + error_code& ec) noexcept; + + path current_path(); + path current_path(error_code& ec); + void current_path(const path& p); + void current_path(const path& p, error_code& ec) noexcept; + + bool exists(file_status s) noexcept; + bool exists(const path& p); + bool exists(const path& p, error_code& ec) noexcept; + + bool equivalent(const path& p1, const path& p2); + bool equivalent(const path& p1, const path& p2, error_code& ec) noexcept; + + uintmax_t file_size(const path& p); + uintmax_t file_size(const path& p, error_code& ec) noexcept; + + uintmax_t hard_link_count(const path& p); + uintmax_t hard_link_count(const path& p, error_code& ec) noexcept; + + bool is_block_file(file_status s) noexcept; + bool is_block_file(const path& p); + bool is_block_file(const path& p, error_code& ec) noexcept; + + bool is_character_file(file_status s) noexcept; + bool is_character_file(const path& p); + bool is_character_file(const path& p, error_code& ec) noexcept; + + bool is_directory(file_status s) noexcept; + bool is_directory(const path& p); + bool is_directory(const path& p, error_code& ec) noexcept; + + bool is_empty(const path& p); + bool is_empty(const path& p, error_code& ec) noexcept; + + bool is_fifo(file_status s) noexcept; + bool is_fifo(const path& p); + bool is_fifo(const path& p, error_code& ec) noexcept; + + bool is_other(file_status s) noexcept; + bool is_other(const path& p); + bool is_other(const path& p, error_code& ec) noexcept; + + bool is_regular_file(file_status s) noexcept; + bool is_regular_file(const path& p); + bool is_regular_file(const path& p, error_code& ec) noexcept; + + bool is_socket(file_status s) noexcept; + bool is_socket(const path& p); + bool is_socket(const path& p, error_code& ec) noexcept; + + bool is_symlink(file_status s) noexcept; + bool is_symlink(const path& p); + bool is_symlink(const path& p, error_code& ec) noexcept; + + file_time_type last_write_time(const path& p); + file_time_type last_write_time(const path& p, error_code& ec) noexcept; + void last_write_time(const path& p, file_time_type new_time); + void last_write_time(const path& p, file_time_type new_time, + error_code& ec) noexcept; + + void permissions(const path& p, perms prms, + perm_options opts=perm_options::replace); + void permissions(const path& p, perms prms, error_code& ec) noexcept; + void permissions(const path& p, perms prms, perm_options opts, + error_code& ec); + + path proximate(const path& p, error_code& ec); + path proximate(const path& p, const path& base = current_path()); + path proximate(const path& p, const path& base, error_code &ec); + + path read_symlink(const path& p); + path read_symlink(const path& p, error_code& ec); + + path relative(const path& p, error_code& ec); + path relative(const path& p, const path& base=current_path()); + path relative(const path& p, const path& base, error_code& ec); + + bool remove(const path& p); + bool remove(const path& p, error_code& ec) noexcept; + + uintmax_t remove_all(const path& p); + uintmax_t remove_all(const path& p, error_code& ec); + + void rename(const path& from, const path& to); + void rename(const path& from, const path& to, error_code& ec) noexcept; + + void resize_file(const path& p, uintmax_t size); + void resize_file(const path& p, uintmax_t size, error_code& ec) noexcept; + + space_info space(const path& p); + space_info space(const path& p, error_code& ec) noexcept; + + file_status status(const path& p); + file_status status(const path& p, error_code& ec) noexcept; + + bool status_known(file_status s) noexcept; + + file_status symlink_status(const path& p); + file_status symlink_status(const path& p, error_code& ec) noexcept; + + path temp_directory_path(); + path temp_directory_path(error_code& ec); + + path weakly_canonical(path const& p); + path weakly_canonical(path const& p, error_code& ec); + + +} } // namespaces std::filesystem + +*/ + +#include "third_party/libcxx/__config" +#include "third_party/libcxx/cstddef" +#include "third_party/libcxx/cstdlib" +#include "third_party/libcxx/chrono" +#include "third_party/libcxx/iterator" +#include "third_party/libcxx/iosfwd" +#include "third_party/libcxx/locale" +#include "third_party/libcxx/memory" +#include "third_party/libcxx/stack" +#include "third_party/libcxx/string" +#include "third_party/libcxx/system_error" +#include "third_party/libcxx/utility" +#include "third_party/libcxx/iomanip" // for quoted +#include "third_party/libcxx/string_view" +#include "third_party/libcxx/version" + +#include "third_party/libcxx/__debug" + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include "third_party/libcxx/__undef_macros" + +#ifndef _LIBCPP_CXX03_LANG + +_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM + +_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH + +typedef chrono::time_point<_FilesystemClock> file_time_type; + +struct _LIBCPP_TYPE_VIS space_info { + uintmax_t capacity; + uintmax_t free; + uintmax_t available; +}; + +enum class _LIBCPP_ENUM_VIS file_type : signed char { + none = 0, + not_found = -1, + regular = 1, + directory = 2, + symlink = 3, + block = 4, + character = 5, + fifo = 6, + socket = 7, + unknown = 8 +}; + +enum class _LIBCPP_ENUM_VIS perms : unsigned { + none = 0, + + owner_read = 0400, + owner_write = 0200, + owner_exec = 0100, + owner_all = 0700, + + group_read = 040, + group_write = 020, + group_exec = 010, + group_all = 070, + + others_read = 04, + others_write = 02, + others_exec = 01, + others_all = 07, + + all = 0777, + + set_uid = 04000, + set_gid = 02000, + sticky_bit = 01000, + mask = 07777, + unknown = 0xFFFF, +}; + +_LIBCPP_INLINE_VISIBILITY +inline constexpr perms operator&(perms _LHS, perms _RHS) { + return static_cast(static_cast(_LHS) & + static_cast(_RHS)); +} + +_LIBCPP_INLINE_VISIBILITY +inline constexpr perms operator|(perms _LHS, perms _RHS) { + return static_cast(static_cast(_LHS) | + static_cast(_RHS)); +} + +_LIBCPP_INLINE_VISIBILITY +inline constexpr perms operator^(perms _LHS, perms _RHS) { + return static_cast(static_cast(_LHS) ^ + static_cast(_RHS)); +} + +_LIBCPP_INLINE_VISIBILITY +inline constexpr perms operator~(perms _LHS) { + return static_cast(~static_cast(_LHS)); +} + +_LIBCPP_INLINE_VISIBILITY +inline perms& operator&=(perms& _LHS, perms _RHS) { return _LHS = _LHS & _RHS; } + +_LIBCPP_INLINE_VISIBILITY +inline perms& operator|=(perms& _LHS, perms _RHS) { return _LHS = _LHS | _RHS; } + +_LIBCPP_INLINE_VISIBILITY +inline perms& operator^=(perms& _LHS, perms _RHS) { return _LHS = _LHS ^ _RHS; } + +enum class _LIBCPP_ENUM_VIS perm_options : unsigned char { + replace = 1, + add = 2, + remove = 4, + nofollow = 8 +}; + +_LIBCPP_INLINE_VISIBILITY +inline constexpr perm_options operator&(perm_options _LHS, perm_options _RHS) { + return static_cast(static_cast(_LHS) & + static_cast(_RHS)); +} + +_LIBCPP_INLINE_VISIBILITY +inline constexpr perm_options operator|(perm_options _LHS, perm_options _RHS) { + return static_cast(static_cast(_LHS) | + static_cast(_RHS)); +} + +_LIBCPP_INLINE_VISIBILITY +inline constexpr perm_options operator^(perm_options _LHS, perm_options _RHS) { + return static_cast(static_cast(_LHS) ^ + static_cast(_RHS)); +} + +_LIBCPP_INLINE_VISIBILITY +inline constexpr perm_options operator~(perm_options _LHS) { + return static_cast(~static_cast(_LHS)); +} + +_LIBCPP_INLINE_VISIBILITY +inline perm_options& operator&=(perm_options& _LHS, perm_options _RHS) { + return _LHS = _LHS & _RHS; +} + +_LIBCPP_INLINE_VISIBILITY +inline perm_options& operator|=(perm_options& _LHS, perm_options _RHS) { + return _LHS = _LHS | _RHS; +} + +_LIBCPP_INLINE_VISIBILITY +inline perm_options& operator^=(perm_options& _LHS, perm_options _RHS) { + return _LHS = _LHS ^ _RHS; +} + +enum class _LIBCPP_ENUM_VIS copy_options : unsigned short { + none = 0, + skip_existing = 1, + overwrite_existing = 2, + update_existing = 4, + recursive = 8, + copy_symlinks = 16, + skip_symlinks = 32, + directories_only = 64, + create_symlinks = 128, + create_hard_links = 256, + __in_recursive_copy = 512, +}; + +_LIBCPP_INLINE_VISIBILITY +inline constexpr copy_options operator&(copy_options _LHS, copy_options _RHS) { + return static_cast(static_cast(_LHS) & + static_cast(_RHS)); +} + +_LIBCPP_INLINE_VISIBILITY +inline constexpr copy_options operator|(copy_options _LHS, copy_options _RHS) { + return static_cast(static_cast(_LHS) | + static_cast(_RHS)); +} + +_LIBCPP_INLINE_VISIBILITY +inline constexpr copy_options operator^(copy_options _LHS, copy_options _RHS) { + return static_cast(static_cast(_LHS) ^ + static_cast(_RHS)); +} + +_LIBCPP_INLINE_VISIBILITY +inline constexpr copy_options operator~(copy_options _LHS) { + return static_cast(~static_cast(_LHS)); +} + +_LIBCPP_INLINE_VISIBILITY +inline copy_options& operator&=(copy_options& _LHS, copy_options _RHS) { + return _LHS = _LHS & _RHS; +} + +_LIBCPP_INLINE_VISIBILITY +inline copy_options& operator|=(copy_options& _LHS, copy_options _RHS) { + return _LHS = _LHS | _RHS; +} + +_LIBCPP_INLINE_VISIBILITY +inline copy_options& operator^=(copy_options& _LHS, copy_options _RHS) { + return _LHS = _LHS ^ _RHS; +} + +enum class _LIBCPP_ENUM_VIS directory_options : unsigned char { + none = 0, + follow_directory_symlink = 1, + skip_permission_denied = 2 +}; + +_LIBCPP_INLINE_VISIBILITY +inline constexpr directory_options operator&(directory_options _LHS, + directory_options _RHS) { + return static_cast(static_cast(_LHS) & + static_cast(_RHS)); +} + +_LIBCPP_INLINE_VISIBILITY +inline constexpr directory_options operator|(directory_options _LHS, + directory_options _RHS) { + return static_cast(static_cast(_LHS) | + static_cast(_RHS)); +} + +_LIBCPP_INLINE_VISIBILITY +inline constexpr directory_options operator^(directory_options _LHS, + directory_options _RHS) { + return static_cast(static_cast(_LHS) ^ + static_cast(_RHS)); +} + +_LIBCPP_INLINE_VISIBILITY +inline constexpr directory_options operator~(directory_options _LHS) { + return static_cast(~static_cast(_LHS)); +} + +_LIBCPP_INLINE_VISIBILITY +inline directory_options& operator&=(directory_options& _LHS, + directory_options _RHS) { + return _LHS = _LHS & _RHS; +} + +_LIBCPP_INLINE_VISIBILITY +inline directory_options& operator|=(directory_options& _LHS, + directory_options _RHS) { + return _LHS = _LHS | _RHS; +} + +_LIBCPP_INLINE_VISIBILITY +inline directory_options& operator^=(directory_options& _LHS, + directory_options _RHS) { + return _LHS = _LHS ^ _RHS; +} + +class _LIBCPP_TYPE_VIS file_status { +public: + // constructors + _LIBCPP_INLINE_VISIBILITY + file_status() noexcept : file_status(file_type::none) {} + _LIBCPP_INLINE_VISIBILITY + explicit file_status(file_type __ft, perms __prms = perms::unknown) noexcept + : __ft_(__ft), + __prms_(__prms) {} + + file_status(const file_status&) noexcept = default; + file_status(file_status&&) noexcept = default; + + _LIBCPP_INLINE_VISIBILITY + ~file_status() {} + + file_status& operator=(const file_status&) noexcept = default; + file_status& operator=(file_status&&) noexcept = default; + + // observers + _LIBCPP_INLINE_VISIBILITY + file_type type() const noexcept { return __ft_; } + + _LIBCPP_INLINE_VISIBILITY + perms permissions() const noexcept { return __prms_; } + + // modifiers + _LIBCPP_INLINE_VISIBILITY + void type(file_type __ft) noexcept { __ft_ = __ft; } + + _LIBCPP_INLINE_VISIBILITY + void permissions(perms __p) noexcept { __prms_ = __p; } + +private: + file_type __ft_; + perms __prms_; +}; + +class _LIBCPP_TYPE_VIS directory_entry; + +template +struct __can_convert_char { + static const bool value = false; +}; +template +struct __can_convert_char : public __can_convert_char<_Tp> {}; +template <> +struct __can_convert_char { + static const bool value = true; + using __char_type = char; +}; +template <> +struct __can_convert_char { + static const bool value = true; + using __char_type = wchar_t; +}; +template <> +struct __can_convert_char { + static const bool value = true; + using __char_type = char16_t; +}; +template <> +struct __can_convert_char { + static const bool value = true; + using __char_type = char32_t; +}; + +template +typename enable_if<__can_convert_char<_ECharT>::value, bool>::type +__is_separator(_ECharT __e) { + return __e == _ECharT('/'); +} + +struct _NullSentinal {}; + +template +using _Void = void; + +template +struct __is_pathable_string : public false_type {}; + +template +struct __is_pathable_string< + basic_string<_ECharT, _Traits, _Alloc>, + _Void::__char_type> > + : public __can_convert_char<_ECharT> { + using _Str = basic_string<_ECharT, _Traits, _Alloc>; + using _Base = __can_convert_char<_ECharT>; + static _ECharT const* __range_begin(_Str const& __s) { return __s.data(); } + static _ECharT const* __range_end(_Str const& __s) { + return __s.data() + __s.length(); + } + static _ECharT __first_or_null(_Str const& __s) { + return __s.empty() ? _ECharT{} : __s[0]; + } +}; + +template +struct __is_pathable_string< + basic_string_view<_ECharT, _Traits>, + _Void::__char_type> > + : public __can_convert_char<_ECharT> { + using _Str = basic_string_view<_ECharT, _Traits>; + using _Base = __can_convert_char<_ECharT>; + static _ECharT const* __range_begin(_Str const& __s) { return __s.data(); } + static _ECharT const* __range_end(_Str const& __s) { + return __s.data() + __s.length(); + } + static _ECharT __first_or_null(_Str const& __s) { + return __s.empty() ? _ECharT{} : __s[0]; + } +}; + +template ::type, + class _UnqualPtrType = + typename remove_const::type>::type, + bool _IsCharPtr = is_pointer<_DS>::value&& + __can_convert_char<_UnqualPtrType>::value> +struct __is_pathable_char_array : false_type {}; + +template +struct __is_pathable_char_array<_Source, _ECharT*, _UPtr, true> + : __can_convert_char::type> { + using _Base = __can_convert_char::type>; + + static _ECharT const* __range_begin(const _ECharT* __b) { return __b; } + static _ECharT const* __range_end(const _ECharT* __b) { + using _Iter = const _ECharT*; + const _ECharT __sentinal = _ECharT{}; + _Iter __e = __b; + for (; *__e != __sentinal; ++__e) + ; + return __e; + } + + static _ECharT __first_or_null(const _ECharT* __b) { return *__b; } +}; + +template ::value, + class = void> +struct __is_pathable_iter : false_type {}; + +template +struct __is_pathable_iter< + _Iter, true, + _Void::value_type>::__char_type> > + : __can_convert_char::value_type> { + using _ECharT = typename iterator_traits<_Iter>::value_type; + using _Base = __can_convert_char<_ECharT>; + + static _Iter __range_begin(_Iter __b) { return __b; } + static _NullSentinal __range_end(_Iter) { return _NullSentinal{}; } + + static _ECharT __first_or_null(_Iter __b) { return *__b; } +}; + +template ::value, + bool _IsCharIterT = __is_pathable_char_array<_Tp>::value, + bool _IsIterT = !_IsCharIterT && __is_pathable_iter<_Tp>::value> +struct __is_pathable : false_type { + static_assert(!_IsStringT && !_IsCharIterT && !_IsIterT, "Must all be false"); +}; + +template +struct __is_pathable<_Tp, true, false, false> : __is_pathable_string<_Tp> {}; + +template +struct __is_pathable<_Tp, false, true, false> : __is_pathable_char_array<_Tp> { +}; + +template +struct __is_pathable<_Tp, false, false, true> : __is_pathable_iter<_Tp> {}; + +template +struct _PathCVT { + static_assert(__can_convert_char<_ECharT>::value, + "Char type not convertible"); + + typedef __narrow_to_utf8 _Narrower; + + static void __append_range(string& __dest, _ECharT const* __b, + _ECharT const* __e) { + _Narrower()(back_inserter(__dest), __b, __e); + } + + template + static void __append_range(string& __dest, _Iter __b, _Iter __e) { + static_assert(!is_same<_Iter, _ECharT*>::value, "Call const overload"); + if (__b == __e) + return; + basic_string<_ECharT> __tmp(__b, __e); + _Narrower()(back_inserter(__dest), __tmp.data(), + __tmp.data() + __tmp.length()); + } + + template + static void __append_range(string& __dest, _Iter __b, _NullSentinal) { + static_assert(!is_same<_Iter, _ECharT*>::value, "Call const overload"); + const _ECharT __sentinal = _ECharT{}; + if (*__b == __sentinal) + return; + basic_string<_ECharT> __tmp; + for (; *__b != __sentinal; ++__b) + __tmp.push_back(*__b); + _Narrower()(back_inserter(__dest), __tmp.data(), + __tmp.data() + __tmp.length()); + } + + template + static void __append_source(string& __dest, _Source const& __s) { + using _Traits = __is_pathable<_Source>; + __append_range(__dest, _Traits::__range_begin(__s), + _Traits::__range_end(__s)); + } +}; + +template <> +struct _PathCVT { + + template + static typename enable_if<__is_exactly_input_iterator<_Iter>::value>::type + __append_range(string& __dest, _Iter __b, _Iter __e) { + for (; __b != __e; ++__b) + __dest.push_back(*__b); + } + + template + static typename enable_if<__is_forward_iterator<_Iter>::value>::type + __append_range(string& __dest, _Iter __b, _Iter __e) { + __dest.__append_forward_unsafe(__b, __e); + } + + template + static void __append_range(string& __dest, _Iter __b, _NullSentinal) { + const char __sentinal = char{}; + for (; *__b != __sentinal; ++__b) + __dest.push_back(*__b); + } + + template + static void __append_source(string& __dest, _Source const& __s) { + using _Traits = __is_pathable<_Source>; + __append_range(__dest, _Traits::__range_begin(__s), + _Traits::__range_end(__s)); + } +}; + +class _LIBCPP_TYPE_VIS path { + template + using _EnableIfPathable = + typename enable_if<__is_pathable<_SourceOrIter>::value, _Tp>::type; + + template + using _SourceChar = typename __is_pathable<_Tp>::__char_type; + + template + using _SourceCVT = _PathCVT<_SourceChar<_Tp> >; + +public: + typedef char value_type; + typedef basic_string string_type; + typedef _VSTD::string_view __string_view; + static constexpr value_type preferred_separator = '/'; + + enum class _LIBCPP_ENUM_VIS format : unsigned char { + auto_format, + native_format, + generic_format + }; + + // constructors and destructor + _LIBCPP_INLINE_VISIBILITY path() noexcept {} + _LIBCPP_INLINE_VISIBILITY path(const path& __p) : __pn_(__p.__pn_) {} + _LIBCPP_INLINE_VISIBILITY path(path&& __p) noexcept + : __pn_(_VSTD::move(__p.__pn_)) {} + + _LIBCPP_INLINE_VISIBILITY + path(string_type&& __s, format = format::auto_format) noexcept + : __pn_(_VSTD::move(__s)) {} + + template > + path(const _Source& __src, format = format::auto_format) { + _SourceCVT<_Source>::__append_source(__pn_, __src); + } + + template + path(_InputIt __first, _InputIt __last, format = format::auto_format) { + typedef typename iterator_traits<_InputIt>::value_type _ItVal; + _PathCVT<_ItVal>::__append_range(__pn_, __first, __last); + } + + // TODO Implement locale conversions. + template > + path(const _Source& __src, const locale& __loc, format = format::auto_format); + template + path(_InputIt __first, _InputIt _last, const locale& __loc, + format = format::auto_format); + + _LIBCPP_INLINE_VISIBILITY + ~path() = default; + + // assignments + _LIBCPP_INLINE_VISIBILITY + path& operator=(const path& __p) { + __pn_ = __p.__pn_; + return *this; + } + + _LIBCPP_INLINE_VISIBILITY + path& operator=(path&& __p) noexcept { + __pn_ = _VSTD::move(__p.__pn_); + return *this; + } + + template + _LIBCPP_INLINE_VISIBILITY path& operator=(string_type&& __s) noexcept { + __pn_ = _VSTD::move(__s); + return *this; + } + + _LIBCPP_INLINE_VISIBILITY + path& assign(string_type&& __s) noexcept { + __pn_ = _VSTD::move(__s); + return *this; + } + + template + _LIBCPP_INLINE_VISIBILITY _EnableIfPathable<_Source> + operator=(const _Source& __src) { + return this->assign(__src); + } + + template + _EnableIfPathable<_Source> assign(const _Source& __src) { + __pn_.clear(); + _SourceCVT<_Source>::__append_source(__pn_, __src); + return *this; + } + + template + path& assign(_InputIt __first, _InputIt __last) { + typedef typename iterator_traits<_InputIt>::value_type _ItVal; + __pn_.clear(); + _PathCVT<_ItVal>::__append_range(__pn_, __first, __last); + return *this; + } + +private: + template + static bool __source_is_absolute(_ECharT __first_or_null) { + return __is_separator(__first_or_null); + } + +public: + // appends + path& operator/=(const path& __p) { + if (__p.is_absolute()) { + __pn_ = __p.__pn_; + return *this; + } + if (has_filename()) + __pn_ += preferred_separator; + __pn_ += __p.native(); + return *this; + } + + // FIXME: Use _LIBCPP_DIAGNOSE_WARNING to produce a diagnostic when __src + // is known at compile time to be "/' since the user almost certainly intended + // to append a separator instead of overwriting the path with "/" + template + _LIBCPP_INLINE_VISIBILITY _EnableIfPathable<_Source> + operator/=(const _Source& __src) { + return this->append(__src); + } + + template + _EnableIfPathable<_Source> append(const _Source& __src) { + using _Traits = __is_pathable<_Source>; + using _CVT = _PathCVT<_SourceChar<_Source> >; + if (__source_is_absolute(_Traits::__first_or_null(__src))) + __pn_.clear(); + else if (has_filename()) + __pn_ += preferred_separator; + _CVT::__append_source(__pn_, __src); + return *this; + } + + template + path& append(_InputIt __first, _InputIt __last) { + typedef typename iterator_traits<_InputIt>::value_type _ItVal; + static_assert(__can_convert_char<_ItVal>::value, "Must convertible"); + using _CVT = _PathCVT<_ItVal>; + if (__first != __last && __source_is_absolute(*__first)) + __pn_.clear(); + else if (has_filename()) + __pn_ += preferred_separator; + _CVT::__append_range(__pn_, __first, __last); + return *this; + } + + // concatenation + _LIBCPP_INLINE_VISIBILITY + path& operator+=(const path& __x) { + __pn_ += __x.__pn_; + return *this; + } + + _LIBCPP_INLINE_VISIBILITY + path& operator+=(const string_type& __x) { + __pn_ += __x; + return *this; + } + + _LIBCPP_INLINE_VISIBILITY + path& operator+=(__string_view __x) { + __pn_ += __x; + return *this; + } + + _LIBCPP_INLINE_VISIBILITY + path& operator+=(const value_type* __x) { + __pn_ += __x; + return *this; + } + + _LIBCPP_INLINE_VISIBILITY + path& operator+=(value_type __x) { + __pn_ += __x; + return *this; + } + + template + typename enable_if<__can_convert_char<_ECharT>::value, path&>::type + operator+=(_ECharT __x) { + basic_string<_ECharT> __tmp; + __tmp += __x; + _PathCVT<_ECharT>::__append_source(__pn_, __tmp); + return *this; + } + + template + _EnableIfPathable<_Source> operator+=(const _Source& __x) { + return this->concat(__x); + } + + template + _EnableIfPathable<_Source> concat(const _Source& __x) { + _SourceCVT<_Source>::__append_source(__pn_, __x); + return *this; + } + + template + path& concat(_InputIt __first, _InputIt __last) { + typedef typename iterator_traits<_InputIt>::value_type _ItVal; + _PathCVT<_ItVal>::__append_range(__pn_, __first, __last); + return *this; + } + + // modifiers + _LIBCPP_INLINE_VISIBILITY + void clear() noexcept { __pn_.clear(); } + + path& make_preferred() { return *this; } + + _LIBCPP_INLINE_VISIBILITY + path& remove_filename() { + auto __fname = __filename(); + if (!__fname.empty()) + __pn_.erase(__fname.data() - __pn_.data()); + return *this; + } + + path& replace_filename(const path& __replacement) { + remove_filename(); + return (*this /= __replacement); + } + + path& replace_extension(const path& __replacement = path()); + + _LIBCPP_INLINE_VISIBILITY + void swap(path& __rhs) noexcept { __pn_.swap(__rhs.__pn_); } + + // private helper to allow reserving memory in the path + _LIBCPP_INLINE_VISIBILITY + void __reserve(size_t __s) { __pn_.reserve(__s); } + + // native format observers + _LIBCPP_INLINE_VISIBILITY + const string_type& native() const noexcept { return __pn_; } + + _LIBCPP_INLINE_VISIBILITY + const value_type* c_str() const noexcept { return __pn_.c_str(); } + + _LIBCPP_INLINE_VISIBILITY operator string_type() const { return __pn_; } + + template , + class _Allocator = allocator<_ECharT> > + basic_string<_ECharT, _Traits, _Allocator> + string(const _Allocator& __a = _Allocator()) const { + using _CVT = __widen_from_utf8; + using _Str = basic_string<_ECharT, _Traits, _Allocator>; + _Str __s(__a); + __s.reserve(__pn_.size()); + _CVT()(back_inserter(__s), __pn_.data(), __pn_.data() + __pn_.size()); + return __s; + } + + _LIBCPP_INLINE_VISIBILITY std::string string() const { return __pn_; } + _LIBCPP_INLINE_VISIBILITY std::wstring wstring() const { + return string(); + } + _LIBCPP_INLINE_VISIBILITY std::string u8string() const { return __pn_; } + _LIBCPP_INLINE_VISIBILITY std::u16string u16string() const { + return string(); + } + _LIBCPP_INLINE_VISIBILITY std::u32string u32string() const { + return string(); + } + + // generic format observers + template , + class _Allocator = allocator<_ECharT> > + basic_string<_ECharT, _Traits, _Allocator> + generic_string(const _Allocator& __a = _Allocator()) const { + return string<_ECharT, _Traits, _Allocator>(__a); + } + + std::string generic_string() const { return __pn_; } + std::wstring generic_wstring() const { return string(); } + std::string generic_u8string() const { return __pn_; } + std::u16string generic_u16string() const { return string(); } + std::u32string generic_u32string() const { return string(); } + +private: + int __compare(__string_view) const; + __string_view __root_name() const; + __string_view __root_directory() const; + __string_view __root_path_raw() const; + __string_view __relative_path() const; + __string_view __parent_path() const; + __string_view __filename() const; + __string_view __stem() const; + __string_view __extension() const; + +public: + // compare + _LIBCPP_INLINE_VISIBILITY int compare(const path& __p) const noexcept { + return __compare(__p.__pn_); + } + _LIBCPP_INLINE_VISIBILITY int compare(const string_type& __s) const { + return __compare(__s); + } + _LIBCPP_INLINE_VISIBILITY int compare(__string_view __s) const { + return __compare(__s); + } + _LIBCPP_INLINE_VISIBILITY int compare(const value_type* __s) const { + return __compare(__s); + } + + // decomposition + _LIBCPP_INLINE_VISIBILITY path root_name() const { + return string_type(__root_name()); + } + _LIBCPP_INLINE_VISIBILITY path root_directory() const { + return string_type(__root_directory()); + } + _LIBCPP_INLINE_VISIBILITY path root_path() const { + return root_name().append(string_type(__root_directory())); + } + _LIBCPP_INLINE_VISIBILITY path relative_path() const { + return string_type(__relative_path()); + } + _LIBCPP_INLINE_VISIBILITY path parent_path() const { + return string_type(__parent_path()); + } + _LIBCPP_INLINE_VISIBILITY path filename() const { + return string_type(__filename()); + } + _LIBCPP_INLINE_VISIBILITY path stem() const { return string_type(__stem()); } + _LIBCPP_INLINE_VISIBILITY path extension() const { + return string_type(__extension()); + } + + // query + _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY bool + empty() const noexcept { + return __pn_.empty(); + } + + _LIBCPP_INLINE_VISIBILITY bool has_root_name() const { + return !__root_name().empty(); + } + _LIBCPP_INLINE_VISIBILITY bool has_root_directory() const { + return !__root_directory().empty(); + } + _LIBCPP_INLINE_VISIBILITY bool has_root_path() const { + return !__root_path_raw().empty(); + } + _LIBCPP_INLINE_VISIBILITY bool has_relative_path() const { + return !__relative_path().empty(); + } + _LIBCPP_INLINE_VISIBILITY bool has_parent_path() const { + return !__parent_path().empty(); + } + _LIBCPP_INLINE_VISIBILITY bool has_filename() const { + return !__filename().empty(); + } + _LIBCPP_INLINE_VISIBILITY bool has_stem() const { return !__stem().empty(); } + _LIBCPP_INLINE_VISIBILITY bool has_extension() const { + return !__extension().empty(); + } + + _LIBCPP_INLINE_VISIBILITY bool is_absolute() const { + return has_root_directory(); + } + _LIBCPP_INLINE_VISIBILITY bool is_relative() const { return !is_absolute(); } + + // relative paths + path lexically_normal() const; + path lexically_relative(const path& __base) const; + + _LIBCPP_INLINE_VISIBILITY path lexically_proximate(const path& __base) const { + path __result = this->lexically_relative(__base); + if (__result.native().empty()) + return *this; + return __result; + } + + // iterators + class _LIBCPP_TYPE_VIS iterator; + typedef iterator const_iterator; + + iterator begin() const; + iterator end() const; + + template + _LIBCPP_INLINE_VISIBILITY friend + typename enable_if::value && + is_same<_Traits, char_traits >::value, + basic_ostream<_CharT, _Traits>&>::type + operator<<(basic_ostream<_CharT, _Traits>& __os, const path& __p) { + __os << std::__quoted(__p.native()); + return __os; + } + + template + _LIBCPP_INLINE_VISIBILITY friend + typename enable_if::value || + !is_same<_Traits, char_traits >::value, + basic_ostream<_CharT, _Traits>&>::type + operator<<(basic_ostream<_CharT, _Traits>& __os, const path& __p) { + __os << std::__quoted(__p.string<_CharT, _Traits>()); + return __os; + } + + template + _LIBCPP_INLINE_VISIBILITY friend basic_istream<_CharT, _Traits>& + operator>>(basic_istream<_CharT, _Traits>& __is, path& __p) { + basic_string<_CharT, _Traits> __tmp; + __is >> __quoted(__tmp); + __p = __tmp; + return __is; + } + + friend _LIBCPP_INLINE_VISIBILITY bool operator==(const path& __lhs, const path& __rhs) noexcept { + return __lhs.compare(__rhs) == 0; + } + friend _LIBCPP_INLINE_VISIBILITY bool operator!=(const path& __lhs, const path& __rhs) noexcept { + return __lhs.compare(__rhs) != 0; + } + friend _LIBCPP_INLINE_VISIBILITY bool operator<(const path& __lhs, const path& __rhs) noexcept { + return __lhs.compare(__rhs) < 0; + } + friend _LIBCPP_INLINE_VISIBILITY bool operator<=(const path& __lhs, const path& __rhs) noexcept { + return __lhs.compare(__rhs) <= 0; + } + friend _LIBCPP_INLINE_VISIBILITY bool operator>(const path& __lhs, const path& __rhs) noexcept { + return __lhs.compare(__rhs) > 0; + } + friend _LIBCPP_INLINE_VISIBILITY bool operator>=(const path& __lhs, const path& __rhs) noexcept { + return __lhs.compare(__rhs) >= 0; + } + + friend _LIBCPP_INLINE_VISIBILITY path operator/(const path& __lhs, + const path& __rhs) { + path __result(__lhs); + __result /= __rhs; + return __result; + } +private: + inline _LIBCPP_INLINE_VISIBILITY path& + __assign_view(__string_view const& __s) noexcept { + __pn_ = string_type(__s); + return *this; + } + string_type __pn_; +}; + +inline _LIBCPP_INLINE_VISIBILITY void swap(path& __lhs, path& __rhs) noexcept { + __lhs.swap(__rhs); +} + +_LIBCPP_FUNC_VIS +size_t hash_value(const path& __p) noexcept; + +template +_LIBCPP_INLINE_VISIBILITY + typename enable_if<__is_pathable<_Source>::value, path>::type + u8path(const _Source& __s) { + static_assert( + is_same::__char_type, char>::value, + "u8path(Source const&) requires Source have a character type of type " + "'char'"); + return path(__s); +} + +template +_LIBCPP_INLINE_VISIBILITY + typename enable_if<__is_pathable<_InputIt>::value, path>::type + u8path(_InputIt __f, _InputIt __l) { + static_assert( + is_same::__char_type, char>::value, + "u8path(Iter, Iter) requires Iter have a value_type of type 'char'"); + return path(__f, __l); +} + +class _LIBCPP_TYPE_VIS path::iterator { +public: + enum _ParserState : unsigned char { + _Singular, + _BeforeBegin, + _InRootName, + _InRootDir, + _InFilenames, + _InTrailingSep, + _AtEnd + }; + +public: + typedef bidirectional_iterator_tag iterator_category; + + typedef path value_type; + typedef std::ptrdiff_t difference_type; + typedef const path* pointer; + typedef const path& reference; + + typedef void + __stashing_iterator_tag; // See reverse_iterator and __is_stashing_iterator + +public: + _LIBCPP_INLINE_VISIBILITY + iterator() + : __stashed_elem_(), __path_ptr_(nullptr), __entry_(), + __state_(_Singular) {} + + iterator(const iterator&) = default; + ~iterator() = default; + + iterator& operator=(const iterator&) = default; + + _LIBCPP_INLINE_VISIBILITY + reference operator*() const { return __stashed_elem_; } + + _LIBCPP_INLINE_VISIBILITY + pointer operator->() const { return &__stashed_elem_; } + + _LIBCPP_INLINE_VISIBILITY + iterator& operator++() { + _LIBCPP_ASSERT(__state_ != _Singular, + "attempting to increment a singular iterator"); + _LIBCPP_ASSERT(__state_ != _AtEnd, + "attempting to increment the end iterator"); + return __increment(); + } + + _LIBCPP_INLINE_VISIBILITY + iterator operator++(int) { + iterator __it(*this); + this->operator++(); + return __it; + } + + _LIBCPP_INLINE_VISIBILITY + iterator& operator--() { + _LIBCPP_ASSERT(__state_ != _Singular, + "attempting to decrement a singular iterator"); + _LIBCPP_ASSERT(__entry_.data() != __path_ptr_->native().data(), + "attempting to decrement the begin iterator"); + return __decrement(); + } + + _LIBCPP_INLINE_VISIBILITY + iterator operator--(int) { + iterator __it(*this); + this->operator--(); + return __it; + } + +private: + friend class path; + + inline _LIBCPP_INLINE_VISIBILITY friend bool operator==(const iterator&, + const iterator&); + + iterator& __increment(); + iterator& __decrement(); + + path __stashed_elem_; + const path* __path_ptr_; + path::__string_view __entry_; + _ParserState __state_; +}; + +inline _LIBCPP_INLINE_VISIBILITY bool operator==(const path::iterator& __lhs, + const path::iterator& __rhs) { + return __lhs.__path_ptr_ == __rhs.__path_ptr_ && + __lhs.__entry_.data() == __rhs.__entry_.data(); +} + +inline _LIBCPP_INLINE_VISIBILITY bool operator!=(const path::iterator& __lhs, + const path::iterator& __rhs) { + return !(__lhs == __rhs); +} + +// TODO(ldionne): We need to pop the pragma and push it again after +// filesystem_error to work around PR41078. +_LIBCPP_AVAILABILITY_FILESYSTEM_POP + +class _LIBCPP_AVAILABILITY_FILESYSTEM _LIBCPP_EXCEPTION_ABI filesystem_error : public system_error { +public: + _LIBCPP_INLINE_VISIBILITY + filesystem_error(const string& __what, error_code __ec) + : system_error(__ec, __what), + __storage_(make_shared<_Storage>(path(), path())) { + __create_what(0); + } + + _LIBCPP_INLINE_VISIBILITY + filesystem_error(const string& __what, const path& __p1, error_code __ec) + : system_error(__ec, __what), + __storage_(make_shared<_Storage>(__p1, path())) { + __create_what(1); + } + + _LIBCPP_INLINE_VISIBILITY + filesystem_error(const string& __what, const path& __p1, const path& __p2, + error_code __ec) + : system_error(__ec, __what), + __storage_(make_shared<_Storage>(__p1, __p2)) { + __create_what(2); + } + + _LIBCPP_INLINE_VISIBILITY + const path& path1() const noexcept { return __storage_->__p1_; } + + _LIBCPP_INLINE_VISIBILITY + const path& path2() const noexcept { return __storage_->__p2_; } + + ~filesystem_error() override; // key function + + _LIBCPP_INLINE_VISIBILITY + const char* what() const noexcept override { + return __storage_->__what_.c_str(); + } + + void __create_what(int __num_paths); + +private: + struct _LIBCPP_HIDDEN _Storage { + _LIBCPP_INLINE_VISIBILITY + _Storage(const path& __p1, const path& __p2) : __p1_(__p1), __p2_(__p2) {} + + path __p1_; + path __p2_; + string __what_; + }; + shared_ptr<_Storage> __storage_; +}; + +_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH + +template +_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY +#ifndef _LIBCPP_NO_EXCEPTIONS +void __throw_filesystem_error(_Args&&... __args) { + throw filesystem_error(std::forward<_Args>(__args)...); +} +#else +void __throw_filesystem_error(_Args&&...) { + _VSTD::abort(); +} +#endif + +// operational functions + +_LIBCPP_FUNC_VIS +path __absolute(const path&, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS +path __canonical(const path&, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS +void __copy(const path& __from, const path& __to, copy_options __opt, + error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS +bool __copy_file(const path& __from, const path& __to, copy_options __opt, + error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS +void __copy_symlink(const path& __existing_symlink, const path& __new_symlink, + error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS +bool __create_directories(const path& p, error_code* ec = nullptr); +_LIBCPP_FUNC_VIS +bool __create_directory(const path& p, error_code* ec = nullptr); +_LIBCPP_FUNC_VIS +bool __create_directory(const path& p, const path& attributes, + error_code* ec = nullptr); +_LIBCPP_FUNC_VIS +void __create_directory_symlink(const path& __to, const path& __new_symlink, + error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS +void __create_hard_link(const path& __to, const path& __new_hard_link, + error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS +void __create_symlink(const path& __to, const path& __new_symlink, + error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS +path __current_path(error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS +void __current_path(const path&, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS +bool __equivalent(const path&, const path&, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS +uintmax_t __file_size(const path&, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS +uintmax_t __hard_link_count(const path&, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS +bool __fs_is_empty(const path& p, error_code* ec = nullptr); +_LIBCPP_FUNC_VIS +file_time_type __last_write_time(const path& p, error_code* ec = nullptr); +_LIBCPP_FUNC_VIS +void __last_write_time(const path& p, file_time_type new_time, + error_code* ec = nullptr); +_LIBCPP_FUNC_VIS +void __permissions(const path&, perms, perm_options, error_code* = nullptr); +_LIBCPP_FUNC_VIS +path __read_symlink(const path& p, error_code* ec = nullptr); +_LIBCPP_FUNC_VIS +bool __remove(const path& p, error_code* ec = nullptr); +_LIBCPP_FUNC_VIS +uintmax_t __remove_all(const path& p, error_code* ec = nullptr); +_LIBCPP_FUNC_VIS +void __rename(const path& from, const path& to, error_code* ec = nullptr); +_LIBCPP_FUNC_VIS +void __resize_file(const path& p, uintmax_t size, error_code* ec = nullptr); +_LIBCPP_FUNC_VIS +space_info __space(const path&, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS +file_status __status(const path&, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS +file_status __symlink_status(const path&, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS +path __system_complete(const path&, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS +path __temp_directory_path(error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS +path __weakly_canonical(path const& __p, error_code* __ec = nullptr); + +inline _LIBCPP_INLINE_VISIBILITY path current_path() { + return __current_path(); +} + +inline _LIBCPP_INLINE_VISIBILITY path current_path(error_code& __ec) { + return __current_path(&__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY void current_path(const path& __p) { + __current_path(__p); +} + +inline _LIBCPP_INLINE_VISIBILITY void current_path(const path& __p, + error_code& __ec) noexcept { + __current_path(__p, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY path absolute(const path& __p) { + return __absolute(__p); +} + +inline _LIBCPP_INLINE_VISIBILITY path absolute(const path& __p, + error_code& __ec) { + return __absolute(__p, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY path canonical(const path& __p) { + return __canonical(__p); +} + +inline _LIBCPP_INLINE_VISIBILITY path canonical(const path& __p, + error_code& __ec) { + return __canonical(__p, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY void copy(const path& __from, + const path& __to) { + __copy(__from, __to, copy_options::none); +} + +inline _LIBCPP_INLINE_VISIBILITY void copy(const path& __from, const path& __to, + error_code& __ec) { + __copy(__from, __to, copy_options::none, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY void copy(const path& __from, const path& __to, + copy_options __opt) { + __copy(__from, __to, __opt); +} + +inline _LIBCPP_INLINE_VISIBILITY void copy(const path& __from, const path& __to, + copy_options __opt, + error_code& __ec) { + __copy(__from, __to, __opt, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY bool copy_file(const path& __from, + const path& __to) { + return __copy_file(__from, __to, copy_options::none); +} + +inline _LIBCPP_INLINE_VISIBILITY bool +copy_file(const path& __from, const path& __to, error_code& __ec) { + return __copy_file(__from, __to, copy_options::none, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY bool +copy_file(const path& __from, const path& __to, copy_options __opt) { + return __copy_file(__from, __to, __opt); +} + +inline _LIBCPP_INLINE_VISIBILITY bool copy_file(const path& __from, + const path& __to, + copy_options __opt, + error_code& __ec) { + return __copy_file(__from, __to, __opt, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY void copy_symlink(const path& __existing, + const path& __new) { + __copy_symlink(__existing, __new); +} + +inline _LIBCPP_INLINE_VISIBILITY void +copy_symlink(const path& __ext, const path& __new, error_code& __ec) noexcept { + __copy_symlink(__ext, __new, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY bool create_directories(const path& __p) { + return __create_directories(__p); +} + +inline _LIBCPP_INLINE_VISIBILITY bool create_directories(const path& __p, + error_code& __ec) { + return __create_directories(__p, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY bool create_directory(const path& __p) { + return __create_directory(__p); +} + +inline _LIBCPP_INLINE_VISIBILITY bool +create_directory(const path& __p, error_code& __ec) noexcept { + return __create_directory(__p, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY bool create_directory(const path& __p, + const path& __attrs) { + return __create_directory(__p, __attrs); +} + +inline _LIBCPP_INLINE_VISIBILITY bool +create_directory(const path& __p, const path& __attrs, + error_code& __ec) noexcept { + return __create_directory(__p, __attrs, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY void +create_directory_symlink(const path& __to, const path& __new) { + __create_directory_symlink(__to, __new); +} + +inline _LIBCPP_INLINE_VISIBILITY void +create_directory_symlink(const path& __to, const path& __new, + error_code& __ec) noexcept { + __create_directory_symlink(__to, __new, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY void create_hard_link(const path& __to, + const path& __new) { + __create_hard_link(__to, __new); +} + +inline _LIBCPP_INLINE_VISIBILITY void +create_hard_link(const path& __to, const path& __new, + error_code& __ec) noexcept { + __create_hard_link(__to, __new, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY void create_symlink(const path& __to, + const path& __new) { + __create_symlink(__to, __new); +} + +inline _LIBCPP_INLINE_VISIBILITY void +create_symlink(const path& __to, const path& __new, error_code& __ec) noexcept { + return __create_symlink(__to, __new, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY bool status_known(file_status __s) noexcept { + return __s.type() != file_type::none; +} + +inline _LIBCPP_INLINE_VISIBILITY bool exists(file_status __s) noexcept { + return status_known(__s) && __s.type() != file_type::not_found; +} + +inline _LIBCPP_INLINE_VISIBILITY bool exists(const path& __p) { + return exists(__status(__p)); +} + +inline _LIBCPP_INLINE_VISIBILITY bool exists(const path& __p, + error_code& __ec) noexcept { + auto __s = __status(__p, &__ec); + if (status_known(__s)) + __ec.clear(); + return exists(__s); +} + +inline _LIBCPP_INLINE_VISIBILITY bool equivalent(const path& __p1, + const path& __p2) { + return __equivalent(__p1, __p2); +} + +inline _LIBCPP_INLINE_VISIBILITY bool +equivalent(const path& __p1, const path& __p2, error_code& __ec) noexcept { + return __equivalent(__p1, __p2, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY uintmax_t file_size(const path& __p) { + return __file_size(__p); +} + +inline _LIBCPP_INLINE_VISIBILITY uintmax_t +file_size(const path& __p, error_code& __ec) noexcept { + return __file_size(__p, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY uintmax_t hard_link_count(const path& __p) { + return __hard_link_count(__p); +} + +inline _LIBCPP_INLINE_VISIBILITY uintmax_t +hard_link_count(const path& __p, error_code& __ec) noexcept { + return __hard_link_count(__p, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY bool is_block_file(file_status __s) noexcept { + return __s.type() == file_type::block; +} + +inline _LIBCPP_INLINE_VISIBILITY bool is_block_file(const path& __p) { + return is_block_file(__status(__p)); +} + +inline _LIBCPP_INLINE_VISIBILITY bool is_block_file(const path& __p, + error_code& __ec) noexcept { + return is_block_file(__status(__p, &__ec)); +} + +inline _LIBCPP_INLINE_VISIBILITY bool +is_character_file(file_status __s) noexcept { + return __s.type() == file_type::character; +} + +inline _LIBCPP_INLINE_VISIBILITY bool is_character_file(const path& __p) { + return is_character_file(__status(__p)); +} + +inline _LIBCPP_INLINE_VISIBILITY bool +is_character_file(const path& __p, error_code& __ec) noexcept { + return is_character_file(__status(__p, &__ec)); +} + +inline _LIBCPP_INLINE_VISIBILITY bool is_directory(file_status __s) noexcept { + return __s.type() == file_type::directory; +} + +inline _LIBCPP_INLINE_VISIBILITY bool is_directory(const path& __p) { + return is_directory(__status(__p)); +} + +inline _LIBCPP_INLINE_VISIBILITY bool is_directory(const path& __p, + error_code& __ec) noexcept { + return is_directory(__status(__p, &__ec)); +} + +inline _LIBCPP_INLINE_VISIBILITY bool is_empty(const path& __p) { + return __fs_is_empty(__p); +} + +inline _LIBCPP_INLINE_VISIBILITY bool is_empty(const path& __p, + error_code& __ec) { + return __fs_is_empty(__p, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY bool is_fifo(file_status __s) noexcept { + return __s.type() == file_type::fifo; +} +inline _LIBCPP_INLINE_VISIBILITY bool is_fifo(const path& __p) { + return is_fifo(__status(__p)); +} + +inline _LIBCPP_INLINE_VISIBILITY bool is_fifo(const path& __p, + error_code& __ec) noexcept { + return is_fifo(__status(__p, &__ec)); +} + +inline _LIBCPP_INLINE_VISIBILITY bool +is_regular_file(file_status __s) noexcept { + return __s.type() == file_type::regular; +} + +inline _LIBCPP_INLINE_VISIBILITY bool is_regular_file(const path& __p) { + return is_regular_file(__status(__p)); +} + +inline _LIBCPP_INLINE_VISIBILITY bool +is_regular_file(const path& __p, error_code& __ec) noexcept { + return is_regular_file(__status(__p, &__ec)); +} + +inline _LIBCPP_INLINE_VISIBILITY bool is_socket(file_status __s) noexcept { + return __s.type() == file_type::socket; +} + +inline _LIBCPP_INLINE_VISIBILITY bool is_socket(const path& __p) { + return is_socket(__status(__p)); +} + +inline _LIBCPP_INLINE_VISIBILITY bool is_socket(const path& __p, + error_code& __ec) noexcept { + return is_socket(__status(__p, &__ec)); +} + +inline _LIBCPP_INLINE_VISIBILITY bool is_symlink(file_status __s) noexcept { + return __s.type() == file_type::symlink; +} + +inline _LIBCPP_INLINE_VISIBILITY bool is_symlink(const path& __p) { + return is_symlink(__symlink_status(__p)); +} + +inline _LIBCPP_INLINE_VISIBILITY bool is_symlink(const path& __p, + error_code& __ec) noexcept { + return is_symlink(__symlink_status(__p, &__ec)); +} + +inline _LIBCPP_INLINE_VISIBILITY bool is_other(file_status __s) noexcept { + return exists(__s) && !is_regular_file(__s) && !is_directory(__s) && + !is_symlink(__s); +} + +inline _LIBCPP_INLINE_VISIBILITY bool is_other(const path& __p) { + return is_other(__status(__p)); +} + +inline _LIBCPP_INLINE_VISIBILITY bool is_other(const path& __p, + error_code& __ec) noexcept { + return is_other(__status(__p, &__ec)); +} + +inline _LIBCPP_INLINE_VISIBILITY file_time_type +last_write_time(const path& __p) { + return __last_write_time(__p); +} + +inline _LIBCPP_INLINE_VISIBILITY file_time_type +last_write_time(const path& __p, error_code& __ec) noexcept { + return __last_write_time(__p, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY void last_write_time(const path& __p, + file_time_type __t) { + __last_write_time(__p, __t); +} + +inline _LIBCPP_INLINE_VISIBILITY void +last_write_time(const path& __p, file_time_type __t, + error_code& __ec) noexcept { + __last_write_time(__p, __t, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY void +permissions(const path& __p, perms __prms, + perm_options __opts = perm_options::replace) { + __permissions(__p, __prms, __opts); +} + +inline _LIBCPP_INLINE_VISIBILITY void permissions(const path& __p, perms __prms, + error_code& __ec) noexcept { + __permissions(__p, __prms, perm_options::replace, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY void permissions(const path& __p, perms __prms, + perm_options __opts, + error_code& __ec) { + __permissions(__p, __prms, __opts, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY path proximate(const path& __p, + const path& __base, + error_code& __ec) { + path __tmp = __weakly_canonical(__p, &__ec); + if (__ec) + return {}; + path __tmp_base = __weakly_canonical(__base, &__ec); + if (__ec) + return {}; + return __tmp.lexically_proximate(__tmp_base); +} + +inline _LIBCPP_INLINE_VISIBILITY path proximate(const path& __p, + error_code& __ec) { + return proximate(__p, current_path(), __ec); +} + +inline _LIBCPP_INLINE_VISIBILITY path +proximate(const path& __p, const path& __base = current_path()) { + return __weakly_canonical(__p).lexically_proximate( + __weakly_canonical(__base)); +} + +inline _LIBCPP_INLINE_VISIBILITY path read_symlink(const path& __p) { + return __read_symlink(__p); +} + +inline _LIBCPP_INLINE_VISIBILITY path read_symlink(const path& __p, + error_code& __ec) { + return __read_symlink(__p, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY path relative(const path& __p, + const path& __base, + error_code& __ec) { + path __tmp = __weakly_canonical(__p, &__ec); + if (__ec) + return path(); + path __tmpbase = __weakly_canonical(__base, &__ec); + if (__ec) + return path(); + return __tmp.lexically_relative(__tmpbase); +} + +inline _LIBCPP_INLINE_VISIBILITY path relative(const path& __p, + error_code& __ec) { + return relative(__p, current_path(), __ec); +} + +inline _LIBCPP_INLINE_VISIBILITY path +relative(const path& __p, const path& __base = current_path()) { + return __weakly_canonical(__p).lexically_relative(__weakly_canonical(__base)); +} + +inline _LIBCPP_INLINE_VISIBILITY bool remove(const path& __p) { + return __remove(__p); +} + +inline _LIBCPP_INLINE_VISIBILITY bool remove(const path& __p, + error_code& __ec) noexcept { + return __remove(__p, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY uintmax_t remove_all(const path& __p) { + return __remove_all(__p); +} + +inline _LIBCPP_INLINE_VISIBILITY uintmax_t remove_all(const path& __p, + error_code& __ec) { + return __remove_all(__p, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY void rename(const path& __from, + const path& __to) { + return __rename(__from, __to); +} + +inline _LIBCPP_INLINE_VISIBILITY void +rename(const path& __from, const path& __to, error_code& __ec) noexcept { + return __rename(__from, __to, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY void resize_file(const path& __p, + uintmax_t __ns) { + return __resize_file(__p, __ns); +} + +inline _LIBCPP_INLINE_VISIBILITY void +resize_file(const path& __p, uintmax_t __ns, error_code& __ec) noexcept { + return __resize_file(__p, __ns, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY space_info space(const path& __p) { + return __space(__p); +} + +inline _LIBCPP_INLINE_VISIBILITY space_info space(const path& __p, + error_code& __ec) noexcept { + return __space(__p, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY file_status status(const path& __p) { + return __status(__p); +} + +inline _LIBCPP_INLINE_VISIBILITY file_status status(const path& __p, + error_code& __ec) noexcept { + return __status(__p, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY file_status symlink_status(const path& __p) { + return __symlink_status(__p); +} + +inline _LIBCPP_INLINE_VISIBILITY file_status +symlink_status(const path& __p, error_code& __ec) noexcept { + return __symlink_status(__p, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY path temp_directory_path() { + return __temp_directory_path(); +} + +inline _LIBCPP_INLINE_VISIBILITY path temp_directory_path(error_code& __ec) { + return __temp_directory_path(&__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY path weakly_canonical(path const& __p) { + return __weakly_canonical(__p); +} + +inline _LIBCPP_INLINE_VISIBILITY path weakly_canonical(path const& __p, + error_code& __ec) { + return __weakly_canonical(__p, &__ec); +} + +class directory_iterator; +class recursive_directory_iterator; +class _LIBCPP_HIDDEN __dir_stream; + +class directory_entry { + typedef _VSTD_FS::path _Path; + +public: + // constructors and destructors + directory_entry() noexcept = default; + directory_entry(directory_entry const&) = default; + directory_entry(directory_entry&&) noexcept = default; + + _LIBCPP_INLINE_VISIBILITY + explicit directory_entry(_Path const& __p) : __p_(__p) { + error_code __ec; + __refresh(&__ec); + } + + _LIBCPP_INLINE_VISIBILITY + directory_entry(_Path const& __p, error_code& __ec) : __p_(__p) { + __refresh(&__ec); + } + + ~directory_entry() {} + + directory_entry& operator=(directory_entry const&) = default; + directory_entry& operator=(directory_entry&&) noexcept = default; + + _LIBCPP_INLINE_VISIBILITY + void assign(_Path const& __p) { + __p_ = __p; + error_code __ec; + __refresh(&__ec); + } + + _LIBCPP_INLINE_VISIBILITY + void assign(_Path const& __p, error_code& __ec) { + __p_ = __p; + __refresh(&__ec); + } + + _LIBCPP_INLINE_VISIBILITY + void replace_filename(_Path const& __p) { + __p_.replace_filename(__p); + error_code __ec; + __refresh(&__ec); + } + + _LIBCPP_INLINE_VISIBILITY + void replace_filename(_Path const& __p, error_code& __ec) { + __p_ = __p_.parent_path() / __p; + __refresh(&__ec); + } + + _LIBCPP_INLINE_VISIBILITY + void refresh() { __refresh(); } + + _LIBCPP_INLINE_VISIBILITY + void refresh(error_code& __ec) noexcept { __refresh(&__ec); } + + _LIBCPP_INLINE_VISIBILITY + _Path const& path() const noexcept { return __p_; } + + _LIBCPP_INLINE_VISIBILITY + operator const _Path&() const noexcept { return __p_; } + + _LIBCPP_INLINE_VISIBILITY + bool exists() const { return _VSTD_FS::exists(file_status{__get_ft()}); } + + _LIBCPP_INLINE_VISIBILITY + bool exists(error_code& __ec) const noexcept { + return _VSTD_FS::exists(file_status{__get_ft(&__ec)}); + } + + _LIBCPP_INLINE_VISIBILITY + bool is_block_file() const { return __get_ft() == file_type::block; } + + _LIBCPP_INLINE_VISIBILITY + bool is_block_file(error_code& __ec) const noexcept { + return __get_ft(&__ec) == file_type::block; + } + + _LIBCPP_INLINE_VISIBILITY + bool is_character_file() const { return __get_ft() == file_type::character; } + + _LIBCPP_INLINE_VISIBILITY + bool is_character_file(error_code& __ec) const noexcept { + return __get_ft(&__ec) == file_type::character; + } + + _LIBCPP_INLINE_VISIBILITY + bool is_directory() const { return __get_ft() == file_type::directory; } + + _LIBCPP_INLINE_VISIBILITY + bool is_directory(error_code& __ec) const noexcept { + return __get_ft(&__ec) == file_type::directory; + } + + _LIBCPP_INLINE_VISIBILITY + bool is_fifo() const { return __get_ft() == file_type::fifo; } + + _LIBCPP_INLINE_VISIBILITY + bool is_fifo(error_code& __ec) const noexcept { + return __get_ft(&__ec) == file_type::fifo; + } + + _LIBCPP_INLINE_VISIBILITY + bool is_other() const { return _VSTD_FS::is_other(file_status{__get_ft()}); } + + _LIBCPP_INLINE_VISIBILITY + bool is_other(error_code& __ec) const noexcept { + return _VSTD_FS::is_other(file_status{__get_ft(&__ec)}); + } + + _LIBCPP_INLINE_VISIBILITY + bool is_regular_file() const { return __get_ft() == file_type::regular; } + + _LIBCPP_INLINE_VISIBILITY + bool is_regular_file(error_code& __ec) const noexcept { + return __get_ft(&__ec) == file_type::regular; + } + + _LIBCPP_INLINE_VISIBILITY + bool is_socket() const { return __get_ft() == file_type::socket; } + + _LIBCPP_INLINE_VISIBILITY + bool is_socket(error_code& __ec) const noexcept { + return __get_ft(&__ec) == file_type::socket; + } + + _LIBCPP_INLINE_VISIBILITY + bool is_symlink() const { return __get_sym_ft() == file_type::symlink; } + + _LIBCPP_INLINE_VISIBILITY + bool is_symlink(error_code& __ec) const noexcept { + return __get_sym_ft(&__ec) == file_type::symlink; + } + _LIBCPP_INLINE_VISIBILITY + uintmax_t file_size() const { return __get_size(); } + + _LIBCPP_INLINE_VISIBILITY + uintmax_t file_size(error_code& __ec) const noexcept { + return __get_size(&__ec); + } + + _LIBCPP_INLINE_VISIBILITY + uintmax_t hard_link_count() const { return __get_nlink(); } + + _LIBCPP_INLINE_VISIBILITY + uintmax_t hard_link_count(error_code& __ec) const noexcept { + return __get_nlink(&__ec); + } + + _LIBCPP_INLINE_VISIBILITY + file_time_type last_write_time() const { return __get_write_time(); } + + _LIBCPP_INLINE_VISIBILITY + file_time_type last_write_time(error_code& __ec) const noexcept { + return __get_write_time(&__ec); + } + + _LIBCPP_INLINE_VISIBILITY + file_status status() const { return __get_status(); } + + _LIBCPP_INLINE_VISIBILITY + file_status status(error_code& __ec) const noexcept { + return __get_status(&__ec); + } + + _LIBCPP_INLINE_VISIBILITY + file_status symlink_status() const { return __get_symlink_status(); } + + _LIBCPP_INLINE_VISIBILITY + file_status symlink_status(error_code& __ec) const noexcept { + return __get_symlink_status(&__ec); + } + + _LIBCPP_INLINE_VISIBILITY + bool operator<(directory_entry const& __rhs) const noexcept { + return __p_ < __rhs.__p_; + } + + _LIBCPP_INLINE_VISIBILITY + bool operator==(directory_entry const& __rhs) const noexcept { + return __p_ == __rhs.__p_; + } + + _LIBCPP_INLINE_VISIBILITY + bool operator!=(directory_entry const& __rhs) const noexcept { + return __p_ != __rhs.__p_; + } + + _LIBCPP_INLINE_VISIBILITY + bool operator<=(directory_entry const& __rhs) const noexcept { + return __p_ <= __rhs.__p_; + } + + _LIBCPP_INLINE_VISIBILITY + bool operator>(directory_entry const& __rhs) const noexcept { + return __p_ > __rhs.__p_; + } + + _LIBCPP_INLINE_VISIBILITY + bool operator>=(directory_entry const& __rhs) const noexcept { + return __p_ >= __rhs.__p_; + } + +private: + friend class directory_iterator; + friend class recursive_directory_iterator; + friend class __dir_stream; + + enum _CacheType : unsigned char { + _Empty, + _IterSymlink, + _IterNonSymlink, + _RefreshSymlink, + _RefreshSymlinkUnresolved, + _RefreshNonSymlink + }; + + struct __cached_data { + uintmax_t __size_; + uintmax_t __nlink_; + file_time_type __write_time_; + perms __sym_perms_; + perms __non_sym_perms_; + file_type __type_; + _CacheType __cache_type_; + + _LIBCPP_INLINE_VISIBILITY + __cached_data() noexcept { __reset(); } + + _LIBCPP_INLINE_VISIBILITY + void __reset() { + __cache_type_ = _Empty; + __type_ = file_type::none; + __sym_perms_ = __non_sym_perms_ = perms::unknown; + __size_ = __nlink_ = uintmax_t(-1); + __write_time_ = file_time_type::min(); + } + }; + + _LIBCPP_INLINE_VISIBILITY + static __cached_data __create_iter_result(file_type __ft) { + __cached_data __data; + __data.__type_ = __ft; + __data.__cache_type_ = [&]() { + switch (__ft) { + case file_type::none: + return _Empty; + case file_type::symlink: + return _IterSymlink; + default: + return _IterNonSymlink; + } + }(); + return __data; + } + + _LIBCPP_INLINE_VISIBILITY + void __assign_iter_entry(_Path&& __p, __cached_data __dt) { + __p_ = std::move(__p); + __data_ = __dt; + } + + _LIBCPP_FUNC_VIS + error_code __do_refresh() noexcept; + + _LIBCPP_INLINE_VISIBILITY + static bool __is_dne_error(error_code const& __ec) { + if (!__ec) + return true; + switch (static_cast(__ec.value())) { + case errc::no_such_file_or_directory: + case errc::not_a_directory: + return true; + default: + return false; + } + } + + _LIBCPP_INLINE_VISIBILITY + void __handle_error(const char* __msg, error_code* __dest_ec, + error_code const& __ec, bool __allow_dne = false) const { + if (__dest_ec) { + *__dest_ec = __ec; + return; + } + if (__ec && (!__allow_dne || !__is_dne_error(__ec))) + __throw_filesystem_error(__msg, __p_, __ec); + } + + _LIBCPP_INLINE_VISIBILITY + void __refresh(error_code* __ec = nullptr) { + __handle_error("in directory_entry::refresh", __ec, __do_refresh(), + /*allow_dne*/ true); + } + + _LIBCPP_INLINE_VISIBILITY + file_type __get_sym_ft(error_code* __ec = nullptr) const { + switch (__data_.__cache_type_) { + case _Empty: + return __symlink_status(__p_, __ec).type(); + case _IterSymlink: + case _RefreshSymlink: + case _RefreshSymlinkUnresolved: + if (__ec) + __ec->clear(); + return file_type::symlink; + case _IterNonSymlink: + case _RefreshNonSymlink: + file_status __st(__data_.__type_); + if (__ec && !_VSTD_FS::exists(__st)) + *__ec = make_error_code(errc::no_such_file_or_directory); + else if (__ec) + __ec->clear(); + return __data_.__type_; + } + _LIBCPP_UNREACHABLE(); + } + + _LIBCPP_INLINE_VISIBILITY + file_type __get_ft(error_code* __ec = nullptr) const { + switch (__data_.__cache_type_) { + case _Empty: + case _IterSymlink: + case _RefreshSymlinkUnresolved: + return __status(__p_, __ec).type(); + case _IterNonSymlink: + case _RefreshNonSymlink: + case _RefreshSymlink: { + file_status __st(__data_.__type_); + if (__ec && !_VSTD_FS::exists(__st)) + *__ec = make_error_code(errc::no_such_file_or_directory); + else if (__ec) + __ec->clear(); + return __data_.__type_; + } + } + _LIBCPP_UNREACHABLE(); + } + + _LIBCPP_INLINE_VISIBILITY + file_status __get_status(error_code* __ec = nullptr) const { + switch (__data_.__cache_type_) { + case _Empty: + case _IterNonSymlink: + case _IterSymlink: + case _RefreshSymlinkUnresolved: + return __status(__p_, __ec); + case _RefreshNonSymlink: + case _RefreshSymlink: + return file_status(__get_ft(__ec), __data_.__non_sym_perms_); + } + _LIBCPP_UNREACHABLE(); + } + + _LIBCPP_INLINE_VISIBILITY + file_status __get_symlink_status(error_code* __ec = nullptr) const { + switch (__data_.__cache_type_) { + case _Empty: + case _IterNonSymlink: + case _IterSymlink: + return __symlink_status(__p_, __ec); + case _RefreshNonSymlink: + return file_status(__get_sym_ft(__ec), __data_.__non_sym_perms_); + case _RefreshSymlink: + case _RefreshSymlinkUnresolved: + return file_status(__get_sym_ft(__ec), __data_.__sym_perms_); + } + _LIBCPP_UNREACHABLE(); + } + + _LIBCPP_INLINE_VISIBILITY + uintmax_t __get_size(error_code* __ec = nullptr) const { + switch (__data_.__cache_type_) { + case _Empty: + case _IterNonSymlink: + case _IterSymlink: + case _RefreshSymlinkUnresolved: + return _VSTD_FS::__file_size(__p_, __ec); + case _RefreshSymlink: + case _RefreshNonSymlink: { + error_code __m_ec; + file_status __st(__get_ft(&__m_ec)); + __handle_error("in directory_entry::file_size", __ec, __m_ec); + if (_VSTD_FS::exists(__st) && !_VSTD_FS::is_regular_file(__st)) { + errc __err_kind = _VSTD_FS::is_directory(__st) ? errc::is_a_directory + : errc::not_supported; + __handle_error("in directory_entry::file_size", __ec, + make_error_code(__err_kind)); + } + return __data_.__size_; + } + } + _LIBCPP_UNREACHABLE(); + } + + _LIBCPP_INLINE_VISIBILITY + uintmax_t __get_nlink(error_code* __ec = nullptr) const { + switch (__data_.__cache_type_) { + case _Empty: + case _IterNonSymlink: + case _IterSymlink: + case _RefreshSymlinkUnresolved: + return _VSTD_FS::__hard_link_count(__p_, __ec); + case _RefreshSymlink: + case _RefreshNonSymlink: { + error_code __m_ec; + (void)__get_ft(&__m_ec); + __handle_error("in directory_entry::hard_link_count", __ec, __m_ec); + return __data_.__nlink_; + } + } + _LIBCPP_UNREACHABLE(); + } + + _LIBCPP_INLINE_VISIBILITY + file_time_type __get_write_time(error_code* __ec = nullptr) const { + switch (__data_.__cache_type_) { + case _Empty: + case _IterNonSymlink: + case _IterSymlink: + case _RefreshSymlinkUnresolved: + return _VSTD_FS::__last_write_time(__p_, __ec); + case _RefreshSymlink: + case _RefreshNonSymlink: { + error_code __m_ec; + file_status __st(__get_ft(&__m_ec)); + __handle_error("in directory_entry::last_write_time", __ec, __m_ec); + if (_VSTD_FS::exists(__st) && + __data_.__write_time_ == file_time_type::min()) + __handle_error("in directory_entry::last_write_time", __ec, + make_error_code(errc::value_too_large)); + return __data_.__write_time_; + } + } + _LIBCPP_UNREACHABLE(); + } + +private: + _Path __p_; + __cached_data __data_; +}; + +class __dir_element_proxy { +public: + inline _LIBCPP_INLINE_VISIBILITY directory_entry operator*() { + return _VSTD::move(__elem_); + } + +private: + friend class directory_iterator; + friend class recursive_directory_iterator; + explicit __dir_element_proxy(directory_entry const& __e) : __elem_(__e) {} + __dir_element_proxy(__dir_element_proxy&& __o) + : __elem_(_VSTD::move(__o.__elem_)) {} + directory_entry __elem_; +}; + +class directory_iterator { +public: + typedef directory_entry value_type; + typedef ptrdiff_t difference_type; + typedef value_type const* pointer; + typedef value_type const& reference; + typedef input_iterator_tag iterator_category; + +public: + //ctor & dtor + directory_iterator() noexcept {} + + explicit directory_iterator(const path& __p) + : directory_iterator(__p, nullptr) {} + + directory_iterator(const path& __p, directory_options __opts) + : directory_iterator(__p, nullptr, __opts) {} + + directory_iterator(const path& __p, error_code& __ec) + : directory_iterator(__p, &__ec) {} + + directory_iterator(const path& __p, directory_options __opts, + error_code& __ec) + : directory_iterator(__p, &__ec, __opts) {} + + directory_iterator(const directory_iterator&) = default; + directory_iterator(directory_iterator&&) = default; + directory_iterator& operator=(const directory_iterator&) = default; + + directory_iterator& operator=(directory_iterator&& __o) noexcept { + // non-default implementation provided to support self-move assign. + if (this != &__o) { + __imp_ = _VSTD::move(__o.__imp_); + } + return *this; + } + + ~directory_iterator() = default; + + const directory_entry& operator*() const { + _LIBCPP_ASSERT(__imp_, "The end iterator cannot be dereferenced"); + return __dereference(); + } + + const directory_entry* operator->() const { return &**this; } + + directory_iterator& operator++() { return __increment(); } + + __dir_element_proxy operator++(int) { + __dir_element_proxy __p(**this); + __increment(); + return __p; + } + + directory_iterator& increment(error_code& __ec) { return __increment(&__ec); } + +private: + inline _LIBCPP_INLINE_VISIBILITY friend bool + operator==(const directory_iterator& __lhs, + const directory_iterator& __rhs) noexcept; + + // construct the dir_stream + _LIBCPP_FUNC_VIS + directory_iterator(const path&, error_code*, + directory_options = directory_options::none); + + _LIBCPP_FUNC_VIS + directory_iterator& __increment(error_code* __ec = nullptr); + + _LIBCPP_FUNC_VIS + const directory_entry& __dereference() const; + +private: + shared_ptr<__dir_stream> __imp_; +}; + +inline _LIBCPP_INLINE_VISIBILITY bool +operator==(const directory_iterator& __lhs, + const directory_iterator& __rhs) noexcept { + return __lhs.__imp_ == __rhs.__imp_; +} + +inline _LIBCPP_INLINE_VISIBILITY bool +operator!=(const directory_iterator& __lhs, + const directory_iterator& __rhs) noexcept { + return !(__lhs == __rhs); +} + +// enable directory_iterator range-based for statements +inline _LIBCPP_INLINE_VISIBILITY directory_iterator +begin(directory_iterator __iter) noexcept { + return __iter; +} + +inline _LIBCPP_INLINE_VISIBILITY directory_iterator +end(const directory_iterator&) noexcept { + return directory_iterator(); +} + +class recursive_directory_iterator { +public: + using value_type = directory_entry; + using difference_type = std::ptrdiff_t; + using pointer = directory_entry const*; + using reference = directory_entry const&; + using iterator_category = std::input_iterator_tag; + +public: + // constructors and destructor + _LIBCPP_INLINE_VISIBILITY + recursive_directory_iterator() noexcept : __rec_(false) {} + + _LIBCPP_INLINE_VISIBILITY + explicit recursive_directory_iterator( + const path& __p, directory_options __xoptions = directory_options::none) + : recursive_directory_iterator(__p, __xoptions, nullptr) {} + + _LIBCPP_INLINE_VISIBILITY + recursive_directory_iterator(const path& __p, directory_options __xoptions, + error_code& __ec) + : recursive_directory_iterator(__p, __xoptions, &__ec) {} + + _LIBCPP_INLINE_VISIBILITY + recursive_directory_iterator(const path& __p, error_code& __ec) + : recursive_directory_iterator(__p, directory_options::none, &__ec) {} + + recursive_directory_iterator(const recursive_directory_iterator&) = default; + recursive_directory_iterator(recursive_directory_iterator&&) = default; + + recursive_directory_iterator& + operator=(const recursive_directory_iterator&) = default; + + _LIBCPP_INLINE_VISIBILITY + recursive_directory_iterator& + operator=(recursive_directory_iterator&& __o) noexcept { + // non-default implementation provided to support self-move assign. + if (this != &__o) { + __imp_ = _VSTD::move(__o.__imp_); + __rec_ = __o.__rec_; + } + return *this; + } + + ~recursive_directory_iterator() = default; + + _LIBCPP_INLINE_VISIBILITY + const directory_entry& operator*() const { return __dereference(); } + + _LIBCPP_INLINE_VISIBILITY + const directory_entry* operator->() const { return &__dereference(); } + + recursive_directory_iterator& operator++() { return __increment(); } + + _LIBCPP_INLINE_VISIBILITY + __dir_element_proxy operator++(int) { + __dir_element_proxy __p(**this); + __increment(); + return __p; + } + + _LIBCPP_INLINE_VISIBILITY + recursive_directory_iterator& increment(error_code& __ec) { + return __increment(&__ec); + } + + _LIBCPP_FUNC_VIS directory_options options() const; + _LIBCPP_FUNC_VIS int depth() const; + + _LIBCPP_INLINE_VISIBILITY + void pop() { __pop(); } + + _LIBCPP_INLINE_VISIBILITY + void pop(error_code& __ec) { __pop(&__ec); } + + _LIBCPP_INLINE_VISIBILITY + bool recursion_pending() const { return __rec_; } + + _LIBCPP_INLINE_VISIBILITY + void disable_recursion_pending() { __rec_ = false; } + +private: + _LIBCPP_FUNC_VIS + recursive_directory_iterator(const path& __p, directory_options __opt, + error_code* __ec); + + _LIBCPP_FUNC_VIS + const directory_entry& __dereference() const; + + _LIBCPP_FUNC_VIS + bool __try_recursion(error_code* __ec); + + _LIBCPP_FUNC_VIS + void __advance(error_code* __ec = nullptr); + + _LIBCPP_FUNC_VIS + recursive_directory_iterator& __increment(error_code* __ec = nullptr); + + _LIBCPP_FUNC_VIS + void __pop(error_code* __ec = nullptr); + + inline _LIBCPP_INLINE_VISIBILITY friend bool + operator==(const recursive_directory_iterator&, + const recursive_directory_iterator&) noexcept; + + struct _LIBCPP_HIDDEN __shared_imp; + shared_ptr<__shared_imp> __imp_; + bool __rec_; +}; // class recursive_directory_iterator + +inline _LIBCPP_INLINE_VISIBILITY bool +operator==(const recursive_directory_iterator& __lhs, + const recursive_directory_iterator& __rhs) noexcept { + return __lhs.__imp_ == __rhs.__imp_; +} + +_LIBCPP_INLINE_VISIBILITY +inline bool operator!=(const recursive_directory_iterator& __lhs, + const recursive_directory_iterator& __rhs) noexcept { + return !(__lhs == __rhs); +} +// enable recursive_directory_iterator range-based for statements +inline _LIBCPP_INLINE_VISIBILITY recursive_directory_iterator +begin(recursive_directory_iterator __iter) noexcept { + return __iter; +} + +inline _LIBCPP_INLINE_VISIBILITY recursive_directory_iterator +end(const recursive_directory_iterator&) noexcept { + return recursive_directory_iterator(); +} + +_LIBCPP_AVAILABILITY_FILESYSTEM_POP + +_LIBCPP_END_NAMESPACE_FILESYSTEM + +#endif // !_LIBCPP_CXX03_LANG + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP_FILESYSTEM diff --git a/third_party/libcxx/forward_list b/third_party/libcxx/forward_list new file mode 100644 index 000000000..6c779a396 --- /dev/null +++ b/third_party/libcxx/forward_list @@ -0,0 +1,1782 @@ +// -*- C++ -*- +// clang-format off +//===----------------------- forward_list ---------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_FORWARD_LIST +#define _LIBCPP_FORWARD_LIST + +/* + forward_list synopsis + +namespace std +{ + +template > +class forward_list +{ +public: + typedef T value_type; + typedef Allocator allocator_type; + + typedef value_type& reference; + typedef const value_type& const_reference; + typedef typename allocator_traits::pointer pointer; + typedef typename allocator_traits::const_pointer const_pointer; + typedef typename allocator_traits::size_type size_type; + typedef typename allocator_traits::difference_type difference_type; + + typedef
iterator; + typedef
const_iterator; + + forward_list() + noexcept(is_nothrow_default_constructible::value); + explicit forward_list(const allocator_type& a); + explicit forward_list(size_type n); + explicit forward_list(size_type n, const allocator_type& a); // C++14 + forward_list(size_type n, const value_type& v); + forward_list(size_type n, const value_type& v, const allocator_type& a); + template + forward_list(InputIterator first, InputIterator last); + template + forward_list(InputIterator first, InputIterator last, const allocator_type& a); + forward_list(const forward_list& x); + forward_list(const forward_list& x, const allocator_type& a); + forward_list(forward_list&& x) + noexcept(is_nothrow_move_constructible::value); + forward_list(forward_list&& x, const allocator_type& a); + forward_list(initializer_list il); + forward_list(initializer_list il, const allocator_type& a); + + ~forward_list(); + + forward_list& operator=(const forward_list& x); + forward_list& operator=(forward_list&& x) + noexcept( + allocator_type::propagate_on_container_move_assignment::value && + is_nothrow_move_assignable::value); + forward_list& operator=(initializer_list il); + + template + void assign(InputIterator first, InputIterator last); + void assign(size_type n, const value_type& v); + void assign(initializer_list il); + + allocator_type get_allocator() const noexcept; + + iterator begin() noexcept; + const_iterator begin() const noexcept; + iterator end() noexcept; + const_iterator end() const noexcept; + + const_iterator cbegin() const noexcept; + const_iterator cend() const noexcept; + + iterator before_begin() noexcept; + const_iterator before_begin() const noexcept; + const_iterator cbefore_begin() const noexcept; + + bool empty() const noexcept; + size_type max_size() const noexcept; + + reference front(); + const_reference front() const; + + template reference emplace_front(Args&&... args); // reference in C++17 + void push_front(const value_type& v); + void push_front(value_type&& v); + + void pop_front(); + + template + iterator emplace_after(const_iterator p, Args&&... args); + iterator insert_after(const_iterator p, const value_type& v); + iterator insert_after(const_iterator p, value_type&& v); + iterator insert_after(const_iterator p, size_type n, const value_type& v); + template + iterator insert_after(const_iterator p, + InputIterator first, InputIterator last); + iterator insert_after(const_iterator p, initializer_list il); + + iterator erase_after(const_iterator p); + iterator erase_after(const_iterator first, const_iterator last); + + void swap(forward_list& x) + noexcept(allocator_traits::is_always_equal::value); // C++17 + + void resize(size_type n); + void resize(size_type n, const value_type& v); + void clear() noexcept; + + void splice_after(const_iterator p, forward_list& x); + void splice_after(const_iterator p, forward_list&& x); + void splice_after(const_iterator p, forward_list& x, const_iterator i); + void splice_after(const_iterator p, forward_list&& x, const_iterator i); + void splice_after(const_iterator p, forward_list& x, + const_iterator first, const_iterator last); + void splice_after(const_iterator p, forward_list&& x, + const_iterator first, const_iterator last); + size_type remove(const value_type& v); // void before C++20 + template + size_type remove_if(Predicate pred); // void before C++20 + size_type unique(); // void before C++20 + template + size_type unique(BinaryPredicate binary_pred); // void before C++20 + void merge(forward_list& x); + void merge(forward_list&& x); + template void merge(forward_list& x, Compare comp); + template void merge(forward_list&& x, Compare comp); + void sort(); + template void sort(Compare comp); + void reverse() noexcept; +}; + + +template ::value_type>> + forward_list(InputIterator, InputIterator, Allocator = Allocator()) + -> forward_list::value_type, Allocator>; // C++17 + +template + bool operator==(const forward_list& x, + const forward_list& y); + +template + bool operator< (const forward_list& x, + const forward_list& y); + +template + bool operator!=(const forward_list& x, + const forward_list& y); + +template + bool operator> (const forward_list& x, + const forward_list& y); + +template + bool operator>=(const forward_list& x, + const forward_list& y); + +template + bool operator<=(const forward_list& x, + const forward_list& y); + +template + void swap(forward_list& x, forward_list& y) + noexcept(noexcept(x.swap(y))); + +template + void erase(forward_list& c, const U& value); // C++20 +template + void erase_if(forward_list& c, Predicate pred); // C++20 + +} // std + +*/ + +#include "third_party/libcxx/__config" +#include "third_party/libcxx/initializer_list" +#include "third_party/libcxx/memory" +#include "third_party/libcxx/limits" +#include "third_party/libcxx/iterator" +#include "third_party/libcxx/algorithm" +#include "third_party/libcxx/version" + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include "third_party/libcxx/__undef_macros" + + +_LIBCPP_BEGIN_NAMESPACE_STD + +template struct __forward_list_node; +template struct __forward_begin_node; + + +template +struct __forward_list_node_value_type; + +template +struct __forward_list_node_value_type<__forward_list_node<_Tp, _VoidPtr> > { + typedef _Tp type; +}; + +template +struct __forward_node_traits { + + typedef typename remove_cv< + typename pointer_traits<_NodePtr>::element_type>::type __node; + typedef typename __forward_list_node_value_type<__node>::type __node_value_type; + typedef _NodePtr __node_pointer; + typedef __forward_begin_node<_NodePtr> __begin_node; + typedef typename __rebind_pointer<_NodePtr, __begin_node>::type + __begin_node_pointer; + typedef typename __rebind_pointer<_NodePtr, void>::type __void_pointer; + +#if defined(_LIBCPP_ABI_FORWARD_LIST_REMOVE_NODE_POINTER_UB) + typedef __begin_node_pointer __iter_node_pointer; +#else + typedef typename conditional< + is_pointer<__void_pointer>::value, + __begin_node_pointer, + __node_pointer + >::type __iter_node_pointer; +#endif + + typedef typename conditional< + is_same<__iter_node_pointer, __node_pointer>::value, + __begin_node_pointer, + __node_pointer + >::type __non_iter_node_pointer; + + _LIBCPP_INLINE_VISIBILITY + static __iter_node_pointer __as_iter_node(__iter_node_pointer __p) { + return __p; + } + _LIBCPP_INLINE_VISIBILITY + static __iter_node_pointer __as_iter_node(__non_iter_node_pointer __p) { + return static_cast<__iter_node_pointer>(static_cast<__void_pointer>(__p)); + } +}; + +template +struct __forward_begin_node +{ + typedef _NodePtr pointer; + typedef typename __rebind_pointer<_NodePtr, __forward_begin_node>::type __begin_node_pointer; + + pointer __next_; + + _LIBCPP_INLINE_VISIBILITY __forward_begin_node() : __next_(nullptr) {} + + _LIBCPP_INLINE_VISIBILITY + __begin_node_pointer __next_as_begin() const { + return static_cast<__begin_node_pointer>(__next_); + } +}; + +template +struct _LIBCPP_HIDDEN __begin_node_of +{ + typedef __forward_begin_node< + typename __rebind_pointer<_VoidPtr, __forward_list_node<_Tp, _VoidPtr> >::type + > type; +}; + +template +struct __forward_list_node + : public __begin_node_of<_Tp, _VoidPtr>::type +{ + typedef _Tp value_type; + + value_type __value_; +}; + + +template > class _LIBCPP_TEMPLATE_VIS forward_list; +template class _LIBCPP_TEMPLATE_VIS __forward_list_const_iterator; + +template +class _LIBCPP_TEMPLATE_VIS __forward_list_iterator +{ + typedef __forward_node_traits<_NodePtr> __traits; + typedef typename __traits::__node_pointer __node_pointer; + typedef typename __traits::__begin_node_pointer __begin_node_pointer; + typedef typename __traits::__iter_node_pointer __iter_node_pointer; + typedef typename __traits::__void_pointer __void_pointer; + + __iter_node_pointer __ptr_; + + _LIBCPP_INLINE_VISIBILITY + __begin_node_pointer __get_begin() const { + return static_cast<__begin_node_pointer>( + static_cast<__void_pointer>(__ptr_)); + } + _LIBCPP_INLINE_VISIBILITY + __node_pointer __get_unsafe_node_pointer() const { + return static_cast<__node_pointer>( + static_cast<__void_pointer>(__ptr_)); + } + + _LIBCPP_INLINE_VISIBILITY + explicit __forward_list_iterator(nullptr_t) _NOEXCEPT : __ptr_(nullptr) {} + + _LIBCPP_INLINE_VISIBILITY + explicit __forward_list_iterator(__begin_node_pointer __p) _NOEXCEPT + : __ptr_(__traits::__as_iter_node(__p)) {} + + _LIBCPP_INLINE_VISIBILITY + explicit __forward_list_iterator(__node_pointer __p) _NOEXCEPT + : __ptr_(__traits::__as_iter_node(__p)) {} + + template friend class _LIBCPP_TEMPLATE_VIS forward_list; + template friend class _LIBCPP_TEMPLATE_VIS __forward_list_const_iterator; + +public: + typedef forward_iterator_tag iterator_category; + typedef typename __traits::__node_value_type value_type; + typedef value_type& reference; + typedef typename pointer_traits<__node_pointer>::difference_type + difference_type; + typedef typename __rebind_pointer<__node_pointer, value_type>::type pointer; + + _LIBCPP_INLINE_VISIBILITY + __forward_list_iterator() _NOEXCEPT : __ptr_(nullptr) {} + + _LIBCPP_INLINE_VISIBILITY + reference operator*() const {return __get_unsafe_node_pointer()->__value_;} + _LIBCPP_INLINE_VISIBILITY + pointer operator->() const { + return pointer_traits::pointer_to(__get_unsafe_node_pointer()->__value_); + } + + _LIBCPP_INLINE_VISIBILITY + __forward_list_iterator& operator++() + { + __ptr_ = __traits::__as_iter_node(__ptr_->__next_); + return *this; + } + _LIBCPP_INLINE_VISIBILITY + __forward_list_iterator operator++(int) + { + __forward_list_iterator __t(*this); + ++(*this); + return __t; + } + + friend _LIBCPP_INLINE_VISIBILITY + bool operator==(const __forward_list_iterator& __x, + const __forward_list_iterator& __y) + {return __x.__ptr_ == __y.__ptr_;} + friend _LIBCPP_INLINE_VISIBILITY + bool operator!=(const __forward_list_iterator& __x, + const __forward_list_iterator& __y) + {return !(__x == __y);} +}; + +template +class _LIBCPP_TEMPLATE_VIS __forward_list_const_iterator +{ + static_assert((!is_const::element_type>::value), ""); + typedef _NodeConstPtr _NodePtr; + + typedef __forward_node_traits<_NodePtr> __traits; + typedef typename __traits::__node __node; + typedef typename __traits::__node_pointer __node_pointer; + typedef typename __traits::__begin_node_pointer __begin_node_pointer; + typedef typename __traits::__iter_node_pointer __iter_node_pointer; + typedef typename __traits::__void_pointer __void_pointer; + + __iter_node_pointer __ptr_; + + __begin_node_pointer __get_begin() const { + return static_cast<__begin_node_pointer>( + static_cast<__void_pointer>(__ptr_)); + } + __node_pointer __get_unsafe_node_pointer() const { + return static_cast<__node_pointer>( + static_cast<__void_pointer>(__ptr_)); + } + + _LIBCPP_INLINE_VISIBILITY + explicit __forward_list_const_iterator(nullptr_t) _NOEXCEPT + : __ptr_(nullptr) {} + + _LIBCPP_INLINE_VISIBILITY + explicit __forward_list_const_iterator(__begin_node_pointer __p) _NOEXCEPT + : __ptr_(__traits::__as_iter_node(__p)) {} + + _LIBCPP_INLINE_VISIBILITY + explicit __forward_list_const_iterator(__node_pointer __p) _NOEXCEPT + : __ptr_(__traits::__as_iter_node(__p)) {} + + + template friend class forward_list; + +public: + typedef forward_iterator_tag iterator_category; + typedef typename __traits::__node_value_type value_type; + typedef const value_type& reference; + typedef typename pointer_traits<__node_pointer>::difference_type + difference_type; + typedef typename __rebind_pointer<__node_pointer, const value_type>::type + pointer; + + _LIBCPP_INLINE_VISIBILITY + __forward_list_const_iterator() _NOEXCEPT : __ptr_(nullptr) {} + _LIBCPP_INLINE_VISIBILITY + __forward_list_const_iterator(__forward_list_iterator<__node_pointer> __p) _NOEXCEPT + : __ptr_(__p.__ptr_) {} + + _LIBCPP_INLINE_VISIBILITY + reference operator*() const {return __get_unsafe_node_pointer()->__value_;} + _LIBCPP_INLINE_VISIBILITY + pointer operator->() const {return pointer_traits::pointer_to( + __get_unsafe_node_pointer()->__value_);} + + _LIBCPP_INLINE_VISIBILITY + __forward_list_const_iterator& operator++() + { + __ptr_ = __traits::__as_iter_node(__ptr_->__next_); + return *this; + } + _LIBCPP_INLINE_VISIBILITY + __forward_list_const_iterator operator++(int) + { + __forward_list_const_iterator __t(*this); + ++(*this); + return __t; + } + + friend _LIBCPP_INLINE_VISIBILITY + bool operator==(const __forward_list_const_iterator& __x, + const __forward_list_const_iterator& __y) + {return __x.__ptr_ == __y.__ptr_;} + friend _LIBCPP_INLINE_VISIBILITY + bool operator!=(const __forward_list_const_iterator& __x, + const __forward_list_const_iterator& __y) + {return !(__x == __y);} +}; + +template +class __forward_list_base +{ +protected: + typedef _Tp value_type; + typedef _Alloc allocator_type; + + typedef typename allocator_traits::void_pointer void_pointer; + typedef __forward_list_node __node; + typedef typename __begin_node_of::type __begin_node; + typedef typename __rebind_alloc_helper, __node>::type __node_allocator; + typedef allocator_traits<__node_allocator> __node_traits; + typedef typename __node_traits::pointer __node_pointer; + + typedef typename __rebind_alloc_helper< + allocator_traits, __begin_node + >::type __begin_node_allocator; + typedef typename allocator_traits<__begin_node_allocator>::pointer + __begin_node_pointer; + + static_assert((!is_same::value), + "internal allocator type must differ from user-specified " + "type; otherwise overload resolution breaks"); + + __compressed_pair<__begin_node, __node_allocator> __before_begin_; + + _LIBCPP_INLINE_VISIBILITY + __begin_node_pointer __before_begin() _NOEXCEPT + {return pointer_traits<__begin_node_pointer>::pointer_to(__before_begin_.first());} + _LIBCPP_INLINE_VISIBILITY + __begin_node_pointer __before_begin() const _NOEXCEPT + {return pointer_traits<__begin_node_pointer>::pointer_to(const_cast<__begin_node&>(__before_begin_.first()));} + + _LIBCPP_INLINE_VISIBILITY + __node_allocator& __alloc() _NOEXCEPT + {return __before_begin_.second();} + _LIBCPP_INLINE_VISIBILITY + const __node_allocator& __alloc() const _NOEXCEPT + {return __before_begin_.second();} + + typedef __forward_list_iterator<__node_pointer> iterator; + typedef __forward_list_const_iterator<__node_pointer> const_iterator; + + _LIBCPP_INLINE_VISIBILITY + __forward_list_base() + _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value) + : __before_begin_(__begin_node()) {} + _LIBCPP_INLINE_VISIBILITY + explicit __forward_list_base(const allocator_type& __a) + : __before_begin_(__begin_node(), __node_allocator(__a)) {} + _LIBCPP_INLINE_VISIBILITY + explicit __forward_list_base(const __node_allocator& __a) + : __before_begin_(__begin_node(), __a) {} +#ifndef _LIBCPP_CXX03_LANG +public: + _LIBCPP_INLINE_VISIBILITY + __forward_list_base(__forward_list_base&& __x) + _NOEXCEPT_(is_nothrow_move_constructible<__node_allocator>::value); + _LIBCPP_INLINE_VISIBILITY + __forward_list_base(__forward_list_base&& __x, const allocator_type& __a); +#endif // _LIBCPP_CXX03_LANG + +private: + __forward_list_base(const __forward_list_base&); + __forward_list_base& operator=(const __forward_list_base&); + +public: + ~__forward_list_base(); + +protected: + _LIBCPP_INLINE_VISIBILITY + void __copy_assign_alloc(const __forward_list_base& __x) + {__copy_assign_alloc(__x, integral_constant());} + + _LIBCPP_INLINE_VISIBILITY + void __move_assign_alloc(__forward_list_base& __x) + _NOEXCEPT_(!__node_traits::propagate_on_container_move_assignment::value || + is_nothrow_move_assignable<__node_allocator>::value) + {__move_assign_alloc(__x, integral_constant());} + +public: + _LIBCPP_INLINE_VISIBILITY + void swap(__forward_list_base& __x) +#if _LIBCPP_STD_VER >= 14 + _NOEXCEPT; +#else + _NOEXCEPT_(!__node_traits::propagate_on_container_move_assignment::value || + __is_nothrow_swappable<__node_allocator>::value); +#endif +protected: + void clear() _NOEXCEPT; + +private: + _LIBCPP_INLINE_VISIBILITY + void __copy_assign_alloc(const __forward_list_base&, false_type) {} + _LIBCPP_INLINE_VISIBILITY + void __copy_assign_alloc(const __forward_list_base& __x, true_type) + { + if (__alloc() != __x.__alloc()) + clear(); + __alloc() = __x.__alloc(); + } + + _LIBCPP_INLINE_VISIBILITY + void __move_assign_alloc(__forward_list_base&, false_type) _NOEXCEPT + {} + _LIBCPP_INLINE_VISIBILITY + void __move_assign_alloc(__forward_list_base& __x, true_type) + _NOEXCEPT_(is_nothrow_move_assignable<__node_allocator>::value) + {__alloc() = _VSTD::move(__x.__alloc());} +}; + +#ifndef _LIBCPP_CXX03_LANG + +template +inline +__forward_list_base<_Tp, _Alloc>::__forward_list_base(__forward_list_base&& __x) + _NOEXCEPT_(is_nothrow_move_constructible<__node_allocator>::value) + : __before_begin_(_VSTD::move(__x.__before_begin_)) +{ + __x.__before_begin()->__next_ = nullptr; +} + +template +inline +__forward_list_base<_Tp, _Alloc>::__forward_list_base(__forward_list_base&& __x, + const allocator_type& __a) + : __before_begin_(__begin_node(), __node_allocator(__a)) +{ + if (__alloc() == __x.__alloc()) + { + __before_begin()->__next_ = __x.__before_begin()->__next_; + __x.__before_begin()->__next_ = nullptr; + } +} + +#endif // _LIBCPP_CXX03_LANG + +template +__forward_list_base<_Tp, _Alloc>::~__forward_list_base() +{ + clear(); +} + +template +inline +void +__forward_list_base<_Tp, _Alloc>::swap(__forward_list_base& __x) +#if _LIBCPP_STD_VER >= 14 + _NOEXCEPT +#else + _NOEXCEPT_(!__node_traits::propagate_on_container_move_assignment::value || + __is_nothrow_swappable<__node_allocator>::value) +#endif +{ + __swap_allocator(__alloc(), __x.__alloc(), + integral_constant()); + using _VSTD::swap; + swap(__before_begin()->__next_, __x.__before_begin()->__next_); +} + +template +void +__forward_list_base<_Tp, _Alloc>::clear() _NOEXCEPT +{ + __node_allocator& __a = __alloc(); + for (__node_pointer __p = __before_begin()->__next_; __p != nullptr;) + { + __node_pointer __next = __p->__next_; + __node_traits::destroy(__a, _VSTD::addressof(__p->__value_)); + __node_traits::deallocate(__a, __p, 1); + __p = __next; + } + __before_begin()->__next_ = nullptr; +} + +template */> +class _LIBCPP_TEMPLATE_VIS forward_list + : private __forward_list_base<_Tp, _Alloc> +{ + typedef __forward_list_base<_Tp, _Alloc> base; + typedef typename base::__node_allocator __node_allocator; + typedef typename base::__node __node; + typedef typename base::__node_traits __node_traits; + typedef typename base::__node_pointer __node_pointer; + typedef typename base::__begin_node_pointer __begin_node_pointer; + +public: + typedef _Tp value_type; + typedef _Alloc allocator_type; + + static_assert((is_same::value), + "Allocator::value_type must be same type as value_type"); + + typedef value_type& reference; + typedef const value_type& const_reference; + typedef typename allocator_traits::pointer pointer; + typedef typename allocator_traits::const_pointer const_pointer; + typedef typename allocator_traits::size_type size_type; + typedef typename allocator_traits::difference_type difference_type; + + typedef typename base::iterator iterator; + typedef typename base::const_iterator const_iterator; +#if _LIBCPP_STD_VER > 17 + typedef size_type __remove_return_type; +#else + typedef void __remove_return_type; +#endif + + _LIBCPP_INLINE_VISIBILITY + forward_list() + _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value) + {} // = default; + _LIBCPP_INLINE_VISIBILITY + explicit forward_list(const allocator_type& __a); + explicit forward_list(size_type __n); +#if _LIBCPP_STD_VER > 11 + explicit forward_list(size_type __n, const allocator_type& __a); +#endif + forward_list(size_type __n, const value_type& __v); + forward_list(size_type __n, const value_type& __v, const allocator_type& __a); + template + forward_list(_InputIterator __f, _InputIterator __l, + typename enable_if< + __is_input_iterator<_InputIterator>::value + >::type* = nullptr); + template + forward_list(_InputIterator __f, _InputIterator __l, + const allocator_type& __a, + typename enable_if< + __is_input_iterator<_InputIterator>::value + >::type* = nullptr); + forward_list(const forward_list& __x); + forward_list(const forward_list& __x, const allocator_type& __a); + + forward_list& operator=(const forward_list& __x); + +#ifndef _LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY + forward_list(forward_list&& __x) + _NOEXCEPT_(is_nothrow_move_constructible::value) + : base(_VSTD::move(__x)) {} + forward_list(forward_list&& __x, const allocator_type& __a); + + forward_list(initializer_list __il); + forward_list(initializer_list __il, const allocator_type& __a); + + _LIBCPP_INLINE_VISIBILITY + forward_list& operator=(forward_list&& __x) + _NOEXCEPT_( + __node_traits::propagate_on_container_move_assignment::value && + is_nothrow_move_assignable::value); + + _LIBCPP_INLINE_VISIBILITY + forward_list& operator=(initializer_list __il); + + _LIBCPP_INLINE_VISIBILITY + void assign(initializer_list __il); +#endif // _LIBCPP_CXX03_LANG + + // ~forward_list() = default; + + template + typename enable_if + < + __is_input_iterator<_InputIterator>::value, + void + >::type + assign(_InputIterator __f, _InputIterator __l); + void assign(size_type __n, const value_type& __v); + + _LIBCPP_INLINE_VISIBILITY + allocator_type get_allocator() const _NOEXCEPT + {return allocator_type(base::__alloc());} + + _LIBCPP_INLINE_VISIBILITY + iterator begin() _NOEXCEPT + {return iterator(base::__before_begin()->__next_);} + _LIBCPP_INLINE_VISIBILITY + const_iterator begin() const _NOEXCEPT + {return const_iterator(base::__before_begin()->__next_);} + _LIBCPP_INLINE_VISIBILITY + iterator end() _NOEXCEPT + {return iterator(nullptr);} + _LIBCPP_INLINE_VISIBILITY + const_iterator end() const _NOEXCEPT + {return const_iterator(nullptr);} + + _LIBCPP_INLINE_VISIBILITY + const_iterator cbegin() const _NOEXCEPT + {return const_iterator(base::__before_begin()->__next_);} + _LIBCPP_INLINE_VISIBILITY + const_iterator cend() const _NOEXCEPT + {return const_iterator(nullptr);} + + _LIBCPP_INLINE_VISIBILITY + iterator before_begin() _NOEXCEPT + {return iterator(base::__before_begin());} + _LIBCPP_INLINE_VISIBILITY + const_iterator before_begin() const _NOEXCEPT + {return const_iterator(base::__before_begin());} + _LIBCPP_INLINE_VISIBILITY + const_iterator cbefore_begin() const _NOEXCEPT + {return const_iterator(base::__before_begin());} + + _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY + bool empty() const _NOEXCEPT + {return base::__before_begin()->__next_ == nullptr;} + _LIBCPP_INLINE_VISIBILITY + size_type max_size() const _NOEXCEPT { + return std::min( + __node_traits::max_size(base::__alloc()), + numeric_limits::max()); + } + + _LIBCPP_INLINE_VISIBILITY + reference front() {return base::__before_begin()->__next_->__value_;} + _LIBCPP_INLINE_VISIBILITY + const_reference front() const {return base::__before_begin()->__next_->__value_;} + +#ifndef _LIBCPP_CXX03_LANG +#if _LIBCPP_STD_VER > 14 + template reference emplace_front(_Args&&... __args); +#else + template void emplace_front(_Args&&... __args); +#endif + void push_front(value_type&& __v); +#endif // _LIBCPP_CXX03_LANG + void push_front(const value_type& __v); + + void pop_front(); + +#ifndef _LIBCPP_CXX03_LANG + template + iterator emplace_after(const_iterator __p, _Args&&... __args); + + iterator insert_after(const_iterator __p, value_type&& __v); + iterator insert_after(const_iterator __p, initializer_list __il) + {return insert_after(__p, __il.begin(), __il.end());} +#endif // _LIBCPP_CXX03_LANG + iterator insert_after(const_iterator __p, const value_type& __v); + iterator insert_after(const_iterator __p, size_type __n, const value_type& __v); + template + _LIBCPP_INLINE_VISIBILITY + typename enable_if + < + __is_input_iterator<_InputIterator>::value, + iterator + >::type + insert_after(const_iterator __p, _InputIterator __f, _InputIterator __l); + + iterator erase_after(const_iterator __p); + iterator erase_after(const_iterator __f, const_iterator __l); + + _LIBCPP_INLINE_VISIBILITY + void swap(forward_list& __x) +#if _LIBCPP_STD_VER >= 14 + _NOEXCEPT +#else + _NOEXCEPT_(!__node_traits::propagate_on_container_swap::value || + __is_nothrow_swappable<__node_allocator>::value) +#endif + {base::swap(__x);} + + void resize(size_type __n); + void resize(size_type __n, const value_type& __v); + _LIBCPP_INLINE_VISIBILITY + void clear() _NOEXCEPT {base::clear();} + + _LIBCPP_INLINE_VISIBILITY + void splice_after(const_iterator __p, forward_list&& __x); + _LIBCPP_INLINE_VISIBILITY + void splice_after(const_iterator __p, forward_list&& __x, const_iterator __i); + _LIBCPP_INLINE_VISIBILITY + void splice_after(const_iterator __p, forward_list&& __x, + const_iterator __f, const_iterator __l); + void splice_after(const_iterator __p, forward_list& __x); + void splice_after(const_iterator __p, forward_list& __x, const_iterator __i); + void splice_after(const_iterator __p, forward_list& __x, + const_iterator __f, const_iterator __l); + __remove_return_type remove(const value_type& __v); + template __remove_return_type remove_if(_Predicate __pred); + _LIBCPP_INLINE_VISIBILITY + __remove_return_type unique() {return unique(__equal_to());} + template __remove_return_type unique(_BinaryPredicate __binary_pred); +#ifndef _LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY + void merge(forward_list&& __x) {merge(__x, __less());} + template + _LIBCPP_INLINE_VISIBILITY + void merge(forward_list&& __x, _Compare __comp) + {merge(__x, _VSTD::move(__comp));} +#endif // _LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY + void merge(forward_list& __x) {merge(__x, __less());} + template void merge(forward_list& __x, _Compare __comp); + _LIBCPP_INLINE_VISIBILITY + void sort() {sort(__less());} + template _LIBCPP_INLINE_VISIBILITY void sort(_Compare __comp); + void reverse() _NOEXCEPT; + +private: + +#ifndef _LIBCPP_CXX03_LANG + void __move_assign(forward_list& __x, true_type) + _NOEXCEPT_(is_nothrow_move_assignable::value); + void __move_assign(forward_list& __x, false_type); +#endif // _LIBCPP_CXX03_LANG + + template + static + __node_pointer + __merge(__node_pointer __f1, __node_pointer __f2, _Compare& __comp); + + template + static + __node_pointer + __sort(__node_pointer __f, difference_type __sz, _Compare& __comp); +}; + + +#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES +template::value_type>, + class = typename enable_if<__is_allocator<_Alloc>::value, void>::type + > +forward_list(_InputIterator, _InputIterator) + -> forward_list::value_type, _Alloc>; + +template::value, void>::type + > +forward_list(_InputIterator, _InputIterator, _Alloc) + -> forward_list::value_type, _Alloc>; +#endif + +template +inline +forward_list<_Tp, _Alloc>::forward_list(const allocator_type& __a) + : base(__a) +{ +} + +template +forward_list<_Tp, _Alloc>::forward_list(size_type __n) +{ + if (__n > 0) + { + __node_allocator& __a = base::__alloc(); + typedef __allocator_destructor<__node_allocator> _Dp; + unique_ptr<__node, _Dp> __h(nullptr, _Dp(__a, 1)); + for (__begin_node_pointer __p = base::__before_begin(); __n > 0; --__n, + __p = __p->__next_as_begin()) + { + __h.reset(__node_traits::allocate(__a, 1)); + __node_traits::construct(__a, _VSTD::addressof(__h->__value_)); + __h->__next_ = nullptr; + __p->__next_ = __h.release(); + } + } +} + +#if _LIBCPP_STD_VER > 11 +template +forward_list<_Tp, _Alloc>::forward_list(size_type __n, + const allocator_type& __base_alloc) + : base ( __base_alloc ) +{ + if (__n > 0) + { + __node_allocator& __a = base::__alloc(); + typedef __allocator_destructor<__node_allocator> _Dp; + unique_ptr<__node, _Dp> __h(nullptr, _Dp(__a, 1)); + for (__begin_node_pointer __p = base::__before_begin(); __n > 0; --__n, + __p = __p->__next_as_begin()) + { + __h.reset(__node_traits::allocate(__a, 1)); + __node_traits::construct(__a, _VSTD::addressof(__h->__value_)); + __h->__next_ = nullptr; + __p->__next_ = __h.release(); + } + } +} +#endif + +template +forward_list<_Tp, _Alloc>::forward_list(size_type __n, const value_type& __v) +{ + insert_after(cbefore_begin(), __n, __v); +} + +template +forward_list<_Tp, _Alloc>::forward_list(size_type __n, const value_type& __v, + const allocator_type& __a) + : base(__a) +{ + insert_after(cbefore_begin(), __n, __v); +} + +template +template +forward_list<_Tp, _Alloc>::forward_list(_InputIterator __f, _InputIterator __l, + typename enable_if< + __is_input_iterator<_InputIterator>::value + >::type*) +{ + insert_after(cbefore_begin(), __f, __l); +} + +template +template +forward_list<_Tp, _Alloc>::forward_list(_InputIterator __f, _InputIterator __l, + const allocator_type& __a, + typename enable_if< + __is_input_iterator<_InputIterator>::value + >::type*) + : base(__a) +{ + insert_after(cbefore_begin(), __f, __l); +} + +template +forward_list<_Tp, _Alloc>::forward_list(const forward_list& __x) + : base( + __node_traits::select_on_container_copy_construction(__x.__alloc())) { + insert_after(cbefore_begin(), __x.begin(), __x.end()); +} + +template +forward_list<_Tp, _Alloc>::forward_list(const forward_list& __x, + const allocator_type& __a) + : base(__a) +{ + insert_after(cbefore_begin(), __x.begin(), __x.end()); +} + +template +forward_list<_Tp, _Alloc>& +forward_list<_Tp, _Alloc>::operator=(const forward_list& __x) +{ + if (this != &__x) + { + base::__copy_assign_alloc(__x); + assign(__x.begin(), __x.end()); + } + return *this; +} + +#ifndef _LIBCPP_CXX03_LANG +template +forward_list<_Tp, _Alloc>::forward_list(forward_list&& __x, + const allocator_type& __a) + : base(_VSTD::move(__x), __a) +{ + if (base::__alloc() != __x.__alloc()) + { + typedef move_iterator _Ip; + insert_after(cbefore_begin(), _Ip(__x.begin()), _Ip(__x.end())); + } +} + +template +forward_list<_Tp, _Alloc>::forward_list(initializer_list __il) +{ + insert_after(cbefore_begin(), __il.begin(), __il.end()); +} + +template +forward_list<_Tp, _Alloc>::forward_list(initializer_list __il, + const allocator_type& __a) + : base(__a) +{ + insert_after(cbefore_begin(), __il.begin(), __il.end()); +} + +template +void +forward_list<_Tp, _Alloc>::__move_assign(forward_list& __x, true_type) + _NOEXCEPT_(is_nothrow_move_assignable::value) +{ + clear(); + base::__move_assign_alloc(__x); + base::__before_begin()->__next_ = __x.__before_begin()->__next_; + __x.__before_begin()->__next_ = nullptr; +} + +template +void +forward_list<_Tp, _Alloc>::__move_assign(forward_list& __x, false_type) +{ + if (base::__alloc() == __x.__alloc()) + __move_assign(__x, true_type()); + else + { + typedef move_iterator _Ip; + assign(_Ip(__x.begin()), _Ip(__x.end())); + } +} + +template +inline +forward_list<_Tp, _Alloc>& +forward_list<_Tp, _Alloc>::operator=(forward_list&& __x) + _NOEXCEPT_( + __node_traits::propagate_on_container_move_assignment::value && + is_nothrow_move_assignable::value) +{ + __move_assign(__x, integral_constant()); + return *this; +} + +template +inline +forward_list<_Tp, _Alloc>& +forward_list<_Tp, _Alloc>::operator=(initializer_list __il) +{ + assign(__il.begin(), __il.end()); + return *this; +} + +#endif // _LIBCPP_CXX03_LANG + +template +template +typename enable_if +< + __is_input_iterator<_InputIterator>::value, + void +>::type +forward_list<_Tp, _Alloc>::assign(_InputIterator __f, _InputIterator __l) +{ + iterator __i = before_begin(); + iterator __j = _VSTD::next(__i); + iterator __e = end(); + for (; __j != __e && __f != __l; ++__i, (void) ++__j, ++__f) + *__j = *__f; + if (__j == __e) + insert_after(__i, __f, __l); + else + erase_after(__i, __e); +} + +template +void +forward_list<_Tp, _Alloc>::assign(size_type __n, const value_type& __v) +{ + iterator __i = before_begin(); + iterator __j = _VSTD::next(__i); + iterator __e = end(); + for (; __j != __e && __n > 0; --__n, ++__i, ++__j) + *__j = __v; + if (__j == __e) + insert_after(__i, __n, __v); + else + erase_after(__i, __e); +} + +#ifndef _LIBCPP_CXX03_LANG + +template +inline +void +forward_list<_Tp, _Alloc>::assign(initializer_list __il) +{ + assign(__il.begin(), __il.end()); +} + +template +template +#if _LIBCPP_STD_VER > 14 +typename forward_list<_Tp, _Alloc>::reference +#else +void +#endif +forward_list<_Tp, _Alloc>::emplace_front(_Args&&... __args) +{ + __node_allocator& __a = base::__alloc(); + typedef __allocator_destructor<__node_allocator> _Dp; + unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1)); + __node_traits::construct(__a, _VSTD::addressof(__h->__value_), + _VSTD::forward<_Args>(__args)...); + __h->__next_ = base::__before_begin()->__next_; + base::__before_begin()->__next_ = __h.release(); +#if _LIBCPP_STD_VER > 14 + return base::__before_begin()->__next_->__value_; +#endif +} + +template +void +forward_list<_Tp, _Alloc>::push_front(value_type&& __v) +{ + __node_allocator& __a = base::__alloc(); + typedef __allocator_destructor<__node_allocator> _Dp; + unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1)); + __node_traits::construct(__a, _VSTD::addressof(__h->__value_), _VSTD::move(__v)); + __h->__next_ = base::__before_begin()->__next_; + base::__before_begin()->__next_ = __h.release(); +} + +#endif // _LIBCPP_CXX03_LANG + +template +void +forward_list<_Tp, _Alloc>::push_front(const value_type& __v) +{ + __node_allocator& __a = base::__alloc(); + typedef __allocator_destructor<__node_allocator> _Dp; + unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1)); + __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v); + __h->__next_ = base::__before_begin()->__next_; + base::__before_begin()->__next_ = __h.release(); +} + +template +void +forward_list<_Tp, _Alloc>::pop_front() +{ + __node_allocator& __a = base::__alloc(); + __node_pointer __p = base::__before_begin()->__next_; + base::__before_begin()->__next_ = __p->__next_; + __node_traits::destroy(__a, _VSTD::addressof(__p->__value_)); + __node_traits::deallocate(__a, __p, 1); +} + +#ifndef _LIBCPP_CXX03_LANG + +template +template +typename forward_list<_Tp, _Alloc>::iterator +forward_list<_Tp, _Alloc>::emplace_after(const_iterator __p, _Args&&... __args) +{ + __begin_node_pointer const __r = __p.__get_begin(); + __node_allocator& __a = base::__alloc(); + typedef __allocator_destructor<__node_allocator> _Dp; + unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1)); + __node_traits::construct(__a, _VSTD::addressof(__h->__value_), + _VSTD::forward<_Args>(__args)...); + __h->__next_ = __r->__next_; + __r->__next_ = __h.release(); + return iterator(__r->__next_); +} + +template +typename forward_list<_Tp, _Alloc>::iterator +forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, value_type&& __v) +{ + __begin_node_pointer const __r = __p.__get_begin(); + __node_allocator& __a = base::__alloc(); + typedef __allocator_destructor<__node_allocator> _Dp; + unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1)); + __node_traits::construct(__a, _VSTD::addressof(__h->__value_), _VSTD::move(__v)); + __h->__next_ = __r->__next_; + __r->__next_ = __h.release(); + return iterator(__r->__next_); +} + +#endif // _LIBCPP_CXX03_LANG + +template +typename forward_list<_Tp, _Alloc>::iterator +forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, const value_type& __v) +{ + __begin_node_pointer const __r = __p.__get_begin(); + __node_allocator& __a = base::__alloc(); + typedef __allocator_destructor<__node_allocator> _Dp; + unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1)); + __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v); + __h->__next_ = __r->__next_; + __r->__next_ = __h.release(); + return iterator(__r->__next_); +} + +template +typename forward_list<_Tp, _Alloc>::iterator +forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, size_type __n, + const value_type& __v) +{ + __begin_node_pointer __r = __p.__get_begin(); + if (__n > 0) + { + __node_allocator& __a = base::__alloc(); + typedef __allocator_destructor<__node_allocator> _Dp; + unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1)); + __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v); + __node_pointer __first = __h.release(); + __node_pointer __last = __first; +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + for (--__n; __n != 0; --__n, __last = __last->__next_) + { + __h.reset(__node_traits::allocate(__a, 1)); + __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v); + __last->__next_ = __h.release(); + } +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + while (__first != nullptr) + { + __node_pointer __next = __first->__next_; + __node_traits::destroy(__a, _VSTD::addressof(__first->__value_)); + __node_traits::deallocate(__a, __first, 1); + __first = __next; + } + throw; + } +#endif // _LIBCPP_NO_EXCEPTIONS + __last->__next_ = __r->__next_; + __r->__next_ = __first; + __r = static_cast<__begin_node_pointer>(__last); + } + return iterator(__r); +} + +template +template +typename enable_if +< + __is_input_iterator<_InputIterator>::value, + typename forward_list<_Tp, _Alloc>::iterator +>::type +forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, + _InputIterator __f, _InputIterator __l) +{ + __begin_node_pointer __r = __p.__get_begin(); + if (__f != __l) + { + __node_allocator& __a = base::__alloc(); + typedef __allocator_destructor<__node_allocator> _Dp; + unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1)); + __node_traits::construct(__a, _VSTD::addressof(__h->__value_), *__f); + __node_pointer __first = __h.release(); + __node_pointer __last = __first; +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + for (++__f; __f != __l; ++__f, ((void)(__last = __last->__next_))) + { + __h.reset(__node_traits::allocate(__a, 1)); + __node_traits::construct(__a, _VSTD::addressof(__h->__value_), *__f); + __last->__next_ = __h.release(); + } +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + while (__first != nullptr) + { + __node_pointer __next = __first->__next_; + __node_traits::destroy(__a, _VSTD::addressof(__first->__value_)); + __node_traits::deallocate(__a, __first, 1); + __first = __next; + } + throw; + } +#endif // _LIBCPP_NO_EXCEPTIONS + __last->__next_ = __r->__next_; + __r->__next_ = __first; + __r = static_cast<__begin_node_pointer>(__last); + } + return iterator(__r); +} + +template +typename forward_list<_Tp, _Alloc>::iterator +forward_list<_Tp, _Alloc>::erase_after(const_iterator __f) +{ + __begin_node_pointer __p = __f.__get_begin(); + __node_pointer __n = __p->__next_; + __p->__next_ = __n->__next_; + __node_allocator& __a = base::__alloc(); + __node_traits::destroy(__a, _VSTD::addressof(__n->__value_)); + __node_traits::deallocate(__a, __n, 1); + return iterator(__p->__next_); +} + +template +typename forward_list<_Tp, _Alloc>::iterator +forward_list<_Tp, _Alloc>::erase_after(const_iterator __f, const_iterator __l) +{ + __node_pointer __e = __l.__get_unsafe_node_pointer(); + if (__f != __l) + { + __begin_node_pointer __bp = __f.__get_begin(); + + __node_pointer __n = __bp->__next_; + if (__n != __e) + { + __bp->__next_ = __e; + __node_allocator& __a = base::__alloc(); + do + { + __node_pointer __tmp = __n->__next_; + __node_traits::destroy(__a, _VSTD::addressof(__n->__value_)); + __node_traits::deallocate(__a, __n, 1); + __n = __tmp; + } while (__n != __e); + } + } + return iterator(__e); +} + +template +void +forward_list<_Tp, _Alloc>::resize(size_type __n) +{ + size_type __sz = 0; + iterator __p = before_begin(); + iterator __i = begin(); + iterator __e = end(); + for (; __i != __e && __sz < __n; ++__p, ++__i, ++__sz) + ; + if (__i != __e) + erase_after(__p, __e); + else + { + __n -= __sz; + if (__n > 0) + { + __node_allocator& __a = base::__alloc(); + typedef __allocator_destructor<__node_allocator> _Dp; + unique_ptr<__node, _Dp> __h(nullptr, _Dp(__a, 1)); + for (__begin_node_pointer __ptr = __p.__get_begin(); __n > 0; --__n, + __ptr = __ptr->__next_as_begin()) + { + __h.reset(__node_traits::allocate(__a, 1)); + __node_traits::construct(__a, _VSTD::addressof(__h->__value_)); + __h->__next_ = nullptr; + __ptr->__next_ = __h.release(); + } + } + } +} + +template +void +forward_list<_Tp, _Alloc>::resize(size_type __n, const value_type& __v) +{ + size_type __sz = 0; + iterator __p = before_begin(); + iterator __i = begin(); + iterator __e = end(); + for (; __i != __e && __sz < __n; ++__p, ++__i, ++__sz) + ; + if (__i != __e) + erase_after(__p, __e); + else + { + __n -= __sz; + if (__n > 0) + { + __node_allocator& __a = base::__alloc(); + typedef __allocator_destructor<__node_allocator> _Dp; + unique_ptr<__node, _Dp> __h(nullptr, _Dp(__a, 1)); + for (__begin_node_pointer __ptr = __p.__get_begin(); __n > 0; --__n, + __ptr = __ptr->__next_as_begin()) + { + __h.reset(__node_traits::allocate(__a, 1)); + __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v); + __h->__next_ = nullptr; + __ptr->__next_ = __h.release(); + } + } + } +} + +template +void +forward_list<_Tp, _Alloc>::splice_after(const_iterator __p, + forward_list& __x) +{ + if (!__x.empty()) + { + if (__p.__get_begin()->__next_ != nullptr) + { + const_iterator __lm1 = __x.before_begin(); + while (__lm1.__get_begin()->__next_ != nullptr) + ++__lm1; + __lm1.__get_begin()->__next_ = __p.__get_begin()->__next_; + } + __p.__get_begin()->__next_ = __x.__before_begin()->__next_; + __x.__before_begin()->__next_ = nullptr; + } +} + +template +void +forward_list<_Tp, _Alloc>::splice_after(const_iterator __p, + forward_list& /*__other*/, + const_iterator __i) +{ + const_iterator __lm1 = _VSTD::next(__i); + if (__p != __i && __p != __lm1) + { + __i.__get_begin()->__next_ = __lm1.__get_begin()->__next_; + __lm1.__get_begin()->__next_ = __p.__get_begin()->__next_; + __p.__get_begin()->__next_ = __lm1.__get_unsafe_node_pointer(); + } +} + +template +void +forward_list<_Tp, _Alloc>::splice_after(const_iterator __p, + forward_list& /*__other*/, + const_iterator __f, const_iterator __l) +{ + if (__f != __l && __p != __f) + { + const_iterator __lm1 = __f; + while (__lm1.__get_begin()->__next_ != __l.__get_begin()) + ++__lm1; + if (__f != __lm1) + { + __lm1.__get_begin()->__next_ = __p.__get_begin()->__next_; + __p.__get_begin()->__next_ = __f.__get_begin()->__next_; + __f.__get_begin()->__next_ = __l.__get_unsafe_node_pointer(); + } + } +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +forward_list<_Tp, _Alloc>::splice_after(const_iterator __p, + forward_list&& __x) +{ + splice_after(__p, __x); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +forward_list<_Tp, _Alloc>::splice_after(const_iterator __p, + forward_list&& __x, + const_iterator __i) +{ + splice_after(__p, __x, __i); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +forward_list<_Tp, _Alloc>::splice_after(const_iterator __p, + forward_list&& __x, + const_iterator __f, const_iterator __l) +{ + splice_after(__p, __x, __f, __l); +} + +template +typename forward_list<_Tp, _Alloc>::__remove_return_type +forward_list<_Tp, _Alloc>::remove(const value_type& __v) +{ + forward_list<_Tp, _Alloc> __deleted_nodes(get_allocator()); // collect the nodes we're removing + typename forward_list<_Tp, _Alloc>::size_type __count_removed = 0; + const iterator __e = end(); + for (iterator __i = before_begin(); __i.__get_begin()->__next_ != nullptr;) + { + if (__i.__get_begin()->__next_->__value_ == __v) + { + ++__count_removed; + iterator __j = _VSTD::next(__i, 2); + for (; __j != __e && *__j == __v; ++__j) + ++__count_removed; + __deleted_nodes.splice_after(__deleted_nodes.before_begin(), *this, __i, __j); + if (__j == __e) + break; + __i = __j; + } + else + ++__i; + } + + return (__remove_return_type) __count_removed; +} + +template +template +typename forward_list<_Tp, _Alloc>::__remove_return_type +forward_list<_Tp, _Alloc>::remove_if(_Predicate __pred) +{ + forward_list<_Tp, _Alloc> __deleted_nodes(get_allocator()); // collect the nodes we're removing + typename forward_list<_Tp, _Alloc>::size_type __count_removed = 0; + const iterator __e = end(); + for (iterator __i = before_begin(); __i.__get_begin()->__next_ != nullptr;) + { + if (__pred(__i.__get_begin()->__next_->__value_)) + { + ++__count_removed; + iterator __j = _VSTD::next(__i, 2); + for (; __j != __e && __pred(*__j); ++__j) + ++__count_removed; + __deleted_nodes.splice_after(__deleted_nodes.before_begin(), *this, __i, __j); + if (__j == __e) + break; + __i = __j; + } + else + ++__i; + } + + return (__remove_return_type) __count_removed; +} + +template +template +typename forward_list<_Tp, _Alloc>::__remove_return_type +forward_list<_Tp, _Alloc>::unique(_BinaryPredicate __binary_pred) +{ + forward_list<_Tp, _Alloc> __deleted_nodes(get_allocator()); // collect the nodes we're removing + typename forward_list<_Tp, _Alloc>::size_type __count_removed = 0; + for (iterator __i = begin(), __e = end(); __i != __e;) + { + iterator __j = _VSTD::next(__i); + for (; __j != __e && __binary_pred(*__i, *__j); ++__j) + ++__count_removed; + if (__i.__get_begin()->__next_ != __j.__get_unsafe_node_pointer()) + __deleted_nodes.splice_after(__deleted_nodes.before_begin(), *this, __i, __j); + __i = __j; + } + + return (__remove_return_type) __count_removed; +} + +template +template +void +forward_list<_Tp, _Alloc>::merge(forward_list& __x, _Compare __comp) +{ + if (this != &__x) + { + base::__before_begin()->__next_ = __merge(base::__before_begin()->__next_, + __x.__before_begin()->__next_, + __comp); + __x.__before_begin()->__next_ = nullptr; + } +} + +template +template +typename forward_list<_Tp, _Alloc>::__node_pointer +forward_list<_Tp, _Alloc>::__merge(__node_pointer __f1, __node_pointer __f2, + _Compare& __comp) +{ + if (__f1 == nullptr) + return __f2; + if (__f2 == nullptr) + return __f1; + __node_pointer __r; + if (__comp(__f2->__value_, __f1->__value_)) + { + __node_pointer __t = __f2; + while (__t->__next_ != nullptr && + __comp(__t->__next_->__value_, __f1->__value_)) + __t = __t->__next_; + __r = __f2; + __f2 = __t->__next_; + __t->__next_ = __f1; + } + else + __r = __f1; + __node_pointer __p = __f1; + __f1 = __f1->__next_; + while (__f1 != nullptr && __f2 != nullptr) + { + if (__comp(__f2->__value_, __f1->__value_)) + { + __node_pointer __t = __f2; + while (__t->__next_ != nullptr && + __comp(__t->__next_->__value_, __f1->__value_)) + __t = __t->__next_; + __p->__next_ = __f2; + __f2 = __t->__next_; + __t->__next_ = __f1; + } + __p = __f1; + __f1 = __f1->__next_; + } + if (__f2 != nullptr) + __p->__next_ = __f2; + return __r; +} + +template +template +inline +void +forward_list<_Tp, _Alloc>::sort(_Compare __comp) +{ + base::__before_begin()->__next_ = __sort(base::__before_begin()->__next_, + _VSTD::distance(begin(), end()), __comp); +} + +template +template +typename forward_list<_Tp, _Alloc>::__node_pointer +forward_list<_Tp, _Alloc>::__sort(__node_pointer __f1, difference_type __sz, + _Compare& __comp) +{ + switch (__sz) + { + case 0: + case 1: + return __f1; + case 2: + if (__comp(__f1->__next_->__value_, __f1->__value_)) + { + __node_pointer __t = __f1->__next_; + __t->__next_ = __f1; + __f1->__next_ = nullptr; + __f1 = __t; + } + return __f1; + } + difference_type __sz1 = __sz / 2; + difference_type __sz2 = __sz - __sz1; + __node_pointer __t = _VSTD::next(iterator(__f1), __sz1 - 1).__get_unsafe_node_pointer(); + __node_pointer __f2 = __t->__next_; + __t->__next_ = nullptr; + return __merge(__sort(__f1, __sz1, __comp), + __sort(__f2, __sz2, __comp), __comp); +} + +template +void +forward_list<_Tp, _Alloc>::reverse() _NOEXCEPT +{ + __node_pointer __p = base::__before_begin()->__next_; + if (__p != nullptr) + { + __node_pointer __f = __p->__next_; + __p->__next_ = nullptr; + while (__f != nullptr) + { + __node_pointer __t = __f->__next_; + __f->__next_ = __p; + __p = __f; + __f = __t; + } + base::__before_begin()->__next_ = __p; + } +} + +template +bool operator==(const forward_list<_Tp, _Alloc>& __x, + const forward_list<_Tp, _Alloc>& __y) +{ + typedef forward_list<_Tp, _Alloc> _Cp; + typedef typename _Cp::const_iterator _Ip; + _Ip __ix = __x.begin(); + _Ip __ex = __x.end(); + _Ip __iy = __y.begin(); + _Ip __ey = __y.end(); + for (; __ix != __ex && __iy != __ey; ++__ix, ++__iy) + if (!(*__ix == *__iy)) + return false; + return (__ix == __ex) == (__iy == __ey); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool operator!=(const forward_list<_Tp, _Alloc>& __x, + const forward_list<_Tp, _Alloc>& __y) +{ + return !(__x == __y); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool operator< (const forward_list<_Tp, _Alloc>& __x, + const forward_list<_Tp, _Alloc>& __y) +{ + return _VSTD::lexicographical_compare(__x.begin(), __x.end(), + __y.begin(), __y.end()); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool operator> (const forward_list<_Tp, _Alloc>& __x, + const forward_list<_Tp, _Alloc>& __y) +{ + return __y < __x; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool operator>=(const forward_list<_Tp, _Alloc>& __x, + const forward_list<_Tp, _Alloc>& __y) +{ + return !(__x < __y); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool operator<=(const forward_list<_Tp, _Alloc>& __x, + const forward_list<_Tp, _Alloc>& __y) +{ + return !(__y < __x); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +swap(forward_list<_Tp, _Alloc>& __x, forward_list<_Tp, _Alloc>& __y) + _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) +{ + __x.swap(__y); +} + +#if _LIBCPP_STD_VER > 17 +template +inline _LIBCPP_INLINE_VISIBILITY +void erase_if(forward_list<_Tp, _Allocator>& __c, _Predicate __pred) +{ __c.remove_if(__pred); } + +template +inline _LIBCPP_INLINE_VISIBILITY +void erase(forward_list<_Tp, _Allocator>& __c, const _Up& __v) +{ _VSTD::erase_if(__c, [&](auto& __elem) { return __elem == __v; }); } +#endif + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP_FORWARD_LIST diff --git a/third_party/libcxx/fstream b/third_party/libcxx/fstream new file mode 100644 index 000000000..8b44a29ca --- /dev/null +++ b/third_party/libcxx/fstream @@ -0,0 +1,1764 @@ +// -*- C++ -*- +// clang-format off +//===------------------------- fstream ------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_FSTREAM +#define _LIBCPP_FSTREAM + +/* + fstream synopsis + +template > +class basic_filebuf + : public basic_streambuf +{ +public: + typedef charT char_type; + typedef traits traits_type; + typedef typename traits_type::int_type int_type; + typedef typename traits_type::pos_type pos_type; + typedef typename traits_type::off_type off_type; + + // 27.9.1.2 Constructors/destructor: + basic_filebuf(); + basic_filebuf(basic_filebuf&& rhs); + virtual ~basic_filebuf(); + + // 27.9.1.3 Assign/swap: + basic_filebuf& operator=(basic_filebuf&& rhs); + void swap(basic_filebuf& rhs); + + // 27.9.1.4 Members: + bool is_open() const; + basic_filebuf* open(const char* s, ios_base::openmode mode); + basic_filebuf* open(const string& s, ios_base::openmode mode); + basic_filebuf* open(const filesystem::path& p, ios_base::openmode mode); // C++17 + basic_filebuf* close(); + +protected: + // 27.9.1.5 Overridden virtual functions: + virtual streamsize showmanyc(); + virtual int_type underflow(); + virtual int_type uflow(); + virtual int_type pbackfail(int_type c = traits_type::eof()); + virtual int_type overflow (int_type c = traits_type::eof()); + virtual basic_streambuf* setbuf(char_type* s, streamsize n); + virtual pos_type seekoff(off_type off, ios_base::seekdir way, + ios_base::openmode which = ios_base::in | ios_base::out); + virtual pos_type seekpos(pos_type sp, + ios_base::openmode which = ios_base::in | ios_base::out); + virtual int sync(); + virtual void imbue(const locale& loc); +}; + +template + void + swap(basic_filebuf& x, basic_filebuf& y); + +typedef basic_filebuf filebuf; +typedef basic_filebuf wfilebuf; + +template > +class basic_ifstream + : public basic_istream +{ +public: + typedef charT char_type; + typedef traits traits_type; + typedef typename traits_type::int_type int_type; + typedef typename traits_type::pos_type pos_type; + typedef typename traits_type::off_type off_type; + + basic_ifstream(); + explicit basic_ifstream(const char* s, ios_base::openmode mode = ios_base::in); + explicit basic_ifstream(const string& s, ios_base::openmode mode = ios_base::in); + explicit basic_ifstream(const filesystem::path& p, + ios_base::openmode mode = ios_base::in); // C++17 + basic_ifstream(basic_ifstream&& rhs); + + basic_ifstream& operator=(basic_ifstream&& rhs); + void swap(basic_ifstream& rhs); + + basic_filebuf* rdbuf() const; + bool is_open() const; + void open(const char* s, ios_base::openmode mode = ios_base::in); + void open(const string& s, ios_base::openmode mode = ios_base::in); + void open(const filesystem::path& s, ios_base::openmode mode = ios_base::in); // C++17 + + void close(); +}; + +template + void + swap(basic_ifstream& x, basic_ifstream& y); + +typedef basic_ifstream ifstream; +typedef basic_ifstream wifstream; + +template > +class basic_ofstream + : public basic_ostream +{ +public: + typedef charT char_type; + typedef traits traits_type; + typedef typename traits_type::int_type int_type; + typedef typename traits_type::pos_type pos_type; + typedef typename traits_type::off_type off_type; + + basic_ofstream(); + explicit basic_ofstream(const char* s, ios_base::openmode mode = ios_base::out); + explicit basic_ofstream(const string& s, ios_base::openmode mode = ios_base::out); + explicit basic_ofstream(const filesystem::path& p, + ios_base::openmode mode = ios_base::out); // C++17 + basic_ofstream(basic_ofstream&& rhs); + + basic_ofstream& operator=(basic_ofstream&& rhs); + void swap(basic_ofstream& rhs); + + basic_filebuf* rdbuf() const; + bool is_open() const; + void open(const char* s, ios_base::openmode mode = ios_base::out); + void open(const string& s, ios_base::openmode mode = ios_base::out); + void open(const filesystem::path& p, + ios_base::openmode mode = ios_base::out); // C++17 + + void close(); +}; + +template + void + swap(basic_ofstream& x, basic_ofstream& y); + +typedef basic_ofstream ofstream; +typedef basic_ofstream wofstream; + +template > +class basic_fstream + : public basic_iostream +{ +public: + typedef charT char_type; + typedef traits traits_type; + typedef typename traits_type::int_type int_type; + typedef typename traits_type::pos_type pos_type; + typedef typename traits_type::off_type off_type; + + basic_fstream(); + explicit basic_fstream(const char* s, ios_base::openmode mode = ios_base::in|ios_base::out); + explicit basic_fstream(const string& s, ios_base::openmode mode = ios_base::in|ios_base::out); + explicit basic_fstream(const filesystem::path& p, + ios_base::openmode mode = ios_base::in|ios_base::out); C++17 + basic_fstream(basic_fstream&& rhs); + + basic_fstream& operator=(basic_fstream&& rhs); + void swap(basic_fstream& rhs); + + basic_filebuf* rdbuf() const; + bool is_open() const; + void open(const char* s, ios_base::openmode mode = ios_base::in|ios_base::out); + void open(const string& s, ios_base::openmode mode = ios_base::in|ios_base::out); + void open(const filesystem::path& s, + ios_base::openmode mode = ios_base::in|ios_base::out); // C++17 + + void close(); +}; + +template + void swap(basic_fstream& x, basic_fstream& y); + +typedef basic_fstream fstream; +typedef basic_fstream wfstream; + +} // std + +*/ + +#include "third_party/libcxx/__config" +#include "third_party/libcxx/ostream" +#include "third_party/libcxx/istream" +#include "third_party/libcxx/__locale" +#include "third_party/libcxx/cstdio" +#include "third_party/libcxx/cstdlib" +#include "third_party/libcxx/filesystem" + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include "third_party/libcxx/__undef_macros" + + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +class _LIBCPP_TEMPLATE_VIS basic_filebuf + : public basic_streambuf<_CharT, _Traits> +{ +public: + typedef _CharT char_type; + typedef _Traits traits_type; + typedef typename traits_type::int_type int_type; + typedef typename traits_type::pos_type pos_type; + typedef typename traits_type::off_type off_type; + typedef typename traits_type::state_type state_type; + + // 27.9.1.2 Constructors/destructor: + basic_filebuf(); +#ifndef _LIBCPP_CXX03_LANG + basic_filebuf(basic_filebuf&& __rhs); +#endif + virtual ~basic_filebuf(); + + // 27.9.1.3 Assign/swap: +#ifndef _LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY + basic_filebuf& operator=(basic_filebuf&& __rhs); +#endif + void swap(basic_filebuf& __rhs); + + // 27.9.1.4 Members: + _LIBCPP_INLINE_VISIBILITY + bool is_open() const; +#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE + basic_filebuf* open(const char* __s, ios_base::openmode __mode); +#ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR + basic_filebuf* open(const wchar_t* __s, ios_base::openmode __mode); +#endif + _LIBCPP_INLINE_VISIBILITY + basic_filebuf* open(const string& __s, ios_base::openmode __mode); + +#if _LIBCPP_STD_VER >= 17 + _LIBCPP_AVAILABILITY_FILESYSTEM _LIBCPP_INLINE_VISIBILITY + basic_filebuf* open(const _VSTD_FS::path& __p, ios_base::openmode __mode) { + return open(__p.c_str(), __mode); + } +#endif + _LIBCPP_INLINE_VISIBILITY + basic_filebuf* __open(int __fd, ios_base::openmode __mode); +#endif + basic_filebuf* close(); + + _LIBCPP_INLINE_VISIBILITY + inline static const char* + __make_mdstring(ios_base::openmode __mode) _NOEXCEPT; + + protected: + // 27.9.1.5 Overridden virtual functions: + virtual int_type underflow(); + virtual int_type pbackfail(int_type __c = traits_type::eof()); + virtual int_type overflow (int_type __c = traits_type::eof()); + virtual basic_streambuf* setbuf(char_type* __s, streamsize __n); + virtual pos_type seekoff(off_type __off, ios_base::seekdir __way, + ios_base::openmode __wch = ios_base::in | ios_base::out); + virtual pos_type seekpos(pos_type __sp, + ios_base::openmode __wch = ios_base::in | ios_base::out); + virtual int sync(); + virtual void imbue(const locale& __loc); + +private: + char* __extbuf_; + const char* __extbufnext_; + const char* __extbufend_; + char __extbuf_min_[8]; + size_t __ebs_; + char_type* __intbuf_; + size_t __ibs_; + FILE* __file_; + const codecvt* __cv_; + state_type __st_; + state_type __st_last_; + ios_base::openmode __om_; + ios_base::openmode __cm_; + bool __owns_eb_; + bool __owns_ib_; + bool __always_noconv_; + + bool __read_mode(); + void __write_mode(); +}; + +template +basic_filebuf<_CharT, _Traits>::basic_filebuf() + : __extbuf_(0), + __extbufnext_(0), + __extbufend_(0), + __ebs_(0), + __intbuf_(0), + __ibs_(0), + __file_(0), + __cv_(nullptr), + __st_(), + __st_last_(), + __om_(0), + __cm_(0), + __owns_eb_(false), + __owns_ib_(false), + __always_noconv_(false) +{ + if (has_facet >(this->getloc())) + { + __cv_ = &use_facet >(this->getloc()); + __always_noconv_ = __cv_->always_noconv(); + } + setbuf(0, 4096); +} + +#ifndef _LIBCPP_CXX03_LANG + +template +basic_filebuf<_CharT, _Traits>::basic_filebuf(basic_filebuf&& __rhs) + : basic_streambuf<_CharT, _Traits>(__rhs) +{ + if (__rhs.__extbuf_ == __rhs.__extbuf_min_) + { + __extbuf_ = __extbuf_min_; + __extbufnext_ = __extbuf_ + (__rhs.__extbufnext_ - __rhs.__extbuf_); + __extbufend_ = __extbuf_ + (__rhs.__extbufend_ - __rhs.__extbuf_); + } + else + { + __extbuf_ = __rhs.__extbuf_; + __extbufnext_ = __rhs.__extbufnext_; + __extbufend_ = __rhs.__extbufend_; + } + __ebs_ = __rhs.__ebs_; + __intbuf_ = __rhs.__intbuf_; + __ibs_ = __rhs.__ibs_; + __file_ = __rhs.__file_; + __cv_ = __rhs.__cv_; + __st_ = __rhs.__st_; + __st_last_ = __rhs.__st_last_; + __om_ = __rhs.__om_; + __cm_ = __rhs.__cm_; + __owns_eb_ = __rhs.__owns_eb_; + __owns_ib_ = __rhs.__owns_ib_; + __always_noconv_ = __rhs.__always_noconv_; + if (__rhs.pbase()) + { + if (__rhs.pbase() == __rhs.__intbuf_) + this->setp(__intbuf_, __intbuf_ + (__rhs. epptr() - __rhs.pbase())); + else + this->setp((char_type*)__extbuf_, + (char_type*)__extbuf_ + (__rhs. epptr() - __rhs.pbase())); + this->__pbump(__rhs. pptr() - __rhs.pbase()); + } + else if (__rhs.eback()) + { + if (__rhs.eback() == __rhs.__intbuf_) + this->setg(__intbuf_, __intbuf_ + (__rhs.gptr() - __rhs.eback()), + __intbuf_ + (__rhs.egptr() - __rhs.eback())); + else + this->setg((char_type*)__extbuf_, + (char_type*)__extbuf_ + (__rhs.gptr() - __rhs.eback()), + (char_type*)__extbuf_ + (__rhs.egptr() - __rhs.eback())); + } + __rhs.__extbuf_ = 0; + __rhs.__extbufnext_ = 0; + __rhs.__extbufend_ = 0; + __rhs.__ebs_ = 0; + __rhs.__intbuf_ = 0; + __rhs.__ibs_ = 0; + __rhs.__file_ = 0; + __rhs.__st_ = state_type(); + __rhs.__st_last_ = state_type(); + __rhs.__om_ = 0; + __rhs.__cm_ = 0; + __rhs.__owns_eb_ = false; + __rhs.__owns_ib_ = false; + __rhs.setg(0, 0, 0); + __rhs.setp(0, 0); +} + +template +inline +basic_filebuf<_CharT, _Traits>& +basic_filebuf<_CharT, _Traits>::operator=(basic_filebuf&& __rhs) +{ + close(); + swap(__rhs); + return *this; +} + +#endif // _LIBCPP_CXX03_LANG + +template +basic_filebuf<_CharT, _Traits>::~basic_filebuf() +{ +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + close(); +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + } +#endif // _LIBCPP_NO_EXCEPTIONS + if (__owns_eb_) + delete [] __extbuf_; + if (__owns_ib_) + delete [] __intbuf_; +} + +template +void +basic_filebuf<_CharT, _Traits>::swap(basic_filebuf& __rhs) +{ + basic_streambuf::swap(__rhs); + if (__extbuf_ != __extbuf_min_ && __rhs.__extbuf_ != __rhs.__extbuf_min_) + { + _VSTD::swap(__extbuf_, __rhs.__extbuf_); + _VSTD::swap(__extbufnext_, __rhs.__extbufnext_); + _VSTD::swap(__extbufend_, __rhs.__extbufend_); + } + else + { + ptrdiff_t __ln = __extbufnext_ - __extbuf_; + ptrdiff_t __le = __extbufend_ - __extbuf_; + ptrdiff_t __rn = __rhs.__extbufnext_ - __rhs.__extbuf_; + ptrdiff_t __re = __rhs.__extbufend_ - __rhs.__extbuf_; + if (__extbuf_ == __extbuf_min_ && __rhs.__extbuf_ != __rhs.__extbuf_min_) + { + __extbuf_ = __rhs.__extbuf_; + __rhs.__extbuf_ = __rhs.__extbuf_min_; + } + else if (__extbuf_ != __extbuf_min_ && __rhs.__extbuf_ == __rhs.__extbuf_min_) + { + __rhs.__extbuf_ = __extbuf_; + __extbuf_ = __extbuf_min_; + } + __extbufnext_ = __extbuf_ + __rn; + __extbufend_ = __extbuf_ + __re; + __rhs.__extbufnext_ = __rhs.__extbuf_ + __ln; + __rhs.__extbufend_ = __rhs.__extbuf_ + __le; + } + _VSTD::swap(__ebs_, __rhs.__ebs_); + _VSTD::swap(__intbuf_, __rhs.__intbuf_); + _VSTD::swap(__ibs_, __rhs.__ibs_); + _VSTD::swap(__file_, __rhs.__file_); + _VSTD::swap(__cv_, __rhs.__cv_); + _VSTD::swap(__st_, __rhs.__st_); + _VSTD::swap(__st_last_, __rhs.__st_last_); + _VSTD::swap(__om_, __rhs.__om_); + _VSTD::swap(__cm_, __rhs.__cm_); + _VSTD::swap(__owns_eb_, __rhs.__owns_eb_); + _VSTD::swap(__owns_ib_, __rhs.__owns_ib_); + _VSTD::swap(__always_noconv_, __rhs.__always_noconv_); + if (this->eback() == (char_type*)__rhs.__extbuf_min_) + { + ptrdiff_t __n = this->gptr() - this->eback(); + ptrdiff_t __e = this->egptr() - this->eback(); + this->setg((char_type*)__extbuf_min_, + (char_type*)__extbuf_min_ + __n, + (char_type*)__extbuf_min_ + __e); + } + else if (this->pbase() == (char_type*)__rhs.__extbuf_min_) + { + ptrdiff_t __n = this->pptr() - this->pbase(); + ptrdiff_t __e = this->epptr() - this->pbase(); + this->setp((char_type*)__extbuf_min_, + (char_type*)__extbuf_min_ + __e); + this->__pbump(__n); + } + if (__rhs.eback() == (char_type*)__extbuf_min_) + { + ptrdiff_t __n = __rhs.gptr() - __rhs.eback(); + ptrdiff_t __e = __rhs.egptr() - __rhs.eback(); + __rhs.setg((char_type*)__rhs.__extbuf_min_, + (char_type*)__rhs.__extbuf_min_ + __n, + (char_type*)__rhs.__extbuf_min_ + __e); + } + else if (__rhs.pbase() == (char_type*)__extbuf_min_) + { + ptrdiff_t __n = __rhs.pptr() - __rhs.pbase(); + ptrdiff_t __e = __rhs.epptr() - __rhs.pbase(); + __rhs.setp((char_type*)__rhs.__extbuf_min_, + (char_type*)__rhs.__extbuf_min_ + __e); + __rhs.__pbump(__n); + } +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +swap(basic_filebuf<_CharT, _Traits>& __x, basic_filebuf<_CharT, _Traits>& __y) +{ + __x.swap(__y); +} + +template +inline +bool +basic_filebuf<_CharT, _Traits>::is_open() const +{ + return __file_ != 0; +} + +template +const char* basic_filebuf<_CharT, _Traits>::__make_mdstring( + ios_base::openmode __mode) _NOEXCEPT { + switch (__mode & ~ios_base::ate) { + case ios_base::out: + case ios_base::out | ios_base::trunc: + return "w" _LIBCPP_FOPEN_CLOEXEC_MODE; + case ios_base::out | ios_base::app: + case ios_base::app: + return "a" _LIBCPP_FOPEN_CLOEXEC_MODE; + case ios_base::in: + return "r" _LIBCPP_FOPEN_CLOEXEC_MODE; + case ios_base::in | ios_base::out: + return "r+" _LIBCPP_FOPEN_CLOEXEC_MODE; + case ios_base::in | ios_base::out | ios_base::trunc: + return "w+" _LIBCPP_FOPEN_CLOEXEC_MODE; + case ios_base::in | ios_base::out | ios_base::app: + case ios_base::in | ios_base::app: + return "a+" _LIBCPP_FOPEN_CLOEXEC_MODE; + case ios_base::out | ios_base::binary: + case ios_base::out | ios_base::trunc | ios_base::binary: + return "wb" _LIBCPP_FOPEN_CLOEXEC_MODE; + case ios_base::out | ios_base::app | ios_base::binary: + case ios_base::app | ios_base::binary: + return "ab" _LIBCPP_FOPEN_CLOEXEC_MODE; + case ios_base::in | ios_base::binary: + return "rb" _LIBCPP_FOPEN_CLOEXEC_MODE; + case ios_base::in | ios_base::out | ios_base::binary: + return "r+b" _LIBCPP_FOPEN_CLOEXEC_MODE; + case ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary: + return "w+b" _LIBCPP_FOPEN_CLOEXEC_MODE; + case ios_base::in | ios_base::out | ios_base::app | ios_base::binary: + case ios_base::in | ios_base::app | ios_base::binary: + return "a+b" _LIBCPP_FOPEN_CLOEXEC_MODE; + default: + return nullptr; + } + _LIBCPP_UNREACHABLE(); +} + +#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE +template +basic_filebuf<_CharT, _Traits>* +basic_filebuf<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode) +{ + basic_filebuf<_CharT, _Traits>* __rt = 0; + if (__file_ == 0) + { + if (const char* __mdstr = __make_mdstring(__mode)) { + __rt = this; + __file_ = fopen(__s, __mdstr); + if (__file_) { + __om_ = __mode; + if (__mode & ios_base::ate) { + if (fseek(__file_, 0, SEEK_END)) { + fclose(__file_); + __file_ = 0; + __rt = 0; + } + } + } else + __rt = 0; + } + } + return __rt; +} + +template +_LIBCPP_INLINE_VISIBILITY basic_filebuf<_CharT, _Traits>* +basic_filebuf<_CharT, _Traits>::__open(int __fd, ios_base::openmode __mode) { + basic_filebuf<_CharT, _Traits>* __rt = 0; + if (__file_ == 0) { + if (const char* __mdstr = __make_mdstring(__mode)) { + __rt = this; + __file_ = fdopen(__fd, __mdstr); + if (__file_) { + __om_ = __mode; + if (__mode & ios_base::ate) { + if (fseek(__file_, 0, SEEK_END)) { + fclose(__file_); + __file_ = 0; + __rt = 0; + } + } + } else + __rt = 0; + } + } + return __rt; +} + +#ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR +// This is basically the same as the char* overload except that it uses _wfopen +// and long mode strings. +template +basic_filebuf<_CharT, _Traits>* +basic_filebuf<_CharT, _Traits>::open(const wchar_t* __s, ios_base::openmode __mode) +{ + basic_filebuf<_CharT, _Traits>* __rt = 0; + if (__file_ == 0) + { + __rt = this; + const wchar_t* __mdstr; + switch (__mode & ~ios_base::ate) + { + case ios_base::out: + case ios_base::out | ios_base::trunc: + __mdstr = L"w"; + break; + case ios_base::out | ios_base::app: + case ios_base::app: + __mdstr = L"a"; + break; + case ios_base::in: + __mdstr = L"r"; + break; + case ios_base::in | ios_base::out: + __mdstr = L"r+"; + break; + case ios_base::in | ios_base::out | ios_base::trunc: + __mdstr = L"w+"; + break; + case ios_base::in | ios_base::out | ios_base::app: + case ios_base::in | ios_base::app: + __mdstr = L"a+"; + break; + case ios_base::out | ios_base::binary: + case ios_base::out | ios_base::trunc | ios_base::binary: + __mdstr = L"wb"; + break; + case ios_base::out | ios_base::app | ios_base::binary: + case ios_base::app | ios_base::binary: + __mdstr = L"ab"; + break; + case ios_base::in | ios_base::binary: + __mdstr = L"rb"; + break; + case ios_base::in | ios_base::out | ios_base::binary: + __mdstr = L"r+b"; + break; + case ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary: + __mdstr = L"w+b"; + break; + case ios_base::in | ios_base::out | ios_base::app | ios_base::binary: + case ios_base::in | ios_base::app | ios_base::binary: + __mdstr = L"a+b"; + break; + default: + __rt = 0; + break; + } + if (__rt) + { + __file_ = _wfopen(__s, __mdstr); + if (__file_) + { + __om_ = __mode; + if (__mode & ios_base::ate) + { + if (fseek(__file_, 0, SEEK_END)) + { + fclose(__file_); + __file_ = 0; + __rt = 0; + } + } + } + else + __rt = 0; + } + } + return __rt; +} +#endif + +template +inline +basic_filebuf<_CharT, _Traits>* +basic_filebuf<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mode) +{ + return open(__s.c_str(), __mode); +} +#endif + +template +basic_filebuf<_CharT, _Traits>* +basic_filebuf<_CharT, _Traits>::close() +{ + basic_filebuf<_CharT, _Traits>* __rt = 0; + if (__file_) + { + __rt = this; + unique_ptr __h(__file_, fclose); + if (sync()) + __rt = 0; + if (fclose(__h.release())) + __rt = 0; + __file_ = 0; + setbuf(0, 0); + } + return __rt; +} + +template +typename basic_filebuf<_CharT, _Traits>::int_type +basic_filebuf<_CharT, _Traits>::underflow() +{ + if (__file_ == 0) + return traits_type::eof(); + bool __initial = __read_mode(); + char_type __1buf; + if (this->gptr() == 0) + this->setg(&__1buf, &__1buf+1, &__1buf+1); + const size_t __unget_sz = __initial ? 0 : min((this->egptr() - this->eback()) / 2, 4); + int_type __c = traits_type::eof(); + if (this->gptr() == this->egptr()) + { + memmove(this->eback(), this->egptr() - __unget_sz, __unget_sz * sizeof(char_type)); + if (__always_noconv_) + { + size_t __nmemb = static_cast(this->egptr() - this->eback() - __unget_sz); + __nmemb = fread(this->eback() + __unget_sz, 1, __nmemb, __file_); + if (__nmemb != 0) + { + this->setg(this->eback(), + this->eback() + __unget_sz, + this->eback() + __unget_sz + __nmemb); + __c = traits_type::to_int_type(*this->gptr()); + } + } + else + { + _LIBCPP_ASSERT ( !(__extbufnext_ == NULL && (__extbufend_ != __extbufnext_)), "underflow moving from NULL" ); + if (__extbufend_ != __extbufnext_) + memmove(__extbuf_, __extbufnext_, __extbufend_ - __extbufnext_); + __extbufnext_ = __extbuf_ + (__extbufend_ - __extbufnext_); + __extbufend_ = __extbuf_ + (__extbuf_ == __extbuf_min_ ? sizeof(__extbuf_min_) : __ebs_); + size_t __nmemb = _VSTD::min(static_cast(__ibs_ - __unget_sz), + static_cast(__extbufend_ - __extbufnext_)); + codecvt_base::result __r; + __st_last_ = __st_; + size_t __nr = fread((void*) const_cast(__extbufnext_), 1, __nmemb, __file_); + if (__nr != 0) + { + if (!__cv_) + __throw_bad_cast(); + + __extbufend_ = __extbufnext_ + __nr; + char_type* __inext; + __r = __cv_->in(__st_, __extbuf_, __extbufend_, __extbufnext_, + this->eback() + __unget_sz, + this->eback() + __ibs_, __inext); + if (__r == codecvt_base::noconv) + { + this->setg((char_type*)__extbuf_, (char_type*)__extbuf_, + (char_type*)const_cast(__extbufend_)); + __c = traits_type::to_int_type(*this->gptr()); + } + else if (__inext != this->eback() + __unget_sz) + { + this->setg(this->eback(), this->eback() + __unget_sz, __inext); + __c = traits_type::to_int_type(*this->gptr()); + } + } + } + } + else + __c = traits_type::to_int_type(*this->gptr()); + if (this->eback() == &__1buf) + this->setg(0, 0, 0); + return __c; +} + +template +typename basic_filebuf<_CharT, _Traits>::int_type +basic_filebuf<_CharT, _Traits>::pbackfail(int_type __c) +{ + if (__file_ && this->eback() < this->gptr()) + { + if (traits_type::eq_int_type(__c, traits_type::eof())) + { + this->gbump(-1); + return traits_type::not_eof(__c); + } + if ((__om_ & ios_base::out) || + traits_type::eq(traits_type::to_char_type(__c), this->gptr()[-1])) + { + this->gbump(-1); + *this->gptr() = traits_type::to_char_type(__c); + return __c; + } + } + return traits_type::eof(); +} + +template +typename basic_filebuf<_CharT, _Traits>::int_type +basic_filebuf<_CharT, _Traits>::overflow(int_type __c) +{ + if (__file_ == 0) + return traits_type::eof(); + __write_mode(); + char_type __1buf; + char_type* __pb_save = this->pbase(); + char_type* __epb_save = this->epptr(); + if (!traits_type::eq_int_type(__c, traits_type::eof())) + { + if (this->pptr() == 0) + this->setp(&__1buf, &__1buf+1); + *this->pptr() = traits_type::to_char_type(__c); + this->pbump(1); + } + if (this->pptr() != this->pbase()) + { + if (__always_noconv_) + { + size_t __nmemb = static_cast(this->pptr() - this->pbase()); + if (fwrite(this->pbase(), sizeof(char_type), __nmemb, __file_) != __nmemb) + return traits_type::eof(); + } + else + { + char* __extbe = __extbuf_; + codecvt_base::result __r; + do + { + if (!__cv_) + __throw_bad_cast(); + + const char_type* __e; + __r = __cv_->out(__st_, this->pbase(), this->pptr(), __e, + __extbuf_, __extbuf_ + __ebs_, __extbe); + if (__e == this->pbase()) + return traits_type::eof(); + if (__r == codecvt_base::noconv) + { + size_t __nmemb = static_cast(this->pptr() - this->pbase()); + if (fwrite(this->pbase(), 1, __nmemb, __file_) != __nmemb) + return traits_type::eof(); + } + else if (__r == codecvt_base::ok || __r == codecvt_base::partial) + { + size_t __nmemb = static_cast(__extbe - __extbuf_); + if (fwrite(__extbuf_, 1, __nmemb, __file_) != __nmemb) + return traits_type::eof(); + if (__r == codecvt_base::partial) + { + this->setp(const_cast(__e), this->pptr()); + this->__pbump(this->epptr() - this->pbase()); + } + } + else + return traits_type::eof(); + } while (__r == codecvt_base::partial); + } + this->setp(__pb_save, __epb_save); + } + return traits_type::not_eof(__c); +} + +template +basic_streambuf<_CharT, _Traits>* +basic_filebuf<_CharT, _Traits>::setbuf(char_type* __s, streamsize __n) +{ + this->setg(0, 0, 0); + this->setp(0, 0); + if (__owns_eb_) + delete [] __extbuf_; + if (__owns_ib_) + delete [] __intbuf_; + __ebs_ = __n; + if (__ebs_ > sizeof(__extbuf_min_)) + { + if (__always_noconv_ && __s) + { + __extbuf_ = (char*)__s; + __owns_eb_ = false; + } + else + { + __extbuf_ = new char[__ebs_]; + __owns_eb_ = true; + } + } + else + { + __extbuf_ = __extbuf_min_; + __ebs_ = sizeof(__extbuf_min_); + __owns_eb_ = false; + } + if (!__always_noconv_) + { + __ibs_ = max(__n, sizeof(__extbuf_min_)); + if (__s && __ibs_ >= sizeof(__extbuf_min_)) + { + __intbuf_ = __s; + __owns_ib_ = false; + } + else + { + __intbuf_ = new char_type[__ibs_]; + __owns_ib_ = true; + } + } + else + { + __ibs_ = 0; + __intbuf_ = 0; + __owns_ib_ = false; + } + return this; +} + +template +typename basic_filebuf<_CharT, _Traits>::pos_type +basic_filebuf<_CharT, _Traits>::seekoff(off_type __off, ios_base::seekdir __way, + ios_base::openmode) +{ + if (!__cv_) + __throw_bad_cast(); + + int __width = __cv_->encoding(); + if (__file_ == 0 || (__width <= 0 && __off != 0) || sync()) + return pos_type(off_type(-1)); + // __width > 0 || __off == 0 + int __whence; + switch (__way) + { + case ios_base::beg: + __whence = SEEK_SET; + break; + case ios_base::cur: + __whence = SEEK_CUR; + break; + case ios_base::end: + __whence = SEEK_END; + break; + default: + return pos_type(off_type(-1)); + } +#if defined(_LIBCPP_HAS_NO_OFF_T_FUNCTIONS) + if (fseek(__file_, __width > 0 ? __width * __off : 0, __whence)) + return pos_type(off_type(-1)); + pos_type __r = ftell(__file_); +#else + if (fseeko(__file_, __width > 0 ? __width * __off : 0, __whence)) + return pos_type(off_type(-1)); + pos_type __r = ftello(__file_); +#endif + __r.state(__st_); + return __r; +} + +template +typename basic_filebuf<_CharT, _Traits>::pos_type +basic_filebuf<_CharT, _Traits>::seekpos(pos_type __sp, ios_base::openmode) +{ + if (__file_ == 0 || sync()) + return pos_type(off_type(-1)); +#if defined(_LIBCPP_HAS_NO_OFF_T_FUNCTIONS) + if (fseek(__file_, __sp, SEEK_SET)) + return pos_type(off_type(-1)); +#else + if (fseeko(__file_, __sp, SEEK_SET)) + return pos_type(off_type(-1)); +#endif + __st_ = __sp.state(); + return __sp; +} + +template +int +basic_filebuf<_CharT, _Traits>::sync() +{ + if (__file_ == 0) + return 0; + if (!__cv_) + __throw_bad_cast(); + + if (__cm_ & ios_base::out) + { + if (this->pptr() != this->pbase()) + if (overflow() == traits_type::eof()) + return -1; + codecvt_base::result __r; + do + { + char* __extbe; + __r = __cv_->unshift(__st_, __extbuf_, __extbuf_ + __ebs_, __extbe); + size_t __nmemb = static_cast(__extbe - __extbuf_); + if (fwrite(__extbuf_, 1, __nmemb, __file_) != __nmemb) + return -1; + } while (__r == codecvt_base::partial); + if (__r == codecvt_base::error) + return -1; + if (fflush(__file_)) + return -1; + } + else if (__cm_ & ios_base::in) + { + off_type __c; + state_type __state = __st_last_; + bool __update_st = false; + if (__always_noconv_) + __c = this->egptr() - this->gptr(); + else + { + int __width = __cv_->encoding(); + __c = __extbufend_ - __extbufnext_; + if (__width > 0) + __c += __width * (this->egptr() - this->gptr()); + else + { + if (this->gptr() != this->egptr()) + { + const int __off = __cv_->length(__state, __extbuf_, + __extbufnext_, + this->gptr() - this->eback()); + __c += __extbufnext_ - __extbuf_ - __off; + __update_st = true; + } + } + } +#if defined(_LIBCPP_HAS_NO_OFF_T_FUNCTIONS) + if (fseek(__file_, -__c, SEEK_CUR)) + return -1; +#else + if (fseeko(__file_, -__c, SEEK_CUR)) + return -1; +#endif + if (__update_st) + __st_ = __state; + __extbufnext_ = __extbufend_ = __extbuf_; + this->setg(0, 0, 0); + __cm_ = 0; + } + return 0; +} + +template +void +basic_filebuf<_CharT, _Traits>::imbue(const locale& __loc) +{ + sync(); + __cv_ = &use_facet >(__loc); + bool __old_anc = __always_noconv_; + __always_noconv_ = __cv_->always_noconv(); + if (__old_anc != __always_noconv_) + { + this->setg(0, 0, 0); + this->setp(0, 0); + // invariant, char_type is char, else we couldn't get here + if (__always_noconv_) // need to dump __intbuf_ + { + if (__owns_eb_) + delete [] __extbuf_; + __owns_eb_ = __owns_ib_; + __ebs_ = __ibs_; + __extbuf_ = (char*)__intbuf_; + __ibs_ = 0; + __intbuf_ = 0; + __owns_ib_ = false; + } + else // need to obtain an __intbuf_. + { // If __extbuf_ is user-supplied, use it, else new __intbuf_ + if (!__owns_eb_ && __extbuf_ != __extbuf_min_) + { + __ibs_ = __ebs_; + __intbuf_ = (char_type*)__extbuf_; + __owns_ib_ = false; + __extbuf_ = new char[__ebs_]; + __owns_eb_ = true; + } + else + { + __ibs_ = __ebs_; + __intbuf_ = new char_type[__ibs_]; + __owns_ib_ = true; + } + } + } +} + +template +bool +basic_filebuf<_CharT, _Traits>::__read_mode() +{ + if (!(__cm_ & ios_base::in)) + { + this->setp(0, 0); + if (__always_noconv_) + this->setg((char_type*)__extbuf_, + (char_type*)__extbuf_ + __ebs_, + (char_type*)__extbuf_ + __ebs_); + else + this->setg(__intbuf_, __intbuf_ + __ibs_, __intbuf_ + __ibs_); + __cm_ = ios_base::in; + return true; + } + return false; +} + +template +void +basic_filebuf<_CharT, _Traits>::__write_mode() +{ + if (!(__cm_ & ios_base::out)) + { + this->setg(0, 0, 0); + if (__ebs_ > sizeof(__extbuf_min_)) + { + if (__always_noconv_) + this->setp((char_type*)__extbuf_, + (char_type*)__extbuf_ + (__ebs_ - 1)); + else + this->setp(__intbuf_, __intbuf_ + (__ibs_ - 1)); + } + else + this->setp(0, 0); + __cm_ = ios_base::out; + } +} + +// basic_ifstream + +template +class _LIBCPP_TEMPLATE_VIS basic_ifstream + : public basic_istream<_CharT, _Traits> +{ +public: + typedef _CharT char_type; + typedef _Traits traits_type; + typedef typename traits_type::int_type int_type; + typedef typename traits_type::pos_type pos_type; + typedef typename traits_type::off_type off_type; + + _LIBCPP_INLINE_VISIBILITY + basic_ifstream(); +#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE + _LIBCPP_INLINE_VISIBILITY + explicit basic_ifstream(const char* __s, ios_base::openmode __mode = ios_base::in); +#ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR + _LIBCPP_INLINE_VISIBILITY + explicit basic_ifstream(const wchar_t* __s, ios_base::openmode __mode = ios_base::in); +#endif + _LIBCPP_INLINE_VISIBILITY + explicit basic_ifstream(const string& __s, ios_base::openmode __mode = ios_base::in); +#if _LIBCPP_STD_VER >= 17 + _LIBCPP_AVAILABILITY_FILESYSTEM _LIBCPP_INLINE_VISIBILITY + explicit basic_ifstream(const filesystem::path& __p, ios_base::openmode __mode = ios_base::in) + : basic_ifstream(__p.c_str(), __mode) {} +#endif // _LIBCPP_STD_VER >= 17 +#endif +#ifndef _LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY + basic_ifstream(basic_ifstream&& __rhs); + + _LIBCPP_INLINE_VISIBILITY + basic_ifstream& operator=(basic_ifstream&& __rhs); +#endif + _LIBCPP_INLINE_VISIBILITY + void swap(basic_ifstream& __rhs); + + _LIBCPP_INLINE_VISIBILITY + basic_filebuf* rdbuf() const; + _LIBCPP_INLINE_VISIBILITY + bool is_open() const; +#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE + void open(const char* __s, ios_base::openmode __mode = ios_base::in); +#ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR + void open(const wchar_t* __s, ios_base::openmode __mode = ios_base::in); +#endif + void open(const string& __s, ios_base::openmode __mode = ios_base::in); +#if _LIBCPP_STD_VER >= 17 + _LIBCPP_AVAILABILITY_FILESYSTEM _LIBCPP_INLINE_VISIBILITY + void open(const filesystem::path& __p, + ios_base::openmode __mode = ios_base::in) { + return open(__p.c_str(), __mode); + } +#endif // _LIBCPP_STD_VER >= 17 + + _LIBCPP_INLINE_VISIBILITY + void __open(int __fd, ios_base::openmode __mode); +#endif + _LIBCPP_INLINE_VISIBILITY + void close(); + +private: + basic_filebuf __sb_; +}; + +template +inline +basic_ifstream<_CharT, _Traits>::basic_ifstream() + : basic_istream(&__sb_) +{ +} + +#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE +template +inline +basic_ifstream<_CharT, _Traits>::basic_ifstream(const char* __s, ios_base::openmode __mode) + : basic_istream(&__sb_) +{ + if (__sb_.open(__s, __mode | ios_base::in) == 0) + this->setstate(ios_base::failbit); +} + +#ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR +template +inline +basic_ifstream<_CharT, _Traits>::basic_ifstream(const wchar_t* __s, ios_base::openmode __mode) + : basic_istream(&__sb_) +{ + if (__sb_.open(__s, __mode | ios_base::in) == 0) + this->setstate(ios_base::failbit); +} +#endif + +template +inline +basic_ifstream<_CharT, _Traits>::basic_ifstream(const string& __s, ios_base::openmode __mode) + : basic_istream(&__sb_) +{ + if (__sb_.open(__s, __mode | ios_base::in) == 0) + this->setstate(ios_base::failbit); +} +#endif + +#ifndef _LIBCPP_CXX03_LANG + +template +inline +basic_ifstream<_CharT, _Traits>::basic_ifstream(basic_ifstream&& __rhs) + : basic_istream(_VSTD::move(__rhs)), + __sb_(_VSTD::move(__rhs.__sb_)) +{ + this->set_rdbuf(&__sb_); +} + +template +inline +basic_ifstream<_CharT, _Traits>& +basic_ifstream<_CharT, _Traits>::operator=(basic_ifstream&& __rhs) +{ + basic_istream::operator=(_VSTD::move(__rhs)); + __sb_ = _VSTD::move(__rhs.__sb_); + return *this; +} + +#endif // _LIBCPP_CXX03_LANG + +template +inline +void +basic_ifstream<_CharT, _Traits>::swap(basic_ifstream& __rhs) +{ + basic_istream::swap(__rhs); + __sb_.swap(__rhs.__sb_); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +swap(basic_ifstream<_CharT, _Traits>& __x, basic_ifstream<_CharT, _Traits>& __y) +{ + __x.swap(__y); +} + +template +inline +basic_filebuf<_CharT, _Traits>* +basic_ifstream<_CharT, _Traits>::rdbuf() const +{ + return const_cast*>(&__sb_); +} + +template +inline +bool +basic_ifstream<_CharT, _Traits>::is_open() const +{ + return __sb_.is_open(); +} + +#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE +template +void +basic_ifstream<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode) +{ + if (__sb_.open(__s, __mode | ios_base::in)) + this->clear(); + else + this->setstate(ios_base::failbit); +} + +#ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR +template +void +basic_ifstream<_CharT, _Traits>::open(const wchar_t* __s, ios_base::openmode __mode) +{ + if (__sb_.open(__s, __mode | ios_base::in)) + this->clear(); + else + this->setstate(ios_base::failbit); +} +#endif + +template +void +basic_ifstream<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mode) +{ + if (__sb_.open(__s, __mode | ios_base::in)) + this->clear(); + else + this->setstate(ios_base::failbit); +} + +template +void basic_ifstream<_CharT, _Traits>::__open(int __fd, + ios_base::openmode __mode) { + if (__sb_.__open(__fd, __mode | ios_base::in)) + this->clear(); + else + this->setstate(ios_base::failbit); +} +#endif + +template +inline +void +basic_ifstream<_CharT, _Traits>::close() +{ + if (__sb_.close() == 0) + this->setstate(ios_base::failbit); +} + +// basic_ofstream + +template +class _LIBCPP_TEMPLATE_VIS basic_ofstream + : public basic_ostream<_CharT, _Traits> +{ +public: + typedef _CharT char_type; + typedef _Traits traits_type; + typedef typename traits_type::int_type int_type; + typedef typename traits_type::pos_type pos_type; + typedef typename traits_type::off_type off_type; + + _LIBCPP_INLINE_VISIBILITY + basic_ofstream(); + _LIBCPP_INLINE_VISIBILITY + explicit basic_ofstream(const char* __s, ios_base::openmode __mode = ios_base::out); +#ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR + _LIBCPP_INLINE_VISIBILITY + explicit basic_ofstream(const wchar_t* __s, ios_base::openmode __mode = ios_base::out); +#endif + _LIBCPP_INLINE_VISIBILITY + explicit basic_ofstream(const string& __s, ios_base::openmode __mode = ios_base::out); + +#if _LIBCPP_STD_VER >= 17 + _LIBCPP_AVAILABILITY_FILESYSTEM _LIBCPP_INLINE_VISIBILITY + explicit basic_ofstream(const filesystem::path& __p, ios_base::openmode __mode = ios_base::out) + : basic_ofstream(__p.c_str(), __mode) {} +#endif // _LIBCPP_STD_VER >= 17 + +#ifndef _LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY + basic_ofstream(basic_ofstream&& __rhs); + + _LIBCPP_INLINE_VISIBILITY + basic_ofstream& operator=(basic_ofstream&& __rhs); +#endif + _LIBCPP_INLINE_VISIBILITY + void swap(basic_ofstream& __rhs); + + _LIBCPP_INLINE_VISIBILITY + basic_filebuf* rdbuf() const; + _LIBCPP_INLINE_VISIBILITY + bool is_open() const; +#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE + void open(const char* __s, ios_base::openmode __mode = ios_base::out); +#ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR + void open(const wchar_t* __s, ios_base::openmode __mode = ios_base::out); +#endif + void open(const string& __s, ios_base::openmode __mode = ios_base::out); + +#if _LIBCPP_STD_VER >= 17 + _LIBCPP_AVAILABILITY_FILESYSTEM _LIBCPP_INLINE_VISIBILITY + void open(const filesystem::path& __p, ios_base::openmode __mode = ios_base::out) + { return open(__p.c_str(), __mode); } +#endif // _LIBCPP_STD_VER >= 17 + + _LIBCPP_INLINE_VISIBILITY + void __open(int __fd, ios_base::openmode __mode); +#endif + _LIBCPP_INLINE_VISIBILITY + void close(); + +private: + basic_filebuf __sb_; +}; + +template +inline +basic_ofstream<_CharT, _Traits>::basic_ofstream() + : basic_ostream(&__sb_) +{ +} + +#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE +template +inline +basic_ofstream<_CharT, _Traits>::basic_ofstream(const char* __s, ios_base::openmode __mode) + : basic_ostream(&__sb_) +{ + if (__sb_.open(__s, __mode | ios_base::out) == 0) + this->setstate(ios_base::failbit); +} + +#ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR +template +inline +basic_ofstream<_CharT, _Traits>::basic_ofstream(const wchar_t* __s, ios_base::openmode __mode) + : basic_ostream(&__sb_) +{ + if (__sb_.open(__s, __mode | ios_base::out) == 0) + this->setstate(ios_base::failbit); +} +#endif + +template +inline +basic_ofstream<_CharT, _Traits>::basic_ofstream(const string& __s, ios_base::openmode __mode) + : basic_ostream(&__sb_) +{ + if (__sb_.open(__s, __mode | ios_base::out) == 0) + this->setstate(ios_base::failbit); +} +#endif + +#ifndef _LIBCPP_CXX03_LANG + +template +inline +basic_ofstream<_CharT, _Traits>::basic_ofstream(basic_ofstream&& __rhs) + : basic_ostream(_VSTD::move(__rhs)), + __sb_(_VSTD::move(__rhs.__sb_)) +{ + this->set_rdbuf(&__sb_); +} + +template +inline +basic_ofstream<_CharT, _Traits>& +basic_ofstream<_CharT, _Traits>::operator=(basic_ofstream&& __rhs) +{ + basic_ostream::operator=(_VSTD::move(__rhs)); + __sb_ = _VSTD::move(__rhs.__sb_); + return *this; +} + +#endif // _LIBCPP_CXX03_LANG + +template +inline +void +basic_ofstream<_CharT, _Traits>::swap(basic_ofstream& __rhs) +{ + basic_ostream::swap(__rhs); + __sb_.swap(__rhs.__sb_); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +swap(basic_ofstream<_CharT, _Traits>& __x, basic_ofstream<_CharT, _Traits>& __y) +{ + __x.swap(__y); +} + +template +inline +basic_filebuf<_CharT, _Traits>* +basic_ofstream<_CharT, _Traits>::rdbuf() const +{ + return const_cast*>(&__sb_); +} + +template +inline +bool +basic_ofstream<_CharT, _Traits>::is_open() const +{ + return __sb_.is_open(); +} + +#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE +template +void +basic_ofstream<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode) +{ + if (__sb_.open(__s, __mode | ios_base::out)) + this->clear(); + else + this->setstate(ios_base::failbit); +} + +#ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR +template +void +basic_ofstream<_CharT, _Traits>::open(const wchar_t* __s, ios_base::openmode __mode) +{ + if (__sb_.open(__s, __mode | ios_base::out)) + this->clear(); + else + this->setstate(ios_base::failbit); +} +#endif + +template +void +basic_ofstream<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mode) +{ + if (__sb_.open(__s, __mode | ios_base::out)) + this->clear(); + else + this->setstate(ios_base::failbit); +} + +template +void basic_ofstream<_CharT, _Traits>::__open(int __fd, + ios_base::openmode __mode) { + if (__sb_.__open(__fd, __mode | ios_base::out)) + this->clear(); + else + this->setstate(ios_base::failbit); +} +#endif + +template +inline +void +basic_ofstream<_CharT, _Traits>::close() +{ + if (__sb_.close() == 0) + this->setstate(ios_base::failbit); +} + +// basic_fstream + +template +class _LIBCPP_TEMPLATE_VIS basic_fstream + : public basic_iostream<_CharT, _Traits> +{ +public: + typedef _CharT char_type; + typedef _Traits traits_type; + typedef typename traits_type::int_type int_type; + typedef typename traits_type::pos_type pos_type; + typedef typename traits_type::off_type off_type; + + _LIBCPP_INLINE_VISIBILITY + basic_fstream(); +#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE + _LIBCPP_INLINE_VISIBILITY + explicit basic_fstream(const char* __s, ios_base::openmode __mode = ios_base::in | ios_base::out); +#ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR + _LIBCPP_INLINE_VISIBILITY + explicit basic_fstream(const wchar_t* __s, ios_base::openmode __mode = ios_base::in | ios_base::out); +#endif + _LIBCPP_INLINE_VISIBILITY + explicit basic_fstream(const string& __s, ios_base::openmode __mode = ios_base::in | ios_base::out); + +#if _LIBCPP_STD_VER >= 17 + _LIBCPP_AVAILABILITY_FILESYSTEM _LIBCPP_INLINE_VISIBILITY + explicit basic_fstream(const filesystem::path& __p, ios_base::openmode __mode = ios_base::in | ios_base::out) + : basic_fstream(__p.c_str(), __mode) {} +#endif // _LIBCPP_STD_VER >= 17 + +#endif +#ifndef _LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY + basic_fstream(basic_fstream&& __rhs); + + _LIBCPP_INLINE_VISIBILITY + basic_fstream& operator=(basic_fstream&& __rhs); +#endif + _LIBCPP_INLINE_VISIBILITY + void swap(basic_fstream& __rhs); + + _LIBCPP_INLINE_VISIBILITY + basic_filebuf* rdbuf() const; + _LIBCPP_INLINE_VISIBILITY + bool is_open() const; +#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE + void open(const char* __s, ios_base::openmode __mode = ios_base::in | ios_base::out); +#ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR + void open(const wchar_t* __s, ios_base::openmode __mode = ios_base::in | ios_base::out); +#endif + void open(const string& __s, ios_base::openmode __mode = ios_base::in | ios_base::out); + +#if _LIBCPP_STD_VER >= 17 + _LIBCPP_AVAILABILITY_FILESYSTEM _LIBCPP_INLINE_VISIBILITY + void open(const filesystem::path& __p, ios_base::openmode __mode = ios_base::in|ios_base::out) + { return open(__p.c_str(), __mode); } +#endif // _LIBCPP_STD_VER >= 17 + +#endif + _LIBCPP_INLINE_VISIBILITY + void close(); + +private: + basic_filebuf __sb_; +}; + +template +inline +basic_fstream<_CharT, _Traits>::basic_fstream() + : basic_iostream(&__sb_) +{ +} + +#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE +template +inline +basic_fstream<_CharT, _Traits>::basic_fstream(const char* __s, ios_base::openmode __mode) + : basic_iostream(&__sb_) +{ + if (__sb_.open(__s, __mode) == 0) + this->setstate(ios_base::failbit); +} + +#ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR +template +inline +basic_fstream<_CharT, _Traits>::basic_fstream(const wchar_t* __s, ios_base::openmode __mode) + : basic_iostream(&__sb_) +{ + if (__sb_.open(__s, __mode) == 0) + this->setstate(ios_base::failbit); +} +#endif + +template +inline +basic_fstream<_CharT, _Traits>::basic_fstream(const string& __s, ios_base::openmode __mode) + : basic_iostream(&__sb_) +{ + if (__sb_.open(__s, __mode) == 0) + this->setstate(ios_base::failbit); +} +#endif + +#ifndef _LIBCPP_CXX03_LANG + +template +inline +basic_fstream<_CharT, _Traits>::basic_fstream(basic_fstream&& __rhs) + : basic_iostream(_VSTD::move(__rhs)), + __sb_(_VSTD::move(__rhs.__sb_)) +{ + this->set_rdbuf(&__sb_); +} + +template +inline +basic_fstream<_CharT, _Traits>& +basic_fstream<_CharT, _Traits>::operator=(basic_fstream&& __rhs) +{ + basic_iostream::operator=(_VSTD::move(__rhs)); + __sb_ = _VSTD::move(__rhs.__sb_); + return *this; +} + +#endif // _LIBCPP_CXX03_LANG + +template +inline +void +basic_fstream<_CharT, _Traits>::swap(basic_fstream& __rhs) +{ + basic_iostream::swap(__rhs); + __sb_.swap(__rhs.__sb_); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +swap(basic_fstream<_CharT, _Traits>& __x, basic_fstream<_CharT, _Traits>& __y) +{ + __x.swap(__y); +} + +template +inline +basic_filebuf<_CharT, _Traits>* +basic_fstream<_CharT, _Traits>::rdbuf() const +{ + return const_cast*>(&__sb_); +} + +template +inline +bool +basic_fstream<_CharT, _Traits>::is_open() const +{ + return __sb_.is_open(); +} + +#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE +template +void +basic_fstream<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode) +{ + if (__sb_.open(__s, __mode)) + this->clear(); + else + this->setstate(ios_base::failbit); +} + +#ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR +template +void +basic_fstream<_CharT, _Traits>::open(const wchar_t* __s, ios_base::openmode __mode) +{ + if (__sb_.open(__s, __mode)) + this->clear(); + else + this->setstate(ios_base::failbit); +} +#endif + +template +void +basic_fstream<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mode) +{ + if (__sb_.open(__s, __mode)) + this->clear(); + else + this->setstate(ios_base::failbit); +} +#endif + +template +inline +void +basic_fstream<_CharT, _Traits>::close() +{ + if (__sb_.close() == 0) + this->setstate(ios_base::failbit); +} + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP_FSTREAM diff --git a/third_party/libcxx/iomanip b/third_party/libcxx/iomanip new file mode 100644 index 000000000..d9b9b64f6 --- /dev/null +++ b/third_party/libcxx/iomanip @@ -0,0 +1,671 @@ +// -*- C++ -*- +// clang-format off +//===--------------------------- iomanip ----------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_IOMANIP +#define _LIBCPP_IOMANIP + +/* + iomanip synopsis + +namespace std { + +// types T1, T2, ... are unspecified implementation types +T1 resetiosflags(ios_base::fmtflags mask); +T2 setiosflags (ios_base::fmtflags mask); +T3 setbase(int base); +template T4 setfill(charT c); +T5 setprecision(int n); +T6 setw(int n); +template T7 get_money(moneyT& mon, bool intl = false); +template T8 put_money(const moneyT& mon, bool intl = false); +template T9 get_time(struct tm* tmb, const charT* fmt); +template T10 put_time(const struct tm* tmb, const charT* fmt); + +template + T11 quoted(const charT* s, charT delim=charT('"'), charT escape=charT('\\')); // C++14 + +template + T12 quoted(const basic_string& s, + charT delim=charT('"'), charT escape=charT('\\')); // C++14 + +template + T13 quoted(basic_string& s, + charT delim=charT('"'), charT escape=charT('\\')); // C++14 + +} // std + +*/ + +#include "third_party/libcxx/__config" +#include "third_party/libcxx/__string" +#include "third_party/libcxx/istream" +#include "third_party/libcxx/version" + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +// resetiosflags + +class __iom_t1 +{ + ios_base::fmtflags __mask_; +public: + _LIBCPP_INLINE_VISIBILITY + explicit __iom_t1(ios_base::fmtflags __m) : __mask_(__m) {} + + template + friend + _LIBCPP_INLINE_VISIBILITY + basic_istream<_CharT, _Traits>& + operator>>(basic_istream<_CharT, _Traits>& __is, const __iom_t1& __x) + { + __is.unsetf(__x.__mask_); + return __is; + } + + template + friend + _LIBCPP_INLINE_VISIBILITY + basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>& __os, const __iom_t1& __x) + { + __os.unsetf(__x.__mask_); + return __os; + } +}; + +inline _LIBCPP_INLINE_VISIBILITY +__iom_t1 +resetiosflags(ios_base::fmtflags __mask) +{ + return __iom_t1(__mask); +} + +// setiosflags + +class __iom_t2 +{ + ios_base::fmtflags __mask_; +public: + _LIBCPP_INLINE_VISIBILITY + explicit __iom_t2(ios_base::fmtflags __m) : __mask_(__m) {} + + template + friend + _LIBCPP_INLINE_VISIBILITY + basic_istream<_CharT, _Traits>& + operator>>(basic_istream<_CharT, _Traits>& __is, const __iom_t2& __x) + { + __is.setf(__x.__mask_); + return __is; + } + + template + friend + _LIBCPP_INLINE_VISIBILITY + basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>& __os, const __iom_t2& __x) + { + __os.setf(__x.__mask_); + return __os; + } +}; + +inline _LIBCPP_INLINE_VISIBILITY +__iom_t2 +setiosflags(ios_base::fmtflags __mask) +{ + return __iom_t2(__mask); +} + +// setbase + +class __iom_t3 +{ + int __base_; +public: + _LIBCPP_INLINE_VISIBILITY + explicit __iom_t3(int __b) : __base_(__b) {} + + template + friend + _LIBCPP_INLINE_VISIBILITY + basic_istream<_CharT, _Traits>& + operator>>(basic_istream<_CharT, _Traits>& __is, const __iom_t3& __x) + { + __is.setf(__x.__base_ == 8 ? ios_base::oct : + __x.__base_ == 10 ? ios_base::dec : + __x.__base_ == 16 ? ios_base::hex : + ios_base::fmtflags(0), ios_base::basefield); + return __is; + } + + template + friend + _LIBCPP_INLINE_VISIBILITY + basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>& __os, const __iom_t3& __x) + { + __os.setf(__x.__base_ == 8 ? ios_base::oct : + __x.__base_ == 10 ? ios_base::dec : + __x.__base_ == 16 ? ios_base::hex : + ios_base::fmtflags(0), ios_base::basefield); + return __os; + } +}; + +inline _LIBCPP_INLINE_VISIBILITY +__iom_t3 +setbase(int __base) +{ + return __iom_t3(__base); +} + +// setfill + +template +class __iom_t4 +{ + _CharT __fill_; +public: + _LIBCPP_INLINE_VISIBILITY + explicit __iom_t4(_CharT __c) : __fill_(__c) {} + + template + friend + _LIBCPP_INLINE_VISIBILITY + basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>& __os, const __iom_t4& __x) + { + __os.fill(__x.__fill_); + return __os; + } +}; + +template +inline _LIBCPP_INLINE_VISIBILITY +__iom_t4<_CharT> +setfill(_CharT __c) +{ + return __iom_t4<_CharT>(__c); +} + +// setprecision + +class __iom_t5 +{ + int __n_; +public: + _LIBCPP_INLINE_VISIBILITY + explicit __iom_t5(int __n) : __n_(__n) {} + + template + friend + _LIBCPP_INLINE_VISIBILITY + basic_istream<_CharT, _Traits>& + operator>>(basic_istream<_CharT, _Traits>& __is, const __iom_t5& __x) + { + __is.precision(__x.__n_); + return __is; + } + + template + friend + _LIBCPP_INLINE_VISIBILITY + basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>& __os, const __iom_t5& __x) + { + __os.precision(__x.__n_); + return __os; + } +}; + +inline _LIBCPP_INLINE_VISIBILITY +__iom_t5 +setprecision(int __n) +{ + return __iom_t5(__n); +} + +// setw + +class __iom_t6 +{ + int __n_; +public: + _LIBCPP_INLINE_VISIBILITY + explicit __iom_t6(int __n) : __n_(__n) {} + + template + friend + _LIBCPP_INLINE_VISIBILITY + basic_istream<_CharT, _Traits>& + operator>>(basic_istream<_CharT, _Traits>& __is, const __iom_t6& __x) + { + __is.width(__x.__n_); + return __is; + } + + template + friend + _LIBCPP_INLINE_VISIBILITY + basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>& __os, const __iom_t6& __x) + { + __os.width(__x.__n_); + return __os; + } +}; + +inline _LIBCPP_INLINE_VISIBILITY +__iom_t6 +setw(int __n) +{ + return __iom_t6(__n); +} + +// get_money + +template class __iom_t7; + +template +basic_istream<_CharT, _Traits>& +operator>>(basic_istream<_CharT, _Traits>& __is, const __iom_t7<_MoneyT>& __x); + +template +class __iom_t7 +{ + _MoneyT& __mon_; + bool __intl_; +public: + _LIBCPP_INLINE_VISIBILITY + __iom_t7(_MoneyT& __mon, bool __intl) + : __mon_(__mon), __intl_(__intl) {} + + template + friend + basic_istream<_CharT, _Traits>& + operator>>(basic_istream<_CharT, _Traits>& __is, const __iom_t7<_Mp>& __x); +}; + +template +basic_istream<_CharT, _Traits>& +operator>>(basic_istream<_CharT, _Traits>& __is, const __iom_t7<_MoneyT>& __x) +{ +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + typename basic_istream<_CharT, _Traits>::sentry __s(__is); + if (__s) + { + typedef istreambuf_iterator<_CharT, _Traits> _Ip; + typedef money_get<_CharT, _Ip> _Fp; + ios_base::iostate __err = ios_base::goodbit; + const _Fp& __mf = use_facet<_Fp>(__is.getloc()); + __mf.get(_Ip(__is), _Ip(), __x.__intl_, __is, __err, __x.__mon_); + __is.setstate(__err); + } +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + __is.__set_badbit_and_consider_rethrow(); + } +#endif // _LIBCPP_NO_EXCEPTIONS + return __is; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +__iom_t7<_MoneyT> +get_money(_MoneyT& __mon, bool __intl = false) +{ + return __iom_t7<_MoneyT>(__mon, __intl); +} + +// put_money + +template class __iom_t8; + +template +basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, const __iom_t8<_MoneyT>& __x); + +template +class __iom_t8 +{ + const _MoneyT& __mon_; + bool __intl_; +public: + _LIBCPP_INLINE_VISIBILITY + __iom_t8(const _MoneyT& __mon, bool __intl) + : __mon_(__mon), __intl_(__intl) {} + + template + friend + basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>& __os, const __iom_t8<_Mp>& __x); +}; + +template +basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, const __iom_t8<_MoneyT>& __x) +{ +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + typename basic_ostream<_CharT, _Traits>::sentry __s(__os); + if (__s) + { + typedef ostreambuf_iterator<_CharT, _Traits> _Op; + typedef money_put<_CharT, _Op> _Fp; + const _Fp& __mf = use_facet<_Fp>(__os.getloc()); + if (__mf.put(_Op(__os), __x.__intl_, __os, __os.fill(), __x.__mon_).failed()) + __os.setstate(ios_base::badbit); + } +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + __os.__set_badbit_and_consider_rethrow(); + } +#endif // _LIBCPP_NO_EXCEPTIONS + return __os; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +__iom_t8<_MoneyT> +put_money(const _MoneyT& __mon, bool __intl = false) +{ + return __iom_t8<_MoneyT>(__mon, __intl); +} + +// get_time + +template class __iom_t9; + +template +basic_istream<_CharT, _Traits>& +operator>>(basic_istream<_CharT, _Traits>& __is, const __iom_t9<_CharT>& __x); + +template +class __iom_t9 +{ + tm* __tm_; + const _CharT* __fmt_; +public: + _LIBCPP_INLINE_VISIBILITY + __iom_t9(tm* __tm, const _CharT* __fmt) + : __tm_(__tm), __fmt_(__fmt) {} + + template + friend + basic_istream<_Cp, _Traits>& + operator>>(basic_istream<_Cp, _Traits>& __is, const __iom_t9<_Cp>& __x); +}; + +template +basic_istream<_CharT, _Traits>& +operator>>(basic_istream<_CharT, _Traits>& __is, const __iom_t9<_CharT>& __x) +{ +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + typename basic_istream<_CharT, _Traits>::sentry __s(__is); + if (__s) + { + typedef istreambuf_iterator<_CharT, _Traits> _Ip; + typedef time_get<_CharT, _Ip> _Fp; + ios_base::iostate __err = ios_base::goodbit; + const _Fp& __tf = use_facet<_Fp>(__is.getloc()); + __tf.get(_Ip(__is), _Ip(), __is, __err, __x.__tm_, + __x.__fmt_, __x.__fmt_ + _Traits::length(__x.__fmt_)); + __is.setstate(__err); + } +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + __is.__set_badbit_and_consider_rethrow(); + } +#endif // _LIBCPP_NO_EXCEPTIONS + return __is; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +__iom_t9<_CharT> +get_time(tm* __tm, const _CharT* __fmt) +{ + return __iom_t9<_CharT>(__tm, __fmt); +} + +// put_time + +template class __iom_t10; + +template +basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, const __iom_t10<_CharT>& __x); + +template +class __iom_t10 +{ + const tm* __tm_; + const _CharT* __fmt_; +public: + _LIBCPP_INLINE_VISIBILITY + __iom_t10(const tm* __tm, const _CharT* __fmt) + : __tm_(__tm), __fmt_(__fmt) {} + + template + friend + basic_ostream<_Cp, _Traits>& + operator<<(basic_ostream<_Cp, _Traits>& __os, const __iom_t10<_Cp>& __x); +}; + +template +basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, const __iom_t10<_CharT>& __x) +{ +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + typename basic_ostream<_CharT, _Traits>::sentry __s(__os); + if (__s) + { + typedef ostreambuf_iterator<_CharT, _Traits> _Op; + typedef time_put<_CharT, _Op> _Fp; + const _Fp& __tf = use_facet<_Fp>(__os.getloc()); + if (__tf.put(_Op(__os), __os, __os.fill(), __x.__tm_, + __x.__fmt_, __x.__fmt_ + _Traits::length(__x.__fmt_)).failed()) + __os.setstate(ios_base::badbit); + } +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + __os.__set_badbit_and_consider_rethrow(); + } +#endif // _LIBCPP_NO_EXCEPTIONS + return __os; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +__iom_t10<_CharT> +put_time(const tm* __tm, const _CharT* __fmt) +{ + return __iom_t10<_CharT>(__tm, __fmt); +} + +template +std::basic_ostream<_CharT, _Traits> & +__quoted_output ( basic_ostream<_CharT, _Traits> &__os, + _ForwardIterator __first, _ForwardIterator __last, _CharT __delim, _CharT __escape ) +{ + _VSTD::basic_string<_CharT, _Traits> __str; + __str.push_back(__delim); + for ( ; __first != __last; ++ __first ) + { + if (_Traits::eq (*__first, __escape) || _Traits::eq (*__first, __delim)) + __str.push_back(__escape); + __str.push_back(*__first); + } + __str.push_back(__delim); + return __put_character_sequence(__os, __str.data(), __str.size()); +} + +template +basic_istream<_CharT, _Traits> & +__quoted_input ( basic_istream<_CharT, _Traits> &__is, _String & __string, _CharT __delim, _CharT __escape ) +{ + __string.clear (); + _CharT __c; + __is >> __c; + if ( __is.fail ()) + return __is; + + if (!_Traits::eq (__c, __delim)) // no delimiter, read the whole string + { + __is.unget (); + __is >> __string; + return __is; + } + + __save_flags<_CharT, _Traits> sf(__is); + noskipws (__is); + while (true) + { + __is >> __c; + if ( __is.fail ()) + break; + if (_Traits::eq (__c, __escape)) + { + __is >> __c; + if ( __is.fail ()) + break; + } + else if (_Traits::eq (__c, __delim)) + break; + __string.push_back ( __c ); + } + return __is; +} + + +template +basic_ostream<_CharT, _Traits>& operator<<( + basic_ostream<_CharT, _Traits>& __os, + const __quoted_output_proxy<_CharT, _Iter, _Traits> & __proxy) +{ + return __quoted_output (__os, __proxy.__first, __proxy.__last, __proxy.__delim, __proxy.__escape); +} + +template +struct __quoted_proxy +{ + basic_string<_CharT, _Traits, _Allocator> &__string; + _CharT __delim; + _CharT __escape; + + __quoted_proxy(basic_string<_CharT, _Traits, _Allocator> &__s, _CharT __d, _CharT __e) + : __string(__s), __delim(__d), __escape(__e) {} +}; + +template +_LIBCPP_INLINE_VISIBILITY +basic_ostream<_CharT, _Traits>& operator<<( + basic_ostream<_CharT, _Traits>& __os, + const __quoted_proxy<_CharT, _Traits, _Allocator> & __proxy) +{ + return __quoted_output (__os, __proxy.__string.cbegin (), __proxy.__string.cend (), __proxy.__delim, __proxy.__escape); +} + +// extractor for non-const basic_string& proxies +template +_LIBCPP_INLINE_VISIBILITY +basic_istream<_CharT, _Traits>& operator>>( + basic_istream<_CharT, _Traits>& __is, + const __quoted_proxy<_CharT, _Traits, _Allocator> & __proxy) +{ + return __quoted_input ( __is, __proxy.__string, __proxy.__delim, __proxy.__escape ); +} + + +template +_LIBCPP_INLINE_VISIBILITY +__quoted_output_proxy<_CharT, const _CharT *> +quoted ( const _CharT *__s, _CharT __delim = _CharT('"'), _CharT __escape =_CharT('\\')) +{ + const _CharT *__end = __s; + while ( *__end ) ++__end; + return __quoted_output_proxy<_CharT, const _CharT *> ( __s, __end, __delim, __escape ); +} + + +template +_LIBCPP_INLINE_VISIBILITY +__quoted_output_proxy<_CharT, typename basic_string <_CharT, _Traits, _Allocator>::const_iterator> +__quoted ( const basic_string <_CharT, _Traits, _Allocator> &__s, _CharT __delim = _CharT('"'), _CharT __escape=_CharT('\\')) +{ + return __quoted_output_proxy<_CharT, + typename basic_string <_CharT, _Traits, _Allocator>::const_iterator> + ( __s.cbegin(), __s.cend (), __delim, __escape ); +} + +template +_LIBCPP_INLINE_VISIBILITY +__quoted_proxy<_CharT, _Traits, _Allocator> +__quoted ( basic_string <_CharT, _Traits, _Allocator> &__s, _CharT __delim = _CharT('"'), _CharT __escape=_CharT('\\')) +{ + return __quoted_proxy<_CharT, _Traits, _Allocator>( __s, __delim, __escape ); +} + + +#if _LIBCPP_STD_VER > 11 + +template +_LIBCPP_INLINE_VISIBILITY +__quoted_output_proxy<_CharT, typename basic_string <_CharT, _Traits, _Allocator>::const_iterator> +quoted ( const basic_string <_CharT, _Traits, _Allocator> &__s, _CharT __delim = _CharT('"'), _CharT __escape=_CharT('\\')) +{ + return __quoted(__s, __delim, __escape); +} + +template +_LIBCPP_INLINE_VISIBILITY +__quoted_proxy<_CharT, _Traits, _Allocator> +quoted ( basic_string <_CharT, _Traits, _Allocator> &__s, _CharT __delim = _CharT('"'), _CharT __escape=_CharT('\\')) +{ + return __quoted(__s, __delim, __escape); +} + +template +__quoted_output_proxy<_CharT, const _CharT *, _Traits> +quoted (basic_string_view <_CharT, _Traits> __sv, + _CharT __delim = _CharT('"'), _CharT __escape=_CharT('\\')) +{ + return __quoted_output_proxy<_CharT, const _CharT *, _Traits> + ( __sv.data(), __sv.data() + __sv.size(), __delim, __escape ); +} +#endif + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_IOMANIP diff --git a/third_party/libcxx/libcxx.mk b/third_party/libcxx/libcxx.mk index 08a90f280..473a95091 100644 --- a/third_party/libcxx/libcxx.mk +++ b/third_party/libcxx/libcxx.mk @@ -7,8 +7,6 @@ THIRD_PARTY_LIBCXX_ARTIFACTS += THIRD_PARTY_LIBCXX_A THIRD_PARTY_LIBCXX = $(THIRD_PARTY_LIBCXX_A_DEPS) $(THIRD_PARTY_LIBCXX_A) THIRD_PARTY_LIBCXX_A = o/$(MODE)/third_party/libcxx/libcxx.a -# third_party/libcxx/__functional_base_03 \ - THIRD_PARTY_LIBCXX_A_HDRS = \ third_party/libcxx/__bit_reference \ third_party/libcxx/__bsd_locale_fallbacks.h \ @@ -30,28 +28,41 @@ THIRD_PARTY_LIBCXX_A_HDRS = \ third_party/libcxx/__tuple \ third_party/libcxx/__undef_macros \ third_party/libcxx/algorithm \ + third_party/libcxx/any \ third_party/libcxx/array \ third_party/libcxx/atomic \ third_party/libcxx/atomic_support.hh \ third_party/libcxx/bit \ third_party/libcxx/bitset \ third_party/libcxx/cassert \ + third_party/libcxx/ccomplex \ third_party/libcxx/cctype \ third_party/libcxx/cerrno \ + third_party/libcxx/cfenv \ + third_party/libcxx/cfloat \ third_party/libcxx/charconv \ third_party/libcxx/chrono \ + third_party/libcxx/cinttypes \ + third_party/libcxx/ciso646 \ third_party/libcxx/climits \ third_party/libcxx/clocale \ third_party/libcxx/cmath \ third_party/libcxx/codecvt \ + third_party/libcxx/compare \ + third_party/libcxx/complex \ third_party/libcxx/condition_variable \ third_party/libcxx/config_elast.h \ + third_party/libcxx/countof.internal.hh \ + third_party/libcxx/csetjmp \ + third_party/libcxx/csignal \ third_party/libcxx/cstdarg \ + third_party/libcxx/cstdbool \ third_party/libcxx/cstddef \ third_party/libcxx/cstdint \ third_party/libcxx/cstdio \ third_party/libcxx/cstdlib \ third_party/libcxx/cstring \ + third_party/libcxx/ctgmath \ third_party/libcxx/ctime \ third_party/libcxx/ctype.h \ third_party/libcxx/cwchar \ @@ -61,11 +72,16 @@ THIRD_PARTY_LIBCXX_A_HDRS = \ third_party/libcxx/exception \ third_party/libcxx/exception_fallback.hh \ third_party/libcxx/exception_pointer_unimplemented.hh \ + third_party/libcxx/execution \ third_party/libcxx/experimental/__config \ + third_party/libcxx/filesystem \ + third_party/libcxx/forward_list \ + third_party/libcxx/fstream \ third_party/libcxx/functional \ third_party/libcxx/include/atomic_support.hh \ third_party/libcxx/include/config_elast.hh \ third_party/libcxx/initializer_list \ + third_party/libcxx/iomanip \ third_party/libcxx/ios \ third_party/libcxx/iosfwd \ third_party/libcxx/iostream \ @@ -90,6 +106,8 @@ THIRD_PARTY_LIBCXX_A_HDRS = \ third_party/libcxx/random \ third_party/libcxx/ratio \ third_party/libcxx/refstring.hh \ + third_party/libcxx/regex \ + third_party/libcxx/scoped_allocator \ third_party/libcxx/set \ third_party/libcxx/sstream \ third_party/libcxx/stack \ @@ -101,14 +119,17 @@ THIRD_PARTY_LIBCXX_A_HDRS = \ third_party/libcxx/string \ third_party/libcxx/string.h \ third_party/libcxx/string_view \ + third_party/libcxx/strstream \ third_party/libcxx/system_error \ third_party/libcxx/thread \ third_party/libcxx/tuple \ third_party/libcxx/type_traits \ + third_party/libcxx/typeindex \ third_party/libcxx/typeinfo \ third_party/libcxx/unordered_map \ third_party/libcxx/unordered_set \ third_party/libcxx/utility \ + third_party/libcxx/valarray \ third_party/libcxx/variant \ third_party/libcxx/vector \ third_party/libcxx/version \ @@ -126,15 +147,21 @@ THIRD_PARTY_LIBCXX_A_SRCS_CC = \ third_party/libcxx/hash.cc \ third_party/libcxx/ios.cc \ third_party/libcxx/iostream.cc \ - third_party/libcxx/locale.cc \ + third_party/libcxx/locale1.cc \ + third_party/libcxx/locale2.cc \ + third_party/libcxx/locale3.cc \ + third_party/libcxx/locale4.cc \ third_party/libcxx/memory.cc \ third_party/libcxx/mutex.cc \ third_party/libcxx/new.cc \ third_party/libcxx/optional.cc \ third_party/libcxx/random.cc \ + third_party/libcxx/regex.cc \ third_party/libcxx/stdexcept.cc \ third_party/libcxx/string.cc \ + third_party/libcxx/strstream.cc \ third_party/libcxx/system_error.cc \ + third_party/libcxx/valarray.cc \ third_party/libcxx/vector.cc THIRD_PARTY_LIBCXX_A_SRCS = \ @@ -182,8 +209,6 @@ $(THIRD_PARTY_LIBCXX_A_OBJS): private \ -ffunction-sections \ -fdata-sections -o/$(MODE)/third_party/libcxx/locale.o: private QUOTA = -C32 -M1024m - THIRD_PARTY_LIBCXX_LIBS = $(foreach x,$(THIRD_PARTY_LIBCXX_ARTIFACTS),$($(x))) THIRD_PARTY_LIBCXX_SRCS = $(foreach x,$(THIRD_PARTY_LIBCXX_ARTIFACTS),$($(x)_SRCS)) THIRD_PARTY_LIBCXX_HDRS = $(foreach x,$(THIRD_PARTY_LIBCXX_ARTIFACTS),$($(x)_HDRS)) diff --git a/third_party/libcxx/locale.cc b/third_party/libcxx/locale.cc deleted file mode 100644 index c5a8efc24..000000000 --- a/third_party/libcxx/locale.cc +++ /dev/null @@ -1,6146 +0,0 @@ -// clang-format off -//===------------------------- locale.cpp ---------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -// On Solaris, we need to define something to make the C99 parts of localeconv -// visible. -#ifdef __sun__ -#define _LCONV_C99 -#endif - -#include "third_party/libcxx/string" -#include "third_party/libcxx/locale" -#include "third_party/libcxx/codecvt" -#include "third_party/libcxx/vector" -#include "third_party/libcxx/algorithm" -#include "third_party/libcxx/typeinfo" -#ifndef _LIBCPP_NO_EXCEPTIONS -#include "third_party/libcxx/type_traits" -#endif -#include "third_party/libcxx/clocale" -#include "third_party/libcxx/cstring" -#include "third_party/libcxx/cwctype" -#include "third_party/libcxx/__sso_allocator" -#include "third_party/libcxx/include/atomic_support.hh" -#include "libc/str/locale.h" -#include "third_party/libcxx/__undef_macros" - -// On Linux, wint_t and wchar_t have different signed-ness, and this causes -// lots of noise in the build log, but no bugs that I know of. -#if defined(__clang__) -#pragma clang diagnostic ignored "-Wsign-conversion" -#endif - -_LIBCPP_BEGIN_NAMESPACE_STD - -struct __libcpp_unique_locale { - __libcpp_unique_locale(const char* nm) : __loc_(newlocale(LC_ALL_MASK, nm, 0)) {} - - ~__libcpp_unique_locale() { - if (__loc_) - freelocale(__loc_); - } - - explicit operator bool() const { return __loc_; } - - locale_t& get() { return __loc_; } - - locale_t __loc_; -private: - __libcpp_unique_locale(__libcpp_unique_locale const&); - __libcpp_unique_locale& operator=(__libcpp_unique_locale const&); -}; - -#ifdef __cloc_defined -locale_t __cloc() { - // In theory this could create a race condition. In practice - // the race condition is non-fatal since it will just create - // a little resource leak. Better approach would be appreciated. - static locale_t result = newlocale(LC_ALL_MASK, "C", 0); - return result; -} -#endif // __cloc_defined - -namespace { - -struct release -{ - void operator()(locale::facet* p) {p->__release_shared();} -}; - -template -inline -T& -make(A0 a0) -{ - static typename aligned_storage::type buf; - auto *obj = ::new (&buf) T(a0); - return *obj; -} - -template -inline -T& -make(A0 a0, A1 a1) -{ - static typename aligned_storage::type buf; - ::new (&buf) T(a0, a1); - return *reinterpret_cast(&buf); -} - -template -inline -T& -make(A0 a0, A1 a1, A2 a2) -{ - static typename aligned_storage::type buf; - auto *obj = ::new (&buf) T(a0, a1, a2); - return *obj; -} - -template -inline -_LIBCPP_CONSTEXPR -size_t -countof(const T (&)[N]) -{ - return N; -} - -template -inline -_LIBCPP_CONSTEXPR -size_t -countof(const T * const begin, const T * const end) -{ - return static_cast(end - begin); -} - -_LIBCPP_NORETURN static void __throw_runtime_error(const string &msg) -{ -#ifndef _LIBCPP_NO_EXCEPTIONS - throw runtime_error(msg); -#else - (void)msg; - _VSTD::abort(); -#endif -} - -} - -#if defined(_AIX) -// Set priority to INT_MIN + 256 + 150 -# pragma priority ( -2147483242 ) -#endif - -const locale::category locale::none; -const locale::category locale::collate; -const locale::category locale::ctype; -const locale::category locale::monetary; -const locale::category locale::numeric; -const locale::category locale::time; -const locale::category locale::messages; -const locale::category locale::all; - -class _LIBCPP_HIDDEN locale::__imp - : public facet -{ - enum {N = 28}; -#if defined(_LIBCPP_COMPILER_MSVC) -// FIXME: MSVC doesn't support aligned parameters by value. -// I can't get the __sso_allocator to work here -// for MSVC I think for this reason. - vector facets_; -#else - vector > facets_; -#endif - string name_; -public: - explicit __imp(size_t refs = 0); - explicit __imp(const string& name, size_t refs = 0); - __imp(const __imp&); - __imp(const __imp&, const string&, locale::category c); - __imp(const __imp& other, const __imp& one, locale::category c); - __imp(const __imp&, facet* f, long id); - ~__imp(); - - const string& name() const {return name_;} - bool has_facet(long id) const - {return static_cast(id) < facets_.size() && facets_[static_cast(id)];} - const locale::facet* use_facet(long id) const; - - static const locale& make_classic(); - static locale& make_global(); -private: - void install(facet* f, long id); - template void install(F* f) {install(f, f->id.__get());} - template void install_from(const __imp& other); -}; - -locale::__imp::__imp(size_t refs) - : facet(refs), - facets_(N), - name_("C") -{ - facets_.clear(); - install(&make<_VSTD::collate >(1u)); - install(&make<_VSTD::collate >(1u)); - install(&make<_VSTD::ctype >(nullptr, false, 1u)); - install(&make<_VSTD::ctype >(1u)); - install(&make >(1u)); - install(&make >(1u)); - install(&make >(1u)); - install(&make >(1u)); - install(&make >(1u)); - install(&make >(1u)); - install(&make >(1u)); - install(&make >(1u)); - install(&make >(1u)); - install(&make >(1u)); - install(&make >(1u)); - install(&make >(1u)); - install(&make >(1u)); - install(&make >(1u)); - install(&make >(1u)); - install(&make >(1u)); - install(&make >(1u)); - install(&make >(1u)); - install(&make >(1u)); - install(&make >(1u)); - install(&make >(1u)); - install(&make >(1u)); - install(&make<_VSTD::messages >(1u)); - install(&make<_VSTD::messages >(1u)); -} - -locale::__imp::__imp(const string& name, size_t refs) - : facet(refs), - facets_(N), - name_(name) -{ -#ifndef _LIBCPP_NO_EXCEPTIONS - try - { -#endif // _LIBCPP_NO_EXCEPTIONS - facets_ = locale::classic().__locale_->facets_; - for (unsigned i = 0; i < facets_.size(); ++i) - if (facets_[i]) - facets_[i]->__add_shared(); - install(new collate_byname(name_)); - install(new collate_byname(name_)); - install(new ctype_byname(name_)); - install(new ctype_byname(name_)); - install(new codecvt_byname(name_)); - install(new codecvt_byname(name_)); - install(new codecvt_byname(name_)); - install(new codecvt_byname(name_)); - install(new numpunct_byname(name_)); - install(new numpunct_byname(name_)); - install(new moneypunct_byname(name_)); - install(new moneypunct_byname(name_)); - install(new moneypunct_byname(name_)); - install(new moneypunct_byname(name_)); - install(new time_get_byname(name_)); - install(new time_get_byname(name_)); - install(new time_put_byname(name_)); - install(new time_put_byname(name_)); - install(new messages_byname(name_)); - install(new messages_byname(name_)); -#ifndef _LIBCPP_NO_EXCEPTIONS - } - catch (...) - { - for (unsigned i = 0; i < facets_.size(); ++i) - if (facets_[i]) - facets_[i]->__release_shared(); - throw; - } -#endif // _LIBCPP_NO_EXCEPTIONS -} - -// NOTE avoid the `base class should be explicitly initialized in the -// copy constructor` warning emitted by GCC -#if defined(__clang__) || _GNUC_VER >= 406 -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wextra" -#endif - -locale::__imp::__imp(const __imp& other) - : facets_(max(N, other.facets_.size())), - name_(other.name_) -{ - facets_ = other.facets_; - for (unsigned i = 0; i < facets_.size(); ++i) - if (facets_[i]) - facets_[i]->__add_shared(); -} - -#if defined(__clang__) || _GNUC_VER >= 406 -#pragma GCC diagnostic pop -#endif - -locale::__imp::__imp(const __imp& other, const string& name, locale::category c) - : facets_(N), - name_("*") -{ - facets_ = other.facets_; - for (unsigned i = 0; i < facets_.size(); ++i) - if (facets_[i]) - facets_[i]->__add_shared(); -#ifndef _LIBCPP_NO_EXCEPTIONS - try - { -#endif // _LIBCPP_NO_EXCEPTIONS - if (c & locale::collate) - { - install(new collate_byname(name)); - install(new collate_byname(name)); - } - if (c & locale::ctype) - { - install(new ctype_byname(name)); - install(new ctype_byname(name)); - install(new codecvt_byname(name)); - install(new codecvt_byname(name)); - install(new codecvt_byname(name)); - install(new codecvt_byname(name)); - } - if (c & locale::monetary) - { - install(new moneypunct_byname(name)); - install(new moneypunct_byname(name)); - install(new moneypunct_byname(name)); - install(new moneypunct_byname(name)); - } - if (c & locale::numeric) - { - install(new numpunct_byname(name)); - install(new numpunct_byname(name)); - } - if (c & locale::time) - { - install(new time_get_byname(name)); - install(new time_get_byname(name)); - install(new time_put_byname(name)); - install(new time_put_byname(name)); - } - if (c & locale::messages) - { - install(new messages_byname(name)); - install(new messages_byname(name)); - } -#ifndef _LIBCPP_NO_EXCEPTIONS - } - catch (...) - { - for (unsigned i = 0; i < facets_.size(); ++i) - if (facets_[i]) - facets_[i]->__release_shared(); - throw; - } -#endif // _LIBCPP_NO_EXCEPTIONS -} - -template -inline -void -locale::__imp::install_from(const locale::__imp& one) -{ - long id = F::id.__get(); - install(const_cast(static_cast(one.use_facet(id))), id); -} - -locale::__imp::__imp(const __imp& other, const __imp& one, locale::category c) - : facets_(N), - name_("*") -{ - facets_ = other.facets_; - for (unsigned i = 0; i < facets_.size(); ++i) - if (facets_[i]) - facets_[i]->__add_shared(); -#ifndef _LIBCPP_NO_EXCEPTIONS - try - { -#endif // _LIBCPP_NO_EXCEPTIONS - if (c & locale::collate) - { - install_from<_VSTD::collate >(one); - install_from<_VSTD::collate >(one); - } - if (c & locale::ctype) - { - install_from<_VSTD::ctype >(one); - install_from<_VSTD::ctype >(one); - install_from<_VSTD::codecvt >(one); - install_from<_VSTD::codecvt >(one); - install_from<_VSTD::codecvt >(one); - install_from<_VSTD::codecvt >(one); - } - if (c & locale::monetary) - { - install_from >(one); - install_from >(one); - install_from >(one); - install_from >(one); - install_from >(one); - install_from >(one); - install_from >(one); - install_from >(one); - } - if (c & locale::numeric) - { - install_from >(one); - install_from >(one); - install_from >(one); - install_from >(one); - install_from >(one); - install_from >(one); - } - if (c & locale::time) - { - install_from >(one); - install_from >(one); - install_from >(one); - install_from >(one); - } - if (c & locale::messages) - { - install_from<_VSTD::messages >(one); - install_from<_VSTD::messages >(one); - } -#ifndef _LIBCPP_NO_EXCEPTIONS - } - catch (...) - { - for (unsigned i = 0; i < facets_.size(); ++i) - if (facets_[i]) - facets_[i]->__release_shared(); - throw; - } -#endif // _LIBCPP_NO_EXCEPTIONS -} - -locale::__imp::__imp(const __imp& other, facet* f, long id) - : facets_(max(N, other.facets_.size()+1)), - name_("*") -{ - f->__add_shared(); - unique_ptr hold(f); - facets_ = other.facets_; - for (unsigned i = 0; i < other.facets_.size(); ++i) - if (facets_[i]) - facets_[i]->__add_shared(); - install(hold.get(), id); -} - -locale::__imp::~__imp() -{ - for (unsigned i = 0; i < facets_.size(); ++i) - if (facets_[i]) - facets_[i]->__release_shared(); -} - -void -locale::__imp::install(facet* f, long id) -{ - f->__add_shared(); - unique_ptr hold(f); - if (static_cast(id) >= facets_.size()) - facets_.resize(static_cast(id+1)); - if (facets_[static_cast(id)]) - facets_[static_cast(id)]->__release_shared(); - facets_[static_cast(id)] = hold.release(); -} - -const locale::facet* -locale::__imp::use_facet(long id) const -{ - if (!has_facet(id)) - __throw_bad_cast(); - return facets_[static_cast(id)]; -} - -// locale - -const locale& -locale::__imp::make_classic() -{ - // only one thread can get in here and it only gets in once - static aligned_storage::type buf; - locale* c = reinterpret_cast(&buf); - c->__locale_ = &make<__imp>(1u); - return *c; -} - -const locale& -locale::classic() -{ - static const locale& c = __imp::make_classic(); - return c; -} - -locale& -locale::__imp::make_global() -{ - // only one thread can get in here and it only gets in once - static aligned_storage::type buf; - auto *obj = ::new (&buf) locale(locale::classic()); - return *obj; -} - -locale& -locale::__global() -{ - static locale& g = __imp::make_global(); - return g; -} - -locale::locale() _NOEXCEPT - : __locale_(__global().__locale_) -{ - __locale_->__add_shared(); -} - -locale::locale(const locale& l) _NOEXCEPT - : __locale_(l.__locale_) -{ - __locale_->__add_shared(); -} - -locale::~locale() -{ - __locale_->__release_shared(); -} - -const locale& -locale::operator=(const locale& other) _NOEXCEPT -{ - other.__locale_->__add_shared(); - __locale_->__release_shared(); - __locale_ = other.__locale_; - return *this; -} - -locale::locale(const char* name) - : __locale_(name ? new __imp(name) - : (__throw_runtime_error("locale constructed with null"), (__imp*)0)) -{ - __locale_->__add_shared(); -} - -locale::locale(const string& name) - : __locale_(new __imp(name)) -{ - __locale_->__add_shared(); -} - -locale::locale(const locale& other, const char* name, category c) - : __locale_(name ? new __imp(*other.__locale_, name, c) - : (__throw_runtime_error("locale constructed with null"), (__imp*)0)) -{ - __locale_->__add_shared(); -} - -locale::locale(const locale& other, const string& name, category c) - : __locale_(new __imp(*other.__locale_, name, c)) -{ - __locale_->__add_shared(); -} - -locale::locale(const locale& other, const locale& one, category c) - : __locale_(new __imp(*other.__locale_, *one.__locale_, c)) -{ - __locale_->__add_shared(); -} - -string -locale::name() const -{ - return __locale_->name(); -} - -void -locale::__install_ctor(const locale& other, facet* f, long id) -{ - if (f) - __locale_ = new __imp(*other.__locale_, f, id); - else - __locale_ = other.__locale_; - __locale_->__add_shared(); -} - -locale -locale::global(const locale& loc) -{ - locale& g = __global(); - locale r = g; - g = loc; - if (g.name() != "*") - setlocale(LC_ALL, g.name().c_str()); - return r; -} - -bool -locale::has_facet(id& x) const -{ - return __locale_->has_facet(x.__get()); -} - -const locale::facet* -locale::use_facet(id& x) const -{ - return __locale_->use_facet(x.__get()); -} - -bool -locale::operator==(const locale& y) const -{ - return (__locale_ == y.__locale_) - || (__locale_->name() != "*" && __locale_->name() == y.__locale_->name()); -} - -// locale::facet - -locale::facet::~facet() -{ -} - -void -locale::facet::__on_zero_shared() _NOEXCEPT -{ - delete this; -} - -// locale::id - -int32_t locale::id::__next_id = 0; - -namespace -{ - -class __fake_bind -{ - locale::id* id_; - void (locale::id::* pmf_)(); -public: - __fake_bind(void (locale::id::* pmf)(), locale::id* id) - : id_(id), pmf_(pmf) {} - - void operator()() const - { - (id_->*pmf_)(); - } -}; - -} - -long -locale::id::__get() -{ - call_once(__flag_, __fake_bind(&locale::id::__init, this)); - return __id_ - 1; -} - -void -locale::id::__init() -{ - __id_ = __libcpp_atomic_add(&__next_id, 1); -} - -// template <> class collate_byname - -collate_byname::collate_byname(const char* n, size_t refs) - : collate(refs), - __l(newlocale(LC_ALL_MASK, n, 0)) -{ - if (__l == 0) - __throw_runtime_error("collate_byname::collate_byname" - " failed to construct for " + string(n)); -} - -collate_byname::collate_byname(const string& name, size_t refs) - : collate(refs), - __l(newlocale(LC_ALL_MASK, name.c_str(), 0)) -{ - if (__l == 0) - __throw_runtime_error("collate_byname::collate_byname" - " failed to construct for " + name); -} - -collate_byname::~collate_byname() -{ - freelocale(__l); -} - -int -collate_byname::do_compare(const char_type* __lo1, const char_type* __hi1, - const char_type* __lo2, const char_type* __hi2) const -{ - string_type lhs(__lo1, __hi1); - string_type rhs(__lo2, __hi2); - int r = strcoll_l(lhs.c_str(), rhs.c_str(), __l); - if (r < 0) - return -1; - if (r > 0) - return 1; - return r; -} - -collate_byname::string_type -collate_byname::do_transform(const char_type* lo, const char_type* hi) const -{ - const string_type in(lo, hi); - string_type out(strxfrm_l(0, in.c_str(), 0, __l), char()); - strxfrm_l(const_cast(out.c_str()), in.c_str(), out.size()+1, __l); - return out; -} - -// template <> class collate_byname - -collate_byname::collate_byname(const char* n, size_t refs) - : collate(refs), - __l(newlocale(LC_ALL_MASK, n, 0)) -{ - if (__l == 0) - __throw_runtime_error("collate_byname::collate_byname(size_t refs)" - " failed to construct for " + string(n)); -} - -collate_byname::collate_byname(const string& name, size_t refs) - : collate(refs), - __l(newlocale(LC_ALL_MASK, name.c_str(), 0)) -{ - if (__l == 0) - __throw_runtime_error("collate_byname::collate_byname(size_t refs)" - " failed to construct for " + name); -} - -collate_byname::~collate_byname() -{ - freelocale(__l); -} - -int -collate_byname::do_compare(const char_type* __lo1, const char_type* __hi1, - const char_type* __lo2, const char_type* __hi2) const -{ - string_type lhs(__lo1, __hi1); - string_type rhs(__lo2, __hi2); - int r = wcscoll_l(lhs.c_str(), rhs.c_str(), __l); - if (r < 0) - return -1; - if (r > 0) - return 1; - return r; -} - -collate_byname::string_type -collate_byname::do_transform(const char_type* lo, const char_type* hi) const -{ - const string_type in(lo, hi); - string_type out(wcsxfrm_l(0, in.c_str(), 0, __l), wchar_t()); - wcsxfrm_l(const_cast(out.c_str()), in.c_str(), out.size()+1, __l); - return out; -} - -// template <> class ctype; - -const ctype_base::mask ctype_base::space; -const ctype_base::mask ctype_base::print; -const ctype_base::mask ctype_base::cntrl; -const ctype_base::mask ctype_base::upper; -const ctype_base::mask ctype_base::lower; -const ctype_base::mask ctype_base::alpha; -const ctype_base::mask ctype_base::digit; -const ctype_base::mask ctype_base::punct; -const ctype_base::mask ctype_base::xdigit; -const ctype_base::mask ctype_base::blank; -const ctype_base::mask ctype_base::alnum; -const ctype_base::mask ctype_base::graph; - -locale::id ctype::id; - -ctype::~ctype() -{ -} - -bool -ctype::do_is(mask m, char_type c) const -{ - return isascii(c) ? (ctype::classic_table()[c] & m) != 0 : false; -} - -const wchar_t* -ctype::do_is(const char_type* low, const char_type* high, mask* vec) const -{ - for (; low != high; ++low, ++vec) - *vec = static_cast(isascii(*low) ? - ctype::classic_table()[*low] : 0); - return low; -} - -const wchar_t* -ctype::do_scan_is(mask m, const char_type* low, const char_type* high) const -{ - for (; low != high; ++low) - if (isascii(*low) && (ctype::classic_table()[*low] & m)) - break; - return low; -} - -const wchar_t* -ctype::do_scan_not(mask m, const char_type* low, const char_type* high) const -{ - for (; low != high; ++low) - if (!(isascii(*low) && (ctype::classic_table()[*low] & m))) - break; - return low; -} - -wchar_t -ctype::do_toupper(char_type c) const -{ -#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE - return isascii(c) ? _DefaultRuneLocale.__mapupper[c] : c; -#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || \ - defined(__NetBSD__) - return isascii(c) ? ctype::__classic_upper_table()[c] : c; -#else - return (isascii(c) && iswlower_l(c, _LIBCPP_GET_C_LOCALE)) ? c-L'a'+L'A' : c; -#endif -} - -const wchar_t* -ctype::do_toupper(char_type* low, const char_type* high) const -{ - for (; low != high; ++low) -#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE - *low = isascii(*low) ? _DefaultRuneLocale.__mapupper[*low] : *low; -#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || \ - defined(__NetBSD__) - *low = isascii(*low) ? ctype::__classic_upper_table()[*low] - : *low; -#else - *low = (isascii(*low) && islower_l(*low, _LIBCPP_GET_C_LOCALE)) ? (*low-L'a'+L'A') : *low; -#endif - return low; -} - -wchar_t -ctype::do_tolower(char_type c) const -{ -#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE - return isascii(c) ? _DefaultRuneLocale.__maplower[c] : c; -#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || \ - defined(__NetBSD__) - return isascii(c) ? ctype::__classic_lower_table()[c] : c; -#else - return (isascii(c) && isupper_l(c, _LIBCPP_GET_C_LOCALE)) ? c-L'A'+'a' : c; -#endif -} - -const wchar_t* -ctype::do_tolower(char_type* low, const char_type* high) const -{ - for (; low != high; ++low) -#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE - *low = isascii(*low) ? _DefaultRuneLocale.__maplower[*low] : *low; -#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || \ - defined(__NetBSD__) - *low = isascii(*low) ? ctype::__classic_lower_table()[*low] - : *low; -#else - *low = (isascii(*low) && isupper_l(*low, _LIBCPP_GET_C_LOCALE)) ? *low-L'A'+L'a' : *low; -#endif - return low; -} - -wchar_t -ctype::do_widen(char c) const -{ - return c; -} - -const char* -ctype::do_widen(const char* low, const char* high, char_type* dest) const -{ - for (; low != high; ++low, ++dest) - *dest = *low; - return low; -} - -char -ctype::do_narrow(char_type c, char dfault) const -{ - if (isascii(c)) - return static_cast(c); - return dfault; -} - -const wchar_t* -ctype::do_narrow(const char_type* low, const char_type* high, char dfault, char* dest) const -{ - for (; low != high; ++low, ++dest) - if (isascii(*low)) - *dest = static_cast(*low); - else - *dest = dfault; - return low; -} - -// template <> class ctype; - -locale::id ctype::id; - -ctype::ctype(const mask* tab, bool del, size_t refs) - : locale::facet(refs), - __tab_(tab), - __del_(del) -{ - if (__tab_ == 0) - __tab_ = classic_table(); -} - -ctype::~ctype() -{ - if (__tab_ && __del_) - delete [] __tab_; -} - -char -ctype::do_toupper(char_type c) const -{ -#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE - return isascii(c) ? - static_cast(_DefaultRuneLocale.__mapupper[static_cast(c)]) : c; -#elif defined(__NetBSD__) - return static_cast(__classic_upper_table()[static_cast(c)]); -#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) - return isascii(c) ? - static_cast(__classic_upper_table()[static_cast(c)]) : c; -#else - return (isascii(c) && islower_l(c, _LIBCPP_GET_C_LOCALE)) ? c-'a'+'A' : c; -#endif -} - -const char* -ctype::do_toupper(char_type* low, const char_type* high) const -{ - for (; low != high; ++low) -#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE - *low = isascii(*low) ? - static_cast(_DefaultRuneLocale.__mapupper[static_cast(*low)]) : *low; -#elif defined(__NetBSD__) - *low = static_cast(__classic_upper_table()[static_cast(*low)]); -#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) - *low = isascii(*low) ? - static_cast(__classic_upper_table()[static_cast(*low)]) : *low; -#else - *low = (isascii(*low) && islower_l(*low, _LIBCPP_GET_C_LOCALE)) ? *low-'a'+'A' : *low; -#endif - return low; -} - -char -ctype::do_tolower(char_type c) const -{ -#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE - return isascii(c) ? - static_cast(_DefaultRuneLocale.__maplower[static_cast(c)]) : c; -#elif defined(__NetBSD__) - return static_cast(__classic_lower_table()[static_cast(c)]); -#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) - return isascii(c) ? - static_cast(__classic_lower_table()[static_cast(c)]) : c; -#else - return (isascii(c) && isupper_l(c, _LIBCPP_GET_C_LOCALE)) ? c-'A'+'a' : c; -#endif -} - -const char* -ctype::do_tolower(char_type* low, const char_type* high) const -{ - for (; low != high; ++low) -#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE - *low = isascii(*low) ? static_cast(_DefaultRuneLocale.__maplower[static_cast(*low)]) : *low; -#elif defined(__NetBSD__) - *low = static_cast(__classic_lower_table()[static_cast(*low)]); -#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) - *low = isascii(*low) ? static_cast(__classic_lower_table()[static_cast(*low)]) : *low; -#else - *low = (isascii(*low) && isupper_l(*low, _LIBCPP_GET_C_LOCALE)) ? *low-'A'+'a' : *low; -#endif - return low; -} - -char -ctype::do_widen(char c) const -{ - return c; -} - -const char* -ctype::do_widen(const char* low, const char* high, char_type* dest) const -{ - for (; low != high; ++low, ++dest) - *dest = *low; - return low; -} - -char -ctype::do_narrow(char_type c, char dfault) const -{ - if (isascii(c)) - return static_cast(c); - return dfault; -} - -const char* -ctype::do_narrow(const char_type* low, const char_type* high, char dfault, char* dest) const -{ - for (; low != high; ++low, ++dest) - if (isascii(*low)) - *dest = *low; - else - *dest = dfault; - return low; -} - -#if defined(__EMSCRIPTEN__) -extern "C" const unsigned short ** __ctype_b_loc(); -extern "C" const int ** __ctype_tolower_loc(); -extern "C" const int ** __ctype_toupper_loc(); -#endif - -#ifdef _LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE -const ctype::mask* -ctype::classic_table() _NOEXCEPT -{ - static _LIBCPP_CONSTEXPR const ctype::mask builtin_table[table_size] = { - cntrl, cntrl, - cntrl, cntrl, - cntrl, cntrl, - cntrl, cntrl, - cntrl, cntrl | space | blank, - cntrl | space, cntrl | space, - cntrl | space, cntrl | space, - cntrl, cntrl, - cntrl, cntrl, - cntrl, cntrl, - cntrl, cntrl, - cntrl, cntrl, - cntrl, cntrl, - cntrl, cntrl, - cntrl, cntrl, - cntrl, cntrl, - space | blank | print, punct | print, - punct | print, punct | print, - punct | print, punct | print, - punct | print, punct | print, - punct | print, punct | print, - punct | print, punct | print, - punct | print, punct | print, - punct | print, punct | print, - digit | print | xdigit, digit | print | xdigit, - digit | print | xdigit, digit | print | xdigit, - digit | print | xdigit, digit | print | xdigit, - digit | print | xdigit, digit | print | xdigit, - digit | print | xdigit, digit | print | xdigit, - punct | print, punct | print, - punct | print, punct | print, - punct | print, punct | print, - punct | print, upper | xdigit | print | alpha, - upper | xdigit | print | alpha, upper | xdigit | print | alpha, - upper | xdigit | print | alpha, upper | xdigit | print | alpha, - upper | xdigit | print | alpha, upper | print | alpha, - upper | print | alpha, upper | print | alpha, - upper | print | alpha, upper | print | alpha, - upper | print | alpha, upper | print | alpha, - upper | print | alpha, upper | print | alpha, - upper | print | alpha, upper | print | alpha, - upper | print | alpha, upper | print | alpha, - upper | print | alpha, upper | print | alpha, - upper | print | alpha, upper | print | alpha, - upper | print | alpha, upper | print | alpha, - upper | print | alpha, punct | print, - punct | print, punct | print, - punct | print, punct | print, - punct | print, lower | xdigit | print | alpha, - lower | xdigit | print | alpha, lower | xdigit | print | alpha, - lower | xdigit | print | alpha, lower | xdigit | print | alpha, - lower | xdigit | print | alpha, lower | print | alpha, - lower | print | alpha, lower | print | alpha, - lower | print | alpha, lower | print | alpha, - lower | print | alpha, lower | print | alpha, - lower | print | alpha, lower | print | alpha, - lower | print | alpha, lower | print | alpha, - lower | print | alpha, lower | print | alpha, - lower | print | alpha, lower | print | alpha, - lower | print | alpha, lower | print | alpha, - lower | print | alpha, lower | print | alpha, - lower | print | alpha, punct | print, - punct | print, punct | print, - punct | print, cntrl, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }; - return builtin_table; -} -#else -const ctype::mask* -ctype::classic_table() _NOEXCEPT -{ -#if defined(__APPLE__) || defined(__FreeBSD__) - return _DefaultRuneLocale.__runetype; -#elif defined(__NetBSD__) - return _C_ctype_tab_ + 1; -#elif defined(__GLIBC__) - return _LIBCPP_GET_C_LOCALE->__ctype_b; -#elif __sun__ - return __ctype_mask; -#elif defined(_LIBCPP_MSVCRT) || defined(__MINGW32__) - return __pctype_func(); -#elif defined(__EMSCRIPTEN__) - return *__ctype_b_loc(); -#elif defined(_NEWLIB_VERSION) - // Newlib has a 257-entry table in ctype_.c, where (char)0 starts at [1]. - return _ctype_ + 1; -#elif defined(_AIX) - return (const unsigned int *)__lc_ctype_ptr->obj->mask; -#else - // Platform not supported: abort so the person doing the port knows what to - // fix -# warning ctype::classic_table() is not implemented - printf("ctype::classic_table() is not implemented\n"); - abort(); - return NULL; -#endif -} -#endif - -#if defined(__GLIBC__) -const int* -ctype::__classic_lower_table() _NOEXCEPT -{ - return _LIBCPP_GET_C_LOCALE->__ctype_tolower; -} - -const int* -ctype::__classic_upper_table() _NOEXCEPT -{ - return _LIBCPP_GET_C_LOCALE->__ctype_toupper; -} -#elif __NetBSD__ -const short* -ctype::__classic_lower_table() _NOEXCEPT -{ - return _C_tolower_tab_ + 1; -} - -const short* -ctype::__classic_upper_table() _NOEXCEPT -{ - return _C_toupper_tab_ + 1; -} - -#elif defined(__EMSCRIPTEN__) -const int* -ctype::__classic_lower_table() _NOEXCEPT -{ - return *__ctype_tolower_loc(); -} - -const int* -ctype::__classic_upper_table() _NOEXCEPT -{ - return *__ctype_toupper_loc(); -} -#endif // __GLIBC__ || __NETBSD__ || __EMSCRIPTEN__ - -// template <> class ctype_byname - -ctype_byname::ctype_byname(const char* name, size_t refs) - : ctype(0, false, refs), - __l(newlocale(LC_ALL_MASK, name, 0)) -{ - if (__l == 0) - __throw_runtime_error("ctype_byname::ctype_byname" - " failed to construct for " + string(name)); -} - -ctype_byname::ctype_byname(const string& name, size_t refs) - : ctype(0, false, refs), - __l(newlocale(LC_ALL_MASK, name.c_str(), 0)) -{ - if (__l == 0) - __throw_runtime_error("ctype_byname::ctype_byname" - " failed to construct for " + name); -} - -ctype_byname::~ctype_byname() -{ - freelocale(__l); -} - -char -ctype_byname::do_toupper(char_type c) const -{ - return static_cast(toupper_l(static_cast(c), __l)); -} - -const char* -ctype_byname::do_toupper(char_type* low, const char_type* high) const -{ - for (; low != high; ++low) - *low = static_cast(toupper_l(static_cast(*low), __l)); - return low; -} - -char -ctype_byname::do_tolower(char_type c) const -{ - return static_cast(tolower_l(static_cast(c), __l)); -} - -const char* -ctype_byname::do_tolower(char_type* low, const char_type* high) const -{ - for (; low != high; ++low) - *low = static_cast(tolower_l(static_cast(*low), __l)); - return low; -} - -// template <> class ctype_byname - -ctype_byname::ctype_byname(const char* name, size_t refs) - : ctype(refs), - __l(newlocale(LC_ALL_MASK, name, 0)) -{ - if (__l == 0) - __throw_runtime_error("ctype_byname::ctype_byname" - " failed to construct for " + string(name)); -} - -ctype_byname::ctype_byname(const string& name, size_t refs) - : ctype(refs), - __l(newlocale(LC_ALL_MASK, name.c_str(), 0)) -{ - if (__l == 0) - __throw_runtime_error("ctype_byname::ctype_byname" - " failed to construct for " + name); -} - -ctype_byname::~ctype_byname() -{ - freelocale(__l); -} - -bool -ctype_byname::do_is(mask m, char_type c) const -{ -#ifdef _LIBCPP_WCTYPE_IS_MASK - return static_cast(iswctype_l(c, m, __l)); -#else - bool result = false; - wint_t ch = static_cast(c); - if ((m & space) == space) result |= (iswspace_l(ch, __l) != 0); - if ((m & print) == print) result |= (iswprint_l(ch, __l) != 0); - if ((m & cntrl) == cntrl) result |= (iswcntrl_l(ch, __l) != 0); - if ((m & upper) == upper) result |= (iswupper_l(ch, __l) != 0); - if ((m & lower) == lower) result |= (iswlower_l(ch, __l) != 0); - if ((m & alpha) == alpha) result |= (iswalpha_l(ch, __l) != 0); - if ((m & digit) == digit) result |= (iswdigit_l(ch, __l) != 0); - if ((m & punct) == punct) result |= (iswpunct_l(ch, __l) != 0); - if ((m & xdigit) == xdigit) result |= (iswxdigit_l(ch, __l) != 0); - if ((m & blank) == blank) result |= (iswblank_l(ch, __l) != 0); - return result; -#endif -} - -const wchar_t* -ctype_byname::do_is(const char_type* low, const char_type* high, mask* vec) const -{ - for (; low != high; ++low, ++vec) - { - if (isascii(*low)) - *vec = static_cast(ctype::classic_table()[*low]); - else - { - *vec = 0; - wint_t ch = static_cast(*low); - if (iswspace_l(ch, __l)) - *vec |= space; -#ifndef _LIBCPP_CTYPE_MASK_IS_COMPOSITE_PRINT - if (iswprint_l(ch, __l)) - *vec |= print; -#endif - if (iswcntrl_l(ch, __l)) - *vec |= cntrl; - if (iswupper_l(ch, __l)) - *vec |= upper; - if (iswlower_l(ch, __l)) - *vec |= lower; -#ifndef _LIBCPP_CTYPE_MASK_IS_COMPOSITE_ALPHA - if (iswalpha_l(ch, __l)) - *vec |= alpha; -#endif - if (iswdigit_l(ch, __l)) - *vec |= digit; - if (iswpunct_l(ch, __l)) - *vec |= punct; -#ifndef _LIBCPP_CTYPE_MASK_IS_COMPOSITE_XDIGIT - if (iswxdigit_l(ch, __l)) - *vec |= xdigit; -#endif -#if !defined(__sun__) - if (iswblank_l(ch, __l)) - *vec |= blank; -#endif - } - } - return low; -} - -const wchar_t* -ctype_byname::do_scan_is(mask m, const char_type* low, const char_type* high) const -{ - for (; low != high; ++low) - { -#ifdef _LIBCPP_WCTYPE_IS_MASK - if (iswctype_l(*low, m, __l)) - break; -#else - wint_t ch = static_cast(*low); - if ((m & space) == space && iswspace_l(ch, __l)) break; - if ((m & print) == print && iswprint_l(ch, __l)) break; - if ((m & cntrl) == cntrl && iswcntrl_l(ch, __l)) break; - if ((m & upper) == upper && iswupper_l(ch, __l)) break; - if ((m & lower) == lower && iswlower_l(ch, __l)) break; - if ((m & alpha) == alpha && iswalpha_l(ch, __l)) break; - if ((m & digit) == digit && iswdigit_l(ch, __l)) break; - if ((m & punct) == punct && iswpunct_l(ch, __l)) break; - if ((m & xdigit) == xdigit && iswxdigit_l(ch, __l)) break; - if ((m & blank) == blank && iswblank_l(ch, __l)) break; -#endif - } - return low; -} - -const wchar_t* -ctype_byname::do_scan_not(mask m, const char_type* low, const char_type* high) const -{ - for (; low != high; ++low) - { -#ifdef _LIBCPP_WCTYPE_IS_MASK - if (!iswctype_l(*low, m, __l)) - break; -#else - wint_t ch = static_cast(*low); - if ((m & space) == space && iswspace_l(ch, __l)) continue; - if ((m & print) == print && iswprint_l(ch, __l)) continue; - if ((m & cntrl) == cntrl && iswcntrl_l(ch, __l)) continue; - if ((m & upper) == upper && iswupper_l(ch, __l)) continue; - if ((m & lower) == lower && iswlower_l(ch, __l)) continue; - if ((m & alpha) == alpha && iswalpha_l(ch, __l)) continue; - if ((m & digit) == digit && iswdigit_l(ch, __l)) continue; - if ((m & punct) == punct && iswpunct_l(ch, __l)) continue; - if ((m & xdigit) == xdigit && iswxdigit_l(ch, __l)) continue; - if ((m & blank) == blank && iswblank_l(ch, __l)) continue; - break; -#endif - } - return low; -} - -wchar_t -ctype_byname::do_toupper(char_type c) const -{ - return towupper_l(c, __l); -} - -const wchar_t* -ctype_byname::do_toupper(char_type* low, const char_type* high) const -{ - for (; low != high; ++low) - *low = towupper_l(*low, __l); - return low; -} - -wchar_t -ctype_byname::do_tolower(char_type c) const -{ - return towlower_l(c, __l); -} - -const wchar_t* -ctype_byname::do_tolower(char_type* low, const char_type* high) const -{ - for (; low != high; ++low) - *low = towlower_l(*low, __l); - return low; -} - -wchar_t -ctype_byname::do_widen(char c) const -{ - return __libcpp_btowc_l(c, __l); -} - -const char* -ctype_byname::do_widen(const char* low, const char* high, char_type* dest) const -{ - for (; low != high; ++low, ++dest) - *dest = __libcpp_btowc_l(*low, __l); - return low; -} - -char -ctype_byname::do_narrow(char_type c, char dfault) const -{ - int r = __libcpp_wctob_l(c, __l); - return r != static_cast(WEOF) ? static_cast(r) : dfault; -} - -const wchar_t* -ctype_byname::do_narrow(const char_type* low, const char_type* high, char dfault, char* dest) const -{ - for (; low != high; ++low, ++dest) - { - int r = __libcpp_wctob_l(*low, __l); - *dest = r != static_cast(WEOF) ? static_cast(r) : dfault; - } - return low; -} - -// template <> class codecvt - -locale::id codecvt::id; - -codecvt::~codecvt() -{ -} - -codecvt::result -codecvt::do_out(state_type&, - const intern_type* frm, const intern_type*, const intern_type*& frm_nxt, - extern_type* to, extern_type*, extern_type*& to_nxt) const -{ - frm_nxt = frm; - to_nxt = to; - return noconv; -} - -codecvt::result -codecvt::do_in(state_type&, - const extern_type* frm, const extern_type*, const extern_type*& frm_nxt, - intern_type* to, intern_type*, intern_type*& to_nxt) const -{ - frm_nxt = frm; - to_nxt = to; - return noconv; -} - -codecvt::result -codecvt::do_unshift(state_type&, - extern_type* to, extern_type*, extern_type*& to_nxt) const -{ - to_nxt = to; - return noconv; -} - -int -codecvt::do_encoding() const _NOEXCEPT -{ - return 1; -} - -bool -codecvt::do_always_noconv() const _NOEXCEPT -{ - return true; -} - -int -codecvt::do_length(state_type&, - const extern_type* frm, const extern_type* end, size_t mx) const -{ - return static_cast(min(mx, static_cast(end-frm))); -} - -int -codecvt::do_max_length() const _NOEXCEPT -{ - return 1; -} - -// template <> class codecvt - -locale::id codecvt::id; - -codecvt::codecvt(size_t refs) - : locale::facet(refs), - __l(_LIBCPP_GET_C_LOCALE) -{ -} - -codecvt::codecvt(const char* nm, size_t refs) - : locale::facet(refs), - __l(newlocale(LC_ALL_MASK, nm, 0)) -{ - if (__l == 0) - __throw_runtime_error("codecvt_byname::codecvt_byname" - " failed to construct for " + string(nm)); -} - -codecvt::~codecvt() -{ - if (__l != _LIBCPP_GET_C_LOCALE) - freelocale(__l); -} - -codecvt::result -codecvt::do_out(state_type& st, - const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt, - extern_type* to, extern_type* to_end, extern_type*& to_nxt) const -{ - // look for first internal null in frm - const intern_type* fend = frm; - for (; fend != frm_end; ++fend) - if (*fend == 0) - break; - // loop over all null-terminated sequences in frm - to_nxt = to; - for (frm_nxt = frm; frm != frm_end && to != to_end; frm = frm_nxt, to = to_nxt) - { - // save state in case it is needed to recover to_nxt on error - mbstate_t save_state = st; - size_t n = __libcpp_wcsnrtombs_l(to, &frm_nxt, static_cast(fend-frm), - static_cast(to_end-to), &st, __l); - if (n == size_t(-1)) - { - // need to recover to_nxt - for (to_nxt = to; frm != frm_nxt; ++frm) - { - n = __libcpp_wcrtomb_l(to_nxt, *frm, &save_state, __l); - if (n == size_t(-1)) - break; - to_nxt += n; - } - frm_nxt = frm; - return error; - } - if (n == 0) - return partial; - to_nxt += n; - if (to_nxt == to_end) - break; - if (fend != frm_end) // set up next null terminated sequence - { - // Try to write the terminating null - extern_type tmp[MB_LEN_MAX]; - n = __libcpp_wcrtomb_l(tmp, intern_type(), &st, __l); - if (n == size_t(-1)) // on error - return error; - if (n > static_cast(to_end-to_nxt)) // is there room? - return partial; - for (extern_type* p = tmp; n; --n) // write it - *to_nxt++ = *p++; - ++frm_nxt; - // look for next null in frm - for (fend = frm_nxt; fend != frm_end; ++fend) - if (*fend == 0) - break; - } - } - return frm_nxt == frm_end ? ok : partial; -} - -codecvt::result -codecvt::do_in(state_type& st, - const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt, - intern_type* to, intern_type* to_end, intern_type*& to_nxt) const -{ - // look for first internal null in frm - const extern_type* fend = frm; - for (; fend != frm_end; ++fend) - if (*fend == 0) - break; - // loop over all null-terminated sequences in frm - to_nxt = to; - for (frm_nxt = frm; frm != frm_end && to != to_end; frm = frm_nxt, to = to_nxt) - { - // save state in case it is needed to recover to_nxt on error - mbstate_t save_state = st; - size_t n = __libcpp_mbsnrtowcs_l(to, &frm_nxt, static_cast(fend-frm), - static_cast(to_end-to), &st, __l); - if (n == size_t(-1)) - { - // need to recover to_nxt - for (to_nxt = to; frm != frm_nxt; ++to_nxt) - { - n = __libcpp_mbrtowc_l(to_nxt, frm, static_cast(fend-frm), - &save_state, __l); - switch (n) - { - case 0: - ++frm; - break; - case size_t(-1): - frm_nxt = frm; - return error; - case size_t(-2): - frm_nxt = frm; - return partial; - default: - frm += n; - break; - } - } - frm_nxt = frm; - return frm_nxt == frm_end ? ok : partial; - } - if (n == size_t(-1)) - return error; - to_nxt += n; - if (to_nxt == to_end) - break; - if (fend != frm_end) // set up next null terminated sequence - { - // Try to write the terminating null - n = __libcpp_mbrtowc_l(to_nxt, frm_nxt, 1, &st, __l); - if (n != 0) // on error - return error; - ++to_nxt; - ++frm_nxt; - // look for next null in frm - for (fend = frm_nxt; fend != frm_end; ++fend) - if (*fend == 0) - break; - } - } - return frm_nxt == frm_end ? ok : partial; -} - -codecvt::result -codecvt::do_unshift(state_type& st, - extern_type* to, extern_type* to_end, extern_type*& to_nxt) const -{ - to_nxt = to; - extern_type tmp[MB_LEN_MAX]; - size_t n = __libcpp_wcrtomb_l(tmp, intern_type(), &st, __l); - if (n == size_t(-1) || n == 0) // on error - return error; - --n; - if (n > static_cast(to_end-to_nxt)) // is there room? - return partial; - for (extern_type* p = tmp; n; --n) // write it - *to_nxt++ = *p++; - return ok; -} - -int -codecvt::do_encoding() const _NOEXCEPT -{ - if (__libcpp_mbtowc_l(nullptr, nullptr, MB_LEN_MAX, __l) != 0) - return -1; - - // stateless encoding - if (__l == 0 || __libcpp_mb_cur_max_l(__l) == 1) // there are no known constant length encodings - return 1; // which take more than 1 char to form a wchar_t - return 0; -} - -bool -codecvt::do_always_noconv() const _NOEXCEPT -{ - return false; -} - -int -codecvt::do_length(state_type& st, - const extern_type* frm, const extern_type* frm_end, size_t mx) const -{ - int nbytes = 0; - for (size_t nwchar_t = 0; nwchar_t < mx && frm != frm_end; ++nwchar_t) - { - size_t n = __libcpp_mbrlen_l(frm, static_cast(frm_end-frm), &st, __l); - switch (n) - { - case 0: - ++nbytes; - ++frm; - break; - case size_t(-1): - case size_t(-2): - return nbytes; - default: - nbytes += n; - frm += n; - break; - } - } - return nbytes; -} - -int -codecvt::do_max_length() const _NOEXCEPT -{ - return __l == 0 ? 1 : static_cast(__libcpp_mb_cur_max_l(__l)); -} - -// Valid UTF ranges -// UTF-32 UTF-16 UTF-8 # of code points -// first second first second third fourth -// 000000 - 00007F 0000 - 007F 00 - 7F 127 -// 000080 - 0007FF 0080 - 07FF C2 - DF, 80 - BF 1920 -// 000800 - 000FFF 0800 - 0FFF E0 - E0, A0 - BF, 80 - BF 2048 -// 001000 - 00CFFF 1000 - CFFF E1 - EC, 80 - BF, 80 - BF 49152 -// 00D000 - 00D7FF D000 - D7FF ED - ED, 80 - 9F, 80 - BF 2048 -// 00D800 - 00DFFF invalid -// 00E000 - 00FFFF E000 - FFFF EE - EF, 80 - BF, 80 - BF 8192 -// 010000 - 03FFFF D800 - D8BF, DC00 - DFFF F0 - F0, 90 - BF, 80 - BF, 80 - BF 196608 -// 040000 - 0FFFFF D8C0 - DBBF, DC00 - DFFF F1 - F3, 80 - BF, 80 - BF, 80 - BF 786432 -// 100000 - 10FFFF DBC0 - DBFF, DC00 - DFFF F4 - F4, 80 - 8F, 80 - BF, 80 - BF 65536 - -static -codecvt_base::result -utf16_to_utf8(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt, - uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt, - unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0)) -{ - frm_nxt = frm; - to_nxt = to; - if (mode & generate_header) - { - if (to_end-to_nxt < 3) - return codecvt_base::partial; - *to_nxt++ = static_cast(0xEF); - *to_nxt++ = static_cast(0xBB); - *to_nxt++ = static_cast(0xBF); - } - for (; frm_nxt < frm_end; ++frm_nxt) - { - uint16_t wc1 = *frm_nxt; - if (wc1 > Maxcode) - return codecvt_base::error; - if (wc1 < 0x0080) - { - if (to_end-to_nxt < 1) - return codecvt_base::partial; - *to_nxt++ = static_cast(wc1); - } - else if (wc1 < 0x0800) - { - if (to_end-to_nxt < 2) - return codecvt_base::partial; - *to_nxt++ = static_cast(0xC0 | (wc1 >> 6)); - *to_nxt++ = static_cast(0x80 | (wc1 & 0x03F)); - } - else if (wc1 < 0xD800) - { - if (to_end-to_nxt < 3) - return codecvt_base::partial; - *to_nxt++ = static_cast(0xE0 | (wc1 >> 12)); - *to_nxt++ = static_cast(0x80 | ((wc1 & 0x0FC0) >> 6)); - *to_nxt++ = static_cast(0x80 | (wc1 & 0x003F)); - } - else if (wc1 < 0xDC00) - { - if (frm_end-frm_nxt < 2) - return codecvt_base::partial; - uint16_t wc2 = frm_nxt[1]; - if ((wc2 & 0xFC00) != 0xDC00) - return codecvt_base::error; - if (to_end-to_nxt < 4) - return codecvt_base::partial; - if (((((wc1 & 0x03C0UL) >> 6) + 1) << 16) + - ((wc1 & 0x003FUL) << 10) + (wc2 & 0x03FF) > Maxcode) - return codecvt_base::error; - ++frm_nxt; - uint8_t z = ((wc1 & 0x03C0) >> 6) + 1; - *to_nxt++ = static_cast(0xF0 | (z >> 2)); - *to_nxt++ = static_cast(0x80 | ((z & 0x03) << 4) | ((wc1 & 0x003C) >> 2)); - *to_nxt++ = static_cast(0x80 | ((wc1 & 0x0003) << 4) | ((wc2 & 0x03C0) >> 6)); - *to_nxt++ = static_cast(0x80 | (wc2 & 0x003F)); - } - else if (wc1 < 0xE000) - { - return codecvt_base::error; - } - else - { - if (to_end-to_nxt < 3) - return codecvt_base::partial; - *to_nxt++ = static_cast(0xE0 | (wc1 >> 12)); - *to_nxt++ = static_cast(0x80 | ((wc1 & 0x0FC0) >> 6)); - *to_nxt++ = static_cast(0x80 | (wc1 & 0x003F)); - } - } - return codecvt_base::ok; -} - -static -codecvt_base::result -utf16_to_utf8(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt, - uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt, - unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0)) -{ - frm_nxt = frm; - to_nxt = to; - if (mode & generate_header) - { - if (to_end-to_nxt < 3) - return codecvt_base::partial; - *to_nxt++ = static_cast(0xEF); - *to_nxt++ = static_cast(0xBB); - *to_nxt++ = static_cast(0xBF); - } - for (; frm_nxt < frm_end; ++frm_nxt) - { - uint16_t wc1 = static_cast(*frm_nxt); - if (wc1 > Maxcode) - return codecvt_base::error; - if (wc1 < 0x0080) - { - if (to_end-to_nxt < 1) - return codecvt_base::partial; - *to_nxt++ = static_cast(wc1); - } - else if (wc1 < 0x0800) - { - if (to_end-to_nxt < 2) - return codecvt_base::partial; - *to_nxt++ = static_cast(0xC0 | (wc1 >> 6)); - *to_nxt++ = static_cast(0x80 | (wc1 & 0x03F)); - } - else if (wc1 < 0xD800) - { - if (to_end-to_nxt < 3) - return codecvt_base::partial; - *to_nxt++ = static_cast(0xE0 | (wc1 >> 12)); - *to_nxt++ = static_cast(0x80 | ((wc1 & 0x0FC0) >> 6)); - *to_nxt++ = static_cast(0x80 | (wc1 & 0x003F)); - } - else if (wc1 < 0xDC00) - { - if (frm_end-frm_nxt < 2) - return codecvt_base::partial; - uint16_t wc2 = static_cast(frm_nxt[1]); - if ((wc2 & 0xFC00) != 0xDC00) - return codecvt_base::error; - if (to_end-to_nxt < 4) - return codecvt_base::partial; - if (((((wc1 & 0x03C0UL) >> 6) + 1) << 16) + - ((wc1 & 0x003FUL) << 10) + (wc2 & 0x03FF) > Maxcode) - return codecvt_base::error; - ++frm_nxt; - uint8_t z = ((wc1 & 0x03C0) >> 6) + 1; - *to_nxt++ = static_cast(0xF0 | (z >> 2)); - *to_nxt++ = static_cast(0x80 | ((z & 0x03) << 4) | ((wc1 & 0x003C) >> 2)); - *to_nxt++ = static_cast(0x80 | ((wc1 & 0x0003) << 4) | ((wc2 & 0x03C0) >> 6)); - *to_nxt++ = static_cast(0x80 | (wc2 & 0x003F)); - } - else if (wc1 < 0xE000) - { - return codecvt_base::error; - } - else - { - if (to_end-to_nxt < 3) - return codecvt_base::partial; - *to_nxt++ = static_cast(0xE0 | (wc1 >> 12)); - *to_nxt++ = static_cast(0x80 | ((wc1 & 0x0FC0) >> 6)); - *to_nxt++ = static_cast(0x80 | (wc1 & 0x003F)); - } - } - return codecvt_base::ok; -} - -static -codecvt_base::result -utf8_to_utf16(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt, - uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt, - unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0)) -{ - frm_nxt = frm; - to_nxt = to; - if (mode & consume_header) - { - if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB && - frm_nxt[2] == 0xBF) - frm_nxt += 3; - } - for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt) - { - uint8_t c1 = *frm_nxt; - if (c1 > Maxcode) - return codecvt_base::error; - if (c1 < 0x80) - { - *to_nxt = static_cast(c1); - ++frm_nxt; - } - else if (c1 < 0xC2) - { - return codecvt_base::error; - } - else if (c1 < 0xE0) - { - if (frm_end-frm_nxt < 2) - return codecvt_base::partial; - uint8_t c2 = frm_nxt[1]; - if ((c2 & 0xC0) != 0x80) - return codecvt_base::error; - uint16_t t = static_cast(((c1 & 0x1F) << 6) | (c2 & 0x3F)); - if (t > Maxcode) - return codecvt_base::error; - *to_nxt = t; - frm_nxt += 2; - } - else if (c1 < 0xF0) - { - if (frm_end-frm_nxt < 3) - return codecvt_base::partial; - uint8_t c2 = frm_nxt[1]; - uint8_t c3 = frm_nxt[2]; - switch (c1) - { - case 0xE0: - if ((c2 & 0xE0) != 0xA0) - return codecvt_base::error; - break; - case 0xED: - if ((c2 & 0xE0) != 0x80) - return codecvt_base::error; - break; - default: - if ((c2 & 0xC0) != 0x80) - return codecvt_base::error; - break; - } - if ((c3 & 0xC0) != 0x80) - return codecvt_base::error; - uint16_t t = static_cast(((c1 & 0x0F) << 12) - | ((c2 & 0x3F) << 6) - | (c3 & 0x3F)); - if (t > Maxcode) - return codecvt_base::error; - *to_nxt = t; - frm_nxt += 3; - } - else if (c1 < 0xF5) - { - if (frm_end-frm_nxt < 4) - return codecvt_base::partial; - uint8_t c2 = frm_nxt[1]; - uint8_t c3 = frm_nxt[2]; - uint8_t c4 = frm_nxt[3]; - switch (c1) - { - case 0xF0: - if (!(0x90 <= c2 && c2 <= 0xBF)) - return codecvt_base::error; - break; - case 0xF4: - if ((c2 & 0xF0) != 0x80) - return codecvt_base::error; - break; - default: - if ((c2 & 0xC0) != 0x80) - return codecvt_base::error; - break; - } - if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80) - return codecvt_base::error; - if (to_end-to_nxt < 2) - return codecvt_base::partial; - if ((((c1 & 7UL) << 18) + - ((c2 & 0x3FUL) << 12) + - ((c3 & 0x3FUL) << 6) + (c4 & 0x3F)) > Maxcode) - return codecvt_base::error; - *to_nxt = static_cast( - 0xD800 - | (((((c1 & 0x07) << 2) | ((c2 & 0x30) >> 4)) - 1) << 6) - | ((c2 & 0x0F) << 2) - | ((c3 & 0x30) >> 4)); - *++to_nxt = static_cast( - 0xDC00 - | ((c3 & 0x0F) << 6) - | (c4 & 0x3F)); - frm_nxt += 4; - } - else - { - return codecvt_base::error; - } - } - return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok; -} - -static -codecvt_base::result -utf8_to_utf16(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt, - uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt, - unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0)) -{ - frm_nxt = frm; - to_nxt = to; - if (mode & consume_header) - { - if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB && - frm_nxt[2] == 0xBF) - frm_nxt += 3; - } - for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt) - { - uint8_t c1 = *frm_nxt; - if (c1 > Maxcode) - return codecvt_base::error; - if (c1 < 0x80) - { - *to_nxt = static_cast(c1); - ++frm_nxt; - } - else if (c1 < 0xC2) - { - return codecvt_base::error; - } - else if (c1 < 0xE0) - { - if (frm_end-frm_nxt < 2) - return codecvt_base::partial; - uint8_t c2 = frm_nxt[1]; - if ((c2 & 0xC0) != 0x80) - return codecvt_base::error; - uint16_t t = static_cast(((c1 & 0x1F) << 6) | (c2 & 0x3F)); - if (t > Maxcode) - return codecvt_base::error; - *to_nxt = static_cast(t); - frm_nxt += 2; - } - else if (c1 < 0xF0) - { - if (frm_end-frm_nxt < 3) - return codecvt_base::partial; - uint8_t c2 = frm_nxt[1]; - uint8_t c3 = frm_nxt[2]; - switch (c1) - { - case 0xE0: - if ((c2 & 0xE0) != 0xA0) - return codecvt_base::error; - break; - case 0xED: - if ((c2 & 0xE0) != 0x80) - return codecvt_base::error; - break; - default: - if ((c2 & 0xC0) != 0x80) - return codecvt_base::error; - break; - } - if ((c3 & 0xC0) != 0x80) - return codecvt_base::error; - uint16_t t = static_cast(((c1 & 0x0F) << 12) - | ((c2 & 0x3F) << 6) - | (c3 & 0x3F)); - if (t > Maxcode) - return codecvt_base::error; - *to_nxt = static_cast(t); - frm_nxt += 3; - } - else if (c1 < 0xF5) - { - if (frm_end-frm_nxt < 4) - return codecvt_base::partial; - uint8_t c2 = frm_nxt[1]; - uint8_t c3 = frm_nxt[2]; - uint8_t c4 = frm_nxt[3]; - switch (c1) - { - case 0xF0: - if (!(0x90 <= c2 && c2 <= 0xBF)) - return codecvt_base::error; - break; - case 0xF4: - if ((c2 & 0xF0) != 0x80) - return codecvt_base::error; - break; - default: - if ((c2 & 0xC0) != 0x80) - return codecvt_base::error; - break; - } - if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80) - return codecvt_base::error; - if (to_end-to_nxt < 2) - return codecvt_base::partial; - if ((((c1 & 7UL) << 18) + - ((c2 & 0x3FUL) << 12) + - ((c3 & 0x3FUL) << 6) + (c4 & 0x3F)) > Maxcode) - return codecvt_base::error; - *to_nxt = static_cast( - 0xD800 - | (((((c1 & 0x07) << 2) | ((c2 & 0x30) >> 4)) - 1) << 6) - | ((c2 & 0x0F) << 2) - | ((c3 & 0x30) >> 4)); - *++to_nxt = static_cast( - 0xDC00 - | ((c3 & 0x0F) << 6) - | (c4 & 0x3F)); - frm_nxt += 4; - } - else - { - return codecvt_base::error; - } - } - return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok; -} - -static -int -utf8_to_utf16_length(const uint8_t* frm, const uint8_t* frm_end, - size_t mx, unsigned long Maxcode = 0x10FFFF, - codecvt_mode mode = codecvt_mode(0)) -{ - const uint8_t* frm_nxt = frm; - if (mode & consume_header) - { - if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB && - frm_nxt[2] == 0xBF) - frm_nxt += 3; - } - for (size_t nchar16_t = 0; frm_nxt < frm_end && nchar16_t < mx; ++nchar16_t) - { - uint8_t c1 = *frm_nxt; - if (c1 > Maxcode) - break; - if (c1 < 0x80) - { - ++frm_nxt; - } - else if (c1 < 0xC2) - { - break; - } - else if (c1 < 0xE0) - { - if ((frm_end-frm_nxt < 2) || (frm_nxt[1] & 0xC0) != 0x80) - break; - uint16_t t = static_cast(((c1 & 0x1F) << 6) | (frm_nxt[1] & 0x3F)); - if (t > Maxcode) - break; - frm_nxt += 2; - } - else if (c1 < 0xF0) - { - if (frm_end-frm_nxt < 3) - break; - uint8_t c2 = frm_nxt[1]; - uint8_t c3 = frm_nxt[2]; - switch (c1) - { - case 0xE0: - if ((c2 & 0xE0) != 0xA0) - return static_cast(frm_nxt - frm); - break; - case 0xED: - if ((c2 & 0xE0) != 0x80) - return static_cast(frm_nxt - frm); - break; - default: - if ((c2 & 0xC0) != 0x80) - return static_cast(frm_nxt - frm); - break; - } - if ((c3 & 0xC0) != 0x80) - break; - if ((((c1 & 0x0Fu) << 12) | ((c2 & 0x3Fu) << 6) | (c3 & 0x3Fu)) > Maxcode) - break; - frm_nxt += 3; - } - else if (c1 < 0xF5) - { - if (frm_end-frm_nxt < 4 || mx-nchar16_t < 2) - break; - uint8_t c2 = frm_nxt[1]; - uint8_t c3 = frm_nxt[2]; - uint8_t c4 = frm_nxt[3]; - switch (c1) - { - case 0xF0: - if (!(0x90 <= c2 && c2 <= 0xBF)) - return static_cast(frm_nxt - frm); - break; - case 0xF4: - if ((c2 & 0xF0) != 0x80) - return static_cast(frm_nxt - frm); - break; - default: - if ((c2 & 0xC0) != 0x80) - return static_cast(frm_nxt - frm); - break; - } - if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80) - break; - if ((((c1 & 7UL) << 18) + - ((c2 & 0x3FUL) << 12) + - ((c3 & 0x3FUL) << 6) + (c4 & 0x3F)) > Maxcode) - break; - ++nchar16_t; - frm_nxt += 4; - } - else - { - break; - } - } - return static_cast(frm_nxt - frm); -} - -static -codecvt_base::result -ucs4_to_utf8(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt, - uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt, - unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0)) -{ - frm_nxt = frm; - to_nxt = to; - if (mode & generate_header) - { - if (to_end-to_nxt < 3) - return codecvt_base::partial; - *to_nxt++ = static_cast(0xEF); - *to_nxt++ = static_cast(0xBB); - *to_nxt++ = static_cast(0xBF); - } - for (; frm_nxt < frm_end; ++frm_nxt) - { - uint32_t wc = *frm_nxt; - if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode) - return codecvt_base::error; - if (wc < 0x000080) - { - if (to_end-to_nxt < 1) - return codecvt_base::partial; - *to_nxt++ = static_cast(wc); - } - else if (wc < 0x000800) - { - if (to_end-to_nxt < 2) - return codecvt_base::partial; - *to_nxt++ = static_cast(0xC0 | (wc >> 6)); - *to_nxt++ = static_cast(0x80 | (wc & 0x03F)); - } - else if (wc < 0x010000) - { - if (to_end-to_nxt < 3) - return codecvt_base::partial; - *to_nxt++ = static_cast(0xE0 | (wc >> 12)); - *to_nxt++ = static_cast(0x80 | ((wc & 0x0FC0) >> 6)); - *to_nxt++ = static_cast(0x80 | (wc & 0x003F)); - } - else // if (wc < 0x110000) - { - if (to_end-to_nxt < 4) - return codecvt_base::partial; - *to_nxt++ = static_cast(0xF0 | (wc >> 18)); - *to_nxt++ = static_cast(0x80 | ((wc & 0x03F000) >> 12)); - *to_nxt++ = static_cast(0x80 | ((wc & 0x000FC0) >> 6)); - *to_nxt++ = static_cast(0x80 | (wc & 0x00003F)); - } - } - return codecvt_base::ok; -} - -static -codecvt_base::result -utf8_to_ucs4(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt, - uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt, - unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0)) -{ - frm_nxt = frm; - to_nxt = to; - if (mode & consume_header) - { - if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB && - frm_nxt[2] == 0xBF) - frm_nxt += 3; - } - for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt) - { - uint8_t c1 = static_cast(*frm_nxt); - if (c1 < 0x80) - { - if (c1 > Maxcode) - return codecvt_base::error; - *to_nxt = static_cast(c1); - ++frm_nxt; - } - else if (c1 < 0xC2) - { - return codecvt_base::error; - } - else if (c1 < 0xE0) - { - if (frm_end-frm_nxt < 2) - return codecvt_base::partial; - uint8_t c2 = frm_nxt[1]; - if ((c2 & 0xC0) != 0x80) - return codecvt_base::error; - uint32_t t = static_cast(((c1 & 0x1F) << 6) - | (c2 & 0x3F)); - if (t > Maxcode) - return codecvt_base::error; - *to_nxt = t; - frm_nxt += 2; - } - else if (c1 < 0xF0) - { - if (frm_end-frm_nxt < 3) - return codecvt_base::partial; - uint8_t c2 = frm_nxt[1]; - uint8_t c3 = frm_nxt[2]; - switch (c1) - { - case 0xE0: - if ((c2 & 0xE0) != 0xA0) - return codecvt_base::error; - break; - case 0xED: - if ((c2 & 0xE0) != 0x80) - return codecvt_base::error; - break; - default: - if ((c2 & 0xC0) != 0x80) - return codecvt_base::error; - break; - } - if ((c3 & 0xC0) != 0x80) - return codecvt_base::error; - uint32_t t = static_cast(((c1 & 0x0F) << 12) - | ((c2 & 0x3F) << 6) - | (c3 & 0x3F)); - if (t > Maxcode) - return codecvt_base::error; - *to_nxt = t; - frm_nxt += 3; - } - else if (c1 < 0xF5) - { - if (frm_end-frm_nxt < 4) - return codecvt_base::partial; - uint8_t c2 = frm_nxt[1]; - uint8_t c3 = frm_nxt[2]; - uint8_t c4 = frm_nxt[3]; - switch (c1) - { - case 0xF0: - if (!(0x90 <= c2 && c2 <= 0xBF)) - return codecvt_base::error; - break; - case 0xF4: - if ((c2 & 0xF0) != 0x80) - return codecvt_base::error; - break; - default: - if ((c2 & 0xC0) != 0x80) - return codecvt_base::error; - break; - } - if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80) - return codecvt_base::error; - uint32_t t = static_cast(((c1 & 0x07) << 18) - | ((c2 & 0x3F) << 12) - | ((c3 & 0x3F) << 6) - | (c4 & 0x3F)); - if (t > Maxcode) - return codecvt_base::error; - *to_nxt = t; - frm_nxt += 4; - } - else - { - return codecvt_base::error; - } - } - return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok; -} - -static -int -utf8_to_ucs4_length(const uint8_t* frm, const uint8_t* frm_end, - size_t mx, unsigned long Maxcode = 0x10FFFF, - codecvt_mode mode = codecvt_mode(0)) -{ - const uint8_t* frm_nxt = frm; - if (mode & consume_header) - { - if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB && - frm_nxt[2] == 0xBF) - frm_nxt += 3; - } - for (size_t nchar32_t = 0; frm_nxt < frm_end && nchar32_t < mx; ++nchar32_t) - { - uint8_t c1 = static_cast(*frm_nxt); - if (c1 < 0x80) - { - if (c1 > Maxcode) - break; - ++frm_nxt; - } - else if (c1 < 0xC2) - { - break; - } - else if (c1 < 0xE0) - { - if ((frm_end-frm_nxt < 2) || ((frm_nxt[1] & 0xC0) != 0x80)) - break; - if ((((c1 & 0x1Fu) << 6) | (frm_nxt[1] & 0x3Fu)) > Maxcode) - break; - frm_nxt += 2; - } - else if (c1 < 0xF0) - { - if (frm_end-frm_nxt < 3) - break; - uint8_t c2 = frm_nxt[1]; - uint8_t c3 = frm_nxt[2]; - switch (c1) - { - case 0xE0: - if ((c2 & 0xE0) != 0xA0) - return static_cast(frm_nxt - frm); - break; - case 0xED: - if ((c2 & 0xE0) != 0x80) - return static_cast(frm_nxt - frm); - break; - default: - if ((c2 & 0xC0) != 0x80) - return static_cast(frm_nxt - frm); - break; - } - if ((c3 & 0xC0) != 0x80) - break; - if ((((c1 & 0x0Fu) << 12) | ((c2 & 0x3Fu) << 6) | (c3 & 0x3Fu)) > Maxcode) - break; - frm_nxt += 3; - } - else if (c1 < 0xF5) - { - if (frm_end-frm_nxt < 4) - break; - uint8_t c2 = frm_nxt[1]; - uint8_t c3 = frm_nxt[2]; - uint8_t c4 = frm_nxt[3]; - switch (c1) - { - case 0xF0: - if (!(0x90 <= c2 && c2 <= 0xBF)) - return static_cast(frm_nxt - frm); - break; - case 0xF4: - if ((c2 & 0xF0) != 0x80) - return static_cast(frm_nxt - frm); - break; - default: - if ((c2 & 0xC0) != 0x80) - return static_cast(frm_nxt - frm); - break; - } - if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80) - break; - if ((((c1 & 0x07u) << 18) | ((c2 & 0x3Fu) << 12) | - ((c3 & 0x3Fu) << 6) | (c4 & 0x3Fu)) > Maxcode) - break; - frm_nxt += 4; - } - else - { - break; - } - } - return static_cast(frm_nxt - frm); -} - -static -codecvt_base::result -ucs2_to_utf8(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt, - uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt, - unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0)) -{ - frm_nxt = frm; - to_nxt = to; - if (mode & generate_header) - { - if (to_end-to_nxt < 3) - return codecvt_base::partial; - *to_nxt++ = static_cast(0xEF); - *to_nxt++ = static_cast(0xBB); - *to_nxt++ = static_cast(0xBF); - } - for (; frm_nxt < frm_end; ++frm_nxt) - { - uint16_t wc = *frm_nxt; - if ((wc & 0xF800) == 0xD800 || wc > Maxcode) - return codecvt_base::error; - if (wc < 0x0080) - { - if (to_end-to_nxt < 1) - return codecvt_base::partial; - *to_nxt++ = static_cast(wc); - } - else if (wc < 0x0800) - { - if (to_end-to_nxt < 2) - return codecvt_base::partial; - *to_nxt++ = static_cast(0xC0 | (wc >> 6)); - *to_nxt++ = static_cast(0x80 | (wc & 0x03F)); - } - else // if (wc <= 0xFFFF) - { - if (to_end-to_nxt < 3) - return codecvt_base::partial; - *to_nxt++ = static_cast(0xE0 | (wc >> 12)); - *to_nxt++ = static_cast(0x80 | ((wc & 0x0FC0) >> 6)); - *to_nxt++ = static_cast(0x80 | (wc & 0x003F)); - } - } - return codecvt_base::ok; -} - -static -codecvt_base::result -utf8_to_ucs2(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt, - uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt, - unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0)) -{ - frm_nxt = frm; - to_nxt = to; - if (mode & consume_header) - { - if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB && - frm_nxt[2] == 0xBF) - frm_nxt += 3; - } - for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt) - { - uint8_t c1 = static_cast(*frm_nxt); - if (c1 < 0x80) - { - if (c1 > Maxcode) - return codecvt_base::error; - *to_nxt = static_cast(c1); - ++frm_nxt; - } - else if (c1 < 0xC2) - { - return codecvt_base::error; - } - else if (c1 < 0xE0) - { - if (frm_end-frm_nxt < 2) - return codecvt_base::partial; - uint8_t c2 = frm_nxt[1]; - if ((c2 & 0xC0) != 0x80) - return codecvt_base::error; - uint16_t t = static_cast(((c1 & 0x1F) << 6) - | (c2 & 0x3F)); - if (t > Maxcode) - return codecvt_base::error; - *to_nxt = t; - frm_nxt += 2; - } - else if (c1 < 0xF0) - { - if (frm_end-frm_nxt < 3) - return codecvt_base::partial; - uint8_t c2 = frm_nxt[1]; - uint8_t c3 = frm_nxt[2]; - switch (c1) - { - case 0xE0: - if ((c2 & 0xE0) != 0xA0) - return codecvt_base::error; - break; - case 0xED: - if ((c2 & 0xE0) != 0x80) - return codecvt_base::error; - break; - default: - if ((c2 & 0xC0) != 0x80) - return codecvt_base::error; - break; - } - if ((c3 & 0xC0) != 0x80) - return codecvt_base::error; - uint16_t t = static_cast(((c1 & 0x0F) << 12) - | ((c2 & 0x3F) << 6) - | (c3 & 0x3F)); - if (t > Maxcode) - return codecvt_base::error; - *to_nxt = t; - frm_nxt += 3; - } - else - { - return codecvt_base::error; - } - } - return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok; -} - -static -int -utf8_to_ucs2_length(const uint8_t* frm, const uint8_t* frm_end, - size_t mx, unsigned long Maxcode = 0x10FFFF, - codecvt_mode mode = codecvt_mode(0)) -{ - const uint8_t* frm_nxt = frm; - if (mode & consume_header) - { - if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB && - frm_nxt[2] == 0xBF) - frm_nxt += 3; - } - for (size_t nchar32_t = 0; frm_nxt < frm_end && nchar32_t < mx; ++nchar32_t) - { - uint8_t c1 = static_cast(*frm_nxt); - if (c1 < 0x80) - { - if (c1 > Maxcode) - break; - ++frm_nxt; - } - else if (c1 < 0xC2) - { - break; - } - else if (c1 < 0xE0) - { - if ((frm_end-frm_nxt < 2) || ((frm_nxt[1] & 0xC0) != 0x80)) - break; - if ((((c1 & 0x1Fu) << 6) | (frm_nxt[1] & 0x3Fu)) > Maxcode) - break; - frm_nxt += 2; - } - else if (c1 < 0xF0) - { - if (frm_end-frm_nxt < 3) - break; - uint8_t c2 = frm_nxt[1]; - uint8_t c3 = frm_nxt[2]; - switch (c1) - { - case 0xE0: - if ((c2 & 0xE0) != 0xA0) - return static_cast(frm_nxt - frm); - break; - case 0xED: - if ((c2 & 0xE0) != 0x80) - return static_cast(frm_nxt - frm); - break; - default: - if ((c2 & 0xC0) != 0x80) - return static_cast(frm_nxt - frm); - break; - } - if ((c3 & 0xC0) != 0x80) - break; - if ((((c1 & 0x0Fu) << 12) | ((c2 & 0x3Fu) << 6) | (c3 & 0x3Fu)) > Maxcode) - break; - frm_nxt += 3; - } - else - { - break; - } - } - return static_cast(frm_nxt - frm); -} - -static -codecvt_base::result -ucs4_to_utf16be(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt, - uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt, - unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0)) -{ - frm_nxt = frm; - to_nxt = to; - if (mode & generate_header) - { - if (to_end-to_nxt < 2) - return codecvt_base::partial; - *to_nxt++ = static_cast(0xFE); - *to_nxt++ = static_cast(0xFF); - } - for (; frm_nxt < frm_end; ++frm_nxt) - { - uint32_t wc = *frm_nxt; - if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode) - return codecvt_base::error; - if (wc < 0x010000) - { - if (to_end-to_nxt < 2) - return codecvt_base::partial; - *to_nxt++ = static_cast(wc >> 8); - *to_nxt++ = static_cast(wc); - } - else - { - if (to_end-to_nxt < 4) - return codecvt_base::partial; - uint16_t t = static_cast( - 0xD800 - | ((((wc & 0x1F0000) >> 16) - 1) << 6) - | ((wc & 0x00FC00) >> 10)); - *to_nxt++ = static_cast(t >> 8); - *to_nxt++ = static_cast(t); - t = static_cast(0xDC00 | (wc & 0x03FF)); - *to_nxt++ = static_cast(t >> 8); - *to_nxt++ = static_cast(t); - } - } - return codecvt_base::ok; -} - -static -codecvt_base::result -utf16be_to_ucs4(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt, - uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt, - unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0)) -{ - frm_nxt = frm; - to_nxt = to; - if (mode & consume_header) - { - if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF) - frm_nxt += 2; - } - for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt) - { - uint16_t c1 = static_cast(frm_nxt[0] << 8 | frm_nxt[1]); - if ((c1 & 0xFC00) == 0xDC00) - return codecvt_base::error; - if ((c1 & 0xFC00) != 0xD800) - { - if (c1 > Maxcode) - return codecvt_base::error; - *to_nxt = static_cast(c1); - frm_nxt += 2; - } - else - { - if (frm_end-frm_nxt < 4) - return codecvt_base::partial; - uint16_t c2 = static_cast(frm_nxt[2] << 8 | frm_nxt[3]); - if ((c2 & 0xFC00) != 0xDC00) - return codecvt_base::error; - uint32_t t = static_cast( - ((((c1 & 0x03C0) >> 6) + 1) << 16) - | ((c1 & 0x003F) << 10) - | (c2 & 0x03FF)); - if (t > Maxcode) - return codecvt_base::error; - *to_nxt = t; - frm_nxt += 4; - } - } - return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok; -} - -static -int -utf16be_to_ucs4_length(const uint8_t* frm, const uint8_t* frm_end, - size_t mx, unsigned long Maxcode = 0x10FFFF, - codecvt_mode mode = codecvt_mode(0)) -{ - const uint8_t* frm_nxt = frm; - if (mode & consume_header) - { - if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF) - frm_nxt += 2; - } - for (size_t nchar32_t = 0; frm_nxt < frm_end - 1 && nchar32_t < mx; ++nchar32_t) - { - uint16_t c1 = static_cast(frm_nxt[0] << 8 | frm_nxt[1]); - if ((c1 & 0xFC00) == 0xDC00) - break; - if ((c1 & 0xFC00) != 0xD800) - { - if (c1 > Maxcode) - break; - frm_nxt += 2; - } - else - { - if (frm_end-frm_nxt < 4) - break; - uint16_t c2 = static_cast(frm_nxt[2] << 8 | frm_nxt[3]); - if ((c2 & 0xFC00) != 0xDC00) - break; - uint32_t t = static_cast( - ((((c1 & 0x03C0) >> 6) + 1) << 16) - | ((c1 & 0x003F) << 10) - | (c2 & 0x03FF)); - if (t > Maxcode) - break; - frm_nxt += 4; - } - } - return static_cast(frm_nxt - frm); -} - -static -codecvt_base::result -ucs4_to_utf16le(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt, - uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt, - unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0)) -{ - frm_nxt = frm; - to_nxt = to; - if (mode & generate_header) - { - if (to_end - to_nxt < 2) - return codecvt_base::partial; - *to_nxt++ = static_cast(0xFF); - *to_nxt++ = static_cast(0xFE); - } - for (; frm_nxt < frm_end; ++frm_nxt) - { - uint32_t wc = *frm_nxt; - if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode) - return codecvt_base::error; - if (wc < 0x010000) - { - if (to_end-to_nxt < 2) - return codecvt_base::partial; - *to_nxt++ = static_cast(wc); - *to_nxt++ = static_cast(wc >> 8); - } - else - { - if (to_end-to_nxt < 4) - return codecvt_base::partial; - uint16_t t = static_cast( - 0xD800 - | ((((wc & 0x1F0000) >> 16) - 1) << 6) - | ((wc & 0x00FC00) >> 10)); - *to_nxt++ = static_cast(t); - *to_nxt++ = static_cast(t >> 8); - t = static_cast(0xDC00 | (wc & 0x03FF)); - *to_nxt++ = static_cast(t); - *to_nxt++ = static_cast(t >> 8); - } - } - return codecvt_base::ok; -} - -static -codecvt_base::result -utf16le_to_ucs4(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt, - uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt, - unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0)) -{ - frm_nxt = frm; - to_nxt = to; - if (mode & consume_header) - { - if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE) - frm_nxt += 2; - } - for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt) - { - uint16_t c1 = static_cast(frm_nxt[1] << 8 | frm_nxt[0]); - if ((c1 & 0xFC00) == 0xDC00) - return codecvt_base::error; - if ((c1 & 0xFC00) != 0xD800) - { - if (c1 > Maxcode) - return codecvt_base::error; - *to_nxt = static_cast(c1); - frm_nxt += 2; - } - else - { - if (frm_end-frm_nxt < 4) - return codecvt_base::partial; - uint16_t c2 = static_cast(frm_nxt[3] << 8 | frm_nxt[2]); - if ((c2 & 0xFC00) != 0xDC00) - return codecvt_base::error; - uint32_t t = static_cast( - ((((c1 & 0x03C0) >> 6) + 1) << 16) - | ((c1 & 0x003F) << 10) - | (c2 & 0x03FF)); - if (t > Maxcode) - return codecvt_base::error; - *to_nxt = t; - frm_nxt += 4; - } - } - return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok; -} - -static -int -utf16le_to_ucs4_length(const uint8_t* frm, const uint8_t* frm_end, - size_t mx, unsigned long Maxcode = 0x10FFFF, - codecvt_mode mode = codecvt_mode(0)) -{ - const uint8_t* frm_nxt = frm; - if (mode & consume_header) - { - if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE) - frm_nxt += 2; - } - for (size_t nchar32_t = 0; frm_nxt < frm_end - 1 && nchar32_t < mx; ++nchar32_t) - { - uint16_t c1 = static_cast(frm_nxt[1] << 8 | frm_nxt[0]); - if ((c1 & 0xFC00) == 0xDC00) - break; - if ((c1 & 0xFC00) != 0xD800) - { - if (c1 > Maxcode) - break; - frm_nxt += 2; - } - else - { - if (frm_end-frm_nxt < 4) - break; - uint16_t c2 = static_cast(frm_nxt[3] << 8 | frm_nxt[2]); - if ((c2 & 0xFC00) != 0xDC00) - break; - uint32_t t = static_cast( - ((((c1 & 0x03C0) >> 6) + 1) << 16) - | ((c1 & 0x003F) << 10) - | (c2 & 0x03FF)); - if (t > Maxcode) - break; - frm_nxt += 4; - } - } - return static_cast(frm_nxt - frm); -} - -static -codecvt_base::result -ucs2_to_utf16be(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt, - uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt, - unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0)) -{ - frm_nxt = frm; - to_nxt = to; - if (mode & generate_header) - { - if (to_end-to_nxt < 2) - return codecvt_base::partial; - *to_nxt++ = static_cast(0xFE); - *to_nxt++ = static_cast(0xFF); - } - for (; frm_nxt < frm_end; ++frm_nxt) - { - uint16_t wc = *frm_nxt; - if ((wc & 0xF800) == 0xD800 || wc > Maxcode) - return codecvt_base::error; - if (to_end-to_nxt < 2) - return codecvt_base::partial; - *to_nxt++ = static_cast(wc >> 8); - *to_nxt++ = static_cast(wc); - } - return codecvt_base::ok; -} - -static -codecvt_base::result -utf16be_to_ucs2(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt, - uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt, - unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0)) -{ - frm_nxt = frm; - to_nxt = to; - if (mode & consume_header) - { - if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF) - frm_nxt += 2; - } - for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt) - { - uint16_t c1 = static_cast(frm_nxt[0] << 8 | frm_nxt[1]); - if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode) - return codecvt_base::error; - *to_nxt = c1; - frm_nxt += 2; - } - return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok; -} - -static -int -utf16be_to_ucs2_length(const uint8_t* frm, const uint8_t* frm_end, - size_t mx, unsigned long Maxcode = 0x10FFFF, - codecvt_mode mode = codecvt_mode(0)) -{ - const uint8_t* frm_nxt = frm; - if (mode & consume_header) - { - if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF) - frm_nxt += 2; - } - for (size_t nchar16_t = 0; frm_nxt < frm_end - 1 && nchar16_t < mx; ++nchar16_t) - { - uint16_t c1 = static_cast(frm_nxt[0] << 8 | frm_nxt[1]); - if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode) - break; - frm_nxt += 2; - } - return static_cast(frm_nxt - frm); -} - -static -codecvt_base::result -ucs2_to_utf16le(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt, - uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt, - unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0)) -{ - frm_nxt = frm; - to_nxt = to; - if (mode & generate_header) - { - if (to_end-to_nxt < 2) - return codecvt_base::partial; - *to_nxt++ = static_cast(0xFF); - *to_nxt++ = static_cast(0xFE); - } - for (; frm_nxt < frm_end; ++frm_nxt) - { - uint16_t wc = *frm_nxt; - if ((wc & 0xF800) == 0xD800 || wc > Maxcode) - return codecvt_base::error; - if (to_end-to_nxt < 2) - return codecvt_base::partial; - *to_nxt++ = static_cast(wc); - *to_nxt++ = static_cast(wc >> 8); - } - return codecvt_base::ok; -} - -static -codecvt_base::result -utf16le_to_ucs2(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt, - uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt, - unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0)) -{ - frm_nxt = frm; - to_nxt = to; - if (mode & consume_header) - { - if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE) - frm_nxt += 2; - } - for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt) - { - uint16_t c1 = static_cast(frm_nxt[1] << 8 | frm_nxt[0]); - if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode) - return codecvt_base::error; - *to_nxt = c1; - frm_nxt += 2; - } - return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok; -} - -static -int -utf16le_to_ucs2_length(const uint8_t* frm, const uint8_t* frm_end, - size_t mx, unsigned long Maxcode = 0x10FFFF, - codecvt_mode mode = codecvt_mode(0)) -{ - const uint8_t* frm_nxt = frm; - frm_nxt = frm; - if (mode & consume_header) - { - if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE) - frm_nxt += 2; - } - for (size_t nchar16_t = 0; frm_nxt < frm_end - 1 && nchar16_t < mx; ++nchar16_t) - { - uint16_t c1 = static_cast(frm_nxt[1] << 8 | frm_nxt[0]); - if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode) - break; - frm_nxt += 2; - } - return static_cast(frm_nxt - frm); -} - -// template <> class codecvt - -locale::id codecvt::id; - -codecvt::~codecvt() -{ -} - -codecvt::result -codecvt::do_out(state_type&, - const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt, - extern_type* to, extern_type* to_end, extern_type*& to_nxt) const -{ - const uint16_t* _frm = reinterpret_cast(frm); - const uint16_t* _frm_end = reinterpret_cast(frm_end); - const uint16_t* _frm_nxt = _frm; - uint8_t* _to = reinterpret_cast(to); - uint8_t* _to_end = reinterpret_cast(to_end); - uint8_t* _to_nxt = _to; - result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt); - frm_nxt = frm + (_frm_nxt - _frm); - to_nxt = to + (_to_nxt - _to); - return r; -} - -codecvt::result -codecvt::do_in(state_type&, - const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt, - intern_type* to, intern_type* to_end, intern_type*& to_nxt) const -{ - const uint8_t* _frm = reinterpret_cast(frm); - const uint8_t* _frm_end = reinterpret_cast(frm_end); - const uint8_t* _frm_nxt = _frm; - uint16_t* _to = reinterpret_cast(to); - uint16_t* _to_end = reinterpret_cast(to_end); - uint16_t* _to_nxt = _to; - result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt); - frm_nxt = frm + (_frm_nxt - _frm); - to_nxt = to + (_to_nxt - _to); - return r; -} - -codecvt::result -codecvt::do_unshift(state_type&, - extern_type* to, extern_type*, extern_type*& to_nxt) const -{ - to_nxt = to; - return noconv; -} - -int -codecvt::do_encoding() const _NOEXCEPT -{ - return 0; -} - -bool -codecvt::do_always_noconv() const _NOEXCEPT -{ - return false; -} - -int -codecvt::do_length(state_type&, - const extern_type* frm, const extern_type* frm_end, size_t mx) const -{ - const uint8_t* _frm = reinterpret_cast(frm); - const uint8_t* _frm_end = reinterpret_cast(frm_end); - return utf8_to_utf16_length(_frm, _frm_end, mx); -} - -int -codecvt::do_max_length() const _NOEXCEPT -{ - return 4; -} - -// template <> class codecvt - -locale::id codecvt::id; - -codecvt::~codecvt() -{ -} - -codecvt::result -codecvt::do_out(state_type&, - const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt, - extern_type* to, extern_type* to_end, extern_type*& to_nxt) const -{ - const uint32_t* _frm = reinterpret_cast(frm); - const uint32_t* _frm_end = reinterpret_cast(frm_end); - const uint32_t* _frm_nxt = _frm; - uint8_t* _to = reinterpret_cast(to); - uint8_t* _to_end = reinterpret_cast(to_end); - uint8_t* _to_nxt = _to; - result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt); - frm_nxt = frm + (_frm_nxt - _frm); - to_nxt = to + (_to_nxt - _to); - return r; -} - -codecvt::result -codecvt::do_in(state_type&, - const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt, - intern_type* to, intern_type* to_end, intern_type*& to_nxt) const -{ - const uint8_t* _frm = reinterpret_cast(frm); - const uint8_t* _frm_end = reinterpret_cast(frm_end); - const uint8_t* _frm_nxt = _frm; - uint32_t* _to = reinterpret_cast(to); - uint32_t* _to_end = reinterpret_cast(to_end); - uint32_t* _to_nxt = _to; - result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt); - frm_nxt = frm + (_frm_nxt - _frm); - to_nxt = to + (_to_nxt - _to); - return r; -} - -codecvt::result -codecvt::do_unshift(state_type&, - extern_type* to, extern_type*, extern_type*& to_nxt) const -{ - to_nxt = to; - return noconv; -} - -int -codecvt::do_encoding() const _NOEXCEPT -{ - return 0; -} - -bool -codecvt::do_always_noconv() const _NOEXCEPT -{ - return false; -} - -int -codecvt::do_length(state_type&, - const extern_type* frm, const extern_type* frm_end, size_t mx) const -{ - const uint8_t* _frm = reinterpret_cast(frm); - const uint8_t* _frm_end = reinterpret_cast(frm_end); - return utf8_to_ucs4_length(_frm, _frm_end, mx); -} - -int -codecvt::do_max_length() const _NOEXCEPT -{ - return 4; -} - -// __codecvt_utf8 - -__codecvt_utf8::result -__codecvt_utf8::do_out(state_type&, - const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt, - extern_type* to, extern_type* to_end, extern_type*& to_nxt) const -{ -#if defined(_LIBCPP_SHORT_WCHAR) - const uint16_t* _frm = reinterpret_cast(frm); - const uint16_t* _frm_end = reinterpret_cast(frm_end); - const uint16_t* _frm_nxt = _frm; -#else - const uint32_t* _frm = reinterpret_cast(frm); - const uint32_t* _frm_end = reinterpret_cast(frm_end); - const uint32_t* _frm_nxt = _frm; -#endif - uint8_t* _to = reinterpret_cast(to); - uint8_t* _to_end = reinterpret_cast(to_end); - uint8_t* _to_nxt = _to; -#if defined(_LIBCPP_SHORT_WCHAR) - result r = ucs2_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, - _Maxcode_, _Mode_); -#else - result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, - _Maxcode_, _Mode_); -#endif - frm_nxt = frm + (_frm_nxt - _frm); - to_nxt = to + (_to_nxt - _to); - return r; -} - -__codecvt_utf8::result -__codecvt_utf8::do_in(state_type&, - const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt, - intern_type* to, intern_type* to_end, intern_type*& to_nxt) const -{ - const uint8_t* _frm = reinterpret_cast(frm); - const uint8_t* _frm_end = reinterpret_cast(frm_end); - const uint8_t* _frm_nxt = _frm; -#if defined(_LIBCPP_SHORT_WCHAR) - uint16_t* _to = reinterpret_cast(to); - uint16_t* _to_end = reinterpret_cast(to_end); - uint16_t* _to_nxt = _to; - result r = utf8_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, - _Maxcode_, _Mode_); -#else - uint32_t* _to = reinterpret_cast(to); - uint32_t* _to_end = reinterpret_cast(to_end); - uint32_t* _to_nxt = _to; - result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, - _Maxcode_, _Mode_); -#endif - frm_nxt = frm + (_frm_nxt - _frm); - to_nxt = to + (_to_nxt - _to); - return r; -} - -__codecvt_utf8::result -__codecvt_utf8::do_unshift(state_type&, - extern_type* to, extern_type*, extern_type*& to_nxt) const -{ - to_nxt = to; - return noconv; -} - -int -__codecvt_utf8::do_encoding() const _NOEXCEPT -{ - return 0; -} - -bool -__codecvt_utf8::do_always_noconv() const _NOEXCEPT -{ - return false; -} - -int -__codecvt_utf8::do_length(state_type&, - const extern_type* frm, const extern_type* frm_end, size_t mx) const -{ - const uint8_t* _frm = reinterpret_cast(frm); - const uint8_t* _frm_end = reinterpret_cast(frm_end); - return utf8_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_); -} - -int -__codecvt_utf8::do_max_length() const _NOEXCEPT -{ - if (_Mode_ & consume_header) - return 7; - return 4; -} - -// __codecvt_utf8 - -__codecvt_utf8::result -__codecvt_utf8::do_out(state_type&, - const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt, - extern_type* to, extern_type* to_end, extern_type*& to_nxt) const -{ - const uint16_t* _frm = reinterpret_cast(frm); - const uint16_t* _frm_end = reinterpret_cast(frm_end); - const uint16_t* _frm_nxt = _frm; - uint8_t* _to = reinterpret_cast(to); - uint8_t* _to_end = reinterpret_cast(to_end); - uint8_t* _to_nxt = _to; - result r = ucs2_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, - _Maxcode_, _Mode_); - frm_nxt = frm + (_frm_nxt - _frm); - to_nxt = to + (_to_nxt - _to); - return r; -} - -__codecvt_utf8::result -__codecvt_utf8::do_in(state_type&, - const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt, - intern_type* to, intern_type* to_end, intern_type*& to_nxt) const -{ - const uint8_t* _frm = reinterpret_cast(frm); - const uint8_t* _frm_end = reinterpret_cast(frm_end); - const uint8_t* _frm_nxt = _frm; - uint16_t* _to = reinterpret_cast(to); - uint16_t* _to_end = reinterpret_cast(to_end); - uint16_t* _to_nxt = _to; - result r = utf8_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, - _Maxcode_, _Mode_); - frm_nxt = frm + (_frm_nxt - _frm); - to_nxt = to + (_to_nxt - _to); - return r; -} - -__codecvt_utf8::result -__codecvt_utf8::do_unshift(state_type&, - extern_type* to, extern_type*, extern_type*& to_nxt) const -{ - to_nxt = to; - return noconv; -} - -int -__codecvt_utf8::do_encoding() const _NOEXCEPT -{ - return 0; -} - -bool -__codecvt_utf8::do_always_noconv() const _NOEXCEPT -{ - return false; -} - -int -__codecvt_utf8::do_length(state_type&, - const extern_type* frm, const extern_type* frm_end, size_t mx) const -{ - const uint8_t* _frm = reinterpret_cast(frm); - const uint8_t* _frm_end = reinterpret_cast(frm_end); - return utf8_to_ucs2_length(_frm, _frm_end, mx, _Maxcode_, _Mode_); -} - -int -__codecvt_utf8::do_max_length() const _NOEXCEPT -{ - if (_Mode_ & consume_header) - return 6; - return 3; -} - -// __codecvt_utf8 - -__codecvt_utf8::result -__codecvt_utf8::do_out(state_type&, - const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt, - extern_type* to, extern_type* to_end, extern_type*& to_nxt) const -{ - const uint32_t* _frm = reinterpret_cast(frm); - const uint32_t* _frm_end = reinterpret_cast(frm_end); - const uint32_t* _frm_nxt = _frm; - uint8_t* _to = reinterpret_cast(to); - uint8_t* _to_end = reinterpret_cast(to_end); - uint8_t* _to_nxt = _to; - result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, - _Maxcode_, _Mode_); - frm_nxt = frm + (_frm_nxt - _frm); - to_nxt = to + (_to_nxt - _to); - return r; -} - -__codecvt_utf8::result -__codecvt_utf8::do_in(state_type&, - const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt, - intern_type* to, intern_type* to_end, intern_type*& to_nxt) const -{ - const uint8_t* _frm = reinterpret_cast(frm); - const uint8_t* _frm_end = reinterpret_cast(frm_end); - const uint8_t* _frm_nxt = _frm; - uint32_t* _to = reinterpret_cast(to); - uint32_t* _to_end = reinterpret_cast(to_end); - uint32_t* _to_nxt = _to; - result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, - _Maxcode_, _Mode_); - frm_nxt = frm + (_frm_nxt - _frm); - to_nxt = to + (_to_nxt - _to); - return r; -} - -__codecvt_utf8::result -__codecvt_utf8::do_unshift(state_type&, - extern_type* to, extern_type*, extern_type*& to_nxt) const -{ - to_nxt = to; - return noconv; -} - -int -__codecvt_utf8::do_encoding() const _NOEXCEPT -{ - return 0; -} - -bool -__codecvt_utf8::do_always_noconv() const _NOEXCEPT -{ - return false; -} - -int -__codecvt_utf8::do_length(state_type&, - const extern_type* frm, const extern_type* frm_end, size_t mx) const -{ - const uint8_t* _frm = reinterpret_cast(frm); - const uint8_t* _frm_end = reinterpret_cast(frm_end); - return utf8_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_); -} - -int -__codecvt_utf8::do_max_length() const _NOEXCEPT -{ - if (_Mode_ & consume_header) - return 7; - return 4; -} - -// __codecvt_utf16 - -__codecvt_utf16::result -__codecvt_utf16::do_out(state_type&, - const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt, - extern_type* to, extern_type* to_end, extern_type*& to_nxt) const -{ - const uint32_t* _frm = reinterpret_cast(frm); - const uint32_t* _frm_end = reinterpret_cast(frm_end); - const uint32_t* _frm_nxt = _frm; - uint8_t* _to = reinterpret_cast(to); - uint8_t* _to_end = reinterpret_cast(to_end); - uint8_t* _to_nxt = _to; - result r = ucs4_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, - _Maxcode_, _Mode_); - frm_nxt = frm + (_frm_nxt - _frm); - to_nxt = to + (_to_nxt - _to); - return r; -} - -__codecvt_utf16::result -__codecvt_utf16::do_in(state_type&, - const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt, - intern_type* to, intern_type* to_end, intern_type*& to_nxt) const -{ - const uint8_t* _frm = reinterpret_cast(frm); - const uint8_t* _frm_end = reinterpret_cast(frm_end); - const uint8_t* _frm_nxt = _frm; - uint32_t* _to = reinterpret_cast(to); - uint32_t* _to_end = reinterpret_cast(to_end); - uint32_t* _to_nxt = _to; - result r = utf16be_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, - _Maxcode_, _Mode_); - frm_nxt = frm + (_frm_nxt - _frm); - to_nxt = to + (_to_nxt - _to); - return r; -} - -__codecvt_utf16::result -__codecvt_utf16::do_unshift(state_type&, - extern_type* to, extern_type*, extern_type*& to_nxt) const -{ - to_nxt = to; - return noconv; -} - -int -__codecvt_utf16::do_encoding() const _NOEXCEPT -{ - return 0; -} - -bool -__codecvt_utf16::do_always_noconv() const _NOEXCEPT -{ - return false; -} - -int -__codecvt_utf16::do_length(state_type&, - const extern_type* frm, const extern_type* frm_end, size_t mx) const -{ - const uint8_t* _frm = reinterpret_cast(frm); - const uint8_t* _frm_end = reinterpret_cast(frm_end); - return utf16be_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_); -} - -int -__codecvt_utf16::do_max_length() const _NOEXCEPT -{ - if (_Mode_ & consume_header) - return 6; - return 4; -} - -// __codecvt_utf16 - -__codecvt_utf16::result -__codecvt_utf16::do_out(state_type&, - const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt, - extern_type* to, extern_type* to_end, extern_type*& to_nxt) const -{ - const uint32_t* _frm = reinterpret_cast(frm); - const uint32_t* _frm_end = reinterpret_cast(frm_end); - const uint32_t* _frm_nxt = _frm; - uint8_t* _to = reinterpret_cast(to); - uint8_t* _to_end = reinterpret_cast(to_end); - uint8_t* _to_nxt = _to; - result r = ucs4_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, - _Maxcode_, _Mode_); - frm_nxt = frm + (_frm_nxt - _frm); - to_nxt = to + (_to_nxt - _to); - return r; -} - -__codecvt_utf16::result -__codecvt_utf16::do_in(state_type&, - const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt, - intern_type* to, intern_type* to_end, intern_type*& to_nxt) const -{ - const uint8_t* _frm = reinterpret_cast(frm); - const uint8_t* _frm_end = reinterpret_cast(frm_end); - const uint8_t* _frm_nxt = _frm; - uint32_t* _to = reinterpret_cast(to); - uint32_t* _to_end = reinterpret_cast(to_end); - uint32_t* _to_nxt = _to; - result r = utf16le_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, - _Maxcode_, _Mode_); - frm_nxt = frm + (_frm_nxt - _frm); - to_nxt = to + (_to_nxt - _to); - return r; -} - -__codecvt_utf16::result -__codecvt_utf16::do_unshift(state_type&, - extern_type* to, extern_type*, extern_type*& to_nxt) const -{ - to_nxt = to; - return noconv; -} - -int -__codecvt_utf16::do_encoding() const _NOEXCEPT -{ - return 0; -} - -bool -__codecvt_utf16::do_always_noconv() const _NOEXCEPT -{ - return false; -} - -int -__codecvt_utf16::do_length(state_type&, - const extern_type* frm, const extern_type* frm_end, size_t mx) const -{ - const uint8_t* _frm = reinterpret_cast(frm); - const uint8_t* _frm_end = reinterpret_cast(frm_end); - return utf16le_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_); -} - -int -__codecvt_utf16::do_max_length() const _NOEXCEPT -{ - if (_Mode_ & consume_header) - return 6; - return 4; -} - -// __codecvt_utf16 - -__codecvt_utf16::result -__codecvt_utf16::do_out(state_type&, - const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt, - extern_type* to, extern_type* to_end, extern_type*& to_nxt) const -{ - const uint16_t* _frm = reinterpret_cast(frm); - const uint16_t* _frm_end = reinterpret_cast(frm_end); - const uint16_t* _frm_nxt = _frm; - uint8_t* _to = reinterpret_cast(to); - uint8_t* _to_end = reinterpret_cast(to_end); - uint8_t* _to_nxt = _to; - result r = ucs2_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, - _Maxcode_, _Mode_); - frm_nxt = frm + (_frm_nxt - _frm); - to_nxt = to + (_to_nxt - _to); - return r; -} - -__codecvt_utf16::result -__codecvt_utf16::do_in(state_type&, - const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt, - intern_type* to, intern_type* to_end, intern_type*& to_nxt) const -{ - const uint8_t* _frm = reinterpret_cast(frm); - const uint8_t* _frm_end = reinterpret_cast(frm_end); - const uint8_t* _frm_nxt = _frm; - uint16_t* _to = reinterpret_cast(to); - uint16_t* _to_end = reinterpret_cast(to_end); - uint16_t* _to_nxt = _to; - result r = utf16be_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, - _Maxcode_, _Mode_); - frm_nxt = frm + (_frm_nxt - _frm); - to_nxt = to + (_to_nxt - _to); - return r; -} - -__codecvt_utf16::result -__codecvt_utf16::do_unshift(state_type&, - extern_type* to, extern_type*, extern_type*& to_nxt) const -{ - to_nxt = to; - return noconv; -} - -int -__codecvt_utf16::do_encoding() const _NOEXCEPT -{ - return 0; -} - -bool -__codecvt_utf16::do_always_noconv() const _NOEXCEPT -{ - return false; -} - -int -__codecvt_utf16::do_length(state_type&, - const extern_type* frm, const extern_type* frm_end, size_t mx) const -{ - const uint8_t* _frm = reinterpret_cast(frm); - const uint8_t* _frm_end = reinterpret_cast(frm_end); - return utf16be_to_ucs2_length(_frm, _frm_end, mx, _Maxcode_, _Mode_); -} - -int -__codecvt_utf16::do_max_length() const _NOEXCEPT -{ - if (_Mode_ & consume_header) - return 4; - return 2; -} - -// __codecvt_utf16 - -__codecvt_utf16::result -__codecvt_utf16::do_out(state_type&, - const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt, - extern_type* to, extern_type* to_end, extern_type*& to_nxt) const -{ - const uint16_t* _frm = reinterpret_cast(frm); - const uint16_t* _frm_end = reinterpret_cast(frm_end); - const uint16_t* _frm_nxt = _frm; - uint8_t* _to = reinterpret_cast(to); - uint8_t* _to_end = reinterpret_cast(to_end); - uint8_t* _to_nxt = _to; - result r = ucs2_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, - _Maxcode_, _Mode_); - frm_nxt = frm + (_frm_nxt - _frm); - to_nxt = to + (_to_nxt - _to); - return r; -} - -__codecvt_utf16::result -__codecvt_utf16::do_in(state_type&, - const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt, - intern_type* to, intern_type* to_end, intern_type*& to_nxt) const -{ - const uint8_t* _frm = reinterpret_cast(frm); - const uint8_t* _frm_end = reinterpret_cast(frm_end); - const uint8_t* _frm_nxt = _frm; - uint16_t* _to = reinterpret_cast(to); - uint16_t* _to_end = reinterpret_cast(to_end); - uint16_t* _to_nxt = _to; - result r = utf16le_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, - _Maxcode_, _Mode_); - frm_nxt = frm + (_frm_nxt - _frm); - to_nxt = to + (_to_nxt - _to); - return r; -} - -__codecvt_utf16::result -__codecvt_utf16::do_unshift(state_type&, - extern_type* to, extern_type*, extern_type*& to_nxt) const -{ - to_nxt = to; - return noconv; -} - -int -__codecvt_utf16::do_encoding() const _NOEXCEPT -{ - return 0; -} - -bool -__codecvt_utf16::do_always_noconv() const _NOEXCEPT -{ - return false; -} - -int -__codecvt_utf16::do_length(state_type&, - const extern_type* frm, const extern_type* frm_end, size_t mx) const -{ - const uint8_t* _frm = reinterpret_cast(frm); - const uint8_t* _frm_end = reinterpret_cast(frm_end); - return utf16le_to_ucs2_length(_frm, _frm_end, mx, _Maxcode_, _Mode_); -} - -int -__codecvt_utf16::do_max_length() const _NOEXCEPT -{ - if (_Mode_ & consume_header) - return 4; - return 2; -} - -// __codecvt_utf16 - -__codecvt_utf16::result -__codecvt_utf16::do_out(state_type&, - const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt, - extern_type* to, extern_type* to_end, extern_type*& to_nxt) const -{ - const uint32_t* _frm = reinterpret_cast(frm); - const uint32_t* _frm_end = reinterpret_cast(frm_end); - const uint32_t* _frm_nxt = _frm; - uint8_t* _to = reinterpret_cast(to); - uint8_t* _to_end = reinterpret_cast(to_end); - uint8_t* _to_nxt = _to; - result r = ucs4_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, - _Maxcode_, _Mode_); - frm_nxt = frm + (_frm_nxt - _frm); - to_nxt = to + (_to_nxt - _to); - return r; -} - -__codecvt_utf16::result -__codecvt_utf16::do_in(state_type&, - const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt, - intern_type* to, intern_type* to_end, intern_type*& to_nxt) const -{ - const uint8_t* _frm = reinterpret_cast(frm); - const uint8_t* _frm_end = reinterpret_cast(frm_end); - const uint8_t* _frm_nxt = _frm; - uint32_t* _to = reinterpret_cast(to); - uint32_t* _to_end = reinterpret_cast(to_end); - uint32_t* _to_nxt = _to; - result r = utf16be_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, - _Maxcode_, _Mode_); - frm_nxt = frm + (_frm_nxt - _frm); - to_nxt = to + (_to_nxt - _to); - return r; -} - -__codecvt_utf16::result -__codecvt_utf16::do_unshift(state_type&, - extern_type* to, extern_type*, extern_type*& to_nxt) const -{ - to_nxt = to; - return noconv; -} - -int -__codecvt_utf16::do_encoding() const _NOEXCEPT -{ - return 0; -} - -bool -__codecvt_utf16::do_always_noconv() const _NOEXCEPT -{ - return false; -} - -int -__codecvt_utf16::do_length(state_type&, - const extern_type* frm, const extern_type* frm_end, size_t mx) const -{ - const uint8_t* _frm = reinterpret_cast(frm); - const uint8_t* _frm_end = reinterpret_cast(frm_end); - return utf16be_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_); -} - -int -__codecvt_utf16::do_max_length() const _NOEXCEPT -{ - if (_Mode_ & consume_header) - return 6; - return 4; -} - -// __codecvt_utf16 - -__codecvt_utf16::result -__codecvt_utf16::do_out(state_type&, - const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt, - extern_type* to, extern_type* to_end, extern_type*& to_nxt) const -{ - const uint32_t* _frm = reinterpret_cast(frm); - const uint32_t* _frm_end = reinterpret_cast(frm_end); - const uint32_t* _frm_nxt = _frm; - uint8_t* _to = reinterpret_cast(to); - uint8_t* _to_end = reinterpret_cast(to_end); - uint8_t* _to_nxt = _to; - result r = ucs4_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, - _Maxcode_, _Mode_); - frm_nxt = frm + (_frm_nxt - _frm); - to_nxt = to + (_to_nxt - _to); - return r; -} - -__codecvt_utf16::result -__codecvt_utf16::do_in(state_type&, - const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt, - intern_type* to, intern_type* to_end, intern_type*& to_nxt) const -{ - const uint8_t* _frm = reinterpret_cast(frm); - const uint8_t* _frm_end = reinterpret_cast(frm_end); - const uint8_t* _frm_nxt = _frm; - uint32_t* _to = reinterpret_cast(to); - uint32_t* _to_end = reinterpret_cast(to_end); - uint32_t* _to_nxt = _to; - result r = utf16le_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, - _Maxcode_, _Mode_); - frm_nxt = frm + (_frm_nxt - _frm); - to_nxt = to + (_to_nxt - _to); - return r; -} - -__codecvt_utf16::result -__codecvt_utf16::do_unshift(state_type&, - extern_type* to, extern_type*, extern_type*& to_nxt) const -{ - to_nxt = to; - return noconv; -} - -int -__codecvt_utf16::do_encoding() const _NOEXCEPT -{ - return 0; -} - -bool -__codecvt_utf16::do_always_noconv() const _NOEXCEPT -{ - return false; -} - -int -__codecvt_utf16::do_length(state_type&, - const extern_type* frm, const extern_type* frm_end, size_t mx) const -{ - const uint8_t* _frm = reinterpret_cast(frm); - const uint8_t* _frm_end = reinterpret_cast(frm_end); - return utf16le_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_); -} - -int -__codecvt_utf16::do_max_length() const _NOEXCEPT -{ - if (_Mode_ & consume_header) - return 6; - return 4; -} - -// __codecvt_utf8_utf16 - -__codecvt_utf8_utf16::result -__codecvt_utf8_utf16::do_out(state_type&, - const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt, - extern_type* to, extern_type* to_end, extern_type*& to_nxt) const -{ - const uint32_t* _frm = reinterpret_cast(frm); - const uint32_t* _frm_end = reinterpret_cast(frm_end); - const uint32_t* _frm_nxt = _frm; - uint8_t* _to = reinterpret_cast(to); - uint8_t* _to_end = reinterpret_cast(to_end); - uint8_t* _to_nxt = _to; - result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, - _Maxcode_, _Mode_); - frm_nxt = frm + (_frm_nxt - _frm); - to_nxt = to + (_to_nxt - _to); - return r; -} - -__codecvt_utf8_utf16::result -__codecvt_utf8_utf16::do_in(state_type&, - const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt, - intern_type* to, intern_type* to_end, intern_type*& to_nxt) const -{ - const uint8_t* _frm = reinterpret_cast(frm); - const uint8_t* _frm_end = reinterpret_cast(frm_end); - const uint8_t* _frm_nxt = _frm; - uint32_t* _to = reinterpret_cast(to); - uint32_t* _to_end = reinterpret_cast(to_end); - uint32_t* _to_nxt = _to; - result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, - _Maxcode_, _Mode_); - frm_nxt = frm + (_frm_nxt - _frm); - to_nxt = to + (_to_nxt - _to); - return r; -} - -__codecvt_utf8_utf16::result -__codecvt_utf8_utf16::do_unshift(state_type&, - extern_type* to, extern_type*, extern_type*& to_nxt) const -{ - to_nxt = to; - return noconv; -} - -int -__codecvt_utf8_utf16::do_encoding() const _NOEXCEPT -{ - return 0; -} - -bool -__codecvt_utf8_utf16::do_always_noconv() const _NOEXCEPT -{ - return false; -} - -int -__codecvt_utf8_utf16::do_length(state_type&, - const extern_type* frm, const extern_type* frm_end, size_t mx) const -{ - const uint8_t* _frm = reinterpret_cast(frm); - const uint8_t* _frm_end = reinterpret_cast(frm_end); - return utf8_to_utf16_length(_frm, _frm_end, mx, _Maxcode_, _Mode_); -} - -int -__codecvt_utf8_utf16::do_max_length() const _NOEXCEPT -{ - if (_Mode_ & consume_header) - return 7; - return 4; -} - -// __codecvt_utf8_utf16 - -__codecvt_utf8_utf16::result -__codecvt_utf8_utf16::do_out(state_type&, - const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt, - extern_type* to, extern_type* to_end, extern_type*& to_nxt) const -{ - const uint16_t* _frm = reinterpret_cast(frm); - const uint16_t* _frm_end = reinterpret_cast(frm_end); - const uint16_t* _frm_nxt = _frm; - uint8_t* _to = reinterpret_cast(to); - uint8_t* _to_end = reinterpret_cast(to_end); - uint8_t* _to_nxt = _to; - result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, - _Maxcode_, _Mode_); - frm_nxt = frm + (_frm_nxt - _frm); - to_nxt = to + (_to_nxt - _to); - return r; -} - -__codecvt_utf8_utf16::result -__codecvt_utf8_utf16::do_in(state_type&, - const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt, - intern_type* to, intern_type* to_end, intern_type*& to_nxt) const -{ - const uint8_t* _frm = reinterpret_cast(frm); - const uint8_t* _frm_end = reinterpret_cast(frm_end); - const uint8_t* _frm_nxt = _frm; - uint16_t* _to = reinterpret_cast(to); - uint16_t* _to_end = reinterpret_cast(to_end); - uint16_t* _to_nxt = _to; - result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, - _Maxcode_, _Mode_); - frm_nxt = frm + (_frm_nxt - _frm); - to_nxt = to + (_to_nxt - _to); - return r; -} - -__codecvt_utf8_utf16::result -__codecvt_utf8_utf16::do_unshift(state_type&, - extern_type* to, extern_type*, extern_type*& to_nxt) const -{ - to_nxt = to; - return noconv; -} - -int -__codecvt_utf8_utf16::do_encoding() const _NOEXCEPT -{ - return 0; -} - -bool -__codecvt_utf8_utf16::do_always_noconv() const _NOEXCEPT -{ - return false; -} - -int -__codecvt_utf8_utf16::do_length(state_type&, - const extern_type* frm, const extern_type* frm_end, size_t mx) const -{ - const uint8_t* _frm = reinterpret_cast(frm); - const uint8_t* _frm_end = reinterpret_cast(frm_end); - return utf8_to_utf16_length(_frm, _frm_end, mx, _Maxcode_, _Mode_); -} - -int -__codecvt_utf8_utf16::do_max_length() const _NOEXCEPT -{ - if (_Mode_ & consume_header) - return 7; - return 4; -} - -// __codecvt_utf8_utf16 - -__codecvt_utf8_utf16::result -__codecvt_utf8_utf16::do_out(state_type&, - const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt, - extern_type* to, extern_type* to_end, extern_type*& to_nxt) const -{ - const uint32_t* _frm = reinterpret_cast(frm); - const uint32_t* _frm_end = reinterpret_cast(frm_end); - const uint32_t* _frm_nxt = _frm; - uint8_t* _to = reinterpret_cast(to); - uint8_t* _to_end = reinterpret_cast(to_end); - uint8_t* _to_nxt = _to; - result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, - _Maxcode_, _Mode_); - frm_nxt = frm + (_frm_nxt - _frm); - to_nxt = to + (_to_nxt - _to); - return r; -} - -__codecvt_utf8_utf16::result -__codecvt_utf8_utf16::do_in(state_type&, - const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt, - intern_type* to, intern_type* to_end, intern_type*& to_nxt) const -{ - const uint8_t* _frm = reinterpret_cast(frm); - const uint8_t* _frm_end = reinterpret_cast(frm_end); - const uint8_t* _frm_nxt = _frm; - uint32_t* _to = reinterpret_cast(to); - uint32_t* _to_end = reinterpret_cast(to_end); - uint32_t* _to_nxt = _to; - result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, - _Maxcode_, _Mode_); - frm_nxt = frm + (_frm_nxt - _frm); - to_nxt = to + (_to_nxt - _to); - return r; -} - -__codecvt_utf8_utf16::result -__codecvt_utf8_utf16::do_unshift(state_type&, - extern_type* to, extern_type*, extern_type*& to_nxt) const -{ - to_nxt = to; - return noconv; -} - -int -__codecvt_utf8_utf16::do_encoding() const _NOEXCEPT -{ - return 0; -} - -bool -__codecvt_utf8_utf16::do_always_noconv() const _NOEXCEPT -{ - return false; -} - -int -__codecvt_utf8_utf16::do_length(state_type&, - const extern_type* frm, const extern_type* frm_end, size_t mx) const -{ - const uint8_t* _frm = reinterpret_cast(frm); - const uint8_t* _frm_end = reinterpret_cast(frm_end); - return utf8_to_utf16_length(_frm, _frm_end, mx, _Maxcode_, _Mode_); -} - -int -__codecvt_utf8_utf16::do_max_length() const _NOEXCEPT -{ - if (_Mode_ & consume_header) - return 7; - return 4; -} - -// __narrow_to_utf8<16> - -__narrow_to_utf8<16>::~__narrow_to_utf8() -{ -} - -// __narrow_to_utf8<32> - -__narrow_to_utf8<32>::~__narrow_to_utf8() -{ -} - -// __widen_from_utf8<16> - -__widen_from_utf8<16>::~__widen_from_utf8() -{ -} - -// __widen_from_utf8<32> - -__widen_from_utf8<32>::~__widen_from_utf8() -{ -} - - -static bool checked_string_to_wchar_convert(wchar_t& dest, - const char* ptr, - locale_t loc) { - if (*ptr == '\0') - return false; - mbstate_t mb = {}; - wchar_t out; - size_t ret = __libcpp_mbrtowc_l(&out, ptr, strlen(ptr), &mb, loc); - if (ret == static_cast(-1) || ret == static_cast(-2)) { - return false; - } - dest = out; - return true; -} - -static bool checked_string_to_char_convert(char& dest, - const char* ptr, - locale_t __loc) { - if (*ptr == '\0') - return false; - if (!ptr[1]) { - dest = *ptr; - return true; - } - // First convert the MBS into a wide char then attempt to narrow it using - // wctob_l. - wchar_t wout; - if (!checked_string_to_wchar_convert(wout, ptr, __loc)) - return false; - int res; - if ((res = __libcpp_wctob_l(wout, __loc)) != char_traits::eof()) { - dest = res; - return true; - } - // FIXME: Work around specific multibyte sequences that we can reasonable - // translate into a different single byte. - switch (wout) { - case L'\u202F': // narrow non-breaking space - case L'\u00A0': // non-breaking space - dest = ' '; - return true; - default: - return false; - } - _LIBCPP_UNREACHABLE(); -} - - -// numpunct && numpunct - -locale::id numpunct< char >::id; -locale::id numpunct::id; - -numpunct::numpunct(size_t refs) - : locale::facet(refs), - __decimal_point_('.'), - __thousands_sep_(',') -{ -} - -numpunct::numpunct(size_t refs) - : locale::facet(refs), - __decimal_point_(L'.'), - __thousands_sep_(L',') -{ -} - -numpunct::~numpunct() -{ -} - -numpunct::~numpunct() -{ -} - - char numpunct< char >::do_decimal_point() const {return __decimal_point_;} -wchar_t numpunct::do_decimal_point() const {return __decimal_point_;} - - char numpunct< char >::do_thousands_sep() const {return __thousands_sep_;} -wchar_t numpunct::do_thousands_sep() const {return __thousands_sep_;} - -string numpunct< char >::do_grouping() const {return __grouping_;} -string numpunct::do_grouping() const {return __grouping_;} - - string numpunct< char >::do_truename() const {return "true";} -wstring numpunct::do_truename() const {return L"true";} - - string numpunct< char >::do_falsename() const {return "false";} -wstring numpunct::do_falsename() const {return L"false";} - -// numpunct_byname - -numpunct_byname::numpunct_byname(const char* nm, size_t refs) - : numpunct(refs) -{ - __init(nm); -} - -numpunct_byname::numpunct_byname(const string& nm, size_t refs) - : numpunct(refs) -{ - __init(nm.c_str()); -} - -numpunct_byname::~numpunct_byname() -{ -} - -void -numpunct_byname::__init(const char* nm) -{ - if (strcmp(nm, "C") != 0) - { - __libcpp_unique_locale loc(nm); - if (!loc) - __throw_runtime_error("numpunct_byname::numpunct_byname" - " failed to construct for " + string(nm)); - - lconv* lc = __libcpp_localeconv_l(loc.get()); - checked_string_to_char_convert(__decimal_point_, lc->decimal_point, - loc.get()); - checked_string_to_char_convert(__thousands_sep_, lc->thousands_sep, - loc.get()); - __grouping_ = lc->grouping; - // localization for truename and falsename is not available - } -} - -// numpunct_byname - -numpunct_byname::numpunct_byname(const char* nm, size_t refs) - : numpunct(refs) -{ - __init(nm); -} - -numpunct_byname::numpunct_byname(const string& nm, size_t refs) - : numpunct(refs) -{ - __init(nm.c_str()); -} - -numpunct_byname::~numpunct_byname() -{ -} - -void -numpunct_byname::__init(const char* nm) -{ - if (strcmp(nm, "C") != 0) - { - __libcpp_unique_locale loc(nm); - if (!loc) - __throw_runtime_error("numpunct_byname::numpunct_byname" - " failed to construct for " + string(nm)); - - lconv* lc = __libcpp_localeconv_l(loc.get()); - checked_string_to_wchar_convert(__decimal_point_, lc->decimal_point, - loc.get()); - checked_string_to_wchar_convert(__thousands_sep_, lc->thousands_sep, - loc.get()); - __grouping_ = lc->grouping; - // localization for truename and falsename is not available - } -} - -// num_get helpers - -int -__num_get_base::__get_base(ios_base& iob) -{ - ios_base::fmtflags __basefield = iob.flags() & ios_base::basefield; - if (__basefield == ios_base::oct) - return 8; - else if (__basefield == ios_base::hex) - return 16; - else if (__basefield == 0) - return 0; - return 10; -} - -const char __num_get_base::__src[33] = "0123456789abcdefABCDEFxX+-pPiInN"; - -void -__check_grouping(const string& __grouping, unsigned* __g, unsigned* __g_end, - ios_base::iostate& __err) -{ -// if the grouping pattern is empty _or_ there are no grouping bits, then do nothing -// we always have at least a single entry in [__g, __g_end); the end of the input sequence - if (__grouping.size() != 0 && __g_end - __g > 1) - { - reverse(__g, __g_end); - const char* __ig = __grouping.data(); - const char* __eg = __ig + __grouping.size(); - for (unsigned* __r = __g; __r < __g_end-1; ++__r) - { - if (0 < *__ig && *__ig < numeric_limits::max()) - { - if (static_cast(*__ig) != *__r) - { - __err = ios_base::failbit; - return; - } - } - if (__eg - __ig > 1) - ++__ig; - } - if (0 < *__ig && *__ig < numeric_limits::max()) - { - if (static_cast(*__ig) < __g_end[-1] || __g_end[-1] == 0) - __err = ios_base::failbit; - } - } -} - -void -__num_put_base::__format_int(char* __fmtp, const char* __len, bool __signd, - ios_base::fmtflags __flags) -{ - if (__flags & ios_base::showpos) - *__fmtp++ = '+'; - if (__flags & ios_base::showbase) - *__fmtp++ = '#'; - while(*__len) - *__fmtp++ = *__len++; - if ((__flags & ios_base::basefield) == ios_base::oct) - *__fmtp = 'o'; - else if ((__flags & ios_base::basefield) == ios_base::hex) - { - if (__flags & ios_base::uppercase) - *__fmtp = 'X'; - else - *__fmtp = 'x'; - } - else if (__signd) - *__fmtp = 'd'; - else - *__fmtp = 'u'; -} - -bool -__num_put_base::__format_float(char* __fmtp, const char* __len, - ios_base::fmtflags __flags) -{ - bool specify_precision = true; - if (__flags & ios_base::showpos) - *__fmtp++ = '+'; - if (__flags & ios_base::showpoint) - *__fmtp++ = '#'; - ios_base::fmtflags floatfield = __flags & ios_base::floatfield; - bool uppercase = (__flags & ios_base::uppercase) != 0; - if (floatfield == (ios_base::fixed | ios_base::scientific)) - specify_precision = false; - else - { - *__fmtp++ = '.'; - *__fmtp++ = '*'; - } - while(*__len) - *__fmtp++ = *__len++; - if (floatfield == ios_base::fixed) - { - if (uppercase) - *__fmtp = 'F'; - else - *__fmtp = 'f'; - } - else if (floatfield == ios_base::scientific) - { - if (uppercase) - *__fmtp = 'E'; - else - *__fmtp = 'e'; - } - else if (floatfield == (ios_base::fixed | ios_base::scientific)) - { - if (uppercase) - *__fmtp = 'A'; - else - *__fmtp = 'a'; - } - else - { - if (uppercase) - *__fmtp = 'G'; - else - *__fmtp = 'g'; - } - return specify_precision; -} - -char* -__num_put_base::__identify_padding(char* __nb, char* __ne, - const ios_base& __iob) -{ - switch (__iob.flags() & ios_base::adjustfield) - { - case ios_base::internal: - if (__nb[0] == '-' || __nb[0] == '+') - return __nb+1; - if (__ne - __nb >= 2 && __nb[0] == '0' - && (__nb[1] == 'x' || __nb[1] == 'X')) - return __nb+2; - break; - case ios_base::left: - return __ne; - case ios_base::right: - default: - break; - } - return __nb; -} - -// time_get - -static -string* -init_weeks() -{ - static string weeks[14]; - weeks[0] = "Sunday"; - weeks[1] = "Monday"; - weeks[2] = "Tuesday"; - weeks[3] = "Wednesday"; - weeks[4] = "Thursday"; - weeks[5] = "Friday"; - weeks[6] = "Saturday"; - weeks[7] = "Sun"; - weeks[8] = "Mon"; - weeks[9] = "Tue"; - weeks[10] = "Wed"; - weeks[11] = "Thu"; - weeks[12] = "Fri"; - weeks[13] = "Sat"; - return weeks; -} - -static -wstring* -init_wweeks() -{ - static wstring weeks[14]; - weeks[0] = L"Sunday"; - weeks[1] = L"Monday"; - weeks[2] = L"Tuesday"; - weeks[3] = L"Wednesday"; - weeks[4] = L"Thursday"; - weeks[5] = L"Friday"; - weeks[6] = L"Saturday"; - weeks[7] = L"Sun"; - weeks[8] = L"Mon"; - weeks[9] = L"Tue"; - weeks[10] = L"Wed"; - weeks[11] = L"Thu"; - weeks[12] = L"Fri"; - weeks[13] = L"Sat"; - return weeks; -} - -template <> -const string* -__time_get_c_storage::__weeks() const -{ - static const string* weeks = init_weeks(); - return weeks; -} - -template <> -const wstring* -__time_get_c_storage::__weeks() const -{ - static const wstring* weeks = init_wweeks(); - return weeks; -} - -static -string* -init_months() -{ - static string months[24]; - months[0] = "January"; - months[1] = "February"; - months[2] = "March"; - months[3] = "April"; - months[4] = "May"; - months[5] = "June"; - months[6] = "July"; - months[7] = "August"; - months[8] = "September"; - months[9] = "October"; - months[10] = "November"; - months[11] = "December"; - months[12] = "Jan"; - months[13] = "Feb"; - months[14] = "Mar"; - months[15] = "Apr"; - months[16] = "May"; - months[17] = "Jun"; - months[18] = "Jul"; - months[19] = "Aug"; - months[20] = "Sep"; - months[21] = "Oct"; - months[22] = "Nov"; - months[23] = "Dec"; - return months; -} - -static -wstring* -init_wmonths() -{ - static wstring months[24]; - months[0] = L"January"; - months[1] = L"February"; - months[2] = L"March"; - months[3] = L"April"; - months[4] = L"May"; - months[5] = L"June"; - months[6] = L"July"; - months[7] = L"August"; - months[8] = L"September"; - months[9] = L"October"; - months[10] = L"November"; - months[11] = L"December"; - months[12] = L"Jan"; - months[13] = L"Feb"; - months[14] = L"Mar"; - months[15] = L"Apr"; - months[16] = L"May"; - months[17] = L"Jun"; - months[18] = L"Jul"; - months[19] = L"Aug"; - months[20] = L"Sep"; - months[21] = L"Oct"; - months[22] = L"Nov"; - months[23] = L"Dec"; - return months; -} - -template <> -const string* -__time_get_c_storage::__months() const -{ - static const string* months = init_months(); - return months; -} - -template <> -const wstring* -__time_get_c_storage::__months() const -{ - static const wstring* months = init_wmonths(); - return months; -} - -static -string* -init_am_pm() -{ - static string am_pm[2]; - am_pm[0] = "AM"; - am_pm[1] = "PM"; - return am_pm; -} - -static -wstring* -init_wam_pm() -{ - static wstring am_pm[2]; - am_pm[0] = L"AM"; - am_pm[1] = L"PM"; - return am_pm; -} - -template <> -const string* -__time_get_c_storage::__am_pm() const -{ - static const string* am_pm = init_am_pm(); - return am_pm; -} - -template <> -const wstring* -__time_get_c_storage::__am_pm() const -{ - static const wstring* am_pm = init_wam_pm(); - return am_pm; -} - -template <> -const string& -__time_get_c_storage::__x() const -{ - static string s("%m/%d/%y"); - return s; -} - -template <> -const wstring& -__time_get_c_storage::__x() const -{ - static wstring s(L"%m/%d/%y"); - return s; -} - -template <> -const string& -__time_get_c_storage::__X() const -{ - static string s("%H:%M:%S"); - return s; -} - -template <> -const wstring& -__time_get_c_storage::__X() const -{ - static wstring s(L"%H:%M:%S"); - return s; -} - -template <> -const string& -__time_get_c_storage::__c() const -{ - static string s("%a %b %d %H:%M:%S %Y"); - return s; -} - -template <> -const wstring& -__time_get_c_storage::__c() const -{ - static wstring s(L"%a %b %d %H:%M:%S %Y"); - return s; -} - -template <> -const string& -__time_get_c_storage::__r() const -{ - static string s("%I:%M:%S %p"); - return s; -} - -template <> -const wstring& -__time_get_c_storage::__r() const -{ - static wstring s(L"%I:%M:%S %p"); - return s; -} - -// time_get_byname - -__time_get::__time_get(const char* nm) - : __loc_(newlocale(LC_ALL_MASK, nm, 0)) -{ - if (__loc_ == 0) - __throw_runtime_error("time_get_byname" - " failed to construct for " + string(nm)); -} - -__time_get::__time_get(const string& nm) - : __loc_(newlocale(LC_ALL_MASK, nm.c_str(), 0)) -{ - if (__loc_ == 0) - __throw_runtime_error("time_get_byname" - " failed to construct for " + nm); -} - -__time_get::~__time_get() -{ - freelocale(__loc_); -} -#if defined(__clang__) -#pragma clang diagnostic ignored "-Wmissing-field-initializers" -#endif -#if defined(__GNUG__) -#pragma GCC diagnostic ignored "-Wmissing-field-initializers" -#endif - -template <> -string -__time_get_storage::__analyze(char fmt, const ctype& ct) -{ - tm t = {0}; - t.tm_sec = 59; - t.tm_min = 55; - t.tm_hour = 23; - t.tm_mday = 31; - t.tm_mon = 11; - t.tm_year = 161; - t.tm_wday = 6; - t.tm_yday = 364; - t.tm_isdst = -1; - char buf[100]; - char f[3] = {0}; - f[0] = '%'; - f[1] = fmt; - size_t n = strftime_l(buf, countof(buf), f, &t, __loc_); - char* bb = buf; - char* be = buf + n; - string result; - while (bb != be) - { - if (ct.is(ctype_base::space, *bb)) - { - result.push_back(' '); - for (++bb; bb != be && ct.is(ctype_base::space, *bb); ++bb) - ; - continue; - } - char* w = bb; - ios_base::iostate err = ios_base::goodbit; - ptrdiff_t i = __scan_keyword(w, be, this->__weeks_, this->__weeks_+14, - ct, err, false) - - this->__weeks_; - if (i < 14) - { - result.push_back('%'); - if (i < 7) - result.push_back('A'); - else - result.push_back('a'); - bb = w; - continue; - } - w = bb; - i = __scan_keyword(w, be, this->__months_, this->__months_+24, - ct, err, false) - - this->__months_; - if (i < 24) - { - result.push_back('%'); - if (i < 12) - result.push_back('B'); - else - result.push_back('b'); - if (fmt == 'x' && ct.is(ctype_base::digit, this->__months_[i][0])) - result.back() = 'm'; - bb = w; - continue; - } - if (this->__am_pm_[0].size() + this->__am_pm_[1].size() > 0) - { - w = bb; - i = __scan_keyword(w, be, this->__am_pm_, this->__am_pm_+2, - ct, err, false) - this->__am_pm_; - if (i < 2) - { - result.push_back('%'); - result.push_back('p'); - bb = w; - continue; - } - } - w = bb; - if (ct.is(ctype_base::digit, *bb)) - { - switch(__get_up_to_n_digits(bb, be, err, ct, 4)) - { - case 6: - result.push_back('%'); - result.push_back('w'); - break; - case 7: - result.push_back('%'); - result.push_back('u'); - break; - case 11: - result.push_back('%'); - result.push_back('I'); - break; - case 12: - result.push_back('%'); - result.push_back('m'); - break; - case 23: - result.push_back('%'); - result.push_back('H'); - break; - case 31: - result.push_back('%'); - result.push_back('d'); - break; - case 55: - result.push_back('%'); - result.push_back('M'); - break; - case 59: - result.push_back('%'); - result.push_back('S'); - break; - case 61: - result.push_back('%'); - result.push_back('y'); - break; - case 364: - result.push_back('%'); - result.push_back('j'); - break; - case 2061: - result.push_back('%'); - result.push_back('Y'); - break; - default: - for (; w != bb; ++w) - result.push_back(*w); - break; - } - continue; - } - if (*bb == '%') - { - result.push_back('%'); - result.push_back('%'); - ++bb; - continue; - } - result.push_back(*bb); - ++bb; - } - return result; -} - -#if defined(__clang__) -#pragma clang diagnostic ignored "-Wmissing-braces" -#endif - -template <> -wstring -__time_get_storage::__analyze(char fmt, const ctype& ct) -{ - tm t = {0}; - t.tm_sec = 59; - t.tm_min = 55; - t.tm_hour = 23; - t.tm_mday = 31; - t.tm_mon = 11; - t.tm_year = 161; - t.tm_wday = 6; - t.tm_yday = 364; - t.tm_isdst = -1; - char buf[100]; - char f[3] = {0}; - f[0] = '%'; - f[1] = fmt; - strftime_l(buf, countof(buf), f, &t, __loc_); - wchar_t wbuf[100]; - wchar_t* wbb = wbuf; - mbstate_t mb = {0}; - const char* bb = buf; - size_t j = __libcpp_mbsrtowcs_l( wbb, &bb, countof(wbuf), &mb, __loc_); - if (j == size_t(-1)) - __throw_runtime_error("locale not supported"); - wchar_t* wbe = wbb + j; - wstring result; - while (wbb != wbe) - { - if (ct.is(ctype_base::space, *wbb)) - { - result.push_back(L' '); - for (++wbb; wbb != wbe && ct.is(ctype_base::space, *wbb); ++wbb) - ; - continue; - } - wchar_t* w = wbb; - ios_base::iostate err = ios_base::goodbit; - ptrdiff_t i = __scan_keyword(w, wbe, this->__weeks_, this->__weeks_+14, - ct, err, false) - - this->__weeks_; - if (i < 14) - { - result.push_back(L'%'); - if (i < 7) - result.push_back(L'A'); - else - result.push_back(L'a'); - wbb = w; - continue; - } - w = wbb; - i = __scan_keyword(w, wbe, this->__months_, this->__months_+24, - ct, err, false) - - this->__months_; - if (i < 24) - { - result.push_back(L'%'); - if (i < 12) - result.push_back(L'B'); - else - result.push_back(L'b'); - if (fmt == 'x' && ct.is(ctype_base::digit, this->__months_[i][0])) - result.back() = L'm'; - wbb = w; - continue; - } - if (this->__am_pm_[0].size() + this->__am_pm_[1].size() > 0) - { - w = wbb; - i = __scan_keyword(w, wbe, this->__am_pm_, this->__am_pm_+2, - ct, err, false) - this->__am_pm_; - if (i < 2) - { - result.push_back(L'%'); - result.push_back(L'p'); - wbb = w; - continue; - } - } - w = wbb; - if (ct.is(ctype_base::digit, *wbb)) - { - switch(__get_up_to_n_digits(wbb, wbe, err, ct, 4)) - { - case 6: - result.push_back(L'%'); - result.push_back(L'w'); - break; - case 7: - result.push_back(L'%'); - result.push_back(L'u'); - break; - case 11: - result.push_back(L'%'); - result.push_back(L'I'); - break; - case 12: - result.push_back(L'%'); - result.push_back(L'm'); - break; - case 23: - result.push_back(L'%'); - result.push_back(L'H'); - break; - case 31: - result.push_back(L'%'); - result.push_back(L'd'); - break; - case 55: - result.push_back(L'%'); - result.push_back(L'M'); - break; - case 59: - result.push_back(L'%'); - result.push_back(L'S'); - break; - case 61: - result.push_back(L'%'); - result.push_back(L'y'); - break; - case 364: - result.push_back(L'%'); - result.push_back(L'j'); - break; - case 2061: - result.push_back(L'%'); - result.push_back(L'Y'); - break; - default: - for (; w != wbb; ++w) - result.push_back(*w); - break; - } - continue; - } - if (ct.narrow(*wbb, 0) == '%') - { - result.push_back(L'%'); - result.push_back(L'%'); - ++wbb; - continue; - } - result.push_back(*wbb); - ++wbb; - } - return result; -} - -template <> -void -__time_get_storage::init(const ctype& ct) -{ - tm t = {0}; - char buf[100]; - // __weeks_ - for (int i = 0; i < 7; ++i) - { - t.tm_wday = i; - strftime_l(buf, countof(buf), "%A", &t, __loc_); - __weeks_[i] = buf; - strftime_l(buf, countof(buf), "%a", &t, __loc_); - __weeks_[i+7] = buf; - } - // __months_ - for (int i = 0; i < 12; ++i) - { - t.tm_mon = i; - strftime_l(buf, countof(buf), "%B", &t, __loc_); - __months_[i] = buf; - strftime_l(buf, countof(buf), "%b", &t, __loc_); - __months_[i+12] = buf; - } - // __am_pm_ - t.tm_hour = 1; - strftime_l(buf, countof(buf), "%p", &t, __loc_); - __am_pm_[0] = buf; - t.tm_hour = 13; - strftime_l(buf, countof(buf), "%p", &t, __loc_); - __am_pm_[1] = buf; - __c_ = __analyze('c', ct); - __r_ = __analyze('r', ct); - __x_ = __analyze('x', ct); - __X_ = __analyze('X', ct); -} - -template <> -void -__time_get_storage::init(const ctype& ct) -{ - tm t = {0}; - char buf[100]; - wchar_t wbuf[100]; - wchar_t* wbe; - mbstate_t mb = {0}; - // __weeks_ - for (int i = 0; i < 7; ++i) - { - t.tm_wday = i; - strftime_l(buf, countof(buf), "%A", &t, __loc_); - mb = mbstate_t(); - const char* bb = buf; - size_t j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); - if (j == size_t(-1)) - __throw_runtime_error("locale not supported"); - wbe = wbuf + j; - __weeks_[i].assign(wbuf, wbe); - strftime_l(buf, countof(buf), "%a", &t, __loc_); - mb = mbstate_t(); - bb = buf; - j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); - if (j == size_t(-1)) - __throw_runtime_error("locale not supported"); - wbe = wbuf + j; - __weeks_[i+7].assign(wbuf, wbe); - } - // __months_ - for (int i = 0; i < 12; ++i) - { - t.tm_mon = i; - strftime_l(buf, countof(buf), "%B", &t, __loc_); - mb = mbstate_t(); - const char* bb = buf; - size_t j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); - if (j == size_t(-1)) - __throw_runtime_error("locale not supported"); - wbe = wbuf + j; - __months_[i].assign(wbuf, wbe); - strftime_l(buf, countof(buf), "%b", &t, __loc_); - mb = mbstate_t(); - bb = buf; - j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); - if (j == size_t(-1)) - __throw_runtime_error("locale not supported"); - wbe = wbuf + j; - __months_[i+12].assign(wbuf, wbe); - } - // __am_pm_ - t.tm_hour = 1; - strftime_l(buf, countof(buf), "%p", &t, __loc_); - mb = mbstate_t(); - const char* bb = buf; - size_t j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); - if (j == size_t(-1)) - __throw_runtime_error("locale not supported"); - wbe = wbuf + j; - __am_pm_[0].assign(wbuf, wbe); - t.tm_hour = 13; - strftime_l(buf, countof(buf), "%p", &t, __loc_); - mb = mbstate_t(); - bb = buf; - j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); - if (j == size_t(-1)) - __throw_runtime_error("locale not supported"); - wbe = wbuf + j; - __am_pm_[1].assign(wbuf, wbe); - __c_ = __analyze('c', ct); - __r_ = __analyze('r', ct); - __x_ = __analyze('x', ct); - __X_ = __analyze('X', ct); -} - -template -struct _LIBCPP_HIDDEN __time_get_temp - : public ctype_byname -{ - explicit __time_get_temp(const char* nm) - : ctype_byname(nm, 1) {} - explicit __time_get_temp(const string& nm) - : ctype_byname(nm, 1) {} -}; - -template <> -__time_get_storage::__time_get_storage(const char* __nm) - : __time_get(__nm) -{ - const __time_get_temp ct(__nm); - init(ct); -} - -template <> -__time_get_storage::__time_get_storage(const string& __nm) - : __time_get(__nm) -{ - const __time_get_temp ct(__nm); - init(ct); -} - -template <> -__time_get_storage::__time_get_storage(const char* __nm) - : __time_get(__nm) -{ - const __time_get_temp ct(__nm); - init(ct); -} - -template <> -__time_get_storage::__time_get_storage(const string& __nm) - : __time_get(__nm) -{ - const __time_get_temp ct(__nm); - init(ct); -} - -template <> -time_base::dateorder -__time_get_storage::__do_date_order() const -{ - unsigned i; - for (i = 0; i < __x_.size(); ++i) - if (__x_[i] == '%') - break; - ++i; - switch (__x_[i]) - { - case 'y': - case 'Y': - for (++i; i < __x_.size(); ++i) - if (__x_[i] == '%') - break; - if (i == __x_.size()) - break; - ++i; - switch (__x_[i]) - { - case 'm': - for (++i; i < __x_.size(); ++i) - if (__x_[i] == '%') - break; - if (i == __x_.size()) - break; - ++i; - if (__x_[i] == 'd') - return time_base::ymd; - break; - case 'd': - for (++i; i < __x_.size(); ++i) - if (__x_[i] == '%') - break; - if (i == __x_.size()) - break; - ++i; - if (__x_[i] == 'm') - return time_base::ydm; - break; - } - break; - case 'm': - for (++i; i < __x_.size(); ++i) - if (__x_[i] == '%') - break; - if (i == __x_.size()) - break; - ++i; - if (__x_[i] == 'd') - { - for (++i; i < __x_.size(); ++i) - if (__x_[i] == '%') - break; - if (i == __x_.size()) - break; - ++i; - if (__x_[i] == 'y' || __x_[i] == 'Y') - return time_base::mdy; - break; - } - break; - case 'd': - for (++i; i < __x_.size(); ++i) - if (__x_[i] == '%') - break; - if (i == __x_.size()) - break; - ++i; - if (__x_[i] == 'm') - { - for (++i; i < __x_.size(); ++i) - if (__x_[i] == '%') - break; - if (i == __x_.size()) - break; - ++i; - if (__x_[i] == 'y' || __x_[i] == 'Y') - return time_base::dmy; - break; - } - break; - } - return time_base::no_order; -} - -template <> -time_base::dateorder -__time_get_storage::__do_date_order() const -{ - unsigned i; - for (i = 0; i < __x_.size(); ++i) - if (__x_[i] == L'%') - break; - ++i; - switch (__x_[i]) - { - case L'y': - case L'Y': - for (++i; i < __x_.size(); ++i) - if (__x_[i] == L'%') - break; - if (i == __x_.size()) - break; - ++i; - switch (__x_[i]) - { - case L'm': - for (++i; i < __x_.size(); ++i) - if (__x_[i] == L'%') - break; - if (i == __x_.size()) - break; - ++i; - if (__x_[i] == L'd') - return time_base::ymd; - break; - case L'd': - for (++i; i < __x_.size(); ++i) - if (__x_[i] == L'%') - break; - if (i == __x_.size()) - break; - ++i; - if (__x_[i] == L'm') - return time_base::ydm; - break; - } - break; - case L'm': - for (++i; i < __x_.size(); ++i) - if (__x_[i] == L'%') - break; - if (i == __x_.size()) - break; - ++i; - if (__x_[i] == L'd') - { - for (++i; i < __x_.size(); ++i) - if (__x_[i] == L'%') - break; - if (i == __x_.size()) - break; - ++i; - if (__x_[i] == L'y' || __x_[i] == L'Y') - return time_base::mdy; - break; - } - break; - case L'd': - for (++i; i < __x_.size(); ++i) - if (__x_[i] == L'%') - break; - if (i == __x_.size()) - break; - ++i; - if (__x_[i] == L'm') - { - for (++i; i < __x_.size(); ++i) - if (__x_[i] == L'%') - break; - if (i == __x_.size()) - break; - ++i; - if (__x_[i] == L'y' || __x_[i] == L'Y') - return time_base::dmy; - break; - } - break; - } - return time_base::no_order; -} - -// time_put - -__time_put::__time_put(const char* nm) - : __loc_(newlocale(LC_ALL_MASK, nm, 0)) -{ - if (__loc_ == 0) - __throw_runtime_error("time_put_byname" - " failed to construct for " + string(nm)); -} - -__time_put::__time_put(const string& nm) - : __loc_(newlocale(LC_ALL_MASK, nm.c_str(), 0)) -{ - if (__loc_ == 0) - __throw_runtime_error("time_put_byname" - " failed to construct for " + nm); -} - -__time_put::~__time_put() -{ - if (__loc_ != _LIBCPP_GET_C_LOCALE) - freelocale(__loc_); -} - -void -__time_put::__do_put(char* __nb, char*& __ne, const tm* __tm, - char __fmt, char __mod) const -{ - char fmt[] = {'%', __fmt, __mod, 0}; - if (__mod != 0) - swap(fmt[1], fmt[2]); - size_t n = strftime_l(__nb, countof(__nb, __ne), fmt, __tm, __loc_); - __ne = __nb + n; -} - -void -__time_put::__do_put(wchar_t* __wb, wchar_t*& __we, const tm* __tm, - char __fmt, char __mod) const -{ - char __nar[100]; - char* __ne = __nar + 100; - __do_put(__nar, __ne, __tm, __fmt, __mod); - mbstate_t mb = {0}; - const char* __nb = __nar; - size_t j = __libcpp_mbsrtowcs_l(__wb, &__nb, countof(__wb, __we), &mb, __loc_); - if (j == size_t(-1)) - __throw_runtime_error("locale not supported"); - __we = __wb + j; -} - -// moneypunct_byname - -template -static -void -__init_pat(money_base::pattern& pat, basic_string& __curr_symbol_, - bool intl, char cs_precedes, char sep_by_space, char sign_posn, - charT space_char) -{ - const char sign = static_cast(money_base::sign); - const char space = static_cast(money_base::space); - const char none = static_cast(money_base::none); - const char symbol = static_cast(money_base::symbol); - const char value = static_cast(money_base::value); - const bool symbol_contains_sep = intl && __curr_symbol_.size() == 4; - - // Comments on case branches reflect 'C11 7.11.2.1 The localeconv - // function'. "Space between sign and symbol or value" means that - // if the sign is adjacent to the symbol, there's a space between - // them, and otherwise there's a space between the sign and value. - // - // C11's localeconv specifies that the fourth character of an - // international curr_symbol is used to separate the sign and - // value when sep_by_space says to do so. C++ can't represent - // that, so we just use a space. When sep_by_space says to - // separate the symbol and value-or-sign with a space, we rearrange the - // curr_symbol to put its spacing character on the correct side of - // the symbol. - // - // We also need to avoid adding an extra space between the sign - // and value when the currency symbol is suppressed (by not - // setting showbase). We match glibc's strfmon by interpreting - // sep_by_space==1 as "omit the space when the currency symbol is - // absent". - // - // Users who want to get this right should use ICU instead. - - switch (cs_precedes) - { - case 0: // value before curr_symbol - if (symbol_contains_sep) { - // Move the separator to before the symbol, to place it - // between the value and symbol. - rotate(__curr_symbol_.begin(), __curr_symbol_.begin() + 3, - __curr_symbol_.end()); - } - switch (sign_posn) - { - case 0: // Parentheses surround the quantity and currency symbol. - pat.field[0] = sign; - pat.field[1] = value; - pat.field[2] = none; // Any space appears in the symbol. - pat.field[3] = symbol; - switch (sep_by_space) - { - case 0: // No space separates the currency symbol and value. - // This case may have changed between C99 and C11; - // assume the currency symbol matches the intention. - case 2: // Space between sign and currency or value. - // The "sign" is two parentheses, so no space here either. - return; - case 1: // Space between currency-and-sign or currency and value. - if (!symbol_contains_sep) { - // We insert the space into the symbol instead of - // setting pat.field[2]=space so that when - // showbase is not set, the space goes away too. - __curr_symbol_.insert(0, 1, space_char); - } - return; - default: - break; - } - break; - case 1: // The sign string precedes the quantity and currency symbol. - pat.field[0] = sign; - pat.field[3] = symbol; - switch (sep_by_space) - { - case 0: // No space separates the currency symbol and value. - pat.field[1] = value; - pat.field[2] = none; - return; - case 1: // Space between currency-and-sign or currency and value. - pat.field[1] = value; - pat.field[2] = none; - if (!symbol_contains_sep) { - // We insert the space into the symbol instead of - // setting pat.field[2]=space so that when - // showbase is not set, the space goes away too. - __curr_symbol_.insert(0, 1, space_char); - } - return; - case 2: // Space between sign and currency or value. - pat.field[1] = space; - pat.field[2] = value; - if (symbol_contains_sep) { - // Remove the separator from the symbol, since it - // has already appeared after the sign. - __curr_symbol_.erase(__curr_symbol_.begin()); - } - return; - default: - break; - } - break; - case 2: // The sign string succeeds the quantity and currency symbol. - pat.field[0] = value; - pat.field[3] = sign; - switch (sep_by_space) - { - case 0: // No space separates the currency symbol and value. - pat.field[1] = none; - pat.field[2] = symbol; - return; - case 1: // Space between currency-and-sign or currency and value. - if (!symbol_contains_sep) { - // We insert the space into the symbol instead of - // setting pat.field[1]=space so that when - // showbase is not set, the space goes away too. - __curr_symbol_.insert(0, 1, space_char); - } - pat.field[1] = none; - pat.field[2] = symbol; - return; - case 2: // Space between sign and currency or value. - pat.field[1] = symbol; - pat.field[2] = space; - if (symbol_contains_sep) { - // Remove the separator from the symbol, since it - // should not be removed if showbase is absent. - __curr_symbol_.erase(__curr_symbol_.begin()); - } - return; - default: - break; - } - break; - case 3: // The sign string immediately precedes the currency symbol. - pat.field[0] = value; - pat.field[3] = symbol; - switch (sep_by_space) - { - case 0: // No space separates the currency symbol and value. - pat.field[1] = none; - pat.field[2] = sign; - return; - case 1: // Space between currency-and-sign or currency and value. - pat.field[1] = space; - pat.field[2] = sign; - if (symbol_contains_sep) { - // Remove the separator from the symbol, since it - // has already appeared before the sign. - __curr_symbol_.erase(__curr_symbol_.begin()); - } - return; - case 2: // Space between sign and currency or value. - pat.field[1] = sign; - pat.field[2] = none; - if (!symbol_contains_sep) { - // We insert the space into the symbol instead of - // setting pat.field[2]=space so that when - // showbase is not set, the space goes away too. - __curr_symbol_.insert(0, 1, space_char); - } - return; - default: - break; - } - break; - case 4: // The sign string immediately succeeds the currency symbol. - pat.field[0] = value; - pat.field[3] = sign; - switch (sep_by_space) - { - case 0: // No space separates the currency symbol and value. - pat.field[1] = none; - pat.field[2] = symbol; - return; - case 1: // Space between currency-and-sign or currency and value. - pat.field[1] = none; - pat.field[2] = symbol; - if (!symbol_contains_sep) { - // We insert the space into the symbol instead of - // setting pat.field[1]=space so that when - // showbase is not set, the space goes away too. - __curr_symbol_.insert(0, 1, space_char); - } - return; - case 2: // Space between sign and currency or value. - pat.field[1] = symbol; - pat.field[2] = space; - if (symbol_contains_sep) { - // Remove the separator from the symbol, since it - // should not disappear when showbase is absent. - __curr_symbol_.erase(__curr_symbol_.begin()); - } - return; - default: - break; - } - break; - default: - break; - } - break; - case 1: // curr_symbol before value - switch (sign_posn) - { - case 0: // Parentheses surround the quantity and currency symbol. - pat.field[0] = sign; - pat.field[1] = symbol; - pat.field[2] = none; // Any space appears in the symbol. - pat.field[3] = value; - switch (sep_by_space) - { - case 0: // No space separates the currency symbol and value. - // This case may have changed between C99 and C11; - // assume the currency symbol matches the intention. - case 2: // Space between sign and currency or value. - // The "sign" is two parentheses, so no space here either. - return; - case 1: // Space between currency-and-sign or currency and value. - if (!symbol_contains_sep) { - // We insert the space into the symbol instead of - // setting pat.field[2]=space so that when - // showbase is not set, the space goes away too. - __curr_symbol_.insert(0, 1, space_char); - } - return; - default: - break; - } - break; - case 1: // The sign string precedes the quantity and currency symbol. - pat.field[0] = sign; - pat.field[3] = value; - switch (sep_by_space) - { - case 0: // No space separates the currency symbol and value. - pat.field[1] = symbol; - pat.field[2] = none; - return; - case 1: // Space between currency-and-sign or currency and value. - pat.field[1] = symbol; - pat.field[2] = none; - if (!symbol_contains_sep) { - // We insert the space into the symbol instead of - // setting pat.field[2]=space so that when - // showbase is not set, the space goes away too. - __curr_symbol_.push_back(space_char); - } - return; - case 2: // Space between sign and currency or value. - pat.field[1] = space; - pat.field[2] = symbol; - if (symbol_contains_sep) { - // Remove the separator from the symbol, since it - // has already appeared after the sign. - __curr_symbol_.pop_back(); - } - return; - default: - break; - } - break; - case 2: // The sign string succeeds the quantity and currency symbol. - pat.field[0] = symbol; - pat.field[3] = sign; - switch (sep_by_space) - { - case 0: // No space separates the currency symbol and value. - pat.field[1] = none; - pat.field[2] = value; - return; - case 1: // Space between currency-and-sign or currency and value. - pat.field[1] = none; - pat.field[2] = value; - if (!symbol_contains_sep) { - // We insert the space into the symbol instead of - // setting pat.field[1]=space so that when - // showbase is not set, the space goes away too. - __curr_symbol_.push_back(space_char); - } - return; - case 2: // Space between sign and currency or value. - pat.field[1] = value; - pat.field[2] = space; - if (symbol_contains_sep) { - // Remove the separator from the symbol, since it - // will appear before the sign. - __curr_symbol_.pop_back(); - } - return; - default: - break; - } - break; - case 3: // The sign string immediately precedes the currency symbol. - pat.field[0] = sign; - pat.field[3] = value; - switch (sep_by_space) - { - case 0: // No space separates the currency symbol and value. - pat.field[1] = symbol; - pat.field[2] = none; - return; - case 1: // Space between currency-and-sign or currency and value. - pat.field[1] = symbol; - pat.field[2] = none; - if (!symbol_contains_sep) { - // We insert the space into the symbol instead of - // setting pat.field[2]=space so that when - // showbase is not set, the space goes away too. - __curr_symbol_.push_back(space_char); - } - return; - case 2: // Space between sign and currency or value. - pat.field[1] = space; - pat.field[2] = symbol; - if (symbol_contains_sep) { - // Remove the separator from the symbol, since it - // has already appeared after the sign. - __curr_symbol_.pop_back(); - } - return; - default: - break; - } - break; - case 4: // The sign string immediately succeeds the currency symbol. - pat.field[0] = symbol; - pat.field[3] = value; - switch (sep_by_space) - { - case 0: // No space separates the currency symbol and value. - pat.field[1] = sign; - pat.field[2] = none; - return; - case 1: // Space between currency-and-sign or currency and value. - pat.field[1] = sign; - pat.field[2] = space; - if (symbol_contains_sep) { - // Remove the separator from the symbol, since it - // should not disappear when showbase is absent. - __curr_symbol_.pop_back(); - } - return; - case 2: // Space between sign and currency or value. - pat.field[1] = none; - pat.field[2] = sign; - if (!symbol_contains_sep) { - // We insert the space into the symbol instead of - // setting pat.field[1]=space so that when - // showbase is not set, the space goes away too. - __curr_symbol_.push_back(space_char); - } - return; - default: - break; - } - break; - default: - break; - } - break; - default: - break; - } - pat.field[0] = symbol; - pat.field[1] = sign; - pat.field[2] = none; - pat.field[3] = value; -} - -template<> -void -moneypunct_byname::init(const char* nm) -{ - typedef moneypunct base; - __libcpp_unique_locale loc(nm); - if (!loc) - __throw_runtime_error("moneypunct_byname" - " failed to construct for " + string(nm)); - - lconv* lc = __libcpp_localeconv_l(loc.get()); - if (!checked_string_to_char_convert(__decimal_point_, - lc->mon_decimal_point, - loc.get())) - __decimal_point_ = base::do_decimal_point(); - if (!checked_string_to_char_convert(__thousands_sep_, - lc->mon_thousands_sep, - loc.get())) - __thousands_sep_ = base::do_thousands_sep(); - - __grouping_ = lc->mon_grouping; - __curr_symbol_ = lc->currency_symbol; - if (lc->frac_digits != CHAR_MAX) - __frac_digits_ = lc->frac_digits; - else - __frac_digits_ = base::do_frac_digits(); - if (lc->p_sign_posn == 0) - __positive_sign_ = "()"; - else - __positive_sign_ = lc->positive_sign; - if (lc->n_sign_posn == 0) - __negative_sign_ = "()"; - else - __negative_sign_ = lc->negative_sign; - // Assume the positive and negative formats will want spaces in - // the same places in curr_symbol since there's no way to - // represent anything else. - string_type __dummy_curr_symbol = __curr_symbol_; - __init_pat(__pos_format_, __dummy_curr_symbol, false, - lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, ' '); - __init_pat(__neg_format_, __curr_symbol_, false, - lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, ' '); -} - -template<> -void -moneypunct_byname::init(const char* nm) -{ - typedef moneypunct base; - __libcpp_unique_locale loc(nm); - if (!loc) - __throw_runtime_error("moneypunct_byname" - " failed to construct for " + string(nm)); - - lconv* lc = __libcpp_localeconv_l(loc.get()); - if (!checked_string_to_char_convert(__decimal_point_, - lc->mon_decimal_point, - loc.get())) - __decimal_point_ = base::do_decimal_point(); - if (!checked_string_to_char_convert(__thousands_sep_, - lc->mon_thousands_sep, - loc.get())) - __thousands_sep_ = base::do_thousands_sep(); - __grouping_ = lc->mon_grouping; - __curr_symbol_ = lc->int_curr_symbol; - if (lc->int_frac_digits != CHAR_MAX) - __frac_digits_ = lc->int_frac_digits; - else - __frac_digits_ = base::do_frac_digits(); -#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__) - if (lc->p_sign_posn == 0) -#else // _LIBCPP_MSVCRT - if (lc->int_p_sign_posn == 0) -#endif // !_LIBCPP_MSVCRT - __positive_sign_ = "()"; - else - __positive_sign_ = lc->positive_sign; -#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__) - if(lc->n_sign_posn == 0) -#else // _LIBCPP_MSVCRT - if (lc->int_n_sign_posn == 0) -#endif // !_LIBCPP_MSVCRT - __negative_sign_ = "()"; - else - __negative_sign_ = lc->negative_sign; - // Assume the positive and negative formats will want spaces in - // the same places in curr_symbol since there's no way to - // represent anything else. - string_type __dummy_curr_symbol = __curr_symbol_; -#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__) - __init_pat(__pos_format_, __dummy_curr_symbol, true, - lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, ' '); - __init_pat(__neg_format_, __curr_symbol_, true, - lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, ' '); -#else // _LIBCPP_MSVCRT - __init_pat(__pos_format_, __dummy_curr_symbol, true, - lc->int_p_cs_precedes, lc->int_p_sep_by_space, - lc->int_p_sign_posn, ' '); - __init_pat(__neg_format_, __curr_symbol_, true, - lc->int_n_cs_precedes, lc->int_n_sep_by_space, - lc->int_n_sign_posn, ' '); -#endif // !_LIBCPP_MSVCRT -} - -template<> -void -moneypunct_byname::init(const char* nm) -{ - typedef moneypunct base; - __libcpp_unique_locale loc(nm); - if (!loc) - __throw_runtime_error("moneypunct_byname" - " failed to construct for " + string(nm)); - lconv* lc = __libcpp_localeconv_l(loc.get()); - if (!checked_string_to_wchar_convert(__decimal_point_, - lc->mon_decimal_point, - loc.get())) - __decimal_point_ = base::do_decimal_point(); - if (!checked_string_to_wchar_convert(__thousands_sep_, - lc->mon_thousands_sep, - loc.get())) - __thousands_sep_ = base::do_thousands_sep(); - __grouping_ = lc->mon_grouping; - wchar_t wbuf[100]; - mbstate_t mb = {0}; - const char* bb = lc->currency_symbol; - size_t j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); - if (j == size_t(-1)) - __throw_runtime_error("locale not supported"); - wchar_t* wbe = wbuf + j; - __curr_symbol_.assign(wbuf, wbe); - if (lc->frac_digits != CHAR_MAX) - __frac_digits_ = lc->frac_digits; - else - __frac_digits_ = base::do_frac_digits(); - if (lc->p_sign_posn == 0) - __positive_sign_ = L"()"; - else - { - mb = mbstate_t(); - bb = lc->positive_sign; - j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); - if (j == size_t(-1)) - __throw_runtime_error("locale not supported"); - wbe = wbuf + j; - __positive_sign_.assign(wbuf, wbe); - } - if (lc->n_sign_posn == 0) - __negative_sign_ = L"()"; - else - { - mb = mbstate_t(); - bb = lc->negative_sign; - j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); - if (j == size_t(-1)) - __throw_runtime_error("locale not supported"); - wbe = wbuf + j; - __negative_sign_.assign(wbuf, wbe); - } - // Assume the positive and negative formats will want spaces in - // the same places in curr_symbol since there's no way to - // represent anything else. - string_type __dummy_curr_symbol = __curr_symbol_; - __init_pat(__pos_format_, __dummy_curr_symbol, false, - lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, L' '); - __init_pat(__neg_format_, __curr_symbol_, false, - lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, L' '); -} - -template<> -void -moneypunct_byname::init(const char* nm) -{ - typedef moneypunct base; - __libcpp_unique_locale loc(nm); - if (!loc) - __throw_runtime_error("moneypunct_byname" - " failed to construct for " + string(nm)); - - lconv* lc = __libcpp_localeconv_l(loc.get()); - if (!checked_string_to_wchar_convert(__decimal_point_, - lc->mon_decimal_point, - loc.get())) - __decimal_point_ = base::do_decimal_point(); - if (!checked_string_to_wchar_convert(__thousands_sep_, - lc->mon_thousands_sep, - loc.get())) - __thousands_sep_ = base::do_thousands_sep(); - __grouping_ = lc->mon_grouping; - wchar_t wbuf[100]; - mbstate_t mb = {0}; - const char* bb = lc->int_curr_symbol; - size_t j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); - if (j == size_t(-1)) - __throw_runtime_error("locale not supported"); - wchar_t* wbe = wbuf + j; - __curr_symbol_.assign(wbuf, wbe); - if (lc->int_frac_digits != CHAR_MAX) - __frac_digits_ = lc->int_frac_digits; - else - __frac_digits_ = base::do_frac_digits(); -#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__) - if (lc->p_sign_posn == 0) -#else // _LIBCPP_MSVCRT - if (lc->int_p_sign_posn == 0) -#endif // !_LIBCPP_MSVCRT - __positive_sign_ = L"()"; - else - { - mb = mbstate_t(); - bb = lc->positive_sign; - j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); - if (j == size_t(-1)) - __throw_runtime_error("locale not supported"); - wbe = wbuf + j; - __positive_sign_.assign(wbuf, wbe); - } -#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__) - if (lc->n_sign_posn == 0) -#else // _LIBCPP_MSVCRT - if (lc->int_n_sign_posn == 0) -#endif // !_LIBCPP_MSVCRT - __negative_sign_ = L"()"; - else - { - mb = mbstate_t(); - bb = lc->negative_sign; - j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); - if (j == size_t(-1)) - __throw_runtime_error("locale not supported"); - wbe = wbuf + j; - __negative_sign_.assign(wbuf, wbe); - } - // Assume the positive and negative formats will want spaces in - // the same places in curr_symbol since there's no way to - // represent anything else. - string_type __dummy_curr_symbol = __curr_symbol_; -#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__) - __init_pat(__pos_format_, __dummy_curr_symbol, true, - lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, L' '); - __init_pat(__neg_format_, __curr_symbol_, true, - lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, L' '); -#else // _LIBCPP_MSVCRT - __init_pat(__pos_format_, __dummy_curr_symbol, true, - lc->int_p_cs_precedes, lc->int_p_sep_by_space, - lc->int_p_sign_posn, L' '); - __init_pat(__neg_format_, __curr_symbol_, true, - lc->int_n_cs_precedes, lc->int_n_sep_by_space, - lc->int_n_sign_posn, L' '); -#endif // !_LIBCPP_MSVCRT -} - -void __do_nothing(void*) {} - -void __throw_runtime_error(const char* msg) -{ -#ifndef _LIBCPP_NO_EXCEPTIONS - throw runtime_error(msg); -#else - (void)msg; - _VSTD::abort(); -#endif -} - -template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS collate; -template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS collate; - -template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS num_get; -template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS num_get; - -template struct _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __num_get; -template struct _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __num_get; - -template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS num_put; -template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS num_put; - -template struct _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __num_put; -template struct _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __num_put; - -template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_get; -template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_get; - -template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_get_byname; -template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_get_byname; - -template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_put; -template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_put; - -template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_put_byname; -template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_put_byname; - -template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct; -template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct; -template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct; -template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct; - -template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname; -template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname; -template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname; -template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname; - -template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_get; -template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_get; - -template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_get; -template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_get; - -template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_put; -template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_put; - -template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_put; -template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_put; - -template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages; -template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages; - -template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages_byname; -template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages_byname; - -template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname; -template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname; -template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname; -template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname; - -_LIBCPP_END_NAMESPACE_STD diff --git a/third_party/libcxx/locale1.cc b/third_party/libcxx/locale1.cc new file mode 100644 index 000000000..72e4d6dde --- /dev/null +++ b/third_party/libcxx/locale1.cc @@ -0,0 +1,1660 @@ +// clang-format off +//===------------------------- locale.cpp ---------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "third_party/libcxx/string" +#include "third_party/libcxx/locale" +#include "third_party/libcxx/codecvt" +#include "third_party/libcxx/vector" +#include "third_party/libcxx/algorithm" +#include "third_party/libcxx/typeinfo" +#ifndef _LIBCPP_NO_EXCEPTIONS +#include "third_party/libcxx/type_traits" +#endif +#include "third_party/libcxx/clocale" +#include "third_party/libcxx/cstring" +#include "third_party/libcxx/cwctype" +#include "third_party/libcxx/__sso_allocator" +#include "third_party/libcxx/include/atomic_support.hh" +#include "libc/str/locale.h" +#include "third_party/libcxx/__undef_macros" + +// On Linux, wint_t and wchar_t have different signed-ness, and this causes +// lots of noise in the build log, but no bugs that I know of. +#if defined(__clang__) +#pragma clang diagnostic ignored "-Wsign-conversion" +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#ifdef __cloc_defined +locale_t __cloc() { + // In theory this could create a race condition. In practice + // the race condition is non-fatal since it will just create + // a little resource leak. Better approach would be appreciated. + static locale_t result = newlocale(LC_ALL_MASK, "C", 0); + return result; +} +#endif // __cloc_defined + +namespace { + +struct release +{ + void operator()(locale::facet* p) {p->__release_shared();} +}; + +template +inline +T& +make(A0 a0) +{ + static typename aligned_storage::type buf; + auto *obj = ::new (&buf) T(a0); + return *obj; +} + +template +inline +T& +make(A0 a0, A1 a1) +{ + static typename aligned_storage::type buf; + ::new (&buf) T(a0, a1); + return *reinterpret_cast(&buf); +} + +template +inline +T& +make(A0 a0, A1 a1, A2 a2) +{ + static typename aligned_storage::type buf; + auto *obj = ::new (&buf) T(a0, a1, a2); + return *obj; +} + +_LIBCPP_NORETURN static void __throw_runtime_error(const string &msg) +{ +#ifndef _LIBCPP_NO_EXCEPTIONS + throw runtime_error(msg); +#else + (void)msg; + _VSTD::abort(); +#endif +} + +} + +#if defined(_AIX) +// Set priority to INT_MIN + 256 + 150 +# pragma priority ( -2147483242 ) +#endif + +const locale::category locale::none; +const locale::category locale::collate; +const locale::category locale::ctype; +const locale::category locale::monetary; +const locale::category locale::numeric; +const locale::category locale::time; +const locale::category locale::messages; +const locale::category locale::all; + +class _LIBCPP_HIDDEN locale::__imp + : public facet +{ + enum {N = 28}; +#if defined(_LIBCPP_COMPILER_MSVC) +// FIXME: MSVC doesn't support aligned parameters by value. +// I can't get the __sso_allocator to work here +// for MSVC I think for this reason. + vector facets_; +#else + vector > facets_; +#endif + string name_; +public: + explicit __imp(size_t refs = 0); + explicit __imp(const string& name, size_t refs = 0); + __imp(const __imp&); + __imp(const __imp&, const string&, locale::category c); + __imp(const __imp& other, const __imp& one, locale::category c); + __imp(const __imp&, facet* f, long id); + ~__imp(); + + const string& name() const {return name_;} + bool has_facet(long id) const + {return static_cast(id) < facets_.size() && facets_[static_cast(id)];} + const locale::facet* use_facet(long id) const; + + static const locale& make_classic(); + static locale& make_global(); +private: + void install(facet* f, long id); + template void install(F* f) {install(f, f->id.__get());} + template void install_from(const __imp& other); +}; + +locale::__imp::__imp(size_t refs) + : facet(refs), + facets_(N), + name_("C") +{ + facets_.clear(); + install(&make<_VSTD::collate >(1u)); + install(&make<_VSTD::collate >(1u)); + install(&make<_VSTD::ctype >(nullptr, false, 1u)); + install(&make<_VSTD::ctype >(1u)); + install(&make >(1u)); + install(&make >(1u)); + install(&make >(1u)); + install(&make >(1u)); + install(&make >(1u)); + install(&make >(1u)); + install(&make >(1u)); + install(&make >(1u)); + install(&make >(1u)); + install(&make >(1u)); + install(&make >(1u)); + install(&make >(1u)); + install(&make >(1u)); + install(&make >(1u)); + install(&make >(1u)); + install(&make >(1u)); + install(&make >(1u)); + install(&make >(1u)); + install(&make >(1u)); + install(&make >(1u)); + install(&make >(1u)); + install(&make >(1u)); + install(&make<_VSTD::messages >(1u)); + install(&make<_VSTD::messages >(1u)); +} + +locale::__imp::__imp(const string& name, size_t refs) + : facet(refs), + facets_(N), + name_(name) +{ +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + facets_ = locale::classic().__locale_->facets_; + for (unsigned i = 0; i < facets_.size(); ++i) + if (facets_[i]) + facets_[i]->__add_shared(); + install(new collate_byname(name_)); + install(new collate_byname(name_)); + install(new ctype_byname(name_)); + install(new ctype_byname(name_)); + install(new codecvt_byname(name_)); + install(new codecvt_byname(name_)); + install(new codecvt_byname(name_)); + install(new codecvt_byname(name_)); + install(new numpunct_byname(name_)); + install(new numpunct_byname(name_)); + install(new moneypunct_byname(name_)); + install(new moneypunct_byname(name_)); + install(new moneypunct_byname(name_)); + install(new moneypunct_byname(name_)); + install(new time_get_byname(name_)); + install(new time_get_byname(name_)); + install(new time_put_byname(name_)); + install(new time_put_byname(name_)); + install(new messages_byname(name_)); + install(new messages_byname(name_)); +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + for (unsigned i = 0; i < facets_.size(); ++i) + if (facets_[i]) + facets_[i]->__release_shared(); + throw; + } +#endif // _LIBCPP_NO_EXCEPTIONS +} + +// NOTE avoid the `base class should be explicitly initialized in the +// copy constructor` warning emitted by GCC +#if defined(__clang__) || _GNUC_VER >= 406 +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wextra" +#endif + +locale::__imp::__imp(const __imp& other) + : facets_(max(N, other.facets_.size())), + name_(other.name_) +{ + facets_ = other.facets_; + for (unsigned i = 0; i < facets_.size(); ++i) + if (facets_[i]) + facets_[i]->__add_shared(); +} + +#if defined(__clang__) || _GNUC_VER >= 406 +#pragma GCC diagnostic pop +#endif + +locale::__imp::__imp(const __imp& other, const string& name, locale::category c) + : facets_(N), + name_("*") +{ + facets_ = other.facets_; + for (unsigned i = 0; i < facets_.size(); ++i) + if (facets_[i]) + facets_[i]->__add_shared(); +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + if (c & locale::collate) + { + install(new collate_byname(name)); + install(new collate_byname(name)); + } + if (c & locale::ctype) + { + install(new ctype_byname(name)); + install(new ctype_byname(name)); + install(new codecvt_byname(name)); + install(new codecvt_byname(name)); + install(new codecvt_byname(name)); + install(new codecvt_byname(name)); + } + if (c & locale::monetary) + { + install(new moneypunct_byname(name)); + install(new moneypunct_byname(name)); + install(new moneypunct_byname(name)); + install(new moneypunct_byname(name)); + } + if (c & locale::numeric) + { + install(new numpunct_byname(name)); + install(new numpunct_byname(name)); + } + if (c & locale::time) + { + install(new time_get_byname(name)); + install(new time_get_byname(name)); + install(new time_put_byname(name)); + install(new time_put_byname(name)); + } + if (c & locale::messages) + { + install(new messages_byname(name)); + install(new messages_byname(name)); + } +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + for (unsigned i = 0; i < facets_.size(); ++i) + if (facets_[i]) + facets_[i]->__release_shared(); + throw; + } +#endif // _LIBCPP_NO_EXCEPTIONS +} + +template +inline +void +locale::__imp::install_from(const locale::__imp& one) +{ + long id = F::id.__get(); + install(const_cast(static_cast(one.use_facet(id))), id); +} + +locale::__imp::__imp(const __imp& other, const __imp& one, locale::category c) + : facets_(N), + name_("*") +{ + facets_ = other.facets_; + for (unsigned i = 0; i < facets_.size(); ++i) + if (facets_[i]) + facets_[i]->__add_shared(); +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + if (c & locale::collate) + { + install_from<_VSTD::collate >(one); + install_from<_VSTD::collate >(one); + } + if (c & locale::ctype) + { + install_from<_VSTD::ctype >(one); + install_from<_VSTD::ctype >(one); + install_from<_VSTD::codecvt >(one); + install_from<_VSTD::codecvt >(one); + install_from<_VSTD::codecvt >(one); + install_from<_VSTD::codecvt >(one); + } + if (c & locale::monetary) + { + install_from >(one); + install_from >(one); + install_from >(one); + install_from >(one); + install_from >(one); + install_from >(one); + install_from >(one); + install_from >(one); + } + if (c & locale::numeric) + { + install_from >(one); + install_from >(one); + install_from >(one); + install_from >(one); + install_from >(one); + install_from >(one); + } + if (c & locale::time) + { + install_from >(one); + install_from >(one); + install_from >(one); + install_from >(one); + } + if (c & locale::messages) + { + install_from<_VSTD::messages >(one); + install_from<_VSTD::messages >(one); + } +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + for (unsigned i = 0; i < facets_.size(); ++i) + if (facets_[i]) + facets_[i]->__release_shared(); + throw; + } +#endif // _LIBCPP_NO_EXCEPTIONS +} + +locale::__imp::__imp(const __imp& other, facet* f, long id) + : facets_(max(N, other.facets_.size()+1)), + name_("*") +{ + f->__add_shared(); + unique_ptr hold(f); + facets_ = other.facets_; + for (unsigned i = 0; i < other.facets_.size(); ++i) + if (facets_[i]) + facets_[i]->__add_shared(); + install(hold.get(), id); +} + +locale::__imp::~__imp() +{ + for (unsigned i = 0; i < facets_.size(); ++i) + if (facets_[i]) + facets_[i]->__release_shared(); +} + +void +locale::__imp::install(facet* f, long id) +{ + f->__add_shared(); + unique_ptr hold(f); + if (static_cast(id) >= facets_.size()) + facets_.resize(static_cast(id+1)); + if (facets_[static_cast(id)]) + facets_[static_cast(id)]->__release_shared(); + facets_[static_cast(id)] = hold.release(); +} + +const locale::facet* +locale::__imp::use_facet(long id) const +{ + if (!has_facet(id)) + __throw_bad_cast(); + return facets_[static_cast(id)]; +} + +// locale + +const locale& +locale::__imp::make_classic() +{ + // only one thread can get in here and it only gets in once + static aligned_storage::type buf; + locale* c = reinterpret_cast(&buf); + c->__locale_ = &make<__imp>(1u); + return *c; +} + +const locale& +locale::classic() +{ + static const locale& c = __imp::make_classic(); + return c; +} + +locale& +locale::__imp::make_global() +{ + // only one thread can get in here and it only gets in once + static aligned_storage::type buf; + auto *obj = ::new (&buf) locale(locale::classic()); + return *obj; +} + +locale& +locale::__global() +{ + static locale& g = __imp::make_global(); + return g; +} + +locale::locale() _NOEXCEPT + : __locale_(__global().__locale_) +{ + __locale_->__add_shared(); +} + +locale::locale(const locale& l) _NOEXCEPT + : __locale_(l.__locale_) +{ + __locale_->__add_shared(); +} + +locale::~locale() +{ + __locale_->__release_shared(); +} + +const locale& +locale::operator=(const locale& other) _NOEXCEPT +{ + other.__locale_->__add_shared(); + __locale_->__release_shared(); + __locale_ = other.__locale_; + return *this; +} + +locale::locale(const char* name) + : __locale_(name ? new __imp(name) + : (__throw_runtime_error("locale constructed with null"), (__imp*)0)) +{ + __locale_->__add_shared(); +} + +locale::locale(const string& name) + : __locale_(new __imp(name)) +{ + __locale_->__add_shared(); +} + +locale::locale(const locale& other, const char* name, category c) + : __locale_(name ? new __imp(*other.__locale_, name, c) + : (__throw_runtime_error("locale constructed with null"), (__imp*)0)) +{ + __locale_->__add_shared(); +} + +locale::locale(const locale& other, const string& name, category c) + : __locale_(new __imp(*other.__locale_, name, c)) +{ + __locale_->__add_shared(); +} + +locale::locale(const locale& other, const locale& one, category c) + : __locale_(new __imp(*other.__locale_, *one.__locale_, c)) +{ + __locale_->__add_shared(); +} + +string +locale::name() const +{ + return __locale_->name(); +} + +void +locale::__install_ctor(const locale& other, facet* f, long id) +{ + if (f) + __locale_ = new __imp(*other.__locale_, f, id); + else + __locale_ = other.__locale_; + __locale_->__add_shared(); +} + +locale +locale::global(const locale& loc) +{ + locale& g = __global(); + locale r = g; + g = loc; + if (g.name() != "*") + setlocale(LC_ALL, g.name().c_str()); + return r; +} + +bool +locale::has_facet(id& x) const +{ + return __locale_->has_facet(x.__get()); +} + +const locale::facet* +locale::use_facet(id& x) const +{ + return __locale_->use_facet(x.__get()); +} + +bool +locale::operator==(const locale& y) const +{ + return (__locale_ == y.__locale_) + || (__locale_->name() != "*" && __locale_->name() == y.__locale_->name()); +} + +// locale::facet + +locale::facet::~facet() +{ +} + +void +locale::facet::__on_zero_shared() _NOEXCEPT +{ + delete this; +} + +// locale::id + +int32_t locale::id::__next_id = 0; + +namespace +{ + +class __fake_bind +{ + locale::id* id_; + void (locale::id::* pmf_)(); +public: + __fake_bind(void (locale::id::* pmf)(), locale::id* id) + : id_(id), pmf_(pmf) {} + + void operator()() const + { + (id_->*pmf_)(); + } +}; + +} + +long +locale::id::__get() +{ + call_once(__flag_, __fake_bind(&locale::id::__init, this)); + return __id_ - 1; +} + +void +locale::id::__init() +{ + __id_ = __libcpp_atomic_add(&__next_id, 1); +} + +// template <> class collate_byname + +collate_byname::collate_byname(const char* n, size_t refs) + : collate(refs), + __l(newlocale(LC_ALL_MASK, n, 0)) +{ + if (__l == 0) + __throw_runtime_error("collate_byname::collate_byname" + " failed to construct for " + string(n)); +} + +collate_byname::collate_byname(const string& name, size_t refs) + : collate(refs), + __l(newlocale(LC_ALL_MASK, name.c_str(), 0)) +{ + if (__l == 0) + __throw_runtime_error("collate_byname::collate_byname" + " failed to construct for " + name); +} + +collate_byname::~collate_byname() +{ + freelocale(__l); +} + +int +collate_byname::do_compare(const char_type* __lo1, const char_type* __hi1, + const char_type* __lo2, const char_type* __hi2) const +{ + string_type lhs(__lo1, __hi1); + string_type rhs(__lo2, __hi2); + int r = strcoll_l(lhs.c_str(), rhs.c_str(), __l); + if (r < 0) + return -1; + if (r > 0) + return 1; + return r; +} + +collate_byname::string_type +collate_byname::do_transform(const char_type* lo, const char_type* hi) const +{ + const string_type in(lo, hi); + string_type out(strxfrm_l(0, in.c_str(), 0, __l), char()); + strxfrm_l(const_cast(out.c_str()), in.c_str(), out.size()+1, __l); + return out; +} + +// template <> class collate_byname + +collate_byname::collate_byname(const char* n, size_t refs) + : collate(refs), + __l(newlocale(LC_ALL_MASK, n, 0)) +{ + if (__l == 0) + __throw_runtime_error("collate_byname::collate_byname(size_t refs)" + " failed to construct for " + string(n)); +} + +collate_byname::collate_byname(const string& name, size_t refs) + : collate(refs), + __l(newlocale(LC_ALL_MASK, name.c_str(), 0)) +{ + if (__l == 0) + __throw_runtime_error("collate_byname::collate_byname(size_t refs)" + " failed to construct for " + name); +} + +collate_byname::~collate_byname() +{ + freelocale(__l); +} + +int +collate_byname::do_compare(const char_type* __lo1, const char_type* __hi1, + const char_type* __lo2, const char_type* __hi2) const +{ + string_type lhs(__lo1, __hi1); + string_type rhs(__lo2, __hi2); + int r = wcscoll_l(lhs.c_str(), rhs.c_str(), __l); + if (r < 0) + return -1; + if (r > 0) + return 1; + return r; +} + +collate_byname::string_type +collate_byname::do_transform(const char_type* lo, const char_type* hi) const +{ + const string_type in(lo, hi); + string_type out(wcsxfrm_l(0, in.c_str(), 0, __l), wchar_t()); + wcsxfrm_l(const_cast(out.c_str()), in.c_str(), out.size()+1, __l); + return out; +} + +// template <> class ctype; + +const ctype_base::mask ctype_base::space; +const ctype_base::mask ctype_base::print; +const ctype_base::mask ctype_base::cntrl; +const ctype_base::mask ctype_base::upper; +const ctype_base::mask ctype_base::lower; +const ctype_base::mask ctype_base::alpha; +const ctype_base::mask ctype_base::digit; +const ctype_base::mask ctype_base::punct; +const ctype_base::mask ctype_base::xdigit; +const ctype_base::mask ctype_base::blank; +const ctype_base::mask ctype_base::alnum; +const ctype_base::mask ctype_base::graph; + +locale::id ctype::id; + +ctype::~ctype() +{ +} + +bool +ctype::do_is(mask m, char_type c) const +{ + return isascii(c) ? (ctype::classic_table()[c] & m) != 0 : false; +} + +const wchar_t* +ctype::do_is(const char_type* low, const char_type* high, mask* vec) const +{ + for (; low != high; ++low, ++vec) + *vec = static_cast(isascii(*low) ? + ctype::classic_table()[*low] : 0); + return low; +} + +const wchar_t* +ctype::do_scan_is(mask m, const char_type* low, const char_type* high) const +{ + for (; low != high; ++low) + if (isascii(*low) && (ctype::classic_table()[*low] & m)) + break; + return low; +} + +const wchar_t* +ctype::do_scan_not(mask m, const char_type* low, const char_type* high) const +{ + for (; low != high; ++low) + if (!(isascii(*low) && (ctype::classic_table()[*low] & m))) + break; + return low; +} + +wchar_t +ctype::do_toupper(char_type c) const +{ +#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE + return isascii(c) ? _DefaultRuneLocale.__mapupper[c] : c; +#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || \ + defined(__NetBSD__) + return isascii(c) ? ctype::__classic_upper_table()[c] : c; +#else + return (isascii(c) && iswlower_l(c, _LIBCPP_GET_C_LOCALE)) ? c-L'a'+L'A' : c; +#endif +} + +const wchar_t* +ctype::do_toupper(char_type* low, const char_type* high) const +{ + for (; low != high; ++low) +#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE + *low = isascii(*low) ? _DefaultRuneLocale.__mapupper[*low] : *low; +#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || \ + defined(__NetBSD__) + *low = isascii(*low) ? ctype::__classic_upper_table()[*low] + : *low; +#else + *low = (isascii(*low) && islower_l(*low, _LIBCPP_GET_C_LOCALE)) ? (*low-L'a'+L'A') : *low; +#endif + return low; +} + +wchar_t +ctype::do_tolower(char_type c) const +{ +#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE + return isascii(c) ? _DefaultRuneLocale.__maplower[c] : c; +#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || \ + defined(__NetBSD__) + return isascii(c) ? ctype::__classic_lower_table()[c] : c; +#else + return (isascii(c) && isupper_l(c, _LIBCPP_GET_C_LOCALE)) ? c-L'A'+'a' : c; +#endif +} + +const wchar_t* +ctype::do_tolower(char_type* low, const char_type* high) const +{ + for (; low != high; ++low) +#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE + *low = isascii(*low) ? _DefaultRuneLocale.__maplower[*low] : *low; +#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || \ + defined(__NetBSD__) + *low = isascii(*low) ? ctype::__classic_lower_table()[*low] + : *low; +#else + *low = (isascii(*low) && isupper_l(*low, _LIBCPP_GET_C_LOCALE)) ? *low-L'A'+L'a' : *low; +#endif + return low; +} + +wchar_t +ctype::do_widen(char c) const +{ + return c; +} + +const char* +ctype::do_widen(const char* low, const char* high, char_type* dest) const +{ + for (; low != high; ++low, ++dest) + *dest = *low; + return low; +} + +char +ctype::do_narrow(char_type c, char dfault) const +{ + if (isascii(c)) + return static_cast(c); + return dfault; +} + +const wchar_t* +ctype::do_narrow(const char_type* low, const char_type* high, char dfault, char* dest) const +{ + for (; low != high; ++low, ++dest) + if (isascii(*low)) + *dest = static_cast(*low); + else + *dest = dfault; + return low; +} + +// template <> class ctype; + +locale::id ctype::id; + +ctype::ctype(const mask* tab, bool del, size_t refs) + : locale::facet(refs), + __tab_(tab), + __del_(del) +{ + if (__tab_ == 0) + __tab_ = classic_table(); +} + +ctype::~ctype() +{ + if (__tab_ && __del_) + delete [] __tab_; +} + +char +ctype::do_toupper(char_type c) const +{ +#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE + return isascii(c) ? + static_cast(_DefaultRuneLocale.__mapupper[static_cast(c)]) : c; +#elif defined(__NetBSD__) + return static_cast(__classic_upper_table()[static_cast(c)]); +#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) + return isascii(c) ? + static_cast(__classic_upper_table()[static_cast(c)]) : c; +#else + return (isascii(c) && islower_l(c, _LIBCPP_GET_C_LOCALE)) ? c-'a'+'A' : c; +#endif +} + +const char* +ctype::do_toupper(char_type* low, const char_type* high) const +{ + for (; low != high; ++low) +#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE + *low = isascii(*low) ? + static_cast(_DefaultRuneLocale.__mapupper[static_cast(*low)]) : *low; +#elif defined(__NetBSD__) + *low = static_cast(__classic_upper_table()[static_cast(*low)]); +#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) + *low = isascii(*low) ? + static_cast(__classic_upper_table()[static_cast(*low)]) : *low; +#else + *low = (isascii(*low) && islower_l(*low, _LIBCPP_GET_C_LOCALE)) ? *low-'a'+'A' : *low; +#endif + return low; +} + +char +ctype::do_tolower(char_type c) const +{ +#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE + return isascii(c) ? + static_cast(_DefaultRuneLocale.__maplower[static_cast(c)]) : c; +#elif defined(__NetBSD__) + return static_cast(__classic_lower_table()[static_cast(c)]); +#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) + return isascii(c) ? + static_cast(__classic_lower_table()[static_cast(c)]) : c; +#else + return (isascii(c) && isupper_l(c, _LIBCPP_GET_C_LOCALE)) ? c-'A'+'a' : c; +#endif +} + +const char* +ctype::do_tolower(char_type* low, const char_type* high) const +{ + for (; low != high; ++low) +#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE + *low = isascii(*low) ? static_cast(_DefaultRuneLocale.__maplower[static_cast(*low)]) : *low; +#elif defined(__NetBSD__) + *low = static_cast(__classic_lower_table()[static_cast(*low)]); +#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) + *low = isascii(*low) ? static_cast(__classic_lower_table()[static_cast(*low)]) : *low; +#else + *low = (isascii(*low) && isupper_l(*low, _LIBCPP_GET_C_LOCALE)) ? *low-'A'+'a' : *low; +#endif + return low; +} + +char +ctype::do_widen(char c) const +{ + return c; +} + +const char* +ctype::do_widen(const char* low, const char* high, char_type* dest) const +{ + for (; low != high; ++low, ++dest) + *dest = *low; + return low; +} + +char +ctype::do_narrow(char_type c, char dfault) const +{ + if (isascii(c)) + return static_cast(c); + return dfault; +} + +const char* +ctype::do_narrow(const char_type* low, const char_type* high, char dfault, char* dest) const +{ + for (; low != high; ++low, ++dest) + if (isascii(*low)) + *dest = *low; + else + *dest = dfault; + return low; +} + +#if defined(__EMSCRIPTEN__) +extern "C" const unsigned short ** __ctype_b_loc(); +extern "C" const int ** __ctype_tolower_loc(); +extern "C" const int ** __ctype_toupper_loc(); +#endif + +#ifdef _LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE +const ctype::mask* +ctype::classic_table() _NOEXCEPT +{ + static _LIBCPP_CONSTEXPR const ctype::mask builtin_table[table_size] = { + cntrl, cntrl, + cntrl, cntrl, + cntrl, cntrl, + cntrl, cntrl, + cntrl, cntrl | space | blank, + cntrl | space, cntrl | space, + cntrl | space, cntrl | space, + cntrl, cntrl, + cntrl, cntrl, + cntrl, cntrl, + cntrl, cntrl, + cntrl, cntrl, + cntrl, cntrl, + cntrl, cntrl, + cntrl, cntrl, + cntrl, cntrl, + space | blank | print, punct | print, + punct | print, punct | print, + punct | print, punct | print, + punct | print, punct | print, + punct | print, punct | print, + punct | print, punct | print, + punct | print, punct | print, + punct | print, punct | print, + digit | print | xdigit, digit | print | xdigit, + digit | print | xdigit, digit | print | xdigit, + digit | print | xdigit, digit | print | xdigit, + digit | print | xdigit, digit | print | xdigit, + digit | print | xdigit, digit | print | xdigit, + punct | print, punct | print, + punct | print, punct | print, + punct | print, punct | print, + punct | print, upper | xdigit | print | alpha, + upper | xdigit | print | alpha, upper | xdigit | print | alpha, + upper | xdigit | print | alpha, upper | xdigit | print | alpha, + upper | xdigit | print | alpha, upper | print | alpha, + upper | print | alpha, upper | print | alpha, + upper | print | alpha, upper | print | alpha, + upper | print | alpha, upper | print | alpha, + upper | print | alpha, upper | print | alpha, + upper | print | alpha, upper | print | alpha, + upper | print | alpha, upper | print | alpha, + upper | print | alpha, upper | print | alpha, + upper | print | alpha, upper | print | alpha, + upper | print | alpha, upper | print | alpha, + upper | print | alpha, punct | print, + punct | print, punct | print, + punct | print, punct | print, + punct | print, lower | xdigit | print | alpha, + lower | xdigit | print | alpha, lower | xdigit | print | alpha, + lower | xdigit | print | alpha, lower | xdigit | print | alpha, + lower | xdigit | print | alpha, lower | print | alpha, + lower | print | alpha, lower | print | alpha, + lower | print | alpha, lower | print | alpha, + lower | print | alpha, lower | print | alpha, + lower | print | alpha, lower | print | alpha, + lower | print | alpha, lower | print | alpha, + lower | print | alpha, lower | print | alpha, + lower | print | alpha, lower | print | alpha, + lower | print | alpha, lower | print | alpha, + lower | print | alpha, lower | print | alpha, + lower | print | alpha, punct | print, + punct | print, punct | print, + punct | print, cntrl, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + return builtin_table; +} +#else +const ctype::mask* +ctype::classic_table() _NOEXCEPT +{ +#if defined(__APPLE__) || defined(__FreeBSD__) + return _DefaultRuneLocale.__runetype; +#elif defined(__NetBSD__) + return _C_ctype_tab_ + 1; +#elif defined(__GLIBC__) + return _LIBCPP_GET_C_LOCALE->__ctype_b; +#elif __sun__ + return __ctype_mask; +#elif defined(_LIBCPP_MSVCRT) || defined(__MINGW32__) + return __pctype_func(); +#elif defined(__EMSCRIPTEN__) + return *__ctype_b_loc(); +#elif defined(_NEWLIB_VERSION) + // Newlib has a 257-entry table in ctype_.c, where (char)0 starts at [1]. + return _ctype_ + 1; +#elif defined(_AIX) + return (const unsigned int *)__lc_ctype_ptr->obj->mask; +#else + // Platform not supported: abort so the person doing the port knows what to + // fix +# warning ctype::classic_table() is not implemented + printf("ctype::classic_table() is not implemented\n"); + abort(); + return NULL; +#endif +} +#endif + +#if defined(__GLIBC__) +const int* +ctype::__classic_lower_table() _NOEXCEPT +{ + return _LIBCPP_GET_C_LOCALE->__ctype_tolower; +} + +const int* +ctype::__classic_upper_table() _NOEXCEPT +{ + return _LIBCPP_GET_C_LOCALE->__ctype_toupper; +} +#elif __NetBSD__ +const short* +ctype::__classic_lower_table() _NOEXCEPT +{ + return _C_tolower_tab_ + 1; +} + +const short* +ctype::__classic_upper_table() _NOEXCEPT +{ + return _C_toupper_tab_ + 1; +} + +#elif defined(__EMSCRIPTEN__) +const int* +ctype::__classic_lower_table() _NOEXCEPT +{ + return *__ctype_tolower_loc(); +} + +const int* +ctype::__classic_upper_table() _NOEXCEPT +{ + return *__ctype_toupper_loc(); +} +#endif // __GLIBC__ || __NETBSD__ || __EMSCRIPTEN__ + +// template <> class ctype_byname + +ctype_byname::ctype_byname(const char* name, size_t refs) + : ctype(0, false, refs), + __l(newlocale(LC_ALL_MASK, name, 0)) +{ + if (__l == 0) + __throw_runtime_error("ctype_byname::ctype_byname" + " failed to construct for " + string(name)); +} + +ctype_byname::ctype_byname(const string& name, size_t refs) + : ctype(0, false, refs), + __l(newlocale(LC_ALL_MASK, name.c_str(), 0)) +{ + if (__l == 0) + __throw_runtime_error("ctype_byname::ctype_byname" + " failed to construct for " + name); +} + +ctype_byname::~ctype_byname() +{ + freelocale(__l); +} + +char +ctype_byname::do_toupper(char_type c) const +{ + return static_cast(toupper_l(static_cast(c), __l)); +} + +const char* +ctype_byname::do_toupper(char_type* low, const char_type* high) const +{ + for (; low != high; ++low) + *low = static_cast(toupper_l(static_cast(*low), __l)); + return low; +} + +char +ctype_byname::do_tolower(char_type c) const +{ + return static_cast(tolower_l(static_cast(c), __l)); +} + +const char* +ctype_byname::do_tolower(char_type* low, const char_type* high) const +{ + for (; low != high; ++low) + *low = static_cast(tolower_l(static_cast(*low), __l)); + return low; +} + +// template <> class ctype_byname + +ctype_byname::ctype_byname(const char* name, size_t refs) + : ctype(refs), + __l(newlocale(LC_ALL_MASK, name, 0)) +{ + if (__l == 0) + __throw_runtime_error("ctype_byname::ctype_byname" + " failed to construct for " + string(name)); +} + +ctype_byname::ctype_byname(const string& name, size_t refs) + : ctype(refs), + __l(newlocale(LC_ALL_MASK, name.c_str(), 0)) +{ + if (__l == 0) + __throw_runtime_error("ctype_byname::ctype_byname" + " failed to construct for " + name); +} + +ctype_byname::~ctype_byname() +{ + freelocale(__l); +} + +bool +ctype_byname::do_is(mask m, char_type c) const +{ +#ifdef _LIBCPP_WCTYPE_IS_MASK + return static_cast(iswctype_l(c, m, __l)); +#else + bool result = false; + wint_t ch = static_cast(c); + if ((m & space) == space) result |= (iswspace_l(ch, __l) != 0); + if ((m & print) == print) result |= (iswprint_l(ch, __l) != 0); + if ((m & cntrl) == cntrl) result |= (iswcntrl_l(ch, __l) != 0); + if ((m & upper) == upper) result |= (iswupper_l(ch, __l) != 0); + if ((m & lower) == lower) result |= (iswlower_l(ch, __l) != 0); + if ((m & alpha) == alpha) result |= (iswalpha_l(ch, __l) != 0); + if ((m & digit) == digit) result |= (iswdigit_l(ch, __l) != 0); + if ((m & punct) == punct) result |= (iswpunct_l(ch, __l) != 0); + if ((m & xdigit) == xdigit) result |= (iswxdigit_l(ch, __l) != 0); + if ((m & blank) == blank) result |= (iswblank_l(ch, __l) != 0); + return result; +#endif +} + +const wchar_t* +ctype_byname::do_is(const char_type* low, const char_type* high, mask* vec) const +{ + for (; low != high; ++low, ++vec) + { + if (isascii(*low)) + *vec = static_cast(ctype::classic_table()[*low]); + else + { + *vec = 0; + wint_t ch = static_cast(*low); + if (iswspace_l(ch, __l)) + *vec |= space; +#ifndef _LIBCPP_CTYPE_MASK_IS_COMPOSITE_PRINT + if (iswprint_l(ch, __l)) + *vec |= print; +#endif + if (iswcntrl_l(ch, __l)) + *vec |= cntrl; + if (iswupper_l(ch, __l)) + *vec |= upper; + if (iswlower_l(ch, __l)) + *vec |= lower; +#ifndef _LIBCPP_CTYPE_MASK_IS_COMPOSITE_ALPHA + if (iswalpha_l(ch, __l)) + *vec |= alpha; +#endif + if (iswdigit_l(ch, __l)) + *vec |= digit; + if (iswpunct_l(ch, __l)) + *vec |= punct; +#ifndef _LIBCPP_CTYPE_MASK_IS_COMPOSITE_XDIGIT + if (iswxdigit_l(ch, __l)) + *vec |= xdigit; +#endif +#if !defined(__sun__) + if (iswblank_l(ch, __l)) + *vec |= blank; +#endif + } + } + return low; +} + +const wchar_t* +ctype_byname::do_scan_is(mask m, const char_type* low, const char_type* high) const +{ + for (; low != high; ++low) + { +#ifdef _LIBCPP_WCTYPE_IS_MASK + if (iswctype_l(*low, m, __l)) + break; +#else + wint_t ch = static_cast(*low); + if ((m & space) == space && iswspace_l(ch, __l)) break; + if ((m & print) == print && iswprint_l(ch, __l)) break; + if ((m & cntrl) == cntrl && iswcntrl_l(ch, __l)) break; + if ((m & upper) == upper && iswupper_l(ch, __l)) break; + if ((m & lower) == lower && iswlower_l(ch, __l)) break; + if ((m & alpha) == alpha && iswalpha_l(ch, __l)) break; + if ((m & digit) == digit && iswdigit_l(ch, __l)) break; + if ((m & punct) == punct && iswpunct_l(ch, __l)) break; + if ((m & xdigit) == xdigit && iswxdigit_l(ch, __l)) break; + if ((m & blank) == blank && iswblank_l(ch, __l)) break; +#endif + } + return low; +} + +const wchar_t* +ctype_byname::do_scan_not(mask m, const char_type* low, const char_type* high) const +{ + for (; low != high; ++low) + { +#ifdef _LIBCPP_WCTYPE_IS_MASK + if (!iswctype_l(*low, m, __l)) + break; +#else + wint_t ch = static_cast(*low); + if ((m & space) == space && iswspace_l(ch, __l)) continue; + if ((m & print) == print && iswprint_l(ch, __l)) continue; + if ((m & cntrl) == cntrl && iswcntrl_l(ch, __l)) continue; + if ((m & upper) == upper && iswupper_l(ch, __l)) continue; + if ((m & lower) == lower && iswlower_l(ch, __l)) continue; + if ((m & alpha) == alpha && iswalpha_l(ch, __l)) continue; + if ((m & digit) == digit && iswdigit_l(ch, __l)) continue; + if ((m & punct) == punct && iswpunct_l(ch, __l)) continue; + if ((m & xdigit) == xdigit && iswxdigit_l(ch, __l)) continue; + if ((m & blank) == blank && iswblank_l(ch, __l)) continue; + break; +#endif + } + return low; +} + +wchar_t +ctype_byname::do_toupper(char_type c) const +{ + return towupper_l(c, __l); +} + +const wchar_t* +ctype_byname::do_toupper(char_type* low, const char_type* high) const +{ + for (; low != high; ++low) + *low = towupper_l(*low, __l); + return low; +} + +wchar_t +ctype_byname::do_tolower(char_type c) const +{ + return towlower_l(c, __l); +} + +const wchar_t* +ctype_byname::do_tolower(char_type* low, const char_type* high) const +{ + for (; low != high; ++low) + *low = towlower_l(*low, __l); + return low; +} + +wchar_t +ctype_byname::do_widen(char c) const +{ + return __libcpp_btowc_l(c, __l); +} + +const char* +ctype_byname::do_widen(const char* low, const char* high, char_type* dest) const +{ + for (; low != high; ++low, ++dest) + *dest = __libcpp_btowc_l(*low, __l); + return low; +} + +char +ctype_byname::do_narrow(char_type c, char dfault) const +{ + int r = __libcpp_wctob_l(c, __l); + return r != static_cast(WEOF) ? static_cast(r) : dfault; +} + +const wchar_t* +ctype_byname::do_narrow(const char_type* low, const char_type* high, char dfault, char* dest) const +{ + for (; low != high; ++low, ++dest) + { + int r = __libcpp_wctob_l(*low, __l); + *dest = r != static_cast(WEOF) ? static_cast(r) : dfault; + } + return low; +} + +// template <> class codecvt + +locale::id codecvt::id; + +codecvt::~codecvt() +{ +} + +codecvt::result +codecvt::do_out(state_type&, + const intern_type* frm, const intern_type*, const intern_type*& frm_nxt, + extern_type* to, extern_type*, extern_type*& to_nxt) const +{ + frm_nxt = frm; + to_nxt = to; + return noconv; +} + +codecvt::result +codecvt::do_in(state_type&, + const extern_type* frm, const extern_type*, const extern_type*& frm_nxt, + intern_type* to, intern_type*, intern_type*& to_nxt) const +{ + frm_nxt = frm; + to_nxt = to; + return noconv; +} + +codecvt::result +codecvt::do_unshift(state_type&, + extern_type* to, extern_type*, extern_type*& to_nxt) const +{ + to_nxt = to; + return noconv; +} + +int +codecvt::do_encoding() const _NOEXCEPT +{ + return 1; +} + +bool +codecvt::do_always_noconv() const _NOEXCEPT +{ + return true; +} + +int +codecvt::do_length(state_type&, + const extern_type* frm, const extern_type* end, size_t mx) const +{ + return static_cast(min(mx, static_cast(end-frm))); +} + +int +codecvt::do_max_length() const _NOEXCEPT +{ + return 1; +} + +// template <> class codecvt + +locale::id codecvt::id; + +codecvt::codecvt(size_t refs) + : locale::facet(refs), + __l(_LIBCPP_GET_C_LOCALE) +{ +} + +codecvt::codecvt(const char* nm, size_t refs) + : locale::facet(refs), + __l(newlocale(LC_ALL_MASK, nm, 0)) +{ + if (__l == 0) + __throw_runtime_error("codecvt_byname::codecvt_byname" + " failed to construct for " + string(nm)); +} + +codecvt::~codecvt() +{ + if (__l != _LIBCPP_GET_C_LOCALE) + freelocale(__l); +} + +codecvt::result +codecvt::do_out(state_type& st, + const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt, + extern_type* to, extern_type* to_end, extern_type*& to_nxt) const +{ + // look for first internal null in frm + const intern_type* fend = frm; + for (; fend != frm_end; ++fend) + if (*fend == 0) + break; + // loop over all null-terminated sequences in frm + to_nxt = to; + for (frm_nxt = frm; frm != frm_end && to != to_end; frm = frm_nxt, to = to_nxt) + { + // save state in case it is needed to recover to_nxt on error + mbstate_t save_state = st; + size_t n = __libcpp_wcsnrtombs_l(to, &frm_nxt, static_cast(fend-frm), + static_cast(to_end-to), &st, __l); + if (n == size_t(-1)) + { + // need to recover to_nxt + for (to_nxt = to; frm != frm_nxt; ++frm) + { + n = __libcpp_wcrtomb_l(to_nxt, *frm, &save_state, __l); + if (n == size_t(-1)) + break; + to_nxt += n; + } + frm_nxt = frm; + return error; + } + if (n == 0) + return partial; + to_nxt += n; + if (to_nxt == to_end) + break; + if (fend != frm_end) // set up next null terminated sequence + { + // Try to write the terminating null + extern_type tmp[MB_LEN_MAX]; + n = __libcpp_wcrtomb_l(tmp, intern_type(), &st, __l); + if (n == size_t(-1)) // on error + return error; + if (n > static_cast(to_end-to_nxt)) // is there room? + return partial; + for (extern_type* p = tmp; n; --n) // write it + *to_nxt++ = *p++; + ++frm_nxt; + // look for next null in frm + for (fend = frm_nxt; fend != frm_end; ++fend) + if (*fend == 0) + break; + } + } + return frm_nxt == frm_end ? ok : partial; +} + +codecvt::result +codecvt::do_in(state_type& st, + const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt, + intern_type* to, intern_type* to_end, intern_type*& to_nxt) const +{ + // look for first internal null in frm + const extern_type* fend = frm; + for (; fend != frm_end; ++fend) + if (*fend == 0) + break; + // loop over all null-terminated sequences in frm + to_nxt = to; + for (frm_nxt = frm; frm != frm_end && to != to_end; frm = frm_nxt, to = to_nxt) + { + // save state in case it is needed to recover to_nxt on error + mbstate_t save_state = st; + size_t n = __libcpp_mbsnrtowcs_l(to, &frm_nxt, static_cast(fend-frm), + static_cast(to_end-to), &st, __l); + if (n == size_t(-1)) + { + // need to recover to_nxt + for (to_nxt = to; frm != frm_nxt; ++to_nxt) + { + n = __libcpp_mbrtowc_l(to_nxt, frm, static_cast(fend-frm), + &save_state, __l); + switch (n) + { + case 0: + ++frm; + break; + case size_t(-1): + frm_nxt = frm; + return error; + case size_t(-2): + frm_nxt = frm; + return partial; + default: + frm += n; + break; + } + } + frm_nxt = frm; + return frm_nxt == frm_end ? ok : partial; + } + if (n == size_t(-1)) + return error; + to_nxt += n; + if (to_nxt == to_end) + break; + if (fend != frm_end) // set up next null terminated sequence + { + // Try to write the terminating null + n = __libcpp_mbrtowc_l(to_nxt, frm_nxt, 1, &st, __l); + if (n != 0) // on error + return error; + ++to_nxt; + ++frm_nxt; + // look for next null in frm + for (fend = frm_nxt; fend != frm_end; ++fend) + if (*fend == 0) + break; + } + } + return frm_nxt == frm_end ? ok : partial; +} + +codecvt::result +codecvt::do_unshift(state_type& st, + extern_type* to, extern_type* to_end, extern_type*& to_nxt) const +{ + to_nxt = to; + extern_type tmp[MB_LEN_MAX]; + size_t n = __libcpp_wcrtomb_l(tmp, intern_type(), &st, __l); + if (n == size_t(-1) || n == 0) // on error + return error; + --n; + if (n > static_cast(to_end-to_nxt)) // is there room? + return partial; + for (extern_type* p = tmp; n; --n) // write it + *to_nxt++ = *p++; + return ok; +} + +int +codecvt::do_encoding() const _NOEXCEPT +{ + if (__libcpp_mbtowc_l(nullptr, nullptr, MB_LEN_MAX, __l) != 0) + return -1; + + // stateless encoding + if (__l == 0 || __libcpp_mb_cur_max_l(__l) == 1) // there are no known constant length encodings + return 1; // which take more than 1 char to form a wchar_t + return 0; +} + +bool +codecvt::do_always_noconv() const _NOEXCEPT +{ + return false; +} + +int +codecvt::do_length(state_type& st, + const extern_type* frm, const extern_type* frm_end, size_t mx) const +{ + int nbytes = 0; + for (size_t nwchar_t = 0; nwchar_t < mx && frm != frm_end; ++nwchar_t) + { + size_t n = __libcpp_mbrlen_l(frm, static_cast(frm_end-frm), &st, __l); + switch (n) + { + case 0: + ++nbytes; + ++frm; + break; + case size_t(-1): + case size_t(-2): + return nbytes; + default: + nbytes += n; + frm += n; + break; + } + } + return nbytes; +} + +int +codecvt::do_max_length() const _NOEXCEPT +{ + return __l == 0 ? 1 : static_cast(__libcpp_mb_cur_max_l(__l)); +} + +_LIBCPP_END_NAMESPACE_STD diff --git a/third_party/libcxx/locale2.cc b/third_party/libcxx/locale2.cc new file mode 100644 index 000000000..a4dc16220 --- /dev/null +++ b/third_party/libcxx/locale2.cc @@ -0,0 +1,2904 @@ +// clang-format off +//===------------------------- locale.cpp ---------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "third_party/libcxx/string" +#include "third_party/libcxx/locale" +#include "third_party/libcxx/codecvt" +#include "third_party/libcxx/vector" +#include "third_party/libcxx/algorithm" +#include "third_party/libcxx/typeinfo" +#ifndef _LIBCPP_NO_EXCEPTIONS +#include "third_party/libcxx/type_traits" +#endif +#include "third_party/libcxx/clocale" +#include "third_party/libcxx/cstring" +#include "third_party/libcxx/cwctype" +#include "third_party/libcxx/__sso_allocator" +#include "third_party/libcxx/include/atomic_support.hh" +#include "libc/str/locale.h" +#include "third_party/libcxx/countof.internal.hh" +#include "third_party/libcxx/__undef_macros" + +// On Linux, wint_t and wchar_t have different signed-ness, and this causes +// lots of noise in the build log, but no bugs that I know of. +#if defined(__clang__) +#pragma clang diagnostic ignored "-Wsign-conversion" +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace { + +_LIBCPP_NORETURN static void __throw_runtime_error(const string &msg) +{ +#ifndef _LIBCPP_NO_EXCEPTIONS + throw runtime_error(msg); +#else + (void)msg; + _VSTD::abort(); +#endif +} + +} // namespace + +struct __libcpp_unique_locale { + __libcpp_unique_locale(const char* nm) : __loc_(newlocale(LC_ALL_MASK, nm, 0)) {} + + ~__libcpp_unique_locale() { + if (__loc_) + freelocale(__loc_); + } + + explicit operator bool() const { return __loc_; } + + locale_t& get() { return __loc_; } + + locale_t __loc_; +private: + __libcpp_unique_locale(__libcpp_unique_locale const&); + __libcpp_unique_locale& operator=(__libcpp_unique_locale const&); +}; + +// Valid UTF ranges +// UTF-32 UTF-16 UTF-8 # of code points +// first second first second third fourth +// 000000 - 00007F 0000 - 007F 00 - 7F 127 +// 000080 - 0007FF 0080 - 07FF C2 - DF, 80 - BF 1920 +// 000800 - 000FFF 0800 - 0FFF E0 - E0, A0 - BF, 80 - BF 2048 +// 001000 - 00CFFF 1000 - CFFF E1 - EC, 80 - BF, 80 - BF 49152 +// 00D000 - 00D7FF D000 - D7FF ED - ED, 80 - 9F, 80 - BF 2048 +// 00D800 - 00DFFF invalid +// 00E000 - 00FFFF E000 - FFFF EE - EF, 80 - BF, 80 - BF 8192 +// 010000 - 03FFFF D800 - D8BF, DC00 - DFFF F0 - F0, 90 - BF, 80 - BF, 80 - BF 196608 +// 040000 - 0FFFFF D8C0 - DBBF, DC00 - DFFF F1 - F3, 80 - BF, 80 - BF, 80 - BF 786432 +// 100000 - 10FFFF DBC0 - DBFF, DC00 - DFFF F4 - F4, 80 - 8F, 80 - BF, 80 - BF 65536 + +static +codecvt_base::result +utf16_to_utf8(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt, + uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt, + unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0)) +{ + frm_nxt = frm; + to_nxt = to; + if (mode & generate_header) + { + if (to_end-to_nxt < 3) + return codecvt_base::partial; + *to_nxt++ = static_cast(0xEF); + *to_nxt++ = static_cast(0xBB); + *to_nxt++ = static_cast(0xBF); + } + for (; frm_nxt < frm_end; ++frm_nxt) + { + uint16_t wc1 = *frm_nxt; + if (wc1 > Maxcode) + return codecvt_base::error; + if (wc1 < 0x0080) + { + if (to_end-to_nxt < 1) + return codecvt_base::partial; + *to_nxt++ = static_cast(wc1); + } + else if (wc1 < 0x0800) + { + if (to_end-to_nxt < 2) + return codecvt_base::partial; + *to_nxt++ = static_cast(0xC0 | (wc1 >> 6)); + *to_nxt++ = static_cast(0x80 | (wc1 & 0x03F)); + } + else if (wc1 < 0xD800) + { + if (to_end-to_nxt < 3) + return codecvt_base::partial; + *to_nxt++ = static_cast(0xE0 | (wc1 >> 12)); + *to_nxt++ = static_cast(0x80 | ((wc1 & 0x0FC0) >> 6)); + *to_nxt++ = static_cast(0x80 | (wc1 & 0x003F)); + } + else if (wc1 < 0xDC00) + { + if (frm_end-frm_nxt < 2) + return codecvt_base::partial; + uint16_t wc2 = frm_nxt[1]; + if ((wc2 & 0xFC00) != 0xDC00) + return codecvt_base::error; + if (to_end-to_nxt < 4) + return codecvt_base::partial; + if (((((wc1 & 0x03C0UL) >> 6) + 1) << 16) + + ((wc1 & 0x003FUL) << 10) + (wc2 & 0x03FF) > Maxcode) + return codecvt_base::error; + ++frm_nxt; + uint8_t z = ((wc1 & 0x03C0) >> 6) + 1; + *to_nxt++ = static_cast(0xF0 | (z >> 2)); + *to_nxt++ = static_cast(0x80 | ((z & 0x03) << 4) | ((wc1 & 0x003C) >> 2)); + *to_nxt++ = static_cast(0x80 | ((wc1 & 0x0003) << 4) | ((wc2 & 0x03C0) >> 6)); + *to_nxt++ = static_cast(0x80 | (wc2 & 0x003F)); + } + else if (wc1 < 0xE000) + { + return codecvt_base::error; + } + else + { + if (to_end-to_nxt < 3) + return codecvt_base::partial; + *to_nxt++ = static_cast(0xE0 | (wc1 >> 12)); + *to_nxt++ = static_cast(0x80 | ((wc1 & 0x0FC0) >> 6)); + *to_nxt++ = static_cast(0x80 | (wc1 & 0x003F)); + } + } + return codecvt_base::ok; +} + +static +codecvt_base::result +utf16_to_utf8(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt, + uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt, + unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0)) +{ + frm_nxt = frm; + to_nxt = to; + if (mode & generate_header) + { + if (to_end-to_nxt < 3) + return codecvt_base::partial; + *to_nxt++ = static_cast(0xEF); + *to_nxt++ = static_cast(0xBB); + *to_nxt++ = static_cast(0xBF); + } + for (; frm_nxt < frm_end; ++frm_nxt) + { + uint16_t wc1 = static_cast(*frm_nxt); + if (wc1 > Maxcode) + return codecvt_base::error; + if (wc1 < 0x0080) + { + if (to_end-to_nxt < 1) + return codecvt_base::partial; + *to_nxt++ = static_cast(wc1); + } + else if (wc1 < 0x0800) + { + if (to_end-to_nxt < 2) + return codecvt_base::partial; + *to_nxt++ = static_cast(0xC0 | (wc1 >> 6)); + *to_nxt++ = static_cast(0x80 | (wc1 & 0x03F)); + } + else if (wc1 < 0xD800) + { + if (to_end-to_nxt < 3) + return codecvt_base::partial; + *to_nxt++ = static_cast(0xE0 | (wc1 >> 12)); + *to_nxt++ = static_cast(0x80 | ((wc1 & 0x0FC0) >> 6)); + *to_nxt++ = static_cast(0x80 | (wc1 & 0x003F)); + } + else if (wc1 < 0xDC00) + { + if (frm_end-frm_nxt < 2) + return codecvt_base::partial; + uint16_t wc2 = static_cast(frm_nxt[1]); + if ((wc2 & 0xFC00) != 0xDC00) + return codecvt_base::error; + if (to_end-to_nxt < 4) + return codecvt_base::partial; + if (((((wc1 & 0x03C0UL) >> 6) + 1) << 16) + + ((wc1 & 0x003FUL) << 10) + (wc2 & 0x03FF) > Maxcode) + return codecvt_base::error; + ++frm_nxt; + uint8_t z = ((wc1 & 0x03C0) >> 6) + 1; + *to_nxt++ = static_cast(0xF0 | (z >> 2)); + *to_nxt++ = static_cast(0x80 | ((z & 0x03) << 4) | ((wc1 & 0x003C) >> 2)); + *to_nxt++ = static_cast(0x80 | ((wc1 & 0x0003) << 4) | ((wc2 & 0x03C0) >> 6)); + *to_nxt++ = static_cast(0x80 | (wc2 & 0x003F)); + } + else if (wc1 < 0xE000) + { + return codecvt_base::error; + } + else + { + if (to_end-to_nxt < 3) + return codecvt_base::partial; + *to_nxt++ = static_cast(0xE0 | (wc1 >> 12)); + *to_nxt++ = static_cast(0x80 | ((wc1 & 0x0FC0) >> 6)); + *to_nxt++ = static_cast(0x80 | (wc1 & 0x003F)); + } + } + return codecvt_base::ok; +} + +static +codecvt_base::result +utf8_to_utf16(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt, + uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt, + unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0)) +{ + frm_nxt = frm; + to_nxt = to; + if (mode & consume_header) + { + if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB && + frm_nxt[2] == 0xBF) + frm_nxt += 3; + } + for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt) + { + uint8_t c1 = *frm_nxt; + if (c1 > Maxcode) + return codecvt_base::error; + if (c1 < 0x80) + { + *to_nxt = static_cast(c1); + ++frm_nxt; + } + else if (c1 < 0xC2) + { + return codecvt_base::error; + } + else if (c1 < 0xE0) + { + if (frm_end-frm_nxt < 2) + return codecvt_base::partial; + uint8_t c2 = frm_nxt[1]; + if ((c2 & 0xC0) != 0x80) + return codecvt_base::error; + uint16_t t = static_cast(((c1 & 0x1F) << 6) | (c2 & 0x3F)); + if (t > Maxcode) + return codecvt_base::error; + *to_nxt = t; + frm_nxt += 2; + } + else if (c1 < 0xF0) + { + if (frm_end-frm_nxt < 3) + return codecvt_base::partial; + uint8_t c2 = frm_nxt[1]; + uint8_t c3 = frm_nxt[2]; + switch (c1) + { + case 0xE0: + if ((c2 & 0xE0) != 0xA0) + return codecvt_base::error; + break; + case 0xED: + if ((c2 & 0xE0) != 0x80) + return codecvt_base::error; + break; + default: + if ((c2 & 0xC0) != 0x80) + return codecvt_base::error; + break; + } + if ((c3 & 0xC0) != 0x80) + return codecvt_base::error; + uint16_t t = static_cast(((c1 & 0x0F) << 12) + | ((c2 & 0x3F) << 6) + | (c3 & 0x3F)); + if (t > Maxcode) + return codecvt_base::error; + *to_nxt = t; + frm_nxt += 3; + } + else if (c1 < 0xF5) + { + if (frm_end-frm_nxt < 4) + return codecvt_base::partial; + uint8_t c2 = frm_nxt[1]; + uint8_t c3 = frm_nxt[2]; + uint8_t c4 = frm_nxt[3]; + switch (c1) + { + case 0xF0: + if (!(0x90 <= c2 && c2 <= 0xBF)) + return codecvt_base::error; + break; + case 0xF4: + if ((c2 & 0xF0) != 0x80) + return codecvt_base::error; + break; + default: + if ((c2 & 0xC0) != 0x80) + return codecvt_base::error; + break; + } + if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80) + return codecvt_base::error; + if (to_end-to_nxt < 2) + return codecvt_base::partial; + if ((((c1 & 7UL) << 18) + + ((c2 & 0x3FUL) << 12) + + ((c3 & 0x3FUL) << 6) + (c4 & 0x3F)) > Maxcode) + return codecvt_base::error; + *to_nxt = static_cast( + 0xD800 + | (((((c1 & 0x07) << 2) | ((c2 & 0x30) >> 4)) - 1) << 6) + | ((c2 & 0x0F) << 2) + | ((c3 & 0x30) >> 4)); + *++to_nxt = static_cast( + 0xDC00 + | ((c3 & 0x0F) << 6) + | (c4 & 0x3F)); + frm_nxt += 4; + } + else + { + return codecvt_base::error; + } + } + return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok; +} + +static +codecvt_base::result +utf8_to_utf16(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt, + uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt, + unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0)) +{ + frm_nxt = frm; + to_nxt = to; + if (mode & consume_header) + { + if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB && + frm_nxt[2] == 0xBF) + frm_nxt += 3; + } + for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt) + { + uint8_t c1 = *frm_nxt; + if (c1 > Maxcode) + return codecvt_base::error; + if (c1 < 0x80) + { + *to_nxt = static_cast(c1); + ++frm_nxt; + } + else if (c1 < 0xC2) + { + return codecvt_base::error; + } + else if (c1 < 0xE0) + { + if (frm_end-frm_nxt < 2) + return codecvt_base::partial; + uint8_t c2 = frm_nxt[1]; + if ((c2 & 0xC0) != 0x80) + return codecvt_base::error; + uint16_t t = static_cast(((c1 & 0x1F) << 6) | (c2 & 0x3F)); + if (t > Maxcode) + return codecvt_base::error; + *to_nxt = static_cast(t); + frm_nxt += 2; + } + else if (c1 < 0xF0) + { + if (frm_end-frm_nxt < 3) + return codecvt_base::partial; + uint8_t c2 = frm_nxt[1]; + uint8_t c3 = frm_nxt[2]; + switch (c1) + { + case 0xE0: + if ((c2 & 0xE0) != 0xA0) + return codecvt_base::error; + break; + case 0xED: + if ((c2 & 0xE0) != 0x80) + return codecvt_base::error; + break; + default: + if ((c2 & 0xC0) != 0x80) + return codecvt_base::error; + break; + } + if ((c3 & 0xC0) != 0x80) + return codecvt_base::error; + uint16_t t = static_cast(((c1 & 0x0F) << 12) + | ((c2 & 0x3F) << 6) + | (c3 & 0x3F)); + if (t > Maxcode) + return codecvt_base::error; + *to_nxt = static_cast(t); + frm_nxt += 3; + } + else if (c1 < 0xF5) + { + if (frm_end-frm_nxt < 4) + return codecvt_base::partial; + uint8_t c2 = frm_nxt[1]; + uint8_t c3 = frm_nxt[2]; + uint8_t c4 = frm_nxt[3]; + switch (c1) + { + case 0xF0: + if (!(0x90 <= c2 && c2 <= 0xBF)) + return codecvt_base::error; + break; + case 0xF4: + if ((c2 & 0xF0) != 0x80) + return codecvt_base::error; + break; + default: + if ((c2 & 0xC0) != 0x80) + return codecvt_base::error; + break; + } + if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80) + return codecvt_base::error; + if (to_end-to_nxt < 2) + return codecvt_base::partial; + if ((((c1 & 7UL) << 18) + + ((c2 & 0x3FUL) << 12) + + ((c3 & 0x3FUL) << 6) + (c4 & 0x3F)) > Maxcode) + return codecvt_base::error; + *to_nxt = static_cast( + 0xD800 + | (((((c1 & 0x07) << 2) | ((c2 & 0x30) >> 4)) - 1) << 6) + | ((c2 & 0x0F) << 2) + | ((c3 & 0x30) >> 4)); + *++to_nxt = static_cast( + 0xDC00 + | ((c3 & 0x0F) << 6) + | (c4 & 0x3F)); + frm_nxt += 4; + } + else + { + return codecvt_base::error; + } + } + return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok; +} + +static +int +utf8_to_utf16_length(const uint8_t* frm, const uint8_t* frm_end, + size_t mx, unsigned long Maxcode = 0x10FFFF, + codecvt_mode mode = codecvt_mode(0)) +{ + const uint8_t* frm_nxt = frm; + if (mode & consume_header) + { + if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB && + frm_nxt[2] == 0xBF) + frm_nxt += 3; + } + for (size_t nchar16_t = 0; frm_nxt < frm_end && nchar16_t < mx; ++nchar16_t) + { + uint8_t c1 = *frm_nxt; + if (c1 > Maxcode) + break; + if (c1 < 0x80) + { + ++frm_nxt; + } + else if (c1 < 0xC2) + { + break; + } + else if (c1 < 0xE0) + { + if ((frm_end-frm_nxt < 2) || (frm_nxt[1] & 0xC0) != 0x80) + break; + uint16_t t = static_cast(((c1 & 0x1F) << 6) | (frm_nxt[1] & 0x3F)); + if (t > Maxcode) + break; + frm_nxt += 2; + } + else if (c1 < 0xF0) + { + if (frm_end-frm_nxt < 3) + break; + uint8_t c2 = frm_nxt[1]; + uint8_t c3 = frm_nxt[2]; + switch (c1) + { + case 0xE0: + if ((c2 & 0xE0) != 0xA0) + return static_cast(frm_nxt - frm); + break; + case 0xED: + if ((c2 & 0xE0) != 0x80) + return static_cast(frm_nxt - frm); + break; + default: + if ((c2 & 0xC0) != 0x80) + return static_cast(frm_nxt - frm); + break; + } + if ((c3 & 0xC0) != 0x80) + break; + if ((((c1 & 0x0Fu) << 12) | ((c2 & 0x3Fu) << 6) | (c3 & 0x3Fu)) > Maxcode) + break; + frm_nxt += 3; + } + else if (c1 < 0xF5) + { + if (frm_end-frm_nxt < 4 || mx-nchar16_t < 2) + break; + uint8_t c2 = frm_nxt[1]; + uint8_t c3 = frm_nxt[2]; + uint8_t c4 = frm_nxt[3]; + switch (c1) + { + case 0xF0: + if (!(0x90 <= c2 && c2 <= 0xBF)) + return static_cast(frm_nxt - frm); + break; + case 0xF4: + if ((c2 & 0xF0) != 0x80) + return static_cast(frm_nxt - frm); + break; + default: + if ((c2 & 0xC0) != 0x80) + return static_cast(frm_nxt - frm); + break; + } + if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80) + break; + if ((((c1 & 7UL) << 18) + + ((c2 & 0x3FUL) << 12) + + ((c3 & 0x3FUL) << 6) + (c4 & 0x3F)) > Maxcode) + break; + ++nchar16_t; + frm_nxt += 4; + } + else + { + break; + } + } + return static_cast(frm_nxt - frm); +} + +static +codecvt_base::result +ucs4_to_utf8(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt, + uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt, + unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0)) +{ + frm_nxt = frm; + to_nxt = to; + if (mode & generate_header) + { + if (to_end-to_nxt < 3) + return codecvt_base::partial; + *to_nxt++ = static_cast(0xEF); + *to_nxt++ = static_cast(0xBB); + *to_nxt++ = static_cast(0xBF); + } + for (; frm_nxt < frm_end; ++frm_nxt) + { + uint32_t wc = *frm_nxt; + if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode) + return codecvt_base::error; + if (wc < 0x000080) + { + if (to_end-to_nxt < 1) + return codecvt_base::partial; + *to_nxt++ = static_cast(wc); + } + else if (wc < 0x000800) + { + if (to_end-to_nxt < 2) + return codecvt_base::partial; + *to_nxt++ = static_cast(0xC0 | (wc >> 6)); + *to_nxt++ = static_cast(0x80 | (wc & 0x03F)); + } + else if (wc < 0x010000) + { + if (to_end-to_nxt < 3) + return codecvt_base::partial; + *to_nxt++ = static_cast(0xE0 | (wc >> 12)); + *to_nxt++ = static_cast(0x80 | ((wc & 0x0FC0) >> 6)); + *to_nxt++ = static_cast(0x80 | (wc & 0x003F)); + } + else // if (wc < 0x110000) + { + if (to_end-to_nxt < 4) + return codecvt_base::partial; + *to_nxt++ = static_cast(0xF0 | (wc >> 18)); + *to_nxt++ = static_cast(0x80 | ((wc & 0x03F000) >> 12)); + *to_nxt++ = static_cast(0x80 | ((wc & 0x000FC0) >> 6)); + *to_nxt++ = static_cast(0x80 | (wc & 0x00003F)); + } + } + return codecvt_base::ok; +} + +static +codecvt_base::result +utf8_to_ucs4(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt, + uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt, + unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0)) +{ + frm_nxt = frm; + to_nxt = to; + if (mode & consume_header) + { + if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB && + frm_nxt[2] == 0xBF) + frm_nxt += 3; + } + for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt) + { + uint8_t c1 = static_cast(*frm_nxt); + if (c1 < 0x80) + { + if (c1 > Maxcode) + return codecvt_base::error; + *to_nxt = static_cast(c1); + ++frm_nxt; + } + else if (c1 < 0xC2) + { + return codecvt_base::error; + } + else if (c1 < 0xE0) + { + if (frm_end-frm_nxt < 2) + return codecvt_base::partial; + uint8_t c2 = frm_nxt[1]; + if ((c2 & 0xC0) != 0x80) + return codecvt_base::error; + uint32_t t = static_cast(((c1 & 0x1F) << 6) + | (c2 & 0x3F)); + if (t > Maxcode) + return codecvt_base::error; + *to_nxt = t; + frm_nxt += 2; + } + else if (c1 < 0xF0) + { + if (frm_end-frm_nxt < 3) + return codecvt_base::partial; + uint8_t c2 = frm_nxt[1]; + uint8_t c3 = frm_nxt[2]; + switch (c1) + { + case 0xE0: + if ((c2 & 0xE0) != 0xA0) + return codecvt_base::error; + break; + case 0xED: + if ((c2 & 0xE0) != 0x80) + return codecvt_base::error; + break; + default: + if ((c2 & 0xC0) != 0x80) + return codecvt_base::error; + break; + } + if ((c3 & 0xC0) != 0x80) + return codecvt_base::error; + uint32_t t = static_cast(((c1 & 0x0F) << 12) + | ((c2 & 0x3F) << 6) + | (c3 & 0x3F)); + if (t > Maxcode) + return codecvt_base::error; + *to_nxt = t; + frm_nxt += 3; + } + else if (c1 < 0xF5) + { + if (frm_end-frm_nxt < 4) + return codecvt_base::partial; + uint8_t c2 = frm_nxt[1]; + uint8_t c3 = frm_nxt[2]; + uint8_t c4 = frm_nxt[3]; + switch (c1) + { + case 0xF0: + if (!(0x90 <= c2 && c2 <= 0xBF)) + return codecvt_base::error; + break; + case 0xF4: + if ((c2 & 0xF0) != 0x80) + return codecvt_base::error; + break; + default: + if ((c2 & 0xC0) != 0x80) + return codecvt_base::error; + break; + } + if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80) + return codecvt_base::error; + uint32_t t = static_cast(((c1 & 0x07) << 18) + | ((c2 & 0x3F) << 12) + | ((c3 & 0x3F) << 6) + | (c4 & 0x3F)); + if (t > Maxcode) + return codecvt_base::error; + *to_nxt = t; + frm_nxt += 4; + } + else + { + return codecvt_base::error; + } + } + return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok; +} + +static +int +utf8_to_ucs4_length(const uint8_t* frm, const uint8_t* frm_end, + size_t mx, unsigned long Maxcode = 0x10FFFF, + codecvt_mode mode = codecvt_mode(0)) +{ + const uint8_t* frm_nxt = frm; + if (mode & consume_header) + { + if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB && + frm_nxt[2] == 0xBF) + frm_nxt += 3; + } + for (size_t nchar32_t = 0; frm_nxt < frm_end && nchar32_t < mx; ++nchar32_t) + { + uint8_t c1 = static_cast(*frm_nxt); + if (c1 < 0x80) + { + if (c1 > Maxcode) + break; + ++frm_nxt; + } + else if (c1 < 0xC2) + { + break; + } + else if (c1 < 0xE0) + { + if ((frm_end-frm_nxt < 2) || ((frm_nxt[1] & 0xC0) != 0x80)) + break; + if ((((c1 & 0x1Fu) << 6) | (frm_nxt[1] & 0x3Fu)) > Maxcode) + break; + frm_nxt += 2; + } + else if (c1 < 0xF0) + { + if (frm_end-frm_nxt < 3) + break; + uint8_t c2 = frm_nxt[1]; + uint8_t c3 = frm_nxt[2]; + switch (c1) + { + case 0xE0: + if ((c2 & 0xE0) != 0xA0) + return static_cast(frm_nxt - frm); + break; + case 0xED: + if ((c2 & 0xE0) != 0x80) + return static_cast(frm_nxt - frm); + break; + default: + if ((c2 & 0xC0) != 0x80) + return static_cast(frm_nxt - frm); + break; + } + if ((c3 & 0xC0) != 0x80) + break; + if ((((c1 & 0x0Fu) << 12) | ((c2 & 0x3Fu) << 6) | (c3 & 0x3Fu)) > Maxcode) + break; + frm_nxt += 3; + } + else if (c1 < 0xF5) + { + if (frm_end-frm_nxt < 4) + break; + uint8_t c2 = frm_nxt[1]; + uint8_t c3 = frm_nxt[2]; + uint8_t c4 = frm_nxt[3]; + switch (c1) + { + case 0xF0: + if (!(0x90 <= c2 && c2 <= 0xBF)) + return static_cast(frm_nxt - frm); + break; + case 0xF4: + if ((c2 & 0xF0) != 0x80) + return static_cast(frm_nxt - frm); + break; + default: + if ((c2 & 0xC0) != 0x80) + return static_cast(frm_nxt - frm); + break; + } + if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80) + break; + if ((((c1 & 0x07u) << 18) | ((c2 & 0x3Fu) << 12) | + ((c3 & 0x3Fu) << 6) | (c4 & 0x3Fu)) > Maxcode) + break; + frm_nxt += 4; + } + else + { + break; + } + } + return static_cast(frm_nxt - frm); +} + +static +codecvt_base::result +ucs2_to_utf8(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt, + uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt, + unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0)) +{ + frm_nxt = frm; + to_nxt = to; + if (mode & generate_header) + { + if (to_end-to_nxt < 3) + return codecvt_base::partial; + *to_nxt++ = static_cast(0xEF); + *to_nxt++ = static_cast(0xBB); + *to_nxt++ = static_cast(0xBF); + } + for (; frm_nxt < frm_end; ++frm_nxt) + { + uint16_t wc = *frm_nxt; + if ((wc & 0xF800) == 0xD800 || wc > Maxcode) + return codecvt_base::error; + if (wc < 0x0080) + { + if (to_end-to_nxt < 1) + return codecvt_base::partial; + *to_nxt++ = static_cast(wc); + } + else if (wc < 0x0800) + { + if (to_end-to_nxt < 2) + return codecvt_base::partial; + *to_nxt++ = static_cast(0xC0 | (wc >> 6)); + *to_nxt++ = static_cast(0x80 | (wc & 0x03F)); + } + else // if (wc <= 0xFFFF) + { + if (to_end-to_nxt < 3) + return codecvt_base::partial; + *to_nxt++ = static_cast(0xE0 | (wc >> 12)); + *to_nxt++ = static_cast(0x80 | ((wc & 0x0FC0) >> 6)); + *to_nxt++ = static_cast(0x80 | (wc & 0x003F)); + } + } + return codecvt_base::ok; +} + +static +codecvt_base::result +utf8_to_ucs2(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt, + uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt, + unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0)) +{ + frm_nxt = frm; + to_nxt = to; + if (mode & consume_header) + { + if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB && + frm_nxt[2] == 0xBF) + frm_nxt += 3; + } + for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt) + { + uint8_t c1 = static_cast(*frm_nxt); + if (c1 < 0x80) + { + if (c1 > Maxcode) + return codecvt_base::error; + *to_nxt = static_cast(c1); + ++frm_nxt; + } + else if (c1 < 0xC2) + { + return codecvt_base::error; + } + else if (c1 < 0xE0) + { + if (frm_end-frm_nxt < 2) + return codecvt_base::partial; + uint8_t c2 = frm_nxt[1]; + if ((c2 & 0xC0) != 0x80) + return codecvt_base::error; + uint16_t t = static_cast(((c1 & 0x1F) << 6) + | (c2 & 0x3F)); + if (t > Maxcode) + return codecvt_base::error; + *to_nxt = t; + frm_nxt += 2; + } + else if (c1 < 0xF0) + { + if (frm_end-frm_nxt < 3) + return codecvt_base::partial; + uint8_t c2 = frm_nxt[1]; + uint8_t c3 = frm_nxt[2]; + switch (c1) + { + case 0xE0: + if ((c2 & 0xE0) != 0xA0) + return codecvt_base::error; + break; + case 0xED: + if ((c2 & 0xE0) != 0x80) + return codecvt_base::error; + break; + default: + if ((c2 & 0xC0) != 0x80) + return codecvt_base::error; + break; + } + if ((c3 & 0xC0) != 0x80) + return codecvt_base::error; + uint16_t t = static_cast(((c1 & 0x0F) << 12) + | ((c2 & 0x3F) << 6) + | (c3 & 0x3F)); + if (t > Maxcode) + return codecvt_base::error; + *to_nxt = t; + frm_nxt += 3; + } + else + { + return codecvt_base::error; + } + } + return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok; +} + +static +int +utf8_to_ucs2_length(const uint8_t* frm, const uint8_t* frm_end, + size_t mx, unsigned long Maxcode = 0x10FFFF, + codecvt_mode mode = codecvt_mode(0)) +{ + const uint8_t* frm_nxt = frm; + if (mode & consume_header) + { + if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB && + frm_nxt[2] == 0xBF) + frm_nxt += 3; + } + for (size_t nchar32_t = 0; frm_nxt < frm_end && nchar32_t < mx; ++nchar32_t) + { + uint8_t c1 = static_cast(*frm_nxt); + if (c1 < 0x80) + { + if (c1 > Maxcode) + break; + ++frm_nxt; + } + else if (c1 < 0xC2) + { + break; + } + else if (c1 < 0xE0) + { + if ((frm_end-frm_nxt < 2) || ((frm_nxt[1] & 0xC0) != 0x80)) + break; + if ((((c1 & 0x1Fu) << 6) | (frm_nxt[1] & 0x3Fu)) > Maxcode) + break; + frm_nxt += 2; + } + else if (c1 < 0xF0) + { + if (frm_end-frm_nxt < 3) + break; + uint8_t c2 = frm_nxt[1]; + uint8_t c3 = frm_nxt[2]; + switch (c1) + { + case 0xE0: + if ((c2 & 0xE0) != 0xA0) + return static_cast(frm_nxt - frm); + break; + case 0xED: + if ((c2 & 0xE0) != 0x80) + return static_cast(frm_nxt - frm); + break; + default: + if ((c2 & 0xC0) != 0x80) + return static_cast(frm_nxt - frm); + break; + } + if ((c3 & 0xC0) != 0x80) + break; + if ((((c1 & 0x0Fu) << 12) | ((c2 & 0x3Fu) << 6) | (c3 & 0x3Fu)) > Maxcode) + break; + frm_nxt += 3; + } + else + { + break; + } + } + return static_cast(frm_nxt - frm); +} + +static +codecvt_base::result +ucs4_to_utf16be(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt, + uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt, + unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0)) +{ + frm_nxt = frm; + to_nxt = to; + if (mode & generate_header) + { + if (to_end-to_nxt < 2) + return codecvt_base::partial; + *to_nxt++ = static_cast(0xFE); + *to_nxt++ = static_cast(0xFF); + } + for (; frm_nxt < frm_end; ++frm_nxt) + { + uint32_t wc = *frm_nxt; + if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode) + return codecvt_base::error; + if (wc < 0x010000) + { + if (to_end-to_nxt < 2) + return codecvt_base::partial; + *to_nxt++ = static_cast(wc >> 8); + *to_nxt++ = static_cast(wc); + } + else + { + if (to_end-to_nxt < 4) + return codecvt_base::partial; + uint16_t t = static_cast( + 0xD800 + | ((((wc & 0x1F0000) >> 16) - 1) << 6) + | ((wc & 0x00FC00) >> 10)); + *to_nxt++ = static_cast(t >> 8); + *to_nxt++ = static_cast(t); + t = static_cast(0xDC00 | (wc & 0x03FF)); + *to_nxt++ = static_cast(t >> 8); + *to_nxt++ = static_cast(t); + } + } + return codecvt_base::ok; +} + +static +codecvt_base::result +utf16be_to_ucs4(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt, + uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt, + unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0)) +{ + frm_nxt = frm; + to_nxt = to; + if (mode & consume_header) + { + if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF) + frm_nxt += 2; + } + for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt) + { + uint16_t c1 = static_cast(frm_nxt[0] << 8 | frm_nxt[1]); + if ((c1 & 0xFC00) == 0xDC00) + return codecvt_base::error; + if ((c1 & 0xFC00) != 0xD800) + { + if (c1 > Maxcode) + return codecvt_base::error; + *to_nxt = static_cast(c1); + frm_nxt += 2; + } + else + { + if (frm_end-frm_nxt < 4) + return codecvt_base::partial; + uint16_t c2 = static_cast(frm_nxt[2] << 8 | frm_nxt[3]); + if ((c2 & 0xFC00) != 0xDC00) + return codecvt_base::error; + uint32_t t = static_cast( + ((((c1 & 0x03C0) >> 6) + 1) << 16) + | ((c1 & 0x003F) << 10) + | (c2 & 0x03FF)); + if (t > Maxcode) + return codecvt_base::error; + *to_nxt = t; + frm_nxt += 4; + } + } + return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok; +} + +static +int +utf16be_to_ucs4_length(const uint8_t* frm, const uint8_t* frm_end, + size_t mx, unsigned long Maxcode = 0x10FFFF, + codecvt_mode mode = codecvt_mode(0)) +{ + const uint8_t* frm_nxt = frm; + if (mode & consume_header) + { + if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF) + frm_nxt += 2; + } + for (size_t nchar32_t = 0; frm_nxt < frm_end - 1 && nchar32_t < mx; ++nchar32_t) + { + uint16_t c1 = static_cast(frm_nxt[0] << 8 | frm_nxt[1]); + if ((c1 & 0xFC00) == 0xDC00) + break; + if ((c1 & 0xFC00) != 0xD800) + { + if (c1 > Maxcode) + break; + frm_nxt += 2; + } + else + { + if (frm_end-frm_nxt < 4) + break; + uint16_t c2 = static_cast(frm_nxt[2] << 8 | frm_nxt[3]); + if ((c2 & 0xFC00) != 0xDC00) + break; + uint32_t t = static_cast( + ((((c1 & 0x03C0) >> 6) + 1) << 16) + | ((c1 & 0x003F) << 10) + | (c2 & 0x03FF)); + if (t > Maxcode) + break; + frm_nxt += 4; + } + } + return static_cast(frm_nxt - frm); +} + +static +codecvt_base::result +ucs4_to_utf16le(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt, + uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt, + unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0)) +{ + frm_nxt = frm; + to_nxt = to; + if (mode & generate_header) + { + if (to_end - to_nxt < 2) + return codecvt_base::partial; + *to_nxt++ = static_cast(0xFF); + *to_nxt++ = static_cast(0xFE); + } + for (; frm_nxt < frm_end; ++frm_nxt) + { + uint32_t wc = *frm_nxt; + if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode) + return codecvt_base::error; + if (wc < 0x010000) + { + if (to_end-to_nxt < 2) + return codecvt_base::partial; + *to_nxt++ = static_cast(wc); + *to_nxt++ = static_cast(wc >> 8); + } + else + { + if (to_end-to_nxt < 4) + return codecvt_base::partial; + uint16_t t = static_cast( + 0xD800 + | ((((wc & 0x1F0000) >> 16) - 1) << 6) + | ((wc & 0x00FC00) >> 10)); + *to_nxt++ = static_cast(t); + *to_nxt++ = static_cast(t >> 8); + t = static_cast(0xDC00 | (wc & 0x03FF)); + *to_nxt++ = static_cast(t); + *to_nxt++ = static_cast(t >> 8); + } + } + return codecvt_base::ok; +} + +static +codecvt_base::result +utf16le_to_ucs4(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt, + uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt, + unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0)) +{ + frm_nxt = frm; + to_nxt = to; + if (mode & consume_header) + { + if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE) + frm_nxt += 2; + } + for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt) + { + uint16_t c1 = static_cast(frm_nxt[1] << 8 | frm_nxt[0]); + if ((c1 & 0xFC00) == 0xDC00) + return codecvt_base::error; + if ((c1 & 0xFC00) != 0xD800) + { + if (c1 > Maxcode) + return codecvt_base::error; + *to_nxt = static_cast(c1); + frm_nxt += 2; + } + else + { + if (frm_end-frm_nxt < 4) + return codecvt_base::partial; + uint16_t c2 = static_cast(frm_nxt[3] << 8 | frm_nxt[2]); + if ((c2 & 0xFC00) != 0xDC00) + return codecvt_base::error; + uint32_t t = static_cast( + ((((c1 & 0x03C0) >> 6) + 1) << 16) + | ((c1 & 0x003F) << 10) + | (c2 & 0x03FF)); + if (t > Maxcode) + return codecvt_base::error; + *to_nxt = t; + frm_nxt += 4; + } + } + return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok; +} + +static +int +utf16le_to_ucs4_length(const uint8_t* frm, const uint8_t* frm_end, + size_t mx, unsigned long Maxcode = 0x10FFFF, + codecvt_mode mode = codecvt_mode(0)) +{ + const uint8_t* frm_nxt = frm; + if (mode & consume_header) + { + if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE) + frm_nxt += 2; + } + for (size_t nchar32_t = 0; frm_nxt < frm_end - 1 && nchar32_t < mx; ++nchar32_t) + { + uint16_t c1 = static_cast(frm_nxt[1] << 8 | frm_nxt[0]); + if ((c1 & 0xFC00) == 0xDC00) + break; + if ((c1 & 0xFC00) != 0xD800) + { + if (c1 > Maxcode) + break; + frm_nxt += 2; + } + else + { + if (frm_end-frm_nxt < 4) + break; + uint16_t c2 = static_cast(frm_nxt[3] << 8 | frm_nxt[2]); + if ((c2 & 0xFC00) != 0xDC00) + break; + uint32_t t = static_cast( + ((((c1 & 0x03C0) >> 6) + 1) << 16) + | ((c1 & 0x003F) << 10) + | (c2 & 0x03FF)); + if (t > Maxcode) + break; + frm_nxt += 4; + } + } + return static_cast(frm_nxt - frm); +} + +static +codecvt_base::result +ucs2_to_utf16be(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt, + uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt, + unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0)) +{ + frm_nxt = frm; + to_nxt = to; + if (mode & generate_header) + { + if (to_end-to_nxt < 2) + return codecvt_base::partial; + *to_nxt++ = static_cast(0xFE); + *to_nxt++ = static_cast(0xFF); + } + for (; frm_nxt < frm_end; ++frm_nxt) + { + uint16_t wc = *frm_nxt; + if ((wc & 0xF800) == 0xD800 || wc > Maxcode) + return codecvt_base::error; + if (to_end-to_nxt < 2) + return codecvt_base::partial; + *to_nxt++ = static_cast(wc >> 8); + *to_nxt++ = static_cast(wc); + } + return codecvt_base::ok; +} + +static +codecvt_base::result +utf16be_to_ucs2(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt, + uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt, + unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0)) +{ + frm_nxt = frm; + to_nxt = to; + if (mode & consume_header) + { + if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF) + frm_nxt += 2; + } + for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt) + { + uint16_t c1 = static_cast(frm_nxt[0] << 8 | frm_nxt[1]); + if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode) + return codecvt_base::error; + *to_nxt = c1; + frm_nxt += 2; + } + return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok; +} + +static +int +utf16be_to_ucs2_length(const uint8_t* frm, const uint8_t* frm_end, + size_t mx, unsigned long Maxcode = 0x10FFFF, + codecvt_mode mode = codecvt_mode(0)) +{ + const uint8_t* frm_nxt = frm; + if (mode & consume_header) + { + if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF) + frm_nxt += 2; + } + for (size_t nchar16_t = 0; frm_nxt < frm_end - 1 && nchar16_t < mx; ++nchar16_t) + { + uint16_t c1 = static_cast(frm_nxt[0] << 8 | frm_nxt[1]); + if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode) + break; + frm_nxt += 2; + } + return static_cast(frm_nxt - frm); +} + +static +codecvt_base::result +ucs2_to_utf16le(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt, + uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt, + unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0)) +{ + frm_nxt = frm; + to_nxt = to; + if (mode & generate_header) + { + if (to_end-to_nxt < 2) + return codecvt_base::partial; + *to_nxt++ = static_cast(0xFF); + *to_nxt++ = static_cast(0xFE); + } + for (; frm_nxt < frm_end; ++frm_nxt) + { + uint16_t wc = *frm_nxt; + if ((wc & 0xF800) == 0xD800 || wc > Maxcode) + return codecvt_base::error; + if (to_end-to_nxt < 2) + return codecvt_base::partial; + *to_nxt++ = static_cast(wc); + *to_nxt++ = static_cast(wc >> 8); + } + return codecvt_base::ok; +} + +static +codecvt_base::result +utf16le_to_ucs2(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt, + uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt, + unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0)) +{ + frm_nxt = frm; + to_nxt = to; + if (mode & consume_header) + { + if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE) + frm_nxt += 2; + } + for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt) + { + uint16_t c1 = static_cast(frm_nxt[1] << 8 | frm_nxt[0]); + if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode) + return codecvt_base::error; + *to_nxt = c1; + frm_nxt += 2; + } + return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok; +} + +static +int +utf16le_to_ucs2_length(const uint8_t* frm, const uint8_t* frm_end, + size_t mx, unsigned long Maxcode = 0x10FFFF, + codecvt_mode mode = codecvt_mode(0)) +{ + const uint8_t* frm_nxt = frm; + frm_nxt = frm; + if (mode & consume_header) + { + if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE) + frm_nxt += 2; + } + for (size_t nchar16_t = 0; frm_nxt < frm_end - 1 && nchar16_t < mx; ++nchar16_t) + { + uint16_t c1 = static_cast(frm_nxt[1] << 8 | frm_nxt[0]); + if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode) + break; + frm_nxt += 2; + } + return static_cast(frm_nxt - frm); +} + +// template <> class codecvt + +locale::id codecvt::id; + +codecvt::~codecvt() +{ +} + +codecvt::result +codecvt::do_out(state_type&, + const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt, + extern_type* to, extern_type* to_end, extern_type*& to_nxt) const +{ + const uint16_t* _frm = reinterpret_cast(frm); + const uint16_t* _frm_end = reinterpret_cast(frm_end); + const uint16_t* _frm_nxt = _frm; + uint8_t* _to = reinterpret_cast(to); + uint8_t* _to_end = reinterpret_cast(to_end); + uint8_t* _to_nxt = _to; + result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt); + frm_nxt = frm + (_frm_nxt - _frm); + to_nxt = to + (_to_nxt - _to); + return r; +} + +codecvt::result +codecvt::do_in(state_type&, + const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt, + intern_type* to, intern_type* to_end, intern_type*& to_nxt) const +{ + const uint8_t* _frm = reinterpret_cast(frm); + const uint8_t* _frm_end = reinterpret_cast(frm_end); + const uint8_t* _frm_nxt = _frm; + uint16_t* _to = reinterpret_cast(to); + uint16_t* _to_end = reinterpret_cast(to_end); + uint16_t* _to_nxt = _to; + result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt); + frm_nxt = frm + (_frm_nxt - _frm); + to_nxt = to + (_to_nxt - _to); + return r; +} + +codecvt::result +codecvt::do_unshift(state_type&, + extern_type* to, extern_type*, extern_type*& to_nxt) const +{ + to_nxt = to; + return noconv; +} + +int +codecvt::do_encoding() const _NOEXCEPT +{ + return 0; +} + +bool +codecvt::do_always_noconv() const _NOEXCEPT +{ + return false; +} + +int +codecvt::do_length(state_type&, + const extern_type* frm, const extern_type* frm_end, size_t mx) const +{ + const uint8_t* _frm = reinterpret_cast(frm); + const uint8_t* _frm_end = reinterpret_cast(frm_end); + return utf8_to_utf16_length(_frm, _frm_end, mx); +} + +int +codecvt::do_max_length() const _NOEXCEPT +{ + return 4; +} + +// template <> class codecvt + +locale::id codecvt::id; + +codecvt::~codecvt() +{ +} + +codecvt::result +codecvt::do_out(state_type&, + const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt, + extern_type* to, extern_type* to_end, extern_type*& to_nxt) const +{ + const uint32_t* _frm = reinterpret_cast(frm); + const uint32_t* _frm_end = reinterpret_cast(frm_end); + const uint32_t* _frm_nxt = _frm; + uint8_t* _to = reinterpret_cast(to); + uint8_t* _to_end = reinterpret_cast(to_end); + uint8_t* _to_nxt = _to; + result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt); + frm_nxt = frm + (_frm_nxt - _frm); + to_nxt = to + (_to_nxt - _to); + return r; +} + +codecvt::result +codecvt::do_in(state_type&, + const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt, + intern_type* to, intern_type* to_end, intern_type*& to_nxt) const +{ + const uint8_t* _frm = reinterpret_cast(frm); + const uint8_t* _frm_end = reinterpret_cast(frm_end); + const uint8_t* _frm_nxt = _frm; + uint32_t* _to = reinterpret_cast(to); + uint32_t* _to_end = reinterpret_cast(to_end); + uint32_t* _to_nxt = _to; + result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt); + frm_nxt = frm + (_frm_nxt - _frm); + to_nxt = to + (_to_nxt - _to); + return r; +} + +codecvt::result +codecvt::do_unshift(state_type&, + extern_type* to, extern_type*, extern_type*& to_nxt) const +{ + to_nxt = to; + return noconv; +} + +int +codecvt::do_encoding() const _NOEXCEPT +{ + return 0; +} + +bool +codecvt::do_always_noconv() const _NOEXCEPT +{ + return false; +} + +int +codecvt::do_length(state_type&, + const extern_type* frm, const extern_type* frm_end, size_t mx) const +{ + const uint8_t* _frm = reinterpret_cast(frm); + const uint8_t* _frm_end = reinterpret_cast(frm_end); + return utf8_to_ucs4_length(_frm, _frm_end, mx); +} + +int +codecvt::do_max_length() const _NOEXCEPT +{ + return 4; +} + +// __codecvt_utf8 + +__codecvt_utf8::result +__codecvt_utf8::do_out(state_type&, + const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt, + extern_type* to, extern_type* to_end, extern_type*& to_nxt) const +{ +#if defined(_LIBCPP_SHORT_WCHAR) + const uint16_t* _frm = reinterpret_cast(frm); + const uint16_t* _frm_end = reinterpret_cast(frm_end); + const uint16_t* _frm_nxt = _frm; +#else + const uint32_t* _frm = reinterpret_cast(frm); + const uint32_t* _frm_end = reinterpret_cast(frm_end); + const uint32_t* _frm_nxt = _frm; +#endif + uint8_t* _to = reinterpret_cast(to); + uint8_t* _to_end = reinterpret_cast(to_end); + uint8_t* _to_nxt = _to; +#if defined(_LIBCPP_SHORT_WCHAR) + result r = ucs2_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, + _Maxcode_, _Mode_); +#else + result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, + _Maxcode_, _Mode_); +#endif + frm_nxt = frm + (_frm_nxt - _frm); + to_nxt = to + (_to_nxt - _to); + return r; +} + +__codecvt_utf8::result +__codecvt_utf8::do_in(state_type&, + const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt, + intern_type* to, intern_type* to_end, intern_type*& to_nxt) const +{ + const uint8_t* _frm = reinterpret_cast(frm); + const uint8_t* _frm_end = reinterpret_cast(frm_end); + const uint8_t* _frm_nxt = _frm; +#if defined(_LIBCPP_SHORT_WCHAR) + uint16_t* _to = reinterpret_cast(to); + uint16_t* _to_end = reinterpret_cast(to_end); + uint16_t* _to_nxt = _to; + result r = utf8_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, + _Maxcode_, _Mode_); +#else + uint32_t* _to = reinterpret_cast(to); + uint32_t* _to_end = reinterpret_cast(to_end); + uint32_t* _to_nxt = _to; + result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, + _Maxcode_, _Mode_); +#endif + frm_nxt = frm + (_frm_nxt - _frm); + to_nxt = to + (_to_nxt - _to); + return r; +} + +__codecvt_utf8::result +__codecvt_utf8::do_unshift(state_type&, + extern_type* to, extern_type*, extern_type*& to_nxt) const +{ + to_nxt = to; + return noconv; +} + +int +__codecvt_utf8::do_encoding() const _NOEXCEPT +{ + return 0; +} + +bool +__codecvt_utf8::do_always_noconv() const _NOEXCEPT +{ + return false; +} + +int +__codecvt_utf8::do_length(state_type&, + const extern_type* frm, const extern_type* frm_end, size_t mx) const +{ + const uint8_t* _frm = reinterpret_cast(frm); + const uint8_t* _frm_end = reinterpret_cast(frm_end); + return utf8_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_); +} + +int +__codecvt_utf8::do_max_length() const _NOEXCEPT +{ + if (_Mode_ & consume_header) + return 7; + return 4; +} + +// __codecvt_utf8 + +__codecvt_utf8::result +__codecvt_utf8::do_out(state_type&, + const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt, + extern_type* to, extern_type* to_end, extern_type*& to_nxt) const +{ + const uint16_t* _frm = reinterpret_cast(frm); + const uint16_t* _frm_end = reinterpret_cast(frm_end); + const uint16_t* _frm_nxt = _frm; + uint8_t* _to = reinterpret_cast(to); + uint8_t* _to_end = reinterpret_cast(to_end); + uint8_t* _to_nxt = _to; + result r = ucs2_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, + _Maxcode_, _Mode_); + frm_nxt = frm + (_frm_nxt - _frm); + to_nxt = to + (_to_nxt - _to); + return r; +} + +__codecvt_utf8::result +__codecvt_utf8::do_in(state_type&, + const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt, + intern_type* to, intern_type* to_end, intern_type*& to_nxt) const +{ + const uint8_t* _frm = reinterpret_cast(frm); + const uint8_t* _frm_end = reinterpret_cast(frm_end); + const uint8_t* _frm_nxt = _frm; + uint16_t* _to = reinterpret_cast(to); + uint16_t* _to_end = reinterpret_cast(to_end); + uint16_t* _to_nxt = _to; + result r = utf8_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, + _Maxcode_, _Mode_); + frm_nxt = frm + (_frm_nxt - _frm); + to_nxt = to + (_to_nxt - _to); + return r; +} + +__codecvt_utf8::result +__codecvt_utf8::do_unshift(state_type&, + extern_type* to, extern_type*, extern_type*& to_nxt) const +{ + to_nxt = to; + return noconv; +} + +int +__codecvt_utf8::do_encoding() const _NOEXCEPT +{ + return 0; +} + +bool +__codecvt_utf8::do_always_noconv() const _NOEXCEPT +{ + return false; +} + +int +__codecvt_utf8::do_length(state_type&, + const extern_type* frm, const extern_type* frm_end, size_t mx) const +{ + const uint8_t* _frm = reinterpret_cast(frm); + const uint8_t* _frm_end = reinterpret_cast(frm_end); + return utf8_to_ucs2_length(_frm, _frm_end, mx, _Maxcode_, _Mode_); +} + +int +__codecvt_utf8::do_max_length() const _NOEXCEPT +{ + if (_Mode_ & consume_header) + return 6; + return 3; +} + +// __codecvt_utf8 + +__codecvt_utf8::result +__codecvt_utf8::do_out(state_type&, + const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt, + extern_type* to, extern_type* to_end, extern_type*& to_nxt) const +{ + const uint32_t* _frm = reinterpret_cast(frm); + const uint32_t* _frm_end = reinterpret_cast(frm_end); + const uint32_t* _frm_nxt = _frm; + uint8_t* _to = reinterpret_cast(to); + uint8_t* _to_end = reinterpret_cast(to_end); + uint8_t* _to_nxt = _to; + result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, + _Maxcode_, _Mode_); + frm_nxt = frm + (_frm_nxt - _frm); + to_nxt = to + (_to_nxt - _to); + return r; +} + +__codecvt_utf8::result +__codecvt_utf8::do_in(state_type&, + const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt, + intern_type* to, intern_type* to_end, intern_type*& to_nxt) const +{ + const uint8_t* _frm = reinterpret_cast(frm); + const uint8_t* _frm_end = reinterpret_cast(frm_end); + const uint8_t* _frm_nxt = _frm; + uint32_t* _to = reinterpret_cast(to); + uint32_t* _to_end = reinterpret_cast(to_end); + uint32_t* _to_nxt = _to; + result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, + _Maxcode_, _Mode_); + frm_nxt = frm + (_frm_nxt - _frm); + to_nxt = to + (_to_nxt - _to); + return r; +} + +__codecvt_utf8::result +__codecvt_utf8::do_unshift(state_type&, + extern_type* to, extern_type*, extern_type*& to_nxt) const +{ + to_nxt = to; + return noconv; +} + +int +__codecvt_utf8::do_encoding() const _NOEXCEPT +{ + return 0; +} + +bool +__codecvt_utf8::do_always_noconv() const _NOEXCEPT +{ + return false; +} + +int +__codecvt_utf8::do_length(state_type&, + const extern_type* frm, const extern_type* frm_end, size_t mx) const +{ + const uint8_t* _frm = reinterpret_cast(frm); + const uint8_t* _frm_end = reinterpret_cast(frm_end); + return utf8_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_); +} + +int +__codecvt_utf8::do_max_length() const _NOEXCEPT +{ + if (_Mode_ & consume_header) + return 7; + return 4; +} + +// __codecvt_utf16 + +__codecvt_utf16::result +__codecvt_utf16::do_out(state_type&, + const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt, + extern_type* to, extern_type* to_end, extern_type*& to_nxt) const +{ + const uint32_t* _frm = reinterpret_cast(frm); + const uint32_t* _frm_end = reinterpret_cast(frm_end); + const uint32_t* _frm_nxt = _frm; + uint8_t* _to = reinterpret_cast(to); + uint8_t* _to_end = reinterpret_cast(to_end); + uint8_t* _to_nxt = _to; + result r = ucs4_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, + _Maxcode_, _Mode_); + frm_nxt = frm + (_frm_nxt - _frm); + to_nxt = to + (_to_nxt - _to); + return r; +} + +__codecvt_utf16::result +__codecvt_utf16::do_in(state_type&, + const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt, + intern_type* to, intern_type* to_end, intern_type*& to_nxt) const +{ + const uint8_t* _frm = reinterpret_cast(frm); + const uint8_t* _frm_end = reinterpret_cast(frm_end); + const uint8_t* _frm_nxt = _frm; + uint32_t* _to = reinterpret_cast(to); + uint32_t* _to_end = reinterpret_cast(to_end); + uint32_t* _to_nxt = _to; + result r = utf16be_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, + _Maxcode_, _Mode_); + frm_nxt = frm + (_frm_nxt - _frm); + to_nxt = to + (_to_nxt - _to); + return r; +} + +__codecvt_utf16::result +__codecvt_utf16::do_unshift(state_type&, + extern_type* to, extern_type*, extern_type*& to_nxt) const +{ + to_nxt = to; + return noconv; +} + +int +__codecvt_utf16::do_encoding() const _NOEXCEPT +{ + return 0; +} + +bool +__codecvt_utf16::do_always_noconv() const _NOEXCEPT +{ + return false; +} + +int +__codecvt_utf16::do_length(state_type&, + const extern_type* frm, const extern_type* frm_end, size_t mx) const +{ + const uint8_t* _frm = reinterpret_cast(frm); + const uint8_t* _frm_end = reinterpret_cast(frm_end); + return utf16be_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_); +} + +int +__codecvt_utf16::do_max_length() const _NOEXCEPT +{ + if (_Mode_ & consume_header) + return 6; + return 4; +} + +// __codecvt_utf16 + +__codecvt_utf16::result +__codecvt_utf16::do_out(state_type&, + const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt, + extern_type* to, extern_type* to_end, extern_type*& to_nxt) const +{ + const uint32_t* _frm = reinterpret_cast(frm); + const uint32_t* _frm_end = reinterpret_cast(frm_end); + const uint32_t* _frm_nxt = _frm; + uint8_t* _to = reinterpret_cast(to); + uint8_t* _to_end = reinterpret_cast(to_end); + uint8_t* _to_nxt = _to; + result r = ucs4_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, + _Maxcode_, _Mode_); + frm_nxt = frm + (_frm_nxt - _frm); + to_nxt = to + (_to_nxt - _to); + return r; +} + +__codecvt_utf16::result +__codecvt_utf16::do_in(state_type&, + const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt, + intern_type* to, intern_type* to_end, intern_type*& to_nxt) const +{ + const uint8_t* _frm = reinterpret_cast(frm); + const uint8_t* _frm_end = reinterpret_cast(frm_end); + const uint8_t* _frm_nxt = _frm; + uint32_t* _to = reinterpret_cast(to); + uint32_t* _to_end = reinterpret_cast(to_end); + uint32_t* _to_nxt = _to; + result r = utf16le_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, + _Maxcode_, _Mode_); + frm_nxt = frm + (_frm_nxt - _frm); + to_nxt = to + (_to_nxt - _to); + return r; +} + +__codecvt_utf16::result +__codecvt_utf16::do_unshift(state_type&, + extern_type* to, extern_type*, extern_type*& to_nxt) const +{ + to_nxt = to; + return noconv; +} + +int +__codecvt_utf16::do_encoding() const _NOEXCEPT +{ + return 0; +} + +bool +__codecvt_utf16::do_always_noconv() const _NOEXCEPT +{ + return false; +} + +int +__codecvt_utf16::do_length(state_type&, + const extern_type* frm, const extern_type* frm_end, size_t mx) const +{ + const uint8_t* _frm = reinterpret_cast(frm); + const uint8_t* _frm_end = reinterpret_cast(frm_end); + return utf16le_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_); +} + +int +__codecvt_utf16::do_max_length() const _NOEXCEPT +{ + if (_Mode_ & consume_header) + return 6; + return 4; +} + +// __codecvt_utf16 + +__codecvt_utf16::result +__codecvt_utf16::do_out(state_type&, + const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt, + extern_type* to, extern_type* to_end, extern_type*& to_nxt) const +{ + const uint16_t* _frm = reinterpret_cast(frm); + const uint16_t* _frm_end = reinterpret_cast(frm_end); + const uint16_t* _frm_nxt = _frm; + uint8_t* _to = reinterpret_cast(to); + uint8_t* _to_end = reinterpret_cast(to_end); + uint8_t* _to_nxt = _to; + result r = ucs2_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, + _Maxcode_, _Mode_); + frm_nxt = frm + (_frm_nxt - _frm); + to_nxt = to + (_to_nxt - _to); + return r; +} + +__codecvt_utf16::result +__codecvt_utf16::do_in(state_type&, + const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt, + intern_type* to, intern_type* to_end, intern_type*& to_nxt) const +{ + const uint8_t* _frm = reinterpret_cast(frm); + const uint8_t* _frm_end = reinterpret_cast(frm_end); + const uint8_t* _frm_nxt = _frm; + uint16_t* _to = reinterpret_cast(to); + uint16_t* _to_end = reinterpret_cast(to_end); + uint16_t* _to_nxt = _to; + result r = utf16be_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, + _Maxcode_, _Mode_); + frm_nxt = frm + (_frm_nxt - _frm); + to_nxt = to + (_to_nxt - _to); + return r; +} + +__codecvt_utf16::result +__codecvt_utf16::do_unshift(state_type&, + extern_type* to, extern_type*, extern_type*& to_nxt) const +{ + to_nxt = to; + return noconv; +} + +int +__codecvt_utf16::do_encoding() const _NOEXCEPT +{ + return 0; +} + +bool +__codecvt_utf16::do_always_noconv() const _NOEXCEPT +{ + return false; +} + +int +__codecvt_utf16::do_length(state_type&, + const extern_type* frm, const extern_type* frm_end, size_t mx) const +{ + const uint8_t* _frm = reinterpret_cast(frm); + const uint8_t* _frm_end = reinterpret_cast(frm_end); + return utf16be_to_ucs2_length(_frm, _frm_end, mx, _Maxcode_, _Mode_); +} + +int +__codecvt_utf16::do_max_length() const _NOEXCEPT +{ + if (_Mode_ & consume_header) + return 4; + return 2; +} + +// __codecvt_utf16 + +__codecvt_utf16::result +__codecvt_utf16::do_out(state_type&, + const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt, + extern_type* to, extern_type* to_end, extern_type*& to_nxt) const +{ + const uint16_t* _frm = reinterpret_cast(frm); + const uint16_t* _frm_end = reinterpret_cast(frm_end); + const uint16_t* _frm_nxt = _frm; + uint8_t* _to = reinterpret_cast(to); + uint8_t* _to_end = reinterpret_cast(to_end); + uint8_t* _to_nxt = _to; + result r = ucs2_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, + _Maxcode_, _Mode_); + frm_nxt = frm + (_frm_nxt - _frm); + to_nxt = to + (_to_nxt - _to); + return r; +} + +__codecvt_utf16::result +__codecvt_utf16::do_in(state_type&, + const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt, + intern_type* to, intern_type* to_end, intern_type*& to_nxt) const +{ + const uint8_t* _frm = reinterpret_cast(frm); + const uint8_t* _frm_end = reinterpret_cast(frm_end); + const uint8_t* _frm_nxt = _frm; + uint16_t* _to = reinterpret_cast(to); + uint16_t* _to_end = reinterpret_cast(to_end); + uint16_t* _to_nxt = _to; + result r = utf16le_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, + _Maxcode_, _Mode_); + frm_nxt = frm + (_frm_nxt - _frm); + to_nxt = to + (_to_nxt - _to); + return r; +} + +__codecvt_utf16::result +__codecvt_utf16::do_unshift(state_type&, + extern_type* to, extern_type*, extern_type*& to_nxt) const +{ + to_nxt = to; + return noconv; +} + +int +__codecvt_utf16::do_encoding() const _NOEXCEPT +{ + return 0; +} + +bool +__codecvt_utf16::do_always_noconv() const _NOEXCEPT +{ + return false; +} + +int +__codecvt_utf16::do_length(state_type&, + const extern_type* frm, const extern_type* frm_end, size_t mx) const +{ + const uint8_t* _frm = reinterpret_cast(frm); + const uint8_t* _frm_end = reinterpret_cast(frm_end); + return utf16le_to_ucs2_length(_frm, _frm_end, mx, _Maxcode_, _Mode_); +} + +int +__codecvt_utf16::do_max_length() const _NOEXCEPT +{ + if (_Mode_ & consume_header) + return 4; + return 2; +} + +// __codecvt_utf16 + +__codecvt_utf16::result +__codecvt_utf16::do_out(state_type&, + const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt, + extern_type* to, extern_type* to_end, extern_type*& to_nxt) const +{ + const uint32_t* _frm = reinterpret_cast(frm); + const uint32_t* _frm_end = reinterpret_cast(frm_end); + const uint32_t* _frm_nxt = _frm; + uint8_t* _to = reinterpret_cast(to); + uint8_t* _to_end = reinterpret_cast(to_end); + uint8_t* _to_nxt = _to; + result r = ucs4_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, + _Maxcode_, _Mode_); + frm_nxt = frm + (_frm_nxt - _frm); + to_nxt = to + (_to_nxt - _to); + return r; +} + +__codecvt_utf16::result +__codecvt_utf16::do_in(state_type&, + const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt, + intern_type* to, intern_type* to_end, intern_type*& to_nxt) const +{ + const uint8_t* _frm = reinterpret_cast(frm); + const uint8_t* _frm_end = reinterpret_cast(frm_end); + const uint8_t* _frm_nxt = _frm; + uint32_t* _to = reinterpret_cast(to); + uint32_t* _to_end = reinterpret_cast(to_end); + uint32_t* _to_nxt = _to; + result r = utf16be_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, + _Maxcode_, _Mode_); + frm_nxt = frm + (_frm_nxt - _frm); + to_nxt = to + (_to_nxt - _to); + return r; +} + +__codecvt_utf16::result +__codecvt_utf16::do_unshift(state_type&, + extern_type* to, extern_type*, extern_type*& to_nxt) const +{ + to_nxt = to; + return noconv; +} + +int +__codecvt_utf16::do_encoding() const _NOEXCEPT +{ + return 0; +} + +bool +__codecvt_utf16::do_always_noconv() const _NOEXCEPT +{ + return false; +} + +int +__codecvt_utf16::do_length(state_type&, + const extern_type* frm, const extern_type* frm_end, size_t mx) const +{ + const uint8_t* _frm = reinterpret_cast(frm); + const uint8_t* _frm_end = reinterpret_cast(frm_end); + return utf16be_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_); +} + +int +__codecvt_utf16::do_max_length() const _NOEXCEPT +{ + if (_Mode_ & consume_header) + return 6; + return 4; +} + +// __codecvt_utf16 + +__codecvt_utf16::result +__codecvt_utf16::do_out(state_type&, + const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt, + extern_type* to, extern_type* to_end, extern_type*& to_nxt) const +{ + const uint32_t* _frm = reinterpret_cast(frm); + const uint32_t* _frm_end = reinterpret_cast(frm_end); + const uint32_t* _frm_nxt = _frm; + uint8_t* _to = reinterpret_cast(to); + uint8_t* _to_end = reinterpret_cast(to_end); + uint8_t* _to_nxt = _to; + result r = ucs4_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, + _Maxcode_, _Mode_); + frm_nxt = frm + (_frm_nxt - _frm); + to_nxt = to + (_to_nxt - _to); + return r; +} + +__codecvt_utf16::result +__codecvt_utf16::do_in(state_type&, + const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt, + intern_type* to, intern_type* to_end, intern_type*& to_nxt) const +{ + const uint8_t* _frm = reinterpret_cast(frm); + const uint8_t* _frm_end = reinterpret_cast(frm_end); + const uint8_t* _frm_nxt = _frm; + uint32_t* _to = reinterpret_cast(to); + uint32_t* _to_end = reinterpret_cast(to_end); + uint32_t* _to_nxt = _to; + result r = utf16le_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, + _Maxcode_, _Mode_); + frm_nxt = frm + (_frm_nxt - _frm); + to_nxt = to + (_to_nxt - _to); + return r; +} + +__codecvt_utf16::result +__codecvt_utf16::do_unshift(state_type&, + extern_type* to, extern_type*, extern_type*& to_nxt) const +{ + to_nxt = to; + return noconv; +} + +int +__codecvt_utf16::do_encoding() const _NOEXCEPT +{ + return 0; +} + +bool +__codecvt_utf16::do_always_noconv() const _NOEXCEPT +{ + return false; +} + +int +__codecvt_utf16::do_length(state_type&, + const extern_type* frm, const extern_type* frm_end, size_t mx) const +{ + const uint8_t* _frm = reinterpret_cast(frm); + const uint8_t* _frm_end = reinterpret_cast(frm_end); + return utf16le_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_); +} + +int +__codecvt_utf16::do_max_length() const _NOEXCEPT +{ + if (_Mode_ & consume_header) + return 6; + return 4; +} + +// __codecvt_utf8_utf16 + +__codecvt_utf8_utf16::result +__codecvt_utf8_utf16::do_out(state_type&, + const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt, + extern_type* to, extern_type* to_end, extern_type*& to_nxt) const +{ + const uint32_t* _frm = reinterpret_cast(frm); + const uint32_t* _frm_end = reinterpret_cast(frm_end); + const uint32_t* _frm_nxt = _frm; + uint8_t* _to = reinterpret_cast(to); + uint8_t* _to_end = reinterpret_cast(to_end); + uint8_t* _to_nxt = _to; + result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, + _Maxcode_, _Mode_); + frm_nxt = frm + (_frm_nxt - _frm); + to_nxt = to + (_to_nxt - _to); + return r; +} + +__codecvt_utf8_utf16::result +__codecvt_utf8_utf16::do_in(state_type&, + const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt, + intern_type* to, intern_type* to_end, intern_type*& to_nxt) const +{ + const uint8_t* _frm = reinterpret_cast(frm); + const uint8_t* _frm_end = reinterpret_cast(frm_end); + const uint8_t* _frm_nxt = _frm; + uint32_t* _to = reinterpret_cast(to); + uint32_t* _to_end = reinterpret_cast(to_end); + uint32_t* _to_nxt = _to; + result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, + _Maxcode_, _Mode_); + frm_nxt = frm + (_frm_nxt - _frm); + to_nxt = to + (_to_nxt - _to); + return r; +} + +__codecvt_utf8_utf16::result +__codecvt_utf8_utf16::do_unshift(state_type&, + extern_type* to, extern_type*, extern_type*& to_nxt) const +{ + to_nxt = to; + return noconv; +} + +int +__codecvt_utf8_utf16::do_encoding() const _NOEXCEPT +{ + return 0; +} + +bool +__codecvt_utf8_utf16::do_always_noconv() const _NOEXCEPT +{ + return false; +} + +int +__codecvt_utf8_utf16::do_length(state_type&, + const extern_type* frm, const extern_type* frm_end, size_t mx) const +{ + const uint8_t* _frm = reinterpret_cast(frm); + const uint8_t* _frm_end = reinterpret_cast(frm_end); + return utf8_to_utf16_length(_frm, _frm_end, mx, _Maxcode_, _Mode_); +} + +int +__codecvt_utf8_utf16::do_max_length() const _NOEXCEPT +{ + if (_Mode_ & consume_header) + return 7; + return 4; +} + +// __codecvt_utf8_utf16 + +__codecvt_utf8_utf16::result +__codecvt_utf8_utf16::do_out(state_type&, + const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt, + extern_type* to, extern_type* to_end, extern_type*& to_nxt) const +{ + const uint16_t* _frm = reinterpret_cast(frm); + const uint16_t* _frm_end = reinterpret_cast(frm_end); + const uint16_t* _frm_nxt = _frm; + uint8_t* _to = reinterpret_cast(to); + uint8_t* _to_end = reinterpret_cast(to_end); + uint8_t* _to_nxt = _to; + result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, + _Maxcode_, _Mode_); + frm_nxt = frm + (_frm_nxt - _frm); + to_nxt = to + (_to_nxt - _to); + return r; +} + +__codecvt_utf8_utf16::result +__codecvt_utf8_utf16::do_in(state_type&, + const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt, + intern_type* to, intern_type* to_end, intern_type*& to_nxt) const +{ + const uint8_t* _frm = reinterpret_cast(frm); + const uint8_t* _frm_end = reinterpret_cast(frm_end); + const uint8_t* _frm_nxt = _frm; + uint16_t* _to = reinterpret_cast(to); + uint16_t* _to_end = reinterpret_cast(to_end); + uint16_t* _to_nxt = _to; + result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, + _Maxcode_, _Mode_); + frm_nxt = frm + (_frm_nxt - _frm); + to_nxt = to + (_to_nxt - _to); + return r; +} + +__codecvt_utf8_utf16::result +__codecvt_utf8_utf16::do_unshift(state_type&, + extern_type* to, extern_type*, extern_type*& to_nxt) const +{ + to_nxt = to; + return noconv; +} + +int +__codecvt_utf8_utf16::do_encoding() const _NOEXCEPT +{ + return 0; +} + +bool +__codecvt_utf8_utf16::do_always_noconv() const _NOEXCEPT +{ + return false; +} + +int +__codecvt_utf8_utf16::do_length(state_type&, + const extern_type* frm, const extern_type* frm_end, size_t mx) const +{ + const uint8_t* _frm = reinterpret_cast(frm); + const uint8_t* _frm_end = reinterpret_cast(frm_end); + return utf8_to_utf16_length(_frm, _frm_end, mx, _Maxcode_, _Mode_); +} + +int +__codecvt_utf8_utf16::do_max_length() const _NOEXCEPT +{ + if (_Mode_ & consume_header) + return 7; + return 4; +} + +// __codecvt_utf8_utf16 + +__codecvt_utf8_utf16::result +__codecvt_utf8_utf16::do_out(state_type&, + const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt, + extern_type* to, extern_type* to_end, extern_type*& to_nxt) const +{ + const uint32_t* _frm = reinterpret_cast(frm); + const uint32_t* _frm_end = reinterpret_cast(frm_end); + const uint32_t* _frm_nxt = _frm; + uint8_t* _to = reinterpret_cast(to); + uint8_t* _to_end = reinterpret_cast(to_end); + uint8_t* _to_nxt = _to; + result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, + _Maxcode_, _Mode_); + frm_nxt = frm + (_frm_nxt - _frm); + to_nxt = to + (_to_nxt - _to); + return r; +} + +__codecvt_utf8_utf16::result +__codecvt_utf8_utf16::do_in(state_type&, + const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt, + intern_type* to, intern_type* to_end, intern_type*& to_nxt) const +{ + const uint8_t* _frm = reinterpret_cast(frm); + const uint8_t* _frm_end = reinterpret_cast(frm_end); + const uint8_t* _frm_nxt = _frm; + uint32_t* _to = reinterpret_cast(to); + uint32_t* _to_end = reinterpret_cast(to_end); + uint32_t* _to_nxt = _to; + result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, + _Maxcode_, _Mode_); + frm_nxt = frm + (_frm_nxt - _frm); + to_nxt = to + (_to_nxt - _to); + return r; +} + +__codecvt_utf8_utf16::result +__codecvt_utf8_utf16::do_unshift(state_type&, + extern_type* to, extern_type*, extern_type*& to_nxt) const +{ + to_nxt = to; + return noconv; +} + +int +__codecvt_utf8_utf16::do_encoding() const _NOEXCEPT +{ + return 0; +} + +bool +__codecvt_utf8_utf16::do_always_noconv() const _NOEXCEPT +{ + return false; +} + +int +__codecvt_utf8_utf16::do_length(state_type&, + const extern_type* frm, const extern_type* frm_end, size_t mx) const +{ + const uint8_t* _frm = reinterpret_cast(frm); + const uint8_t* _frm_end = reinterpret_cast(frm_end); + return utf8_to_utf16_length(_frm, _frm_end, mx, _Maxcode_, _Mode_); +} + +int +__codecvt_utf8_utf16::do_max_length() const _NOEXCEPT +{ + if (_Mode_ & consume_header) + return 7; + return 4; +} + +// __narrow_to_utf8<16> + +__narrow_to_utf8<16>::~__narrow_to_utf8() +{ +} + +// __narrow_to_utf8<32> + +__narrow_to_utf8<32>::~__narrow_to_utf8() +{ +} + +// __widen_from_utf8<16> + +__widen_from_utf8<16>::~__widen_from_utf8() +{ +} + +// __widen_from_utf8<32> + +__widen_from_utf8<32>::~__widen_from_utf8() +{ +} + + +bool __checked_string_to_wchar_convert(wchar_t& dest, + const char* ptr, + locale_t loc) { + if (*ptr == '\0') + return false; + mbstate_t mb = {}; + wchar_t out; + size_t ret = __libcpp_mbrtowc_l(&out, ptr, strlen(ptr), &mb, loc); + if (ret == static_cast(-1) || ret == static_cast(-2)) { + return false; + } + dest = out; + return true; +} + +bool __checked_string_to_char_convert(char& dest, + const char* ptr, + locale_t __loc) { + if (*ptr == '\0') + return false; + if (!ptr[1]) { + dest = *ptr; + return true; + } + // First convert the MBS into a wide char then attempt to narrow it using + // wctob_l. + wchar_t wout; + if (!__checked_string_to_wchar_convert(wout, ptr, __loc)) + return false; + int res; + if ((res = __libcpp_wctob_l(wout, __loc)) != char_traits::eof()) { + dest = res; + return true; + } + // FIXME: Work around specific multibyte sequences that we can reasonable + // translate into a different single byte. + switch (wout) { + case L'\u202F': // narrow non-breaking space + case L'\u00A0': // non-breaking space + dest = ' '; + return true; + default: + return false; + } + _LIBCPP_UNREACHABLE(); +} + + +// numpunct && numpunct + +locale::id numpunct< char >::id; +locale::id numpunct::id; + +numpunct::numpunct(size_t refs) + : locale::facet(refs), + __decimal_point_('.'), + __thousands_sep_(',') +{ +} + +numpunct::numpunct(size_t refs) + : locale::facet(refs), + __decimal_point_(L'.'), + __thousands_sep_(L',') +{ +} + +numpunct::~numpunct() +{ +} + +numpunct::~numpunct() +{ +} + + char numpunct< char >::do_decimal_point() const {return __decimal_point_;} +wchar_t numpunct::do_decimal_point() const {return __decimal_point_;} + + char numpunct< char >::do_thousands_sep() const {return __thousands_sep_;} +wchar_t numpunct::do_thousands_sep() const {return __thousands_sep_;} + +string numpunct< char >::do_grouping() const {return __grouping_;} +string numpunct::do_grouping() const {return __grouping_;} + + string numpunct< char >::do_truename() const {return "true";} +wstring numpunct::do_truename() const {return L"true";} + + string numpunct< char >::do_falsename() const {return "false";} +wstring numpunct::do_falsename() const {return L"false";} + +// numpunct_byname + +numpunct_byname::numpunct_byname(const char* nm, size_t refs) + : numpunct(refs) +{ + __init(nm); +} + +numpunct_byname::numpunct_byname(const string& nm, size_t refs) + : numpunct(refs) +{ + __init(nm.c_str()); +} + +numpunct_byname::~numpunct_byname() +{ +} + +void +numpunct_byname::__init(const char* nm) +{ + if (strcmp(nm, "C") != 0) + { + __libcpp_unique_locale loc(nm); + if (!loc) + __throw_runtime_error("numpunct_byname::numpunct_byname" + " failed to construct for " + string(nm)); + + lconv* lc = __libcpp_localeconv_l(loc.get()); + __checked_string_to_char_convert(__decimal_point_, lc->decimal_point, + loc.get()); + __checked_string_to_char_convert(__thousands_sep_, lc->thousands_sep, + loc.get()); + __grouping_ = lc->grouping; + // localization for truename and falsename is not available + } +} + +// numpunct_byname + +numpunct_byname::numpunct_byname(const char* nm, size_t refs) + : numpunct(refs) +{ + __init(nm); +} + +numpunct_byname::numpunct_byname(const string& nm, size_t refs) + : numpunct(refs) +{ + __init(nm.c_str()); +} + +numpunct_byname::~numpunct_byname() +{ +} + +void +numpunct_byname::__init(const char* nm) +{ + if (strcmp(nm, "C") != 0) + { + __libcpp_unique_locale loc(nm); + if (!loc) + __throw_runtime_error("numpunct_byname::numpunct_byname" + " failed to construct for " + string(nm)); + + lconv* lc = __libcpp_localeconv_l(loc.get()); + __checked_string_to_wchar_convert(__decimal_point_, lc->decimal_point, + loc.get()); + __checked_string_to_wchar_convert(__thousands_sep_, lc->thousands_sep, + loc.get()); + __grouping_ = lc->grouping; + // localization for truename and falsename is not available + } +} + +// num_get helpers + +int +__num_get_base::__get_base(ios_base& iob) +{ + ios_base::fmtflags __basefield = iob.flags() & ios_base::basefield; + if (__basefield == ios_base::oct) + return 8; + else if (__basefield == ios_base::hex) + return 16; + else if (__basefield == 0) + return 0; + return 10; +} + +const char __num_get_base::__src[33] = "0123456789abcdefABCDEFxX+-pPiInN"; + +void +__check_grouping(const string& __grouping, unsigned* __g, unsigned* __g_end, + ios_base::iostate& __err) +{ +// if the grouping pattern is empty _or_ there are no grouping bits, then do nothing +// we always have at least a single entry in [__g, __g_end); the end of the input sequence + if (__grouping.size() != 0 && __g_end - __g > 1) + { + reverse(__g, __g_end); + const char* __ig = __grouping.data(); + const char* __eg = __ig + __grouping.size(); + for (unsigned* __r = __g; __r < __g_end-1; ++__r) + { + if (0 < *__ig && *__ig < numeric_limits::max()) + { + if (static_cast(*__ig) != *__r) + { + __err = ios_base::failbit; + return; + } + } + if (__eg - __ig > 1) + ++__ig; + } + if (0 < *__ig && *__ig < numeric_limits::max()) + { + if (static_cast(*__ig) < __g_end[-1] || __g_end[-1] == 0) + __err = ios_base::failbit; + } + } +} + +void +__num_put_base::__format_int(char* __fmtp, const char* __len, bool __signd, + ios_base::fmtflags __flags) +{ + if (__flags & ios_base::showpos) + *__fmtp++ = '+'; + if (__flags & ios_base::showbase) + *__fmtp++ = '#'; + while(*__len) + *__fmtp++ = *__len++; + if ((__flags & ios_base::basefield) == ios_base::oct) + *__fmtp = 'o'; + else if ((__flags & ios_base::basefield) == ios_base::hex) + { + if (__flags & ios_base::uppercase) + *__fmtp = 'X'; + else + *__fmtp = 'x'; + } + else if (__signd) + *__fmtp = 'd'; + else + *__fmtp = 'u'; +} + +bool +__num_put_base::__format_float(char* __fmtp, const char* __len, + ios_base::fmtflags __flags) +{ + bool specify_precision = true; + if (__flags & ios_base::showpos) + *__fmtp++ = '+'; + if (__flags & ios_base::showpoint) + *__fmtp++ = '#'; + ios_base::fmtflags floatfield = __flags & ios_base::floatfield; + bool uppercase = (__flags & ios_base::uppercase) != 0; + if (floatfield == (ios_base::fixed | ios_base::scientific)) + specify_precision = false; + else + { + *__fmtp++ = '.'; + *__fmtp++ = '*'; + } + while(*__len) + *__fmtp++ = *__len++; + if (floatfield == ios_base::fixed) + { + if (uppercase) + *__fmtp = 'F'; + else + *__fmtp = 'f'; + } + else if (floatfield == ios_base::scientific) + { + if (uppercase) + *__fmtp = 'E'; + else + *__fmtp = 'e'; + } + else if (floatfield == (ios_base::fixed | ios_base::scientific)) + { + if (uppercase) + *__fmtp = 'A'; + else + *__fmtp = 'a'; + } + else + { + if (uppercase) + *__fmtp = 'G'; + else + *__fmtp = 'g'; + } + return specify_precision; +} + +char* +__num_put_base::__identify_padding(char* __nb, char* __ne, + const ios_base& __iob) +{ + switch (__iob.flags() & ios_base::adjustfield) + { + case ios_base::internal: + if (__nb[0] == '-' || __nb[0] == '+') + return __nb+1; + if (__ne - __nb >= 2 && __nb[0] == '0' + && (__nb[1] == 'x' || __nb[1] == 'X')) + return __nb+2; + break; + case ios_base::left: + return __ne; + case ios_base::right: + default: + break; + } + return __nb; +} + +void __do_nothing(void*) {} + +void __throw_runtime_error(const char* msg) +{ +#ifndef _LIBCPP_NO_EXCEPTIONS + throw runtime_error(msg); +#else + (void)msg; + _VSTD::abort(); +#endif +} + +template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS collate; +template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS collate; + +template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS num_get; +template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS num_get; + +template struct _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __num_get; +template struct _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __num_get; + +template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS num_put; +template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS num_put; + +template struct _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __num_put; +template struct _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __num_put; + +template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages; +template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages; + +template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages_byname; +template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages_byname; + +template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname; +template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname; +template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname; +template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname; + +_LIBCPP_END_NAMESPACE_STD diff --git a/third_party/libcxx/locale3.cc b/third_party/libcxx/locale3.cc new file mode 100644 index 000000000..ecc91ef27 --- /dev/null +++ b/third_party/libcxx/locale3.cc @@ -0,0 +1,723 @@ +// clang-format off +//===------------------------- locale.cpp ---------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "third_party/libcxx/string" +#include "third_party/libcxx/locale" +#include "third_party/libcxx/codecvt" +#include "third_party/libcxx/vector" +#include "third_party/libcxx/algorithm" +#include "third_party/libcxx/typeinfo" +#ifndef _LIBCPP_NO_EXCEPTIONS +#include "third_party/libcxx/type_traits" +#endif +#include "third_party/libcxx/clocale" +#include "third_party/libcxx/cstring" +#include "third_party/libcxx/cwctype" +#include "third_party/libcxx/__sso_allocator" +#include "third_party/libcxx/include/atomic_support.hh" +#include "libc/str/locale.h" +#include "third_party/libcxx/countof.internal.hh" +#include "third_party/libcxx/__undef_macros" + +// On Linux, wint_t and wchar_t have different signed-ness, and this causes +// lots of noise in the build log, but no bugs that I know of. +#if defined(__clang__) +#pragma clang diagnostic ignored "-Wsign-conversion" +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace { + +_LIBCPP_NORETURN static void __throw_runtime_error(const string &msg) +{ +#ifndef _LIBCPP_NO_EXCEPTIONS + throw runtime_error(msg); +#else + (void)msg; + _VSTD::abort(); +#endif +} + +} // namespace + +bool __checked_string_to_wchar_convert(wchar_t& dest, + const char* ptr, + locale_t loc); +bool __checked_string_to_char_convert(char& dest, + const char* ptr, + locale_t __loc); + +struct __libcpp_unique_locale { + __libcpp_unique_locale(const char* nm) : __loc_(newlocale(LC_ALL_MASK, nm, 0)) {} + + ~__libcpp_unique_locale() { + if (__loc_) + freelocale(__loc_); + } + + explicit operator bool() const { return __loc_; } + + locale_t& get() { return __loc_; } + + locale_t __loc_; +private: + __libcpp_unique_locale(__libcpp_unique_locale const&); + __libcpp_unique_locale& operator=(__libcpp_unique_locale const&); +}; + +// moneypunct_byname + +template +static +void +__init_pat(money_base::pattern& pat, basic_string& __curr_symbol_, + bool intl, char cs_precedes, char sep_by_space, char sign_posn, + charT space_char) +{ + const char sign = static_cast(money_base::sign); + const char space = static_cast(money_base::space); + const char none = static_cast(money_base::none); + const char symbol = static_cast(money_base::symbol); + const char value = static_cast(money_base::value); + const bool symbol_contains_sep = intl && __curr_symbol_.size() == 4; + + // Comments on case branches reflect 'C11 7.11.2.1 The localeconv + // function'. "Space between sign and symbol or value" means that + // if the sign is adjacent to the symbol, there's a space between + // them, and otherwise there's a space between the sign and value. + // + // C11's localeconv specifies that the fourth character of an + // international curr_symbol is used to separate the sign and + // value when sep_by_space says to do so. C++ can't represent + // that, so we just use a space. When sep_by_space says to + // separate the symbol and value-or-sign with a space, we rearrange the + // curr_symbol to put its spacing character on the correct side of + // the symbol. + // + // We also need to avoid adding an extra space between the sign + // and value when the currency symbol is suppressed (by not + // setting showbase). We match glibc's strfmon by interpreting + // sep_by_space==1 as "omit the space when the currency symbol is + // absent". + // + // Users who want to get this right should use ICU instead. + + switch (cs_precedes) + { + case 0: // value before curr_symbol + if (symbol_contains_sep) { + // Move the separator to before the symbol, to place it + // between the value and symbol. + rotate(__curr_symbol_.begin(), __curr_symbol_.begin() + 3, + __curr_symbol_.end()); + } + switch (sign_posn) + { + case 0: // Parentheses surround the quantity and currency symbol. + pat.field[0] = sign; + pat.field[1] = value; + pat.field[2] = none; // Any space appears in the symbol. + pat.field[3] = symbol; + switch (sep_by_space) + { + case 0: // No space separates the currency symbol and value. + // This case may have changed between C99 and C11; + // assume the currency symbol matches the intention. + case 2: // Space between sign and currency or value. + // The "sign" is two parentheses, so no space here either. + return; + case 1: // Space between currency-and-sign or currency and value. + if (!symbol_contains_sep) { + // We insert the space into the symbol instead of + // setting pat.field[2]=space so that when + // showbase is not set, the space goes away too. + __curr_symbol_.insert(0, 1, space_char); + } + return; + default: + break; + } + break; + case 1: // The sign string precedes the quantity and currency symbol. + pat.field[0] = sign; + pat.field[3] = symbol; + switch (sep_by_space) + { + case 0: // No space separates the currency symbol and value. + pat.field[1] = value; + pat.field[2] = none; + return; + case 1: // Space between currency-and-sign or currency and value. + pat.field[1] = value; + pat.field[2] = none; + if (!symbol_contains_sep) { + // We insert the space into the symbol instead of + // setting pat.field[2]=space so that when + // showbase is not set, the space goes away too. + __curr_symbol_.insert(0, 1, space_char); + } + return; + case 2: // Space between sign and currency or value. + pat.field[1] = space; + pat.field[2] = value; + if (symbol_contains_sep) { + // Remove the separator from the symbol, since it + // has already appeared after the sign. + __curr_symbol_.erase(__curr_symbol_.begin()); + } + return; + default: + break; + } + break; + case 2: // The sign string succeeds the quantity and currency symbol. + pat.field[0] = value; + pat.field[3] = sign; + switch (sep_by_space) + { + case 0: // No space separates the currency symbol and value. + pat.field[1] = none; + pat.field[2] = symbol; + return; + case 1: // Space between currency-and-sign or currency and value. + if (!symbol_contains_sep) { + // We insert the space into the symbol instead of + // setting pat.field[1]=space so that when + // showbase is not set, the space goes away too. + __curr_symbol_.insert(0, 1, space_char); + } + pat.field[1] = none; + pat.field[2] = symbol; + return; + case 2: // Space between sign and currency or value. + pat.field[1] = symbol; + pat.field[2] = space; + if (symbol_contains_sep) { + // Remove the separator from the symbol, since it + // should not be removed if showbase is absent. + __curr_symbol_.erase(__curr_symbol_.begin()); + } + return; + default: + break; + } + break; + case 3: // The sign string immediately precedes the currency symbol. + pat.field[0] = value; + pat.field[3] = symbol; + switch (sep_by_space) + { + case 0: // No space separates the currency symbol and value. + pat.field[1] = none; + pat.field[2] = sign; + return; + case 1: // Space between currency-and-sign or currency and value. + pat.field[1] = space; + pat.field[2] = sign; + if (symbol_contains_sep) { + // Remove the separator from the symbol, since it + // has already appeared before the sign. + __curr_symbol_.erase(__curr_symbol_.begin()); + } + return; + case 2: // Space between sign and currency or value. + pat.field[1] = sign; + pat.field[2] = none; + if (!symbol_contains_sep) { + // We insert the space into the symbol instead of + // setting pat.field[2]=space so that when + // showbase is not set, the space goes away too. + __curr_symbol_.insert(0, 1, space_char); + } + return; + default: + break; + } + break; + case 4: // The sign string immediately succeeds the currency symbol. + pat.field[0] = value; + pat.field[3] = sign; + switch (sep_by_space) + { + case 0: // No space separates the currency symbol and value. + pat.field[1] = none; + pat.field[2] = symbol; + return; + case 1: // Space between currency-and-sign or currency and value. + pat.field[1] = none; + pat.field[2] = symbol; + if (!symbol_contains_sep) { + // We insert the space into the symbol instead of + // setting pat.field[1]=space so that when + // showbase is not set, the space goes away too. + __curr_symbol_.insert(0, 1, space_char); + } + return; + case 2: // Space between sign and currency or value. + pat.field[1] = symbol; + pat.field[2] = space; + if (symbol_contains_sep) { + // Remove the separator from the symbol, since it + // should not disappear when showbase is absent. + __curr_symbol_.erase(__curr_symbol_.begin()); + } + return; + default: + break; + } + break; + default: + break; + } + break; + case 1: // curr_symbol before value + switch (sign_posn) + { + case 0: // Parentheses surround the quantity and currency symbol. + pat.field[0] = sign; + pat.field[1] = symbol; + pat.field[2] = none; // Any space appears in the symbol. + pat.field[3] = value; + switch (sep_by_space) + { + case 0: // No space separates the currency symbol and value. + // This case may have changed between C99 and C11; + // assume the currency symbol matches the intention. + case 2: // Space between sign and currency or value. + // The "sign" is two parentheses, so no space here either. + return; + case 1: // Space between currency-and-sign or currency and value. + if (!symbol_contains_sep) { + // We insert the space into the symbol instead of + // setting pat.field[2]=space so that when + // showbase is not set, the space goes away too. + __curr_symbol_.insert(0, 1, space_char); + } + return; + default: + break; + } + break; + case 1: // The sign string precedes the quantity and currency symbol. + pat.field[0] = sign; + pat.field[3] = value; + switch (sep_by_space) + { + case 0: // No space separates the currency symbol and value. + pat.field[1] = symbol; + pat.field[2] = none; + return; + case 1: // Space between currency-and-sign or currency and value. + pat.field[1] = symbol; + pat.field[2] = none; + if (!symbol_contains_sep) { + // We insert the space into the symbol instead of + // setting pat.field[2]=space so that when + // showbase is not set, the space goes away too. + __curr_symbol_.push_back(space_char); + } + return; + case 2: // Space between sign and currency or value. + pat.field[1] = space; + pat.field[2] = symbol; + if (symbol_contains_sep) { + // Remove the separator from the symbol, since it + // has already appeared after the sign. + __curr_symbol_.pop_back(); + } + return; + default: + break; + } + break; + case 2: // The sign string succeeds the quantity and currency symbol. + pat.field[0] = symbol; + pat.field[3] = sign; + switch (sep_by_space) + { + case 0: // No space separates the currency symbol and value. + pat.field[1] = none; + pat.field[2] = value; + return; + case 1: // Space between currency-and-sign or currency and value. + pat.field[1] = none; + pat.field[2] = value; + if (!symbol_contains_sep) { + // We insert the space into the symbol instead of + // setting pat.field[1]=space so that when + // showbase is not set, the space goes away too. + __curr_symbol_.push_back(space_char); + } + return; + case 2: // Space between sign and currency or value. + pat.field[1] = value; + pat.field[2] = space; + if (symbol_contains_sep) { + // Remove the separator from the symbol, since it + // will appear before the sign. + __curr_symbol_.pop_back(); + } + return; + default: + break; + } + break; + case 3: // The sign string immediately precedes the currency symbol. + pat.field[0] = sign; + pat.field[3] = value; + switch (sep_by_space) + { + case 0: // No space separates the currency symbol and value. + pat.field[1] = symbol; + pat.field[2] = none; + return; + case 1: // Space between currency-and-sign or currency and value. + pat.field[1] = symbol; + pat.field[2] = none; + if (!symbol_contains_sep) { + // We insert the space into the symbol instead of + // setting pat.field[2]=space so that when + // showbase is not set, the space goes away too. + __curr_symbol_.push_back(space_char); + } + return; + case 2: // Space between sign and currency or value. + pat.field[1] = space; + pat.field[2] = symbol; + if (symbol_contains_sep) { + // Remove the separator from the symbol, since it + // has already appeared after the sign. + __curr_symbol_.pop_back(); + } + return; + default: + break; + } + break; + case 4: // The sign string immediately succeeds the currency symbol. + pat.field[0] = symbol; + pat.field[3] = value; + switch (sep_by_space) + { + case 0: // No space separates the currency symbol and value. + pat.field[1] = sign; + pat.field[2] = none; + return; + case 1: // Space between currency-and-sign or currency and value. + pat.field[1] = sign; + pat.field[2] = space; + if (symbol_contains_sep) { + // Remove the separator from the symbol, since it + // should not disappear when showbase is absent. + __curr_symbol_.pop_back(); + } + return; + case 2: // Space between sign and currency or value. + pat.field[1] = none; + pat.field[2] = sign; + if (!symbol_contains_sep) { + // We insert the space into the symbol instead of + // setting pat.field[1]=space so that when + // showbase is not set, the space goes away too. + __curr_symbol_.push_back(space_char); + } + return; + default: + break; + } + break; + default: + break; + } + break; + default: + break; + } + pat.field[0] = symbol; + pat.field[1] = sign; + pat.field[2] = none; + pat.field[3] = value; +} + +template<> +void +moneypunct_byname::init(const char* nm) +{ + typedef moneypunct base; + __libcpp_unique_locale loc(nm); + if (!loc) + __throw_runtime_error("moneypunct_byname" + " failed to construct for " + string(nm)); + + lconv* lc = __libcpp_localeconv_l(loc.get()); + if (!__checked_string_to_char_convert(__decimal_point_, + lc->mon_decimal_point, + loc.get())) + __decimal_point_ = base::do_decimal_point(); + if (!__checked_string_to_char_convert(__thousands_sep_, + lc->mon_thousands_sep, + loc.get())) + __thousands_sep_ = base::do_thousands_sep(); + + __grouping_ = lc->mon_grouping; + __curr_symbol_ = lc->currency_symbol; + if (lc->frac_digits != CHAR_MAX) + __frac_digits_ = lc->frac_digits; + else + __frac_digits_ = base::do_frac_digits(); + if (lc->p_sign_posn == 0) + __positive_sign_ = "()"; + else + __positive_sign_ = lc->positive_sign; + if (lc->n_sign_posn == 0) + __negative_sign_ = "()"; + else + __negative_sign_ = lc->negative_sign; + // Assume the positive and negative formats will want spaces in + // the same places in curr_symbol since there's no way to + // represent anything else. + string_type __dummy_curr_symbol = __curr_symbol_; + __init_pat(__pos_format_, __dummy_curr_symbol, false, + lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, ' '); + __init_pat(__neg_format_, __curr_symbol_, false, + lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, ' '); +} + +template<> +void +moneypunct_byname::init(const char* nm) +{ + typedef moneypunct base; + __libcpp_unique_locale loc(nm); + if (!loc) + __throw_runtime_error("moneypunct_byname" + " failed to construct for " + string(nm)); + + lconv* lc = __libcpp_localeconv_l(loc.get()); + if (!__checked_string_to_char_convert(__decimal_point_, + lc->mon_decimal_point, + loc.get())) + __decimal_point_ = base::do_decimal_point(); + if (!__checked_string_to_char_convert(__thousands_sep_, + lc->mon_thousands_sep, + loc.get())) + __thousands_sep_ = base::do_thousands_sep(); + __grouping_ = lc->mon_grouping; + __curr_symbol_ = lc->int_curr_symbol; + if (lc->int_frac_digits != CHAR_MAX) + __frac_digits_ = lc->int_frac_digits; + else + __frac_digits_ = base::do_frac_digits(); +#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__) + if (lc->p_sign_posn == 0) +#else // _LIBCPP_MSVCRT + if (lc->int_p_sign_posn == 0) +#endif // !_LIBCPP_MSVCRT + __positive_sign_ = "()"; + else + __positive_sign_ = lc->positive_sign; +#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__) + if(lc->n_sign_posn == 0) +#else // _LIBCPP_MSVCRT + if (lc->int_n_sign_posn == 0) +#endif // !_LIBCPP_MSVCRT + __negative_sign_ = "()"; + else + __negative_sign_ = lc->negative_sign; + // Assume the positive and negative formats will want spaces in + // the same places in curr_symbol since there's no way to + // represent anything else. + string_type __dummy_curr_symbol = __curr_symbol_; +#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__) + __init_pat(__pos_format_, __dummy_curr_symbol, true, + lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, ' '); + __init_pat(__neg_format_, __curr_symbol_, true, + lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, ' '); +#else // _LIBCPP_MSVCRT + __init_pat(__pos_format_, __dummy_curr_symbol, true, + lc->int_p_cs_precedes, lc->int_p_sep_by_space, + lc->int_p_sign_posn, ' '); + __init_pat(__neg_format_, __curr_symbol_, true, + lc->int_n_cs_precedes, lc->int_n_sep_by_space, + lc->int_n_sign_posn, ' '); +#endif // !_LIBCPP_MSVCRT +} + +template<> +void +moneypunct_byname::init(const char* nm) +{ + typedef moneypunct base; + __libcpp_unique_locale loc(nm); + if (!loc) + __throw_runtime_error("moneypunct_byname" + " failed to construct for " + string(nm)); + lconv* lc = __libcpp_localeconv_l(loc.get()); + if (!__checked_string_to_wchar_convert(__decimal_point_, + lc->mon_decimal_point, + loc.get())) + __decimal_point_ = base::do_decimal_point(); + if (!__checked_string_to_wchar_convert(__thousands_sep_, + lc->mon_thousands_sep, + loc.get())) + __thousands_sep_ = base::do_thousands_sep(); + __grouping_ = lc->mon_grouping; + wchar_t wbuf[100]; + mbstate_t mb = {0}; + const char* bb = lc->currency_symbol; + size_t j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); + if (j == size_t(-1)) + __throw_runtime_error("locale not supported"); + wchar_t* wbe = wbuf + j; + __curr_symbol_.assign(wbuf, wbe); + if (lc->frac_digits != CHAR_MAX) + __frac_digits_ = lc->frac_digits; + else + __frac_digits_ = base::do_frac_digits(); + if (lc->p_sign_posn == 0) + __positive_sign_ = L"()"; + else + { + mb = mbstate_t(); + bb = lc->positive_sign; + j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); + if (j == size_t(-1)) + __throw_runtime_error("locale not supported"); + wbe = wbuf + j; + __positive_sign_.assign(wbuf, wbe); + } + if (lc->n_sign_posn == 0) + __negative_sign_ = L"()"; + else + { + mb = mbstate_t(); + bb = lc->negative_sign; + j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); + if (j == size_t(-1)) + __throw_runtime_error("locale not supported"); + wbe = wbuf + j; + __negative_sign_.assign(wbuf, wbe); + } + // Assume the positive and negative formats will want spaces in + // the same places in curr_symbol since there's no way to + // represent anything else. + string_type __dummy_curr_symbol = __curr_symbol_; + __init_pat(__pos_format_, __dummy_curr_symbol, false, + lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, L' '); + __init_pat(__neg_format_, __curr_symbol_, false, + lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, L' '); +} + +template<> +void +moneypunct_byname::init(const char* nm) +{ + typedef moneypunct base; + __libcpp_unique_locale loc(nm); + if (!loc) + __throw_runtime_error("moneypunct_byname" + " failed to construct for " + string(nm)); + + lconv* lc = __libcpp_localeconv_l(loc.get()); + if (!__checked_string_to_wchar_convert(__decimal_point_, + lc->mon_decimal_point, + loc.get())) + __decimal_point_ = base::do_decimal_point(); + if (!__checked_string_to_wchar_convert(__thousands_sep_, + lc->mon_thousands_sep, + loc.get())) + __thousands_sep_ = base::do_thousands_sep(); + __grouping_ = lc->mon_grouping; + wchar_t wbuf[100]; + mbstate_t mb = {0}; + const char* bb = lc->int_curr_symbol; + size_t j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); + if (j == size_t(-1)) + __throw_runtime_error("locale not supported"); + wchar_t* wbe = wbuf + j; + __curr_symbol_.assign(wbuf, wbe); + if (lc->int_frac_digits != CHAR_MAX) + __frac_digits_ = lc->int_frac_digits; + else + __frac_digits_ = base::do_frac_digits(); +#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__) + if (lc->p_sign_posn == 0) +#else // _LIBCPP_MSVCRT + if (lc->int_p_sign_posn == 0) +#endif // !_LIBCPP_MSVCRT + __positive_sign_ = L"()"; + else + { + mb = mbstate_t(); + bb = lc->positive_sign; + j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); + if (j == size_t(-1)) + __throw_runtime_error("locale not supported"); + wbe = wbuf + j; + __positive_sign_.assign(wbuf, wbe); + } +#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__) + if (lc->n_sign_posn == 0) +#else // _LIBCPP_MSVCRT + if (lc->int_n_sign_posn == 0) +#endif // !_LIBCPP_MSVCRT + __negative_sign_ = L"()"; + else + { + mb = mbstate_t(); + bb = lc->negative_sign; + j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); + if (j == size_t(-1)) + __throw_runtime_error("locale not supported"); + wbe = wbuf + j; + __negative_sign_.assign(wbuf, wbe); + } + // Assume the positive and negative formats will want spaces in + // the same places in curr_symbol since there's no way to + // represent anything else. + string_type __dummy_curr_symbol = __curr_symbol_; +#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__) + __init_pat(__pos_format_, __dummy_curr_symbol, true, + lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, L' '); + __init_pat(__neg_format_, __curr_symbol_, true, + lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, L' '); +#else // _LIBCPP_MSVCRT + __init_pat(__pos_format_, __dummy_curr_symbol, true, + lc->int_p_cs_precedes, lc->int_p_sep_by_space, + lc->int_p_sign_posn, L' '); + __init_pat(__neg_format_, __curr_symbol_, true, + lc->int_n_cs_precedes, lc->int_n_sep_by_space, + lc->int_n_sign_posn, L' '); +#endif // !_LIBCPP_MSVCRT +} + +template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct; +template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct; +template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct; +template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct; + +template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname; +template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname; +template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname; +template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname; + +template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_get; +template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_get; + +template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_get; +template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_get; + +template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_put; +template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_put; + +template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_put; +template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_put; + +_LIBCPP_END_NAMESPACE_STD diff --git a/third_party/libcxx/locale4.cc b/third_party/libcxx/locale4.cc new file mode 100644 index 000000000..0809bc0a7 --- /dev/null +++ b/third_party/libcxx/locale4.cc @@ -0,0 +1,1010 @@ +// clang-format off +//===------------------------- locale.cpp ---------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "third_party/libcxx/string" +#include "third_party/libcxx/locale" +#include "third_party/libcxx/codecvt" +#include "third_party/libcxx/vector" +#include "third_party/libcxx/algorithm" +#include "third_party/libcxx/typeinfo" +#ifndef _LIBCPP_NO_EXCEPTIONS +#include "third_party/libcxx/type_traits" +#endif +#include "third_party/libcxx/clocale" +#include "third_party/libcxx/cstring" +#include "third_party/libcxx/cwctype" +#include "third_party/libcxx/__sso_allocator" +#include "third_party/libcxx/include/atomic_support.hh" +#include "libc/str/locale.h" +#include "third_party/libcxx/countof.internal.hh" +#include "third_party/libcxx/__undef_macros" + +// On Linux, wint_t and wchar_t have different signed-ness, and this causes +// lots of noise in the build log, but no bugs that I know of. +#if defined(__clang__) +#pragma clang diagnostic ignored "-Wsign-conversion" +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace { + +_LIBCPP_NORETURN static void __throw_runtime_error(const string &msg) +{ +#ifndef _LIBCPP_NO_EXCEPTIONS + throw runtime_error(msg); +#else + (void)msg; + _VSTD::abort(); +#endif +} + +} // namespace + +// time_get + +static +string* +init_weeks() +{ + static string weeks[14]; + weeks[0] = "Sunday"; + weeks[1] = "Monday"; + weeks[2] = "Tuesday"; + weeks[3] = "Wednesday"; + weeks[4] = "Thursday"; + weeks[5] = "Friday"; + weeks[6] = "Saturday"; + weeks[7] = "Sun"; + weeks[8] = "Mon"; + weeks[9] = "Tue"; + weeks[10] = "Wed"; + weeks[11] = "Thu"; + weeks[12] = "Fri"; + weeks[13] = "Sat"; + return weeks; +} + +static +wstring* +init_wweeks() +{ + static wstring weeks[14]; + weeks[0] = L"Sunday"; + weeks[1] = L"Monday"; + weeks[2] = L"Tuesday"; + weeks[3] = L"Wednesday"; + weeks[4] = L"Thursday"; + weeks[5] = L"Friday"; + weeks[6] = L"Saturday"; + weeks[7] = L"Sun"; + weeks[8] = L"Mon"; + weeks[9] = L"Tue"; + weeks[10] = L"Wed"; + weeks[11] = L"Thu"; + weeks[12] = L"Fri"; + weeks[13] = L"Sat"; + return weeks; +} + +template <> +const string* +__time_get_c_storage::__weeks() const +{ + static const string* weeks = init_weeks(); + return weeks; +} + +template <> +const wstring* +__time_get_c_storage::__weeks() const +{ + static const wstring* weeks = init_wweeks(); + return weeks; +} + +static +string* +init_months() +{ + static string months[24]; + months[0] = "January"; + months[1] = "February"; + months[2] = "March"; + months[3] = "April"; + months[4] = "May"; + months[5] = "June"; + months[6] = "July"; + months[7] = "August"; + months[8] = "September"; + months[9] = "October"; + months[10] = "November"; + months[11] = "December"; + months[12] = "Jan"; + months[13] = "Feb"; + months[14] = "Mar"; + months[15] = "Apr"; + months[16] = "May"; + months[17] = "Jun"; + months[18] = "Jul"; + months[19] = "Aug"; + months[20] = "Sep"; + months[21] = "Oct"; + months[22] = "Nov"; + months[23] = "Dec"; + return months; +} + +static +wstring* +init_wmonths() +{ + static wstring months[24]; + months[0] = L"January"; + months[1] = L"February"; + months[2] = L"March"; + months[3] = L"April"; + months[4] = L"May"; + months[5] = L"June"; + months[6] = L"July"; + months[7] = L"August"; + months[8] = L"September"; + months[9] = L"October"; + months[10] = L"November"; + months[11] = L"December"; + months[12] = L"Jan"; + months[13] = L"Feb"; + months[14] = L"Mar"; + months[15] = L"Apr"; + months[16] = L"May"; + months[17] = L"Jun"; + months[18] = L"Jul"; + months[19] = L"Aug"; + months[20] = L"Sep"; + months[21] = L"Oct"; + months[22] = L"Nov"; + months[23] = L"Dec"; + return months; +} + +template <> +const string* +__time_get_c_storage::__months() const +{ + static const string* months = init_months(); + return months; +} + +template <> +const wstring* +__time_get_c_storage::__months() const +{ + static const wstring* months = init_wmonths(); + return months; +} + +static +string* +init_am_pm() +{ + static string am_pm[2]; + am_pm[0] = "AM"; + am_pm[1] = "PM"; + return am_pm; +} + +static +wstring* +init_wam_pm() +{ + static wstring am_pm[2]; + am_pm[0] = L"AM"; + am_pm[1] = L"PM"; + return am_pm; +} + +template <> +const string* +__time_get_c_storage::__am_pm() const +{ + static const string* am_pm = init_am_pm(); + return am_pm; +} + +template <> +const wstring* +__time_get_c_storage::__am_pm() const +{ + static const wstring* am_pm = init_wam_pm(); + return am_pm; +} + +template <> +const string& +__time_get_c_storage::__x() const +{ + static string s("%m/%d/%y"); + return s; +} + +template <> +const wstring& +__time_get_c_storage::__x() const +{ + static wstring s(L"%m/%d/%y"); + return s; +} + +template <> +const string& +__time_get_c_storage::__X() const +{ + static string s("%H:%M:%S"); + return s; +} + +template <> +const wstring& +__time_get_c_storage::__X() const +{ + static wstring s(L"%H:%M:%S"); + return s; +} + +template <> +const string& +__time_get_c_storage::__c() const +{ + static string s("%a %b %d %H:%M:%S %Y"); + return s; +} + +template <> +const wstring& +__time_get_c_storage::__c() const +{ + static wstring s(L"%a %b %d %H:%M:%S %Y"); + return s; +} + +template <> +const string& +__time_get_c_storage::__r() const +{ + static string s("%I:%M:%S %p"); + return s; +} + +template <> +const wstring& +__time_get_c_storage::__r() const +{ + static wstring s(L"%I:%M:%S %p"); + return s; +} + +// time_get_byname + +__time_get::__time_get(const char* nm) + : __loc_(newlocale(LC_ALL_MASK, nm, 0)) +{ + if (__loc_ == 0) + __throw_runtime_error("time_get_byname" + " failed to construct for " + string(nm)); +} + +__time_get::__time_get(const string& nm) + : __loc_(newlocale(LC_ALL_MASK, nm.c_str(), 0)) +{ + if (__loc_ == 0) + __throw_runtime_error("time_get_byname" + " failed to construct for " + nm); +} + +__time_get::~__time_get() +{ + freelocale(__loc_); +} +#if defined(__clang__) +#pragma clang diagnostic ignored "-Wmissing-field-initializers" +#endif +#if defined(__GNUG__) +#pragma GCC diagnostic ignored "-Wmissing-field-initializers" +#endif + +template <> +string +__time_get_storage::__analyze(char fmt, const ctype& ct) +{ + tm t = {0}; + t.tm_sec = 59; + t.tm_min = 55; + t.tm_hour = 23; + t.tm_mday = 31; + t.tm_mon = 11; + t.tm_year = 161; + t.tm_wday = 6; + t.tm_yday = 364; + t.tm_isdst = -1; + char buf[100]; + char f[3] = {0}; + f[0] = '%'; + f[1] = fmt; + size_t n = strftime_l(buf, countof(buf), f, &t, __loc_); + char* bb = buf; + char* be = buf + n; + string result; + while (bb != be) + { + if (ct.is(ctype_base::space, *bb)) + { + result.push_back(' '); + for (++bb; bb != be && ct.is(ctype_base::space, *bb); ++bb) + ; + continue; + } + char* w = bb; + ios_base::iostate err = ios_base::goodbit; + ptrdiff_t i = __scan_keyword(w, be, this->__weeks_, this->__weeks_+14, + ct, err, false) + - this->__weeks_; + if (i < 14) + { + result.push_back('%'); + if (i < 7) + result.push_back('A'); + else + result.push_back('a'); + bb = w; + continue; + } + w = bb; + i = __scan_keyword(w, be, this->__months_, this->__months_+24, + ct, err, false) + - this->__months_; + if (i < 24) + { + result.push_back('%'); + if (i < 12) + result.push_back('B'); + else + result.push_back('b'); + if (fmt == 'x' && ct.is(ctype_base::digit, this->__months_[i][0])) + result.back() = 'm'; + bb = w; + continue; + } + if (this->__am_pm_[0].size() + this->__am_pm_[1].size() > 0) + { + w = bb; + i = __scan_keyword(w, be, this->__am_pm_, this->__am_pm_+2, + ct, err, false) - this->__am_pm_; + if (i < 2) + { + result.push_back('%'); + result.push_back('p'); + bb = w; + continue; + } + } + w = bb; + if (ct.is(ctype_base::digit, *bb)) + { + switch(__get_up_to_n_digits(bb, be, err, ct, 4)) + { + case 6: + result.push_back('%'); + result.push_back('w'); + break; + case 7: + result.push_back('%'); + result.push_back('u'); + break; + case 11: + result.push_back('%'); + result.push_back('I'); + break; + case 12: + result.push_back('%'); + result.push_back('m'); + break; + case 23: + result.push_back('%'); + result.push_back('H'); + break; + case 31: + result.push_back('%'); + result.push_back('d'); + break; + case 55: + result.push_back('%'); + result.push_back('M'); + break; + case 59: + result.push_back('%'); + result.push_back('S'); + break; + case 61: + result.push_back('%'); + result.push_back('y'); + break; + case 364: + result.push_back('%'); + result.push_back('j'); + break; + case 2061: + result.push_back('%'); + result.push_back('Y'); + break; + default: + for (; w != bb; ++w) + result.push_back(*w); + break; + } + continue; + } + if (*bb == '%') + { + result.push_back('%'); + result.push_back('%'); + ++bb; + continue; + } + result.push_back(*bb); + ++bb; + } + return result; +} + +#if defined(__clang__) +#pragma clang diagnostic ignored "-Wmissing-braces" +#endif + +template <> +wstring +__time_get_storage::__analyze(char fmt, const ctype& ct) +{ + tm t = {0}; + t.tm_sec = 59; + t.tm_min = 55; + t.tm_hour = 23; + t.tm_mday = 31; + t.tm_mon = 11; + t.tm_year = 161; + t.tm_wday = 6; + t.tm_yday = 364; + t.tm_isdst = -1; + char buf[100]; + char f[3] = {0}; + f[0] = '%'; + f[1] = fmt; + strftime_l(buf, countof(buf), f, &t, __loc_); + wchar_t wbuf[100]; + wchar_t* wbb = wbuf; + mbstate_t mb = {0}; + const char* bb = buf; + size_t j = __libcpp_mbsrtowcs_l( wbb, &bb, countof(wbuf), &mb, __loc_); + if (j == size_t(-1)) + __throw_runtime_error("locale not supported"); + wchar_t* wbe = wbb + j; + wstring result; + while (wbb != wbe) + { + if (ct.is(ctype_base::space, *wbb)) + { + result.push_back(L' '); + for (++wbb; wbb != wbe && ct.is(ctype_base::space, *wbb); ++wbb) + ; + continue; + } + wchar_t* w = wbb; + ios_base::iostate err = ios_base::goodbit; + ptrdiff_t i = __scan_keyword(w, wbe, this->__weeks_, this->__weeks_+14, + ct, err, false) + - this->__weeks_; + if (i < 14) + { + result.push_back(L'%'); + if (i < 7) + result.push_back(L'A'); + else + result.push_back(L'a'); + wbb = w; + continue; + } + w = wbb; + i = __scan_keyword(w, wbe, this->__months_, this->__months_+24, + ct, err, false) + - this->__months_; + if (i < 24) + { + result.push_back(L'%'); + if (i < 12) + result.push_back(L'B'); + else + result.push_back(L'b'); + if (fmt == 'x' && ct.is(ctype_base::digit, this->__months_[i][0])) + result.back() = L'm'; + wbb = w; + continue; + } + if (this->__am_pm_[0].size() + this->__am_pm_[1].size() > 0) + { + w = wbb; + i = __scan_keyword(w, wbe, this->__am_pm_, this->__am_pm_+2, + ct, err, false) - this->__am_pm_; + if (i < 2) + { + result.push_back(L'%'); + result.push_back(L'p'); + wbb = w; + continue; + } + } + w = wbb; + if (ct.is(ctype_base::digit, *wbb)) + { + switch(__get_up_to_n_digits(wbb, wbe, err, ct, 4)) + { + case 6: + result.push_back(L'%'); + result.push_back(L'w'); + break; + case 7: + result.push_back(L'%'); + result.push_back(L'u'); + break; + case 11: + result.push_back(L'%'); + result.push_back(L'I'); + break; + case 12: + result.push_back(L'%'); + result.push_back(L'm'); + break; + case 23: + result.push_back(L'%'); + result.push_back(L'H'); + break; + case 31: + result.push_back(L'%'); + result.push_back(L'd'); + break; + case 55: + result.push_back(L'%'); + result.push_back(L'M'); + break; + case 59: + result.push_back(L'%'); + result.push_back(L'S'); + break; + case 61: + result.push_back(L'%'); + result.push_back(L'y'); + break; + case 364: + result.push_back(L'%'); + result.push_back(L'j'); + break; + case 2061: + result.push_back(L'%'); + result.push_back(L'Y'); + break; + default: + for (; w != wbb; ++w) + result.push_back(*w); + break; + } + continue; + } + if (ct.narrow(*wbb, 0) == '%') + { + result.push_back(L'%'); + result.push_back(L'%'); + ++wbb; + continue; + } + result.push_back(*wbb); + ++wbb; + } + return result; +} + +template <> +void +__time_get_storage::init(const ctype& ct) +{ + tm t = {0}; + char buf[100]; + // __weeks_ + for (int i = 0; i < 7; ++i) + { + t.tm_wday = i; + strftime_l(buf, countof(buf), "%A", &t, __loc_); + __weeks_[i] = buf; + strftime_l(buf, countof(buf), "%a", &t, __loc_); + __weeks_[i+7] = buf; + } + // __months_ + for (int i = 0; i < 12; ++i) + { + t.tm_mon = i; + strftime_l(buf, countof(buf), "%B", &t, __loc_); + __months_[i] = buf; + strftime_l(buf, countof(buf), "%b", &t, __loc_); + __months_[i+12] = buf; + } + // __am_pm_ + t.tm_hour = 1; + strftime_l(buf, countof(buf), "%p", &t, __loc_); + __am_pm_[0] = buf; + t.tm_hour = 13; + strftime_l(buf, countof(buf), "%p", &t, __loc_); + __am_pm_[1] = buf; + __c_ = __analyze('c', ct); + __r_ = __analyze('r', ct); + __x_ = __analyze('x', ct); + __X_ = __analyze('X', ct); +} + +template <> +void +__time_get_storage::init(const ctype& ct) +{ + tm t = {0}; + char buf[100]; + wchar_t wbuf[100]; + wchar_t* wbe; + mbstate_t mb = {0}; + // __weeks_ + for (int i = 0; i < 7; ++i) + { + t.tm_wday = i; + strftime_l(buf, countof(buf), "%A", &t, __loc_); + mb = mbstate_t(); + const char* bb = buf; + size_t j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); + if (j == size_t(-1)) + __throw_runtime_error("locale not supported"); + wbe = wbuf + j; + __weeks_[i].assign(wbuf, wbe); + strftime_l(buf, countof(buf), "%a", &t, __loc_); + mb = mbstate_t(); + bb = buf; + j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); + if (j == size_t(-1)) + __throw_runtime_error("locale not supported"); + wbe = wbuf + j; + __weeks_[i+7].assign(wbuf, wbe); + } + // __months_ + for (int i = 0; i < 12; ++i) + { + t.tm_mon = i; + strftime_l(buf, countof(buf), "%B", &t, __loc_); + mb = mbstate_t(); + const char* bb = buf; + size_t j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); + if (j == size_t(-1)) + __throw_runtime_error("locale not supported"); + wbe = wbuf + j; + __months_[i].assign(wbuf, wbe); + strftime_l(buf, countof(buf), "%b", &t, __loc_); + mb = mbstate_t(); + bb = buf; + j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); + if (j == size_t(-1)) + __throw_runtime_error("locale not supported"); + wbe = wbuf + j; + __months_[i+12].assign(wbuf, wbe); + } + // __am_pm_ + t.tm_hour = 1; + strftime_l(buf, countof(buf), "%p", &t, __loc_); + mb = mbstate_t(); + const char* bb = buf; + size_t j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); + if (j == size_t(-1)) + __throw_runtime_error("locale not supported"); + wbe = wbuf + j; + __am_pm_[0].assign(wbuf, wbe); + t.tm_hour = 13; + strftime_l(buf, countof(buf), "%p", &t, __loc_); + mb = mbstate_t(); + bb = buf; + j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); + if (j == size_t(-1)) + __throw_runtime_error("locale not supported"); + wbe = wbuf + j; + __am_pm_[1].assign(wbuf, wbe); + __c_ = __analyze('c', ct); + __r_ = __analyze('r', ct); + __x_ = __analyze('x', ct); + __X_ = __analyze('X', ct); +} + +template +struct _LIBCPP_HIDDEN __time_get_temp + : public ctype_byname +{ + explicit __time_get_temp(const char* nm) + : ctype_byname(nm, 1) {} + explicit __time_get_temp(const string& nm) + : ctype_byname(nm, 1) {} +}; + +template <> +__time_get_storage::__time_get_storage(const char* __nm) + : __time_get(__nm) +{ + const __time_get_temp ct(__nm); + init(ct); +} + +template <> +__time_get_storage::__time_get_storage(const string& __nm) + : __time_get(__nm) +{ + const __time_get_temp ct(__nm); + init(ct); +} + +template <> +__time_get_storage::__time_get_storage(const char* __nm) + : __time_get(__nm) +{ + const __time_get_temp ct(__nm); + init(ct); +} + +template <> +__time_get_storage::__time_get_storage(const string& __nm) + : __time_get(__nm) +{ + const __time_get_temp ct(__nm); + init(ct); +} + +template <> +time_base::dateorder +__time_get_storage::__do_date_order() const +{ + unsigned i; + for (i = 0; i < __x_.size(); ++i) + if (__x_[i] == '%') + break; + ++i; + switch (__x_[i]) + { + case 'y': + case 'Y': + for (++i; i < __x_.size(); ++i) + if (__x_[i] == '%') + break; + if (i == __x_.size()) + break; + ++i; + switch (__x_[i]) + { + case 'm': + for (++i; i < __x_.size(); ++i) + if (__x_[i] == '%') + break; + if (i == __x_.size()) + break; + ++i; + if (__x_[i] == 'd') + return time_base::ymd; + break; + case 'd': + for (++i; i < __x_.size(); ++i) + if (__x_[i] == '%') + break; + if (i == __x_.size()) + break; + ++i; + if (__x_[i] == 'm') + return time_base::ydm; + break; + } + break; + case 'm': + for (++i; i < __x_.size(); ++i) + if (__x_[i] == '%') + break; + if (i == __x_.size()) + break; + ++i; + if (__x_[i] == 'd') + { + for (++i; i < __x_.size(); ++i) + if (__x_[i] == '%') + break; + if (i == __x_.size()) + break; + ++i; + if (__x_[i] == 'y' || __x_[i] == 'Y') + return time_base::mdy; + break; + } + break; + case 'd': + for (++i; i < __x_.size(); ++i) + if (__x_[i] == '%') + break; + if (i == __x_.size()) + break; + ++i; + if (__x_[i] == 'm') + { + for (++i; i < __x_.size(); ++i) + if (__x_[i] == '%') + break; + if (i == __x_.size()) + break; + ++i; + if (__x_[i] == 'y' || __x_[i] == 'Y') + return time_base::dmy; + break; + } + break; + } + return time_base::no_order; +} + +template <> +time_base::dateorder +__time_get_storage::__do_date_order() const +{ + unsigned i; + for (i = 0; i < __x_.size(); ++i) + if (__x_[i] == L'%') + break; + ++i; + switch (__x_[i]) + { + case L'y': + case L'Y': + for (++i; i < __x_.size(); ++i) + if (__x_[i] == L'%') + break; + if (i == __x_.size()) + break; + ++i; + switch (__x_[i]) + { + case L'm': + for (++i; i < __x_.size(); ++i) + if (__x_[i] == L'%') + break; + if (i == __x_.size()) + break; + ++i; + if (__x_[i] == L'd') + return time_base::ymd; + break; + case L'd': + for (++i; i < __x_.size(); ++i) + if (__x_[i] == L'%') + break; + if (i == __x_.size()) + break; + ++i; + if (__x_[i] == L'm') + return time_base::ydm; + break; + } + break; + case L'm': + for (++i; i < __x_.size(); ++i) + if (__x_[i] == L'%') + break; + if (i == __x_.size()) + break; + ++i; + if (__x_[i] == L'd') + { + for (++i; i < __x_.size(); ++i) + if (__x_[i] == L'%') + break; + if (i == __x_.size()) + break; + ++i; + if (__x_[i] == L'y' || __x_[i] == L'Y') + return time_base::mdy; + break; + } + break; + case L'd': + for (++i; i < __x_.size(); ++i) + if (__x_[i] == L'%') + break; + if (i == __x_.size()) + break; + ++i; + if (__x_[i] == L'm') + { + for (++i; i < __x_.size(); ++i) + if (__x_[i] == L'%') + break; + if (i == __x_.size()) + break; + ++i; + if (__x_[i] == L'y' || __x_[i] == L'Y') + return time_base::dmy; + break; + } + break; + } + return time_base::no_order; +} + +// time_put + +__time_put::__time_put(const char* nm) + : __loc_(newlocale(LC_ALL_MASK, nm, 0)) +{ + if (__loc_ == 0) + __throw_runtime_error("time_put_byname" + " failed to construct for " + string(nm)); +} + +__time_put::__time_put(const string& nm) + : __loc_(newlocale(LC_ALL_MASK, nm.c_str(), 0)) +{ + if (__loc_ == 0) + __throw_runtime_error("time_put_byname" + " failed to construct for " + nm); +} + +__time_put::~__time_put() +{ + if (__loc_ != _LIBCPP_GET_C_LOCALE) + freelocale(__loc_); +} + +void +__time_put::__do_put(char* __nb, char*& __ne, const tm* __tm, + char __fmt, char __mod) const +{ + char fmt[] = {'%', __fmt, __mod, 0}; + if (__mod != 0) + swap(fmt[1], fmt[2]); + size_t n = strftime_l(__nb, countof(__nb, __ne), fmt, __tm, __loc_); + __ne = __nb + n; +} + +void +__time_put::__do_put(wchar_t* __wb, wchar_t*& __we, const tm* __tm, + char __fmt, char __mod) const +{ + char __nar[100]; + char* __ne = __nar + 100; + __do_put(__nar, __ne, __tm, __fmt, __mod); + mbstate_t mb = {0}; + const char* __nb = __nar; + size_t j = __libcpp_mbsrtowcs_l(__wb, &__nb, countof(__wb, __we), &mb, __loc_); + if (j == size_t(-1)) + __throw_runtime_error("locale not supported"); + __we = __wb + j; +} + +template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_get; +template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_get; + +template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_get_byname; +template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_get_byname; + +template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_put; +template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_put; + +template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_put_byname; +template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_put_byname; + +_LIBCPP_END_NAMESPACE_STD diff --git a/third_party/libcxx/regex b/third_party/libcxx/regex new file mode 100644 index 000000000..d53a5f924 --- /dev/null +++ b/third_party/libcxx/regex @@ -0,0 +1,6663 @@ +// -*- C++ -*- +// clang-format off +//===--------------------------- regex ------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_REGEX +#define _LIBCPP_REGEX + +/* + regex synopsis + +#include "third_party/libcxx/initializer_list" + +namespace std +{ + +namespace regex_constants +{ + +emum syntax_option_type +{ + icase = unspecified, + nosubs = unspecified, + optimize = unspecified, + collate = unspecified, + ECMAScript = unspecified, + basic = unspecified, + extended = unspecified, + awk = unspecified, + grep = unspecified, + egrep = unspecified +}; + +constexpr syntax_option_type operator~(syntax_option_type f); +constexpr syntax_option_type operator&(syntax_option_type lhs, syntax_option_type rhs); +constexpr syntax_option_type operator|(syntax_option_type lhs, syntax_option_type rhs); + +enum match_flag_type +{ + match_default = 0, + match_not_bol = unspecified, + match_not_eol = unspecified, + match_not_bow = unspecified, + match_not_eow = unspecified, + match_any = unspecified, + match_not_null = unspecified, + match_continuous = unspecified, + match_prev_avail = unspecified, + format_default = 0, + format_sed = unspecified, + format_no_copy = unspecified, + format_first_only = unspecified +}; + +constexpr match_flag_type operator~(match_flag_type f); +constexpr match_flag_type operator&(match_flag_type lhs, match_flag_type rhs); +constexpr match_flag_type operator|(match_flag_type lhs, match_flag_type rhs); + +enum error_type +{ + error_collate = unspecified, + error_ctype = unspecified, + error_escape = unspecified, + error_backref = unspecified, + error_brack = unspecified, + error_paren = unspecified, + error_brace = unspecified, + error_badbrace = unspecified, + error_range = unspecified, + error_space = unspecified, + error_badrepeat = unspecified, + error_complexity = unspecified, + error_stack = unspecified +}; + +} // regex_constants + +class regex_error + : public runtime_error +{ +public: + explicit regex_error(regex_constants::error_type ecode); + regex_constants::error_type code() const; +}; + +template +struct regex_traits +{ +public: + typedef charT char_type; + typedef basic_string string_type; + typedef locale locale_type; + typedef /bitmask_type/ char_class_type; + + regex_traits(); + + static size_t length(const char_type* p); + charT translate(charT c) const; + charT translate_nocase(charT c) const; + template + string_type + transform(ForwardIterator first, ForwardIterator last) const; + template + string_type + transform_primary( ForwardIterator first, ForwardIterator last) const; + template + string_type + lookup_collatename(ForwardIterator first, ForwardIterator last) const; + template + char_class_type + lookup_classname(ForwardIterator first, ForwardIterator last, + bool icase = false) const; + bool isctype(charT c, char_class_type f) const; + int value(charT ch, int radix) const; + locale_type imbue(locale_type l); + locale_type getloc()const; +}; + +template > +class basic_regex +{ +public: + // types: + typedef charT value_type; + typedef traits traits_type; + typedef typename traits::string_type string_type; + typedef regex_constants::syntax_option_type flag_type; + typedef typename traits::locale_type locale_type; + + // constants: + static constexpr regex_constants::syntax_option_type icase = regex_constants::icase; + static constexpr regex_constants::syntax_option_type nosubs = regex_constants::nosubs; + static constexpr regex_constants::syntax_option_type optimize = regex_constants::optimize; + static constexpr regex_constants::syntax_option_type collate = regex_constants::collate; + static constexpr regex_constants::syntax_option_type ECMAScript = regex_constants::ECMAScript; + static constexpr regex_constants::syntax_option_type basic = regex_constants::basic; + static constexpr regex_constants::syntax_option_type extended = regex_constants::extended; + static constexpr regex_constants::syntax_option_type awk = regex_constants::awk; + static constexpr regex_constants::syntax_option_type grep = regex_constants::grep; + static constexpr regex_constants::syntax_option_type egrep = regex_constants::egrep; + + // construct/copy/destroy: + basic_regex(); + explicit basic_regex(const charT* p, flag_type f = regex_constants::ECMAScript); + basic_regex(const charT* p, size_t len, flag_type f = regex_constants::ECMAScript); + basic_regex(const basic_regex&); + basic_regex(basic_regex&&) noexcept; + template + explicit basic_regex(const basic_string& p, + flag_type f = regex_constants::ECMAScript); + template + basic_regex(ForwardIterator first, ForwardIterator last, + flag_type f = regex_constants::ECMAScript); + basic_regex(initializer_list, flag_type = regex_constants::ECMAScript); + + ~basic_regex(); + + basic_regex& operator=(const basic_regex&); + basic_regex& operator=(basic_regex&&) noexcept; + basic_regex& operator=(const charT* ptr); + basic_regex& operator=(initializer_list il); + template + basic_regex& operator=(const basic_string& p); + + // assign: + basic_regex& assign(const basic_regex& that); + basic_regex& assign(basic_regex&& that) noexcept; + basic_regex& assign(const charT* ptr, flag_type f = regex_constants::ECMAScript); + basic_regex& assign(const charT* p, size_t len, flag_type f = regex_constants::ECMAScript); + template + basic_regex& assign(const basic_string& s, + flag_type f = regex_constants::ECMAScript); + template + basic_regex& assign(InputIterator first, InputIterator last, + flag_type f = regex_constants::ECMAScript); + basic_regex& assign(initializer_list, flag_type f = regex_constants::ECMAScript); + + // const operations: + unsigned mark_count() const; + flag_type flags() const; + + // locale: + locale_type imbue(locale_type loc); + locale_type getloc() const; + + // swap: + void swap(basic_regex&); +}; + +template +basic_regex(ForwardIterator, ForwardIterator, + regex_constants::syntax_option_type = regex_constants::ECMAScript) + -> basic_regex::value_type>; // C++17 + +typedef basic_regex regex; +typedef basic_regex wregex; + +template + void swap(basic_regex& e1, basic_regex& e2); + +template +class sub_match + : public pair +{ +public: + typedef typename iterator_traits::value_type value_type; + typedef typename iterator_traits::difference_type difference_type; + typedef BidirectionalIterator iterator; + typedef basic_string string_type; + + bool matched; + + constexpr sub_match(); + + difference_type length() const; + operator string_type() const; + string_type str() const; + + int compare(const sub_match& s) const; + int compare(const string_type& s) const; + int compare(const value_type* s) const; +}; + +typedef sub_match csub_match; +typedef sub_match wcsub_match; +typedef sub_match ssub_match; +typedef sub_match wssub_match; + +template + bool + operator==(const sub_match& lhs, const sub_match& rhs); + +template + bool + operator!=(const sub_match& lhs, const sub_match& rhs); + +template + bool + operator<(const sub_match& lhs, const sub_match& rhs); + +template + bool + operator<=(const sub_match& lhs, const sub_match& rhs); + +template + bool + operator>=(const sub_match& lhs, const sub_match& rhs); + +template + bool + operator>(const sub_match& lhs, const sub_match& rhs); + +template + bool + operator==(const basic_string::value_type, ST, SA>& lhs, + const sub_match& rhs); + +template + bool + operator!=(const basic_string::value_type, ST, SA>& lhs, + const sub_match& rhs); + +template + bool + operator<(const basic_string::value_type, ST, SA>& lhs, + const sub_match& rhs); + +template + bool + operator>(const basic_string::value_type, ST, SA>& lhs, + const sub_match& rhs); + +template + bool operator>=(const basic_string::value_type, ST, SA>& lhs, + const sub_match& rhs); + +template + bool + operator<=(const basic_string::value_type, ST, SA>& lhs, + const sub_match& rhs); + +template + bool + operator==(const sub_match& lhs, + const basic_string::value_type, ST, SA>& rhs); + +template + bool + operator!=(const sub_match& lhs, + const basic_string::value_type, ST, SA>& rhs); + +template + bool + operator<(const sub_match& lhs, + const basic_string::value_type, ST, SA>& rhs); + +template + bool operator>(const sub_match& lhs, + const basic_string::value_type, ST, SA>& rhs); + +template + bool + operator>=(const sub_match& lhs, + const basic_string::value_type, ST, SA>& rhs); + +template + bool + operator<=(const sub_match& lhs, + const basic_string::value_type, ST, SA>& rhs); + +template + bool + operator==(typename iterator_traits::value_type const* lhs, + const sub_match& rhs); + +template + bool + operator!=(typename iterator_traits::value_type const* lhs, + const sub_match& rhs); + +template + bool + operator<(typename iterator_traits::value_type const* lhs, + const sub_match& rhs); + +template + bool + operator>(typename iterator_traits::value_type const* lhs, + const sub_match& rhs); + +template + bool + operator>=(typename iterator_traits::value_type const* lhs, + const sub_match& rhs); + +template + bool + operator<=(typename iterator_traits::value_type const* lhs, + const sub_match& rhs); + +template + bool + operator==(const sub_match& lhs, + typename iterator_traits::value_type const* rhs); + +template + bool + operator!=(const sub_match& lhs, + typename iterator_traits::value_type const* rhs); + +template + bool + operator<(const sub_match& lhs, + typename iterator_traits::value_type const* rhs); + +template + bool + operator>(const sub_match& lhs, + typename iterator_traits::value_type const* rhs); + +template + bool + operator>=(const sub_match& lhs, + typename iterator_traits::value_type const* rhs); + +template + bool + operator<=(const sub_match& lhs, + typename iterator_traits::value_type const* rhs); + +template + bool + operator==(typename iterator_traits::value_type const& lhs, + const sub_match& rhs); + +template + bool + operator!=(typename iterator_traits::value_type const& lhs, + const sub_match& rhs); + +template + bool + operator<(typename iterator_traits::value_type const& lhs, + const sub_match& rhs); + +template + bool + operator>(typename iterator_traits::value_type const& lhs, + const sub_match& rhs); + +template + bool + operator>=(typename iterator_traits::value_type const& lhs, + const sub_match& rhs); + +template + bool + operator<=(typename iterator_traits::value_type const& lhs, + const sub_match& rhs); + +template + bool + operator==(const sub_match& lhs, + typename iterator_traits::value_type const& rhs); + +template + bool + operator!=(const sub_match& lhs, + typename iterator_traits::value_type const& rhs); + +template + bool + operator<(const sub_match& lhs, + typename iterator_traits::value_type const& rhs); + +template + bool + operator>(const sub_match& lhs, + typename iterator_traits::value_type const& rhs); + +template + bool + operator>=(const sub_match& lhs, + typename iterator_traits::value_type const& rhs); + +template + bool + operator<=(const sub_match& lhs, + typename iterator_traits::value_type const& rhs); + +template + basic_ostream& + operator<<(basic_ostream& os, const sub_match& m); + +template >> +class match_results +{ +public: + typedef sub_match value_type; + typedef const value_type& const_reference; + typedef value_type& reference; + typedef /implementation-defined/ const_iterator; + typedef const_iterator iterator; + typedef typename iterator_traits::difference_type difference_type; + typedef typename allocator_traits::size_type size_type; + typedef Allocator allocator_type; + typedef typename iterator_traits::value_type char_type; + typedef basic_string string_type; + + // construct/copy/destroy: + explicit match_results(const Allocator& a = Allocator()); + match_results(const match_results& m); + match_results(match_results&& m) noexcept; + match_results& operator=(const match_results& m); + match_results& operator=(match_results&& m); + ~match_results(); + + bool ready() const; + + // size: + size_type size() const; + size_type max_size() const; + bool empty() const; + + // element access: + difference_type length(size_type sub = 0) const; + difference_type position(size_type sub = 0) const; + string_type str(size_type sub = 0) const; + const_reference operator[](size_type n) const; + + const_reference prefix() const; + const_reference suffix() const; + + const_iterator begin() const; + const_iterator end() const; + const_iterator cbegin() const; + const_iterator cend() const; + + // format: + template + OutputIter + format(OutputIter out, const char_type* fmt_first, + const char_type* fmt_last, + regex_constants::match_flag_type flags = regex_constants::format_default) const; + template + OutputIter + format(OutputIter out, const basic_string& fmt, + regex_constants::match_flag_type flags = regex_constants::format_default) const; + template + basic_string + format(const basic_string& fmt, + regex_constants::match_flag_type flags = regex_constants::format_default) const; + string_type + format(const char_type* fmt, + regex_constants::match_flag_type flags = regex_constants::format_default) const; + + // allocator: + allocator_type get_allocator() const; + + // swap: + void swap(match_results& that); +}; + +typedef match_results cmatch; +typedef match_results wcmatch; +typedef match_results smatch; +typedef match_results wsmatch; + +template + bool + operator==(const match_results& m1, + const match_results& m2); + +template + bool + operator!=(const match_results& m1, + const match_results& m2); + +template + void + swap(match_results& m1, + match_results& m2); + +template + bool + regex_match(BidirectionalIterator first, BidirectionalIterator last, + match_results& m, + const basic_regex& e, + regex_constants::match_flag_type flags = regex_constants::match_default); + +template + bool + regex_match(BidirectionalIterator first, BidirectionalIterator last, + const basic_regex& e, + regex_constants::match_flag_type flags = regex_constants::match_default); + +template + bool + regex_match(const charT* str, match_results& m, + const basic_regex& e, + regex_constants::match_flag_type flags = regex_constants::match_default); + +template + bool + regex_match(const basic_string& s, + match_results::const_iterator, Allocator>& m, + const basic_regex& e, + regex_constants::match_flag_type flags = regex_constants::match_default); + +template + bool + regex_match(const basic_string&& s, + match_results::const_iterator, Allocator>& m, + const basic_regex& e, + regex_constants::match_flag_type flags = regex_constants::match_default) = delete; // C++14 + +template + bool + regex_match(const charT* str, const basic_regex& e, + regex_constants::match_flag_type flags = regex_constants::match_default); + +template + bool + regex_match(const basic_string& s, + const basic_regex& e, + regex_constants::match_flag_type flags = regex_constants::match_default); + +template + bool + regex_search(BidirectionalIterator first, BidirectionalIterator last, + match_results& m, + const basic_regex& e, + regex_constants::match_flag_type flags = regex_constants::match_default); + +template + bool + regex_search(BidirectionalIterator first, BidirectionalIterator last, + const basic_regex& e, + regex_constants::match_flag_type flags = regex_constants::match_default); + +template + bool + regex_search(const charT* str, match_results& m, + const basic_regex& e, + regex_constants::match_flag_type flags = regex_constants::match_default); + +template + bool + regex_search(const charT* str, const basic_regex& e, + regex_constants::match_flag_type flags = regex_constants::match_default); + +template + bool + regex_search(const basic_string& s, + const basic_regex& e, + regex_constants::match_flag_type flags = regex_constants::match_default); + +template + bool + regex_search(const basic_string& s, + match_results::const_iterator, Allocator>& m, + const basic_regex& e, + regex_constants::match_flag_type flags = regex_constants::match_default); + +template + bool + regex_search(const basic_string&& s, + match_results::const_iterator, Allocator>& m, + const basic_regex& e, + regex_constants::match_flag_type flags = regex_constants::match_default) = delete; // C++14 + +template + OutputIterator + regex_replace(OutputIterator out, + BidirectionalIterator first, BidirectionalIterator last, + const basic_regex& e, + const basic_string& fmt, + regex_constants::match_flag_type flags = regex_constants::match_default); + +template + OutputIterator + regex_replace(OutputIterator out, + BidirectionalIterator first, BidirectionalIterator last, + const basic_regex& e, const charT* fmt, + regex_constants::match_flag_type flags = regex_constants::match_default); + +template > + basic_string + regex_replace(const basic_string& s, + const basic_regex& e, + const basic_string& fmt, + regex_constants::match_flag_type flags = regex_constants::match_default); + +template + basic_string + regex_replace(const basic_string& s, + const basic_regex& e, const charT* fmt, + regex_constants::match_flag_type flags = regex_constants::match_default); + +template + basic_string + regex_replace(const charT* s, + const basic_regex& e, + const basic_string& fmt, + regex_constants::match_flag_type flags = regex_constants::match_default); + +template + basic_string + regex_replace(const charT* s, + const basic_regex& e, + const charT* fmt, + regex_constants::match_flag_type flags = regex_constants::match_default); + +template ::value_type, + class traits = regex_traits> +class regex_iterator +{ +public: + typedef basic_regex regex_type; + typedef match_results value_type; + typedef ptrdiff_t difference_type; + typedef const value_type* pointer; + typedef const value_type& reference; + typedef forward_iterator_tag iterator_category; + + regex_iterator(); + regex_iterator(BidirectionalIterator a, BidirectionalIterator b, + const regex_type& re, + regex_constants::match_flag_type m = regex_constants::match_default); + regex_iterator(_BidirectionalIterator __a, _BidirectionalIterator __b, + const regex_type&& __re, + regex_constants::match_flag_type __m + = regex_constants::match_default) = delete; // C++14 + regex_iterator(const regex_iterator&); + regex_iterator& operator=(const regex_iterator&); + + bool operator==(const regex_iterator&) const; + bool operator!=(const regex_iterator&) const; + + const value_type& operator*() const; + const value_type* operator->() const; + + regex_iterator& operator++(); + regex_iterator operator++(int); +}; + +typedef regex_iterator cregex_iterator; +typedef regex_iterator wcregex_iterator; +typedef regex_iterator sregex_iterator; +typedef regex_iterator wsregex_iterator; + +template ::value_type, + class traits = regex_traits> +class regex_token_iterator +{ +public: + typedef basic_regex regex_type; + typedef sub_match value_type; + typedef ptrdiff_t difference_type; + typedef const value_type* pointer; + typedef const value_type& reference; + typedef forward_iterator_tag iterator_category; + + regex_token_iterator(); + regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b, + const regex_type& re, int submatch = 0, + regex_constants::match_flag_type m = regex_constants::match_default); + regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b, + const regex_type&& re, int submatch = 0, + regex_constants::match_flag_type m = regex_constants::match_default) = delete; // C++14 + regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b, + const regex_type& re, const vector& submatches, + regex_constants::match_flag_type m = regex_constants::match_default); + regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b, + const regex_type&& re, const vector& submatches, + regex_constants::match_flag_type m = regex_constants::match_default) = delete; // C++14 + regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b, + const regex_type& re, initializer_list submatches, + regex_constants::match_flag_type m = regex_constants::match_default); + regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b, + const regex_type&& re, initializer_list submatches, + regex_constants::match_flag_type m = regex_constants::match_default) = delete; // C++14 + template + regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b, + const regex_type& re, const int (&submatches)[N], + regex_constants::match_flag_type m = regex_constants::match_default); + template + regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b, + const regex_type& re, const int (&submatches)[N], + regex_constants::match_flag_type m = regex_constants::match_default) = delete // C++14; + regex_token_iterator(const regex_token_iterator&); + regex_token_iterator& operator=(const regex_token_iterator&); + + bool operator==(const regex_token_iterator&) const; + bool operator!=(const regex_token_iterator&) const; + + const value_type& operator*() const; + const value_type* operator->() const; + + regex_token_iterator& operator++(); + regex_token_iterator operator++(int); +}; + +typedef regex_token_iterator cregex_token_iterator; +typedef regex_token_iterator wcregex_token_iterator; +typedef regex_token_iterator sregex_token_iterator; +typedef regex_token_iterator wsregex_token_iterator; + +} // std +*/ + +#include "third_party/libcxx/__config" +#include "third_party/libcxx/stdexcept" +#include "third_party/libcxx/__locale" +#include "third_party/libcxx/initializer_list" +#include "third_party/libcxx/utility" +#include "third_party/libcxx/iterator" +#include "third_party/libcxx/string" +#include "third_party/libcxx/memory" +#include "third_party/libcxx/vector" +#include "third_party/libcxx/deque" +#include "third_party/libcxx/version" + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include "third_party/libcxx/__undef_macros" + + +#define _LIBCPP_REGEX_COMPLEXITY_FACTOR 4096 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace regex_constants +{ + +// syntax_option_type + +enum syntax_option_type +{ + icase = 1 << 0, + nosubs = 1 << 1, + optimize = 1 << 2, + collate = 1 << 3, +#ifdef _LIBCPP_ABI_REGEX_CONSTANTS_NONZERO + ECMAScript = 1 << 9, +#else + ECMAScript = 0, +#endif + basic = 1 << 4, + extended = 1 << 5, + awk = 1 << 6, + grep = 1 << 7, + egrep = 1 << 8 +}; + +inline _LIBCPP_CONSTEXPR +syntax_option_type __get_grammar(syntax_option_type __g) +{ +#ifdef _LIBCPP_ABI_REGEX_CONSTANTS_NONZERO + return static_cast(__g & 0x3F0); +#else + return static_cast(__g & 0x1F0); +#endif +} + +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +syntax_option_type +operator~(syntax_option_type __x) +{ + return syntax_option_type(~int(__x) & 0x1FF); +} + +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +syntax_option_type +operator&(syntax_option_type __x, syntax_option_type __y) +{ + return syntax_option_type(int(__x) & int(__y)); +} + +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +syntax_option_type +operator|(syntax_option_type __x, syntax_option_type __y) +{ + return syntax_option_type(int(__x) | int(__y)); +} + +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +syntax_option_type +operator^(syntax_option_type __x, syntax_option_type __y) +{ + return syntax_option_type(int(__x) ^ int(__y)); +} + +inline _LIBCPP_INLINE_VISIBILITY +syntax_option_type& +operator&=(syntax_option_type& __x, syntax_option_type __y) +{ + __x = __x & __y; + return __x; +} + +inline _LIBCPP_INLINE_VISIBILITY +syntax_option_type& +operator|=(syntax_option_type& __x, syntax_option_type __y) +{ + __x = __x | __y; + return __x; +} + +inline _LIBCPP_INLINE_VISIBILITY +syntax_option_type& +operator^=(syntax_option_type& __x, syntax_option_type __y) +{ + __x = __x ^ __y; + return __x; +} + +// match_flag_type + +enum match_flag_type +{ + match_default = 0, + match_not_bol = 1 << 0, + match_not_eol = 1 << 1, + match_not_bow = 1 << 2, + match_not_eow = 1 << 3, + match_any = 1 << 4, + match_not_null = 1 << 5, + match_continuous = 1 << 6, + match_prev_avail = 1 << 7, + format_default = 0, + format_sed = 1 << 8, + format_no_copy = 1 << 9, + format_first_only = 1 << 10, + __no_update_pos = 1 << 11, + __full_match = 1 << 12 +}; + +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +match_flag_type +operator~(match_flag_type __x) +{ + return match_flag_type(~int(__x) & 0x0FFF); +} + +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +match_flag_type +operator&(match_flag_type __x, match_flag_type __y) +{ + return match_flag_type(int(__x) & int(__y)); +} + +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +match_flag_type +operator|(match_flag_type __x, match_flag_type __y) +{ + return match_flag_type(int(__x) | int(__y)); +} + +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +match_flag_type +operator^(match_flag_type __x, match_flag_type __y) +{ + return match_flag_type(int(__x) ^ int(__y)); +} + +inline _LIBCPP_INLINE_VISIBILITY +match_flag_type& +operator&=(match_flag_type& __x, match_flag_type __y) +{ + __x = __x & __y; + return __x; +} + +inline _LIBCPP_INLINE_VISIBILITY +match_flag_type& +operator|=(match_flag_type& __x, match_flag_type __y) +{ + __x = __x | __y; + return __x; +} + +inline _LIBCPP_INLINE_VISIBILITY +match_flag_type& +operator^=(match_flag_type& __x, match_flag_type __y) +{ + __x = __x ^ __y; + return __x; +} + +enum error_type +{ + error_collate = 1, + error_ctype, + error_escape, + error_backref, + error_brack, + error_paren, + error_brace, + error_badbrace, + error_range, + error_space, + error_badrepeat, + error_complexity, + error_stack, + __re_err_grammar, + __re_err_empty, + __re_err_unknown +}; + +} // regex_constants + +class _LIBCPP_EXCEPTION_ABI regex_error + : public runtime_error +{ + regex_constants::error_type __code_; +public: + explicit regex_error(regex_constants::error_type __ecode); + virtual ~regex_error() throw(); + _LIBCPP_INLINE_VISIBILITY + regex_constants::error_type code() const {return __code_;} +}; + +template +_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY +void __throw_regex_error() +{ +#ifndef _LIBCPP_NO_EXCEPTIONS + throw regex_error(_Ev); +#else + _VSTD::abort(); +#endif +} + +template +struct _LIBCPP_TEMPLATE_VIS regex_traits +{ +public: + typedef _CharT char_type; + typedef basic_string string_type; + typedef locale locale_type; + typedef ctype_base::mask char_class_type; + + static const char_class_type __regex_word = ctype_base::__regex_word; +private: + locale __loc_; + const ctype* __ct_; + const collate* __col_; + +public: + regex_traits(); + + _LIBCPP_INLINE_VISIBILITY + static size_t length(const char_type* __p) + {return char_traits::length(__p);} + _LIBCPP_INLINE_VISIBILITY + char_type translate(char_type __c) const {return __c;} + char_type translate_nocase(char_type __c) const; + template + string_type + transform(_ForwardIterator __f, _ForwardIterator __l) const; + template + _LIBCPP_INLINE_VISIBILITY + string_type + transform_primary( _ForwardIterator __f, _ForwardIterator __l) const + {return __transform_primary(__f, __l, char_type());} + template + _LIBCPP_INLINE_VISIBILITY + string_type + lookup_collatename(_ForwardIterator __f, _ForwardIterator __l) const + {return __lookup_collatename(__f, __l, char_type());} + template + _LIBCPP_INLINE_VISIBILITY + char_class_type + lookup_classname(_ForwardIterator __f, _ForwardIterator __l, + bool __icase = false) const + {return __lookup_classname(__f, __l, __icase, char_type());} + bool isctype(char_type __c, char_class_type __m) const; + _LIBCPP_INLINE_VISIBILITY + int value(char_type __ch, int __radix) const + {return __regex_traits_value(__ch, __radix);} + locale_type imbue(locale_type __l); + _LIBCPP_INLINE_VISIBILITY + locale_type getloc()const {return __loc_;} + +private: + void __init(); + + template + string_type + __transform_primary(_ForwardIterator __f, _ForwardIterator __l, char) const; + template + string_type + __transform_primary(_ForwardIterator __f, _ForwardIterator __l, wchar_t) const; + + template + string_type + __lookup_collatename(_ForwardIterator __f, _ForwardIterator __l, char) const; + template + string_type + __lookup_collatename(_ForwardIterator __f, _ForwardIterator __l, wchar_t) const; + + template + char_class_type + __lookup_classname(_ForwardIterator __f, _ForwardIterator __l, + bool __icase, char) const; + template + char_class_type + __lookup_classname(_ForwardIterator __f, _ForwardIterator __l, + bool __icase, wchar_t) const; + + static int __regex_traits_value(unsigned char __ch, int __radix); + _LIBCPP_INLINE_VISIBILITY + int __regex_traits_value(char __ch, int __radix) const + {return __regex_traits_value(static_cast(__ch), __radix);} + _LIBCPP_INLINE_VISIBILITY + int __regex_traits_value(wchar_t __ch, int __radix) const; +}; + +template +const typename regex_traits<_CharT>::char_class_type +regex_traits<_CharT>::__regex_word; + +template +regex_traits<_CharT>::regex_traits() +{ + __init(); +} + +template +typename regex_traits<_CharT>::char_type +regex_traits<_CharT>::translate_nocase(char_type __c) const +{ + return __ct_->tolower(__c); +} + +template +template +typename regex_traits<_CharT>::string_type +regex_traits<_CharT>::transform(_ForwardIterator __f, _ForwardIterator __l) const +{ + string_type __s(__f, __l); + return __col_->transform(__s.data(), __s.data() + __s.size()); +} + +template +void +regex_traits<_CharT>::__init() +{ + __ct_ = &use_facet >(__loc_); + __col_ = &use_facet >(__loc_); +} + +template +typename regex_traits<_CharT>::locale_type +regex_traits<_CharT>::imbue(locale_type __l) +{ + locale __r = __loc_; + __loc_ = __l; + __init(); + return __r; +} + +// transform_primary is very FreeBSD-specific + +template +template +typename regex_traits<_CharT>::string_type +regex_traits<_CharT>::__transform_primary(_ForwardIterator __f, + _ForwardIterator __l, char) const +{ + const string_type __s(__f, __l); + string_type __d = __col_->transform(__s.data(), __s.data() + __s.size()); + switch (__d.size()) + { + case 1: + break; + case 12: + __d[11] = __d[3]; + break; + default: + __d.clear(); + break; + } + return __d; +} + +template +template +typename regex_traits<_CharT>::string_type +regex_traits<_CharT>::__transform_primary(_ForwardIterator __f, + _ForwardIterator __l, wchar_t) const +{ + const string_type __s(__f, __l); + string_type __d = __col_->transform(__s.data(), __s.data() + __s.size()); + switch (__d.size()) + { + case 1: + break; + case 3: + __d[2] = __d[0]; + break; + default: + __d.clear(); + break; + } + return __d; +} + +// lookup_collatename is very FreeBSD-specific + +_LIBCPP_FUNC_VIS string __get_collation_name(const char* __s); + +template +template +typename regex_traits<_CharT>::string_type +regex_traits<_CharT>::__lookup_collatename(_ForwardIterator __f, + _ForwardIterator __l, char) const +{ + string_type __s(__f, __l); + string_type __r; + if (!__s.empty()) + { + __r = __get_collation_name(__s.c_str()); + if (__r.empty() && __s.size() <= 2) + { + __r = __col_->transform(__s.data(), __s.data() + __s.size()); + if (__r.size() == 1 || __r.size() == 12) + __r = __s; + else + __r.clear(); + } + } + return __r; +} + +template +template +typename regex_traits<_CharT>::string_type +regex_traits<_CharT>::__lookup_collatename(_ForwardIterator __f, + _ForwardIterator __l, wchar_t) const +{ + string_type __s(__f, __l); + string __n; + __n.reserve(__s.size()); + for (typename string_type::const_iterator __i = __s.begin(), __e = __s.end(); + __i != __e; ++__i) + { + if (static_cast(*__i) >= 127) + return string_type(); + __n.push_back(char(*__i)); + } + string_type __r; + if (!__s.empty()) + { + __n = __get_collation_name(__n.c_str()); + if (!__n.empty()) + __r.assign(__n.begin(), __n.end()); + else if (__s.size() <= 2) + { + __r = __col_->transform(__s.data(), __s.data() + __s.size()); + if (__r.size() == 1 || __r.size() == 3) + __r = __s; + else + __r.clear(); + } + } + return __r; +} + +// lookup_classname + +regex_traits::char_class_type _LIBCPP_FUNC_VIS +__get_classname(const char* __s, bool __icase); + +template +template +typename regex_traits<_CharT>::char_class_type +regex_traits<_CharT>::__lookup_classname(_ForwardIterator __f, + _ForwardIterator __l, + bool __icase, char) const +{ + string_type __s(__f, __l); + __ct_->tolower(&__s[0], &__s[0] + __s.size()); + return __get_classname(__s.c_str(), __icase); +} + +template +template +typename regex_traits<_CharT>::char_class_type +regex_traits<_CharT>::__lookup_classname(_ForwardIterator __f, + _ForwardIterator __l, + bool __icase, wchar_t) const +{ + string_type __s(__f, __l); + __ct_->tolower(&__s[0], &__s[0] + __s.size()); + string __n; + __n.reserve(__s.size()); + for (typename string_type::const_iterator __i = __s.begin(), __e = __s.end(); + __i != __e; ++__i) + { + if (static_cast(*__i) >= 127) + return char_class_type(); + __n.push_back(char(*__i)); + } + return __get_classname(__n.c_str(), __icase); +} + +template +bool +regex_traits<_CharT>::isctype(char_type __c, char_class_type __m) const +{ + if (__ct_->is(__m, __c)) + return true; + return (__c == '_' && (__m & __regex_word)); +} + +template +int +regex_traits<_CharT>::__regex_traits_value(unsigned char __ch, int __radix) +{ + if ((__ch & 0xF8u) == 0x30) // '0' <= __ch && __ch <= '7' + return __ch - '0'; + if (__radix != 8) + { + if ((__ch & 0xFEu) == 0x38) // '8' <= __ch && __ch <= '9' + return __ch - '0'; + if (__radix == 16) + { + __ch |= 0x20; // tolower + if ('a' <= __ch && __ch <= 'f') + return __ch - ('a' - 10); + } + } + return -1; +} + +template +inline +int +regex_traits<_CharT>::__regex_traits_value(wchar_t __ch, int __radix) const +{ + return __regex_traits_value(static_cast(__ct_->narrow(__ch, char_type())), __radix); +} + +template class __node; + +template class _LIBCPP_TEMPLATE_VIS sub_match; + +template > > +class _LIBCPP_TEMPLATE_VIS match_results; + +template +struct __state +{ + enum + { + __end_state = -1000, + __consume_input, // -999 + __begin_marked_expr, // -998 + __end_marked_expr, // -997 + __pop_state, // -996 + __accept_and_consume, // -995 + __accept_but_not_consume, // -994 + __reject, // -993 + __split, + __repeat + }; + + int __do_; + const _CharT* __first_; + const _CharT* __current_; + const _CharT* __last_; + vector > __sub_matches_; + vector > __loop_data_; + const __node<_CharT>* __node_; + regex_constants::match_flag_type __flags_; + bool __at_first_; + + _LIBCPP_INLINE_VISIBILITY + __state() + : __do_(0), __first_(nullptr), __current_(nullptr), __last_(nullptr), + __node_(nullptr), __flags_() {} +}; + +// __node + +template +class __node +{ + __node(const __node&); + __node& operator=(const __node&); +public: + typedef _VSTD::__state<_CharT> __state; + + _LIBCPP_INLINE_VISIBILITY + __node() {} + _LIBCPP_INLINE_VISIBILITY + virtual ~__node() {} + + _LIBCPP_INLINE_VISIBILITY + virtual void __exec(__state&) const {} + _LIBCPP_INLINE_VISIBILITY + virtual void __exec_split(bool, __state&) const {} +}; + +// __end_state + +template +class __end_state + : public __node<_CharT> +{ +public: + typedef _VSTD::__state<_CharT> __state; + + _LIBCPP_INLINE_VISIBILITY + __end_state() {} + + virtual void __exec(__state&) const; +}; + +template +void +__end_state<_CharT>::__exec(__state& __s) const +{ + __s.__do_ = __state::__end_state; +} + +// __has_one_state + +template +class __has_one_state + : public __node<_CharT> +{ + __node<_CharT>* __first_; + +public: + _LIBCPP_INLINE_VISIBILITY + explicit __has_one_state(__node<_CharT>* __s) + : __first_(__s) {} + + _LIBCPP_INLINE_VISIBILITY + __node<_CharT>* first() const {return __first_;} + _LIBCPP_INLINE_VISIBILITY + __node<_CharT>*& first() {return __first_;} +}; + +// __owns_one_state + +template +class __owns_one_state + : public __has_one_state<_CharT> +{ + typedef __has_one_state<_CharT> base; + +public: + _LIBCPP_INLINE_VISIBILITY + explicit __owns_one_state(__node<_CharT>* __s) + : base(__s) {} + + virtual ~__owns_one_state(); +}; + +template +__owns_one_state<_CharT>::~__owns_one_state() +{ + delete this->first(); +} + +// __empty_state + +template +class __empty_state + : public __owns_one_state<_CharT> +{ + typedef __owns_one_state<_CharT> base; + +public: + typedef _VSTD::__state<_CharT> __state; + + _LIBCPP_INLINE_VISIBILITY + explicit __empty_state(__node<_CharT>* __s) + : base(__s) {} + + virtual void __exec(__state&) const; +}; + +template +void +__empty_state<_CharT>::__exec(__state& __s) const +{ + __s.__do_ = __state::__accept_but_not_consume; + __s.__node_ = this->first(); +} + +// __empty_non_own_state + +template +class __empty_non_own_state + : public __has_one_state<_CharT> +{ + typedef __has_one_state<_CharT> base; + +public: + typedef _VSTD::__state<_CharT> __state; + + _LIBCPP_INLINE_VISIBILITY + explicit __empty_non_own_state(__node<_CharT>* __s) + : base(__s) {} + + virtual void __exec(__state&) const; +}; + +template +void +__empty_non_own_state<_CharT>::__exec(__state& __s) const +{ + __s.__do_ = __state::__accept_but_not_consume; + __s.__node_ = this->first(); +} + +// __repeat_one_loop + +template +class __repeat_one_loop + : public __has_one_state<_CharT> +{ + typedef __has_one_state<_CharT> base; + +public: + typedef _VSTD::__state<_CharT> __state; + + _LIBCPP_INLINE_VISIBILITY + explicit __repeat_one_loop(__node<_CharT>* __s) + : base(__s) {} + + virtual void __exec(__state&) const; +}; + +template +void +__repeat_one_loop<_CharT>::__exec(__state& __s) const +{ + __s.__do_ = __state::__repeat; + __s.__node_ = this->first(); +} + +// __owns_two_states + +template +class __owns_two_states + : public __owns_one_state<_CharT> +{ + typedef __owns_one_state<_CharT> base; + + base* __second_; + +public: + _LIBCPP_INLINE_VISIBILITY + explicit __owns_two_states(__node<_CharT>* __s1, base* __s2) + : base(__s1), __second_(__s2) {} + + virtual ~__owns_two_states(); + + _LIBCPP_INLINE_VISIBILITY + base* second() const {return __second_;} + _LIBCPP_INLINE_VISIBILITY + base*& second() {return __second_;} +}; + +template +__owns_two_states<_CharT>::~__owns_two_states() +{ + delete __second_; +} + +// __loop + +template +class __loop + : public __owns_two_states<_CharT> +{ + typedef __owns_two_states<_CharT> base; + + size_t __min_; + size_t __max_; + unsigned __loop_id_; + unsigned __mexp_begin_; + unsigned __mexp_end_; + bool __greedy_; + +public: + typedef _VSTD::__state<_CharT> __state; + + _LIBCPP_INLINE_VISIBILITY + explicit __loop(unsigned __loop_id, + __node<_CharT>* __s1, __owns_one_state<_CharT>* __s2, + unsigned __mexp_begin, unsigned __mexp_end, + bool __greedy = true, + size_t __min = 0, + size_t __max = numeric_limits::max()) + : base(__s1, __s2), __min_(__min), __max_(__max), __loop_id_(__loop_id), + __mexp_begin_(__mexp_begin), __mexp_end_(__mexp_end), + __greedy_(__greedy) {} + + virtual void __exec(__state& __s) const; + virtual void __exec_split(bool __second, __state& __s) const; + +private: + _LIBCPP_INLINE_VISIBILITY + void __init_repeat(__state& __s) const + { + __s.__loop_data_[__loop_id_].second = __s.__current_; + for (size_t __i = __mexp_begin_-1; __i != __mexp_end_-1; ++__i) + { + __s.__sub_matches_[__i].first = __s.__last_; + __s.__sub_matches_[__i].second = __s.__last_; + __s.__sub_matches_[__i].matched = false; + } + } +}; + +template +void +__loop<_CharT>::__exec(__state& __s) const +{ + if (__s.__do_ == __state::__repeat) + { + bool __do_repeat = ++__s.__loop_data_[__loop_id_].first < __max_; + bool __do_alt = __s.__loop_data_[__loop_id_].first >= __min_; + if (__do_repeat && __do_alt && + __s.__loop_data_[__loop_id_].second == __s.__current_) + __do_repeat = false; + if (__do_repeat && __do_alt) + __s.__do_ = __state::__split; + else if (__do_repeat) + { + __s.__do_ = __state::__accept_but_not_consume; + __s.__node_ = this->first(); + __init_repeat(__s); + } + else + { + __s.__do_ = __state::__accept_but_not_consume; + __s.__node_ = this->second(); + } + } + else + { + __s.__loop_data_[__loop_id_].first = 0; + bool __do_repeat = 0 < __max_; + bool __do_alt = 0 >= __min_; + if (__do_repeat && __do_alt) + __s.__do_ = __state::__split; + else if (__do_repeat) + { + __s.__do_ = __state::__accept_but_not_consume; + __s.__node_ = this->first(); + __init_repeat(__s); + } + else + { + __s.__do_ = __state::__accept_but_not_consume; + __s.__node_ = this->second(); + } + } +} + +template +void +__loop<_CharT>::__exec_split(bool __second, __state& __s) const +{ + __s.__do_ = __state::__accept_but_not_consume; + if (__greedy_ != __second) + { + __s.__node_ = this->first(); + __init_repeat(__s); + } + else + __s.__node_ = this->second(); +} + +// __alternate + +template +class __alternate + : public __owns_two_states<_CharT> +{ + typedef __owns_two_states<_CharT> base; + +public: + typedef _VSTD::__state<_CharT> __state; + + _LIBCPP_INLINE_VISIBILITY + explicit __alternate(__owns_one_state<_CharT>* __s1, + __owns_one_state<_CharT>* __s2) + : base(__s1, __s2) {} + + virtual void __exec(__state& __s) const; + virtual void __exec_split(bool __second, __state& __s) const; +}; + +template +void +__alternate<_CharT>::__exec(__state& __s) const +{ + __s.__do_ = __state::__split; +} + +template +void +__alternate<_CharT>::__exec_split(bool __second, __state& __s) const +{ + __s.__do_ = __state::__accept_but_not_consume; + if (__second) + __s.__node_ = this->second(); + else + __s.__node_ = this->first(); +} + +// __begin_marked_subexpression + +template +class __begin_marked_subexpression + : public __owns_one_state<_CharT> +{ + typedef __owns_one_state<_CharT> base; + + unsigned __mexp_; +public: + typedef _VSTD::__state<_CharT> __state; + + _LIBCPP_INLINE_VISIBILITY + explicit __begin_marked_subexpression(unsigned __mexp, __node<_CharT>* __s) + : base(__s), __mexp_(__mexp) {} + + virtual void __exec(__state&) const; +}; + +template +void +__begin_marked_subexpression<_CharT>::__exec(__state& __s) const +{ + __s.__do_ = __state::__accept_but_not_consume; + __s.__sub_matches_[__mexp_-1].first = __s.__current_; + __s.__node_ = this->first(); +} + +// __end_marked_subexpression + +template +class __end_marked_subexpression + : public __owns_one_state<_CharT> +{ + typedef __owns_one_state<_CharT> base; + + unsigned __mexp_; +public: + typedef _VSTD::__state<_CharT> __state; + + _LIBCPP_INLINE_VISIBILITY + explicit __end_marked_subexpression(unsigned __mexp, __node<_CharT>* __s) + : base(__s), __mexp_(__mexp) {} + + virtual void __exec(__state&) const; +}; + +template +void +__end_marked_subexpression<_CharT>::__exec(__state& __s) const +{ + __s.__do_ = __state::__accept_but_not_consume; + __s.__sub_matches_[__mexp_-1].second = __s.__current_; + __s.__sub_matches_[__mexp_-1].matched = true; + __s.__node_ = this->first(); +} + +// __back_ref + +template +class __back_ref + : public __owns_one_state<_CharT> +{ + typedef __owns_one_state<_CharT> base; + + unsigned __mexp_; +public: + typedef _VSTD::__state<_CharT> __state; + + _LIBCPP_INLINE_VISIBILITY + explicit __back_ref(unsigned __mexp, __node<_CharT>* __s) + : base(__s), __mexp_(__mexp) {} + + virtual void __exec(__state&) const; +}; + +template +void +__back_ref<_CharT>::__exec(__state& __s) const +{ + if (__mexp_ > __s.__sub_matches_.size()) + __throw_regex_error(); + sub_match& __sm = __s.__sub_matches_[__mexp_-1]; + if (__sm.matched) + { + ptrdiff_t __len = __sm.second - __sm.first; + if (__s.__last_ - __s.__current_ >= __len && + _VSTD::equal(__sm.first, __sm.second, __s.__current_)) + { + __s.__do_ = __state::__accept_but_not_consume; + __s.__current_ += __len; + __s.__node_ = this->first(); + } + else + { + __s.__do_ = __state::__reject; + __s.__node_ = nullptr; + } + } + else + { + __s.__do_ = __state::__reject; + __s.__node_ = nullptr; + } +} + +// __back_ref_icase + +template +class __back_ref_icase + : public __owns_one_state<_CharT> +{ + typedef __owns_one_state<_CharT> base; + + _Traits __traits_; + unsigned __mexp_; +public: + typedef _VSTD::__state<_CharT> __state; + + _LIBCPP_INLINE_VISIBILITY + explicit __back_ref_icase(const _Traits& __traits, unsigned __mexp, + __node<_CharT>* __s) + : base(__s), __traits_(__traits), __mexp_(__mexp) {} + + virtual void __exec(__state&) const; +}; + +template +void +__back_ref_icase<_CharT, _Traits>::__exec(__state& __s) const +{ + sub_match& __sm = __s.__sub_matches_[__mexp_-1]; + if (__sm.matched) + { + ptrdiff_t __len = __sm.second - __sm.first; + if (__s.__last_ - __s.__current_ >= __len) + { + for (ptrdiff_t __i = 0; __i < __len; ++__i) + { + if (__traits_.translate_nocase(__sm.first[__i]) != + __traits_.translate_nocase(__s.__current_[__i])) + goto __not_equal; + } + __s.__do_ = __state::__accept_but_not_consume; + __s.__current_ += __len; + __s.__node_ = this->first(); + } + else + { + __s.__do_ = __state::__reject; + __s.__node_ = nullptr; + } + } + else + { +__not_equal: + __s.__do_ = __state::__reject; + __s.__node_ = nullptr; + } +} + +// __back_ref_collate + +template +class __back_ref_collate + : public __owns_one_state<_CharT> +{ + typedef __owns_one_state<_CharT> base; + + _Traits __traits_; + unsigned __mexp_; +public: + typedef _VSTD::__state<_CharT> __state; + + _LIBCPP_INLINE_VISIBILITY + explicit __back_ref_collate(const _Traits& __traits, unsigned __mexp, + __node<_CharT>* __s) + : base(__s), __traits_(__traits), __mexp_(__mexp) {} + + virtual void __exec(__state&) const; +}; + +template +void +__back_ref_collate<_CharT, _Traits>::__exec(__state& __s) const +{ + sub_match& __sm = __s.__sub_matches_[__mexp_-1]; + if (__sm.matched) + { + ptrdiff_t __len = __sm.second - __sm.first; + if (__s.__last_ - __s.__current_ >= __len) + { + for (ptrdiff_t __i = 0; __i < __len; ++__i) + { + if (__traits_.translate(__sm.first[__i]) != + __traits_.translate(__s.__current_[__i])) + goto __not_equal; + } + __s.__do_ = __state::__accept_but_not_consume; + __s.__current_ += __len; + __s.__node_ = this->first(); + } + else + { + __s.__do_ = __state::__reject; + __s.__node_ = nullptr; + } + } + else + { +__not_equal: + __s.__do_ = __state::__reject; + __s.__node_ = nullptr; + } +} + +// __word_boundary + +template +class __word_boundary + : public __owns_one_state<_CharT> +{ + typedef __owns_one_state<_CharT> base; + + _Traits __traits_; + bool __invert_; +public: + typedef _VSTD::__state<_CharT> __state; + + _LIBCPP_INLINE_VISIBILITY + explicit __word_boundary(const _Traits& __traits, bool __invert, + __node<_CharT>* __s) + : base(__s), __traits_(__traits), __invert_(__invert) {} + + virtual void __exec(__state&) const; +}; + +template +void +__word_boundary<_CharT, _Traits>::__exec(__state& __s) const +{ + bool __is_word_b = false; + if (__s.__first_ != __s.__last_) + { + if (__s.__current_ == __s.__last_) + { + if (!(__s.__flags_ & regex_constants::match_not_eow)) + { + _CharT __c = __s.__current_[-1]; + __is_word_b = __c == '_' || + __traits_.isctype(__c, ctype_base::alnum); + } + } + else if (__s.__current_ == __s.__first_ && + !(__s.__flags_ & regex_constants::match_prev_avail)) + { + if (!(__s.__flags_ & regex_constants::match_not_bow)) + { + _CharT __c = *__s.__current_; + __is_word_b = __c == '_' || + __traits_.isctype(__c, ctype_base::alnum); + } + } + else + { + _CharT __c1 = __s.__current_[-1]; + _CharT __c2 = *__s.__current_; + bool __is_c1_b = __c1 == '_' || + __traits_.isctype(__c1, ctype_base::alnum); + bool __is_c2_b = __c2 == '_' || + __traits_.isctype(__c2, ctype_base::alnum); + __is_word_b = __is_c1_b != __is_c2_b; + } + } + if (__is_word_b != __invert_) + { + __s.__do_ = __state::__accept_but_not_consume; + __s.__node_ = this->first(); + } + else + { + __s.__do_ = __state::__reject; + __s.__node_ = nullptr; + } +} + +// __l_anchor + +template +class __l_anchor + : public __owns_one_state<_CharT> +{ + typedef __owns_one_state<_CharT> base; + +public: + typedef _VSTD::__state<_CharT> __state; + + _LIBCPP_INLINE_VISIBILITY + __l_anchor(__node<_CharT>* __s) + : base(__s) {} + + virtual void __exec(__state&) const; +}; + +template +void +__l_anchor<_CharT>::__exec(__state& __s) const +{ + if (__s.__at_first_ && __s.__current_ == __s.__first_ && + !(__s.__flags_ & regex_constants::match_not_bol)) + { + __s.__do_ = __state::__accept_but_not_consume; + __s.__node_ = this->first(); + } + else + { + __s.__do_ = __state::__reject; + __s.__node_ = nullptr; + } +} + +// __r_anchor + +template +class __r_anchor + : public __owns_one_state<_CharT> +{ + typedef __owns_one_state<_CharT> base; + +public: + typedef _VSTD::__state<_CharT> __state; + + _LIBCPP_INLINE_VISIBILITY + __r_anchor(__node<_CharT>* __s) + : base(__s) {} + + virtual void __exec(__state&) const; +}; + +template +void +__r_anchor<_CharT>::__exec(__state& __s) const +{ + if (__s.__current_ == __s.__last_ && + !(__s.__flags_ & regex_constants::match_not_eol)) + { + __s.__do_ = __state::__accept_but_not_consume; + __s.__node_ = this->first(); + } + else + { + __s.__do_ = __state::__reject; + __s.__node_ = nullptr; + } +} + +// __match_any + +template +class __match_any + : public __owns_one_state<_CharT> +{ + typedef __owns_one_state<_CharT> base; + +public: + typedef _VSTD::__state<_CharT> __state; + + _LIBCPP_INLINE_VISIBILITY + __match_any(__node<_CharT>* __s) + : base(__s) {} + + virtual void __exec(__state&) const; +}; + +template +void +__match_any<_CharT>::__exec(__state& __s) const +{ + if (__s.__current_ != __s.__last_ && *__s.__current_ != 0) + { + __s.__do_ = __state::__accept_and_consume; + ++__s.__current_; + __s.__node_ = this->first(); + } + else + { + __s.__do_ = __state::__reject; + __s.__node_ = nullptr; + } +} + +// __match_any_but_newline + +template +class __match_any_but_newline + : public __owns_one_state<_CharT> +{ + typedef __owns_one_state<_CharT> base; + +public: + typedef _VSTD::__state<_CharT> __state; + + _LIBCPP_INLINE_VISIBILITY + __match_any_but_newline(__node<_CharT>* __s) + : base(__s) {} + + virtual void __exec(__state&) const; +}; + +template <> _LIBCPP_FUNC_VIS void __match_any_but_newline::__exec(__state&) const; +template <> _LIBCPP_FUNC_VIS void __match_any_but_newline::__exec(__state&) const; + +// __match_char + +template +class __match_char + : public __owns_one_state<_CharT> +{ + typedef __owns_one_state<_CharT> base; + + _CharT __c_; + + __match_char(const __match_char&); + __match_char& operator=(const __match_char&); +public: + typedef _VSTD::__state<_CharT> __state; + + _LIBCPP_INLINE_VISIBILITY + __match_char(_CharT __c, __node<_CharT>* __s) + : base(__s), __c_(__c) {} + + virtual void __exec(__state&) const; +}; + +template +void +__match_char<_CharT>::__exec(__state& __s) const +{ + if (__s.__current_ != __s.__last_ && *__s.__current_ == __c_) + { + __s.__do_ = __state::__accept_and_consume; + ++__s.__current_; + __s.__node_ = this->first(); + } + else + { + __s.__do_ = __state::__reject; + __s.__node_ = nullptr; + } +} + +// __match_char_icase + +template +class __match_char_icase + : public __owns_one_state<_CharT> +{ + typedef __owns_one_state<_CharT> base; + + _Traits __traits_; + _CharT __c_; + + __match_char_icase(const __match_char_icase&); + __match_char_icase& operator=(const __match_char_icase&); +public: + typedef _VSTD::__state<_CharT> __state; + + _LIBCPP_INLINE_VISIBILITY + __match_char_icase(const _Traits& __traits, _CharT __c, __node<_CharT>* __s) + : base(__s), __traits_(__traits), __c_(__traits.translate_nocase(__c)) {} + + virtual void __exec(__state&) const; +}; + +template +void +__match_char_icase<_CharT, _Traits>::__exec(__state& __s) const +{ + if (__s.__current_ != __s.__last_ && + __traits_.translate_nocase(*__s.__current_) == __c_) + { + __s.__do_ = __state::__accept_and_consume; + ++__s.__current_; + __s.__node_ = this->first(); + } + else + { + __s.__do_ = __state::__reject; + __s.__node_ = nullptr; + } +} + +// __match_char_collate + +template +class __match_char_collate + : public __owns_one_state<_CharT> +{ + typedef __owns_one_state<_CharT> base; + + _Traits __traits_; + _CharT __c_; + + __match_char_collate(const __match_char_collate&); + __match_char_collate& operator=(const __match_char_collate&); +public: + typedef _VSTD::__state<_CharT> __state; + + _LIBCPP_INLINE_VISIBILITY + __match_char_collate(const _Traits& __traits, _CharT __c, __node<_CharT>* __s) + : base(__s), __traits_(__traits), __c_(__traits.translate(__c)) {} + + virtual void __exec(__state&) const; +}; + +template +void +__match_char_collate<_CharT, _Traits>::__exec(__state& __s) const +{ + if (__s.__current_ != __s.__last_ && + __traits_.translate(*__s.__current_) == __c_) + { + __s.__do_ = __state::__accept_and_consume; + ++__s.__current_; + __s.__node_ = this->first(); + } + else + { + __s.__do_ = __state::__reject; + __s.__node_ = nullptr; + } +} + +// __bracket_expression + +template +class __bracket_expression + : public __owns_one_state<_CharT> +{ + typedef __owns_one_state<_CharT> base; + typedef typename _Traits::string_type string_type; + + _Traits __traits_; + vector<_CharT> __chars_; + vector<_CharT> __neg_chars_; + vector > __ranges_; + vector > __digraphs_; + vector __equivalences_; + typename regex_traits<_CharT>::char_class_type __mask_; + typename regex_traits<_CharT>::char_class_type __neg_mask_; + bool __negate_; + bool __icase_; + bool __collate_; + bool __might_have_digraph_; + + __bracket_expression(const __bracket_expression&); + __bracket_expression& operator=(const __bracket_expression&); +public: + typedef _VSTD::__state<_CharT> __state; + + _LIBCPP_INLINE_VISIBILITY + __bracket_expression(const _Traits& __traits, __node<_CharT>* __s, + bool __negate, bool __icase, bool __collate) + : base(__s), __traits_(__traits), __mask_(), __neg_mask_(), + __negate_(__negate), __icase_(__icase), __collate_(__collate), + __might_have_digraph_(__traits_.getloc().name() != "C") {} + + virtual void __exec(__state&) const; + + _LIBCPP_INLINE_VISIBILITY + bool __negated() const {return __negate_;} + + _LIBCPP_INLINE_VISIBILITY + void __add_char(_CharT __c) + { + if (__icase_) + __chars_.push_back(__traits_.translate_nocase(__c)); + else if (__collate_) + __chars_.push_back(__traits_.translate(__c)); + else + __chars_.push_back(__c); + } + _LIBCPP_INLINE_VISIBILITY + void __add_neg_char(_CharT __c) + { + if (__icase_) + __neg_chars_.push_back(__traits_.translate_nocase(__c)); + else if (__collate_) + __neg_chars_.push_back(__traits_.translate(__c)); + else + __neg_chars_.push_back(__c); + } + _LIBCPP_INLINE_VISIBILITY + void __add_range(string_type __b, string_type __e) + { + if (__collate_) + { + if (__icase_) + { + for (size_t __i = 0; __i < __b.size(); ++__i) + __b[__i] = __traits_.translate_nocase(__b[__i]); + for (size_t __i = 0; __i < __e.size(); ++__i) + __e[__i] = __traits_.translate_nocase(__e[__i]); + } + else + { + for (size_t __i = 0; __i < __b.size(); ++__i) + __b[__i] = __traits_.translate(__b[__i]); + for (size_t __i = 0; __i < __e.size(); ++__i) + __e[__i] = __traits_.translate(__e[__i]); + } + __ranges_.push_back(make_pair( + __traits_.transform(__b.begin(), __b.end()), + __traits_.transform(__e.begin(), __e.end()))); + } + else + { + if (__b.size() != 1 || __e.size() != 1) + __throw_regex_error(); + if (__icase_) + { + __b[0] = __traits_.translate_nocase(__b[0]); + __e[0] = __traits_.translate_nocase(__e[0]); + } + __ranges_.push_back(make_pair(_VSTD::move(__b), _VSTD::move(__e))); + } + } + _LIBCPP_INLINE_VISIBILITY + void __add_digraph(_CharT __c1, _CharT __c2) + { + if (__icase_) + __digraphs_.push_back(make_pair(__traits_.translate_nocase(__c1), + __traits_.translate_nocase(__c2))); + else if (__collate_) + __digraphs_.push_back(make_pair(__traits_.translate(__c1), + __traits_.translate(__c2))); + else + __digraphs_.push_back(make_pair(__c1, __c2)); + } + _LIBCPP_INLINE_VISIBILITY + void __add_equivalence(const string_type& __s) + {__equivalences_.push_back(__s);} + _LIBCPP_INLINE_VISIBILITY + void __add_class(typename regex_traits<_CharT>::char_class_type __mask) + {__mask_ |= __mask;} + _LIBCPP_INLINE_VISIBILITY + void __add_neg_class(typename regex_traits<_CharT>::char_class_type __mask) + {__neg_mask_ |= __mask;} +}; + +template +void +__bracket_expression<_CharT, _Traits>::__exec(__state& __s) const +{ + bool __found = false; + unsigned __consumed = 0; + if (__s.__current_ != __s.__last_) + { + ++__consumed; + if (__might_have_digraph_) + { + const _CharT* __next = _VSTD::next(__s.__current_); + if (__next != __s.__last_) + { + pair<_CharT, _CharT> __ch2(*__s.__current_, *__next); + if (__icase_) + { + __ch2.first = __traits_.translate_nocase(__ch2.first); + __ch2.second = __traits_.translate_nocase(__ch2.second); + } + else if (__collate_) + { + __ch2.first = __traits_.translate(__ch2.first); + __ch2.second = __traits_.translate(__ch2.second); + } + if (!__traits_.lookup_collatename(&__ch2.first, &__ch2.first+2).empty()) + { + // __ch2 is a digraph in this locale + ++__consumed; + for (size_t __i = 0; __i < __digraphs_.size(); ++__i) + { + if (__ch2 == __digraphs_[__i]) + { + __found = true; + goto __exit; + } + } + if (__collate_ && !__ranges_.empty()) + { + string_type __s2 = __traits_.transform(&__ch2.first, + &__ch2.first + 2); + for (size_t __i = 0; __i < __ranges_.size(); ++__i) + { + if (__ranges_[__i].first <= __s2 && + __s2 <= __ranges_[__i].second) + { + __found = true; + goto __exit; + } + } + } + if (!__equivalences_.empty()) + { + string_type __s2 = __traits_.transform_primary(&__ch2.first, + &__ch2.first + 2); + for (size_t __i = 0; __i < __equivalences_.size(); ++__i) + { + if (__s2 == __equivalences_[__i]) + { + __found = true; + goto __exit; + } + } + } + if (__traits_.isctype(__ch2.first, __mask_) && + __traits_.isctype(__ch2.second, __mask_)) + { + __found = true; + goto __exit; + } + if (!__traits_.isctype(__ch2.first, __neg_mask_) && + !__traits_.isctype(__ch2.second, __neg_mask_)) + { + __found = true; + goto __exit; + } + goto __exit; + } + } + } + // test *__s.__current_ as not a digraph + _CharT __ch = *__s.__current_; + if (__icase_) + __ch = __traits_.translate_nocase(__ch); + else if (__collate_) + __ch = __traits_.translate(__ch); + for (size_t __i = 0; __i < __chars_.size(); ++__i) + { + if (__ch == __chars_[__i]) + { + __found = true; + goto __exit; + } + } + // When there's at least one of __neg_chars_ and __neg_mask_, the set + // of "__found" chars is + // union(complement(union(__neg_chars_, __neg_mask_)), + // other cases...) + // + // It doesn't make sense to check this when there are no __neg_chars_ + // and no __neg_mask_. + if (!(__neg_mask_ == 0 && __neg_chars_.empty())) + { + const bool __in_neg_mask = __traits_.isctype(__ch, __neg_mask_); + const bool __in_neg_chars = + std::find(__neg_chars_.begin(), __neg_chars_.end(), __ch) != + __neg_chars_.end(); + if (!(__in_neg_mask || __in_neg_chars)) + { + __found = true; + goto __exit; + } + } + if (!__ranges_.empty()) + { + string_type __s2 = __collate_ ? + __traits_.transform(&__ch, &__ch + 1) : + string_type(1, __ch); + for (size_t __i = 0; __i < __ranges_.size(); ++__i) + { + if (__ranges_[__i].first <= __s2 && __s2 <= __ranges_[__i].second) + { + __found = true; + goto __exit; + } + } + } + if (!__equivalences_.empty()) + { + string_type __s2 = __traits_.transform_primary(&__ch, &__ch + 1); + for (size_t __i = 0; __i < __equivalences_.size(); ++__i) + { + if (__s2 == __equivalences_[__i]) + { + __found = true; + goto __exit; + } + } + } + if (__traits_.isctype(__ch, __mask_)) + { + __found = true; + goto __exit; + } + } + else + __found = __negate_; // force reject +__exit: + if (__found != __negate_) + { + __s.__do_ = __state::__accept_and_consume; + __s.__current_ += __consumed; + __s.__node_ = this->first(); + } + else + { + __s.__do_ = __state::__reject; + __s.__node_ = nullptr; + } +} + +template class __lookahead; + +template > +class _LIBCPP_TEMPLATE_VIS basic_regex +{ +public: + // types: + typedef _CharT value_type; + typedef _Traits traits_type; + typedef typename _Traits::string_type string_type; + typedef regex_constants::syntax_option_type flag_type; + typedef typename _Traits::locale_type locale_type; + +private: + _Traits __traits_; + flag_type __flags_; + unsigned __marked_count_; + unsigned __loop_count_; + int __open_count_; + shared_ptr<__empty_state<_CharT> > __start_; + __owns_one_state<_CharT>* __end_; + + typedef _VSTD::__state<_CharT> __state; + typedef _VSTD::__node<_CharT> __node; + +public: + // constants: + static const regex_constants::syntax_option_type icase = regex_constants::icase; + static const regex_constants::syntax_option_type nosubs = regex_constants::nosubs; + static const regex_constants::syntax_option_type optimize = regex_constants::optimize; + static const regex_constants::syntax_option_type collate = regex_constants::collate; + static const regex_constants::syntax_option_type ECMAScript = regex_constants::ECMAScript; + static const regex_constants::syntax_option_type basic = regex_constants::basic; + static const regex_constants::syntax_option_type extended = regex_constants::extended; + static const regex_constants::syntax_option_type awk = regex_constants::awk; + static const regex_constants::syntax_option_type grep = regex_constants::grep; + static const regex_constants::syntax_option_type egrep = regex_constants::egrep; + + // construct/copy/destroy: + _LIBCPP_INLINE_VISIBILITY + basic_regex() + : __flags_(regex_constants::ECMAScript), __marked_count_(0), __loop_count_(0), __open_count_(0), + __end_(0) + {} + _LIBCPP_INLINE_VISIBILITY + explicit basic_regex(const value_type* __p, flag_type __f = regex_constants::ECMAScript) + : __flags_(__f), __marked_count_(0), __loop_count_(0), __open_count_(0), + __end_(0) + { + if (__get_grammar(__flags_) == 0) __flags_ |= regex_constants::ECMAScript; + __parse(__p, __p + __traits_.length(__p)); + } + + _LIBCPP_INLINE_VISIBILITY + basic_regex(const value_type* __p, size_t __len, flag_type __f = regex_constants::ECMAScript) + : __flags_(__f), __marked_count_(0), __loop_count_(0), __open_count_(0), + __end_(0) + { + if (__get_grammar(__flags_) == 0) __flags_ |= regex_constants::ECMAScript; + __parse(__p, __p + __len); + } + +// basic_regex(const basic_regex&) = default; +// basic_regex(basic_regex&&) = default; + template + _LIBCPP_INLINE_VISIBILITY + explicit basic_regex(const basic_string& __p, + flag_type __f = regex_constants::ECMAScript) + : __flags_(__f), __marked_count_(0), __loop_count_(0), __open_count_(0), + __end_(0) + { + if (__get_grammar(__flags_) == 0) __flags_ |= regex_constants::ECMAScript; + __parse(__p.begin(), __p.end()); + } + + template + _LIBCPP_INLINE_VISIBILITY + basic_regex(_ForwardIterator __first, _ForwardIterator __last, + flag_type __f = regex_constants::ECMAScript) + : __flags_(__f), __marked_count_(0), __loop_count_(0), __open_count_(0), + __end_(0) + { + if (__get_grammar(__flags_) == 0) __flags_ |= regex_constants::ECMAScript; + __parse(__first, __last); + } +#ifndef _LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY + basic_regex(initializer_list __il, + flag_type __f = regex_constants::ECMAScript) + : __flags_(__f), __marked_count_(0), __loop_count_(0), __open_count_(0), + __end_(0) + { + if (__get_grammar(__flags_) == 0) __flags_ |= regex_constants::ECMAScript; + __parse(__il.begin(), __il.end()); + } +#endif // _LIBCPP_CXX03_LANG + +// ~basic_regex() = default; + +// basic_regex& operator=(const basic_regex&) = default; +// basic_regex& operator=(basic_regex&&) = default; + _LIBCPP_INLINE_VISIBILITY + basic_regex& operator=(const value_type* __p) + {return assign(__p);} +#ifndef _LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY + basic_regex& operator=(initializer_list __il) + {return assign(__il);} +#endif // _LIBCPP_CXX03_LANG + template + _LIBCPP_INLINE_VISIBILITY + basic_regex& operator=(const basic_string& __p) + {return assign(__p);} + + // assign: + _LIBCPP_INLINE_VISIBILITY + basic_regex& assign(const basic_regex& __that) + {return *this = __that;} +#ifndef _LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY + basic_regex& assign(basic_regex&& __that) _NOEXCEPT + {return *this = _VSTD::move(__that);} +#endif + _LIBCPP_INLINE_VISIBILITY + basic_regex& assign(const value_type* __p, flag_type __f = regex_constants::ECMAScript) + {return assign(__p, __p + __traits_.length(__p), __f);} + _LIBCPP_INLINE_VISIBILITY + basic_regex& assign(const value_type* __p, size_t __len, flag_type __f = regex_constants::ECMAScript) + {return assign(__p, __p + __len, __f);} + template + _LIBCPP_INLINE_VISIBILITY + basic_regex& assign(const basic_string& __s, + flag_type __f = regex_constants::ECMAScript) + {return assign(__s.begin(), __s.end(), __f);} + + template + _LIBCPP_INLINE_VISIBILITY + typename enable_if + < + __is_input_iterator <_InputIterator>::value && + !__is_forward_iterator<_InputIterator>::value, + basic_regex& + >::type + assign(_InputIterator __first, _InputIterator __last, + flag_type __f = regex_constants::ECMAScript) + { + basic_string<_CharT> __t(__first, __last); + return assign(__t.begin(), __t.end(), __f); + } + +private: + _LIBCPP_INLINE_VISIBILITY + void __member_init(flag_type __f) + { + __flags_ = __f; + __marked_count_ = 0; + __loop_count_ = 0; + __open_count_ = 0; + __end_ = nullptr; + } +public: + + template + _LIBCPP_INLINE_VISIBILITY + typename enable_if + < + __is_forward_iterator<_ForwardIterator>::value, + basic_regex& + >::type + assign(_ForwardIterator __first, _ForwardIterator __last, + flag_type __f = regex_constants::ECMAScript) + { + return assign(basic_regex(__first, __last, __f)); + } + +#ifndef _LIBCPP_CXX03_LANG + + _LIBCPP_INLINE_VISIBILITY + basic_regex& assign(initializer_list __il, + flag_type __f = regex_constants::ECMAScript) + {return assign(__il.begin(), __il.end(), __f);} + +#endif // _LIBCPP_CXX03_LANG + + // const operations: + _LIBCPP_INLINE_VISIBILITY + unsigned mark_count() const {return __marked_count_;} + _LIBCPP_INLINE_VISIBILITY + flag_type flags() const {return __flags_;} + + // locale: + _LIBCPP_INLINE_VISIBILITY + locale_type imbue(locale_type __loc) + { + __member_init(ECMAScript); + __start_.reset(); + return __traits_.imbue(__loc); + } + _LIBCPP_INLINE_VISIBILITY + locale_type getloc() const {return __traits_.getloc();} + + // swap: + void swap(basic_regex& __r); + +private: + _LIBCPP_INLINE_VISIBILITY + unsigned __loop_count() const {return __loop_count_;} + + template + _ForwardIterator + __parse(_ForwardIterator __first, _ForwardIterator __last); + template + _ForwardIterator + __parse_basic_reg_exp(_ForwardIterator __first, _ForwardIterator __last); + template + _ForwardIterator + __parse_RE_expression(_ForwardIterator __first, _ForwardIterator __last); + template + _ForwardIterator + __parse_simple_RE(_ForwardIterator __first, _ForwardIterator __last); + template + _ForwardIterator + __parse_nondupl_RE(_ForwardIterator __first, _ForwardIterator __last); + template + _ForwardIterator + __parse_one_char_or_coll_elem_RE(_ForwardIterator __first, _ForwardIterator __last); + template + _ForwardIterator + __parse_Back_open_paren(_ForwardIterator __first, _ForwardIterator __last); + template + _ForwardIterator + __parse_Back_close_paren(_ForwardIterator __first, _ForwardIterator __last); + template + _ForwardIterator + __parse_Back_open_brace(_ForwardIterator __first, _ForwardIterator __last); + template + _ForwardIterator + __parse_Back_close_brace(_ForwardIterator __first, _ForwardIterator __last); + template + _ForwardIterator + __parse_BACKREF(_ForwardIterator __first, _ForwardIterator __last); + template + _ForwardIterator + __parse_ORD_CHAR(_ForwardIterator __first, _ForwardIterator __last); + template + _ForwardIterator + __parse_QUOTED_CHAR(_ForwardIterator __first, _ForwardIterator __last); + template + _ForwardIterator + __parse_RE_dupl_symbol(_ForwardIterator __first, _ForwardIterator __last, + __owns_one_state<_CharT>* __s, + unsigned __mexp_begin, unsigned __mexp_end); + template + _ForwardIterator + __parse_ERE_dupl_symbol(_ForwardIterator __first, _ForwardIterator __last, + __owns_one_state<_CharT>* __s, + unsigned __mexp_begin, unsigned __mexp_end); + template + _ForwardIterator + __parse_bracket_expression(_ForwardIterator __first, _ForwardIterator __last); + template + _ForwardIterator + __parse_follow_list(_ForwardIterator __first, _ForwardIterator __last, + __bracket_expression<_CharT, _Traits>* __ml); + template + _ForwardIterator + __parse_expression_term(_ForwardIterator __first, _ForwardIterator __last, + __bracket_expression<_CharT, _Traits>* __ml); + template + _ForwardIterator + __parse_equivalence_class(_ForwardIterator __first, _ForwardIterator __last, + __bracket_expression<_CharT, _Traits>* __ml); + template + _ForwardIterator + __parse_character_class(_ForwardIterator __first, _ForwardIterator __last, + __bracket_expression<_CharT, _Traits>* __ml); + template + _ForwardIterator + __parse_collating_symbol(_ForwardIterator __first, _ForwardIterator __last, + basic_string<_CharT>& __col_sym); + template + _ForwardIterator + __parse_DUP_COUNT(_ForwardIterator __first, _ForwardIterator __last, int& __c); + template + _ForwardIterator + __parse_extended_reg_exp(_ForwardIterator __first, _ForwardIterator __last); + template + _ForwardIterator + __parse_ERE_branch(_ForwardIterator __first, _ForwardIterator __last); + template + _ForwardIterator + __parse_ERE_expression(_ForwardIterator __first, _ForwardIterator __last); + template + _ForwardIterator + __parse_one_char_or_coll_elem_ERE(_ForwardIterator __first, _ForwardIterator __last); + template + _ForwardIterator + __parse_ORD_CHAR_ERE(_ForwardIterator __first, _ForwardIterator __last); + template + _ForwardIterator + __parse_QUOTED_CHAR_ERE(_ForwardIterator __first, _ForwardIterator __last); + template + _ForwardIterator + __parse_ecma_exp(_ForwardIterator __first, _ForwardIterator __last); + template + _ForwardIterator + __parse_alternative(_ForwardIterator __first, _ForwardIterator __last); + template + _ForwardIterator + __parse_term(_ForwardIterator __first, _ForwardIterator __last); + template + _ForwardIterator + __parse_assertion(_ForwardIterator __first, _ForwardIterator __last); + template + _ForwardIterator + __parse_atom(_ForwardIterator __first, _ForwardIterator __last); + template + _ForwardIterator + __parse_atom_escape(_ForwardIterator __first, _ForwardIterator __last); + template + _ForwardIterator + __parse_decimal_escape(_ForwardIterator __first, _ForwardIterator __last); + template + _ForwardIterator + __parse_character_class_escape(_ForwardIterator __first, _ForwardIterator __last); + template + _ForwardIterator + __parse_character_escape(_ForwardIterator __first, _ForwardIterator __last, + basic_string<_CharT>* __str = nullptr); + template + _ForwardIterator + __parse_pattern_character(_ForwardIterator __first, _ForwardIterator __last); + template + _ForwardIterator + __parse_grep(_ForwardIterator __first, _ForwardIterator __last); + template + _ForwardIterator + __parse_egrep(_ForwardIterator __first, _ForwardIterator __last); + template + _ForwardIterator + __parse_class_escape(_ForwardIterator __first, _ForwardIterator __last, + basic_string<_CharT>& __str, + __bracket_expression<_CharT, _Traits>* __ml); + template + _ForwardIterator + __parse_awk_escape(_ForwardIterator __first, _ForwardIterator __last, + basic_string<_CharT>* __str = nullptr); + + _LIBCPP_INLINE_VISIBILITY + void __push_l_anchor(); + void __push_r_anchor(); + void __push_match_any(); + void __push_match_any_but_newline(); + _LIBCPP_INLINE_VISIBILITY + void __push_greedy_inf_repeat(size_t __min, __owns_one_state<_CharT>* __s, + unsigned __mexp_begin = 0, unsigned __mexp_end = 0) + {__push_loop(__min, numeric_limits::max(), __s, + __mexp_begin, __mexp_end);} + _LIBCPP_INLINE_VISIBILITY + void __push_nongreedy_inf_repeat(size_t __min, __owns_one_state<_CharT>* __s, + unsigned __mexp_begin = 0, unsigned __mexp_end = 0) + {__push_loop(__min, numeric_limits::max(), __s, + __mexp_begin, __mexp_end, false);} + void __push_loop(size_t __min, size_t __max, __owns_one_state<_CharT>* __s, + size_t __mexp_begin = 0, size_t __mexp_end = 0, + bool __greedy = true); + __bracket_expression<_CharT, _Traits>* __start_matching_list(bool __negate); + void __push_char(value_type __c); + void __push_back_ref(int __i); + void __push_alternation(__owns_one_state<_CharT>* __sa, + __owns_one_state<_CharT>* __sb); + void __push_begin_marked_subexpression(); + void __push_end_marked_subexpression(unsigned); + void __push_empty(); + void __push_word_boundary(bool); + void __push_lookahead(const basic_regex&, bool, unsigned); + + template + bool + __search(const _CharT* __first, const _CharT* __last, + match_results& __m, + regex_constants::match_flag_type __flags) const; + + template + bool + __match_at_start(const _CharT* __first, const _CharT* __last, + match_results& __m, + regex_constants::match_flag_type __flags, bool) const; + template + bool + __match_at_start_ecma(const _CharT* __first, const _CharT* __last, + match_results& __m, + regex_constants::match_flag_type __flags, bool) const; + template + bool + __match_at_start_posix_nosubs(const _CharT* __first, const _CharT* __last, + match_results& __m, + regex_constants::match_flag_type __flags, bool) const; + template + bool + __match_at_start_posix_subs(const _CharT* __first, const _CharT* __last, + match_results& __m, + regex_constants::match_flag_type __flags, bool) const; + + template + friend + bool + regex_search(_Bp, _Bp, match_results<_Bp, _Ap>&, const basic_regex<_Cp, _Tp>&, + regex_constants::match_flag_type); + + template + friend + bool + regex_search(const _Cp*, const _Cp*, match_results&, + const basic_regex<_Cp, _Tp>&, regex_constants::match_flag_type); + + template + friend + bool + regex_search(_Bp, _Bp, const basic_regex<_Cp, _Tp>&, + regex_constants::match_flag_type); + + template + friend + bool + regex_search(const _Cp*, const _Cp*, + const basic_regex<_Cp, _Tp>&, regex_constants::match_flag_type); + + template + friend + bool + regex_search(const _Cp*, match_results&, const basic_regex<_Cp, _Tp>&, + regex_constants::match_flag_type); + + template + friend + bool + regex_search(const basic_string<_Cp, _ST, _SA>& __s, + const basic_regex<_Cp, _Tp>& __e, + regex_constants::match_flag_type __flags); + + template + friend + bool + regex_search(const basic_string<_Cp, _ST, _SA>& __s, + match_results::const_iterator, _Ap>&, + const basic_regex<_Cp, _Tp>& __e, + regex_constants::match_flag_type __flags); + + template + friend + bool + regex_search(__wrap_iter<_Iter> __first, + __wrap_iter<_Iter> __last, + match_results<__wrap_iter<_Iter>, _Ap>& __m, + const basic_regex<_Cp, _Tp>& __e, + regex_constants::match_flag_type __flags); + + template friend class __lookahead; +}; + +#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES +template ::value, nullptr_t>::type +> +basic_regex(_ForwardIterator, _ForwardIterator, + regex_constants::syntax_option_type = regex_constants::ECMAScript) + -> basic_regex::value_type>; +#endif + +template + const regex_constants::syntax_option_type basic_regex<_CharT, _Traits>::icase; +template + const regex_constants::syntax_option_type basic_regex<_CharT, _Traits>::nosubs; +template + const regex_constants::syntax_option_type basic_regex<_CharT, _Traits>::optimize; +template + const regex_constants::syntax_option_type basic_regex<_CharT, _Traits>::collate; +template + const regex_constants::syntax_option_type basic_regex<_CharT, _Traits>::ECMAScript; +template + const regex_constants::syntax_option_type basic_regex<_CharT, _Traits>::basic; +template + const regex_constants::syntax_option_type basic_regex<_CharT, _Traits>::extended; +template + const regex_constants::syntax_option_type basic_regex<_CharT, _Traits>::awk; +template + const regex_constants::syntax_option_type basic_regex<_CharT, _Traits>::grep; +template + const regex_constants::syntax_option_type basic_regex<_CharT, _Traits>::egrep; + +template +void +basic_regex<_CharT, _Traits>::swap(basic_regex& __r) +{ + using _VSTD::swap; + swap(__traits_, __r.__traits_); + swap(__flags_, __r.__flags_); + swap(__marked_count_, __r.__marked_count_); + swap(__loop_count_, __r.__loop_count_); + swap(__open_count_, __r.__open_count_); + swap(__start_, __r.__start_); + swap(__end_, __r.__end_); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +swap(basic_regex<_CharT, _Traits>& __x, basic_regex<_CharT, _Traits>& __y) +{ + return __x.swap(__y); +} + +// __lookahead + +template +class __lookahead + : public __owns_one_state<_CharT> +{ + typedef __owns_one_state<_CharT> base; + + basic_regex<_CharT, _Traits> __exp_; + unsigned __mexp_; + bool __invert_; + + __lookahead(const __lookahead&); + __lookahead& operator=(const __lookahead&); +public: + typedef _VSTD::__state<_CharT> __state; + + _LIBCPP_INLINE_VISIBILITY + __lookahead(const basic_regex<_CharT, _Traits>& __exp, bool __invert, __node<_CharT>* __s, unsigned __mexp) + : base(__s), __exp_(__exp), __mexp_(__mexp), __invert_(__invert) {} + + virtual void __exec(__state&) const; +}; + +template +void +__lookahead<_CharT, _Traits>::__exec(__state& __s) const +{ + match_results __m; + __m.__init(1 + __exp_.mark_count(), __s.__current_, __s.__last_); + bool __matched = __exp_.__match_at_start_ecma( + __s.__current_, __s.__last_, + __m, + (__s.__flags_ | regex_constants::match_continuous) & + ~regex_constants::__full_match, + __s.__at_first_ && __s.__current_ == __s.__first_); + if (__matched != __invert_) + { + __s.__do_ = __state::__accept_but_not_consume; + __s.__node_ = this->first(); + for (unsigned __i = 1; __i < __m.size(); ++__i) { + __s.__sub_matches_[__mexp_ + __i - 1] = __m.__matches_[__i]; + } + } + else + { + __s.__do_ = __state::__reject; + __s.__node_ = nullptr; + } +} + +template +template +_ForwardIterator +basic_regex<_CharT, _Traits>::__parse(_ForwardIterator __first, + _ForwardIterator __last) +{ + { + unique_ptr<__node> __h(new __end_state<_CharT>); + __start_.reset(new __empty_state<_CharT>(__h.get())); + __h.release(); + __end_ = __start_.get(); + } + switch (__get_grammar(__flags_)) + { + case ECMAScript: + __first = __parse_ecma_exp(__first, __last); + break; + case basic: + __first = __parse_basic_reg_exp(__first, __last); + break; + case extended: + case awk: + __first = __parse_extended_reg_exp(__first, __last); + break; + case grep: + __first = __parse_grep(__first, __last); + break; + case egrep: + __first = __parse_egrep(__first, __last); + break; + default: + __throw_regex_error(); + } + return __first; +} + +template +template +_ForwardIterator +basic_regex<_CharT, _Traits>::__parse_basic_reg_exp(_ForwardIterator __first, + _ForwardIterator __last) +{ + if (__first != __last) + { + if (*__first == '^') + { + __push_l_anchor(); + ++__first; + } + if (__first != __last) + { + __first = __parse_RE_expression(__first, __last); + if (__first != __last) + { + _ForwardIterator __temp = _VSTD::next(__first); + if (__temp == __last && *__first == '$') + { + __push_r_anchor(); + ++__first; + } + } + } + if (__first != __last) + __throw_regex_error(); + } + return __first; +} + +template +template +_ForwardIterator +basic_regex<_CharT, _Traits>::__parse_extended_reg_exp(_ForwardIterator __first, + _ForwardIterator __last) +{ + __owns_one_state<_CharT>* __sa = __end_; + _ForwardIterator __temp = __parse_ERE_branch(__first, __last); + if (__temp == __first) + __throw_regex_error(); + __first = __temp; + while (__first != __last && *__first == '|') + { + __owns_one_state<_CharT>* __sb = __end_; + __temp = __parse_ERE_branch(++__first, __last); + if (__temp == __first) + __throw_regex_error(); + __push_alternation(__sa, __sb); + __first = __temp; + } + return __first; +} + +template +template +_ForwardIterator +basic_regex<_CharT, _Traits>::__parse_ERE_branch(_ForwardIterator __first, + _ForwardIterator __last) +{ + _ForwardIterator __temp = __parse_ERE_expression(__first, __last); + if (__temp == __first) + __throw_regex_error(); + do + { + __first = __temp; + __temp = __parse_ERE_expression(__first, __last); + } while (__temp != __first); + return __first; +} + +template +template +_ForwardIterator +basic_regex<_CharT, _Traits>::__parse_ERE_expression(_ForwardIterator __first, + _ForwardIterator __last) +{ + __owns_one_state<_CharT>* __e = __end_; + unsigned __mexp_begin = __marked_count_; + _ForwardIterator __temp = __parse_one_char_or_coll_elem_ERE(__first, __last); + if (__temp == __first && __temp != __last) + { + switch (*__temp) + { + case '^': + __push_l_anchor(); + ++__temp; + break; + case '$': + __push_r_anchor(); + ++__temp; + break; + case '(': + __push_begin_marked_subexpression(); + unsigned __temp_count = __marked_count_; + ++__open_count_; + __temp = __parse_extended_reg_exp(++__temp, __last); + if (__temp == __last || *__temp != ')') + __throw_regex_error(); + __push_end_marked_subexpression(__temp_count); + --__open_count_; + ++__temp; + break; + } + } + if (__temp != __first) + __temp = __parse_ERE_dupl_symbol(__temp, __last, __e, __mexp_begin+1, + __marked_count_+1); + __first = __temp; + return __first; +} + +template +template +_ForwardIterator +basic_regex<_CharT, _Traits>::__parse_RE_expression(_ForwardIterator __first, + _ForwardIterator __last) +{ + while (true) + { + _ForwardIterator __temp = __parse_simple_RE(__first, __last); + if (__temp == __first) + break; + __first = __temp; + } + return __first; +} + +template +template +_ForwardIterator +basic_regex<_CharT, _Traits>::__parse_simple_RE(_ForwardIterator __first, + _ForwardIterator __last) +{ + if (__first != __last) + { + __owns_one_state<_CharT>* __e = __end_; + unsigned __mexp_begin = __marked_count_; + _ForwardIterator __temp = __parse_nondupl_RE(__first, __last); + if (__temp != __first) + __first = __parse_RE_dupl_symbol(__temp, __last, __e, + __mexp_begin+1, __marked_count_+1); + } + return __first; +} + +template +template +_ForwardIterator +basic_regex<_CharT, _Traits>::__parse_nondupl_RE(_ForwardIterator __first, + _ForwardIterator __last) +{ + _ForwardIterator __temp = __first; + __first = __parse_one_char_or_coll_elem_RE(__first, __last); + if (__temp == __first) + { + __temp = __parse_Back_open_paren(__first, __last); + if (__temp != __first) + { + __push_begin_marked_subexpression(); + unsigned __temp_count = __marked_count_; + __first = __parse_RE_expression(__temp, __last); + __temp = __parse_Back_close_paren(__first, __last); + if (__temp == __first) + __throw_regex_error(); + __push_end_marked_subexpression(__temp_count); + __first = __temp; + } + else + __first = __parse_BACKREF(__first, __last); + } + return __first; +} + +template +template +_ForwardIterator +basic_regex<_CharT, _Traits>::__parse_one_char_or_coll_elem_RE( + _ForwardIterator __first, + _ForwardIterator __last) +{ + _ForwardIterator __temp = __parse_ORD_CHAR(__first, __last); + if (__temp == __first) + { + __temp = __parse_QUOTED_CHAR(__first, __last); + if (__temp == __first) + { + if (__temp != __last && *__temp == '.') + { + __push_match_any(); + ++__temp; + } + else + __temp = __parse_bracket_expression(__first, __last); + } + } + __first = __temp; + return __first; +} + +template +template +_ForwardIterator +basic_regex<_CharT, _Traits>::__parse_one_char_or_coll_elem_ERE( + _ForwardIterator __first, + _ForwardIterator __last) +{ + _ForwardIterator __temp = __parse_ORD_CHAR_ERE(__first, __last); + if (__temp == __first) + { + __temp = __parse_QUOTED_CHAR_ERE(__first, __last); + if (__temp == __first) + { + if (__temp != __last && *__temp == '.') + { + __push_match_any(); + ++__temp; + } + else + __temp = __parse_bracket_expression(__first, __last); + } + } + __first = __temp; + return __first; +} + +template +template +_ForwardIterator +basic_regex<_CharT, _Traits>::__parse_Back_open_paren(_ForwardIterator __first, + _ForwardIterator __last) +{ + if (__first != __last) + { + _ForwardIterator __temp = _VSTD::next(__first); + if (__temp != __last) + { + if (*__first == '\\' && *__temp == '(') + __first = ++__temp; + } + } + return __first; +} + +template +template +_ForwardIterator +basic_regex<_CharT, _Traits>::__parse_Back_close_paren(_ForwardIterator __first, + _ForwardIterator __last) +{ + if (__first != __last) + { + _ForwardIterator __temp = _VSTD::next(__first); + if (__temp != __last) + { + if (*__first == '\\' && *__temp == ')') + __first = ++__temp; + } + } + return __first; +} + +template +template +_ForwardIterator +basic_regex<_CharT, _Traits>::__parse_Back_open_brace(_ForwardIterator __first, + _ForwardIterator __last) +{ + if (__first != __last) + { + _ForwardIterator __temp = _VSTD::next(__first); + if (__temp != __last) + { + if (*__first == '\\' && *__temp == '{') + __first = ++__temp; + } + } + return __first; +} + +template +template +_ForwardIterator +basic_regex<_CharT, _Traits>::__parse_Back_close_brace(_ForwardIterator __first, + _ForwardIterator __last) +{ + if (__first != __last) + { + _ForwardIterator __temp = _VSTD::next(__first); + if (__temp != __last) + { + if (*__first == '\\' && *__temp == '}') + __first = ++__temp; + } + } + return __first; +} + +template +template +_ForwardIterator +basic_regex<_CharT, _Traits>::__parse_BACKREF(_ForwardIterator __first, + _ForwardIterator __last) +{ + if (__first != __last) + { + _ForwardIterator __temp = _VSTD::next(__first); + if (__temp != __last) + { + if (*__first == '\\') + { + int __val = __traits_.value(*__temp, 10); + if (__val >= 1 && __val <= 9) + { + __push_back_ref(__val); + __first = ++__temp; + } + } + } + } + return __first; +} + +template +template +_ForwardIterator +basic_regex<_CharT, _Traits>::__parse_ORD_CHAR(_ForwardIterator __first, + _ForwardIterator __last) +{ + if (__first != __last) + { + _ForwardIterator __temp = _VSTD::next(__first); + if (__temp == __last && *__first == '$') + return __first; + // Not called inside a bracket + if (*__first == '.' || *__first == '\\' || *__first == '[') + return __first; + __push_char(*__first); + ++__first; + } + return __first; +} + +template +template +_ForwardIterator +basic_regex<_CharT, _Traits>::__parse_ORD_CHAR_ERE(_ForwardIterator __first, + _ForwardIterator __last) +{ + if (__first != __last) + { + switch (*__first) + { + case '^': + case '.': + case '[': + case '$': + case '(': + case '|': + case '*': + case '+': + case '?': + case '{': + case '\\': + break; + case ')': + if (__open_count_ == 0) + { + __push_char(*__first); + ++__first; + } + break; + default: + __push_char(*__first); + ++__first; + break; + } + } + return __first; +} + +template +template +_ForwardIterator +basic_regex<_CharT, _Traits>::__parse_QUOTED_CHAR(_ForwardIterator __first, + _ForwardIterator __last) +{ + if (__first != __last) + { + _ForwardIterator __temp = _VSTD::next(__first); + if (__temp != __last) + { + if (*__first == '\\') + { + switch (*__temp) + { + case '^': + case '.': + case '*': + case '[': + case '$': + case '\\': + __push_char(*__temp); + __first = ++__temp; + break; + } + } + } + } + return __first; +} + +template +template +_ForwardIterator +basic_regex<_CharT, _Traits>::__parse_QUOTED_CHAR_ERE(_ForwardIterator __first, + _ForwardIterator __last) +{ + if (__first != __last) + { + _ForwardIterator __temp = _VSTD::next(__first); + if (__temp != __last) + { + if (*__first == '\\') + { + switch (*__temp) + { + case '^': + case '.': + case '*': + case '[': + case '$': + case '\\': + case '(': + case ')': + case '|': + case '+': + case '?': + case '{': + case '}': + __push_char(*__temp); + __first = ++__temp; + break; + default: + if (__get_grammar(__flags_) == awk) + __first = __parse_awk_escape(++__first, __last); + break; + } + } + } + } + return __first; +} + +template +template +_ForwardIterator +basic_regex<_CharT, _Traits>::__parse_RE_dupl_symbol(_ForwardIterator __first, + _ForwardIterator __last, + __owns_one_state<_CharT>* __s, + unsigned __mexp_begin, + unsigned __mexp_end) +{ + if (__first != __last) + { + if (*__first == '*') + { + __push_greedy_inf_repeat(0, __s, __mexp_begin, __mexp_end); + ++__first; + } + else + { + _ForwardIterator __temp = __parse_Back_open_brace(__first, __last); + if (__temp != __first) + { + int __min = 0; + __first = __temp; + __temp = __parse_DUP_COUNT(__first, __last, __min); + if (__temp == __first) + __throw_regex_error(); + __first = __temp; + if (__first == __last) + __throw_regex_error(); + if (*__first != ',') + { + __temp = __parse_Back_close_brace(__first, __last); + if (__temp == __first) + __throw_regex_error(); + __push_loop(__min, __min, __s, __mexp_begin, __mexp_end, + true); + __first = __temp; + } + else + { + ++__first; // consume ',' + int __max = -1; + __first = __parse_DUP_COUNT(__first, __last, __max); + __temp = __parse_Back_close_brace(__first, __last); + if (__temp == __first) + __throw_regex_error(); + if (__max == -1) + __push_greedy_inf_repeat(__min, __s, __mexp_begin, __mexp_end); + else + { + if (__max < __min) + __throw_regex_error(); + __push_loop(__min, __max, __s, __mexp_begin, __mexp_end, + true); + } + __first = __temp; + } + } + } + } + return __first; +} + +template +template +_ForwardIterator +basic_regex<_CharT, _Traits>::__parse_ERE_dupl_symbol(_ForwardIterator __first, + _ForwardIterator __last, + __owns_one_state<_CharT>* __s, + unsigned __mexp_begin, + unsigned __mexp_end) +{ + if (__first != __last) + { + unsigned __grammar = __get_grammar(__flags_); + switch (*__first) + { + case '*': + ++__first; + if (__grammar == ECMAScript && __first != __last && *__first == '?') + { + ++__first; + __push_nongreedy_inf_repeat(0, __s, __mexp_begin, __mexp_end); + } + else + __push_greedy_inf_repeat(0, __s, __mexp_begin, __mexp_end); + break; + case '+': + ++__first; + if (__grammar == ECMAScript && __first != __last && *__first == '?') + { + ++__first; + __push_nongreedy_inf_repeat(1, __s, __mexp_begin, __mexp_end); + } + else + __push_greedy_inf_repeat(1, __s, __mexp_begin, __mexp_end); + break; + case '?': + ++__first; + if (__grammar == ECMAScript && __first != __last && *__first == '?') + { + ++__first; + __push_loop(0, 1, __s, __mexp_begin, __mexp_end, false); + } + else + __push_loop(0, 1, __s, __mexp_begin, __mexp_end); + break; + case '{': + { + int __min; + _ForwardIterator __temp = __parse_DUP_COUNT(++__first, __last, __min); + if (__temp == __first) + __throw_regex_error(); + __first = __temp; + if (__first == __last) + __throw_regex_error(); + switch (*__first) + { + case '}': + ++__first; + if (__grammar == ECMAScript && __first != __last && *__first == '?') + { + ++__first; + __push_loop(__min, __min, __s, __mexp_begin, __mexp_end, false); + } + else + __push_loop(__min, __min, __s, __mexp_begin, __mexp_end); + break; + case ',': + ++__first; + if (__first == __last) + __throw_regex_error(); + if (*__first == '}') + { + ++__first; + if (__grammar == ECMAScript && __first != __last && *__first == '?') + { + ++__first; + __push_nongreedy_inf_repeat(__min, __s, __mexp_begin, __mexp_end); + } + else + __push_greedy_inf_repeat(__min, __s, __mexp_begin, __mexp_end); + } + else + { + int __max = -1; + __temp = __parse_DUP_COUNT(__first, __last, __max); + if (__temp == __first) + __throw_regex_error(); + __first = __temp; + if (__first == __last || *__first != '}') + __throw_regex_error(); + ++__first; + if (__max < __min) + __throw_regex_error(); + if (__grammar == ECMAScript && __first != __last && *__first == '?') + { + ++__first; + __push_loop(__min, __max, __s, __mexp_begin, __mexp_end, false); + } + else + __push_loop(__min, __max, __s, __mexp_begin, __mexp_end); + } + break; + default: + __throw_regex_error(); + } + } + break; + } + } + return __first; +} + +template +template +_ForwardIterator +basic_regex<_CharT, _Traits>::__parse_bracket_expression(_ForwardIterator __first, + _ForwardIterator __last) +{ + if (__first != __last && *__first == '[') + { + ++__first; + if (__first == __last) + __throw_regex_error(); + bool __negate = false; + if (*__first == '^') + { + ++__first; + __negate = true; + } + __bracket_expression<_CharT, _Traits>* __ml = __start_matching_list(__negate); + // __ml owned by *this + if (__first == __last) + __throw_regex_error(); + if (__get_grammar(__flags_) != ECMAScript && *__first == ']') + { + __ml->__add_char(']'); + ++__first; + } + __first = __parse_follow_list(__first, __last, __ml); + if (__first == __last) + __throw_regex_error(); + if (*__first == '-') + { + __ml->__add_char('-'); + ++__first; + } + if (__first == __last || *__first != ']') + __throw_regex_error(); + ++__first; + } + return __first; +} + +template +template +_ForwardIterator +basic_regex<_CharT, _Traits>::__parse_follow_list(_ForwardIterator __first, + _ForwardIterator __last, + __bracket_expression<_CharT, _Traits>* __ml) +{ + if (__first != __last) + { + while (true) + { + _ForwardIterator __temp = __parse_expression_term(__first, __last, + __ml); + if (__temp == __first) + break; + __first = __temp; + } + } + return __first; +} + +template +template +_ForwardIterator +basic_regex<_CharT, _Traits>::__parse_expression_term(_ForwardIterator __first, + _ForwardIterator __last, + __bracket_expression<_CharT, _Traits>* __ml) +{ + if (__first != __last && *__first != ']') + { + _ForwardIterator __temp = _VSTD::next(__first); + basic_string<_CharT> __start_range; + if (__temp != __last && *__first == '[') + { + if (*__temp == '=') + return __parse_equivalence_class(++__temp, __last, __ml); + else if (*__temp == ':') + return __parse_character_class(++__temp, __last, __ml); + else if (*__temp == '.') + __first = __parse_collating_symbol(++__temp, __last, __start_range); + } + unsigned __grammar = __get_grammar(__flags_); + if (__start_range.empty()) + { + if ((__grammar == ECMAScript || __grammar == awk) && *__first == '\\') + { + if (__grammar == ECMAScript) + __first = __parse_class_escape(++__first, __last, __start_range, __ml); + else + __first = __parse_awk_escape(++__first, __last, &__start_range); + } + else + { + __start_range = *__first; + ++__first; + } + } + if (__first != __last && *__first != ']') + { + __temp = _VSTD::next(__first); + if (__temp != __last && *__first == '-' && *__temp != ']') + { + // parse a range + basic_string<_CharT> __end_range; + __first = __temp; + ++__temp; + if (__temp != __last && *__first == '[' && *__temp == '.') + __first = __parse_collating_symbol(++__temp, __last, __end_range); + else + { + if ((__grammar == ECMAScript || __grammar == awk) && *__first == '\\') + { + if (__grammar == ECMAScript) + __first = __parse_class_escape(++__first, __last, + __end_range, __ml); + else + __first = __parse_awk_escape(++__first, __last, + &__end_range); + } + else + { + __end_range = *__first; + ++__first; + } + } + __ml->__add_range(_VSTD::move(__start_range), _VSTD::move(__end_range)); + } + else if (!__start_range.empty()) + { + if (__start_range.size() == 1) + __ml->__add_char(__start_range[0]); + else + __ml->__add_digraph(__start_range[0], __start_range[1]); + } + } + else if (!__start_range.empty()) + { + if (__start_range.size() == 1) + __ml->__add_char(__start_range[0]); + else + __ml->__add_digraph(__start_range[0], __start_range[1]); + } + } + return __first; +} + +template +template +_ForwardIterator +basic_regex<_CharT, _Traits>::__parse_class_escape(_ForwardIterator __first, + _ForwardIterator __last, + basic_string<_CharT>& __str, + __bracket_expression<_CharT, _Traits>* __ml) +{ + if (__first == __last) + __throw_regex_error(); + switch (*__first) + { + case 0: + __str = *__first; + return ++__first; + case 'b': + __str = _CharT(8); + return ++__first; + case 'd': + __ml->__add_class(ctype_base::digit); + return ++__first; + case 'D': + __ml->__add_neg_class(ctype_base::digit); + return ++__first; + case 's': + __ml->__add_class(ctype_base::space); + return ++__first; + case 'S': + __ml->__add_neg_class(ctype_base::space); + return ++__first; + case 'w': + __ml->__add_class(ctype_base::alnum); + __ml->__add_char('_'); + return ++__first; + case 'W': + __ml->__add_neg_class(ctype_base::alnum); + __ml->__add_neg_char('_'); + return ++__first; + } + __first = __parse_character_escape(__first, __last, &__str); + return __first; +} + +template +template +_ForwardIterator +basic_regex<_CharT, _Traits>::__parse_awk_escape(_ForwardIterator __first, + _ForwardIterator __last, + basic_string<_CharT>* __str) +{ + if (__first == __last) + __throw_regex_error(); + switch (*__first) + { + case '\\': + case '"': + case '/': + if (__str) + *__str = *__first; + else + __push_char(*__first); + return ++__first; + case 'a': + if (__str) + *__str = _CharT(7); + else + __push_char(_CharT(7)); + return ++__first; + case 'b': + if (__str) + *__str = _CharT(8); + else + __push_char(_CharT(8)); + return ++__first; + case 'f': + if (__str) + *__str = _CharT(0xC); + else + __push_char(_CharT(0xC)); + return ++__first; + case 'n': + if (__str) + *__str = _CharT(0xA); + else + __push_char(_CharT(0xA)); + return ++__first; + case 'r': + if (__str) + *__str = _CharT(0xD); + else + __push_char(_CharT(0xD)); + return ++__first; + case 't': + if (__str) + *__str = _CharT(0x9); + else + __push_char(_CharT(0x9)); + return ++__first; + case 'v': + if (__str) + *__str = _CharT(0xB); + else + __push_char(_CharT(0xB)); + return ++__first; + } + if ('0' <= *__first && *__first <= '7') + { + unsigned __val = *__first - '0'; + if (++__first != __last && ('0' <= *__first && *__first <= '7')) + { + __val = 8 * __val + *__first - '0'; + if (++__first != __last && ('0' <= *__first && *__first <= '7')) + __val = 8 * __val + *__first++ - '0'; + } + if (__str) + *__str = _CharT(__val); + else + __push_char(_CharT(__val)); + } + else + __throw_regex_error(); + return __first; +} + +template +template +_ForwardIterator +basic_regex<_CharT, _Traits>::__parse_equivalence_class(_ForwardIterator __first, + _ForwardIterator __last, + __bracket_expression<_CharT, _Traits>* __ml) +{ + // Found [= + // This means =] must exist + value_type _Equal_close[2] = {'=', ']'}; + _ForwardIterator __temp = _VSTD::search(__first, __last, _Equal_close, + _Equal_close+2); + if (__temp == __last) + __throw_regex_error(); + // [__first, __temp) contains all text in [= ... =] + string_type __collate_name = + __traits_.lookup_collatename(__first, __temp); + if (__collate_name.empty()) + __throw_regex_error(); + string_type __equiv_name = + __traits_.transform_primary(__collate_name.begin(), + __collate_name.end()); + if (!__equiv_name.empty()) + __ml->__add_equivalence(__equiv_name); + else + { + switch (__collate_name.size()) + { + case 1: + __ml->__add_char(__collate_name[0]); + break; + case 2: + __ml->__add_digraph(__collate_name[0], __collate_name[1]); + break; + default: + __throw_regex_error(); + } + } + __first = _VSTD::next(__temp, 2); + return __first; +} + +template +template +_ForwardIterator +basic_regex<_CharT, _Traits>::__parse_character_class(_ForwardIterator __first, + _ForwardIterator __last, + __bracket_expression<_CharT, _Traits>* __ml) +{ + // Found [: + // This means :] must exist + value_type _Colon_close[2] = {':', ']'}; + _ForwardIterator __temp = _VSTD::search(__first, __last, _Colon_close, + _Colon_close+2); + if (__temp == __last) + __throw_regex_error(); + // [__first, __temp) contains all text in [: ... :] + typedef typename _Traits::char_class_type char_class_type; + char_class_type __class_type = + __traits_.lookup_classname(__first, __temp, __flags_ & icase); + if (__class_type == 0) + __throw_regex_error(); + __ml->__add_class(__class_type); + __first = _VSTD::next(__temp, 2); + return __first; +} + +template +template +_ForwardIterator +basic_regex<_CharT, _Traits>::__parse_collating_symbol(_ForwardIterator __first, + _ForwardIterator __last, + basic_string<_CharT>& __col_sym) +{ + // Found [. + // This means .] must exist + value_type _Dot_close[2] = {'.', ']'}; + _ForwardIterator __temp = _VSTD::search(__first, __last, _Dot_close, + _Dot_close+2); + if (__temp == __last) + __throw_regex_error(); + // [__first, __temp) contains all text in [. ... .] + __col_sym = __traits_.lookup_collatename(__first, __temp); + switch (__col_sym.size()) + { + case 1: + case 2: + break; + default: + __throw_regex_error(); + } + __first = _VSTD::next(__temp, 2); + return __first; +} + +template +template +_ForwardIterator +basic_regex<_CharT, _Traits>::__parse_DUP_COUNT(_ForwardIterator __first, + _ForwardIterator __last, + int& __c) +{ + if (__first != __last ) + { + int __val = __traits_.value(*__first, 10); + if ( __val != -1 ) + { + __c = __val; + for (++__first; + __first != __last && ( __val = __traits_.value(*__first, 10)) != -1; + ++__first) + { + if (__c >= std::numeric_limits::max() / 10) + __throw_regex_error(); + __c *= 10; + __c += __val; + } + } + } + return __first; +} + +template +template +_ForwardIterator +basic_regex<_CharT, _Traits>::__parse_ecma_exp(_ForwardIterator __first, + _ForwardIterator __last) +{ + __owns_one_state<_CharT>* __sa = __end_; + _ForwardIterator __temp = __parse_alternative(__first, __last); + if (__temp == __first) + __push_empty(); + __first = __temp; + while (__first != __last && *__first == '|') + { + __owns_one_state<_CharT>* __sb = __end_; + __temp = __parse_alternative(++__first, __last); + if (__temp == __first) + __push_empty(); + __push_alternation(__sa, __sb); + __first = __temp; + } + return __first; +} + +template +template +_ForwardIterator +basic_regex<_CharT, _Traits>::__parse_alternative(_ForwardIterator __first, + _ForwardIterator __last) +{ + while (true) + { + _ForwardIterator __temp = __parse_term(__first, __last); + if (__temp == __first) + break; + __first = __temp; + } + return __first; +} + +template +template +_ForwardIterator +basic_regex<_CharT, _Traits>::__parse_term(_ForwardIterator __first, + _ForwardIterator __last) +{ + _ForwardIterator __temp = __parse_assertion(__first, __last); + if (__temp == __first) + { + __owns_one_state<_CharT>* __e = __end_; + unsigned __mexp_begin = __marked_count_; + __temp = __parse_atom(__first, __last); + if (__temp != __first) + __first = __parse_ERE_dupl_symbol(__temp, __last, __e, + __mexp_begin+1, __marked_count_+1); + } + else + __first = __temp; + return __first; +} + +template +template +_ForwardIterator +basic_regex<_CharT, _Traits>::__parse_assertion(_ForwardIterator __first, + _ForwardIterator __last) +{ + if (__first != __last) + { + switch (*__first) + { + case '^': + __push_l_anchor(); + ++__first; + break; + case '$': + __push_r_anchor(); + ++__first; + break; + case '\\': + { + _ForwardIterator __temp = _VSTD::next(__first); + if (__temp != __last) + { + if (*__temp == 'b') + { + __push_word_boundary(false); + __first = ++__temp; + } + else if (*__temp == 'B') + { + __push_word_boundary(true); + __first = ++__temp; + } + } + } + break; + case '(': + { + _ForwardIterator __temp = _VSTD::next(__first); + if (__temp != __last && *__temp == '?') + { + if (++__temp != __last) + { + switch (*__temp) + { + case '=': + { + basic_regex __exp; + __exp.__flags_ = __flags_; + __temp = __exp.__parse(++__temp, __last); + unsigned __mexp = __exp.__marked_count_; + __push_lookahead(_VSTD::move(__exp), false, __marked_count_); + __marked_count_ += __mexp; + if (__temp == __last || *__temp != ')') + __throw_regex_error(); + __first = ++__temp; + } + break; + case '!': + { + basic_regex __exp; + __exp.__flags_ = __flags_; + __temp = __exp.__parse(++__temp, __last); + unsigned __mexp = __exp.__marked_count_; + __push_lookahead(_VSTD::move(__exp), true, __marked_count_); + __marked_count_ += __mexp; + if (__temp == __last || *__temp != ')') + __throw_regex_error(); + __first = ++__temp; + } + break; + } + } + } + } + break; + } + } + return __first; +} + +template +template +_ForwardIterator +basic_regex<_CharT, _Traits>::__parse_atom(_ForwardIterator __first, + _ForwardIterator __last) +{ + if (__first != __last) + { + switch (*__first) + { + case '.': + __push_match_any_but_newline(); + ++__first; + break; + case '\\': + __first = __parse_atom_escape(__first, __last); + break; + case '[': + __first = __parse_bracket_expression(__first, __last); + break; + case '(': + { + ++__first; + if (__first == __last) + __throw_regex_error(); + _ForwardIterator __temp = _VSTD::next(__first); + if (__temp != __last && *__first == '?' && *__temp == ':') + { + ++__open_count_; + __first = __parse_ecma_exp(++__temp, __last); + if (__first == __last || *__first != ')') + __throw_regex_error(); + --__open_count_; + ++__first; + } + else + { + __push_begin_marked_subexpression(); + unsigned __temp_count = __marked_count_; + ++__open_count_; + __first = __parse_ecma_exp(__first, __last); + if (__first == __last || *__first != ')') + __throw_regex_error(); + __push_end_marked_subexpression(__temp_count); + --__open_count_; + ++__first; + } + } + break; + case '*': + case '+': + case '?': + case '{': + __throw_regex_error(); + break; + default: + __first = __parse_pattern_character(__first, __last); + break; + } + } + return __first; +} + +template +template +_ForwardIterator +basic_regex<_CharT, _Traits>::__parse_atom_escape(_ForwardIterator __first, + _ForwardIterator __last) +{ + if (__first != __last && *__first == '\\') + { + _ForwardIterator __t1 = _VSTD::next(__first); + if (__t1 == __last) + __throw_regex_error(); + + _ForwardIterator __t2 = __parse_decimal_escape(__t1, __last); + if (__t2 != __t1) + __first = __t2; + else + { + __t2 = __parse_character_class_escape(__t1, __last); + if (__t2 != __t1) + __first = __t2; + else + { + __t2 = __parse_character_escape(__t1, __last); + if (__t2 != __t1) + __first = __t2; + } + } + } + return __first; +} + +template +template +_ForwardIterator +basic_regex<_CharT, _Traits>::__parse_decimal_escape(_ForwardIterator __first, + _ForwardIterator __last) +{ + if (__first != __last) + { + if (*__first == '0') + { + __push_char(_CharT()); + ++__first; + } + else if ('1' <= *__first && *__first <= '9') + { + unsigned __v = *__first - '0'; + for (++__first; + __first != __last && '0' <= *__first && *__first <= '9'; ++__first) + { + if (__v >= std::numeric_limits::max() / 10) + __throw_regex_error(); + __v = 10 * __v + *__first - '0'; + } + if (__v == 0 || __v > mark_count()) + __throw_regex_error(); + __push_back_ref(__v); + } + } + return __first; +} + +template +template +_ForwardIterator +basic_regex<_CharT, _Traits>::__parse_character_class_escape(_ForwardIterator __first, + _ForwardIterator __last) +{ + if (__first != __last) + { + __bracket_expression<_CharT, _Traits>* __ml; + switch (*__first) + { + case 'd': + __ml = __start_matching_list(false); + __ml->__add_class(ctype_base::digit); + ++__first; + break; + case 'D': + __ml = __start_matching_list(true); + __ml->__add_class(ctype_base::digit); + ++__first; + break; + case 's': + __ml = __start_matching_list(false); + __ml->__add_class(ctype_base::space); + ++__first; + break; + case 'S': + __ml = __start_matching_list(true); + __ml->__add_class(ctype_base::space); + ++__first; + break; + case 'w': + __ml = __start_matching_list(false); + __ml->__add_class(ctype_base::alnum); + __ml->__add_char('_'); + ++__first; + break; + case 'W': + __ml = __start_matching_list(true); + __ml->__add_class(ctype_base::alnum); + __ml->__add_char('_'); + ++__first; + break; + } + } + return __first; +} + +template +template +_ForwardIterator +basic_regex<_CharT, _Traits>::__parse_character_escape(_ForwardIterator __first, + _ForwardIterator __last, + basic_string<_CharT>* __str) +{ + if (__first != __last) + { + _ForwardIterator __t; + unsigned __sum = 0; + int __hd; + switch (*__first) + { + case 'f': + if (__str) + *__str = _CharT(0xC); + else + __push_char(_CharT(0xC)); + ++__first; + break; + case 'n': + if (__str) + *__str = _CharT(0xA); + else + __push_char(_CharT(0xA)); + ++__first; + break; + case 'r': + if (__str) + *__str = _CharT(0xD); + else + __push_char(_CharT(0xD)); + ++__first; + break; + case 't': + if (__str) + *__str = _CharT(0x9); + else + __push_char(_CharT(0x9)); + ++__first; + break; + case 'v': + if (__str) + *__str = _CharT(0xB); + else + __push_char(_CharT(0xB)); + ++__first; + break; + case 'c': + if ((__t = _VSTD::next(__first)) != __last) + { + if (('A' <= *__t && *__t <= 'Z') || + ('a' <= *__t && *__t <= 'z')) + { + if (__str) + *__str = _CharT(*__t % 32); + else + __push_char(_CharT(*__t % 32)); + __first = ++__t; + } + else + __throw_regex_error(); + } + else + __throw_regex_error(); + break; + case 'u': + ++__first; + if (__first == __last) + __throw_regex_error(); + __hd = __traits_.value(*__first, 16); + if (__hd == -1) + __throw_regex_error(); + __sum = 16 * __sum + static_cast(__hd); + ++__first; + if (__first == __last) + __throw_regex_error(); + __hd = __traits_.value(*__first, 16); + if (__hd == -1) + __throw_regex_error(); + __sum = 16 * __sum + static_cast(__hd); + // drop through + case 'x': + ++__first; + if (__first == __last) + __throw_regex_error(); + __hd = __traits_.value(*__first, 16); + if (__hd == -1) + __throw_regex_error(); + __sum = 16 * __sum + static_cast(__hd); + ++__first; + if (__first == __last) + __throw_regex_error(); + __hd = __traits_.value(*__first, 16); + if (__hd == -1) + __throw_regex_error(); + __sum = 16 * __sum + static_cast(__hd); + if (__str) + *__str = _CharT(__sum); + else + __push_char(_CharT(__sum)); + ++__first; + break; + case '0': + if (__str) + *__str = _CharT(0); + else + __push_char(_CharT(0)); + ++__first; + break; + default: + if (*__first != '_' && !__traits_.isctype(*__first, ctype_base::alnum)) + { + if (__str) + *__str = *__first; + else + __push_char(*__first); + ++__first; + } + else + __throw_regex_error(); + break; + } + } + return __first; +} + +template +template +_ForwardIterator +basic_regex<_CharT, _Traits>::__parse_pattern_character(_ForwardIterator __first, + _ForwardIterator __last) +{ + if (__first != __last) + { + switch (*__first) + { + case '^': + case '$': + case '\\': + case '.': + case '*': + case '+': + case '?': + case '(': + case ')': + case '[': + case ']': + case '{': + case '}': + case '|': + break; + default: + __push_char(*__first); + ++__first; + break; + } + } + return __first; +} + +template +template +_ForwardIterator +basic_regex<_CharT, _Traits>::__parse_grep(_ForwardIterator __first, + _ForwardIterator __last) +{ + __owns_one_state<_CharT>* __sa = __end_; + _ForwardIterator __t1 = _VSTD::find(__first, __last, _CharT('\n')); + if (__t1 != __first) + __parse_basic_reg_exp(__first, __t1); + else + __push_empty(); + __first = __t1; + if (__first != __last) + ++__first; + while (__first != __last) + { + __t1 = _VSTD::find(__first, __last, _CharT('\n')); + __owns_one_state<_CharT>* __sb = __end_; + if (__t1 != __first) + __parse_basic_reg_exp(__first, __t1); + else + __push_empty(); + __push_alternation(__sa, __sb); + __first = __t1; + if (__first != __last) + ++__first; + } + return __first; +} + +template +template +_ForwardIterator +basic_regex<_CharT, _Traits>::__parse_egrep(_ForwardIterator __first, + _ForwardIterator __last) +{ + __owns_one_state<_CharT>* __sa = __end_; + _ForwardIterator __t1 = _VSTD::find(__first, __last, _CharT('\n')); + if (__t1 != __first) + __parse_extended_reg_exp(__first, __t1); + else + __push_empty(); + __first = __t1; + if (__first != __last) + ++__first; + while (__first != __last) + { + __t1 = _VSTD::find(__first, __last, _CharT('\n')); + __owns_one_state<_CharT>* __sb = __end_; + if (__t1 != __first) + __parse_extended_reg_exp(__first, __t1); + else + __push_empty(); + __push_alternation(__sa, __sb); + __first = __t1; + if (__first != __last) + ++__first; + } + return __first; +} + +template +void +basic_regex<_CharT, _Traits>::__push_loop(size_t __min, size_t __max, + __owns_one_state<_CharT>* __s, size_t __mexp_begin, size_t __mexp_end, + bool __greedy) +{ + unique_ptr<__empty_state<_CharT> > __e1(new __empty_state<_CharT>(__end_->first())); + __end_->first() = nullptr; + unique_ptr<__loop<_CharT> > __e2(new __loop<_CharT>(__loop_count_, + __s->first(), __e1.get(), __mexp_begin, __mexp_end, __greedy, + __min, __max)); + __s->first() = nullptr; + __e1.release(); + __end_->first() = new __repeat_one_loop<_CharT>(__e2.get()); + __end_ = __e2->second(); + __s->first() = __e2.release(); + ++__loop_count_; +} + +template +void +basic_regex<_CharT, _Traits>::__push_char(value_type __c) +{ + if (flags() & icase) + __end_->first() = new __match_char_icase<_CharT, _Traits> + (__traits_, __c, __end_->first()); + else if (flags() & collate) + __end_->first() = new __match_char_collate<_CharT, _Traits> + (__traits_, __c, __end_->first()); + else + __end_->first() = new __match_char<_CharT>(__c, __end_->first()); + __end_ = static_cast<__owns_one_state<_CharT>*>(__end_->first()); +} + +template +void +basic_regex<_CharT, _Traits>::__push_begin_marked_subexpression() +{ + if (!(__flags_ & nosubs)) + { + __end_->first() = + new __begin_marked_subexpression<_CharT>(++__marked_count_, + __end_->first()); + __end_ = static_cast<__owns_one_state<_CharT>*>(__end_->first()); + } +} + +template +void +basic_regex<_CharT, _Traits>::__push_end_marked_subexpression(unsigned __sub) +{ + if (!(__flags_ & nosubs)) + { + __end_->first() = + new __end_marked_subexpression<_CharT>(__sub, __end_->first()); + __end_ = static_cast<__owns_one_state<_CharT>*>(__end_->first()); + } +} + +template +void +basic_regex<_CharT, _Traits>::__push_l_anchor() +{ + __end_->first() = new __l_anchor<_CharT>(__end_->first()); + __end_ = static_cast<__owns_one_state<_CharT>*>(__end_->first()); +} + +template +void +basic_regex<_CharT, _Traits>::__push_r_anchor() +{ + __end_->first() = new __r_anchor<_CharT>(__end_->first()); + __end_ = static_cast<__owns_one_state<_CharT>*>(__end_->first()); +} + +template +void +basic_regex<_CharT, _Traits>::__push_match_any() +{ + __end_->first() = new __match_any<_CharT>(__end_->first()); + __end_ = static_cast<__owns_one_state<_CharT>*>(__end_->first()); +} + +template +void +basic_regex<_CharT, _Traits>::__push_match_any_but_newline() +{ + __end_->first() = new __match_any_but_newline<_CharT>(__end_->first()); + __end_ = static_cast<__owns_one_state<_CharT>*>(__end_->first()); +} + +template +void +basic_regex<_CharT, _Traits>::__push_empty() +{ + __end_->first() = new __empty_state<_CharT>(__end_->first()); + __end_ = static_cast<__owns_one_state<_CharT>*>(__end_->first()); +} + +template +void +basic_regex<_CharT, _Traits>::__push_word_boundary(bool __invert) +{ + __end_->first() = new __word_boundary<_CharT, _Traits>(__traits_, __invert, + __end_->first()); + __end_ = static_cast<__owns_one_state<_CharT>*>(__end_->first()); +} + +template +void +basic_regex<_CharT, _Traits>::__push_back_ref(int __i) +{ + if (flags() & icase) + __end_->first() = new __back_ref_icase<_CharT, _Traits> + (__traits_, __i, __end_->first()); + else if (flags() & collate) + __end_->first() = new __back_ref_collate<_CharT, _Traits> + (__traits_, __i, __end_->first()); + else + __end_->first() = new __back_ref<_CharT>(__i, __end_->first()); + __end_ = static_cast<__owns_one_state<_CharT>*>(__end_->first()); +} + +template +void +basic_regex<_CharT, _Traits>::__push_alternation(__owns_one_state<_CharT>* __sa, + __owns_one_state<_CharT>* __ea) +{ + __sa->first() = new __alternate<_CharT>( + static_cast<__owns_one_state<_CharT>*>(__sa->first()), + static_cast<__owns_one_state<_CharT>*>(__ea->first())); + __ea->first() = nullptr; + __ea->first() = new __empty_state<_CharT>(__end_->first()); + __end_->first() = nullptr; + __end_->first() = new __empty_non_own_state<_CharT>(__ea->first()); + __end_ = static_cast<__owns_one_state<_CharT>*>(__ea->first()); +} + +template +__bracket_expression<_CharT, _Traits>* +basic_regex<_CharT, _Traits>::__start_matching_list(bool __negate) +{ + __bracket_expression<_CharT, _Traits>* __r = + new __bracket_expression<_CharT, _Traits>(__traits_, __end_->first(), + __negate, __flags_ & icase, + __flags_ & collate); + __end_->first() = __r; + __end_ = __r; + return __r; +} + +template +void +basic_regex<_CharT, _Traits>::__push_lookahead(const basic_regex& __exp, + bool __invert, + unsigned __mexp) +{ + __end_->first() = new __lookahead<_CharT, _Traits>(__exp, __invert, + __end_->first(), __mexp); + __end_ = static_cast<__owns_one_state<_CharT>*>(__end_->first()); +} + +typedef basic_regex regex; +typedef basic_regex wregex; + +// sub_match + +template +class _LIBCPP_TEMPLATE_VIS sub_match + : public pair<_BidirectionalIterator, _BidirectionalIterator> +{ +public: + typedef _BidirectionalIterator iterator; + typedef typename iterator_traits::value_type value_type; + typedef typename iterator_traits::difference_type difference_type; + typedef basic_string string_type; + + bool matched; + + _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR sub_match() : matched() {} + + _LIBCPP_INLINE_VISIBILITY + difference_type length() const + {return matched ? _VSTD::distance(this->first, this->second) : 0;} + _LIBCPP_INLINE_VISIBILITY + string_type str() const + {return matched ? string_type(this->first, this->second) : string_type();} + _LIBCPP_INLINE_VISIBILITY + operator string_type() const + {return str();} + + _LIBCPP_INLINE_VISIBILITY + int compare(const sub_match& __s) const + {return str().compare(__s.str());} + _LIBCPP_INLINE_VISIBILITY + int compare(const string_type& __s) const + {return str().compare(__s);} + _LIBCPP_INLINE_VISIBILITY + int compare(const value_type* __s) const + {return str().compare(__s);} +}; + +typedef sub_match csub_match; +typedef sub_match wcsub_match; +typedef sub_match ssub_match; +typedef sub_match wssub_match; + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator==(const sub_match<_BiIter>& __x, const sub_match<_BiIter>& __y) +{ + return __x.compare(__y) == 0; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator!=(const sub_match<_BiIter>& __x, const sub_match<_BiIter>& __y) +{ + return !(__x == __y); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator<(const sub_match<_BiIter>& __x, const sub_match<_BiIter>& __y) +{ + return __x.compare(__y) < 0; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator<=(const sub_match<_BiIter>& __x, const sub_match<_BiIter>& __y) +{ + return !(__y < __x); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator>=(const sub_match<_BiIter>& __x, const sub_match<_BiIter>& __y) +{ + return !(__x < __y); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator>(const sub_match<_BiIter>& __x, const sub_match<_BiIter>& __y) +{ + return __y < __x; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator==(const basic_string::value_type, _ST, _SA>& __x, + const sub_match<_BiIter>& __y) +{ + return __y.compare(typename sub_match<_BiIter>::string_type(__x.data(), __x.size())) == 0; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator!=(const basic_string::value_type, _ST, _SA>& __x, + const sub_match<_BiIter>& __y) +{ + return !(__x == __y); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator<(const basic_string::value_type, _ST, _SA>& __x, + const sub_match<_BiIter>& __y) +{ + return __y.compare(typename sub_match<_BiIter>::string_type(__x.data(), __x.size())) > 0; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator>(const basic_string::value_type, _ST, _SA>& __x, + const sub_match<_BiIter>& __y) +{ + return __y < __x; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool operator>=(const basic_string::value_type, _ST, _SA>& __x, + const sub_match<_BiIter>& __y) +{ + return !(__x < __y); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator<=(const basic_string::value_type, _ST, _SA>& __x, + const sub_match<_BiIter>& __y) +{ + return !(__y < __x); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator==(const sub_match<_BiIter>& __x, + const basic_string::value_type, _ST, _SA>& __y) +{ + return __x.compare(typename sub_match<_BiIter>::string_type(__y.data(), __y.size())) == 0; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator!=(const sub_match<_BiIter>& __x, + const basic_string::value_type, _ST, _SA>& __y) +{ + return !(__x == __y); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator<(const sub_match<_BiIter>& __x, + const basic_string::value_type, _ST, _SA>& __y) +{ + return __x.compare(typename sub_match<_BiIter>::string_type(__y.data(), __y.size())) < 0; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool operator>(const sub_match<_BiIter>& __x, + const basic_string::value_type, _ST, _SA>& __y) +{ + return __y < __x; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator>=(const sub_match<_BiIter>& __x, + const basic_string::value_type, _ST, _SA>& __y) +{ + return !(__x < __y); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator<=(const sub_match<_BiIter>& __x, + const basic_string::value_type, _ST, _SA>& __y) +{ + return !(__y < __x); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator==(typename iterator_traits<_BiIter>::value_type const* __x, + const sub_match<_BiIter>& __y) +{ + return __y.compare(__x) == 0; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator!=(typename iterator_traits<_BiIter>::value_type const* __x, + const sub_match<_BiIter>& __y) +{ + return !(__x == __y); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator<(typename iterator_traits<_BiIter>::value_type const* __x, + const sub_match<_BiIter>& __y) +{ + return __y.compare(__x) > 0; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator>(typename iterator_traits<_BiIter>::value_type const* __x, + const sub_match<_BiIter>& __y) +{ + return __y < __x; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator>=(typename iterator_traits<_BiIter>::value_type const* __x, + const sub_match<_BiIter>& __y) +{ + return !(__x < __y); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator<=(typename iterator_traits<_BiIter>::value_type const* __x, + const sub_match<_BiIter>& __y) +{ + return !(__y < __x); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator==(const sub_match<_BiIter>& __x, + typename iterator_traits<_BiIter>::value_type const* __y) +{ + return __x.compare(__y) == 0; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator!=(const sub_match<_BiIter>& __x, + typename iterator_traits<_BiIter>::value_type const* __y) +{ + return !(__x == __y); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator<(const sub_match<_BiIter>& __x, + typename iterator_traits<_BiIter>::value_type const* __y) +{ + return __x.compare(__y) < 0; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator>(const sub_match<_BiIter>& __x, + typename iterator_traits<_BiIter>::value_type const* __y) +{ + return __y < __x; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator>=(const sub_match<_BiIter>& __x, + typename iterator_traits<_BiIter>::value_type const* __y) +{ + return !(__x < __y); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator<=(const sub_match<_BiIter>& __x, + typename iterator_traits<_BiIter>::value_type const* __y) +{ + return !(__y < __x); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator==(typename iterator_traits<_BiIter>::value_type const& __x, + const sub_match<_BiIter>& __y) +{ + typedef basic_string::value_type> string_type; + return __y.compare(string_type(1, __x)) == 0; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator!=(typename iterator_traits<_BiIter>::value_type const& __x, + const sub_match<_BiIter>& __y) +{ + return !(__x == __y); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator<(typename iterator_traits<_BiIter>::value_type const& __x, + const sub_match<_BiIter>& __y) +{ + typedef basic_string::value_type> string_type; + return __y.compare(string_type(1, __x)) > 0; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator>(typename iterator_traits<_BiIter>::value_type const& __x, + const sub_match<_BiIter>& __y) +{ + return __y < __x; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator>=(typename iterator_traits<_BiIter>::value_type const& __x, + const sub_match<_BiIter>& __y) +{ + return !(__x < __y); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator<=(typename iterator_traits<_BiIter>::value_type const& __x, + const sub_match<_BiIter>& __y) +{ + return !(__y < __x); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator==(const sub_match<_BiIter>& __x, + typename iterator_traits<_BiIter>::value_type const& __y) +{ + typedef basic_string::value_type> string_type; + return __x.compare(string_type(1, __y)) == 0; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator!=(const sub_match<_BiIter>& __x, + typename iterator_traits<_BiIter>::value_type const& __y) +{ + return !(__x == __y); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator<(const sub_match<_BiIter>& __x, + typename iterator_traits<_BiIter>::value_type const& __y) +{ + typedef basic_string::value_type> string_type; + return __x.compare(string_type(1, __y)) < 0; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator>(const sub_match<_BiIter>& __x, + typename iterator_traits<_BiIter>::value_type const& __y) +{ + return __y < __x; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator>=(const sub_match<_BiIter>& __x, + typename iterator_traits<_BiIter>::value_type const& __y) +{ + return !(__x < __y); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator<=(const sub_match<_BiIter>& __x, + typename iterator_traits<_BiIter>::value_type const& __y) +{ + return !(__y < __x); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +basic_ostream<_CharT, _ST>& +operator<<(basic_ostream<_CharT, _ST>& __os, const sub_match<_BiIter>& __m) +{ + return __os << __m.str(); +} + +template +class _LIBCPP_TEMPLATE_VIS match_results +{ +public: + typedef _Allocator allocator_type; + typedef sub_match<_BidirectionalIterator> value_type; +private: + typedef vector __container_type; + + __container_type __matches_; + value_type __unmatched_; + value_type __prefix_; + value_type __suffix_; + bool __ready_; +public: + _BidirectionalIterator __position_start_; + typedef const value_type& const_reference; + typedef value_type& reference; + typedef typename __container_type::const_iterator const_iterator; + typedef const_iterator iterator; + typedef typename iterator_traits<_BidirectionalIterator>::difference_type difference_type; + typedef typename allocator_traits::size_type size_type; + typedef typename iterator_traits<_BidirectionalIterator>::value_type char_type; + typedef basic_string string_type; + + // construct/copy/destroy: + explicit match_results(const allocator_type& __a = allocator_type()); +// match_results(const match_results&) = default; +// match_results& operator=(const match_results&) = default; +// match_results(match_results&& __m) = default; +// match_results& operator=(match_results&& __m) = default; +// ~match_results() = default; + + _LIBCPP_INLINE_VISIBILITY + bool ready() const {return __ready_;} + + // size: + _LIBCPP_INLINE_VISIBILITY + size_type size() const _NOEXCEPT {return __matches_.size();} + _LIBCPP_INLINE_VISIBILITY + size_type max_size() const _NOEXCEPT {return __matches_.max_size();} + _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY + bool empty() const _NOEXCEPT {return size() == 0;} + + // element access: + _LIBCPP_INLINE_VISIBILITY + difference_type length(size_type __sub = 0) const + { + _LIBCPP_ASSERT(ready(), "match_results::length() called when not ready"); + return (*this)[__sub].length(); + } + _LIBCPP_INLINE_VISIBILITY + difference_type position(size_type __sub = 0) const + { + _LIBCPP_ASSERT(ready(), "match_results::position() called when not ready"); + return _VSTD::distance(__position_start_, (*this)[__sub].first); + } + _LIBCPP_INLINE_VISIBILITY + string_type str(size_type __sub = 0) const + { + _LIBCPP_ASSERT(ready(), "match_results::str() called when not ready"); + return (*this)[__sub].str(); + } + _LIBCPP_INLINE_VISIBILITY + const_reference operator[](size_type __n) const + { + _LIBCPP_ASSERT(ready(), "match_results::operator[]() called when not ready"); + return __n < __matches_.size() ? __matches_[__n] : __unmatched_; + } + + _LIBCPP_INLINE_VISIBILITY + const_reference prefix() const + { + _LIBCPP_ASSERT(ready(), "match_results::prefix() called when not ready"); + return __prefix_; + } + _LIBCPP_INLINE_VISIBILITY + const_reference suffix() const + { + _LIBCPP_ASSERT(ready(), "match_results::suffix() called when not ready"); + return __suffix_; + } + + _LIBCPP_INLINE_VISIBILITY + const_iterator begin() const {return empty() ? __matches_.end() : __matches_.begin();} + _LIBCPP_INLINE_VISIBILITY + const_iterator end() const {return __matches_.end();} + _LIBCPP_INLINE_VISIBILITY + const_iterator cbegin() const {return empty() ? __matches_.end() : __matches_.begin();} + _LIBCPP_INLINE_VISIBILITY + const_iterator cend() const {return __matches_.end();} + + // format: + template + _OutputIter + format(_OutputIter __output_iter, const char_type* __fmt_first, + const char_type* __fmt_last, + regex_constants::match_flag_type __flags = regex_constants::format_default) const; + template + _LIBCPP_INLINE_VISIBILITY + _OutputIter + format(_OutputIter __output_iter, const basic_string& __fmt, + regex_constants::match_flag_type __flags = regex_constants::format_default) const + {return format(__output_iter, __fmt.data(), __fmt.data() + __fmt.size(), __flags);} + template + _LIBCPP_INLINE_VISIBILITY + basic_string + format(const basic_string& __fmt, + regex_constants::match_flag_type __flags = regex_constants::format_default) const + { + basic_string __r; + format(back_inserter(__r), __fmt.data(), __fmt.data() + __fmt.size(), + __flags); + return __r; + } + _LIBCPP_INLINE_VISIBILITY + string_type + format(const char_type* __fmt, + regex_constants::match_flag_type __flags = regex_constants::format_default) const + { + string_type __r; + format(back_inserter(__r), __fmt, + __fmt + char_traits::length(__fmt), __flags); + return __r; + } + + // allocator: + _LIBCPP_INLINE_VISIBILITY + allocator_type get_allocator() const {return __matches_.get_allocator();} + + // swap: + void swap(match_results& __m); + + template + _LIBCPP_INLINE_VISIBILITY + void __assign(_BidirectionalIterator __f, _BidirectionalIterator __l, + const match_results<_Bp, _Ap>& __m, bool __no_update_pos) + { + _Bp __mf = __m.prefix().first; + __matches_.resize(__m.size()); + for (size_type __i = 0; __i < __matches_.size(); ++__i) + { + __matches_[__i].first = _VSTD::next(__f, _VSTD::distance(__mf, __m[__i].first)); + __matches_[__i].second = _VSTD::next(__f, _VSTD::distance(__mf, __m[__i].second)); + __matches_[__i].matched = __m[__i].matched; + } + __unmatched_.first = __l; + __unmatched_.second = __l; + __unmatched_.matched = false; + __prefix_.first = _VSTD::next(__f, _VSTD::distance(__mf, __m.prefix().first)); + __prefix_.second = _VSTD::next(__f, _VSTD::distance(__mf, __m.prefix().second)); + __prefix_.matched = __m.prefix().matched; + __suffix_.first = _VSTD::next(__f, _VSTD::distance(__mf, __m.suffix().first)); + __suffix_.second = _VSTD::next(__f, _VSTD::distance(__mf, __m.suffix().second)); + __suffix_.matched = __m.suffix().matched; + if (!__no_update_pos) + __position_start_ = __prefix_.first; + __ready_ = __m.ready(); + } + +private: + void __init(unsigned __s, + _BidirectionalIterator __f, _BidirectionalIterator __l, + bool __no_update_pos = false); + + template friend class basic_regex; + + template + friend + bool + regex_match(_Bp, _Bp, match_results<_Bp, _Ap>&, const basic_regex<_Cp, _Tp>&, + regex_constants::match_flag_type); + + template + friend + bool + operator==(const match_results<_Bp, _Ap>&, const match_results<_Bp, _Ap>&); + + template friend class __lookahead; +}; + +template +match_results<_BidirectionalIterator, _Allocator>::match_results( + const allocator_type& __a) + : __matches_(__a), + __unmatched_(), + __prefix_(), + __suffix_(), + __ready_(false), + __position_start_() +{ +} + +template +void +match_results<_BidirectionalIterator, _Allocator>::__init(unsigned __s, + _BidirectionalIterator __f, _BidirectionalIterator __l, + bool __no_update_pos) +{ + __unmatched_.first = __l; + __unmatched_.second = __l; + __unmatched_.matched = false; + __matches_.assign(__s, __unmatched_); + __prefix_.first = __f; + __prefix_.second = __f; + __prefix_.matched = false; + __suffix_ = __unmatched_; + if (!__no_update_pos) + __position_start_ = __prefix_.first; + __ready_ = true; +} + +template +template +_OutputIter +match_results<_BidirectionalIterator, _Allocator>::format(_OutputIter __output_iter, + const char_type* __fmt_first, const char_type* __fmt_last, + regex_constants::match_flag_type __flags) const +{ + _LIBCPP_ASSERT(ready(), "match_results::format() called when not ready"); + if (__flags & regex_constants::format_sed) + { + for (; __fmt_first != __fmt_last; ++__fmt_first) + { + if (*__fmt_first == '&') + __output_iter = _VSTD::copy(__matches_[0].first, __matches_[0].second, + __output_iter); + else if (*__fmt_first == '\\' && __fmt_first + 1 != __fmt_last) + { + ++__fmt_first; + if ('0' <= *__fmt_first && *__fmt_first <= '9') + { + size_t __i = *__fmt_first - '0'; + __output_iter = _VSTD::copy((*this)[__i].first, + (*this)[__i].second, __output_iter); + } + else + { + *__output_iter = *__fmt_first; + ++__output_iter; + } + } + else + { + *__output_iter = *__fmt_first; + ++__output_iter; + } + } + } + else + { + for (; __fmt_first != __fmt_last; ++__fmt_first) + { + if (*__fmt_first == '$' && __fmt_first + 1 != __fmt_last) + { + switch (__fmt_first[1]) + { + case '$': + *__output_iter = *++__fmt_first; + ++__output_iter; + break; + case '&': + ++__fmt_first; + __output_iter = _VSTD::copy(__matches_[0].first, __matches_[0].second, + __output_iter); + break; + case '`': + ++__fmt_first; + __output_iter = _VSTD::copy(__prefix_.first, __prefix_.second, __output_iter); + break; + case '\'': + ++__fmt_first; + __output_iter = _VSTD::copy(__suffix_.first, __suffix_.second, __output_iter); + break; + default: + if ('0' <= __fmt_first[1] && __fmt_first[1] <= '9') + { + ++__fmt_first; + size_t __idx = *__fmt_first - '0'; + if (__fmt_first + 1 != __fmt_last && + '0' <= __fmt_first[1] && __fmt_first[1] <= '9') + { + ++__fmt_first; + if (__idx >= std::numeric_limits::max() / 10) + __throw_regex_error(); + __idx = 10 * __idx + *__fmt_first - '0'; + } + __output_iter = _VSTD::copy((*this)[__idx].first, + (*this)[__idx].second, __output_iter); + } + else + { + *__output_iter = *__fmt_first; + ++__output_iter; + } + break; + } + } + else + { + *__output_iter = *__fmt_first; + ++__output_iter; + } + } + } + return __output_iter; +} + +template +void +match_results<_BidirectionalIterator, _Allocator>::swap(match_results& __m) +{ + using _VSTD::swap; + swap(__matches_, __m.__matches_); + swap(__unmatched_, __m.__unmatched_); + swap(__prefix_, __m.__prefix_); + swap(__suffix_, __m.__suffix_); + swap(__position_start_, __m.__position_start_); + swap(__ready_, __m.__ready_); +} + +typedef match_results cmatch; +typedef match_results wcmatch; +typedef match_results smatch; +typedef match_results wsmatch; + +template +bool +operator==(const match_results<_BidirectionalIterator, _Allocator>& __x, + const match_results<_BidirectionalIterator, _Allocator>& __y) +{ + if (__x.__ready_ != __y.__ready_) + return false; + if (!__x.__ready_) + return true; + return __x.__matches_ == __y.__matches_ && + __x.__prefix_ == __y.__prefix_ && + __x.__suffix_ == __y.__suffix_; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator!=(const match_results<_BidirectionalIterator, _Allocator>& __x, + const match_results<_BidirectionalIterator, _Allocator>& __y) +{ + return !(__x == __y); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +swap(match_results<_BidirectionalIterator, _Allocator>& __x, + match_results<_BidirectionalIterator, _Allocator>& __y) +{ + __x.swap(__y); +} + +// regex_search + +template +template +bool +basic_regex<_CharT, _Traits>::__match_at_start_ecma( + const _CharT* __first, const _CharT* __last, + match_results& __m, + regex_constants::match_flag_type __flags, bool __at_first) const +{ + vector<__state> __states; + __node* __st = __start_.get(); + if (__st) + { + sub_match __unmatched; + __unmatched.first = __last; + __unmatched.second = __last; + __unmatched.matched = false; + + __states.push_back(__state()); + __states.back().__do_ = 0; + __states.back().__first_ = __first; + __states.back().__current_ = __first; + __states.back().__last_ = __last; + __states.back().__sub_matches_.resize(mark_count(), __unmatched); + __states.back().__loop_data_.resize(__loop_count()); + __states.back().__node_ = __st; + __states.back().__flags_ = __flags; + __states.back().__at_first_ = __at_first; + int __counter = 0; + int __length = __last - __first; + do + { + ++__counter; + if (__counter % _LIBCPP_REGEX_COMPLEXITY_FACTOR == 0 && + __counter / _LIBCPP_REGEX_COMPLEXITY_FACTOR >= __length) + __throw_regex_error(); + __state& __s = __states.back(); + if (__s.__node_) + __s.__node_->__exec(__s); + switch (__s.__do_) + { + case __state::__end_state: + if ((__flags & regex_constants::match_not_null) && + __s.__current_ == __first) + { + __states.pop_back(); + break; + } + if ((__flags & regex_constants::__full_match) && + __s.__current_ != __last) + { + __states.pop_back(); + break; + } + __m.__matches_[0].first = __first; + __m.__matches_[0].second = _VSTD::next(__first, __s.__current_ - __first); + __m.__matches_[0].matched = true; + for (unsigned __i = 0; __i < __s.__sub_matches_.size(); ++__i) + __m.__matches_[__i+1] = __s.__sub_matches_[__i]; + return true; + case __state::__accept_and_consume: + case __state::__repeat: + case __state::__accept_but_not_consume: + break; + case __state::__split: + { + __state __snext = __s; + __s.__node_->__exec_split(true, __s); + __snext.__node_->__exec_split(false, __snext); + __states.push_back(_VSTD::move(__snext)); + } + break; + case __state::__reject: + __states.pop_back(); + break; + default: + __throw_regex_error(); + break; + + } + } while (!__states.empty()); + } + return false; +} + +template +template +bool +basic_regex<_CharT, _Traits>::__match_at_start_posix_nosubs( + const _CharT* __first, const _CharT* __last, + match_results& __m, + regex_constants::match_flag_type __flags, bool __at_first) const +{ + deque<__state> __states; + ptrdiff_t __highest_j = 0; + ptrdiff_t _Np = _VSTD::distance(__first, __last); + __node* __st = __start_.get(); + if (__st) + { + __states.push_back(__state()); + __states.back().__do_ = 0; + __states.back().__first_ = __first; + __states.back().__current_ = __first; + __states.back().__last_ = __last; + __states.back().__loop_data_.resize(__loop_count()); + __states.back().__node_ = __st; + __states.back().__flags_ = __flags; + __states.back().__at_first_ = __at_first; + bool __matched = false; + int __counter = 0; + int __length = __last - __first; + do + { + ++__counter; + if (__counter % _LIBCPP_REGEX_COMPLEXITY_FACTOR == 0 && + __counter / _LIBCPP_REGEX_COMPLEXITY_FACTOR >= __length) + __throw_regex_error(); + __state& __s = __states.back(); + if (__s.__node_) + __s.__node_->__exec(__s); + switch (__s.__do_) + { + case __state::__end_state: + if ((__flags & regex_constants::match_not_null) && + __s.__current_ == __first) + { + __states.pop_back(); + break; + } + if ((__flags & regex_constants::__full_match) && + __s.__current_ != __last) + { + __states.pop_back(); + break; + } + if (!__matched || __highest_j < __s.__current_ - __s.__first_) + __highest_j = __s.__current_ - __s.__first_; + __matched = true; + if (__highest_j == _Np) + __states.clear(); + else + __states.pop_back(); + break; + case __state::__consume_input: + break; + case __state::__accept_and_consume: + __states.push_front(_VSTD::move(__s)); + __states.pop_back(); + break; + case __state::__repeat: + case __state::__accept_but_not_consume: + break; + case __state::__split: + { + __state __snext = __s; + __s.__node_->__exec_split(true, __s); + __snext.__node_->__exec_split(false, __snext); + __states.push_back(_VSTD::move(__snext)); + } + break; + case __state::__reject: + __states.pop_back(); + break; + default: + __throw_regex_error(); + break; + } + } while (!__states.empty()); + if (__matched) + { + __m.__matches_[0].first = __first; + __m.__matches_[0].second = _VSTD::next(__first, __highest_j); + __m.__matches_[0].matched = true; + return true; + } + } + return false; +} + +template +template +bool +basic_regex<_CharT, _Traits>::__match_at_start_posix_subs( + const _CharT* __first, const _CharT* __last, + match_results& __m, + regex_constants::match_flag_type __flags, bool __at_first) const +{ + vector<__state> __states; + __state __best_state; + ptrdiff_t __j = 0; + ptrdiff_t __highest_j = 0; + ptrdiff_t _Np = _VSTD::distance(__first, __last); + __node* __st = __start_.get(); + if (__st) + { + sub_match __unmatched; + __unmatched.first = __last; + __unmatched.second = __last; + __unmatched.matched = false; + + __states.push_back(__state()); + __states.back().__do_ = 0; + __states.back().__first_ = __first; + __states.back().__current_ = __first; + __states.back().__last_ = __last; + __states.back().__sub_matches_.resize(mark_count(), __unmatched); + __states.back().__loop_data_.resize(__loop_count()); + __states.back().__node_ = __st; + __states.back().__flags_ = __flags; + __states.back().__at_first_ = __at_first; + const _CharT* __current = __first; + bool __matched = false; + int __counter = 0; + int __length = __last - __first; + do + { + ++__counter; + if (__counter % _LIBCPP_REGEX_COMPLEXITY_FACTOR == 0 && + __counter / _LIBCPP_REGEX_COMPLEXITY_FACTOR >= __length) + __throw_regex_error(); + __state& __s = __states.back(); + if (__s.__node_) + __s.__node_->__exec(__s); + switch (__s.__do_) + { + case __state::__end_state: + if ((__flags & regex_constants::match_not_null) && + __s.__current_ == __first) + { + __states.pop_back(); + break; + } + if ((__flags & regex_constants::__full_match) && + __s.__current_ != __last) + { + __states.pop_back(); + break; + } + if (!__matched || __highest_j < __s.__current_ - __s.__first_) + { + __highest_j = __s.__current_ - __s.__first_; + __best_state = __s; + } + __matched = true; + if (__highest_j == _Np) + __states.clear(); + else + __states.pop_back(); + break; + case __state::__accept_and_consume: + __j += __s.__current_ - __current; + __current = __s.__current_; + break; + case __state::__repeat: + case __state::__accept_but_not_consume: + break; + case __state::__split: + { + __state __snext = __s; + __s.__node_->__exec_split(true, __s); + __snext.__node_->__exec_split(false, __snext); + __states.push_back(_VSTD::move(__snext)); + } + break; + case __state::__reject: + __states.pop_back(); + break; + default: + __throw_regex_error(); + break; + } + } while (!__states.empty()); + if (__matched) + { + __m.__matches_[0].first = __first; + __m.__matches_[0].second = _VSTD::next(__first, __highest_j); + __m.__matches_[0].matched = true; + for (unsigned __i = 0; __i < __best_state.__sub_matches_.size(); ++__i) + __m.__matches_[__i+1] = __best_state.__sub_matches_[__i]; + return true; + } + } + return false; +} + +template +template +bool +basic_regex<_CharT, _Traits>::__match_at_start( + const _CharT* __first, const _CharT* __last, + match_results& __m, + regex_constants::match_flag_type __flags, bool __at_first) const +{ + if (__get_grammar(__flags_) == ECMAScript) + return __match_at_start_ecma(__first, __last, __m, __flags, __at_first); + if (mark_count() == 0) + return __match_at_start_posix_nosubs(__first, __last, __m, __flags, __at_first); + return __match_at_start_posix_subs(__first, __last, __m, __flags, __at_first); +} + +template +template +bool +basic_regex<_CharT, _Traits>::__search( + const _CharT* __first, const _CharT* __last, + match_results& __m, + regex_constants::match_flag_type __flags) const +{ + __m.__init(1 + mark_count(), __first, __last, + __flags & regex_constants::__no_update_pos); + if (__match_at_start(__first, __last, __m, __flags, + !(__flags & regex_constants::__no_update_pos))) + { + __m.__prefix_.second = __m[0].first; + __m.__prefix_.matched = __m.__prefix_.first != __m.__prefix_.second; + __m.__suffix_.first = __m[0].second; + __m.__suffix_.matched = __m.__suffix_.first != __m.__suffix_.second; + return true; + } + if (__first != __last && !(__flags & regex_constants::match_continuous)) + { + __flags |= regex_constants::match_prev_avail; + for (++__first; __first != __last; ++__first) + { + __m.__matches_.assign(__m.size(), __m.__unmatched_); + if (__match_at_start(__first, __last, __m, __flags, false)) + { + __m.__prefix_.second = __m[0].first; + __m.__prefix_.matched = __m.__prefix_.first != __m.__prefix_.second; + __m.__suffix_.first = __m[0].second; + __m.__suffix_.matched = __m.__suffix_.first != __m.__suffix_.second; + return true; + } + __m.__matches_.assign(__m.size(), __m.__unmatched_); + } + } + __m.__matches_.clear(); + return false; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +regex_search(_BidirectionalIterator __first, _BidirectionalIterator __last, + match_results<_BidirectionalIterator, _Allocator>& __m, + const basic_regex<_CharT, _Traits>& __e, + regex_constants::match_flag_type __flags = regex_constants::match_default) +{ + int __offset = (__flags & regex_constants::match_prev_avail) ? 1 : 0; + basic_string<_CharT> __s(_VSTD::prev(__first, __offset), __last); + match_results __mc; + bool __r = __e.__search(__s.data() + __offset, __s.data() + __s.size(), __mc, __flags); + __m.__assign(__first, __last, __mc, __flags & regex_constants::__no_update_pos); + return __r; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +regex_search(__wrap_iter<_Iter> __first, + __wrap_iter<_Iter> __last, + match_results<__wrap_iter<_Iter>, _Allocator>& __m, + const basic_regex<_CharT, _Traits>& __e, + regex_constants::match_flag_type __flags = regex_constants::match_default) +{ + match_results __mc; + bool __r = __e.__search(__first.base(), __last.base(), __mc, __flags); + __m.__assign(__first, __last, __mc, __flags & regex_constants::__no_update_pos); + return __r; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +regex_search(const _CharT* __first, const _CharT* __last, + match_results& __m, + const basic_regex<_CharT, _Traits>& __e, + regex_constants::match_flag_type __flags = regex_constants::match_default) +{ + return __e.__search(__first, __last, __m, __flags); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +regex_search(_BidirectionalIterator __first, _BidirectionalIterator __last, + const basic_regex<_CharT, _Traits>& __e, + regex_constants::match_flag_type __flags = regex_constants::match_default) +{ + basic_string<_CharT> __s(__first, __last); + match_results __mc; + return __e.__search(__s.data(), __s.data() + __s.size(), __mc, __flags); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +regex_search(const _CharT* __first, const _CharT* __last, + const basic_regex<_CharT, _Traits>& __e, + regex_constants::match_flag_type __flags = regex_constants::match_default) +{ + match_results __mc; + return __e.__search(__first, __last, __mc, __flags); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +regex_search(const _CharT* __str, match_results& __m, + const basic_regex<_CharT, _Traits>& __e, + regex_constants::match_flag_type __flags = regex_constants::match_default) +{ + return __e.__search(__str, __str + _Traits::length(__str), __m, __flags); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +regex_search(const _CharT* __str, const basic_regex<_CharT, _Traits>& __e, + regex_constants::match_flag_type __flags = regex_constants::match_default) +{ + match_results __m; + return _VSTD::regex_search(__str, __m, __e, __flags); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +regex_search(const basic_string<_CharT, _ST, _SA>& __s, + const basic_regex<_CharT, _Traits>& __e, + regex_constants::match_flag_type __flags = regex_constants::match_default) +{ + match_results __mc; + return __e.__search(__s.data(), __s.data() + __s.size(), __mc, __flags); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +regex_search(const basic_string<_CharT, _ST, _SA>& __s, + match_results::const_iterator, _Allocator>& __m, + const basic_regex<_CharT, _Traits>& __e, + regex_constants::match_flag_type __flags = regex_constants::match_default) +{ + match_results __mc; + bool __r = __e.__search(__s.data(), __s.data() + __s.size(), __mc, __flags); + __m.__assign(__s.begin(), __s.end(), __mc, __flags & regex_constants::__no_update_pos); + return __r; +} + +#if _LIBCPP_STD_VER > 11 +template +bool +regex_search(const basic_string<_Cp, _ST, _SA>&& __s, + match_results::const_iterator, _Ap>&, + const basic_regex<_Cp, _Tp>& __e, + regex_constants::match_flag_type __flags = regex_constants::match_default) = delete; +#endif + +// regex_match + +template +bool +regex_match(_BidirectionalIterator __first, _BidirectionalIterator __last, + match_results<_BidirectionalIterator, _Allocator>& __m, + const basic_regex<_CharT, _Traits>& __e, + regex_constants::match_flag_type __flags = regex_constants::match_default) +{ + bool __r = _VSTD::regex_search( + __first, __last, __m, __e, + __flags | regex_constants::match_continuous | + regex_constants::__full_match); + if (__r) + { + __r = !__m.suffix().matched; + if (!__r) + __m.__matches_.clear(); + } + return __r; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +regex_match(_BidirectionalIterator __first, _BidirectionalIterator __last, + const basic_regex<_CharT, _Traits>& __e, + regex_constants::match_flag_type __flags = regex_constants::match_default) +{ + match_results<_BidirectionalIterator> __m; + return _VSTD::regex_match(__first, __last, __m, __e, __flags); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +regex_match(const _CharT* __str, match_results& __m, + const basic_regex<_CharT, _Traits>& __e, + regex_constants::match_flag_type __flags = regex_constants::match_default) +{ + return _VSTD::regex_match(__str, __str + _Traits::length(__str), __m, __e, __flags); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +regex_match(const basic_string<_CharT, _ST, _SA>& __s, + match_results::const_iterator, _Allocator>& __m, + const basic_regex<_CharT, _Traits>& __e, + regex_constants::match_flag_type __flags = regex_constants::match_default) +{ + return _VSTD::regex_match(__s.begin(), __s.end(), __m, __e, __flags); +} + +#if _LIBCPP_STD_VER > 11 +template +inline _LIBCPP_INLINE_VISIBILITY +bool +regex_match(const basic_string<_CharT, _ST, _SA>&& __s, + match_results::const_iterator, _Allocator>& __m, + const basic_regex<_CharT, _Traits>& __e, + regex_constants::match_flag_type __flags = regex_constants::match_default) = delete; +#endif + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +regex_match(const _CharT* __str, const basic_regex<_CharT, _Traits>& __e, + regex_constants::match_flag_type __flags = regex_constants::match_default) +{ + return _VSTD::regex_match(__str, __str + _Traits::length(__str), __e, __flags); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +regex_match(const basic_string<_CharT, _ST, _SA>& __s, + const basic_regex<_CharT, _Traits>& __e, + regex_constants::match_flag_type __flags = regex_constants::match_default) +{ + return _VSTD::regex_match(__s.begin(), __s.end(), __e, __flags); +} + +// regex_iterator + +template ::value_type, + class _Traits = regex_traits<_CharT> > +class _LIBCPP_TEMPLATE_VIS regex_iterator +{ +public: + typedef basic_regex<_CharT, _Traits> regex_type; + typedef match_results<_BidirectionalIterator> value_type; + typedef ptrdiff_t difference_type; + typedef const value_type* pointer; + typedef const value_type& reference; + typedef forward_iterator_tag iterator_category; + +private: + _BidirectionalIterator __begin_; + _BidirectionalIterator __end_; + const regex_type* __pregex_; + regex_constants::match_flag_type __flags_; + value_type __match_; + +public: + regex_iterator(); + regex_iterator(_BidirectionalIterator __a, _BidirectionalIterator __b, + const regex_type& __re, + regex_constants::match_flag_type __m + = regex_constants::match_default); +#if _LIBCPP_STD_VER > 11 + regex_iterator(_BidirectionalIterator __a, _BidirectionalIterator __b, + const regex_type&& __re, + regex_constants::match_flag_type __m + = regex_constants::match_default) = delete; +#endif + + bool operator==(const regex_iterator& __x) const; + _LIBCPP_INLINE_VISIBILITY + bool operator!=(const regex_iterator& __x) const {return !(*this == __x);} + + _LIBCPP_INLINE_VISIBILITY + reference operator*() const {return __match_;} + _LIBCPP_INLINE_VISIBILITY + pointer operator->() const {return _VSTD::addressof(__match_);} + + regex_iterator& operator++(); + _LIBCPP_INLINE_VISIBILITY + regex_iterator operator++(int) + { + regex_iterator __t(*this); + ++(*this); + return __t; + } +}; + +template +regex_iterator<_BidirectionalIterator, _CharT, _Traits>::regex_iterator() + : __begin_(), __end_(), __pregex_(nullptr), __flags_(), __match_() +{ +} + +template +regex_iterator<_BidirectionalIterator, _CharT, _Traits>:: + regex_iterator(_BidirectionalIterator __a, _BidirectionalIterator __b, + const regex_type& __re, regex_constants::match_flag_type __m) + : __begin_(__a), + __end_(__b), + __pregex_(_VSTD::addressof(__re)), + __flags_(__m) +{ + _VSTD::regex_search(__begin_, __end_, __match_, *__pregex_, __flags_); +} + +template +bool +regex_iterator<_BidirectionalIterator, _CharT, _Traits>:: + operator==(const regex_iterator& __x) const +{ + if (__match_.empty() && __x.__match_.empty()) + return true; + if (__match_.empty() || __x.__match_.empty()) + return false; + return __begin_ == __x.__begin_ && + __end_ == __x.__end_ && + __pregex_ == __x.__pregex_ && + __flags_ == __x.__flags_ && + __match_[0] == __x.__match_[0]; +} + +template +regex_iterator<_BidirectionalIterator, _CharT, _Traits>& +regex_iterator<_BidirectionalIterator, _CharT, _Traits>::operator++() +{ + __flags_ |= regex_constants::__no_update_pos; + _BidirectionalIterator __start = __match_[0].second; + if (__match_[0].first == __match_[0].second) + { + if (__start == __end_) + { + __match_ = value_type(); + return *this; + } + else if (_VSTD::regex_search(__start, __end_, __match_, *__pregex_, + __flags_ | regex_constants::match_not_null | + regex_constants::match_continuous)) + return *this; + else + ++__start; + } + __flags_ |= regex_constants::match_prev_avail; + if (!_VSTD::regex_search(__start, __end_, __match_, *__pregex_, __flags_)) + __match_ = value_type(); + return *this; +} + +typedef regex_iterator cregex_iterator; +typedef regex_iterator wcregex_iterator; +typedef regex_iterator sregex_iterator; +typedef regex_iterator wsregex_iterator; + +// regex_token_iterator + +template ::value_type, + class _Traits = regex_traits<_CharT> > +class _LIBCPP_TEMPLATE_VIS regex_token_iterator +{ +public: + typedef basic_regex<_CharT, _Traits> regex_type; + typedef sub_match<_BidirectionalIterator> value_type; + typedef ptrdiff_t difference_type; + typedef const value_type* pointer; + typedef const value_type& reference; + typedef forward_iterator_tag iterator_category; + +private: + typedef regex_iterator<_BidirectionalIterator, _CharT, _Traits> _Position; + + _Position __position_; + const value_type* __result_; + value_type __suffix_; + ptrdiff_t __n_; + vector __subs_; + +public: + regex_token_iterator(); + regex_token_iterator(_BidirectionalIterator __a, _BidirectionalIterator __b, + const regex_type& __re, int __submatch = 0, + regex_constants::match_flag_type __m = + regex_constants::match_default); +#if _LIBCPP_STD_VER > 11 + regex_token_iterator(_BidirectionalIterator __a, _BidirectionalIterator __b, + const regex_type&& __re, int __submatch = 0, + regex_constants::match_flag_type __m = + regex_constants::match_default) = delete; +#endif + + regex_token_iterator(_BidirectionalIterator __a, _BidirectionalIterator __b, + const regex_type& __re, const vector& __submatches, + regex_constants::match_flag_type __m = + regex_constants::match_default); +#if _LIBCPP_STD_VER > 11 + regex_token_iterator(_BidirectionalIterator __a, _BidirectionalIterator __b, + const regex_type&& __re, const vector& __submatches, + regex_constants::match_flag_type __m = + regex_constants::match_default) = delete; +#endif + +#ifndef _LIBCPP_CXX03_LANG + regex_token_iterator(_BidirectionalIterator __a, _BidirectionalIterator __b, + const regex_type& __re, + initializer_list __submatches, + regex_constants::match_flag_type __m = + regex_constants::match_default); + +#if _LIBCPP_STD_VER > 11 + regex_token_iterator(_BidirectionalIterator __a, _BidirectionalIterator __b, + const regex_type&& __re, + initializer_list __submatches, + regex_constants::match_flag_type __m = + regex_constants::match_default) = delete; +#endif +#endif // _LIBCPP_CXX03_LANG + template + regex_token_iterator(_BidirectionalIterator __a, + _BidirectionalIterator __b, + const regex_type& __re, + const int (&__submatches)[_Np], + regex_constants::match_flag_type __m = + regex_constants::match_default); +#if _LIBCPP_STD_VER > 11 + template + regex_token_iterator(_BidirectionalIterator __a, + _BidirectionalIterator __b, + const regex_type&& __re, + const int (&__submatches)[_Np], + regex_constants::match_flag_type __m = + regex_constants::match_default) = delete; +#endif + + regex_token_iterator(const regex_token_iterator&); + regex_token_iterator& operator=(const regex_token_iterator&); + + bool operator==(const regex_token_iterator& __x) const; + _LIBCPP_INLINE_VISIBILITY + bool operator!=(const regex_token_iterator& __x) const {return !(*this == __x);} + + _LIBCPP_INLINE_VISIBILITY + const value_type& operator*() const {return *__result_;} + _LIBCPP_INLINE_VISIBILITY + const value_type* operator->() const {return __result_;} + + regex_token_iterator& operator++(); + _LIBCPP_INLINE_VISIBILITY + regex_token_iterator operator++(int) + { + regex_token_iterator __t(*this); + ++(*this); + return __t; + } + +private: + void __init(_BidirectionalIterator __a, _BidirectionalIterator __b); + void __establish_result () { + if (__subs_[__n_] == -1) + __result_ = &__position_->prefix(); + else + __result_ = &(*__position_)[__subs_[__n_]]; + } +}; + +template +regex_token_iterator<_BidirectionalIterator, _CharT, _Traits>:: + regex_token_iterator() + : __result_(nullptr), + __suffix_(), + __n_(0) +{ +} + +template +void +regex_token_iterator<_BidirectionalIterator, _CharT, _Traits>:: + __init(_BidirectionalIterator __a, _BidirectionalIterator __b) +{ + if (__position_ != _Position()) + __establish_result (); + else if (__subs_[__n_] == -1) + { + __suffix_.matched = true; + __suffix_.first = __a; + __suffix_.second = __b; + __result_ = &__suffix_; + } + else + __result_ = nullptr; +} + +template +regex_token_iterator<_BidirectionalIterator, _CharT, _Traits>:: + regex_token_iterator(_BidirectionalIterator __a, _BidirectionalIterator __b, + const regex_type& __re, int __submatch, + regex_constants::match_flag_type __m) + : __position_(__a, __b, __re, __m), + __n_(0), + __subs_(1, __submatch) +{ + __init(__a, __b); +} + +template +regex_token_iterator<_BidirectionalIterator, _CharT, _Traits>:: + regex_token_iterator(_BidirectionalIterator __a, _BidirectionalIterator __b, + const regex_type& __re, const vector& __submatches, + regex_constants::match_flag_type __m) + : __position_(__a, __b, __re, __m), + __n_(0), + __subs_(__submatches) +{ + __init(__a, __b); +} + +#ifndef _LIBCPP_CXX03_LANG + +template +regex_token_iterator<_BidirectionalIterator, _CharT, _Traits>:: + regex_token_iterator(_BidirectionalIterator __a, _BidirectionalIterator __b, + const regex_type& __re, + initializer_list __submatches, + regex_constants::match_flag_type __m) + : __position_(__a, __b, __re, __m), + __n_(0), + __subs_(__submatches) +{ + __init(__a, __b); +} + +#endif // _LIBCPP_CXX03_LANG + +template +template +regex_token_iterator<_BidirectionalIterator, _CharT, _Traits>:: + regex_token_iterator(_BidirectionalIterator __a, _BidirectionalIterator __b, + const regex_type& __re, + const int (&__submatches)[_Np], + regex_constants::match_flag_type __m) + : __position_(__a, __b, __re, __m), + __n_(0), + __subs_(begin(__submatches), end(__submatches)) +{ + __init(__a, __b); +} + +template +regex_token_iterator<_BidirectionalIterator, _CharT, _Traits>:: + regex_token_iterator(const regex_token_iterator& __x) + : __position_(__x.__position_), + __result_(__x.__result_), + __suffix_(__x.__suffix_), + __n_(__x.__n_), + __subs_(__x.__subs_) +{ + if (__x.__result_ == &__x.__suffix_) + __result_ = &__suffix_; + else if ( __result_ != nullptr ) + __establish_result (); +} + +template +regex_token_iterator<_BidirectionalIterator, _CharT, _Traits>& +regex_token_iterator<_BidirectionalIterator, _CharT, _Traits>:: + operator=(const regex_token_iterator& __x) +{ + if (this != &__x) + { + __position_ = __x.__position_; + if (__x.__result_ == &__x.__suffix_) + __result_ = &__suffix_; + else + __result_ = __x.__result_; + __suffix_ = __x.__suffix_; + __n_ = __x.__n_; + __subs_ = __x.__subs_; + + if ( __result_ != nullptr && __result_ != &__suffix_ ) + __establish_result(); + } + return *this; +} + +template +bool +regex_token_iterator<_BidirectionalIterator, _CharT, _Traits>:: + operator==(const regex_token_iterator& __x) const +{ + if (__result_ == nullptr && __x.__result_ == nullptr) + return true; + if (__result_ == &__suffix_ && __x.__result_ == &__x.__suffix_ && + __suffix_ == __x.__suffix_) + return true; + if (__result_ == nullptr || __x.__result_ == nullptr) + return false; + if (__result_ == &__suffix_ || __x.__result_ == &__x.__suffix_) + return false; + return __position_ == __x.__position_ && __n_ == __x.__n_ && + __subs_ == __x.__subs_; +} + +template +regex_token_iterator<_BidirectionalIterator, _CharT, _Traits>& +regex_token_iterator<_BidirectionalIterator, _CharT, _Traits>::operator++() +{ + _Position __prev = __position_; + if (__result_ == &__suffix_) + __result_ = nullptr; + else if (static_cast(__n_ + 1) < __subs_.size()) + { + ++__n_; + __establish_result(); + } + else + { + __n_ = 0; + ++__position_; + if (__position_ != _Position()) + __establish_result(); + else + { + if (_VSTD::find(__subs_.begin(), __subs_.end(), -1) != __subs_.end() + && __prev->suffix().length() != 0) + { + __suffix_.matched = true; + __suffix_.first = __prev->suffix().first; + __suffix_.second = __prev->suffix().second; + __result_ = &__suffix_; + } + else + __result_ = nullptr; + } + } + return *this; +} + +typedef regex_token_iterator cregex_token_iterator; +typedef regex_token_iterator wcregex_token_iterator; +typedef regex_token_iterator sregex_token_iterator; +typedef regex_token_iterator wsregex_token_iterator; + +// regex_replace + +template +_OutputIterator +regex_replace(_OutputIterator __output_iter, + _BidirectionalIterator __first, _BidirectionalIterator __last, + const basic_regex<_CharT, _Traits>& __e, const _CharT* __fmt, + regex_constants::match_flag_type __flags = regex_constants::match_default) +{ + typedef regex_iterator<_BidirectionalIterator, _CharT, _Traits> _Iter; + _Iter __i(__first, __last, __e, __flags); + _Iter __eof; + if (__i == __eof) + { + if (!(__flags & regex_constants::format_no_copy)) + __output_iter = _VSTD::copy(__first, __last, __output_iter); + } + else + { + sub_match<_BidirectionalIterator> __lm; + for (size_t __len = char_traits<_CharT>::length(__fmt); __i != __eof; ++__i) + { + if (!(__flags & regex_constants::format_no_copy)) + __output_iter = _VSTD::copy(__i->prefix().first, __i->prefix().second, __output_iter); + __output_iter = __i->format(__output_iter, __fmt, __fmt + __len, __flags); + __lm = __i->suffix(); + if (__flags & regex_constants::format_first_only) + break; + } + if (!(__flags & regex_constants::format_no_copy)) + __output_iter = _VSTD::copy(__lm.first, __lm.second, __output_iter); + } + return __output_iter; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_OutputIterator +regex_replace(_OutputIterator __output_iter, + _BidirectionalIterator __first, _BidirectionalIterator __last, + const basic_regex<_CharT, _Traits>& __e, + const basic_string<_CharT, _ST, _SA>& __fmt, + regex_constants::match_flag_type __flags = regex_constants::match_default) +{ + return _VSTD::regex_replace(__output_iter, __first, __last, __e, __fmt.c_str(), __flags); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +basic_string<_CharT, _ST, _SA> +regex_replace(const basic_string<_CharT, _ST, _SA>& __s, + const basic_regex<_CharT, _Traits>& __e, + const basic_string<_CharT, _FST, _FSA>& __fmt, + regex_constants::match_flag_type __flags = regex_constants::match_default) +{ + basic_string<_CharT, _ST, _SA> __r; + _VSTD::regex_replace(back_inserter(__r), __s.begin(), __s.end(), __e, + __fmt.c_str(), __flags); + return __r; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +basic_string<_CharT, _ST, _SA> +regex_replace(const basic_string<_CharT, _ST, _SA>& __s, + const basic_regex<_CharT, _Traits>& __e, const _CharT* __fmt, + regex_constants::match_flag_type __flags = regex_constants::match_default) +{ + basic_string<_CharT, _ST, _SA> __r; + _VSTD::regex_replace(back_inserter(__r), __s.begin(), __s.end(), __e, + __fmt, __flags); + return __r; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +basic_string<_CharT> +regex_replace(const _CharT* __s, + const basic_regex<_CharT, _Traits>& __e, + const basic_string<_CharT, _ST, _SA>& __fmt, + regex_constants::match_flag_type __flags = regex_constants::match_default) +{ + basic_string<_CharT> __r; + _VSTD::regex_replace(back_inserter(__r), __s, + __s + char_traits<_CharT>::length(__s), __e, + __fmt.c_str(), __flags); + return __r; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +basic_string<_CharT> +regex_replace(const _CharT* __s, + const basic_regex<_CharT, _Traits>& __e, + const _CharT* __fmt, + regex_constants::match_flag_type __flags = regex_constants::match_default) +{ + basic_string<_CharT> __r; + _VSTD::regex_replace(back_inserter(__r), __s, + __s + char_traits<_CharT>::length(__s), __e, + __fmt, __flags); + return __r; +} + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP_REGEX diff --git a/third_party/libcxx/regex.cc b/third_party/libcxx/regex.cc new file mode 100644 index 000000000..8518ae086 --- /dev/null +++ b/third_party/libcxx/regex.cc @@ -0,0 +1,315 @@ +// clang-format off +//===-------------------------- regex.cpp ---------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "third_party/libcxx/regex" +#include "third_party/libcxx/algorithm" +#include "third_party/libcxx/iterator" + +_LIBCPP_BEGIN_NAMESPACE_STD + +static +const char* +make_error_type_string(regex_constants::error_type ecode) +{ + switch (ecode) + { + case regex_constants::error_collate: + return "The expression contained an invalid collating element name."; + case regex_constants::error_ctype: + return "The expression contained an invalid character class name."; + case regex_constants::error_escape: + return "The expression contained an invalid escaped character, or a " + "trailing escape."; + case regex_constants::error_backref: + return "The expression contained an invalid back reference."; + case regex_constants::error_brack: + return "The expression contained mismatched [ and ]."; + case regex_constants::error_paren: + return "The expression contained mismatched ( and )."; + case regex_constants::error_brace: + return "The expression contained mismatched { and }."; + case regex_constants::error_badbrace: + return "The expression contained an invalid range in a {} expression."; + case regex_constants::error_range: + return "The expression contained an invalid character range, " + "such as [b-a] in most encodings."; + case regex_constants::error_space: + return "There was insufficient memory to convert the expression into " + "a finite state machine."; + case regex_constants::error_badrepeat: + return "One of *?+{ was not preceded by a valid regular expression."; + case regex_constants::error_complexity: + return "The complexity of an attempted match against a regular " + "expression exceeded a pre-set level."; + case regex_constants::error_stack: + return "There was insufficient memory to determine whether the regular " + "expression could match the specified character sequence."; + case regex_constants::__re_err_grammar: + return "An invalid regex grammar has been requested."; + case regex_constants::__re_err_empty: + return "An empty regex is not allowed in the POSIX grammar."; + default: + break; + } + return "Unknown error type"; +} + +regex_error::regex_error(regex_constants::error_type ecode) + : runtime_error(make_error_type_string(ecode)), + __code_(ecode) +{} + +regex_error::~regex_error() throw() {} + +namespace { + +struct collationnames +{ + const char* elem_; + char char_; +}; + +const collationnames collatenames[] = +{ + {"A", 0x41}, + {"B", 0x42}, + {"C", 0x43}, + {"D", 0x44}, + {"E", 0x45}, + {"F", 0x46}, + {"G", 0x47}, + {"H", 0x48}, + {"I", 0x49}, + {"J", 0x4a}, + {"K", 0x4b}, + {"L", 0x4c}, + {"M", 0x4d}, + {"N", 0x4e}, + {"NUL", 0x00}, + {"O", 0x4f}, + {"P", 0x50}, + {"Q", 0x51}, + {"R", 0x52}, + {"S", 0x53}, + {"T", 0x54}, + {"U", 0x55}, + {"V", 0x56}, + {"W", 0x57}, + {"X", 0x58}, + {"Y", 0x59}, + {"Z", 0x5a}, + {"a", 0x61}, + {"alert", 0x07}, + {"ampersand", 0x26}, + {"apostrophe", 0x27}, + {"asterisk", 0x2a}, + {"b", 0x62}, + {"backslash", 0x5c}, + {"backspace", 0x08}, + {"c", 0x63}, + {"carriage-return", 0x0d}, + {"circumflex", 0x5e}, + {"circumflex-accent", 0x5e}, + {"colon", 0x3a}, + {"comma", 0x2c}, + {"commercial-at", 0x40}, + {"d", 0x64}, + {"dollar-sign", 0x24}, + {"e", 0x65}, + {"eight", 0x38}, + {"equals-sign", 0x3d}, + {"exclamation-mark", 0x21}, + {"f", 0x66}, + {"five", 0x35}, + {"form-feed", 0x0c}, + {"four", 0x34}, + {"full-stop", 0x2e}, + {"g", 0x67}, + {"grave-accent", 0x60}, + {"greater-than-sign", 0x3e}, + {"h", 0x68}, + {"hyphen", 0x2d}, + {"hyphen-minus", 0x2d}, + {"i", 0x69}, + {"j", 0x6a}, + {"k", 0x6b}, + {"l", 0x6c}, + {"left-brace", 0x7b}, + {"left-curly-bracket", 0x7b}, + {"left-parenthesis", 0x28}, + {"left-square-bracket", 0x5b}, + {"less-than-sign", 0x3c}, + {"low-line", 0x5f}, + {"m", 0x6d}, + {"n", 0x6e}, + {"newline", 0x0a}, + {"nine", 0x39}, + {"number-sign", 0x23}, + {"o", 0x6f}, + {"one", 0x31}, + {"p", 0x70}, + {"percent-sign", 0x25}, + {"period", 0x2e}, + {"plus-sign", 0x2b}, + {"q", 0x71}, + {"question-mark", 0x3f}, + {"quotation-mark", 0x22}, + {"r", 0x72}, + {"reverse-solidus", 0x5c}, + {"right-brace", 0x7d}, + {"right-curly-bracket", 0x7d}, + {"right-parenthesis", 0x29}, + {"right-square-bracket", 0x5d}, + {"s", 0x73}, + {"semicolon", 0x3b}, + {"seven", 0x37}, + {"six", 0x36}, + {"slash", 0x2f}, + {"solidus", 0x2f}, + {"space", 0x20}, + {"t", 0x74}, + {"tab", 0x09}, + {"three", 0x33}, + {"tilde", 0x7e}, + {"two", 0x32}, + {"u", 0x75}, + {"underscore", 0x5f}, + {"v", 0x76}, + {"vertical-line", 0x7c}, + {"vertical-tab", 0x0b}, + {"w", 0x77}, + {"x", 0x78}, + {"y", 0x79}, + {"z", 0x7a}, + {"zero", 0x30} +}; + +struct classnames +{ + const char* elem_; + regex_traits::char_class_type mask_; +}; + +const classnames ClassNames[] = +{ + {"alnum", ctype_base::alnum}, + {"alpha", ctype_base::alpha}, + {"blank", ctype_base::blank}, + {"cntrl", ctype_base::cntrl}, + {"d", ctype_base::digit}, + {"digit", ctype_base::digit}, + {"graph", ctype_base::graph}, + {"lower", ctype_base::lower}, + {"print", ctype_base::print}, + {"punct", ctype_base::punct}, + {"s", ctype_base::space}, + {"space", ctype_base::space}, + {"upper", ctype_base::upper}, + {"w", regex_traits::__regex_word}, + {"xdigit", ctype_base::xdigit} +}; + +struct use_strcmp +{ + bool operator()(const collationnames& x, const char* y) + {return strcmp(x.elem_, y) < 0;} + bool operator()(const classnames& x, const char* y) + {return strcmp(x.elem_, y) < 0;} +}; + +} + +string +__get_collation_name(const char* s) +{ + const collationnames* i = + _VSTD::lower_bound(begin(collatenames), end(collatenames), s, use_strcmp()); + string r; + if (i != end(collatenames) && strcmp(s, i->elem_) == 0) + r = char(i->char_); + return r; +} + +regex_traits::char_class_type +__get_classname(const char* s, bool __icase) +{ + const classnames* i = + _VSTD::lower_bound(begin(ClassNames), end(ClassNames), s, use_strcmp()); + regex_traits::char_class_type r = 0; + if (i != end(ClassNames) && strcmp(s, i->elem_) == 0) + { + r = i->mask_; + if (r == regex_traits::__regex_word) + r |= ctype_base::alnum | ctype_base::upper | ctype_base::lower; + else if (__icase) + { + if (r & (ctype_base::lower | ctype_base::upper)) + r |= ctype_base::alpha; + } + } + return r; +} + +template <> +void +__match_any_but_newline::__exec(__state& __s) const +{ + if (__s.__current_ != __s.__last_) + { + switch (*__s.__current_) + { + case '\r': + case '\n': + __s.__do_ = __state::__reject; + __s.__node_ = nullptr; + break; + default: + __s.__do_ = __state::__accept_and_consume; + ++__s.__current_; + __s.__node_ = this->first(); + break; + } + } + else + { + __s.__do_ = __state::__reject; + __s.__node_ = nullptr; + } +} + +template <> +void +__match_any_but_newline::__exec(__state& __s) const +{ + if (__s.__current_ != __s.__last_) + { + switch (*__s.__current_) + { + case '\r': + case '\n': + case 0x2028: + case 0x2029: + __s.__do_ = __state::__reject; + __s.__node_ = nullptr; + break; + default: + __s.__do_ = __state::__accept_and_consume; + ++__s.__current_; + __s.__node_ = this->first(); + break; + } + } + else + { + __s.__do_ = __state::__reject; + __s.__node_ = nullptr; + } +} + +_LIBCPP_END_NAMESPACE_STD diff --git a/third_party/libcxx/scoped_allocator b/third_party/libcxx/scoped_allocator new file mode 100644 index 000000000..72785c3d6 --- /dev/null +++ b/third_party/libcxx/scoped_allocator @@ -0,0 +1,684 @@ +// -*- C++ -*- +// clang-format off +//===-------------------------- scoped_allocator --------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_SCOPED_ALLOCATOR +#define _LIBCPP_SCOPED_ALLOCATOR + +/* + scoped_allocator synopsis + +namespace std +{ + +template +class scoped_allocator_adaptor : public OuterAlloc +{ + typedef allocator_traits OuterTraits; // exposition only + scoped_allocator_adaptor inner; // exposition only +public: + + typedef OuterAlloc outer_allocator_type; + typedef see below inner_allocator_type; + + typedef typename OuterTraits::value_type value_type; + typedef typename OuterTraits::size_type size_type; + typedef typename OuterTraits::difference_type difference_type; + typedef typename OuterTraits::pointer pointer; + typedef typename OuterTraits::const_pointer const_pointer; + typedef typename OuterTraits::void_pointer void_pointer; + typedef typename OuterTraits::const_void_pointer const_void_pointer; + + typedef see below propagate_on_container_copy_assignment; + typedef see below propagate_on_container_move_assignment; + typedef see below propagate_on_container_swap; + typedef see below is_always_equal; + + template + struct rebind + { + typedef scoped_allocator_adaptor< + OuterTraits::template rebind_alloc, InnerAllocs...> other; + }; + + scoped_allocator_adaptor(); + template + scoped_allocator_adaptor(OuterA2&& outerAlloc, + const InnerAllocs&... innerAllocs) noexcept; + scoped_allocator_adaptor(const scoped_allocator_adaptor& other) noexcept; + scoped_allocator_adaptor(scoped_allocator_adaptor&& other) noexcept; + template + scoped_allocator_adaptor(const scoped_allocator_adaptor& other) noexcept; + template + scoped_allocator_adaptor(const scoped_allocator_adaptor&& other) noexcept; + + scoped_allocator_adaptor& operator=(const scoped_allocator_adaptor&) = default; + scoped_allocator_adaptor& operator=(scoped_allocator_adaptor&&) = default; + ~scoped_allocator_adaptor(); + + inner_allocator_type& inner_allocator() noexcept; + const inner_allocator_type& inner_allocator() const noexcept; + + outer_allocator_type& outer_allocator() noexcept; + const outer_allocator_type& outer_allocator() const noexcept; + + pointer allocate(size_type n); // [[nodiscard]] in C++20 + pointer allocate(size_type n, const_void_pointer hint); // [[nodiscard]] in C++20 + void deallocate(pointer p, size_type n) noexcept; + + size_type max_size() const; + template void construct(T* p, Args&& args); + template + void construct(pair* p, piecewise_construct t, tuple x, + tuple y); + template + void construct(pair* p); + template + void construct(pair* p, U&& x, V&& y); + template + void construct(pair* p, const pair& x); + template + void construct(pair* p, pair&& x); + template void destroy(T* p); + + template void destroy(T* p) noexcept; + + scoped_allocator_adaptor select_on_container_copy_construction() const noexcept; +}; + +template + bool + operator==(const scoped_allocator_adaptor& a, + const scoped_allocator_adaptor& b) noexcept; + +template + bool + operator!=(const scoped_allocator_adaptor& a, + const scoped_allocator_adaptor& b) noexcept; + +} // std + +*/ + +#include "third_party/libcxx/__config" +#include "third_party/libcxx/memory" +#include "third_party/libcxx/version" + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if !defined(_LIBCPP_CXX03_LANG) + +// scoped_allocator_adaptor + +template +class scoped_allocator_adaptor; + +template struct __get_poc_copy_assignment; + +template +struct __get_poc_copy_assignment<_A0> +{ + static const bool value = allocator_traits<_A0>:: + propagate_on_container_copy_assignment::value; +}; + +template +struct __get_poc_copy_assignment<_A0, _Allocs...> +{ + static const bool value = + allocator_traits<_A0>::propagate_on_container_copy_assignment::value || + __get_poc_copy_assignment<_Allocs...>::value; +}; + +template struct __get_poc_move_assignment; + +template +struct __get_poc_move_assignment<_A0> +{ + static const bool value = allocator_traits<_A0>:: + propagate_on_container_move_assignment::value; +}; + +template +struct __get_poc_move_assignment<_A0, _Allocs...> +{ + static const bool value = + allocator_traits<_A0>::propagate_on_container_move_assignment::value || + __get_poc_move_assignment<_Allocs...>::value; +}; + +template struct __get_poc_swap; + +template +struct __get_poc_swap<_A0> +{ + static const bool value = allocator_traits<_A0>:: + propagate_on_container_swap::value; +}; + +template +struct __get_poc_swap<_A0, _Allocs...> +{ + static const bool value = + allocator_traits<_A0>::propagate_on_container_swap::value || + __get_poc_swap<_Allocs...>::value; +}; + +template struct __get_is_always_equal; + +template +struct __get_is_always_equal<_A0> +{ + static const bool value = allocator_traits<_A0>::is_always_equal::value; +}; + +template +struct __get_is_always_equal<_A0, _Allocs...> +{ + static const bool value = + allocator_traits<_A0>::is_always_equal::value && + __get_is_always_equal<_Allocs...>::value; +}; + +template +class __scoped_allocator_storage; + +template +class __scoped_allocator_storage<_OuterAlloc, _InnerAllocs...> + : public _OuterAlloc +{ + typedef _OuterAlloc outer_allocator_type; +protected: + typedef scoped_allocator_adaptor<_InnerAllocs...> inner_allocator_type; + +private: + inner_allocator_type __inner_; + +protected: + + _LIBCPP_INLINE_VISIBILITY + __scoped_allocator_storage() _NOEXCEPT {} + + template ::value + >::type> + _LIBCPP_INLINE_VISIBILITY + __scoped_allocator_storage(_OuterA2&& __outerAlloc, + const _InnerAllocs& ...__innerAllocs) _NOEXCEPT + : outer_allocator_type(_VSTD::forward<_OuterA2>(__outerAlloc)), + __inner_(__innerAllocs...) {} + + template ::value + >::type> + _LIBCPP_INLINE_VISIBILITY + __scoped_allocator_storage( + const __scoped_allocator_storage<_OuterA2, _InnerAllocs...>& __other) _NOEXCEPT + : outer_allocator_type(__other.outer_allocator()), + __inner_(__other.inner_allocator()) {} + + template ::value + >::type> + _LIBCPP_INLINE_VISIBILITY + __scoped_allocator_storage( + __scoped_allocator_storage<_OuterA2, _InnerAllocs...>&& __other) _NOEXCEPT + : outer_allocator_type(_VSTD::move(__other.outer_allocator())), + __inner_(_VSTD::move(__other.inner_allocator())) {} + + template ::value + >::type> + _LIBCPP_INLINE_VISIBILITY + __scoped_allocator_storage(_OuterA2&& __o, + const inner_allocator_type& __i) _NOEXCEPT + : outer_allocator_type(_VSTD::forward<_OuterA2>(__o)), + __inner_(__i) + { + } + + _LIBCPP_INLINE_VISIBILITY + inner_allocator_type& inner_allocator() _NOEXCEPT {return __inner_;} + _LIBCPP_INLINE_VISIBILITY + const inner_allocator_type& inner_allocator() const _NOEXCEPT {return __inner_;} + + _LIBCPP_INLINE_VISIBILITY + outer_allocator_type& outer_allocator() _NOEXCEPT + {return static_cast(*this);} + _LIBCPP_INLINE_VISIBILITY + const outer_allocator_type& outer_allocator() const _NOEXCEPT + {return static_cast(*this);} + + scoped_allocator_adaptor + _LIBCPP_INLINE_VISIBILITY + select_on_container_copy_construction() const _NOEXCEPT + { + return scoped_allocator_adaptor + ( + allocator_traits:: + select_on_container_copy_construction(outer_allocator()), + allocator_traits:: + select_on_container_copy_construction(inner_allocator()) + ); + } + + template friend class __scoped_allocator_storage; +}; + +template +class __scoped_allocator_storage<_OuterAlloc> + : public _OuterAlloc +{ + typedef _OuterAlloc outer_allocator_type; +protected: + typedef scoped_allocator_adaptor<_OuterAlloc> inner_allocator_type; + + _LIBCPP_INLINE_VISIBILITY + __scoped_allocator_storage() _NOEXCEPT {} + + template ::value + >::type> + _LIBCPP_INLINE_VISIBILITY + __scoped_allocator_storage(_OuterA2&& __outerAlloc) _NOEXCEPT + : outer_allocator_type(_VSTD::forward<_OuterA2>(__outerAlloc)) {} + + template ::value + >::type> + _LIBCPP_INLINE_VISIBILITY + __scoped_allocator_storage( + const __scoped_allocator_storage<_OuterA2>& __other) _NOEXCEPT + : outer_allocator_type(__other.outer_allocator()) {} + + template ::value + >::type> + _LIBCPP_INLINE_VISIBILITY + __scoped_allocator_storage( + __scoped_allocator_storage<_OuterA2>&& __other) _NOEXCEPT + : outer_allocator_type(_VSTD::move(__other.outer_allocator())) {} + + _LIBCPP_INLINE_VISIBILITY + inner_allocator_type& inner_allocator() _NOEXCEPT + {return static_cast(*this);} + _LIBCPP_INLINE_VISIBILITY + const inner_allocator_type& inner_allocator() const _NOEXCEPT + {return static_cast(*this);} + + _LIBCPP_INLINE_VISIBILITY + outer_allocator_type& outer_allocator() _NOEXCEPT + {return static_cast(*this);} + _LIBCPP_INLINE_VISIBILITY + const outer_allocator_type& outer_allocator() const _NOEXCEPT + {return static_cast(*this);} + + _LIBCPP_INLINE_VISIBILITY + scoped_allocator_adaptor + select_on_container_copy_construction() const _NOEXCEPT + {return scoped_allocator_adaptor( + allocator_traits:: + select_on_container_copy_construction(outer_allocator()) + );} + + __scoped_allocator_storage(const outer_allocator_type& __o, + const inner_allocator_type& __i) _NOEXCEPT; + + template friend class __scoped_allocator_storage; +}; + +// __outermost + +template +decltype(declval<_Alloc>().outer_allocator(), true_type()) +__has_outer_allocator_test(_Alloc&& __a); + +template +false_type +__has_outer_allocator_test(const volatile _Alloc& __a); + +template +struct __has_outer_allocator + : public common_type + < + decltype(__has_outer_allocator_test(declval<_Alloc&>())) + >::type +{ +}; + +template ::value> +struct __outermost +{ + typedef _Alloc type; + _LIBCPP_INLINE_VISIBILITY + type& operator()(type& __a) const _NOEXCEPT {return __a;} +}; + +template +struct __outermost<_Alloc, true> +{ + typedef typename remove_reference + < + decltype(_VSTD::declval<_Alloc>().outer_allocator()) + >::type _OuterAlloc; + typedef typename __outermost<_OuterAlloc>::type type; + _LIBCPP_INLINE_VISIBILITY + type& operator()(_Alloc& __a) const _NOEXCEPT + {return __outermost<_OuterAlloc>()(__a.outer_allocator());} +}; + +template +class _LIBCPP_TEMPLATE_VIS scoped_allocator_adaptor<_OuterAlloc, _InnerAllocs...> + : public __scoped_allocator_storage<_OuterAlloc, _InnerAllocs...> +{ + typedef __scoped_allocator_storage<_OuterAlloc, _InnerAllocs...> base; + typedef allocator_traits<_OuterAlloc> _OuterTraits; +public: + typedef _OuterAlloc outer_allocator_type; + typedef typename base::inner_allocator_type inner_allocator_type; + typedef typename _OuterTraits::size_type size_type; + typedef typename _OuterTraits::difference_type difference_type; + typedef typename _OuterTraits::pointer pointer; + typedef typename _OuterTraits::const_pointer const_pointer; + typedef typename _OuterTraits::void_pointer void_pointer; + typedef typename _OuterTraits::const_void_pointer const_void_pointer; + + typedef integral_constant + < + bool, + __get_poc_copy_assignment::value + > propagate_on_container_copy_assignment; + typedef integral_constant + < + bool, + __get_poc_move_assignment::value + > propagate_on_container_move_assignment; + typedef integral_constant + < + bool, + __get_poc_swap::value + > propagate_on_container_swap; + typedef integral_constant + < + bool, + __get_is_always_equal::value + > is_always_equal; + + template + struct rebind + { + typedef scoped_allocator_adaptor + < + typename _OuterTraits::template rebind_alloc<_Tp>, _InnerAllocs... + > other; + }; + + _LIBCPP_INLINE_VISIBILITY + scoped_allocator_adaptor() _NOEXCEPT {} + template ::value + >::type> + _LIBCPP_INLINE_VISIBILITY + scoped_allocator_adaptor(_OuterA2&& __outerAlloc, + const _InnerAllocs& ...__innerAllocs) _NOEXCEPT + : base(_VSTD::forward<_OuterA2>(__outerAlloc), __innerAllocs...) {} + // scoped_allocator_adaptor(const scoped_allocator_adaptor& __other) = default; + template ::value + >::type> + _LIBCPP_INLINE_VISIBILITY + scoped_allocator_adaptor( + const scoped_allocator_adaptor<_OuterA2, _InnerAllocs...>& __other) _NOEXCEPT + : base(__other) {} + template ::value + >::type> + _LIBCPP_INLINE_VISIBILITY + scoped_allocator_adaptor( + scoped_allocator_adaptor<_OuterA2, _InnerAllocs...>&& __other) _NOEXCEPT + : base(_VSTD::move(__other)) {} + + // scoped_allocator_adaptor& operator=(const scoped_allocator_adaptor&) = default; + // scoped_allocator_adaptor& operator=(scoped_allocator_adaptor&&) = default; + // ~scoped_allocator_adaptor() = default; + + _LIBCPP_INLINE_VISIBILITY + inner_allocator_type& inner_allocator() _NOEXCEPT + {return base::inner_allocator();} + _LIBCPP_INLINE_VISIBILITY + const inner_allocator_type& inner_allocator() const _NOEXCEPT + {return base::inner_allocator();} + + _LIBCPP_INLINE_VISIBILITY + outer_allocator_type& outer_allocator() _NOEXCEPT + {return base::outer_allocator();} + _LIBCPP_INLINE_VISIBILITY + const outer_allocator_type& outer_allocator() const _NOEXCEPT + {return base::outer_allocator();} + + _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY + pointer allocate(size_type __n) + {return allocator_traits:: + allocate(outer_allocator(), __n);} + _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY + pointer allocate(size_type __n, const_void_pointer __hint) + {return allocator_traits:: + allocate(outer_allocator(), __n, __hint);} + + _LIBCPP_INLINE_VISIBILITY + void deallocate(pointer __p, size_type __n) _NOEXCEPT + {allocator_traits:: + deallocate(outer_allocator(), __p, __n);} + + _LIBCPP_INLINE_VISIBILITY + size_type max_size() const + {return allocator_traits::max_size(outer_allocator());} + + template + _LIBCPP_INLINE_VISIBILITY + void construct(_Tp* __p, _Args&& ...__args) + {__construct(__uses_alloc_ctor<_Tp, inner_allocator_type&, _Args...>(), + __p, _VSTD::forward<_Args>(__args)...);} + + template + void construct(pair<_T1, _T2>* __p, piecewise_construct_t, + tuple<_Args1...> __x, tuple<_Args2...> __y) + { + typedef __outermost _OM; + allocator_traits::construct( + _OM()(outer_allocator()), __p, piecewise_construct + , __transform_tuple( + typename __uses_alloc_ctor< + _T1, inner_allocator_type&, _Args1... + >::type() + , _VSTD::move(__x) + , typename __make_tuple_indices::type{} + ) + , __transform_tuple( + typename __uses_alloc_ctor< + _T2, inner_allocator_type&, _Args2... + >::type() + , _VSTD::move(__y) + , typename __make_tuple_indices::type{} + ) + ); + } + + template + void construct(pair<_T1, _T2>* __p) + { construct(__p, piecewise_construct, tuple<>{}, tuple<>{}); } + + template + void construct(pair<_T1, _T2>* __p, _Up&& __x, _Vp&& __y) { + construct(__p, piecewise_construct, + _VSTD::forward_as_tuple(_VSTD::forward<_Up>(__x)), + _VSTD::forward_as_tuple(_VSTD::forward<_Vp>(__y))); + } + + template + void construct(pair<_T1, _T2>* __p, const pair<_Up, _Vp>& __x) { + construct(__p, piecewise_construct, + _VSTD::forward_as_tuple(__x.first), + _VSTD::forward_as_tuple(__x.second)); + } + + template + void construct(pair<_T1, _T2>* __p, pair<_Up, _Vp>&& __x) { + construct(__p, piecewise_construct, + _VSTD::forward_as_tuple(_VSTD::forward<_Up>(__x.first)), + _VSTD::forward_as_tuple(_VSTD::forward<_Vp>(__x.second))); + } + + template + _LIBCPP_INLINE_VISIBILITY + void destroy(_Tp* __p) + { + typedef __outermost _OM; + allocator_traits:: + destroy(_OM()(outer_allocator()), __p); + } + + _LIBCPP_INLINE_VISIBILITY + scoped_allocator_adaptor select_on_container_copy_construction() const _NOEXCEPT + {return base::select_on_container_copy_construction();} + +private: + + + template ::value + >::type> + _LIBCPP_INLINE_VISIBILITY + scoped_allocator_adaptor(_OuterA2&& __o, + const inner_allocator_type& __i) _NOEXCEPT + : base(_VSTD::forward<_OuterA2>(__o), __i) {} + + template + _LIBCPP_INLINE_VISIBILITY + void __construct(integral_constant, _Tp* __p, _Args&& ...__args) + { + typedef __outermost _OM; + allocator_traits::construct + ( + _OM()(outer_allocator()), + __p, + _VSTD::forward<_Args>(__args)... + ); + } + + template + _LIBCPP_INLINE_VISIBILITY + void __construct(integral_constant, _Tp* __p, _Args&& ...__args) + { + typedef __outermost _OM; + allocator_traits::construct + ( + _OM()(outer_allocator()), + __p, allocator_arg, inner_allocator(), + _VSTD::forward<_Args>(__args)... + ); + } + + template + _LIBCPP_INLINE_VISIBILITY + void __construct(integral_constant, _Tp* __p, _Args&& ...__args) + { + typedef __outermost _OM; + allocator_traits::construct + ( + _OM()(outer_allocator()), + __p, + _VSTD::forward<_Args>(__args)..., + inner_allocator() + ); + } + + template + _LIBCPP_INLINE_VISIBILITY + tuple<_Args&&...> + __transform_tuple(integral_constant, tuple<_Args...>&& __t, + __tuple_indices<_Idx...>) + { + return _VSTD::forward_as_tuple(_VSTD::get<_Idx>(_VSTD::move(__t))...); + } + + template + _LIBCPP_INLINE_VISIBILITY + tuple + __transform_tuple(integral_constant, tuple<_Args...> && __t, + __tuple_indices<_Idx...>) + { + using _Tup = tuple; + return _Tup(allocator_arg, inner_allocator(), + _VSTD::get<_Idx>(_VSTD::move(__t))...); + } + + template + _LIBCPP_INLINE_VISIBILITY + tuple<_Args&&..., inner_allocator_type&> + __transform_tuple(integral_constant, tuple<_Args...> && __t, + __tuple_indices<_Idx...>) + { + using _Tup = tuple<_Args&&..., inner_allocator_type&>; + return _Tup(_VSTD::get<_Idx>(_VSTD::move(__t))..., inner_allocator()); + } + + template friend class __scoped_allocator_storage; +}; + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator==(const scoped_allocator_adaptor<_OuterA1>& __a, + const scoped_allocator_adaptor<_OuterA2>& __b) _NOEXCEPT +{ + return __a.outer_allocator() == __b.outer_allocator(); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator==(const scoped_allocator_adaptor<_OuterA1, _InnerA0, _InnerAllocs...>& __a, + const scoped_allocator_adaptor<_OuterA2, _InnerA0, _InnerAllocs...>& __b) _NOEXCEPT +{ + return __a.outer_allocator() == __b.outer_allocator() && + __a.inner_allocator() == __b.inner_allocator(); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator!=(const scoped_allocator_adaptor<_OuterA1, _InnerAllocs...>& __a, + const scoped_allocator_adaptor<_OuterA2, _InnerAllocs...>& __b) _NOEXCEPT +{ + return !(__a == __b); +} + +#endif // !defined(_LIBCPP_CXX03_LANG) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_SCOPED_ALLOCATOR diff --git a/third_party/libcxx/strstream b/third_party/libcxx/strstream new file mode 100644 index 000000000..5ef123ba4 --- /dev/null +++ b/third_party/libcxx/strstream @@ -0,0 +1,400 @@ +// -*- C++ -*- +// clang-format off +//===--------------------------- strstream --------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_STRSTREAM +#define _LIBCPP_STRSTREAM + +/* + strstream synopsis + +class strstreambuf + : public basic_streambuf +{ +public: + explicit strstreambuf(streamsize alsize_arg = 0); + strstreambuf(void* (*palloc_arg)(size_t), void (*pfree_arg)(void*)); + strstreambuf(char* gnext_arg, streamsize n, char* pbeg_arg = 0); + strstreambuf(const char* gnext_arg, streamsize n); + + strstreambuf(signed char* gnext_arg, streamsize n, signed char* pbeg_arg = 0); + strstreambuf(const signed char* gnext_arg, streamsize n); + strstreambuf(unsigned char* gnext_arg, streamsize n, unsigned char* pbeg_arg = 0); + strstreambuf(const unsigned char* gnext_arg, streamsize n); + + strstreambuf(strstreambuf&& rhs); + strstreambuf& operator=(strstreambuf&& rhs); + + virtual ~strstreambuf(); + + void swap(strstreambuf& rhs); + + void freeze(bool freezefl = true); + char* str(); + int pcount() const; + +protected: + virtual int_type overflow (int_type c = EOF); + virtual int_type pbackfail(int_type c = EOF); + virtual int_type underflow(); + virtual pos_type seekoff(off_type off, ios_base::seekdir way, + ios_base::openmode which = ios_base::in | ios_base::out); + virtual pos_type seekpos(pos_type sp, + ios_base::openmode which = ios_base::in | ios_base::out); + virtual streambuf* setbuf(char* s, streamsize n); + +private: + typedef T1 strstate; // exposition only + static const strstate allocated; // exposition only + static const strstate constant; // exposition only + static const strstate dynamic; // exposition only + static const strstate frozen; // exposition only + strstate strmode; // exposition only + streamsize alsize; // exposition only + void* (*palloc)(size_t); // exposition only + void (*pfree)(void*); // exposition only +}; + +class istrstream + : public basic_istream +{ +public: + explicit istrstream(const char* s); + explicit istrstream(char* s); + istrstream(const char* s, streamsize n); + istrstream(char* s, streamsize n); + + virtual ~istrstream(); + + strstreambuf* rdbuf() const; + char *str(); + +private: + strstreambuf sb; // exposition only +}; + +class ostrstream + : public basic_ostream +{ +public: + ostrstream(); + ostrstream(char* s, int n, ios_base::openmode mode = ios_base::out); + + virtual ~ostrstream(); + + strstreambuf* rdbuf() const; + void freeze(bool freezefl = true); + char* str(); + int pcount() const; + +private: + strstreambuf sb; // exposition only +}; + +class strstream + : public basic_iostream +{ +public: + // Types + typedef char char_type; + typedef char_traits::int_type int_type; + typedef char_traits::pos_type pos_type; + typedef char_traits::off_type off_type; + + // constructors/destructor + strstream(); + strstream(char* s, int n, ios_base::openmode mode = ios_base::in | ios_base::out); + + virtual ~strstream(); + + // Members: + strstreambuf* rdbuf() const; + void freeze(bool freezefl = true); + int pcount() const; + char* str(); + +private: + strstreambuf sb; // exposition only +}; + +} // std + +*/ + +#include "third_party/libcxx/__config" +#include "third_party/libcxx/ostream" +#include "third_party/libcxx/istream" + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +class _LIBCPP_TYPE_VIS strstreambuf + : public streambuf +{ +public: + explicit strstreambuf(streamsize __alsize = 0); + strstreambuf(void* (*__palloc)(size_t), void (*__pfree)(void*)); + strstreambuf(char* __gnext, streamsize __n, char* __pbeg = 0); + strstreambuf(const char* __gnext, streamsize __n); + + strstreambuf(signed char* __gnext, streamsize __n, signed char* __pbeg = 0); + strstreambuf(const signed char* __gnext, streamsize __n); + strstreambuf(unsigned char* __gnext, streamsize __n, unsigned char* __pbeg = 0); + strstreambuf(const unsigned char* __gnext, streamsize __n); + +#ifndef _LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY + strstreambuf(strstreambuf&& __rhs); + _LIBCPP_INLINE_VISIBILITY + strstreambuf& operator=(strstreambuf&& __rhs); +#endif // _LIBCPP_CXX03_LANG + + virtual ~strstreambuf(); + + void swap(strstreambuf& __rhs); + + void freeze(bool __freezefl = true); + char* str(); + int pcount() const; + +protected: + virtual int_type overflow (int_type __c = EOF); + virtual int_type pbackfail(int_type __c = EOF); + virtual int_type underflow(); + virtual pos_type seekoff(off_type __off, ios_base::seekdir __way, + ios_base::openmode __which = ios_base::in | ios_base::out); + virtual pos_type seekpos(pos_type __sp, + ios_base::openmode __which = ios_base::in | ios_base::out); + +private: + typedef unsigned __mode_type; + static const __mode_type __allocated = 0x01; + static const __mode_type __constant = 0x02; + static const __mode_type __dynamic = 0x04; + static const __mode_type __frozen = 0x08; + static const streamsize __default_alsize = 4096; + + __mode_type __strmode_; + streamsize __alsize_; + void* (*__palloc_)(size_t); + void (*__pfree_)(void*); + + void __init(char* __gnext, streamsize __n, char* __pbeg); +}; + +#ifndef _LIBCPP_CXX03_LANG + +inline _LIBCPP_INLINE_VISIBILITY +strstreambuf::strstreambuf(strstreambuf&& __rhs) + : streambuf(__rhs), + __strmode_(__rhs.__strmode_), + __alsize_(__rhs.__alsize_), + __palloc_(__rhs.__palloc_), + __pfree_(__rhs.__pfree_) +{ + __rhs.setg(nullptr, nullptr, nullptr); + __rhs.setp(nullptr, nullptr); +} + +inline _LIBCPP_INLINE_VISIBILITY +strstreambuf& +strstreambuf::operator=(strstreambuf&& __rhs) +{ + if (eback() && (__strmode_ & __allocated) != 0 && (__strmode_ & __frozen) == 0) + { + if (__pfree_) + __pfree_(eback()); + else + delete [] eback(); + } + streambuf::operator=(__rhs); + __strmode_ = __rhs.__strmode_; + __alsize_ = __rhs.__alsize_; + __palloc_ = __rhs.__palloc_; + __pfree_ = __rhs.__pfree_; + __rhs.setg(nullptr, nullptr, nullptr); + __rhs.setp(nullptr, nullptr); + return *this; +} + +#endif // _LIBCPP_CXX03_LANG + +class _LIBCPP_TYPE_VIS istrstream + : public istream +{ +public: + _LIBCPP_INLINE_VISIBILITY + explicit istrstream(const char* __s) + : istream(&__sb_), __sb_(__s, 0) {} + _LIBCPP_INLINE_VISIBILITY + explicit istrstream(char* __s) + : istream(&__sb_), __sb_(__s, 0) {} + _LIBCPP_INLINE_VISIBILITY + istrstream(const char* __s, streamsize __n) + : istream(&__sb_), __sb_(__s, __n) {} + _LIBCPP_INLINE_VISIBILITY + istrstream(char* __s, streamsize __n) + : istream(&__sb_), __sb_(__s, __n) {} + +#ifndef _LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY + istrstream(istrstream&& __rhs) + : istream(_VSTD::move(__rhs)), + __sb_(_VSTD::move(__rhs.__sb_)) + { + istream::set_rdbuf(&__sb_); + } + + _LIBCPP_INLINE_VISIBILITY + istrstream& operator=(istrstream&& __rhs) + { + istream::operator=(_VSTD::move(__rhs)); + __sb_ = _VSTD::move(__rhs.__sb_); + return *this; + } +#endif // _LIBCPP_CXX03_LANG + + virtual ~istrstream(); + + _LIBCPP_INLINE_VISIBILITY + void swap(istrstream& __rhs) + { + istream::swap(__rhs); + __sb_.swap(__rhs.__sb_); + } + + _LIBCPP_INLINE_VISIBILITY + strstreambuf* rdbuf() const {return const_cast(&__sb_);} + _LIBCPP_INLINE_VISIBILITY + char *str() {return __sb_.str();} + +private: + strstreambuf __sb_; +}; + +class _LIBCPP_TYPE_VIS ostrstream + : public ostream +{ +public: + _LIBCPP_INLINE_VISIBILITY + ostrstream() + : ostream(&__sb_) {} + _LIBCPP_INLINE_VISIBILITY + ostrstream(char* __s, int __n, ios_base::openmode __mode = ios_base::out) + : ostream(&__sb_), + __sb_(__s, __n, __s + (__mode & ios::app ? strlen(__s) : 0)) + {} + +#ifndef _LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY + ostrstream(ostrstream&& __rhs) + : ostream(_VSTD::move(__rhs)), + __sb_(_VSTD::move(__rhs.__sb_)) + { + ostream::set_rdbuf(&__sb_); + } + + _LIBCPP_INLINE_VISIBILITY + ostrstream& operator=(ostrstream&& __rhs) + { + ostream::operator=(_VSTD::move(__rhs)); + __sb_ = _VSTD::move(__rhs.__sb_); + return *this; + } +#endif // _LIBCPP_CXX03_LANG + + virtual ~ostrstream(); + + _LIBCPP_INLINE_VISIBILITY + void swap(ostrstream& __rhs) + { + ostream::swap(__rhs); + __sb_.swap(__rhs.__sb_); + } + + _LIBCPP_INLINE_VISIBILITY + strstreambuf* rdbuf() const {return const_cast(&__sb_);} + _LIBCPP_INLINE_VISIBILITY + void freeze(bool __freezefl = true) {__sb_.freeze(__freezefl);} + _LIBCPP_INLINE_VISIBILITY + char* str() {return __sb_.str();} + _LIBCPP_INLINE_VISIBILITY + int pcount() const {return __sb_.pcount();} + +private: + strstreambuf __sb_; // exposition only +}; + +class _LIBCPP_TYPE_VIS strstream + : public iostream +{ +public: + // Types + typedef char char_type; + typedef char_traits::int_type int_type; + typedef char_traits::pos_type pos_type; + typedef char_traits::off_type off_type; + + // constructors/destructor + _LIBCPP_INLINE_VISIBILITY + strstream() + : iostream(&__sb_) {} + _LIBCPP_INLINE_VISIBILITY + strstream(char* __s, int __n, ios_base::openmode __mode = ios_base::in | ios_base::out) + : iostream(&__sb_), + __sb_(__s, __n, __s + (__mode & ios::app ? strlen(__s) : 0)) + {} + +#ifndef _LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY + strstream(strstream&& __rhs) + : iostream(_VSTD::move(__rhs)), + __sb_(_VSTD::move(__rhs.__sb_)) + { + iostream::set_rdbuf(&__sb_); + } + + _LIBCPP_INLINE_VISIBILITY + strstream& operator=(strstream&& __rhs) + { + iostream::operator=(_VSTD::move(__rhs)); + __sb_ = _VSTD::move(__rhs.__sb_); + return *this; + } +#endif // _LIBCPP_CXX03_LANG + + virtual ~strstream(); + + _LIBCPP_INLINE_VISIBILITY + void swap(strstream& __rhs) + { + iostream::swap(__rhs); + __sb_.swap(__rhs.__sb_); + } + + // Members: + _LIBCPP_INLINE_VISIBILITY + strstreambuf* rdbuf() const {return const_cast(&__sb_);} + _LIBCPP_INLINE_VISIBILITY + void freeze(bool __freezefl = true) {__sb_.freeze(__freezefl);} + _LIBCPP_INLINE_VISIBILITY + int pcount() const {return __sb_.pcount();} + _LIBCPP_INLINE_VISIBILITY + char* str() {return __sb_.str();} + +private: + strstreambuf __sb_; // exposition only +}; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STRSTREAM diff --git a/third_party/libcxx/strstream.cc b/third_party/libcxx/strstream.cc new file mode 100644 index 000000000..9fdb2398c --- /dev/null +++ b/third_party/libcxx/strstream.cc @@ -0,0 +1,336 @@ +// clang-format off +//===------------------------ strstream.cpp -------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "third_party/libcxx/strstream" +#include "third_party/libcxx/algorithm" +#include "third_party/libcxx/climits" +#include "third_party/libcxx/cstring" +#include "third_party/libcxx/cstdlib" +#include "third_party/libcxx/__debug" +#include "third_party/libcxx/__undef_macros" + +_LIBCPP_BEGIN_NAMESPACE_STD + +strstreambuf::strstreambuf(streamsize __alsize) + : __strmode_(__dynamic), + __alsize_(__alsize), + __palloc_(nullptr), + __pfree_(nullptr) +{ +} + +strstreambuf::strstreambuf(void* (*__palloc)(size_t), void (*__pfree)(void*)) + : __strmode_(__dynamic), + __alsize_(__default_alsize), + __palloc_(__palloc), + __pfree_(__pfree) +{ +} + +void +strstreambuf::__init(char* __gnext, streamsize __n, char* __pbeg) +{ + if (__n == 0) + __n = static_cast(strlen(__gnext)); + else if (__n < 0) + __n = INT_MAX; + if (__pbeg == nullptr) + setg(__gnext, __gnext, __gnext + __n); + else + { + setg(__gnext, __gnext, __pbeg); + setp(__pbeg, __pbeg + __n); + } +} + +strstreambuf::strstreambuf(char* __gnext, streamsize __n, char* __pbeg) + : __strmode_(), + __alsize_(__default_alsize), + __palloc_(nullptr), + __pfree_(nullptr) +{ + __init(__gnext, __n, __pbeg); +} + +strstreambuf::strstreambuf(const char* __gnext, streamsize __n) + : __strmode_(__constant), + __alsize_(__default_alsize), + __palloc_(nullptr), + __pfree_(nullptr) +{ + __init(const_cast(__gnext), __n, nullptr); +} + +strstreambuf::strstreambuf(signed char* __gnext, streamsize __n, signed char* __pbeg) + : __strmode_(), + __alsize_(__default_alsize), + __palloc_(nullptr), + __pfree_(nullptr) +{ + __init(const_cast(reinterpret_cast(__gnext)), __n, reinterpret_cast(__pbeg)); +} + +strstreambuf::strstreambuf(const signed char* __gnext, streamsize __n) + : __strmode_(__constant), + __alsize_(__default_alsize), + __palloc_(nullptr), + __pfree_(nullptr) +{ + __init(const_cast(reinterpret_cast(__gnext)), __n, nullptr); +} + +strstreambuf::strstreambuf(unsigned char* __gnext, streamsize __n, unsigned char* __pbeg) + : __strmode_(), + __alsize_(__default_alsize), + __palloc_(nullptr), + __pfree_(nullptr) +{ + __init(const_cast(reinterpret_cast(__gnext)), __n, reinterpret_cast(__pbeg)); +} + +strstreambuf::strstreambuf(const unsigned char* __gnext, streamsize __n) + : __strmode_(__constant), + __alsize_(__default_alsize), + __palloc_(nullptr), + __pfree_(nullptr) +{ + __init(const_cast(reinterpret_cast(__gnext)), __n, nullptr); +} + +strstreambuf::~strstreambuf() +{ + if (eback() && (__strmode_ & __allocated) != 0 && (__strmode_ & __frozen) == 0) + { + if (__pfree_) + __pfree_(eback()); + else + delete [] eback(); + } +} + +void +strstreambuf::swap(strstreambuf& __rhs) +{ + streambuf::swap(__rhs); + _VSTD::swap(__strmode_, __rhs.__strmode_); + _VSTD::swap(__alsize_, __rhs.__alsize_); + _VSTD::swap(__palloc_, __rhs.__palloc_); + _VSTD::swap(__pfree_, __rhs.__pfree_); +} + +void +strstreambuf::freeze(bool __freezefl) +{ + if (__strmode_ & __dynamic) + { + if (__freezefl) + __strmode_ |= __frozen; + else + __strmode_ &= ~__frozen; + } +} + +char* +strstreambuf::str() +{ + if (__strmode_ & __dynamic) + __strmode_ |= __frozen; + return eback(); +} + +int +strstreambuf::pcount() const +{ + return static_cast(pptr() - pbase()); +} + +strstreambuf::int_type +strstreambuf::overflow(int_type __c) +{ + if (__c == EOF) + return int_type(0); + if (pptr() == epptr()) + { + if ((__strmode_ & __dynamic) == 0 || (__strmode_ & __frozen) != 0) + return int_type(EOF); + size_t old_size = static_cast ((epptr() ? epptr() : egptr()) - eback()); + size_t new_size = max(static_cast(__alsize_), 2*old_size); + if (new_size == 0) + new_size = __default_alsize; + char* buf = nullptr; + if (__palloc_) + buf = static_cast(__palloc_(new_size)); + else + buf = new char[new_size]; + if (buf == nullptr) + return int_type(EOF); + if (old_size != 0) { + _LIBCPP_ASSERT(eback(), "overflow copying from NULL"); + memcpy(buf, eback(), static_cast(old_size)); + } + ptrdiff_t ninp = gptr() - eback(); + ptrdiff_t einp = egptr() - eback(); + ptrdiff_t nout = pptr() - pbase(); + if (__strmode_ & __allocated) + { + if (__pfree_) + __pfree_(eback()); + else + delete [] eback(); + } + setg(buf, buf + ninp, buf + einp); + setp(buf + einp, buf + new_size); + __pbump(nout); + __strmode_ |= __allocated; + } + *pptr() = static_cast(__c); + pbump(1); + return int_type(static_cast(__c)); +} + +strstreambuf::int_type +strstreambuf::pbackfail(int_type __c) +{ + if (eback() == gptr()) + return EOF; + if (__c == EOF) + { + gbump(-1); + return int_type(0); + } + if (__strmode_ & __constant) + { + if (gptr()[-1] == static_cast(__c)) + { + gbump(-1); + return __c; + } + return EOF; + } + gbump(-1); + *gptr() = static_cast(__c); + return __c; +} + +strstreambuf::int_type +strstreambuf::underflow() +{ + if (gptr() == egptr()) + { + if (egptr() >= pptr()) + return EOF; + setg(eback(), gptr(), pptr()); + } + return int_type(static_cast(*gptr())); +} + +strstreambuf::pos_type +strstreambuf::seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode __which) +{ + off_type __p(-1); + bool pos_in = (__which & ios::in) != 0; + bool pos_out = (__which & ios::out) != 0; + bool legal = false; + switch (__way) + { + case ios::beg: + case ios::end: + if (pos_in || pos_out) + legal = true; + break; + case ios::cur: + if (pos_in != pos_out) + legal = true; + break; + } + if (pos_in && gptr() == nullptr) + legal = false; + if (pos_out && pptr() == nullptr) + legal = false; + if (legal) + { + off_type newoff; + char* seekhigh = epptr() ? epptr() : egptr(); + switch (__way) + { + case ios::beg: + newoff = 0; + break; + case ios::cur: + newoff = (pos_in ? gptr() : pptr()) - eback(); + break; + case ios::end: + newoff = seekhigh - eback(); + break; + default: + _LIBCPP_UNREACHABLE(); + } + newoff += __off; + if (0 <= newoff && newoff <= seekhigh - eback()) + { + char* newpos = eback() + newoff; + if (pos_in) + setg(eback(), newpos, _VSTD::max(newpos, egptr())); + if (pos_out) + { + // min(pbase, newpos), newpos, epptr() + __off = epptr() - newpos; + setp(min(pbase(), newpos), epptr()); + __pbump((epptr() - pbase()) - __off); + } + __p = newoff; + } + } + return pos_type(__p); +} + +strstreambuf::pos_type +strstreambuf::seekpos(pos_type __sp, ios_base::openmode __which) +{ + off_type __p(-1); + bool pos_in = (__which & ios::in) != 0; + bool pos_out = (__which & ios::out) != 0; + if (pos_in || pos_out) + { + if (!((pos_in && gptr() == nullptr) || (pos_out && pptr() == nullptr))) + { + off_type newoff = __sp; + char* seekhigh = epptr() ? epptr() : egptr(); + if (0 <= newoff && newoff <= seekhigh - eback()) + { + char* newpos = eback() + newoff; + if (pos_in) + setg(eback(), newpos, _VSTD::max(newpos, egptr())); + if (pos_out) + { + // min(pbase, newpos), newpos, epptr() + off_type temp = epptr() - newpos; + setp(min(pbase(), newpos), epptr()); + __pbump((epptr() - pbase()) - temp); + } + __p = newoff; + } + } + } + return pos_type(__p); +} + +istrstream::~istrstream() +{ +} + +ostrstream::~ostrstream() +{ +} + +strstream::~strstream() +{ +} + +_LIBCPP_END_NAMESPACE_STD diff --git a/third_party/libcxx/typeindex b/third_party/libcxx/typeindex new file mode 100644 index 000000000..b69943c29 --- /dev/null +++ b/third_party/libcxx/typeindex @@ -0,0 +1,103 @@ +// -*- C++ -*- +// clang-format off +//===-------------------------- typeindex ---------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_TYPEINDEX +#define _LIBCPP_TYPEINDEX + +/* + + typeindex synopsis + +namespace std +{ + +class type_index +{ +public: + type_index(const type_info& rhs) noexcept; + + bool operator==(const type_index& rhs) const noexcept; + bool operator!=(const type_index& rhs) const noexcept; + bool operator< (const type_index& rhs) const noexcept; + bool operator<=(const type_index& rhs) const noexcept; + bool operator> (const type_index& rhs) const noexcept; + bool operator>=(const type_index& rhs) const noexcept; + + size_t hash_code() const noexcept; + const char* name() const noexcept; +}; + +template <> +struct hash + : public unary_function +{ + size_t operator()(type_index index) const noexcept; +}; + +} // std + +*/ + +#include "third_party/libcxx/__config" +#include "third_party/libcxx/typeinfo" +#include "third_party/libcxx/__functional_base" + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +class _LIBCPP_TEMPLATE_VIS type_index +{ + const type_info* __t_; +public: + _LIBCPP_INLINE_VISIBILITY + type_index(const type_info& __y) _NOEXCEPT : __t_(&__y) {} + + _LIBCPP_INLINE_VISIBILITY + bool operator==(const type_index& __y) const _NOEXCEPT + {return *__t_ == *__y.__t_;} + _LIBCPP_INLINE_VISIBILITY + bool operator!=(const type_index& __y) const _NOEXCEPT + {return *__t_ != *__y.__t_;} + _LIBCPP_INLINE_VISIBILITY + bool operator< (const type_index& __y) const _NOEXCEPT + {return __t_->before(*__y.__t_);} + _LIBCPP_INLINE_VISIBILITY + bool operator<=(const type_index& __y) const _NOEXCEPT + {return !__y.__t_->before(*__t_);} + _LIBCPP_INLINE_VISIBILITY + bool operator> (const type_index& __y) const _NOEXCEPT + {return __y.__t_->before(*__t_);} + _LIBCPP_INLINE_VISIBILITY + bool operator>=(const type_index& __y) const _NOEXCEPT + {return !__t_->before(*__y.__t_);} + + _LIBCPP_INLINE_VISIBILITY + size_t hash_code() const _NOEXCEPT {return __t_->hash_code();} + _LIBCPP_INLINE_VISIBILITY + const char* name() const _NOEXCEPT {return __t_->name();} +}; + +template struct _LIBCPP_TEMPLATE_VIS hash; + +template <> +struct _LIBCPP_TEMPLATE_VIS hash + : public unary_function +{ + _LIBCPP_INLINE_VISIBILITY + size_t operator()(type_index __index) const _NOEXCEPT + {return __index.hash_code();} +}; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_TYPEINDEX diff --git a/third_party/libcxx/valarray b/third_party/libcxx/valarray new file mode 100644 index 000000000..6bb5d2e48 --- /dev/null +++ b/third_party/libcxx/valarray @@ -0,0 +1,4943 @@ +// -*- C++ -*- +// clang-format off +//===-------------------------- valarray ----------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_VALARRAY +#define _LIBCPP_VALARRAY + +/* + valarray synopsis + +namespace std +{ + +template +class valarray +{ +public: + typedef T value_type; + + // construct/destroy: + valarray(); + explicit valarray(size_t n); + valarray(const value_type& x, size_t n); + valarray(const value_type* px, size_t n); + valarray(const valarray& v); + valarray(valarray&& v) noexcept; + valarray(const slice_array& sa); + valarray(const gslice_array& ga); + valarray(const mask_array& ma); + valarray(const indirect_array& ia); + valarray(initializer_list il); + ~valarray(); + + // assignment: + valarray& operator=(const valarray& v); + valarray& operator=(valarray&& v) noexcept; + valarray& operator=(initializer_list il); + valarray& operator=(const value_type& x); + valarray& operator=(const slice_array& sa); + valarray& operator=(const gslice_array& ga); + valarray& operator=(const mask_array& ma); + valarray& operator=(const indirect_array& ia); + + // element access: + const value_type& operator[](size_t i) const; + value_type& operator[](size_t i); + + // subset operations: + valarray operator[](slice s) const; + slice_array operator[](slice s); + valarray operator[](const gslice& gs) const; + gslice_array operator[](const gslice& gs); + valarray operator[](const valarray& vb) const; + mask_array operator[](const valarray& vb); + valarray operator[](const valarray& vs) const; + indirect_array operator[](const valarray& vs); + + // unary operators: + valarray operator+() const; + valarray operator-() const; + valarray operator~() const; + valarray operator!() const; + + // computed assignment: + valarray& operator*= (const value_type& x); + valarray& operator/= (const value_type& x); + valarray& operator%= (const value_type& x); + valarray& operator+= (const value_type& x); + valarray& operator-= (const value_type& x); + valarray& operator^= (const value_type& x); + valarray& operator&= (const value_type& x); + valarray& operator|= (const value_type& x); + valarray& operator<<=(const value_type& x); + valarray& operator>>=(const value_type& x); + + valarray& operator*= (const valarray& v); + valarray& operator/= (const valarray& v); + valarray& operator%= (const valarray& v); + valarray& operator+= (const valarray& v); + valarray& operator-= (const valarray& v); + valarray& operator^= (const valarray& v); + valarray& operator|= (const valarray& v); + valarray& operator&= (const valarray& v); + valarray& operator<<=(const valarray& v); + valarray& operator>>=(const valarray& v); + + // member functions: + void swap(valarray& v) noexcept; + + size_t size() const; + + value_type sum() const; + value_type min() const; + value_type max() const; + + valarray shift (int i) const; + valarray cshift(int i) const; + valarray apply(value_type f(value_type)) const; + valarray apply(value_type f(const value_type&)) const; + void resize(size_t n, value_type x = value_type()); +}; + +class slice +{ +public: + slice(); + slice(size_t start, size_t size, size_t stride); + + size_t start() const; + size_t size() const; + size_t stride() const; +}; + +template +class slice_array +{ +public: + typedef T value_type; + + const slice_array& operator=(const slice_array& sa) const; + void operator= (const valarray& v) const; + void operator*= (const valarray& v) const; + void operator/= (const valarray& v) const; + void operator%= (const valarray& v) const; + void operator+= (const valarray& v) const; + void operator-= (const valarray& v) const; + void operator^= (const valarray& v) const; + void operator&= (const valarray& v) const; + void operator|= (const valarray& v) const; + void operator<<=(const valarray& v) const; + void operator>>=(const valarray& v) const; + + void operator=(const value_type& x) const; + + slice_array() = delete; +}; + +class gslice +{ +public: + gslice(); + gslice(size_t start, const valarray& size, + const valarray& stride); + + size_t start() const; + valarray size() const; + valarray stride() const; +}; + +template +class gslice_array +{ +public: + typedef T value_type; + + void operator= (const valarray& v) const; + void operator*= (const valarray& v) const; + void operator/= (const valarray& v) const; + void operator%= (const valarray& v) const; + void operator+= (const valarray& v) const; + void operator-= (const valarray& v) const; + void operator^= (const valarray& v) const; + void operator&= (const valarray& v) const; + void operator|= (const valarray& v) const; + void operator<<=(const valarray& v) const; + void operator>>=(const valarray& v) const; + + gslice_array(const gslice_array& ga); + ~gslice_array(); + const gslice_array& operator=(const gslice_array& ga) const; + void operator=(const value_type& x) const; + + gslice_array() = delete; +}; + +template +class mask_array +{ +public: + typedef T value_type; + + void operator= (const valarray& v) const; + void operator*= (const valarray& v) const; + void operator/= (const valarray& v) const; + void operator%= (const valarray& v) const; + void operator+= (const valarray& v) const; + void operator-= (const valarray& v) const; + void operator^= (const valarray& v) const; + void operator&= (const valarray& v) const; + void operator|= (const valarray& v) const; + void operator<<=(const valarray& v) const; + void operator>>=(const valarray& v) const; + + mask_array(const mask_array& ma); + ~mask_array(); + const mask_array& operator=(const mask_array& ma) const; + void operator=(const value_type& x) const; + + mask_array() = delete; +}; + +template +class indirect_array +{ +public: + typedef T value_type; + + void operator= (const valarray& v) const; + void operator*= (const valarray& v) const; + void operator/= (const valarray& v) const; + void operator%= (const valarray& v) const; + void operator+= (const valarray& v) const; + void operator-= (const valarray& v) const; + void operator^= (const valarray& v) const; + void operator&= (const valarray& v) const; + void operator|= (const valarray& v) const; + void operator<<=(const valarray& v) const; + void operator>>=(const valarray& v) const; + + indirect_array(const indirect_array& ia); + ~indirect_array(); + const indirect_array& operator=(const indirect_array& ia) const; + void operator=(const value_type& x) const; + + indirect_array() = delete; +}; + +template void swap(valarray& x, valarray& y) noexcept; + +template valarray operator* (const valarray& x, const valarray& y); +template valarray operator* (const valarray& x, const T& y); +template valarray operator* (const T& x, const valarray& y); + +template valarray operator/ (const valarray& x, const valarray& y); +template valarray operator/ (const valarray& x, const T& y); +template valarray operator/ (const T& x, const valarray& y); + +template valarray operator% (const valarray& x, const valarray& y); +template valarray operator% (const valarray& x, const T& y); +template valarray operator% (const T& x, const valarray& y); + +template valarray operator+ (const valarray& x, const valarray& y); +template valarray operator+ (const valarray& x, const T& y); +template valarray operator+ (const T& x, const valarray& y); + +template valarray operator- (const valarray& x, const valarray& y); +template valarray operator- (const valarray& x, const T& y); +template valarray operator- (const T& x, const valarray& y); + +template valarray operator^ (const valarray& x, const valarray& y); +template valarray operator^ (const valarray& x, const T& y); +template valarray operator^ (const T& x, const valarray& y); + +template valarray operator& (const valarray& x, const valarray& y); +template valarray operator& (const valarray& x, const T& y); +template valarray operator& (const T& x, const valarray& y); + +template valarray operator| (const valarray& x, const valarray& y); +template valarray operator| (const valarray& x, const T& y); +template valarray operator| (const T& x, const valarray& y); + +template valarray operator<<(const valarray& x, const valarray& y); +template valarray operator<<(const valarray& x, const T& y); +template valarray operator<<(const T& x, const valarray& y); + +template valarray operator>>(const valarray& x, const valarray& y); +template valarray operator>>(const valarray& x, const T& y); +template valarray operator>>(const T& x, const valarray& y); + +template valarray operator&&(const valarray& x, const valarray& y); +template valarray operator&&(const valarray& x, const T& y); +template valarray operator&&(const T& x, const valarray& y); + +template valarray operator||(const valarray& x, const valarray& y); +template valarray operator||(const valarray& x, const T& y); +template valarray operator||(const T& x, const valarray& y); + +template valarray operator==(const valarray& x, const valarray& y); +template valarray operator==(const valarray& x, const T& y); +template valarray operator==(const T& x, const valarray& y); + +template valarray operator!=(const valarray& x, const valarray& y); +template valarray operator!=(const valarray& x, const T& y); +template valarray operator!=(const T& x, const valarray& y); + +template valarray operator< (const valarray& x, const valarray& y); +template valarray operator< (const valarray& x, const T& y); +template valarray operator< (const T& x, const valarray& y); + +template valarray operator> (const valarray& x, const valarray& y); +template valarray operator> (const valarray& x, const T& y); +template valarray operator> (const T& x, const valarray& y); + +template valarray operator<=(const valarray& x, const valarray& y); +template valarray operator<=(const valarray& x, const T& y); +template valarray operator<=(const T& x, const valarray& y); + +template valarray operator>=(const valarray& x, const valarray& y); +template valarray operator>=(const valarray& x, const T& y); +template valarray operator>=(const T& x, const valarray& y); + +template valarray abs (const valarray& x); +template valarray acos (const valarray& x); +template valarray asin (const valarray& x); +template valarray atan (const valarray& x); + +template valarray atan2(const valarray& x, const valarray& y); +template valarray atan2(const valarray& x, const T& y); +template valarray atan2(const T& x, const valarray& y); + +template valarray cos (const valarray& x); +template valarray cosh (const valarray& x); +template valarray exp (const valarray& x); +template valarray log (const valarray& x); +template valarray log10(const valarray& x); + +template valarray pow(const valarray& x, const valarray& y); +template valarray pow(const valarray& x, const T& y); +template valarray pow(const T& x, const valarray& y); + +template valarray sin (const valarray& x); +template valarray sinh (const valarray& x); +template valarray sqrt (const valarray& x); +template valarray tan (const valarray& x); +template valarray tanh (const valarray& x); + +template unspecified1 begin(valarray& v); +template unspecified2 begin(const valarray& v); +template unspecified1 end(valarray& v); +template unspecified2 end(const valarray& v); + +} // std + +*/ + +#include "third_party/libcxx/__config" +#include "third_party/libcxx/cstddef" +#include "third_party/libcxx/cmath" +#include "third_party/libcxx/initializer_list" +#include "third_party/libcxx/algorithm" +#include "third_party/libcxx/functional" +#include "third_party/libcxx/new" + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +// MISSING #include <__undef_macros> + + +_LIBCPP_BEGIN_NAMESPACE_STD + +template class _LIBCPP_TEMPLATE_VIS valarray; + +class _LIBCPP_TEMPLATE_VIS slice +{ + size_t __start_; + size_t __size_; + size_t __stride_; +public: + _LIBCPP_INLINE_VISIBILITY + slice() + : __start_(0), + __size_(0), + __stride_(0) + {} + + _LIBCPP_INLINE_VISIBILITY + slice(size_t __start, size_t __size, size_t __stride) + : __start_(__start), + __size_(__size), + __stride_(__stride) + {} + + _LIBCPP_INLINE_VISIBILITY size_t start() const {return __start_;} + _LIBCPP_INLINE_VISIBILITY size_t size() const {return __size_;} + _LIBCPP_INLINE_VISIBILITY size_t stride() const {return __stride_;} +}; + +template class _LIBCPP_TEMPLATE_VIS slice_array; +class _LIBCPP_TYPE_VIS gslice; +template class _LIBCPP_TEMPLATE_VIS gslice_array; +template class _LIBCPP_TEMPLATE_VIS mask_array; +template class _LIBCPP_TEMPLATE_VIS indirect_array; + +template +_LIBCPP_INLINE_VISIBILITY +_Tp* +begin(valarray<_Tp>& __v); + +template +_LIBCPP_INLINE_VISIBILITY +const _Tp* +begin(const valarray<_Tp>& __v); + +template +_LIBCPP_INLINE_VISIBILITY +_Tp* +end(valarray<_Tp>& __v); + +template +_LIBCPP_INLINE_VISIBILITY +const _Tp* +end(const valarray<_Tp>& __v); + +template +struct _UnaryOp +{ + typedef typename _Op::result_type result_type; + typedef typename _A0::value_type value_type; + + _Op __op_; + _A0 __a0_; + + _LIBCPP_INLINE_VISIBILITY + _UnaryOp(const _Op& __op, const _A0& __a0) : __op_(__op), __a0_(__a0) {} + + _LIBCPP_INLINE_VISIBILITY + result_type operator[](size_t __i) const {return __op_(__a0_[__i]);} + + _LIBCPP_INLINE_VISIBILITY + size_t size() const {return __a0_.size();} +}; + +template +struct _BinaryOp +{ + typedef typename _Op::result_type result_type; + typedef typename _A0::value_type value_type; + + _Op __op_; + _A0 __a0_; + _A1 __a1_; + + _LIBCPP_INLINE_VISIBILITY + _BinaryOp(const _Op& __op, const _A0& __a0, const _A1& __a1) + : __op_(__op), __a0_(__a0), __a1_(__a1) {} + + _LIBCPP_INLINE_VISIBILITY + value_type operator[](size_t __i) const {return __op_(__a0_[__i], __a1_[__i]);} + + _LIBCPP_INLINE_VISIBILITY + size_t size() const {return __a0_.size();} +}; + +template +class __scalar_expr +{ +public: + typedef _Tp value_type; + typedef const _Tp& result_type; +private: + const value_type& __t_; + size_t __s_; +public: + _LIBCPP_INLINE_VISIBILITY + explicit __scalar_expr(const value_type& __t, size_t __s) : __t_(__t), __s_(__s) {} + + _LIBCPP_INLINE_VISIBILITY + result_type operator[](size_t) const {return __t_;} + + _LIBCPP_INLINE_VISIBILITY + size_t size() const {return __s_;} +}; + +template +struct __unary_plus : unary_function<_Tp, _Tp> +{ + _LIBCPP_INLINE_VISIBILITY + _Tp operator()(const _Tp& __x) const + {return +__x;} +}; + +template +struct __bit_not : unary_function<_Tp, _Tp> +{ + _LIBCPP_INLINE_VISIBILITY + _Tp operator()(const _Tp& __x) const + {return ~__x;} +}; + +template +struct __bit_shift_left : binary_function<_Tp, _Tp, _Tp> +{ + _LIBCPP_INLINE_VISIBILITY + _Tp operator()(const _Tp& __x, const _Tp& __y) const + {return __x << __y;} +}; + +template +struct __bit_shift_right : binary_function<_Tp, _Tp, _Tp> +{ + _LIBCPP_INLINE_VISIBILITY + _Tp operator()(const _Tp& __x, const _Tp& __y) const + {return __x >> __y;} +}; + +template +struct __apply_expr : unary_function<_Tp, _Tp> +{ +private: + _Fp __f_; +public: + _LIBCPP_INLINE_VISIBILITY + explicit __apply_expr(_Fp __f) : __f_(__f) {} + + _LIBCPP_INLINE_VISIBILITY + _Tp operator()(const _Tp& __x) const + {return __f_(__x);} +}; + +template +struct __abs_expr : unary_function<_Tp, _Tp> +{ + _LIBCPP_INLINE_VISIBILITY + _Tp operator()(const _Tp& __x) const + {return abs(__x);} +}; + +template +struct __acos_expr : unary_function<_Tp, _Tp> +{ + _LIBCPP_INLINE_VISIBILITY + _Tp operator()(const _Tp& __x) const + {return acos(__x);} +}; + +template +struct __asin_expr : unary_function<_Tp, _Tp> +{ + _LIBCPP_INLINE_VISIBILITY + _Tp operator()(const _Tp& __x) const + {return asin(__x);} +}; + +template +struct __atan_expr : unary_function<_Tp, _Tp> +{ + _LIBCPP_INLINE_VISIBILITY + _Tp operator()(const _Tp& __x) const + {return atan(__x);} +}; + +template +struct __atan2_expr : binary_function<_Tp, _Tp, _Tp> +{ + _LIBCPP_INLINE_VISIBILITY + _Tp operator()(const _Tp& __x, const _Tp& __y) const + {return atan2(__x, __y);} +}; + +template +struct __cos_expr : unary_function<_Tp, _Tp> +{ + _LIBCPP_INLINE_VISIBILITY + _Tp operator()(const _Tp& __x) const + {return cos(__x);} +}; + +template +struct __cosh_expr : unary_function<_Tp, _Tp> +{ + _LIBCPP_INLINE_VISIBILITY + _Tp operator()(const _Tp& __x) const + {return cosh(__x);} +}; + +template +struct __exp_expr : unary_function<_Tp, _Tp> +{ + _LIBCPP_INLINE_VISIBILITY + _Tp operator()(const _Tp& __x) const + {return exp(__x);} +}; + +template +struct __log_expr : unary_function<_Tp, _Tp> +{ + _LIBCPP_INLINE_VISIBILITY + _Tp operator()(const _Tp& __x) const + {return log(__x);} +}; + +template +struct __log10_expr : unary_function<_Tp, _Tp> +{ + _LIBCPP_INLINE_VISIBILITY + _Tp operator()(const _Tp& __x) const + {return log10(__x);} +}; + +template +struct __pow_expr : binary_function<_Tp, _Tp, _Tp> +{ + _LIBCPP_INLINE_VISIBILITY + _Tp operator()(const _Tp& __x, const _Tp& __y) const + {return pow(__x, __y);} +}; + +template +struct __sin_expr : unary_function<_Tp, _Tp> +{ + _LIBCPP_INLINE_VISIBILITY + _Tp operator()(const _Tp& __x) const + {return sin(__x);} +}; + +template +struct __sinh_expr : unary_function<_Tp, _Tp> +{ + _LIBCPP_INLINE_VISIBILITY + _Tp operator()(const _Tp& __x) const + {return sinh(__x);} +}; + +template +struct __sqrt_expr : unary_function<_Tp, _Tp> +{ + _LIBCPP_INLINE_VISIBILITY + _Tp operator()(const _Tp& __x) const + {return sqrt(__x);} +}; + +template +struct __tan_expr : unary_function<_Tp, _Tp> +{ + _LIBCPP_INLINE_VISIBILITY + _Tp operator()(const _Tp& __x) const + {return tan(__x);} +}; + +template +struct __tanh_expr : unary_function<_Tp, _Tp> +{ + _LIBCPP_INLINE_VISIBILITY + _Tp operator()(const _Tp& __x) const + {return tanh(__x);} +}; + +template +class __slice_expr +{ + typedef typename remove_reference<_ValExpr>::type _RmExpr; +public: + typedef typename _RmExpr::value_type value_type; + typedef value_type result_type; + +private: + _ValExpr __expr_; + size_t __start_; + size_t __size_; + size_t __stride_; + + _LIBCPP_INLINE_VISIBILITY + __slice_expr(const slice& __sl, const _RmExpr& __e) + : __expr_(__e), + __start_(__sl.start()), + __size_(__sl.size()), + __stride_(__sl.stride()) + {} +public: + + _LIBCPP_INLINE_VISIBILITY + result_type operator[](size_t __i) const + {return __expr_[__start_ + __i * __stride_];} + + _LIBCPP_INLINE_VISIBILITY + size_t size() const {return __size_;} + + template friend class __val_expr; + template friend class _LIBCPP_TEMPLATE_VIS valarray; +}; + +template +class __mask_expr; + +template +class __indirect_expr; + +template +class __shift_expr +{ + typedef typename remove_reference<_ValExpr>::type _RmExpr; +public: + typedef typename _RmExpr::value_type value_type; + typedef value_type result_type; + +private: + _ValExpr __expr_; + size_t __size_; + ptrdiff_t __ul_; + ptrdiff_t __sn_; + ptrdiff_t __n_; + static const ptrdiff_t _Np = static_cast( + sizeof(ptrdiff_t) * __CHAR_BIT__ - 1); + + _LIBCPP_INLINE_VISIBILITY + __shift_expr(int __n, const _RmExpr& __e) + : __expr_(__e), + __size_(__e.size()), + __n_(__n) + { + ptrdiff_t __neg_n = static_cast(__n_ >> _Np); + __sn_ = __neg_n | static_cast(static_cast(-__n_) >> _Np); + __ul_ = ((__size_ - __n_) & ~__neg_n) | ((__n_ + 1) & __neg_n); + } +public: + + _LIBCPP_INLINE_VISIBILITY + result_type operator[](size_t __j) const + { + ptrdiff_t __i = static_cast(__j); + ptrdiff_t __m = (__sn_ * __i - __ul_) >> _Np; + return (__expr_[(__i + __n_) & __m] & __m) | (value_type() & ~__m); + } + + _LIBCPP_INLINE_VISIBILITY + size_t size() const {return __size_;} + + template friend class __val_expr; +}; + +template +class __cshift_expr +{ + typedef typename remove_reference<_ValExpr>::type _RmExpr; +public: + typedef typename _RmExpr::value_type value_type; + typedef value_type result_type; + +private: + _ValExpr __expr_; + size_t __size_; + size_t __m_; + size_t __o1_; + size_t __o2_; + + _LIBCPP_INLINE_VISIBILITY + __cshift_expr(int __n, const _RmExpr& __e) + : __expr_(__e), + __size_(__e.size()) + { + __n %= static_cast(__size_); + if (__n >= 0) + { + __m_ = __size_ - __n; + __o1_ = __n; + __o2_ = __n - __size_; + } + else + { + __m_ = -__n; + __o1_ = __n + __size_; + __o2_ = __n; + } + } +public: + + _LIBCPP_INLINE_VISIBILITY + result_type operator[](size_t __i) const + { + if (__i < __m_) + return __expr_[__i + __o1_]; + return __expr_[__i + __o2_]; + } + + _LIBCPP_INLINE_VISIBILITY + size_t size() const {return __size_;} + + template friend class __val_expr; +}; + +template +class __val_expr; + +template +struct __is_val_expr : false_type {}; + +template +struct __is_val_expr<__val_expr<_ValExpr> > : true_type {}; + +template +struct __is_val_expr > : true_type {}; + +template +class _LIBCPP_TEMPLATE_VIS valarray +{ +public: + typedef _Tp value_type; + typedef _Tp result_type; + +private: + value_type* __begin_; + value_type* __end_; + +public: + // construct/destroy: + _LIBCPP_INLINE_VISIBILITY + valarray() : __begin_(0), __end_(0) {} + inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 + explicit valarray(size_t __n); + _LIBCPP_INLINE_VISIBILITY + valarray(const value_type& __x, size_t __n); + valarray(const value_type* __p, size_t __n); + valarray(const valarray& __v); +#ifndef _LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY + valarray(valarray&& __v) _NOEXCEPT; + valarray(initializer_list __il); +#endif // _LIBCPP_CXX03_LANG + valarray(const slice_array& __sa); + valarray(const gslice_array& __ga); + valarray(const mask_array& __ma); + valarray(const indirect_array& __ia); + inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 + ~valarray(); + + // assignment: + valarray& operator=(const valarray& __v); +#ifndef _LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY + valarray& operator=(valarray&& __v) _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY + valarray& operator=(initializer_list); +#endif // _LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY + valarray& operator=(const value_type& __x); + _LIBCPP_INLINE_VISIBILITY + valarray& operator=(const slice_array& __sa); + _LIBCPP_INLINE_VISIBILITY + valarray& operator=(const gslice_array& __ga); + _LIBCPP_INLINE_VISIBILITY + valarray& operator=(const mask_array& __ma); + _LIBCPP_INLINE_VISIBILITY + valarray& operator=(const indirect_array& __ia); + template + _LIBCPP_INLINE_VISIBILITY + valarray& operator=(const __val_expr<_ValExpr>& __v); + + // element access: + _LIBCPP_INLINE_VISIBILITY + const value_type& operator[](size_t __i) const {return __begin_[__i];} + + _LIBCPP_INLINE_VISIBILITY + value_type& operator[](size_t __i) {return __begin_[__i];} + + // subset operations: + _LIBCPP_INLINE_VISIBILITY + __val_expr<__slice_expr > operator[](slice __s) const; + _LIBCPP_INLINE_VISIBILITY + slice_array operator[](slice __s); + _LIBCPP_INLINE_VISIBILITY + __val_expr<__indirect_expr > operator[](const gslice& __gs) const; + _LIBCPP_INLINE_VISIBILITY + gslice_array operator[](const gslice& __gs); +#ifndef _LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY + __val_expr<__indirect_expr > operator[](gslice&& __gs) const; + _LIBCPP_INLINE_VISIBILITY + gslice_array operator[](gslice&& __gs); +#endif // _LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY + __val_expr<__mask_expr > operator[](const valarray& __vb) const; + _LIBCPP_INLINE_VISIBILITY + mask_array operator[](const valarray& __vb); +#ifndef _LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY + __val_expr<__mask_expr > operator[](valarray&& __vb) const; + _LIBCPP_INLINE_VISIBILITY + mask_array operator[](valarray&& __vb); +#endif // _LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY + __val_expr<__indirect_expr > operator[](const valarray& __vs) const; + _LIBCPP_INLINE_VISIBILITY + indirect_array operator[](const valarray& __vs); +#ifndef _LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY + __val_expr<__indirect_expr > operator[](valarray&& __vs) const; + _LIBCPP_INLINE_VISIBILITY + indirect_array operator[](valarray&& __vs); +#endif // _LIBCPP_CXX03_LANG + + // unary operators: + valarray operator+() const; + valarray operator-() const; + valarray operator~() const; + valarray operator!() const; + + // computed assignment: + _LIBCPP_INLINE_VISIBILITY + valarray& operator*= (const value_type& __x); + _LIBCPP_INLINE_VISIBILITY + valarray& operator/= (const value_type& __x); + _LIBCPP_INLINE_VISIBILITY + valarray& operator%= (const value_type& __x); + _LIBCPP_INLINE_VISIBILITY + valarray& operator+= (const value_type& __x); + _LIBCPP_INLINE_VISIBILITY + valarray& operator-= (const value_type& __x); + _LIBCPP_INLINE_VISIBILITY + valarray& operator^= (const value_type& __x); + _LIBCPP_INLINE_VISIBILITY + valarray& operator&= (const value_type& __x); + _LIBCPP_INLINE_VISIBILITY + valarray& operator|= (const value_type& __x); + _LIBCPP_INLINE_VISIBILITY + valarray& operator<<=(const value_type& __x); + _LIBCPP_INLINE_VISIBILITY + valarray& operator>>=(const value_type& __x); + + template + typename enable_if + < + __is_val_expr<_Expr>::value, + valarray& + >::type + _LIBCPP_INLINE_VISIBILITY + operator*= (const _Expr& __v); + + template + typename enable_if + < + __is_val_expr<_Expr>::value, + valarray& + >::type + _LIBCPP_INLINE_VISIBILITY + operator/= (const _Expr& __v); + + template + typename enable_if + < + __is_val_expr<_Expr>::value, + valarray& + >::type + _LIBCPP_INLINE_VISIBILITY + operator%= (const _Expr& __v); + + template + typename enable_if + < + __is_val_expr<_Expr>::value, + valarray& + >::type + _LIBCPP_INLINE_VISIBILITY + operator+= (const _Expr& __v); + + template + typename enable_if + < + __is_val_expr<_Expr>::value, + valarray& + >::type + _LIBCPP_INLINE_VISIBILITY + operator-= (const _Expr& __v); + + template + typename enable_if + < + __is_val_expr<_Expr>::value, + valarray& + >::type + _LIBCPP_INLINE_VISIBILITY + operator^= (const _Expr& __v); + + template + typename enable_if + < + __is_val_expr<_Expr>::value, + valarray& + >::type + _LIBCPP_INLINE_VISIBILITY + operator|= (const _Expr& __v); + + template + typename enable_if + < + __is_val_expr<_Expr>::value, + valarray& + >::type + _LIBCPP_INLINE_VISIBILITY + operator&= (const _Expr& __v); + + template + typename enable_if + < + __is_val_expr<_Expr>::value, + valarray& + >::type + _LIBCPP_INLINE_VISIBILITY + operator<<= (const _Expr& __v); + + template + typename enable_if + < + __is_val_expr<_Expr>::value, + valarray& + >::type + _LIBCPP_INLINE_VISIBILITY + operator>>= (const _Expr& __v); + + // member functions: + _LIBCPP_INLINE_VISIBILITY + void swap(valarray& __v) _NOEXCEPT; + + _LIBCPP_INLINE_VISIBILITY + size_t size() const {return static_cast(__end_ - __begin_);} + + _LIBCPP_INLINE_VISIBILITY + value_type sum() const; + _LIBCPP_INLINE_VISIBILITY + value_type min() const; + _LIBCPP_INLINE_VISIBILITY + value_type max() const; + + valarray shift (int __i) const; + valarray cshift(int __i) const; + valarray apply(value_type __f(value_type)) const; + valarray apply(value_type __f(const value_type&)) const; + void resize(size_t __n, value_type __x = value_type()); + +private: + template friend class _LIBCPP_TEMPLATE_VIS valarray; + template friend class _LIBCPP_TEMPLATE_VIS slice_array; + template friend class _LIBCPP_TEMPLATE_VIS gslice_array; + template friend class _LIBCPP_TEMPLATE_VIS mask_array; + template friend class __mask_expr; + template friend class _LIBCPP_TEMPLATE_VIS indirect_array; + template friend class __indirect_expr; + template friend class __val_expr; + + template + friend + _Up* + begin(valarray<_Up>& __v); + + template + friend + const _Up* + begin(const valarray<_Up>& __v); + + template + friend + _Up* + end(valarray<_Up>& __v); + + template + friend + const _Up* + end(const valarray<_Up>& __v); + + _LIBCPP_INLINE_VISIBILITY + void __clear(size_t __capacity); + valarray& __assign_range(const value_type* __f, const value_type* __l); +}; + +_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void valarray::resize(size_t, size_t)) + +template +struct _UnaryOp<_Op, valarray<_Tp> > +{ + typedef typename _Op::result_type result_type; + typedef _Tp value_type; + + _Op __op_; + const valarray<_Tp>& __a0_; + + _LIBCPP_INLINE_VISIBILITY + _UnaryOp(const _Op& __op, const valarray<_Tp>& __a0) : __op_(__op), __a0_(__a0) {} + + _LIBCPP_INLINE_VISIBILITY + result_type operator[](size_t __i) const {return __op_(__a0_[__i]);} + + _LIBCPP_INLINE_VISIBILITY + size_t size() const {return __a0_.size();} +}; + +template +struct _BinaryOp<_Op, valarray<_Tp>, _A1> +{ + typedef typename _Op::result_type result_type; + typedef _Tp value_type; + + _Op __op_; + const valarray<_Tp>& __a0_; + _A1 __a1_; + + _LIBCPP_INLINE_VISIBILITY + _BinaryOp(const _Op& __op, const valarray<_Tp>& __a0, const _A1& __a1) + : __op_(__op), __a0_(__a0), __a1_(__a1) {} + + _LIBCPP_INLINE_VISIBILITY + value_type operator[](size_t __i) const {return __op_(__a0_[__i], __a1_[__i]);} + + _LIBCPP_INLINE_VISIBILITY + size_t size() const {return __a0_.size();} +}; + +template +struct _BinaryOp<_Op, _A0, valarray<_Tp> > +{ + typedef typename _Op::result_type result_type; + typedef _Tp value_type; + + _Op __op_; + _A0 __a0_; + const valarray<_Tp>& __a1_; + + _LIBCPP_INLINE_VISIBILITY + _BinaryOp(const _Op& __op, const _A0& __a0, const valarray<_Tp>& __a1) + : __op_(__op), __a0_(__a0), __a1_(__a1) {} + + _LIBCPP_INLINE_VISIBILITY + value_type operator[](size_t __i) const {return __op_(__a0_[__i], __a1_[__i]);} + + _LIBCPP_INLINE_VISIBILITY + size_t size() const {return __a0_.size();} +}; + +template +struct _BinaryOp<_Op, valarray<_Tp>, valarray<_Tp> > +{ + typedef typename _Op::result_type result_type; + typedef _Tp value_type; + + _Op __op_; + const valarray<_Tp>& __a0_; + const valarray<_Tp>& __a1_; + + _LIBCPP_INLINE_VISIBILITY + _BinaryOp(const _Op& __op, const valarray<_Tp>& __a0, const valarray<_Tp>& __a1) + : __op_(__op), __a0_(__a0), __a1_(__a1) {} + + _LIBCPP_INLINE_VISIBILITY + value_type operator[](size_t __i) const {return __op_(__a0_[__i], __a1_[__i]);} + + _LIBCPP_INLINE_VISIBILITY + size_t size() const {return __a0_.size();} +}; + +// slice_array + +template +class _LIBCPP_TEMPLATE_VIS slice_array +{ +public: + typedef _Tp value_type; + +private: + value_type* __vp_; + size_t __size_; + size_t __stride_; + +public: + template + typename enable_if + < + __is_val_expr<_Expr>::value, + void + >::type + _LIBCPP_INLINE_VISIBILITY + operator=(const _Expr& __v) const; + + template + typename enable_if + < + __is_val_expr<_Expr>::value, + void + >::type + _LIBCPP_INLINE_VISIBILITY + operator*=(const _Expr& __v) const; + + template + typename enable_if + < + __is_val_expr<_Expr>::value, + void + >::type + _LIBCPP_INLINE_VISIBILITY + operator/=(const _Expr& __v) const; + + template + typename enable_if + < + __is_val_expr<_Expr>::value, + void + >::type + _LIBCPP_INLINE_VISIBILITY + operator%=(const _Expr& __v) const; + + template + typename enable_if + < + __is_val_expr<_Expr>::value, + void + >::type + _LIBCPP_INLINE_VISIBILITY + operator+=(const _Expr& __v) const; + + template + typename enable_if + < + __is_val_expr<_Expr>::value, + void + >::type + _LIBCPP_INLINE_VISIBILITY + operator-=(const _Expr& __v) const; + + template + typename enable_if + < + __is_val_expr<_Expr>::value, + void + >::type + _LIBCPP_INLINE_VISIBILITY + operator^=(const _Expr& __v) const; + + template + typename enable_if + < + __is_val_expr<_Expr>::value, + void + >::type + _LIBCPP_INLINE_VISIBILITY + operator&=(const _Expr& __v) const; + + template + typename enable_if + < + __is_val_expr<_Expr>::value, + void + >::type + _LIBCPP_INLINE_VISIBILITY + operator|=(const _Expr& __v) const; + + template + typename enable_if + < + __is_val_expr<_Expr>::value, + void + >::type + _LIBCPP_INLINE_VISIBILITY + operator<<=(const _Expr& __v) const; + + template + typename enable_if + < + __is_val_expr<_Expr>::value, + void + >::type + _LIBCPP_INLINE_VISIBILITY + operator>>=(const _Expr& __v) const; + + _LIBCPP_INLINE_VISIBILITY + const slice_array& operator=(const slice_array& __sa) const; + + _LIBCPP_INLINE_VISIBILITY + void operator=(const value_type& __x) const; + +private: + _LIBCPP_INLINE_VISIBILITY + slice_array(const slice& __sl, const valarray& __v) + : __vp_(const_cast(__v.__begin_ + __sl.start())), + __size_(__sl.size()), + __stride_(__sl.stride()) + {} + + template friend class valarray; + template friend class sliceExpr; +}; + +template +inline +const slice_array<_Tp>& +slice_array<_Tp>::operator=(const slice_array& __sa) const +{ + value_type* __t = __vp_; + const value_type* __s = __sa.__vp_; + for (size_t __n = __size_; __n; --__n, __t += __stride_, __s += __sa.__stride_) + *__t = *__s; + return *this; +} + +template +template +inline +typename enable_if +< + __is_val_expr<_Expr>::value, + void +>::type +slice_array<_Tp>::operator=(const _Expr& __v) const +{ + value_type* __t = __vp_; + for (size_t __i = 0; __i < __size_; ++__i, __t += __stride_) + *__t = __v[__i]; +} + +template +template +inline +typename enable_if +< + __is_val_expr<_Expr>::value, + void +>::type +slice_array<_Tp>::operator*=(const _Expr& __v) const +{ + value_type* __t = __vp_; + for (size_t __i = 0; __i < __size_; ++__i, __t += __stride_) + *__t *= __v[__i]; +} + +template +template +inline +typename enable_if +< + __is_val_expr<_Expr>::value, + void +>::type +slice_array<_Tp>::operator/=(const _Expr& __v) const +{ + value_type* __t = __vp_; + for (size_t __i = 0; __i < __size_; ++__i, __t += __stride_) + *__t /= __v[__i]; +} + +template +template +inline +typename enable_if +< + __is_val_expr<_Expr>::value, + void +>::type +slice_array<_Tp>::operator%=(const _Expr& __v) const +{ + value_type* __t = __vp_; + for (size_t __i = 0; __i < __size_; ++__i, __t += __stride_) + *__t %= __v[__i]; +} + +template +template +inline +typename enable_if +< + __is_val_expr<_Expr>::value, + void +>::type +slice_array<_Tp>::operator+=(const _Expr& __v) const +{ + value_type* __t = __vp_; + for (size_t __i = 0; __i < __size_; ++__i, __t += __stride_) + *__t += __v[__i]; +} + +template +template +inline +typename enable_if +< + __is_val_expr<_Expr>::value, + void +>::type +slice_array<_Tp>::operator-=(const _Expr& __v) const +{ + value_type* __t = __vp_; + for (size_t __i = 0; __i < __size_; ++__i, __t += __stride_) + *__t -= __v[__i]; +} + +template +template +inline +typename enable_if +< + __is_val_expr<_Expr>::value, + void +>::type +slice_array<_Tp>::operator^=(const _Expr& __v) const +{ + value_type* __t = __vp_; + for (size_t __i = 0; __i < __size_; ++__i, __t += __stride_) + *__t ^= __v[__i]; +} + +template +template +inline +typename enable_if +< + __is_val_expr<_Expr>::value, + void +>::type +slice_array<_Tp>::operator&=(const _Expr& __v) const +{ + value_type* __t = __vp_; + for (size_t __i = 0; __i < __size_; ++__i, __t += __stride_) + *__t &= __v[__i]; +} + +template +template +inline +typename enable_if +< + __is_val_expr<_Expr>::value, + void +>::type +slice_array<_Tp>::operator|=(const _Expr& __v) const +{ + value_type* __t = __vp_; + for (size_t __i = 0; __i < __size_; ++__i, __t += __stride_) + *__t |= __v[__i]; +} + +template +template +inline +typename enable_if +< + __is_val_expr<_Expr>::value, + void +>::type +slice_array<_Tp>::operator<<=(const _Expr& __v) const +{ + value_type* __t = __vp_; + for (size_t __i = 0; __i < __size_; ++__i, __t += __stride_) + *__t <<= __v[__i]; +} + +template +template +inline +typename enable_if +< + __is_val_expr<_Expr>::value, + void +>::type +slice_array<_Tp>::operator>>=(const _Expr& __v) const +{ + value_type* __t = __vp_; + for (size_t __i = 0; __i < __size_; ++__i, __t += __stride_) + *__t >>= __v[__i]; +} + +template +inline +void +slice_array<_Tp>::operator=(const value_type& __x) const +{ + value_type* __t = __vp_; + for (size_t __n = __size_; __n; --__n, __t += __stride_) + *__t = __x; +} + +// gslice + +class _LIBCPP_TYPE_VIS gslice +{ + valarray __size_; + valarray __stride_; + valarray __1d_; + +public: + _LIBCPP_INLINE_VISIBILITY + gslice() {} + + _LIBCPP_INLINE_VISIBILITY + gslice(size_t __start, const valarray& __size, + const valarray& __stride) + : __size_(__size), + __stride_(__stride) + {__init(__start);} + +#ifndef _LIBCPP_CXX03_LANG + + _LIBCPP_INLINE_VISIBILITY + gslice(size_t __start, const valarray& __size, + valarray&& __stride) + : __size_(__size), + __stride_(move(__stride)) + {__init(__start);} + + _LIBCPP_INLINE_VISIBILITY + gslice(size_t __start, valarray&& __size, + const valarray& __stride) + : __size_(move(__size)), + __stride_(__stride) + {__init(__start);} + + _LIBCPP_INLINE_VISIBILITY + gslice(size_t __start, valarray&& __size, + valarray&& __stride) + : __size_(move(__size)), + __stride_(move(__stride)) + {__init(__start);} + +#endif // _LIBCPP_CXX03_LANG + +// gslice(const gslice&) = default; +// gslice(gslice&&) = default; +// gslice& operator=(const gslice&) = default; +// gslice& operator=(gslice&&) = default; + + _LIBCPP_INLINE_VISIBILITY + size_t start() const {return __1d_.size() ? __1d_[0] : 0;} + + _LIBCPP_INLINE_VISIBILITY + valarray size() const {return __size_;} + + _LIBCPP_INLINE_VISIBILITY + valarray stride() const {return __stride_;} + +private: + void __init(size_t __start); + + template friend class gslice_array; + template friend class valarray; + template friend class __val_expr; +}; + +// gslice_array + +template +class _LIBCPP_TEMPLATE_VIS gslice_array +{ +public: + typedef _Tp value_type; + +private: + value_type* __vp_; + valarray __1d_; + +public: + template + typename enable_if + < + __is_val_expr<_Expr>::value, + void + >::type + _LIBCPP_INLINE_VISIBILITY + operator=(const _Expr& __v) const; + + template + typename enable_if + < + __is_val_expr<_Expr>::value, + void + >::type + _LIBCPP_INLINE_VISIBILITY + operator*=(const _Expr& __v) const; + + template + typename enable_if + < + __is_val_expr<_Expr>::value, + void + >::type + _LIBCPP_INLINE_VISIBILITY + operator/=(const _Expr& __v) const; + + template + typename enable_if + < + __is_val_expr<_Expr>::value, + void + >::type + _LIBCPP_INLINE_VISIBILITY + operator%=(const _Expr& __v) const; + + template + typename enable_if + < + __is_val_expr<_Expr>::value, + void + >::type + _LIBCPP_INLINE_VISIBILITY + operator+=(const _Expr& __v) const; + + template + typename enable_if + < + __is_val_expr<_Expr>::value, + void + >::type + _LIBCPP_INLINE_VISIBILITY + operator-=(const _Expr& __v) const; + + template + typename enable_if + < + __is_val_expr<_Expr>::value, + void + >::type + _LIBCPP_INLINE_VISIBILITY + operator^=(const _Expr& __v) const; + + template + typename enable_if + < + __is_val_expr<_Expr>::value, + void + >::type + _LIBCPP_INLINE_VISIBILITY + operator&=(const _Expr& __v) const; + + template + typename enable_if + < + __is_val_expr<_Expr>::value, + void + >::type + _LIBCPP_INLINE_VISIBILITY + operator|=(const _Expr& __v) const; + + template + typename enable_if + < + __is_val_expr<_Expr>::value, + void + >::type + _LIBCPP_INLINE_VISIBILITY + operator<<=(const _Expr& __v) const; + + template + typename enable_if + < + __is_val_expr<_Expr>::value, + void + >::type + _LIBCPP_INLINE_VISIBILITY + operator>>=(const _Expr& __v) const; + + _LIBCPP_INLINE_VISIBILITY + const gslice_array& operator=(const gslice_array& __ga) const; + + _LIBCPP_INLINE_VISIBILITY + void operator=(const value_type& __x) const; + +// gslice_array(const gslice_array&) = default; +// gslice_array(gslice_array&&) = default; +// gslice_array& operator=(const gslice_array&) = default; +// gslice_array& operator=(gslice_array&&) = default; + +private: + gslice_array(const gslice& __gs, const valarray& __v) + : __vp_(const_cast(__v.__begin_)), + __1d_(__gs.__1d_) + {} + +#ifndef _LIBCPP_CXX03_LANG + gslice_array(gslice&& __gs, const valarray& __v) + : __vp_(const_cast(__v.__begin_)), + __1d_(move(__gs.__1d_)) + {} +#endif // _LIBCPP_CXX03_LANG + + template friend class valarray; +}; + +template +template +inline +typename enable_if +< + __is_val_expr<_Expr>::value, + void +>::type +gslice_array<_Tp>::operator=(const _Expr& __v) const +{ + typedef const size_t* _Ip; + size_t __j = 0; + for (_Ip __i = __1d_.__begin_, __e = __1d_.__end_; __i != __e; ++__i, ++__j) + __vp_[*__i] = __v[__j]; +} + +template +template +inline +typename enable_if +< + __is_val_expr<_Expr>::value, + void +>::type +gslice_array<_Tp>::operator*=(const _Expr& __v) const +{ + typedef const size_t* _Ip; + size_t __j = 0; + for (_Ip __i = __1d_.__begin_, __e = __1d_.__end_; __i != __e; ++__i, ++__j) + __vp_[*__i] *= __v[__j]; +} + +template +template +inline +typename enable_if +< + __is_val_expr<_Expr>::value, + void +>::type +gslice_array<_Tp>::operator/=(const _Expr& __v) const +{ + typedef const size_t* _Ip; + size_t __j = 0; + for (_Ip __i = __1d_.__begin_, __e = __1d_.__end_; __i != __e; ++__i, ++__j) + __vp_[*__i] /= __v[__j]; +} + +template +template +inline +typename enable_if +< + __is_val_expr<_Expr>::value, + void +>::type +gslice_array<_Tp>::operator%=(const _Expr& __v) const +{ + typedef const size_t* _Ip; + size_t __j = 0; + for (_Ip __i = __1d_.__begin_, __e = __1d_.__end_; __i != __e; ++__i, ++__j) + __vp_[*__i] %= __v[__j]; +} + +template +template +inline +typename enable_if +< + __is_val_expr<_Expr>::value, + void +>::type +gslice_array<_Tp>::operator+=(const _Expr& __v) const +{ + typedef const size_t* _Ip; + size_t __j = 0; + for (_Ip __i = __1d_.__begin_, __e = __1d_.__end_; __i != __e; ++__i, ++__j) + __vp_[*__i] += __v[__j]; +} + +template +template +inline +typename enable_if +< + __is_val_expr<_Expr>::value, + void +>::type +gslice_array<_Tp>::operator-=(const _Expr& __v) const +{ + typedef const size_t* _Ip; + size_t __j = 0; + for (_Ip __i = __1d_.__begin_, __e = __1d_.__end_; __i != __e; ++__i, ++__j) + __vp_[*__i] -= __v[__j]; +} + +template +template +inline +typename enable_if +< + __is_val_expr<_Expr>::value, + void +>::type +gslice_array<_Tp>::operator^=(const _Expr& __v) const +{ + typedef const size_t* _Ip; + size_t __j = 0; + for (_Ip __i = __1d_.__begin_, __e = __1d_.__end_; __i != __e; ++__i, ++__j) + __vp_[*__i] ^= __v[__j]; +} + +template +template +inline +typename enable_if +< + __is_val_expr<_Expr>::value, + void +>::type +gslice_array<_Tp>::operator&=(const _Expr& __v) const +{ + typedef const size_t* _Ip; + size_t __j = 0; + for (_Ip __i = __1d_.__begin_, __e = __1d_.__end_; __i != __e; ++__i, ++__j) + __vp_[*__i] &= __v[__j]; +} + +template +template +inline +typename enable_if +< + __is_val_expr<_Expr>::value, + void +>::type +gslice_array<_Tp>::operator|=(const _Expr& __v) const +{ + typedef const size_t* _Ip; + size_t __j = 0; + for (_Ip __i = __1d_.__begin_, __e = __1d_.__end_; __i != __e; ++__i, ++__j) + __vp_[*__i] |= __v[__j]; +} + +template +template +inline +typename enable_if +< + __is_val_expr<_Expr>::value, + void +>::type +gslice_array<_Tp>::operator<<=(const _Expr& __v) const +{ + typedef const size_t* _Ip; + size_t __j = 0; + for (_Ip __i = __1d_.__begin_, __e = __1d_.__end_; __i != __e; ++__i, ++__j) + __vp_[*__i] <<= __v[__j]; +} + +template +template +inline +typename enable_if +< + __is_val_expr<_Expr>::value, + void +>::type +gslice_array<_Tp>::operator>>=(const _Expr& __v) const +{ + typedef const size_t* _Ip; + size_t __j = 0; + for (_Ip __i = __1d_.__begin_, __e = __1d_.__end_; __i != __e; ++__i, ++__j) + __vp_[*__i] >>= __v[__j]; +} + +template +inline +const gslice_array<_Tp>& +gslice_array<_Tp>::operator=(const gslice_array& __ga) const +{ + typedef const size_t* _Ip; + const value_type* __s = __ga.__vp_; + for (_Ip __i = __1d_.__begin_, __e = __1d_.__end_, __j = __ga.__1d_.__begin_; + __i != __e; ++__i, ++__j) + __vp_[*__i] = __s[*__j]; + return *this; +} + +template +inline +void +gslice_array<_Tp>::operator=(const value_type& __x) const +{ + typedef const size_t* _Ip; + for (_Ip __i = __1d_.__begin_, __e = __1d_.__end_; __i != __e; ++__i) + __vp_[*__i] = __x; +} + +// mask_array + +template +class _LIBCPP_TEMPLATE_VIS mask_array +{ +public: + typedef _Tp value_type; + +private: + value_type* __vp_; + valarray __1d_; + +public: + template + typename enable_if + < + __is_val_expr<_Expr>::value, + void + >::type + _LIBCPP_INLINE_VISIBILITY + operator=(const _Expr& __v) const; + + template + typename enable_if + < + __is_val_expr<_Expr>::value, + void + >::type + _LIBCPP_INLINE_VISIBILITY + operator*=(const _Expr& __v) const; + + template + typename enable_if + < + __is_val_expr<_Expr>::value, + void + >::type + _LIBCPP_INLINE_VISIBILITY + operator/=(const _Expr& __v) const; + + template + typename enable_if + < + __is_val_expr<_Expr>::value, + void + >::type + _LIBCPP_INLINE_VISIBILITY + operator%=(const _Expr& __v) const; + + template + typename enable_if + < + __is_val_expr<_Expr>::value, + void + >::type + _LIBCPP_INLINE_VISIBILITY + operator+=(const _Expr& __v) const; + + template + typename enable_if + < + __is_val_expr<_Expr>::value, + void + >::type + _LIBCPP_INLINE_VISIBILITY + operator-=(const _Expr& __v) const; + + template + typename enable_if + < + __is_val_expr<_Expr>::value, + void + >::type + _LIBCPP_INLINE_VISIBILITY + operator^=(const _Expr& __v) const; + + template + typename enable_if + < + __is_val_expr<_Expr>::value, + void + >::type + _LIBCPP_INLINE_VISIBILITY + operator&=(const _Expr& __v) const; + + template + typename enable_if + < + __is_val_expr<_Expr>::value, + void + >::type + _LIBCPP_INLINE_VISIBILITY + operator|=(const _Expr& __v) const; + + template + typename enable_if + < + __is_val_expr<_Expr>::value, + void + >::type + _LIBCPP_INLINE_VISIBILITY + operator<<=(const _Expr& __v) const; + + template + typename enable_if + < + __is_val_expr<_Expr>::value, + void + >::type + _LIBCPP_INLINE_VISIBILITY + operator>>=(const _Expr& __v) const; + + _LIBCPP_INLINE_VISIBILITY + const mask_array& operator=(const mask_array& __ma) const; + + _LIBCPP_INLINE_VISIBILITY + void operator=(const value_type& __x) const; + +// mask_array(const mask_array&) = default; +// mask_array(mask_array&&) = default; +// mask_array& operator=(const mask_array&) = default; +// mask_array& operator=(mask_array&&) = default; + +private: + _LIBCPP_INLINE_VISIBILITY + mask_array(const valarray& __vb, const valarray& __v) + : __vp_(const_cast(__v.__begin_)), + __1d_(static_cast(count(__vb.__begin_, __vb.__end_, true))) + { + size_t __j = 0; + for (size_t __i = 0; __i < __vb.size(); ++__i) + if (__vb[__i]) + __1d_[__j++] = __i; + } + + template friend class valarray; +}; + +template +template +inline +typename enable_if +< + __is_val_expr<_Expr>::value, + void +>::type +mask_array<_Tp>::operator=(const _Expr& __v) const +{ + size_t __n = __1d_.size(); + for (size_t __i = 0; __i < __n; ++__i) + __vp_[__1d_[__i]] = __v[__i]; +} + +template +template +inline +typename enable_if +< + __is_val_expr<_Expr>::value, + void +>::type +mask_array<_Tp>::operator*=(const _Expr& __v) const +{ + size_t __n = __1d_.size(); + for (size_t __i = 0; __i < __n; ++__i) + __vp_[__1d_[__i]] *= __v[__i]; +} + +template +template +inline +typename enable_if +< + __is_val_expr<_Expr>::value, + void +>::type +mask_array<_Tp>::operator/=(const _Expr& __v) const +{ + size_t __n = __1d_.size(); + for (size_t __i = 0; __i < __n; ++__i) + __vp_[__1d_[__i]] /= __v[__i]; +} + +template +template +inline +typename enable_if +< + __is_val_expr<_Expr>::value, + void +>::type +mask_array<_Tp>::operator%=(const _Expr& __v) const +{ + size_t __n = __1d_.size(); + for (size_t __i = 0; __i < __n; ++__i) + __vp_[__1d_[__i]] %= __v[__i]; +} + +template +template +inline +typename enable_if +< + __is_val_expr<_Expr>::value, + void +>::type +mask_array<_Tp>::operator+=(const _Expr& __v) const +{ + size_t __n = __1d_.size(); + for (size_t __i = 0; __i < __n; ++__i) + __vp_[__1d_[__i]] += __v[__i]; +} + +template +template +inline +typename enable_if +< + __is_val_expr<_Expr>::value, + void +>::type +mask_array<_Tp>::operator-=(const _Expr& __v) const +{ + size_t __n = __1d_.size(); + for (size_t __i = 0; __i < __n; ++__i) + __vp_[__1d_[__i]] -= __v[__i]; +} + +template +template +inline +typename enable_if +< + __is_val_expr<_Expr>::value, + void +>::type +mask_array<_Tp>::operator^=(const _Expr& __v) const +{ + size_t __n = __1d_.size(); + for (size_t __i = 0; __i < __n; ++__i) + __vp_[__1d_[__i]] ^= __v[__i]; +} + +template +template +inline +typename enable_if +< + __is_val_expr<_Expr>::value, + void +>::type +mask_array<_Tp>::operator&=(const _Expr& __v) const +{ + size_t __n = __1d_.size(); + for (size_t __i = 0; __i < __n; ++__i) + __vp_[__1d_[__i]] &= __v[__i]; +} + +template +template +inline +typename enable_if +< + __is_val_expr<_Expr>::value, + void +>::type +mask_array<_Tp>::operator|=(const _Expr& __v) const +{ + size_t __n = __1d_.size(); + for (size_t __i = 0; __i < __n; ++__i) + __vp_[__1d_[__i]] |= __v[__i]; +} + +template +template +inline +typename enable_if +< + __is_val_expr<_Expr>::value, + void +>::type +mask_array<_Tp>::operator<<=(const _Expr& __v) const +{ + size_t __n = __1d_.size(); + for (size_t __i = 0; __i < __n; ++__i) + __vp_[__1d_[__i]] <<= __v[__i]; +} + +template +template +inline +typename enable_if +< + __is_val_expr<_Expr>::value, + void +>::type +mask_array<_Tp>::operator>>=(const _Expr& __v) const +{ + size_t __n = __1d_.size(); + for (size_t __i = 0; __i < __n; ++__i) + __vp_[__1d_[__i]] >>= __v[__i]; +} + +template +inline +const mask_array<_Tp>& +mask_array<_Tp>::operator=(const mask_array& __ma) const +{ + size_t __n = __1d_.size(); + for (size_t __i = 0; __i < __n; ++__i) + __vp_[__1d_[__i]] = __ma.__vp_[__1d_[__i]]; + return *this; +} + +template +inline +void +mask_array<_Tp>::operator=(const value_type& __x) const +{ + size_t __n = __1d_.size(); + for (size_t __i = 0; __i < __n; ++__i) + __vp_[__1d_[__i]] = __x; +} + +template +class __mask_expr +{ + typedef typename remove_reference<_ValExpr>::type _RmExpr; +public: + typedef typename _RmExpr::value_type value_type; + typedef value_type result_type; + +private: + _ValExpr __expr_; + valarray __1d_; + + _LIBCPP_INLINE_VISIBILITY + __mask_expr(const valarray& __vb, const _RmExpr& __e) + : __expr_(__e), + __1d_(static_cast(count(__vb.__begin_, __vb.__end_, true))) + { + size_t __j = 0; + for (size_t __i = 0; __i < __vb.size(); ++__i) + if (__vb[__i]) + __1d_[__j++] = __i; + } + +public: + _LIBCPP_INLINE_VISIBILITY + result_type operator[](size_t __i) const + {return __expr_[__1d_[__i]];} + + _LIBCPP_INLINE_VISIBILITY + size_t size() const {return __1d_.size();} + + template friend class __val_expr; + template friend class valarray; +}; + +// indirect_array + +template +class _LIBCPP_TEMPLATE_VIS indirect_array +{ +public: + typedef _Tp value_type; + +private: + value_type* __vp_; + valarray __1d_; + +public: + template + typename enable_if + < + __is_val_expr<_Expr>::value, + void + >::type + _LIBCPP_INLINE_VISIBILITY + operator=(const _Expr& __v) const; + + template + typename enable_if + < + __is_val_expr<_Expr>::value, + void + >::type + _LIBCPP_INLINE_VISIBILITY + operator*=(const _Expr& __v) const; + + template + typename enable_if + < + __is_val_expr<_Expr>::value, + void + >::type + _LIBCPP_INLINE_VISIBILITY + operator/=(const _Expr& __v) const; + + template + typename enable_if + < + __is_val_expr<_Expr>::value, + void + >::type + _LIBCPP_INLINE_VISIBILITY + operator%=(const _Expr& __v) const; + + template + typename enable_if + < + __is_val_expr<_Expr>::value, + void + >::type + _LIBCPP_INLINE_VISIBILITY + operator+=(const _Expr& __v) const; + + template + typename enable_if + < + __is_val_expr<_Expr>::value, + void + >::type + _LIBCPP_INLINE_VISIBILITY + operator-=(const _Expr& __v) const; + + template + typename enable_if + < + __is_val_expr<_Expr>::value, + void + >::type + _LIBCPP_INLINE_VISIBILITY + operator^=(const _Expr& __v) const; + + template + typename enable_if + < + __is_val_expr<_Expr>::value, + void + >::type + _LIBCPP_INLINE_VISIBILITY + operator&=(const _Expr& __v) const; + + template + typename enable_if + < + __is_val_expr<_Expr>::value, + void + >::type + _LIBCPP_INLINE_VISIBILITY + operator|=(const _Expr& __v) const; + + template + typename enable_if + < + __is_val_expr<_Expr>::value, + void + >::type + _LIBCPP_INLINE_VISIBILITY + operator<<=(const _Expr& __v) const; + + template + typename enable_if + < + __is_val_expr<_Expr>::value, + void + >::type + _LIBCPP_INLINE_VISIBILITY + operator>>=(const _Expr& __v) const; + + _LIBCPP_INLINE_VISIBILITY + const indirect_array& operator=(const indirect_array& __ia) const; + + _LIBCPP_INLINE_VISIBILITY + void operator=(const value_type& __x) const; + +// indirect_array(const indirect_array&) = default; +// indirect_array(indirect_array&&) = default; +// indirect_array& operator=(const indirect_array&) = default; +// indirect_array& operator=(indirect_array&&) = default; + +private: + _LIBCPP_INLINE_VISIBILITY + indirect_array(const valarray& __ia, const valarray& __v) + : __vp_(const_cast(__v.__begin_)), + __1d_(__ia) + {} + +#ifndef _LIBCPP_CXX03_LANG + + _LIBCPP_INLINE_VISIBILITY + indirect_array(valarray&& __ia, const valarray& __v) + : __vp_(const_cast(__v.__begin_)), + __1d_(move(__ia)) + {} + +#endif // _LIBCPP_CXX03_LANG + + template friend class valarray; +}; + +template +template +inline +typename enable_if +< + __is_val_expr<_Expr>::value, + void +>::type +indirect_array<_Tp>::operator=(const _Expr& __v) const +{ + size_t __n = __1d_.size(); + for (size_t __i = 0; __i < __n; ++__i) + __vp_[__1d_[__i]] = __v[__i]; +} + +template +template +inline +typename enable_if +< + __is_val_expr<_Expr>::value, + void +>::type +indirect_array<_Tp>::operator*=(const _Expr& __v) const +{ + size_t __n = __1d_.size(); + for (size_t __i = 0; __i < __n; ++__i) + __vp_[__1d_[__i]] *= __v[__i]; +} + +template +template +inline +typename enable_if +< + __is_val_expr<_Expr>::value, + void +>::type +indirect_array<_Tp>::operator/=(const _Expr& __v) const +{ + size_t __n = __1d_.size(); + for (size_t __i = 0; __i < __n; ++__i) + __vp_[__1d_[__i]] /= __v[__i]; +} + +template +template +inline +typename enable_if +< + __is_val_expr<_Expr>::value, + void +>::type +indirect_array<_Tp>::operator%=(const _Expr& __v) const +{ + size_t __n = __1d_.size(); + for (size_t __i = 0; __i < __n; ++__i) + __vp_[__1d_[__i]] %= __v[__i]; +} + +template +template +inline +typename enable_if +< + __is_val_expr<_Expr>::value, + void +>::type +indirect_array<_Tp>::operator+=(const _Expr& __v) const +{ + size_t __n = __1d_.size(); + for (size_t __i = 0; __i < __n; ++__i) + __vp_[__1d_[__i]] += __v[__i]; +} + +template +template +inline +typename enable_if +< + __is_val_expr<_Expr>::value, + void +>::type +indirect_array<_Tp>::operator-=(const _Expr& __v) const +{ + size_t __n = __1d_.size(); + for (size_t __i = 0; __i < __n; ++__i) + __vp_[__1d_[__i]] -= __v[__i]; +} + +template +template +inline +typename enable_if +< + __is_val_expr<_Expr>::value, + void +>::type +indirect_array<_Tp>::operator^=(const _Expr& __v) const +{ + size_t __n = __1d_.size(); + for (size_t __i = 0; __i < __n; ++__i) + __vp_[__1d_[__i]] ^= __v[__i]; +} + +template +template +inline +typename enable_if +< + __is_val_expr<_Expr>::value, + void +>::type +indirect_array<_Tp>::operator&=(const _Expr& __v) const +{ + size_t __n = __1d_.size(); + for (size_t __i = 0; __i < __n; ++__i) + __vp_[__1d_[__i]] &= __v[__i]; +} + +template +template +inline +typename enable_if +< + __is_val_expr<_Expr>::value, + void +>::type +indirect_array<_Tp>::operator|=(const _Expr& __v) const +{ + size_t __n = __1d_.size(); + for (size_t __i = 0; __i < __n; ++__i) + __vp_[__1d_[__i]] |= __v[__i]; +} + +template +template +inline +typename enable_if +< + __is_val_expr<_Expr>::value, + void +>::type +indirect_array<_Tp>::operator<<=(const _Expr& __v) const +{ + size_t __n = __1d_.size(); + for (size_t __i = 0; __i < __n; ++__i) + __vp_[__1d_[__i]] <<= __v[__i]; +} + +template +template +inline +typename enable_if +< + __is_val_expr<_Expr>::value, + void +>::type +indirect_array<_Tp>::operator>>=(const _Expr& __v) const +{ + size_t __n = __1d_.size(); + for (size_t __i = 0; __i < __n; ++__i) + __vp_[__1d_[__i]] >>= __v[__i]; +} + +template +inline +const indirect_array<_Tp>& +indirect_array<_Tp>::operator=(const indirect_array& __ia) const +{ + typedef const size_t* _Ip; + const value_type* __s = __ia.__vp_; + for (_Ip __i = __1d_.__begin_, __e = __1d_.__end_, __j = __ia.__1d_.__begin_; + __i != __e; ++__i, ++__j) + __vp_[*__i] = __s[*__j]; + return *this; +} + +template +inline +void +indirect_array<_Tp>::operator=(const value_type& __x) const +{ + typedef const size_t* _Ip; + for (_Ip __i = __1d_.__begin_, __e = __1d_.__end_; __i != __e; ++__i) + __vp_[*__i] = __x; +} + +template +class __indirect_expr +{ + typedef typename remove_reference<_ValExpr>::type _RmExpr; +public: + typedef typename _RmExpr::value_type value_type; + typedef value_type result_type; + +private: + _ValExpr __expr_; + valarray __1d_; + + _LIBCPP_INLINE_VISIBILITY + __indirect_expr(const valarray& __ia, const _RmExpr& __e) + : __expr_(__e), + __1d_(__ia) + {} + +#ifndef _LIBCPP_CXX03_LANG + + _LIBCPP_INLINE_VISIBILITY + __indirect_expr(valarray&& __ia, const _RmExpr& __e) + : __expr_(__e), + __1d_(move(__ia)) + {} + +#endif // _LIBCPP_CXX03_LANG + +public: + _LIBCPP_INLINE_VISIBILITY + result_type operator[](size_t __i) const + {return __expr_[__1d_[__i]];} + + _LIBCPP_INLINE_VISIBILITY + size_t size() const {return __1d_.size();} + + template friend class __val_expr; + template friend class _LIBCPP_TEMPLATE_VIS valarray; +}; + +template +class __val_expr +{ + typedef typename remove_reference<_ValExpr>::type _RmExpr; + + _ValExpr __expr_; +public: + typedef typename _RmExpr::value_type value_type; + typedef typename _RmExpr::result_type result_type; + + _LIBCPP_INLINE_VISIBILITY + explicit __val_expr(const _RmExpr& __e) : __expr_(__e) {} + + _LIBCPP_INLINE_VISIBILITY + result_type operator[](size_t __i) const + {return __expr_[__i];} + + _LIBCPP_INLINE_VISIBILITY + __val_expr<__slice_expr<_ValExpr> > operator[](slice __s) const + { + typedef __slice_expr<_ValExpr> _NewExpr; + return __val_expr< _NewExpr >(_NewExpr(__s, __expr_)); + } + + _LIBCPP_INLINE_VISIBILITY + __val_expr<__indirect_expr<_ValExpr> > operator[](const gslice& __gs) const + { + typedef __indirect_expr<_ValExpr> _NewExpr; + return __val_expr<_NewExpr >(_NewExpr(__gs.__1d_, __expr_)); + } + + _LIBCPP_INLINE_VISIBILITY + __val_expr<__mask_expr<_ValExpr> > operator[](const valarray& __vb) const + { + typedef __mask_expr<_ValExpr> _NewExpr; + return __val_expr< _NewExpr >( _NewExpr(__vb, __expr_)); + } + + _LIBCPP_INLINE_VISIBILITY + __val_expr<__indirect_expr<_ValExpr> > operator[](const valarray& __vs) const + { + typedef __indirect_expr<_ValExpr> _NewExpr; + return __val_expr< _NewExpr >(_NewExpr(__vs, __expr_)); + } + + _LIBCPP_INLINE_VISIBILITY + __val_expr<_UnaryOp<__unary_plus, _ValExpr> > + operator+() const + { + typedef _UnaryOp<__unary_plus, _ValExpr> _NewExpr; + return __val_expr<_NewExpr>(_NewExpr(__unary_plus(), __expr_)); + } + + _LIBCPP_INLINE_VISIBILITY + __val_expr<_UnaryOp, _ValExpr> > + operator-() const + { + typedef _UnaryOp, _ValExpr> _NewExpr; + return __val_expr<_NewExpr>(_NewExpr(negate(), __expr_)); + } + + _LIBCPP_INLINE_VISIBILITY + __val_expr<_UnaryOp<__bit_not, _ValExpr> > + operator~() const + { + typedef _UnaryOp<__bit_not, _ValExpr> _NewExpr; + return __val_expr<_NewExpr>(_NewExpr(__bit_not(), __expr_)); + } + + _LIBCPP_INLINE_VISIBILITY + __val_expr<_UnaryOp, _ValExpr> > + operator!() const + { + typedef _UnaryOp, _ValExpr> _NewExpr; + return __val_expr<_NewExpr>(_NewExpr(logical_not(), __expr_)); + } + + operator valarray() const; + + _LIBCPP_INLINE_VISIBILITY + size_t size() const {return __expr_.size();} + + _LIBCPP_INLINE_VISIBILITY + result_type sum() const + { + size_t __n = __expr_.size(); + result_type __r = __n ? __expr_[0] : result_type(); + for (size_t __i = 1; __i < __n; ++__i) + __r += __expr_[__i]; + return __r; + } + + _LIBCPP_INLINE_VISIBILITY + result_type min() const + { + size_t __n = size(); + result_type __r = __n ? (*this)[0] : result_type(); + for (size_t __i = 1; __i < __n; ++__i) + { + result_type __x = __expr_[__i]; + if (__x < __r) + __r = __x; + } + return __r; + } + + _LIBCPP_INLINE_VISIBILITY + result_type max() const + { + size_t __n = size(); + result_type __r = __n ? (*this)[0] : result_type(); + for (size_t __i = 1; __i < __n; ++__i) + { + result_type __x = __expr_[__i]; + if (__r < __x) + __r = __x; + } + return __r; + } + + _LIBCPP_INLINE_VISIBILITY + __val_expr<__shift_expr<_ValExpr> > shift (int __i) const + {return __val_expr<__shift_expr<_ValExpr> >(__shift_expr<_ValExpr>(__i, __expr_));} + + _LIBCPP_INLINE_VISIBILITY + __val_expr<__cshift_expr<_ValExpr> > cshift(int __i) const + {return __val_expr<__cshift_expr<_ValExpr> >(__cshift_expr<_ValExpr>(__i, __expr_));} + + _LIBCPP_INLINE_VISIBILITY + __val_expr<_UnaryOp<__apply_expr, _ValExpr> > + apply(value_type __f(value_type)) const + { + typedef __apply_expr _Op; + typedef _UnaryOp<_Op, _ValExpr> _NewExpr; + return __val_expr<_NewExpr>(_NewExpr(_Op(__f), __expr_)); + } + + _LIBCPP_INLINE_VISIBILITY + __val_expr<_UnaryOp<__apply_expr, _ValExpr> > + apply(value_type __f(const value_type&)) const + { + typedef __apply_expr _Op; + typedef _UnaryOp<_Op, _ValExpr> _NewExpr; + return __val_expr<_NewExpr>(_NewExpr(_Op(__f), __expr_)); + } +}; + +template +__val_expr<_ValExpr>::operator valarray<__val_expr::result_type>() const +{ + valarray __r; + size_t __n = __expr_.size(); + if (__n) + { + __r.__begin_ = + __r.__end_ = + static_cast( + _VSTD::__libcpp_allocate(__n * sizeof(result_type), _LIBCPP_ALIGNOF(result_type))); + for (size_t __i = 0; __i != __n; ++__r.__end_, ++__i) + ::new (__r.__end_) result_type(__expr_[__i]); + } + return __r; +} + +// valarray + +template +inline +valarray<_Tp>::valarray(size_t __n) + : __begin_(0), + __end_(0) +{ + if (__n) + { + __begin_ = __end_ = static_cast( + _VSTD::__libcpp_allocate(__n * sizeof(value_type), _LIBCPP_ALIGNOF(value_type))); +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + for (size_t __n_left = __n; __n_left; --__n_left, ++__end_) + ::new (__end_) value_type(); +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + __clear(__n); + throw; + } +#endif // _LIBCPP_NO_EXCEPTIONS + } +} + +template +inline +valarray<_Tp>::valarray(const value_type& __x, size_t __n) + : __begin_(0), + __end_(0) +{ + resize(__n, __x); +} + +template +valarray<_Tp>::valarray(const value_type* __p, size_t __n) + : __begin_(0), + __end_(0) +{ + if (__n) + { + __begin_ = __end_ = static_cast( + _VSTD::__libcpp_allocate(__n * sizeof(value_type), _LIBCPP_ALIGNOF(value_type))); +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + for (size_t __n_left = __n; __n_left; ++__end_, ++__p, --__n_left) + ::new (__end_) value_type(*__p); +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + __clear(__n); + throw; + } +#endif // _LIBCPP_NO_EXCEPTIONS + } +} + +template +valarray<_Tp>::valarray(const valarray& __v) + : __begin_(0), + __end_(0) +{ + if (__v.size()) + { + __begin_ = __end_ = static_cast( + _VSTD::__libcpp_allocate(__v.size() * sizeof(value_type), _LIBCPP_ALIGNOF(value_type))); +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + for (value_type* __p = __v.__begin_; __p != __v.__end_; ++__end_, ++__p) + ::new (__end_) value_type(*__p); +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + __clear(__v.size()); + throw; + } +#endif // _LIBCPP_NO_EXCEPTIONS + } +} + +#ifndef _LIBCPP_CXX03_LANG + +template +inline +valarray<_Tp>::valarray(valarray&& __v) _NOEXCEPT + : __begin_(__v.__begin_), + __end_(__v.__end_) +{ + __v.__begin_ = __v.__end_ = nullptr; +} + +template +valarray<_Tp>::valarray(initializer_list __il) + : __begin_(0), + __end_(0) +{ + const size_t __n = __il.size(); + if (__n) + { + __begin_ = __end_ = static_cast( +_VSTD::__libcpp_allocate(__n * sizeof(value_type), _LIBCPP_ALIGNOF(value_type))); +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + size_t __n_left = __n; + for (const value_type* __p = __il.begin(); __n_left; ++__end_, ++__p, --__n_left) + ::new (__end_) value_type(*__p); +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + __clear(__n); + throw; + } +#endif // _LIBCPP_NO_EXCEPTIONS + } +} + +#endif // _LIBCPP_CXX03_LANG + +template +valarray<_Tp>::valarray(const slice_array& __sa) + : __begin_(0), + __end_(0) +{ + const size_t __n = __sa.__size_; + if (__n) + { + __begin_ = __end_ = static_cast( + _VSTD::__libcpp_allocate(__n * sizeof(value_type), _LIBCPP_ALIGNOF(value_type))); +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + size_t __n_left = __n; + for (const value_type* __p = __sa.__vp_; __n_left; ++__end_, __p += __sa.__stride_, --__n_left) + ::new (__end_) value_type(*__p); +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + __clear(__n); + throw; + } +#endif // _LIBCPP_NO_EXCEPTIONS + } +} + +template +valarray<_Tp>::valarray(const gslice_array& __ga) + : __begin_(0), + __end_(0) +{ + const size_t __n = __ga.__1d_.size(); + if (__n) + { + __begin_ = __end_ = static_cast( + _VSTD::__libcpp_allocate(__n * sizeof(value_type), _LIBCPP_ALIGNOF(value_type))); +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + typedef const size_t* _Ip; + const value_type* __s = __ga.__vp_; + for (_Ip __i = __ga.__1d_.__begin_, __e = __ga.__1d_.__end_; + __i != __e; ++__i, ++__end_) + ::new (__end_) value_type(__s[*__i]); +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + __clear(__n); + throw; + } +#endif // _LIBCPP_NO_EXCEPTIONS + } +} + +template +valarray<_Tp>::valarray(const mask_array& __ma) + : __begin_(0), + __end_(0) +{ + const size_t __n = __ma.__1d_.size(); + if (__n) + { + __begin_ = __end_ = static_cast( + _VSTD::__libcpp_allocate(__n * sizeof(value_type), _LIBCPP_ALIGNOF(value_type))); +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + typedef const size_t* _Ip; + const value_type* __s = __ma.__vp_; + for (_Ip __i = __ma.__1d_.__begin_, __e = __ma.__1d_.__end_; + __i != __e; ++__i, ++__end_) + ::new (__end_) value_type(__s[*__i]); +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + __clear(__n); + throw; + } +#endif // _LIBCPP_NO_EXCEPTIONS + } +} + +template +valarray<_Tp>::valarray(const indirect_array& __ia) + : __begin_(0), + __end_(0) +{ + const size_t __n = __ia.__1d_.size(); + if (__n) + { + __begin_ = __end_ = static_cast( + _VSTD::__libcpp_allocate(__n * sizeof(value_type), _LIBCPP_ALIGNOF(value_type))); +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + typedef const size_t* _Ip; + const value_type* __s = __ia.__vp_; + for (_Ip __i = __ia.__1d_.__begin_, __e = __ia.__1d_.__end_; + __i != __e; ++__i, ++__end_) + ::new (__end_) value_type(__s[*__i]); +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + __clear(__n); + throw; + } +#endif // _LIBCPP_NO_EXCEPTIONS + } +} + +template +inline +valarray<_Tp>::~valarray() +{ + __clear(size()); +} + +template +valarray<_Tp>& +valarray<_Tp>::__assign_range(const value_type* __f, const value_type* __l) +{ + size_t __n = __l - __f; + if (size() != __n) + { + __clear(size()); + __begin_ = static_cast( + _VSTD::__libcpp_allocate(__n * sizeof(value_type), _LIBCPP_ALIGNOF(value_type))); + __end_ = __begin_ + __n; + _VSTD::uninitialized_copy(__f, __l, __begin_); + } else { + _VSTD::copy(__f, __l, __begin_); + } + return *this; +} + +template +valarray<_Tp>& +valarray<_Tp>::operator=(const valarray& __v) +{ + if (this != &__v) + return __assign_range(__v.__begin_, __v.__end_); + return *this; +} + +#ifndef _LIBCPP_CXX03_LANG + +template +inline +valarray<_Tp>& +valarray<_Tp>::operator=(valarray&& __v) _NOEXCEPT +{ + __clear(size()); + __begin_ = __v.__begin_; + __end_ = __v.__end_; + __v.__begin_ = nullptr; + __v.__end_ = nullptr; + return *this; +} + +template +inline +valarray<_Tp>& +valarray<_Tp>::operator=(initializer_list __il) +{ + return __assign_range(__il.begin(), __il.end()); +} + +#endif // _LIBCPP_CXX03_LANG + +template +inline +valarray<_Tp>& +valarray<_Tp>::operator=(const value_type& __x) +{ + _VSTD::fill(__begin_, __end_, __x); + return *this; +} + +template +inline +valarray<_Tp>& +valarray<_Tp>::operator=(const slice_array& __sa) +{ + value_type* __t = __begin_; + const value_type* __s = __sa.__vp_; + for (size_t __n = __sa.__size_; __n; --__n, __s += __sa.__stride_, ++__t) + *__t = *__s; + return *this; +} + +template +inline +valarray<_Tp>& +valarray<_Tp>::operator=(const gslice_array& __ga) +{ + typedef const size_t* _Ip; + value_type* __t = __begin_; + const value_type* __s = __ga.__vp_; + for (_Ip __i = __ga.__1d_.__begin_, __e = __ga.__1d_.__end_; + __i != __e; ++__i, ++__t) + *__t = __s[*__i]; + return *this; +} + +template +inline +valarray<_Tp>& +valarray<_Tp>::operator=(const mask_array& __ma) +{ + typedef const size_t* _Ip; + value_type* __t = __begin_; + const value_type* __s = __ma.__vp_; + for (_Ip __i = __ma.__1d_.__begin_, __e = __ma.__1d_.__end_; + __i != __e; ++__i, ++__t) + *__t = __s[*__i]; + return *this; +} + +template +inline +valarray<_Tp>& +valarray<_Tp>::operator=(const indirect_array& __ia) +{ + typedef const size_t* _Ip; + value_type* __t = __begin_; + const value_type* __s = __ia.__vp_; + for (_Ip __i = __ia.__1d_.__begin_, __e = __ia.__1d_.__end_; + __i != __e; ++__i, ++__t) + *__t = __s[*__i]; + return *this; +} + +template +template +inline +valarray<_Tp>& +valarray<_Tp>::operator=(const __val_expr<_ValExpr>& __v) +{ + size_t __n = __v.size(); + if (size() != __n) + resize(__n); + value_type* __t = __begin_; + for (size_t __i = 0; __i != __n; ++__t, ++__i) + *__t = result_type(__v[__i]); + return *this; +} + +template +inline +__val_expr<__slice_expr&> > +valarray<_Tp>::operator[](slice __s) const +{ + return __val_expr<__slice_expr >(__slice_expr(__s, *this)); +} + +template +inline +slice_array<_Tp> +valarray<_Tp>::operator[](slice __s) +{ + return slice_array(__s, *this); +} + +template +inline +__val_expr<__indirect_expr&> > +valarray<_Tp>::operator[](const gslice& __gs) const +{ + return __val_expr<__indirect_expr >(__indirect_expr(__gs.__1d_, *this)); +} + +template +inline +gslice_array<_Tp> +valarray<_Tp>::operator[](const gslice& __gs) +{ + return gslice_array(__gs, *this); +} + +#ifndef _LIBCPP_CXX03_LANG + +template +inline +__val_expr<__indirect_expr&> > +valarray<_Tp>::operator[](gslice&& __gs) const +{ + return __val_expr<__indirect_expr >(__indirect_expr(move(__gs.__1d_), *this)); +} + +template +inline +gslice_array<_Tp> +valarray<_Tp>::operator[](gslice&& __gs) +{ + return gslice_array(move(__gs), *this); +} + +#endif // _LIBCPP_CXX03_LANG + +template +inline +__val_expr<__mask_expr&> > +valarray<_Tp>::operator[](const valarray& __vb) const +{ + return __val_expr<__mask_expr >(__mask_expr(__vb, *this)); +} + +template +inline +mask_array<_Tp> +valarray<_Tp>::operator[](const valarray& __vb) +{ + return mask_array(__vb, *this); +} + +#ifndef _LIBCPP_CXX03_LANG + +template +inline +__val_expr<__mask_expr&> > +valarray<_Tp>::operator[](valarray&& __vb) const +{ + return __val_expr<__mask_expr >(__mask_expr(move(__vb), *this)); +} + +template +inline +mask_array<_Tp> +valarray<_Tp>::operator[](valarray&& __vb) +{ + return mask_array(move(__vb), *this); +} + +#endif // _LIBCPP_CXX03_LANG + +template +inline +__val_expr<__indirect_expr&> > +valarray<_Tp>::operator[](const valarray& __vs) const +{ + return __val_expr<__indirect_expr >(__indirect_expr(__vs, *this)); +} + +template +inline +indirect_array<_Tp> +valarray<_Tp>::operator[](const valarray& __vs) +{ + return indirect_array(__vs, *this); +} + +#ifndef _LIBCPP_CXX03_LANG + +template +inline +__val_expr<__indirect_expr&> > +valarray<_Tp>::operator[](valarray&& __vs) const +{ + return __val_expr<__indirect_expr >(__indirect_expr(move(__vs), *this)); +} + +template +inline +indirect_array<_Tp> +valarray<_Tp>::operator[](valarray&& __vs) +{ + return indirect_array(move(__vs), *this); +} + +#endif // _LIBCPP_CXX03_LANG + +template +valarray<_Tp> +valarray<_Tp>::operator+() const +{ + valarray __r; + size_t __n = size(); + if (__n) + { + __r.__begin_ = + __r.__end_ = + static_cast( + _VSTD::__libcpp_allocate(__n * sizeof(value_type), _LIBCPP_ALIGNOF(value_type))); + for (const value_type* __p = __begin_; __n; ++__r.__end_, ++__p, --__n) + ::new (__r.__end_) value_type(+*__p); + } + return __r; +} + +template +valarray<_Tp> +valarray<_Tp>::operator-() const +{ + valarray __r; + size_t __n = size(); + if (__n) + { + __r.__begin_ = + __r.__end_ = + static_cast( + _VSTD::__libcpp_allocate(__n * sizeof(value_type), _LIBCPP_ALIGNOF(value_type))); + for (const value_type* __p = __begin_; __n; ++__r.__end_, ++__p, --__n) + ::new (__r.__end_) value_type(-*__p); + } + return __r; +} + +template +valarray<_Tp> +valarray<_Tp>::operator~() const +{ + valarray __r; + size_t __n = size(); + if (__n) + { + __r.__begin_ = + __r.__end_ = + static_cast( + _VSTD::__libcpp_allocate(__n * sizeof(value_type), _LIBCPP_ALIGNOF(value_type))); + for (const value_type* __p = __begin_; __n; ++__r.__end_, ++__p, --__n) + ::new (__r.__end_) value_type(~*__p); + } + return __r; +} + +template +valarray +valarray<_Tp>::operator!() const +{ + valarray __r; + size_t __n = size(); + if (__n) + { + __r.__begin_ = + __r.__end_ = + static_cast(_VSTD::__libcpp_allocate(__n * sizeof(bool), _LIBCPP_ALIGNOF(bool))); + for (const value_type* __p = __begin_; __n; ++__r.__end_, ++__p, --__n) + ::new (__r.__end_) bool(!*__p); + } + return __r; +} + +template +inline +valarray<_Tp>& +valarray<_Tp>::operator*=(const value_type& __x) +{ + for (value_type* __p = __begin_; __p != __end_; ++__p) + *__p *= __x; + return *this; +} + +template +inline +valarray<_Tp>& +valarray<_Tp>::operator/=(const value_type& __x) +{ + for (value_type* __p = __begin_; __p != __end_; ++__p) + *__p /= __x; + return *this; +} + +template +inline +valarray<_Tp>& +valarray<_Tp>::operator%=(const value_type& __x) +{ + for (value_type* __p = __begin_; __p != __end_; ++__p) + *__p %= __x; + return *this; +} + +template +inline +valarray<_Tp>& +valarray<_Tp>::operator+=(const value_type& __x) +{ + for (value_type* __p = __begin_; __p != __end_; ++__p) + *__p += __x; + return *this; +} + +template +inline +valarray<_Tp>& +valarray<_Tp>::operator-=(const value_type& __x) +{ + for (value_type* __p = __begin_; __p != __end_; ++__p) + *__p -= __x; + return *this; +} + +template +inline +valarray<_Tp>& +valarray<_Tp>::operator^=(const value_type& __x) +{ + for (value_type* __p = __begin_; __p != __end_; ++__p) + *__p ^= __x; + return *this; +} + +template +inline +valarray<_Tp>& +valarray<_Tp>::operator&=(const value_type& __x) +{ + for (value_type* __p = __begin_; __p != __end_; ++__p) + *__p &= __x; + return *this; +} + +template +inline +valarray<_Tp>& +valarray<_Tp>::operator|=(const value_type& __x) +{ + for (value_type* __p = __begin_; __p != __end_; ++__p) + *__p |= __x; + return *this; +} + +template +inline +valarray<_Tp>& +valarray<_Tp>::operator<<=(const value_type& __x) +{ + for (value_type* __p = __begin_; __p != __end_; ++__p) + *__p <<= __x; + return *this; +} + +template +inline +valarray<_Tp>& +valarray<_Tp>::operator>>=(const value_type& __x) +{ + for (value_type* __p = __begin_; __p != __end_; ++__p) + *__p >>= __x; + return *this; +} + +template +template +inline +typename enable_if +< + __is_val_expr<_Expr>::value, + valarray<_Tp>& +>::type +valarray<_Tp>::operator*=(const _Expr& __v) +{ + size_t __i = 0; + for (value_type* __t = __begin_; __t != __end_ ; ++__t, ++__i) + *__t *= __v[__i]; + return *this; +} + +template +template +inline +typename enable_if +< + __is_val_expr<_Expr>::value, + valarray<_Tp>& +>::type +valarray<_Tp>::operator/=(const _Expr& __v) +{ + size_t __i = 0; + for (value_type* __t = __begin_; __t != __end_ ; ++__t, ++__i) + *__t /= __v[__i]; + return *this; +} + +template +template +inline +typename enable_if +< + __is_val_expr<_Expr>::value, + valarray<_Tp>& +>::type +valarray<_Tp>::operator%=(const _Expr& __v) +{ + size_t __i = 0; + for (value_type* __t = __begin_; __t != __end_ ; ++__t, ++__i) + *__t %= __v[__i]; + return *this; +} + +template +template +inline +typename enable_if +< + __is_val_expr<_Expr>::value, + valarray<_Tp>& +>::type +valarray<_Tp>::operator+=(const _Expr& __v) +{ + size_t __i = 0; + for (value_type* __t = __begin_; __t != __end_ ; ++__t, ++__i) + *__t += __v[__i]; + return *this; +} + +template +template +inline +typename enable_if +< + __is_val_expr<_Expr>::value, + valarray<_Tp>& +>::type +valarray<_Tp>::operator-=(const _Expr& __v) +{ + size_t __i = 0; + for (value_type* __t = __begin_; __t != __end_ ; ++__t, ++__i) + *__t -= __v[__i]; + return *this; +} + +template +template +inline +typename enable_if +< + __is_val_expr<_Expr>::value, + valarray<_Tp>& +>::type +valarray<_Tp>::operator^=(const _Expr& __v) +{ + size_t __i = 0; + for (value_type* __t = __begin_; __t != __end_ ; ++__t, ++__i) + *__t ^= __v[__i]; + return *this; +} + +template +template +inline +typename enable_if +< + __is_val_expr<_Expr>::value, + valarray<_Tp>& +>::type +valarray<_Tp>::operator|=(const _Expr& __v) +{ + size_t __i = 0; + for (value_type* __t = __begin_; __t != __end_ ; ++__t, ++__i) + *__t |= __v[__i]; + return *this; +} + +template +template +inline +typename enable_if +< + __is_val_expr<_Expr>::value, + valarray<_Tp>& +>::type +valarray<_Tp>::operator&=(const _Expr& __v) +{ + size_t __i = 0; + for (value_type* __t = __begin_; __t != __end_ ; ++__t, ++__i) + *__t &= __v[__i]; + return *this; +} + +template +template +inline +typename enable_if +< + __is_val_expr<_Expr>::value, + valarray<_Tp>& +>::type +valarray<_Tp>::operator<<=(const _Expr& __v) +{ + size_t __i = 0; + for (value_type* __t = __begin_; __t != __end_ ; ++__t, ++__i) + *__t <<= __v[__i]; + return *this; +} + +template +template +inline +typename enable_if +< + __is_val_expr<_Expr>::value, + valarray<_Tp>& +>::type +valarray<_Tp>::operator>>=(const _Expr& __v) +{ + size_t __i = 0; + for (value_type* __t = __begin_; __t != __end_ ; ++__t, ++__i) + *__t >>= __v[__i]; + return *this; +} + +template +inline +void +valarray<_Tp>::swap(valarray& __v) _NOEXCEPT +{ + _VSTD::swap(__begin_, __v.__begin_); + _VSTD::swap(__end_, __v.__end_); +} + +template +inline +_Tp +valarray<_Tp>::sum() const +{ + if (__begin_ == __end_) + return value_type(); + const value_type* __p = __begin_; + _Tp __r = *__p; + for (++__p; __p != __end_; ++__p) + __r += *__p; + return __r; +} + +template +inline +_Tp +valarray<_Tp>::min() const +{ + if (__begin_ == __end_) + return value_type(); + return *_VSTD::min_element(__begin_, __end_); +} + +template +inline +_Tp +valarray<_Tp>::max() const +{ + if (__begin_ == __end_) + return value_type(); + return *_VSTD::max_element(__begin_, __end_); +} + +template +valarray<_Tp> +valarray<_Tp>::shift(int __i) const +{ + valarray __r; + size_t __n = size(); + if (__n) + { + __r.__begin_ = + __r.__end_ = + static_cast( + _VSTD::__libcpp_allocate(__n * sizeof(value_type), _LIBCPP_ALIGNOF(value_type))); + const value_type* __sb; + value_type* __tb; + value_type* __te; + if (__i >= 0) + { + __i = _VSTD::min(__i, static_cast(__n)); + __sb = __begin_ + __i; + __tb = __r.__begin_; + __te = __r.__begin_ + (__n - __i); + } + else + { + __i = _VSTD::min(-__i, static_cast(__n)); + __sb = __begin_; + __tb = __r.__begin_ + __i; + __te = __r.__begin_ + __n; + } + for (; __r.__end_ != __tb; ++__r.__end_) + ::new (__r.__end_) value_type(); + for (; __r.__end_ != __te; ++__r.__end_, ++__sb) + ::new (__r.__end_) value_type(*__sb); + for (__te = __r.__begin_ + __n; __r.__end_ != __te; ++__r.__end_) + ::new (__r.__end_) value_type(); + } + return __r; +} + +template +valarray<_Tp> +valarray<_Tp>::cshift(int __i) const +{ + valarray __r; + size_t __n = size(); + if (__n) + { + __r.__begin_ = + __r.__end_ = + static_cast( + _VSTD::__libcpp_allocate(__n * sizeof(value_type), _LIBCPP_ALIGNOF(value_type))); + __i %= static_cast(__n); + const value_type* __m = __i >= 0 ? __begin_ + __i : __end_ + __i; + for (const value_type* __s = __m; __s != __end_; ++__r.__end_, ++__s) + ::new (__r.__end_) value_type(*__s); + for (const value_type* __s = __begin_; __s != __m; ++__r.__end_, ++__s) + ::new (__r.__end_) value_type(*__s); + } + return __r; +} + +template +valarray<_Tp> +valarray<_Tp>::apply(value_type __f(value_type)) const +{ + valarray __r; + size_t __n = size(); + if (__n) + { + __r.__begin_ = + __r.__end_ = + static_cast( + _VSTD::__libcpp_allocate(__n * sizeof(value_type), _LIBCPP_ALIGNOF(value_type))); + for (const value_type* __p = __begin_; __n; ++__r.__end_, ++__p, --__n) + ::new (__r.__end_) value_type(__f(*__p)); + } + return __r; +} + +template +valarray<_Tp> +valarray<_Tp>::apply(value_type __f(const value_type&)) const +{ + valarray __r; + size_t __n = size(); + if (__n) + { + __r.__begin_ = + __r.__end_ = + static_cast( + _VSTD::__libcpp_allocate(__n * sizeof(value_type), _LIBCPP_ALIGNOF(value_type))); + for (const value_type* __p = __begin_; __n; ++__r.__end_, ++__p, --__n) + ::new (__r.__end_) value_type(__f(*__p)); + } + return __r; +} + +template +inline +void valarray<_Tp>::__clear(size_t __capacity) +{ + if (__begin_ != nullptr) + { + while (__end_ != __begin_) + (--__end_)->~value_type(); + _VSTD::__libcpp_deallocate(__begin_, __capacity * sizeof(value_type), _LIBCPP_ALIGNOF(value_type)); + __begin_ = __end_ = nullptr; + } +} + +template +void +valarray<_Tp>::resize(size_t __n, value_type __x) +{ + __clear(size()); + if (__n) + { + __begin_ = __end_ = static_cast( + _VSTD::__libcpp_allocate(__n * sizeof(value_type), _LIBCPP_ALIGNOF(value_type))); +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + for (size_t __n_left = __n; __n_left; --__n_left, ++__end_) + ::new (__end_) value_type(__x); +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + __clear(__n); + throw; + } +#endif // _LIBCPP_NO_EXCEPTIONS + } +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +swap(valarray<_Tp>& __x, valarray<_Tp>& __y) _NOEXCEPT +{ + __x.swap(__y); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + __is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value, + __val_expr<_BinaryOp, _Expr1, _Expr2> > +>::type +operator*(const _Expr1& __x, const _Expr2& __y) +{ + typedef typename _Expr1::value_type value_type; + typedef _BinaryOp, _Expr1, _Expr2> _Op; + return __val_expr<_Op>(_Op(multiplies(), __x, __y)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + __is_val_expr<_Expr>::value, + __val_expr<_BinaryOp, + _Expr, __scalar_expr > > +>::type +operator*(const _Expr& __x, const typename _Expr::value_type& __y) +{ + typedef typename _Expr::value_type value_type; + typedef _BinaryOp, _Expr, __scalar_expr > _Op; + return __val_expr<_Op>(_Op(multiplies(), + __x, __scalar_expr(__y, __x.size()))); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + __is_val_expr<_Expr>::value, + __val_expr<_BinaryOp, + __scalar_expr, _Expr> > +>::type +operator*(const typename _Expr::value_type& __x, const _Expr& __y) +{ + typedef typename _Expr::value_type value_type; + typedef _BinaryOp, __scalar_expr, _Expr> _Op; + return __val_expr<_Op>(_Op(multiplies(), + __scalar_expr(__x, __y.size()), __y)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + __is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value, + __val_expr<_BinaryOp, _Expr1, _Expr2> > +>::type +operator/(const _Expr1& __x, const _Expr2& __y) +{ + typedef typename _Expr1::value_type value_type; + typedef _BinaryOp, _Expr1, _Expr2> _Op; + return __val_expr<_Op>(_Op(divides(), __x, __y)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + __is_val_expr<_Expr>::value, + __val_expr<_BinaryOp, + _Expr, __scalar_expr > > +>::type +operator/(const _Expr& __x, const typename _Expr::value_type& __y) +{ + typedef typename _Expr::value_type value_type; + typedef _BinaryOp, _Expr, __scalar_expr > _Op; + return __val_expr<_Op>(_Op(divides(), + __x, __scalar_expr(__y, __x.size()))); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + __is_val_expr<_Expr>::value, + __val_expr<_BinaryOp, + __scalar_expr, _Expr> > +>::type +operator/(const typename _Expr::value_type& __x, const _Expr& __y) +{ + typedef typename _Expr::value_type value_type; + typedef _BinaryOp, __scalar_expr, _Expr> _Op; + return __val_expr<_Op>(_Op(divides(), + __scalar_expr(__x, __y.size()), __y)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + __is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value, + __val_expr<_BinaryOp, _Expr1, _Expr2> > +>::type +operator%(const _Expr1& __x, const _Expr2& __y) +{ + typedef typename _Expr1::value_type value_type; + typedef _BinaryOp, _Expr1, _Expr2> _Op; + return __val_expr<_Op>(_Op(modulus(), __x, __y)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + __is_val_expr<_Expr>::value, + __val_expr<_BinaryOp, + _Expr, __scalar_expr > > +>::type +operator%(const _Expr& __x, const typename _Expr::value_type& __y) +{ + typedef typename _Expr::value_type value_type; + typedef _BinaryOp, _Expr, __scalar_expr > _Op; + return __val_expr<_Op>(_Op(modulus(), + __x, __scalar_expr(__y, __x.size()))); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + __is_val_expr<_Expr>::value, + __val_expr<_BinaryOp, + __scalar_expr, _Expr> > +>::type +operator%(const typename _Expr::value_type& __x, const _Expr& __y) +{ + typedef typename _Expr::value_type value_type; + typedef _BinaryOp, __scalar_expr, _Expr> _Op; + return __val_expr<_Op>(_Op(modulus(), + __scalar_expr(__x, __y.size()), __y)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + __is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value, + __val_expr<_BinaryOp, _Expr1, _Expr2> > +>::type +operator+(const _Expr1& __x, const _Expr2& __y) +{ + typedef typename _Expr1::value_type value_type; + typedef _BinaryOp, _Expr1, _Expr2> _Op; + return __val_expr<_Op>(_Op(plus(), __x, __y)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + __is_val_expr<_Expr>::value, + __val_expr<_BinaryOp, + _Expr, __scalar_expr > > +>::type +operator+(const _Expr& __x, const typename _Expr::value_type& __y) +{ + typedef typename _Expr::value_type value_type; + typedef _BinaryOp, _Expr, __scalar_expr > _Op; + return __val_expr<_Op>(_Op(plus(), + __x, __scalar_expr(__y, __x.size()))); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + __is_val_expr<_Expr>::value, + __val_expr<_BinaryOp, + __scalar_expr, _Expr> > +>::type +operator+(const typename _Expr::value_type& __x, const _Expr& __y) +{ + typedef typename _Expr::value_type value_type; + typedef _BinaryOp, __scalar_expr, _Expr> _Op; + return __val_expr<_Op>(_Op(plus(), + __scalar_expr(__x, __y.size()), __y)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + __is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value, + __val_expr<_BinaryOp, _Expr1, _Expr2> > +>::type +operator-(const _Expr1& __x, const _Expr2& __y) +{ + typedef typename _Expr1::value_type value_type; + typedef _BinaryOp, _Expr1, _Expr2> _Op; + return __val_expr<_Op>(_Op(minus(), __x, __y)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + __is_val_expr<_Expr>::value, + __val_expr<_BinaryOp, + _Expr, __scalar_expr > > +>::type +operator-(const _Expr& __x, const typename _Expr::value_type& __y) +{ + typedef typename _Expr::value_type value_type; + typedef _BinaryOp, _Expr, __scalar_expr > _Op; + return __val_expr<_Op>(_Op(minus(), + __x, __scalar_expr(__y, __x.size()))); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + __is_val_expr<_Expr>::value, + __val_expr<_BinaryOp, + __scalar_expr, _Expr> > +>::type +operator-(const typename _Expr::value_type& __x, const _Expr& __y) +{ + typedef typename _Expr::value_type value_type; + typedef _BinaryOp, __scalar_expr, _Expr> _Op; + return __val_expr<_Op>(_Op(minus(), + __scalar_expr(__x, __y.size()), __y)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + __is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value, + __val_expr<_BinaryOp, _Expr1, _Expr2> > +>::type +operator^(const _Expr1& __x, const _Expr2& __y) +{ + typedef typename _Expr1::value_type value_type; + typedef _BinaryOp, _Expr1, _Expr2> _Op; + return __val_expr<_Op>(_Op(bit_xor(), __x, __y)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + __is_val_expr<_Expr>::value, + __val_expr<_BinaryOp, + _Expr, __scalar_expr > > +>::type +operator^(const _Expr& __x, const typename _Expr::value_type& __y) +{ + typedef typename _Expr::value_type value_type; + typedef _BinaryOp, _Expr, __scalar_expr > _Op; + return __val_expr<_Op>(_Op(bit_xor(), + __x, __scalar_expr(__y, __x.size()))); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + __is_val_expr<_Expr>::value, + __val_expr<_BinaryOp, + __scalar_expr, _Expr> > +>::type +operator^(const typename _Expr::value_type& __x, const _Expr& __y) +{ + typedef typename _Expr::value_type value_type; + typedef _BinaryOp, __scalar_expr, _Expr> _Op; + return __val_expr<_Op>(_Op(bit_xor(), + __scalar_expr(__x, __y.size()), __y)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + __is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value, + __val_expr<_BinaryOp, _Expr1, _Expr2> > +>::type +operator&(const _Expr1& __x, const _Expr2& __y) +{ + typedef typename _Expr1::value_type value_type; + typedef _BinaryOp, _Expr1, _Expr2> _Op; + return __val_expr<_Op>(_Op(bit_and(), __x, __y)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + __is_val_expr<_Expr>::value, + __val_expr<_BinaryOp, + _Expr, __scalar_expr > > +>::type +operator&(const _Expr& __x, const typename _Expr::value_type& __y) +{ + typedef typename _Expr::value_type value_type; + typedef _BinaryOp, _Expr, __scalar_expr > _Op; + return __val_expr<_Op>(_Op(bit_and(), + __x, __scalar_expr(__y, __x.size()))); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + __is_val_expr<_Expr>::value, + __val_expr<_BinaryOp, + __scalar_expr, _Expr> > +>::type +operator&(const typename _Expr::value_type& __x, const _Expr& __y) +{ + typedef typename _Expr::value_type value_type; + typedef _BinaryOp, __scalar_expr, _Expr> _Op; + return __val_expr<_Op>(_Op(bit_and(), + __scalar_expr(__x, __y.size()), __y)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + __is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value, + __val_expr<_BinaryOp, _Expr1, _Expr2> > +>::type +operator|(const _Expr1& __x, const _Expr2& __y) +{ + typedef typename _Expr1::value_type value_type; + typedef _BinaryOp, _Expr1, _Expr2> _Op; + return __val_expr<_Op>(_Op(bit_or(), __x, __y)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + __is_val_expr<_Expr>::value, + __val_expr<_BinaryOp, + _Expr, __scalar_expr > > +>::type +operator|(const _Expr& __x, const typename _Expr::value_type& __y) +{ + typedef typename _Expr::value_type value_type; + typedef _BinaryOp, _Expr, __scalar_expr > _Op; + return __val_expr<_Op>(_Op(bit_or(), + __x, __scalar_expr(__y, __x.size()))); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + __is_val_expr<_Expr>::value, + __val_expr<_BinaryOp, + __scalar_expr, _Expr> > +>::type +operator|(const typename _Expr::value_type& __x, const _Expr& __y) +{ + typedef typename _Expr::value_type value_type; + typedef _BinaryOp, __scalar_expr, _Expr> _Op; + return __val_expr<_Op>(_Op(bit_or(), + __scalar_expr(__x, __y.size()), __y)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + __is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value, + __val_expr<_BinaryOp<__bit_shift_left, _Expr1, _Expr2> > +>::type +operator<<(const _Expr1& __x, const _Expr2& __y) +{ + typedef typename _Expr1::value_type value_type; + typedef _BinaryOp<__bit_shift_left, _Expr1, _Expr2> _Op; + return __val_expr<_Op>(_Op(__bit_shift_left(), __x, __y)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + __is_val_expr<_Expr>::value, + __val_expr<_BinaryOp<__bit_shift_left, + _Expr, __scalar_expr > > +>::type +operator<<(const _Expr& __x, const typename _Expr::value_type& __y) +{ + typedef typename _Expr::value_type value_type; + typedef _BinaryOp<__bit_shift_left, _Expr, __scalar_expr > _Op; + return __val_expr<_Op>(_Op(__bit_shift_left(), + __x, __scalar_expr(__y, __x.size()))); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + __is_val_expr<_Expr>::value, + __val_expr<_BinaryOp<__bit_shift_left, + __scalar_expr, _Expr> > +>::type +operator<<(const typename _Expr::value_type& __x, const _Expr& __y) +{ + typedef typename _Expr::value_type value_type; + typedef _BinaryOp<__bit_shift_left, __scalar_expr, _Expr> _Op; + return __val_expr<_Op>(_Op(__bit_shift_left(), + __scalar_expr(__x, __y.size()), __y)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + __is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value, + __val_expr<_BinaryOp<__bit_shift_right, _Expr1, _Expr2> > +>::type +operator>>(const _Expr1& __x, const _Expr2& __y) +{ + typedef typename _Expr1::value_type value_type; + typedef _BinaryOp<__bit_shift_right, _Expr1, _Expr2> _Op; + return __val_expr<_Op>(_Op(__bit_shift_right(), __x, __y)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + __is_val_expr<_Expr>::value, + __val_expr<_BinaryOp<__bit_shift_right, + _Expr, __scalar_expr > > +>::type +operator>>(const _Expr& __x, const typename _Expr::value_type& __y) +{ + typedef typename _Expr::value_type value_type; + typedef _BinaryOp<__bit_shift_right, _Expr, __scalar_expr > _Op; + return __val_expr<_Op>(_Op(__bit_shift_right(), + __x, __scalar_expr(__y, __x.size()))); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + __is_val_expr<_Expr>::value, + __val_expr<_BinaryOp<__bit_shift_right, + __scalar_expr, _Expr> > +>::type +operator>>(const typename _Expr::value_type& __x, const _Expr& __y) +{ + typedef typename _Expr::value_type value_type; + typedef _BinaryOp<__bit_shift_right, __scalar_expr, _Expr> _Op; + return __val_expr<_Op>(_Op(__bit_shift_right(), + __scalar_expr(__x, __y.size()), __y)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + __is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value, + __val_expr<_BinaryOp, _Expr1, _Expr2> > +>::type +operator&&(const _Expr1& __x, const _Expr2& __y) +{ + typedef typename _Expr1::value_type value_type; + typedef _BinaryOp, _Expr1, _Expr2> _Op; + return __val_expr<_Op>(_Op(logical_and(), __x, __y)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + __is_val_expr<_Expr>::value, + __val_expr<_BinaryOp, + _Expr, __scalar_expr > > +>::type +operator&&(const _Expr& __x, const typename _Expr::value_type& __y) +{ + typedef typename _Expr::value_type value_type; + typedef _BinaryOp, _Expr, __scalar_expr > _Op; + return __val_expr<_Op>(_Op(logical_and(), + __x, __scalar_expr(__y, __x.size()))); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + __is_val_expr<_Expr>::value, + __val_expr<_BinaryOp, + __scalar_expr, _Expr> > +>::type +operator&&(const typename _Expr::value_type& __x, const _Expr& __y) +{ + typedef typename _Expr::value_type value_type; + typedef _BinaryOp, __scalar_expr, _Expr> _Op; + return __val_expr<_Op>(_Op(logical_and(), + __scalar_expr(__x, __y.size()), __y)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + __is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value, + __val_expr<_BinaryOp, _Expr1, _Expr2> > +>::type +operator||(const _Expr1& __x, const _Expr2& __y) +{ + typedef typename _Expr1::value_type value_type; + typedef _BinaryOp, _Expr1, _Expr2> _Op; + return __val_expr<_Op>(_Op(logical_or(), __x, __y)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + __is_val_expr<_Expr>::value, + __val_expr<_BinaryOp, + _Expr, __scalar_expr > > +>::type +operator||(const _Expr& __x, const typename _Expr::value_type& __y) +{ + typedef typename _Expr::value_type value_type; + typedef _BinaryOp, _Expr, __scalar_expr > _Op; + return __val_expr<_Op>(_Op(logical_or(), + __x, __scalar_expr(__y, __x.size()))); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + __is_val_expr<_Expr>::value, + __val_expr<_BinaryOp, + __scalar_expr, _Expr> > +>::type +operator||(const typename _Expr::value_type& __x, const _Expr& __y) +{ + typedef typename _Expr::value_type value_type; + typedef _BinaryOp, __scalar_expr, _Expr> _Op; + return __val_expr<_Op>(_Op(logical_or(), + __scalar_expr(__x, __y.size()), __y)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + __is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value, + __val_expr<_BinaryOp, _Expr1, _Expr2> > +>::type +operator==(const _Expr1& __x, const _Expr2& __y) +{ + typedef typename _Expr1::value_type value_type; + typedef _BinaryOp, _Expr1, _Expr2> _Op; + return __val_expr<_Op>(_Op(equal_to(), __x, __y)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + __is_val_expr<_Expr>::value, + __val_expr<_BinaryOp, + _Expr, __scalar_expr > > +>::type +operator==(const _Expr& __x, const typename _Expr::value_type& __y) +{ + typedef typename _Expr::value_type value_type; + typedef _BinaryOp, _Expr, __scalar_expr > _Op; + return __val_expr<_Op>(_Op(equal_to(), + __x, __scalar_expr(__y, __x.size()))); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + __is_val_expr<_Expr>::value, + __val_expr<_BinaryOp, + __scalar_expr, _Expr> > +>::type +operator==(const typename _Expr::value_type& __x, const _Expr& __y) +{ + typedef typename _Expr::value_type value_type; + typedef _BinaryOp, __scalar_expr, _Expr> _Op; + return __val_expr<_Op>(_Op(equal_to(), + __scalar_expr(__x, __y.size()), __y)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + __is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value, + __val_expr<_BinaryOp, _Expr1, _Expr2> > +>::type +operator!=(const _Expr1& __x, const _Expr2& __y) +{ + typedef typename _Expr1::value_type value_type; + typedef _BinaryOp, _Expr1, _Expr2> _Op; + return __val_expr<_Op>(_Op(not_equal_to(), __x, __y)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + __is_val_expr<_Expr>::value, + __val_expr<_BinaryOp, + _Expr, __scalar_expr > > +>::type +operator!=(const _Expr& __x, const typename _Expr::value_type& __y) +{ + typedef typename _Expr::value_type value_type; + typedef _BinaryOp, _Expr, __scalar_expr > _Op; + return __val_expr<_Op>(_Op(not_equal_to(), + __x, __scalar_expr(__y, __x.size()))); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + __is_val_expr<_Expr>::value, + __val_expr<_BinaryOp, + __scalar_expr, _Expr> > +>::type +operator!=(const typename _Expr::value_type& __x, const _Expr& __y) +{ + typedef typename _Expr::value_type value_type; + typedef _BinaryOp, __scalar_expr, _Expr> _Op; + return __val_expr<_Op>(_Op(not_equal_to(), + __scalar_expr(__x, __y.size()), __y)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + __is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value, + __val_expr<_BinaryOp, _Expr1, _Expr2> > +>::type +operator<(const _Expr1& __x, const _Expr2& __y) +{ + typedef typename _Expr1::value_type value_type; + typedef _BinaryOp, _Expr1, _Expr2> _Op; + return __val_expr<_Op>(_Op(less(), __x, __y)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + __is_val_expr<_Expr>::value, + __val_expr<_BinaryOp, + _Expr, __scalar_expr > > +>::type +operator<(const _Expr& __x, const typename _Expr::value_type& __y) +{ + typedef typename _Expr::value_type value_type; + typedef _BinaryOp, _Expr, __scalar_expr > _Op; + return __val_expr<_Op>(_Op(less(), + __x, __scalar_expr(__y, __x.size()))); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + __is_val_expr<_Expr>::value, + __val_expr<_BinaryOp, + __scalar_expr, _Expr> > +>::type +operator<(const typename _Expr::value_type& __x, const _Expr& __y) +{ + typedef typename _Expr::value_type value_type; + typedef _BinaryOp, __scalar_expr, _Expr> _Op; + return __val_expr<_Op>(_Op(less(), + __scalar_expr(__x, __y.size()), __y)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + __is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value, + __val_expr<_BinaryOp, _Expr1, _Expr2> > +>::type +operator>(const _Expr1& __x, const _Expr2& __y) +{ + typedef typename _Expr1::value_type value_type; + typedef _BinaryOp, _Expr1, _Expr2> _Op; + return __val_expr<_Op>(_Op(greater(), __x, __y)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + __is_val_expr<_Expr>::value, + __val_expr<_BinaryOp, + _Expr, __scalar_expr > > +>::type +operator>(const _Expr& __x, const typename _Expr::value_type& __y) +{ + typedef typename _Expr::value_type value_type; + typedef _BinaryOp, _Expr, __scalar_expr > _Op; + return __val_expr<_Op>(_Op(greater(), + __x, __scalar_expr(__y, __x.size()))); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + __is_val_expr<_Expr>::value, + __val_expr<_BinaryOp, + __scalar_expr, _Expr> > +>::type +operator>(const typename _Expr::value_type& __x, const _Expr& __y) +{ + typedef typename _Expr::value_type value_type; + typedef _BinaryOp, __scalar_expr, _Expr> _Op; + return __val_expr<_Op>(_Op(greater(), + __scalar_expr(__x, __y.size()), __y)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + __is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value, + __val_expr<_BinaryOp, _Expr1, _Expr2> > +>::type +operator<=(const _Expr1& __x, const _Expr2& __y) +{ + typedef typename _Expr1::value_type value_type; + typedef _BinaryOp, _Expr1, _Expr2> _Op; + return __val_expr<_Op>(_Op(less_equal(), __x, __y)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + __is_val_expr<_Expr>::value, + __val_expr<_BinaryOp, + _Expr, __scalar_expr > > +>::type +operator<=(const _Expr& __x, const typename _Expr::value_type& __y) +{ + typedef typename _Expr::value_type value_type; + typedef _BinaryOp, _Expr, __scalar_expr > _Op; + return __val_expr<_Op>(_Op(less_equal(), + __x, __scalar_expr(__y, __x.size()))); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + __is_val_expr<_Expr>::value, + __val_expr<_BinaryOp, + __scalar_expr, _Expr> > +>::type +operator<=(const typename _Expr::value_type& __x, const _Expr& __y) +{ + typedef typename _Expr::value_type value_type; + typedef _BinaryOp, __scalar_expr, _Expr> _Op; + return __val_expr<_Op>(_Op(less_equal(), + __scalar_expr(__x, __y.size()), __y)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + __is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value, + __val_expr<_BinaryOp, _Expr1, _Expr2> > +>::type +operator>=(const _Expr1& __x, const _Expr2& __y) +{ + typedef typename _Expr1::value_type value_type; + typedef _BinaryOp, _Expr1, _Expr2> _Op; + return __val_expr<_Op>(_Op(greater_equal(), __x, __y)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + __is_val_expr<_Expr>::value, + __val_expr<_BinaryOp, + _Expr, __scalar_expr > > +>::type +operator>=(const _Expr& __x, const typename _Expr::value_type& __y) +{ + typedef typename _Expr::value_type value_type; + typedef _BinaryOp, _Expr, __scalar_expr > _Op; + return __val_expr<_Op>(_Op(greater_equal(), + __x, __scalar_expr(__y, __x.size()))); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + __is_val_expr<_Expr>::value, + __val_expr<_BinaryOp, + __scalar_expr, _Expr> > +>::type +operator>=(const typename _Expr::value_type& __x, const _Expr& __y) +{ + typedef typename _Expr::value_type value_type; + typedef _BinaryOp, __scalar_expr, _Expr> _Op; + return __val_expr<_Op>(_Op(greater_equal(), + __scalar_expr(__x, __y.size()), __y)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + __is_val_expr<_Expr>::value, + __val_expr<_UnaryOp<__abs_expr, _Expr> > +>::type +abs(const _Expr& __x) +{ + typedef typename _Expr::value_type value_type; + typedef _UnaryOp<__abs_expr, _Expr> _Op; + return __val_expr<_Op>(_Op(__abs_expr(), __x)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + __is_val_expr<_Expr>::value, + __val_expr<_UnaryOp<__acos_expr, _Expr> > +>::type +acos(const _Expr& __x) +{ + typedef typename _Expr::value_type value_type; + typedef _UnaryOp<__acos_expr, _Expr> _Op; + return __val_expr<_Op>(_Op(__acos_expr(), __x)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + __is_val_expr<_Expr>::value, + __val_expr<_UnaryOp<__asin_expr, _Expr> > +>::type +asin(const _Expr& __x) +{ + typedef typename _Expr::value_type value_type; + typedef _UnaryOp<__asin_expr, _Expr> _Op; + return __val_expr<_Op>(_Op(__asin_expr(), __x)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + __is_val_expr<_Expr>::value, + __val_expr<_UnaryOp<__atan_expr, _Expr> > +>::type +atan(const _Expr& __x) +{ + typedef typename _Expr::value_type value_type; + typedef _UnaryOp<__atan_expr, _Expr> _Op; + return __val_expr<_Op>(_Op(__atan_expr(), __x)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + __is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value, + __val_expr<_BinaryOp<__atan2_expr, _Expr1, _Expr2> > +>::type +atan2(const _Expr1& __x, const _Expr2& __y) +{ + typedef typename _Expr1::value_type value_type; + typedef _BinaryOp<__atan2_expr, _Expr1, _Expr2> _Op; + return __val_expr<_Op>(_Op(__atan2_expr(), __x, __y)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + __is_val_expr<_Expr>::value, + __val_expr<_BinaryOp<__atan2_expr, + _Expr, __scalar_expr > > +>::type +atan2(const _Expr& __x, const typename _Expr::value_type& __y) +{ + typedef typename _Expr::value_type value_type; + typedef _BinaryOp<__atan2_expr, _Expr, __scalar_expr > _Op; + return __val_expr<_Op>(_Op(__atan2_expr(), + __x, __scalar_expr(__y, __x.size()))); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + __is_val_expr<_Expr>::value, + __val_expr<_BinaryOp<__atan2_expr, + __scalar_expr, _Expr> > +>::type +atan2(const typename _Expr::value_type& __x, const _Expr& __y) +{ + typedef typename _Expr::value_type value_type; + typedef _BinaryOp<__atan2_expr, __scalar_expr, _Expr> _Op; + return __val_expr<_Op>(_Op(__atan2_expr(), + __scalar_expr(__x, __y.size()), __y)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + __is_val_expr<_Expr>::value, + __val_expr<_UnaryOp<__cos_expr, _Expr> > +>::type +cos(const _Expr& __x) +{ + typedef typename _Expr::value_type value_type; + typedef _UnaryOp<__cos_expr, _Expr> _Op; + return __val_expr<_Op>(_Op(__cos_expr(), __x)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + __is_val_expr<_Expr>::value, + __val_expr<_UnaryOp<__cosh_expr, _Expr> > +>::type +cosh(const _Expr& __x) +{ + typedef typename _Expr::value_type value_type; + typedef _UnaryOp<__cosh_expr, _Expr> _Op; + return __val_expr<_Op>(_Op(__cosh_expr(), __x)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + __is_val_expr<_Expr>::value, + __val_expr<_UnaryOp<__exp_expr, _Expr> > +>::type +exp(const _Expr& __x) +{ + typedef typename _Expr::value_type value_type; + typedef _UnaryOp<__exp_expr, _Expr> _Op; + return __val_expr<_Op>(_Op(__exp_expr(), __x)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + __is_val_expr<_Expr>::value, + __val_expr<_UnaryOp<__log_expr, _Expr> > +>::type +log(const _Expr& __x) +{ + typedef typename _Expr::value_type value_type; + typedef _UnaryOp<__log_expr, _Expr> _Op; + return __val_expr<_Op>(_Op(__log_expr(), __x)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + __is_val_expr<_Expr>::value, + __val_expr<_UnaryOp<__log10_expr, _Expr> > +>::type +log10(const _Expr& __x) +{ + typedef typename _Expr::value_type value_type; + typedef _UnaryOp<__log10_expr, _Expr> _Op; + return __val_expr<_Op>(_Op(__log10_expr(), __x)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + __is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value, + __val_expr<_BinaryOp<__pow_expr, _Expr1, _Expr2> > +>::type +pow(const _Expr1& __x, const _Expr2& __y) +{ + typedef typename _Expr1::value_type value_type; + typedef _BinaryOp<__pow_expr, _Expr1, _Expr2> _Op; + return __val_expr<_Op>(_Op(__pow_expr(), __x, __y)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + __is_val_expr<_Expr>::value, + __val_expr<_BinaryOp<__pow_expr, + _Expr, __scalar_expr > > +>::type +pow(const _Expr& __x, const typename _Expr::value_type& __y) +{ + typedef typename _Expr::value_type value_type; + typedef _BinaryOp<__pow_expr, _Expr, __scalar_expr > _Op; + return __val_expr<_Op>(_Op(__pow_expr(), + __x, __scalar_expr(__y, __x.size()))); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + __is_val_expr<_Expr>::value, + __val_expr<_BinaryOp<__pow_expr, + __scalar_expr, _Expr> > +>::type +pow(const typename _Expr::value_type& __x, const _Expr& __y) +{ + typedef typename _Expr::value_type value_type; + typedef _BinaryOp<__pow_expr, __scalar_expr, _Expr> _Op; + return __val_expr<_Op>(_Op(__pow_expr(), + __scalar_expr(__x, __y.size()), __y)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + __is_val_expr<_Expr>::value, + __val_expr<_UnaryOp<__sin_expr, _Expr> > +>::type +sin(const _Expr& __x) +{ + typedef typename _Expr::value_type value_type; + typedef _UnaryOp<__sin_expr, _Expr> _Op; + return __val_expr<_Op>(_Op(__sin_expr(), __x)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + __is_val_expr<_Expr>::value, + __val_expr<_UnaryOp<__sinh_expr, _Expr> > +>::type +sinh(const _Expr& __x) +{ + typedef typename _Expr::value_type value_type; + typedef _UnaryOp<__sinh_expr, _Expr> _Op; + return __val_expr<_Op>(_Op(__sinh_expr(), __x)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + __is_val_expr<_Expr>::value, + __val_expr<_UnaryOp<__sqrt_expr, _Expr> > +>::type +sqrt(const _Expr& __x) +{ + typedef typename _Expr::value_type value_type; + typedef _UnaryOp<__sqrt_expr, _Expr> _Op; + return __val_expr<_Op>(_Op(__sqrt_expr(), __x)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + __is_val_expr<_Expr>::value, + __val_expr<_UnaryOp<__tan_expr, _Expr> > +>::type +tan(const _Expr& __x) +{ + typedef typename _Expr::value_type value_type; + typedef _UnaryOp<__tan_expr, _Expr> _Op; + return __val_expr<_Op>(_Op(__tan_expr(), __x)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + __is_val_expr<_Expr>::value, + __val_expr<_UnaryOp<__tanh_expr, _Expr> > +>::type +tanh(const _Expr& __x) +{ + typedef typename _Expr::value_type value_type; + typedef _UnaryOp<__tanh_expr, _Expr> _Op; + return __val_expr<_Op>(_Op(__tanh_expr(), __x)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_Tp* +begin(valarray<_Tp>& __v) +{ + return __v.__begin_; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +const _Tp* +begin(const valarray<_Tp>& __v) +{ + return __v.__begin_; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_Tp* +end(valarray<_Tp>& __v) +{ + return __v.__end_; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +const _Tp* +end(const valarray<_Tp>& __v) +{ + return __v.__end_; +} + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP_VALARRAY diff --git a/third_party/libcxx/valarray.cc b/third_party/libcxx/valarray.cc new file mode 100644 index 000000000..10598d059 --- /dev/null +++ b/third_party/libcxx/valarray.cc @@ -0,0 +1,58 @@ +// clang-format off +//===------------------------ valarray.cpp --------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "third_party/libcxx/valarray" + +_LIBCPP_BEGIN_NAMESPACE_STD + +// These two symbols are part of the v1 ABI but not part of the >=v2 ABI. +#if _LIBCPP_ABI_VERSION == 1 +template _LIBCPP_FUNC_VIS valarray::valarray(size_t); +template _LIBCPP_FUNC_VIS valarray::~valarray(); +#endif + +template void valarray::resize(size_t, size_t); + +void +gslice::__init(size_t __start) +{ + valarray __indices(__size_.size()); + size_t __k = __size_.size() != 0; + for (size_t __i = 0; __i < __size_.size(); ++__i) + __k *= __size_[__i]; + __1d_.resize(__k); + if (__1d_.size()) + { + __k = 0; + __1d_[__k] = __start; + while (true) + { + size_t __i = __indices.size() - 1; + while (true) + { + if (++__indices[__i] < __size_[__i]) + { + ++__k; + __1d_[__k] = __1d_[__k-1] + __stride_[__i]; + for (size_t __j = __i + 1; __j != __indices.size(); ++__j) + __1d_[__k] -= __stride_[__j] * (__size_[__j] - 1); + break; + } + else + { + if (__i == 0) + return; + __indices[__i--] = 0; + } + } + } + } +} + +_LIBCPP_END_NAMESPACE_STD diff --git a/tool/build/lib/elfwriter.c b/tool/build/lib/elfwriter.c index 7bd0cb8f2..a092da79d 100644 --- a/tool/build/lib/elfwriter.c +++ b/tool/build/lib/elfwriter.c @@ -22,6 +22,7 @@ #include "libc/mem/arraylist2.internal.h" #include "libc/runtime/gc.internal.h" #include "libc/runtime/memtrack.internal.h" +#include "libc/stdalign.internal.h" #include "libc/str/str.h" #include "libc/sysv/consts/map.h" #include "libc/sysv/consts/msync.h" diff --git a/tool/build/lib/memorymalloc.c b/tool/build/lib/memorymalloc.c index 8927c4472..d4c312cca 100644 --- a/tool/build/lib/memorymalloc.c +++ b/tool/build/lib/memorymalloc.c @@ -27,7 +27,7 @@ struct Machine *NewMachine(void) { struct Machine *m; - m = xmemalignzero(alignof(struct Machine), sizeof(struct Machine)); + m = xmemalignzero(_Alignof(struct Machine), sizeof(struct Machine)); ResetCpu(m); ResetMem(m); return m; diff --git a/tool/emacs/cosmo-stuff.el b/tool/emacs/cosmo-stuff.el index c02f40531..a10d4b269 100644 --- a/tool/emacs/cosmo-stuff.el +++ b/tool/emacs/cosmo-stuff.el @@ -225,7 +225,7 @@ ;; "nm -C --size o/$m/%s.o | sort -r" "echo" "size -A o/$m/$n.o | grep '^[.T]' | grep -v 'debug\\|command.line\\|stack' | sort -rnk2" - "objdump %s -wzCd o/$m/$n%s.o")) + "objdump %s -wzCd o/$m/$n%s.o | c++filt")) mode name suffix objdumpflags suffix)) ((eq kind 'run) (format @@ -249,7 +249,7 @@ ;; "nm -C --size $f | sort -r" "echo" "size -A $f | grep '^[.T]' | grep -v 'debug\\|command.line\\|stack' | sort -rnk2" - "objdump %s -wzCd $f")) + "objdump %s -wzCd $f | c++filt")) mode name suffix objdumpflags))))) (defun cosmo-compile (arg) @@ -781,7 +781,8 @@ (progn (define-key prog-mode-map (kbd "C-c C-h") 'cosmo-add-include) (define-key asm-mode-map (kbd "C-c C-h") 'cosmo-add-include) - (define-key c-mode-base-map (kbd "C-c C-h") 'cosmo-add-include)) + (define-key c-mode-base-map (kbd "C-c C-h") 'cosmo-add-include) + (define-key c++-mode-map (kbd "C-c C-h") 'cosmo-add-include)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;