11#ifndef NONSTD_VARIANT_LITE_HPP
12#define NONSTD_VARIANT_LITE_HPP
14#define variant_lite_MAJOR 1
15#define variant_lite_MINOR 2
16#define variant_lite_PATCH 2
18#define variant_lite_VERSION \
19 variant_STRINGIFY(variant_lite_MAJOR) "." variant_STRINGIFY( \
20 variant_lite_MINOR) "." variant_STRINGIFY(variant_lite_PATCH)
22#define variant_STRINGIFY(x) variant_STRINGIFY_(x)
23#define variant_STRINGIFY_(x) #x
27#define variant_VARIANT_DEFAULT 0
28#define variant_VARIANT_NONSTD 1
29#define variant_VARIANT_STD 2
31#if !defined(variant_CONFIG_SELECT_VARIANT)
32#define variant_CONFIG_SELECT_VARIANT \
33 (variant_HAVE_STD_VARIANT ? variant_VARIANT_STD : variant_VARIANT_NONSTD)
36#ifndef variant_CONFIG_OMIT_VARIANT_SIZE_V_MACRO
37#define variant_CONFIG_OMIT_VARIANT_SIZE_V_MACRO 0
40#ifndef variant_CONFIG_OMIT_VARIANT_ALTERNATIVE_T_MACRO
41#define variant_CONFIG_OMIT_VARIANT_ALTERNATIVE_T_MACRO 0
46#ifndef variant_CONFIG_NO_EXCEPTIONS
47#if defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)
48#define variant_CONFIG_NO_EXCEPTIONS 0
50#define variant_CONFIG_NO_EXCEPTIONS 1
57#ifndef variant_CPLUSPLUS
58#if defined(_MSVC_LANG) && !defined(__clang__)
59#define variant_CPLUSPLUS (_MSC_VER == 1900 ? 201103L : _MSVC_LANG)
61#define variant_CPLUSPLUS __cplusplus
65#define variant_CPP98_OR_GREATER (variant_CPLUSPLUS >= 199711L)
66#define variant_CPP11_OR_GREATER (variant_CPLUSPLUS >= 201103L)
67#define variant_CPP11_OR_GREATER_ (variant_CPLUSPLUS >= 201103L)
68#define variant_CPP14_OR_GREATER (variant_CPLUSPLUS >= 201402L)
69#define variant_CPP17_OR_GREATER (variant_CPLUSPLUS >= 201703L)
70#define variant_CPP20_OR_GREATER (variant_CPLUSPLUS >= 202000L)
74#if variant_CPP17_OR_GREATER && defined(__has_include)
75#if __has_include(<variant> )
76#define variant_HAVE_STD_VARIANT 1
78#define variant_HAVE_STD_VARIANT 0
81#define variant_HAVE_STD_VARIANT 0
84#define variant_USES_STD_VARIANT \
85 ((variant_CONFIG_SELECT_VARIANT == variant_VARIANT_STD) || \
86 ((variant_CONFIG_SELECT_VARIANT == variant_VARIANT_DEFAULT) && \
87 variant_HAVE_STD_VARIANT))
94#ifndef nonstd_lite_HAVE_IN_PLACE_TYPES
95#define nonstd_lite_HAVE_IN_PLACE_TYPES 1
99#if variant_CPP17_OR_GREATER
106using std::in_place_index;
107using std::in_place_index_t;
108using std::in_place_t;
109using std::in_place_type;
110using std::in_place_type_t;
112#define nonstd_lite_in_place_t(T) std::in_place_t
113#define nonstd_lite_in_place_type_t(T) std::in_place_type_t<T>
114#define nonstd_lite_in_place_index_t(K) std::in_place_index_t<K>
116#define nonstd_lite_in_place(T) \
118#define nonstd_lite_in_place_type(T) \
119 std::in_place_type_t<T> {}
120#define nonstd_lite_in_place_index(K) \
121 std::in_place_index_t<K> {}
146template <std::
size_t K>
148in_place(detail::in_place_index_tag<K> = detail::in_place_index_tag<K>()) {
158template <std::
size_t K>
166#define nonstd_lite_in_place_t(T) \
167 nonstd::in_place_t (&)(nonstd::detail::in_place_type_tag<T>)
168#define nonstd_lite_in_place_type_t(T) \
169 nonstd::in_place_t (&)(nonstd::detail::in_place_type_tag<T>)
170#define nonstd_lite_in_place_index_t(K) \
171 nonstd::in_place_t (&)(nonstd::detail::in_place_index_tag<K>)
173#define nonstd_lite_in_place(T) nonstd::in_place_type<T>
174#define nonstd_lite_in_place_type(T) nonstd::in_place_type<T>
175#define nonstd_lite_in_place_index(K) nonstd::in_place_index<K>
186#if variant_USES_STD_VARIANT
191#if !variant_CONFIG_OMIT_VARIANT_SIZE_V_MACRO
192#define variant_size_V(T) nonstd::variant_size<T>::value
195#if !variant_CONFIG_OMIT_VARIANT_ALTERNATIVE_T_MACRO
196#define variant_alternative_T(K, T) \
197 typename nonstd::variant_alternative<K, T>::type
202using std::bad_variant_access;
206using std::variant_alternative;
207using std::variant_alternative_t;
208using std::variant_size;
209using std::variant_size_v;
213using std::holds_alternative;
215using std::operator==;
216using std::operator!=;
218using std::operator<=;
220using std::operator>=;
223constexpr auto variant_npos = std::variant_npos;
233#if variant_CONFIG_NO_EXCEPTIONS
242#define variant_CONFIG_MAX_TYPE_COUNT 16
243#define variant_CONFIG_MAX_VISITOR_ARG_COUNT 5
247#ifndef variant_CONFIG_MAX_ALIGN_HACK
248#define variant_CONFIG_MAX_ALIGN_HACK 0
251#ifndef variant_CONFIG_ALIGN_AS
255#ifndef variant_CONFIG_ALIGN_AS_FALLBACK
256#define variant_CONFIG_ALIGN_AS_FALLBACK double
260#define variant_BETWEEN(v, lo, hi) ((lo) <= (v) && (v) < (hi))
279#if defined(_MSC_VER) && !defined(__clang__)
280#define variant_COMPILER_MSVC_VER (_MSC_VER)
281#define variant_COMPILER_MSVC_VERSION \
282 (_MSC_VER / 10 - 10 * (5 + (_MSC_VER < 1900)))
284#define variant_COMPILER_MSVC_VER 0
285#define variant_COMPILER_MSVC_VERSION 0
288#define variant_COMPILER_VERSION(major, minor, patch) \
289 (10 * (10 * (major) + (minor)) + (patch))
291#if defined(__clang__)
292#define variant_COMPILER_CLANG_VERSION \
293 variant_COMPILER_VERSION(__clang_major__, __clang_minor__, \
294 __clang_patchlevel__)
296#define variant_COMPILER_CLANG_VERSION 0
299#if defined(__GNUC__) && !defined(__clang__)
300#define variant_COMPILER_GNUC_VERSION \
301 variant_COMPILER_VERSION(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
303#define variant_COMPILER_GNUC_VERSION 0
306#if variant_BETWEEN(variant_COMPILER_MSVC_VER, 1300, 1900)
308#pragma warning(disable : 4345)
313#define variant_HAVE(feature) (variant_HAVE_##feature)
316#define variant_HAS_CPP0X _HAS_CPP0X
318#define variant_HAS_CPP0X 0
323#if variant_COMPILER_MSVC_VER >= 1900
324#undef variant_CPP11_OR_GREATER
325#define variant_CPP11_OR_GREATER 1
328#define variant_CPP11_90 \
329 (variant_CPP11_OR_GREATER_ || variant_COMPILER_MSVC_VER >= 1500)
330#define variant_CPP11_100 \
331 (variant_CPP11_OR_GREATER_ || variant_COMPILER_MSVC_VER >= 1600)
332#define variant_CPP11_110 \
333 (variant_CPP11_OR_GREATER_ || variant_COMPILER_MSVC_VER >= 1700)
334#define variant_CPP11_120 \
335 (variant_CPP11_OR_GREATER_ || variant_COMPILER_MSVC_VER >= 1800)
336#define variant_CPP11_140 \
337 (variant_CPP11_OR_GREATER_ || variant_COMPILER_MSVC_VER >= 1900)
338#define variant_CPP11_141 \
339 (variant_CPP11_OR_GREATER_ || variant_COMPILER_MSVC_VER >= 1910)
341#define variant_CPP14_000 (variant_CPP14_OR_GREATER)
342#define variant_CPP17_000 (variant_CPP17_OR_GREATER)
346#define variant_HAVE_CONSTEXPR_11 variant_CPP11_140
347#define variant_HAVE_INITIALIZER_LIST variant_CPP11_120
348#define variant_HAVE_NOEXCEPT variant_CPP11_140
349#define variant_HAVE_NULLPTR variant_CPP11_100
350#define variant_HAVE_OVERRIDE variant_CPP11_140
354#define variant_HAVE_CONSTEXPR_14 variant_CPP14_000
362#define variant_HAVE_CONDITIONAL variant_CPP11_120
363#define variant_HAVE_REMOVE_CV variant_CPP11_120
364#define variant_HAVE_STD_ADD_POINTER variant_CPP11_90
365#define variant_HAVE_TYPE_TRAITS variant_CPP11_90
367#define variant_HAVE_TR1_TYPE_TRAITS (!!variant_COMPILER_GNUC_VERSION)
368#define variant_HAVE_TR1_ADD_POINTER (!!variant_COMPILER_GNUC_VERSION)
372#if variant_HAVE_CONSTEXPR_11
373#define variant_constexpr constexpr
375#define variant_constexpr
378#if variant_HAVE_CONSTEXPR_14
379#define variant_constexpr14 constexpr
381#define variant_constexpr14
384#if variant_HAVE_NOEXCEPT
385#define variant_noexcept noexcept
387#define variant_noexcept
390#if variant_HAVE_NULLPTR
391#define variant_nullptr nullptr
393#define variant_nullptr NULL
396#if variant_HAVE_OVERRIDE
397#define variant_override override
399#define variant_override
404#if variant_CPP11_OR_GREATER
408#if variant_HAVE_INITIALIZER_LIST
409#include <initializer_list>
412#if variant_HAVE_TYPE_TRAITS
413#include <type_traits>
414#elif variant_HAVE_TR1_TYPE_TRAITS
415#include <tr1/type_traits>
420#if variant_CPP11_OR_GREATER
422#define variant_REQUIRES_0(...) \
423 template <bool B = (__VA_ARGS__), typename std::enable_if<B, int>::type = 0>
425#define variant_REQUIRES_T(...) \
426 , typename std::enable_if<(__VA_ARGS__), int>::type = 0
428#define variant_REQUIRES_R(R, ...) \
429 typename std::enable_if<(__VA_ARGS__), R>::type
431#define variant_REQUIRES_A(...) \
432 , typename std::enable_if<(__VA_ARGS__), void*>::type = nullptr
447#if variant_HAVE_STD_ADD_POINTER
449using std::add_pointer;
451#elif variant_HAVE_TR1_ADD_POINTER
453using std::tr1::add_pointer;
465 typedef typename remove_reference<T>::type* type;
470#if variant_HAVE_REMOVE_CV
496#if variant_HAVE_CONDITIONAL
498using std::conditional;
504template <
class Then,
class Else>
struct conditional<true, Then, Else> {
508template <
class Then,
class Else>
struct conditional<false, Then, Else> {
520#if variant_CPP17_OR_GREATER
522using std::is_nothrow_swappable;
523using std::is_swappable;
525#elif variant_CPP11_OR_GREATER
532 template <
typename T,
533 typename =
decltype(swap(std::declval<T&>(), std::declval<T&>()))>
534 static std::true_type test(
int);
536 template <
typename>
static std::false_type test(...);
539struct is_nothrow_swappable {
543 template <
typename T>
static constexpr bool test() {
544 return noexcept(swap(std::declval<T&>(), std::declval<T&>()));
547 template <
typename T>
548 static auto test(
int) -> std::integral_constant<bool, test<T>()> {}
550 template <
typename>
static std::false_type test(...);
558struct is_swappable : decltype(detail::is_swappable::test<T>(0)) {};
561struct is_nothrow_swappable
562 : decltype(detail::is_nothrow_swappable::test<T>(0)) {};
574#define variant_TL1(T1) detail::typelist<T1, detail::nulltype>
575#define variant_TL2(T1, T2) detail::typelist<T1, variant_TL1(T2)>
576#define variant_TL3(T1, T2, T3) detail::typelist<T1, variant_TL2(T2, T3)>
577#define variant_TL4(T1, T2, T3, T4) \
578 detail::typelist<T1, variant_TL3(T2, T3, T4)>
579#define variant_TL5(T1, T2, T3, T4, T5) \
580 detail::typelist<T1, variant_TL4(T2, T3, T4, T5)>
581#define variant_TL6(T1, T2, T3, T4, T5, T6) \
582 detail::typelist<T1, variant_TL5(T2, T3, T4, T5, T6)>
583#define variant_TL7(T1, T2, T3, T4, T5, T6, T7) \
584 detail::typelist<T1, variant_TL6(T2, T3, T4, T5, T6, T7)>
585#define variant_TL8(T1, T2, T3, T4, T5, T6, T7, T8) \
586 detail::typelist<T1, variant_TL7(T2, T3, T4, T5, T6, T7, T8)>
587#define variant_TL9(T1, T2, T3, T4, T5, T6, T7, T8, T9) \
588 detail::typelist<T1, variant_TL8(T2, T3, T4, T5, T6, T7, T8, T9)>
589#define variant_TL10(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) \
590 detail::typelist<T1, variant_TL9(T2, T3, T4, T5, T6, T7, T8, T9, T10)>
591#define variant_TL11(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) \
592 detail::typelist<T1, variant_TL10(T2, T3, T4, T5, T6, T7, T8, T9, T10, T11)>
593#define variant_TL12(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12) \
594 detail::typelist<T1, variant_TL11(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
596#define variant_TL13(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13) \
597 detail::typelist<T1, variant_TL12(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
599#define variant_TL14(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, \
601 detail::typelist<T1, variant_TL13(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
603#define variant_TL15(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, \
605 detail::typelist<T1, variant_TL14(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
606 T11, T12, T13, T14, T15)>
607#define variant_TL16(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, \
609 detail::typelist<T1, variant_TL15(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
610 T11, T12, T13, T14, T15, T16)>
614template <
class T>
struct TX : T {
615 inline TX<T> operator+()
const {
return TX<T>(); }
616 inline TX<T> operator-()
const {
return TX<T>(); }
618 inline TX<T> operator!()
const {
return TX<T>(); }
619 inline TX<T> operator~()
const {
return TX<T>(); }
621 inline TX<T>* operator&()
const {
return variant_nullptr; }
623 template <
class U>
inline TX<T> operator*(U
const&)
const {
626 template <
class U>
inline TX<T> operator/(U
const&)
const {
630 template <
class U>
inline TX<T> operator%(U
const&)
const {
633 template <
class U>
inline TX<T> operator+(U
const&)
const {
636 template <
class U>
inline TX<T> operator-(U
const&)
const {
640 template <
class U>
inline TX<T> operator<<(U
const&)
const {
643 template <
class U>
inline TX<T> operator>>(U
const&)
const {
647 inline bool operator==(T
const&)
const {
return false; }
648 inline bool operator<(T
const&)
const {
return false; }
650 template <
class U>
inline TX<T> operator&(U
const&)
const {
653 template <
class U>
inline TX<T> operator|(U
const&)
const {
656 template <
class U>
inline TX<T> operator^(U
const&)
const {
660 template <
class U>
inline TX<T> operator&&(U
const&)
const {
663 template <
class U>
inline TX<T> operator||(U
const&)
const {
713 enum V { value = 0 };
726 (
sizeof(Head) > tail_value) ?
sizeof(Head) : std::size_t(tail_value)
730 tail_type>::type type;
733#if variant_CPP11_OR_GREATER
737template <
class List>
struct typelist_max_alignof;
739template <>
struct typelist_max_alignof<
nulltype> {
740 enum V { value = 0 };
743template <
class Head,
class Tail>
744struct typelist_max_alignof<typelist<Head, Tail>> {
746 enum TV { tail_value = size_t(typelist_max_alignof<Tail>::value) };
750 value = (
alignof(Head) > tail_value) ?
alignof(Head)
751 : std::size_t(tail_value)
760 enum V { value = 1 };
764 enum V { value = 0 };
767 enum V { value = 0 };
770 enum V { value = 0 };
773 enum V { value = 0 };
776 enum V { value = 0 };
779 enum V { value = 0 };
782 enum V { value = 0 };
785 enum V { value = 0 };
788 enum V { value = 0 };
791 enum V { value = 0 };
794 enum V { value = 0 };
797 enum V { value = 0 };
800 enum V { value = 0 };
803 enum V { value = 0 };
806 enum V { value = 0 };
809 enum V { value = 0 };
813 enum V { value = 0 };
817 enum V { value = typelist_size<Head>::value + typelist_size<Tail>::value };
825 enum V { value = -1 };
829 enum V { value = 0 };
832template <
class Head,
class Tail,
class T>
838 enum V { value = nextVal == -1 ? -1 : 1 + nextVal };
845template <
class Head,
class Tail>
850template <
class Head,
class Tail, std::
size_t i>
855#if variant_CONFIG_MAX_ALIGN_HACK
859#define variant_UNIQUE(name) variant_UNIQUE2(name, __LINE__)
860#define variant_UNIQUE2(name, line) variant_UNIQUE3(name, line)
861#define variant_UNIQUE3(name, line) name##line
863#define variant_ALIGN_TYPE(type) \
864 type variant_UNIQUE(_t); \
865 struct_t<type> variant_UNIQUE(_st)
872 variant_ALIGN_TYPE(
char);
873 variant_ALIGN_TYPE(
short int);
874 variant_ALIGN_TYPE(
int);
875 variant_ALIGN_TYPE(
long int);
876 variant_ALIGN_TYPE(
float);
877 variant_ALIGN_TYPE(
double);
878 variant_ALIGN_TYPE(
long double);
879 variant_ALIGN_TYPE(
char*);
880 variant_ALIGN_TYPE(
short int*);
881 variant_ALIGN_TYPE(
int*);
882 variant_ALIGN_TYPE(
long int*);
883 variant_ALIGN_TYPE(
float*);
884 variant_ALIGN_TYPE(
double*);
885 variant_ALIGN_TYPE(
long double*);
886 variant_ALIGN_TYPE(
void*);
889 variant_ALIGN_TYPE(
long long);
894 Unknown (*variant_UNIQUE(_))(Unknown);
895 Unknown* Unknown::* variant_UNIQUE(_);
896 Unknown (Unknown::* variant_UNIQUE(_))(Unknown);
898 struct_t<Unknown (*)(Unknown)> variant_UNIQUE(_);
899 struct_t<Unknown * Unknown::*> variant_UNIQUE(_);
900 struct_t<Unknown (Unknown::*)(Unknown)> variant_UNIQUE(_);
904#undef variant_UNIQUE2
905#undef variant_UNIQUE3
907#undef variant_ALIGN_TYPE
909#elif defined(variant_CONFIG_ALIGN_AS)
913#define variant_ALIGN_AS(unused) variant_CONFIG_ALIGN_AS
919#define variant_ALIGN_AS(to_align) \
920 typename detail::type_of_size<detail::alignment_types, \
921 detail::alignment_of<to_align>::value>::type
923template <
typename T>
struct alignment_of;
925template <
typename T>
struct alignment_of_hack {
932 enum V { value = A < S ? A : S };
944 N ==
sizeof(
typename List::head),
typename List::head,
945 typename type_of_size<typename List::tail, N>::type>::type type;
949 typedef variant_CONFIG_ALIGN_AS_FALLBACK type;
956#define variant_ALIGN_TYPE(type) typelist < type, typelist < struct_t<type>
960typedef variant_ALIGN_TYPE(
char), variant_ALIGN_TYPE(
short),
961 variant_ALIGN_TYPE(
int), variant_ALIGN_TYPE(
long),
962 variant_ALIGN_TYPE(
float), variant_ALIGN_TYPE(
double),
963 variant_ALIGN_TYPE(
long double),
965 variant_ALIGN_TYPE(
char*), variant_ALIGN_TYPE(
short*),
966 variant_ALIGN_TYPE(
int*), variant_ALIGN_TYPE(
long*),
967 variant_ALIGN_TYPE(
float*), variant_ALIGN_TYPE(
double*),
968 variant_ALIGN_TYPE(
long double*),
970 variant_ALIGN_TYPE(Unknown (*)(Unknown)),
971 variant_ALIGN_TYPE(Unknown* Unknown::*),
972 variant_ALIGN_TYPE(Unknown (Unknown::*)(Unknown)),
974 nulltype >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> alignment_types;
976#undef variant_ALIGN_TYPE
980#if variant_CPP11_OR_GREATER
982template <
typename T>
inline std::size_t hash(T
const& v) {
983 return std::hash<T>()(v);
986inline std::size_t hash(T0
const&) {
989inline std::size_t hash(T1
const&) {
992inline std::size_t hash(T2
const&) {
995inline std::size_t hash(T3
const&) {
998inline std::size_t hash(T4
const&) {
1001inline std::size_t hash(T5
const&) {
1004inline std::size_t hash(T6
const&) {
1007inline std::size_t hash(T7
const&) {
1010inline std::size_t hash(T8
const&) {
1013inline std::size_t hash(T9
const&) {
1016inline std::size_t hash(T10
const&) {
1019inline std::size_t hash(T11
const&) {
1022inline std::size_t hash(T12
const&) {
1025inline std::size_t hash(T13
const&) {
1028inline std::size_t hash(T14
const&) {
1031inline std::size_t hash(T15
const&) {
1037template <
class T0,
class T1,
class T2,
class T3,
class T4,
class T5,
class T6,
1038 class T7,
class T8,
class T9,
class T10,
class T11,
class T12,
1039 class T13,
class T14,
class T15>
1041 typedef signed char type_index_t;
1042 typedef variant_TL16(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
1043 T13, T14, T15) variant_types;
1045 template <
class U>
static U* as(
void* data) {
1046 return reinterpret_cast<U*
>(data);
1049 template <
class U>
static U
const* as(
void const* data) {
1050 return reinterpret_cast<const U*
>(data);
1053 static type_index_t to_index_t(std::size_t index) {
1054 return static_cast<type_index_t
>(index);
1057 static void destroy(type_index_t index,
void* data) {
1060 as<T0>(data)->~T0();
1063 as<T1>(data)->~T1();
1066 as<T2>(data)->~T2();
1069 as<T3>(data)->~T3();
1072 as<T4>(data)->~T4();
1075 as<T5>(data)->~T5();
1078 as<T6>(data)->~T6();
1081 as<T7>(data)->~T7();
1084 as<T8>(data)->~T8();
1087 as<T9>(data)->~T9();
1090 as<T10>(data)->~T10();
1093 as<T11>(data)->~T11();
1096 as<T12>(data)->~T12();
1099 as<T13>(data)->~T13();
1102 as<T14>(data)->~T14();
1105 as<T15>(data)->~T15();
1110#if variant_CPP11_OR_GREATER
1111 template <
class T,
class... Args>
1112 static type_index_t construct_t(
void* data, Args&&... args) {
1113 new (data) T(std::forward<Args>(args)...);
1118 template <std::size_t K,
class... Args>
1119 static type_index_t construct_i(
void* data, Args&&... args) {
1122 construct_t<type>(data, std::forward<Args>(args)...);
1124 return to_index_t(K);
1127 static type_index_t move_construct(type_index_t
const from_index,
1128 void* from_value,
void* to_value) {
1129 switch (from_index) {
1131 new (to_value) T0(std::move(*as<T0>(from_value)));
1134 new (to_value) T1(std::move(*as<T1>(from_value)));
1137 new (to_value) T2(std::move(*as<T2>(from_value)));
1140 new (to_value) T3(std::move(*as<T3>(from_value)));
1143 new (to_value) T4(std::move(*as<T4>(from_value)));
1146 new (to_value) T5(std::move(*as<T5>(from_value)));
1149 new (to_value) T6(std::move(*as<T6>(from_value)));
1152 new (to_value) T7(std::move(*as<T7>(from_value)));
1155 new (to_value) T8(std::move(*as<T8>(from_value)));
1158 new (to_value) T9(std::move(*as<T9>(from_value)));
1161 new (to_value) T10(std::move(*as<T10>(from_value)));
1164 new (to_value) T11(std::move(*as<T11>(from_value)));
1167 new (to_value) T12(std::move(*as<T12>(from_value)));
1170 new (to_value) T13(std::move(*as<T13>(from_value)));
1173 new (to_value) T14(std::move(*as<T14>(from_value)));
1176 new (to_value) T15(std::move(*as<T15>(from_value)));
1182 static type_index_t move_assign(type_index_t
const from_index,
1183 void* from_value,
void* to_value) {
1184 switch (from_index) {
1186 *as<T0>(to_value) = std::move(*as<T0>(from_value));
1189 *as<T1>(to_value) = std::move(*as<T1>(from_value));
1192 *as<T2>(to_value) = std::move(*as<T2>(from_value));
1195 *as<T3>(to_value) = std::move(*as<T3>(from_value));
1198 *as<T4>(to_value) = std::move(*as<T4>(from_value));
1201 *as<T5>(to_value) = std::move(*as<T5>(from_value));
1204 *as<T6>(to_value) = std::move(*as<T6>(from_value));
1207 *as<T7>(to_value) = std::move(*as<T7>(from_value));
1210 *as<T8>(to_value) = std::move(*as<T8>(from_value));
1213 *as<T9>(to_value) = std::move(*as<T9>(from_value));
1216 *as<T10>(to_value) = std::move(*as<T10>(from_value));
1219 *as<T11>(to_value) = std::move(*as<T11>(from_value));
1222 *as<T12>(to_value) = std::move(*as<T12>(from_value));
1225 *as<T13>(to_value) = std::move(*as<T13>(from_value));
1228 *as<T14>(to_value) = std::move(*as<T14>(from_value));
1231 *as<T15>(to_value) = std::move(*as<T15>(from_value));
1238 static type_index_t copy_construct(type_index_t
const from_index,
1239 const void* from_value,
void* to_value) {
1240 switch (from_index) {
1242 new (to_value) T0(*as<T0>(from_value));
1245 new (to_value) T1(*as<T1>(from_value));
1248 new (to_value) T2(*as<T2>(from_value));
1251 new (to_value) T3(*as<T3>(from_value));
1254 new (to_value) T4(*as<T4>(from_value));
1257 new (to_value) T5(*as<T5>(from_value));
1260 new (to_value) T6(*as<T6>(from_value));
1263 new (to_value) T7(*as<T7>(from_value));
1266 new (to_value) T8(*as<T8>(from_value));
1269 new (to_value) T9(*as<T9>(from_value));
1272 new (to_value) T10(*as<T10>(from_value));
1275 new (to_value) T11(*as<T11>(from_value));
1278 new (to_value) T12(*as<T12>(from_value));
1281 new (to_value) T13(*as<T13>(from_value));
1284 new (to_value) T14(*as<T14>(from_value));
1287 new (to_value) T15(*as<T15>(from_value));
1293 static type_index_t copy_assign(type_index_t
const from_index,
1294 const void* from_value,
void* to_value) {
1295 switch (from_index) {
1297 *as<T0>(to_value) = *as<T0>(from_value);
1300 *as<T1>(to_value) = *as<T1>(from_value);
1303 *as<T2>(to_value) = *as<T2>(from_value);
1306 *as<T3>(to_value) = *as<T3>(from_value);
1309 *as<T4>(to_value) = *as<T4>(from_value);
1312 *as<T5>(to_value) = *as<T5>(from_value);
1315 *as<T6>(to_value) = *as<T6>(from_value);
1318 *as<T7>(to_value) = *as<T7>(from_value);
1321 *as<T8>(to_value) = *as<T8>(from_value);
1324 *as<T9>(to_value) = *as<T9>(from_value);
1327 *as<T10>(to_value) = *as<T10>(from_value);
1330 *as<T11>(to_value) = *as<T11>(from_value);
1333 *as<T12>(to_value) = *as<T12>(from_value);
1336 *as<T13>(to_value) = *as<T13>(from_value);
1339 *as<T14>(to_value) = *as<T14>(from_value);
1342 *as<T15>(to_value) = *as<T15>(from_value);
1355template <
class T0,
class T1,
class T2,
class T3,
class T4,
class T5,
class T6,
1356 class T7,
class T8,
class T9,
class T10,
class T11,
class T12,
1357 class T13,
class T14,
class T15>
1372inline variant_constexpr
bool operator<=(monostate,
1373 monostate) variant_noexcept {
1376inline variant_constexpr
bool operator>=(
monostate,
1380inline variant_constexpr
bool operator==(
monostate,
1384inline variant_constexpr
bool operator!=(
monostate,
1395template <
class T0,
class T1,
class T2,
class T3,
class T4,
class T5,
class T6,
1396 class T7,
class T8,
class T9,
class T10,
class T11,
class T12,
1397 class T13,
class T14,
class T15>
1398struct variant_size<
variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
1399 T12, T13, T14, T15>> {
1402 T7, T8, T9, T10, T11, T12,
1403 T13, T14, T15)>::value
1407#if variant_CPP14_OR_GREATER
1412#if !variant_CONFIG_OMIT_VARIANT_SIZE_V_MACRO
1413#define variant_size_V(T) nonstd::variant_size<T>::value
1420template <std::size_t K,
class T0,
class T1,
class T2,
class T3,
class T4,
1421 class T5,
class T6,
class T7,
class T8,
class T9,
class T10,
1422 class T11,
class T12,
class T13,
class T14,
class T15>
1423struct variant_alternative<K,
variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9,
1424 T10, T11, T12, T13, T14, T15>> {
1427 T6, T7, T8, T9, T10, T11,
1428 T12, T13, T14, T15),
1432#if variant_CPP11_OR_GREATER
1433template <std::
size_t K,
class T>
1437#if !variant_CONFIG_OMIT_VARIANT_ALTERNATIVE_T_MACRO
1438#define variant_alternative_T(K, T) \
1439 typename nonstd::variant_alternative<K, T>::type
1447#if variant_CPP11_OR_GREATER
1448variant_constexpr std::size_t variant_npos =
static_cast<std::size_t
>(-1);
1450static const std::size_t variant_npos =
static_cast<std::size_t
>(-1);
1453#if !variant_CONFIG_NO_EXCEPTIONS
1457class bad_variant_access :
public std::exception {
1459#if variant_CPP11_OR_GREATER
1460 virtual const char* what() const variant_noexcept variant_override
1462 virtual const char* what()
const throw()
1465 return "bad variant access";
1473template <
class T0,
class T1 = detail::T1,
class T2 = detail::T2,
1474 class T3 = detail::T3,
class T4 = detail::T4,
class T5 = detail::T5,
1475 class T6 = detail::T6,
class T7 = detail::T7,
class T8 = detail::T8,
1476 class T9 = detail::T9,
class T10 = detail::T10,
1477 class T11 = detail::T11,
class T12 = detail::T12,
1478 class T13 = detail::T13,
class T14 = detail::T14,
1479 class T15 = detail::T15>
1481 typedef detail::helper<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
1484 typedef variant_TL16(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
1485 T13, T14, T15) variant_types;
1490 variant() : type_index(0) {
new (ptr()) T0(); }
1492 variant(T0
const& t0) : type_index(0) {
new (ptr()) T0(t0); }
1493 variant(T1
const& t1) : type_index(1) {
new (ptr()) T1(t1); }
1494 variant(T2
const& t2) : type_index(2) {
new (ptr()) T2(t2); }
1495 variant(T3
const& t3) : type_index(3) {
new (ptr()) T3(t3); }
1496 variant(T4
const& t4) : type_index(4) {
new (ptr()) T4(t4); }
1497 variant(T5
const& t5) : type_index(5) {
new (ptr()) T5(t5); }
1498 variant(T6
const& t6) : type_index(6) {
new (ptr()) T6(t6); }
1499 variant(T7
const& t7) : type_index(7) {
new (ptr()) T7(t7); }
1500 variant(T8
const& t8) : type_index(8) {
new (ptr()) T8(t8); }
1501 variant(T9
const& t9) : type_index(9) {
new (ptr()) T9(t9); }
1502 variant(T10
const& t10) : type_index(10) {
new (ptr()) T10(t10); }
1503 variant(T11
const& t11) : type_index(11) {
new (ptr()) T11(t11); }
1504 variant(T12
const& t12) : type_index(12) {
new (ptr()) T12(t12); }
1505 variant(T13
const& t13) : type_index(13) {
new (ptr()) T13(t13); }
1506 variant(T14
const& t14) : type_index(14) {
new (ptr()) T14(t14); }
1507 variant(T15
const& t15) : type_index(15) {
new (ptr()) T15(t15); }
1509#if variant_CPP11_OR_GREATER
1510 variant(T0&& t0) : type_index(0) {
new (ptr()) T0(std::move(t0)); }
1511 variant(T1&& t1) : type_index(1) {
new (ptr()) T1(std::move(t1)); }
1512 variant(T2&& t2) : type_index(2) {
new (ptr()) T2(std::move(t2)); }
1513 variant(T3&& t3) : type_index(3) {
new (ptr()) T3(std::move(t3)); }
1514 variant(T4&& t4) : type_index(4) {
new (ptr()) T4(std::move(t4)); }
1515 variant(T5&& t5) : type_index(5) {
new (ptr()) T5(std::move(t5)); }
1516 variant(T6&& t6) : type_index(6) {
new (ptr()) T6(std::move(t6)); }
1517 variant(T7&& t7) : type_index(7) {
new (ptr()) T7(std::move(t7)); }
1518 variant(T8&& t8) : type_index(8) {
new (ptr()) T8(std::move(t8)); }
1519 variant(T9&& t9) : type_index(9) {
new (ptr()) T9(std::move(t9)); }
1520 variant(T10&& t10) : type_index(10) {
new (ptr()) T10(std::move(t10)); }
1521 variant(T11&& t11) : type_index(11) {
new (ptr()) T11(std::move(t11)); }
1522 variant(T12&& t12) : type_index(12) {
new (ptr()) T12(std::move(t12)); }
1523 variant(T13&& t13) : type_index(13) {
new (ptr()) T13(std::move(t13)); }
1524 variant(T14&& t14) : type_index(14) {
new (ptr()) T14(std::move(t14)); }
1525 variant(T15&& t15) : type_index(15) {
new (ptr()) T15(std::move(t15)); }
1529 variant(variant
const& other) : type_index(other.type_index) {
1530 (void) helper_type::copy_construct(other.type_index, other.ptr(),
1534#if variant_CPP11_OR_GREATER
1536 variant(variant&& other)
noexcept(
1537 std::is_nothrow_move_constructible<T0>::value &&
1538 std::is_nothrow_move_constructible<T1>::value &&
1539 std::is_nothrow_move_constructible<T2>::value &&
1540 std::is_nothrow_move_constructible<T3>::value &&
1541 std::is_nothrow_move_constructible<T4>::value &&
1542 std::is_nothrow_move_constructible<T5>::value &&
1543 std::is_nothrow_move_constructible<T6>::value &&
1544 std::is_nothrow_move_constructible<T7>::value &&
1545 std::is_nothrow_move_constructible<T8>::value &&
1546 std::is_nothrow_move_constructible<T9>::value &&
1547 std::is_nothrow_move_constructible<T10>::value &&
1548 std::is_nothrow_move_constructible<T11>::value &&
1549 std::is_nothrow_move_constructible<T12>::value &&
1550 std::is_nothrow_move_constructible<T13>::value &&
1551 std::is_nothrow_move_constructible<T14>::value &&
1552 std::is_nothrow_move_constructible<T15>::value)
1553 : type_index(other.type_index) {
1554 (void) helper_type::move_construct(other.type_index, other.ptr(),
1558 template <std::
size_t K>
1561 template <
class T,
class... Args variant_REQUIRES_T(
1562 std::is_constructible<T, Args...>::value)>
1563 explicit variant(nonstd_lite_in_place_type_t(T), Args&&... args) {
1564 type_index = variant_npos_internal();
1565 type_index = helper_type::template construct_t<T>(
1566 ptr(), std::forward<Args>(args)...);
1569 template <
class T,
class U,
1570 class... Args variant_REQUIRES_T(
1571 std::is_constructible<T, std::initializer_list<U>&,
1573 explicit variant(nonstd_lite_in_place_type_t(T),
1574 std::initializer_list<U> il, Args&&... args) {
1575 type_index = variant_npos_internal();
1576 type_index = helper_type::template construct_t<T>(
1577 ptr(), il, std::forward<Args>(args)...);
1580 template <std::size_t K,
1581 class... Args variant_REQUIRES_T(
1582 std::is_constructible<type_at_t<K>, Args...>::value)>
1583 explicit variant(nonstd_lite_in_place_index_t(K), Args&&... args) {
1584 type_index = variant_npos_internal();
1585 type_index = helper_type::template construct_i<K>(
1586 ptr(), std::forward<Args>(args)...);
1589 template <
size_t K,
class U,
1590 class... Args variant_REQUIRES_T(
1591 std::is_constructible<type_at_t<K>, std::initializer_list<U>&,
1593 explicit variant(nonstd_lite_in_place_index_t(K),
1594 std::initializer_list<U> il, Args&&... args) {
1595 type_index = variant_npos_internal();
1596 type_index = helper_type::template construct_i<K>(
1597 ptr(), il, std::forward<Args>(args)...);
1605 if (!valueless_by_exception()) {
1606 helper_type::destroy(type_index, ptr());
1612 variant& operator=(variant
const& other) {
return copy_assign(other); }
1614#if variant_CPP11_OR_GREATER
1616 variant& operator=(variant&& other)
noexcept(
1617 std::is_nothrow_move_assignable<T0>::value &&
1618 std::is_nothrow_move_assignable<T1>::value &&
1619 std::is_nothrow_move_assignable<T2>::value &&
1620 std::is_nothrow_move_assignable<T3>::value &&
1621 std::is_nothrow_move_assignable<T4>::value &&
1622 std::is_nothrow_move_assignable<T5>::value &&
1623 std::is_nothrow_move_assignable<T6>::value &&
1624 std::is_nothrow_move_assignable<T7>::value &&
1625 std::is_nothrow_move_assignable<T8>::value &&
1626 std::is_nothrow_move_assignable<T9>::value &&
1627 std::is_nothrow_move_assignable<T10>::value &&
1628 std::is_nothrow_move_assignable<T11>::value &&
1629 std::is_nothrow_move_assignable<T12>::value &&
1630 std::is_nothrow_move_assignable<T13>::value &&
1631 std::is_nothrow_move_assignable<T14>::value &&
1632 std::is_nothrow_move_assignable<T15>::value) {
1633 return move_assign(std::move(other));
1636 variant& operator=(T0&& t0) {
return assign_value<0>(std::move(t0)); }
1637 variant& operator=(T1&& t1) {
return assign_value<1>(std::move(t1)); }
1638 variant& operator=(T2&& t2) {
return assign_value<2>(std::move(t2)); }
1639 variant& operator=(T3&& t3) {
return assign_value<3>(std::move(t3)); }
1640 variant& operator=(T4&& t4) {
return assign_value<4>(std::move(t4)); }
1641 variant& operator=(T5&& t5) {
return assign_value<5>(std::move(t5)); }
1642 variant& operator=(T6&& t6) {
return assign_value<6>(std::move(t6)); }
1643 variant& operator=(T7&& t7) {
return assign_value<7>(std::move(t7)); }
1644 variant& operator=(T8&& t8) {
return assign_value<8>(std::move(t8)); }
1645 variant& operator=(T9&& t9) {
return assign_value<9>(std::move(t9)); }
1646 variant& operator=(T10&& t10) {
return assign_value<10>(std::move(t10)); }
1647 variant& operator=(T11&& t11) {
return assign_value<11>(std::move(t11)); }
1648 variant& operator=(T12&& t12) {
return assign_value<12>(std::move(t12)); }
1649 variant& operator=(T13&& t13) {
return assign_value<13>(std::move(t13)); }
1650 variant& operator=(T14&& t14) {
return assign_value<14>(std::move(t14)); }
1651 variant& operator=(T15&& t15) {
return assign_value<15>(std::move(t15)); }
1655 variant& operator=(T0
const& t0) {
return assign_value<0>(t0); }
1656 variant& operator=(T1
const& t1) {
return assign_value<1>(t1); }
1657 variant& operator=(T2
const& t2) {
return assign_value<2>(t2); }
1658 variant& operator=(T3
const& t3) {
return assign_value<3>(t3); }
1659 variant& operator=(T4
const& t4) {
return assign_value<4>(t4); }
1660 variant& operator=(T5
const& t5) {
return assign_value<5>(t5); }
1661 variant& operator=(T6
const& t6) {
return assign_value<6>(t6); }
1662 variant& operator=(T7
const& t7) {
return assign_value<7>(t7); }
1663 variant& operator=(T8
const& t8) {
return assign_value<8>(t8); }
1664 variant& operator=(T9
const& t9) {
return assign_value<9>(t9); }
1665 variant& operator=(T10
const& t10) {
return assign_value<10>(t10); }
1666 variant& operator=(T11
const& t11) {
return assign_value<11>(t11); }
1667 variant& operator=(T12
const& t12) {
return assign_value<12>(t12); }
1668 variant& operator=(T13
const& t13) {
return assign_value<13>(t13); }
1669 variant& operator=(T14
const& t14) {
return assign_value<14>(t14); }
1670 variant& operator=(T15
const& t15) {
return assign_value<15>(t15); }
1672 std::size_t index()
const {
1673 return variant_npos_internal() == type_index
1675 :
static_cast<std::size_t
>(type_index);
1680#if variant_CPP11_OR_GREATER
1681 template <
class T,
class... Args variant_REQUIRES_T(
1682 std::is_constructible<T, Args...>::value)>
1683 T& emplace(Args&&... args) {
1684 helper_type::destroy(type_index, ptr());
1685 type_index = variant_npos_internal();
1686 type_index = helper_type::template construct_t<T>(
1687 ptr(), std::forward<Args>(args)...);
1692 template <
class T,
class U,
1693 class... Args variant_REQUIRES_T(
1694 std::is_constructible<T, std::initializer_list<U>&,
1696 T& emplace(std::initializer_list<U> il, Args&&... args) {
1697 helper_type::destroy(type_index, ptr());
1698 type_index = variant_npos_internal();
1699 type_index = helper_type::template construct_t<T>(
1700 ptr(), il, std::forward<Args>(args)...);
1706 class... Args variant_REQUIRES_T(
1707 std::is_constructible<type_at_t<K>, Args...>::value)>
1708 variant_alternative_t<K, variant>& emplace(Args&&... args) {
1709 return this->
template emplace<type_at_t<K>>(
1710 std::forward<Args>(args)...);
1713 template <
size_t K,
class U,
1714 class... Args variant_REQUIRES_T(
1715 std::is_constructible<type_at_t<K>, std::initializer_list<U>&,
1717 variant_alternative_t<K, variant>& emplace(std::initializer_list<U> il,
1719 return this->
template emplace<type_at_t<K>>(
1720 il, std::forward<Args>(args)...);
1727 bool valueless_by_exception()
const {
1728 return type_index == variant_npos_internal();
1733 void swap(variant& other)
1734#if variant_CPP11_OR_GREATER
1735 noexcept(std::is_nothrow_move_constructible<T0>::value &&
1736 std17::is_nothrow_swappable<T0>::value &&
1737 std::is_nothrow_move_constructible<T1>::value &&
1738 std17::is_nothrow_swappable<T1>::value &&
1739 std::is_nothrow_move_constructible<T2>::value &&
1740 std17::is_nothrow_swappable<T2>::value &&
1741 std::is_nothrow_move_constructible<T3>::value &&
1742 std17::is_nothrow_swappable<T3>::value &&
1743 std::is_nothrow_move_constructible<T4>::value &&
1744 std17::is_nothrow_swappable<T4>::value &&
1745 std::is_nothrow_move_constructible<T5>::value &&
1746 std17::is_nothrow_swappable<T5>::value &&
1747 std::is_nothrow_move_constructible<T6>::value &&
1748 std17::is_nothrow_swappable<T6>::value &&
1749 std::is_nothrow_move_constructible<T7>::value &&
1750 std17::is_nothrow_swappable<T7>::value &&
1751 std::is_nothrow_move_constructible<T8>::value &&
1752 std17::is_nothrow_swappable<T8>::value &&
1753 std::is_nothrow_move_constructible<T9>::value &&
1754 std17::is_nothrow_swappable<T9>::value &&
1755 std::is_nothrow_move_constructible<T10>::value &&
1756 std17::is_nothrow_swappable<T10>::value &&
1757 std::is_nothrow_move_constructible<T11>::value &&
1758 std17::is_nothrow_swappable<T11>::value &&
1759 std::is_nothrow_move_constructible<T12>::value &&
1760 std17::is_nothrow_swappable<T12>::value &&
1761 std::is_nothrow_move_constructible<T13>::value &&
1762 std17::is_nothrow_swappable<T13>::value &&
1763 std::is_nothrow_move_constructible<T14>::value &&
1764 std17::is_nothrow_swappable<T14>::value &&
1765 std::is_nothrow_move_constructible<T15>::value &&
1766 std17::is_nothrow_swappable<T15>::value
1771 if (valueless_by_exception() && other.valueless_by_exception()) {
1773 }
else if (type_index == other.type_index) {
1774 this->swap_value(type_index, other);
1776#if variant_CPP11_OR_GREATER
1777 variant tmp(std::move(*
this));
1778 *
this = std::move(other);
1779 other = std::move(tmp);
1793 static variant_constexpr std::size_t index_of() variant_noexcept {
1796 variant_types,
typename std11::remove_cv<T>::type>::value);
1799 template <
class T> T& get() {
1800#if variant_CONFIG_NO_EXCEPTIONS
1801 assert(index_of<T>() == index());
1803 if (index_of<T>() != index()) {
1804 throw bad_variant_access();
1810 template <
class T> T
const& get()
const {
1811#if variant_CONFIG_NO_EXCEPTIONS
1812 assert(index_of<T>() == index());
1814 if (index_of<T>() != index()) {
1815 throw bad_variant_access();
1818 return *as<const T>();
1821 template <std::
size_t K>
1823 return this->
template get<
1827 template <std::
size_t K>
1829 return this->
template get<
1834 typedef typename helper_type::type_index_t type_index_t;
1836 void* ptr() variant_noexcept {
return &data; }
1838 void const* ptr()
const variant_noexcept {
return &data; }
1840 template <
class U> U* as() {
return reinterpret_cast<U*
>(ptr()); }
1842 template <
class U> U
const* as()
const {
1843 return reinterpret_cast<U const*
>(ptr());
1846 template <
class U>
static variant_constexpr std::size_t to_size_t(U index) {
1847 return static_cast<std::size_t
>(index);
1850 variant_constexpr type_index_t
1851 variant_npos_internal()
const variant_noexcept {
1852 return static_cast<type_index_t
>(-1);
1855 variant& copy_assign(variant
const& other) {
1856 if (valueless_by_exception() && other.valueless_by_exception()) {
1858 }
else if (!valueless_by_exception() &&
1859 other.valueless_by_exception()) {
1860 helper_type::destroy(type_index, ptr());
1861 type_index = variant_npos_internal();
1862 }
else if (index() == other.index()) {
1864 helper_type::copy_assign(other.type_index, other.ptr(), ptr());
1866 helper_type::destroy(type_index, ptr());
1867 type_index = variant_npos_internal();
1868 type_index = helper_type::copy_construct(other.type_index,
1869 other.ptr(), ptr());
1874#if variant_CPP11_OR_GREATER
1876 variant& move_assign(variant&& other) {
1877 if (valueless_by_exception() && other.valueless_by_exception()) {
1879 }
else if (!valueless_by_exception() &&
1880 other.valueless_by_exception()) {
1881 helper_type::destroy(type_index, ptr());
1882 type_index = variant_npos_internal();
1883 }
else if (index() == other.index()) {
1885 helper_type::move_assign(other.type_index, other.ptr(), ptr());
1887 helper_type::destroy(type_index, ptr());
1888 type_index = variant_npos_internal();
1889 type_index = helper_type::move_construct(other.type_index,
1890 other.ptr(), ptr());
1895 template <std::
size_t K,
class T> variant& assign_value(T&& value) {
1897 *as<T>() = std::forward<T>(value);
1899 helper_type::destroy(type_index, ptr());
1900 type_index = variant_npos_internal();
1901 new (ptr()) T(std::forward<T>(value));
1909 template <std::
size_t K,
class T> variant& assign_value(T
const& value) {
1913 helper_type::destroy(type_index, ptr());
1914 type_index = variant_npos_internal();
1915 new (ptr()) T(value);
1921 void swap_value(type_index_t index, variant& other) {
1925 swap(this->get<0>(), other.get<0>());
1928 swap(this->get<1>(), other.get<1>());
1931 swap(this->get<2>(), other.get<2>());
1934 swap(this->get<3>(), other.get<3>());
1937 swap(this->get<4>(), other.get<4>());
1940 swap(this->get<5>(), other.get<5>());
1943 swap(this->get<6>(), other.get<6>());
1946 swap(this->get<7>(), other.get<7>());
1949 swap(this->get<8>(), other.get<8>());
1952 swap(this->get<9>(), other.get<9>());
1955 swap(this->get<10>(), other.get<10>());
1958 swap(this->get<11>(), other.get<11>());
1961 swap(this->get<12>(), other.get<12>());
1964 swap(this->get<13>(), other.get<13>());
1967 swap(this->get<14>(), other.get<14>());
1970 swap(this->get<15>(), other.get<15>());
1978#if variant_CPP11_OR_GREATER
1980 enum { data_align = detail::typelist_max_alignof<variant_types>::value };
1983 typename std::aligned_storage<data_size, data_align>::type;
1986#elif variant_CONFIG_MAX_ALIGN_HACK
1989 unsigned char data[data_size];
1992 detail::max_align_t hack;
1998 typedef variant_ALIGN_AS(max_type) align_as_type;
2001 align_as_type data[1 + (data_size - 1) /
sizeof(align_as_type)];
2009 type_index_t type_index;
2014template <
class T,
class T0,
class T1,
class T2,
class T3,
class T4,
class T5,
2015 class T6,
class T7,
class T8,
class T9,
class T10,
class T11,
2016 class T12,
class T13,
class T14,
class T15>
2018holds_alternative(
variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
2019 T13, T14, T15>
const& v) variant_noexcept {
2021 variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
2022 T14, T15>::template index_of<T>();
2025template <
class R,
class T0,
class T1,
class T2,
class T3,
class T4,
class T5,
2026 class T6,
class T7,
class T8,
class T9,
class T10,
class T11,
2027 class T12,
class T13,
class T14,
class T15>
2028inline R& get(
variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
2030 nonstd_lite_in_place_type_t(R) = nonstd_lite_in_place_type(R)) {
2031 return v.template get<R>();
2034template <
class R,
class T0,
class T1,
class T2,
class T3,
class T4,
class T5,
2035 class T6,
class T7,
class T8,
class T9,
class T10,
class T11,
2036 class T12,
class T13,
class T14,
class T15>
2038get(variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
2040 nonstd_lite_in_place_type_t(R) = nonstd_lite_in_place_type(R)) {
2041 return v.template get<R>();
2044template <std::size_t K,
class T0,
class T1,
class T2,
class T3,
class T4,
2045 class T5,
class T6,
class T7,
class T8,
class T9,
class T10,
2046 class T11,
class T12,
class T13,
class T14,
class T15>
2049 variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9,
2050 T10, T11, T12, T13, T14, T15>>::type&
2051 get(
variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
2053 nonstd_lite_in_place_index_t(K) = nonstd_lite_in_place_index(K)) {
2054#if variant_CONFIG_NO_EXCEPTIONS
2055 assert(K == v.index());
2057 if (K != v.index()) {
2058 throw bad_variant_access();
2061 return v.template get<K>();
2064template <std::size_t K,
class T0,
class T1,
class T2,
class T3,
class T4,
2065 class T5,
class T6,
class T7,
class T8,
class T9,
class T10,
2066 class T11,
class T12,
class T13,
class T14,
class T15>
2068 K,
variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
2070get(
variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
2072 nonstd_lite_in_place_index_t(K) = nonstd_lite_in_place_index(K)) {
2073#if variant_CONFIG_NO_EXCEPTIONS
2074 assert(K == v.index());
2076 if (K != v.index()) {
2077 throw bad_variant_access();
2080 return v.template get<K>();
2083#if variant_CPP11_OR_GREATER
2085template <
class R,
class T0,
class T1,
class T2,
class T3,
class T4,
class T5,
2086 class T6,
class T7,
class T8,
class T9,
class T10,
class T11,
2087 class T12,
class T13,
class T14,
class T15>
2088inline R&& get(
variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
2090 nonstd_lite_in_place_type_t(R) = nonstd_lite_in_place_type(R)) {
2091 return std::move(v.template get<R>());
2094template <
class R,
class T0,
class T1,
class T2,
class T3,
class T4,
class T5,
2095 class T6,
class T7,
class T8,
class T9,
class T10,
class T11,
2096 class T12,
class T13,
class T14,
class T15>
2098get(
variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
2100 nonstd_lite_in_place_type_t(R) = nonstd_lite_in_place_type(R)) {
2101 return std::move(v.template get<R>());
2104template <std::size_t K,
class T0,
class T1,
class T2,
class T3,
class T4,
2105 class T5,
class T6,
class T7,
class T8,
class T9,
class T10,
2106 class T11,
class T12,
class T13,
class T14,
class T15>
2109 variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9,
2110 T10, T11, T12, T13, T14, T15>>::type&&
2111 get(
variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
2113 nonstd_lite_in_place_index_t(K) = nonstd_lite_in_place_index(K)) {
2114#if variant_CONFIG_NO_EXCEPTIONS
2115 assert(K == v.index());
2117 if (K != v.index()) {
2118 throw bad_variant_access();
2121 return std::move(v.template get<K>());
2124template <std::size_t K,
class T0,
class T1,
class T2,
class T3,
class T4,
2125 class T5,
class T6,
class T7,
class T8,
class T9,
class T10,
2126 class T11,
class T12,
class T13,
class T14,
class T15>
2128 K,
variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
2130get(
variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
2132 nonstd_lite_in_place_index_t(K) = nonstd_lite_in_place_index(K)) {
2133#if variant_CONFIG_NO_EXCEPTIONS
2134 assert(K == v.index());
2136 if (K != v.index()) {
2137 throw bad_variant_access();
2140 return std::move(v.template get<K>());
2145template <
class T,
class T0,
class T1,
class T2,
class T3,
class T4,
class T5,
2146 class T6,
class T7,
class T8,
class T9,
class T10,
class T11,
2147 class T12,
class T13,
class T14,
class T15>
2148inline typename std11::add_pointer<T>::type
2149get_if(
variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
2151 nonstd_lite_in_place_type_t(T) = nonstd_lite_in_place_type(T)) {
2152 return (pv->index() ==
2153 variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
2154 T14, T15>::template index_of<T>())
2159template <
class T,
class T0,
class T1,
class T2,
class T3,
class T4,
class T5,
2160 class T6,
class T7,
class T8,
class T9,
class T10,
class T11,
2161 class T12,
class T13,
class T14,
class T15>
2162inline typename std11::add_pointer<const T>::type
2163get_if(
variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
2165 nonstd_lite_in_place_type_t(T) = nonstd_lite_in_place_type(T)) {
2166 return (pv->index() ==
2167 variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
2168 T14, T15>::template index_of<T>())
2173template <std::size_t K,
class T0,
class T1,
class T2,
class T3,
class T4,
2174 class T5,
class T6,
class T7,
class T8,
class T9,
class T10,
2175 class T11,
class T12,
class T13,
class T14,
class T15>
2177 K,
variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
2179get_if(
variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
2181 nonstd_lite_in_place_index_t(K) = nonstd_lite_in_place_index(K)) {
2182 return (pv->index() == K) ? &get<K>(*pv) : variant_nullptr;
2185template <std::size_t K,
class T0,
class T1,
class T2,
class T3,
class T4,
2186 class T5,
class T6,
class T7,
class T8,
class T9,
class T10,
2187 class T11,
class T12,
class T13,
class T14,
class T15>
2189 K,
variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
2191get_if(
variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
2193 nonstd_lite_in_place_index_t(K) = nonstd_lite_in_place_index(K)) {
2194 return (pv->index() == K) ? &get<K>(*pv) : variant_nullptr;
2200 class T0,
class T1,
class T2,
class T3,
class T4,
class T5,
class T6,
2201 class T7,
class T8,
class T9,
class T10,
class T11,
class T12,
class T13,
2204#if variant_CPP11_OR_GREATER
2206 std::is_move_constructible<T0>::value&& std17::is_swappable<
2207 T0>::value&& std::is_move_constructible<T1>::value&&
2208 std17::is_swappable<T1>::value&& std::is_move_constructible<
2209 T2>::value&& std17::is_swappable<T2>::value&&
2210 std::is_move_constructible<T3>::value&& std17::is_swappable<
2211 T3>::value&& std::is_move_constructible<T4>::value&&
std17::
2212 is_swappable<T4>::value&& std::is_move_constructible<
2213 T5>::value&& std17::is_swappable<T5>::value&& std::
2214 is_move_constructible<T6>::value&& std17::is_swappable<
2215 T6>::value&& std::is_move_constructible<T7>::value&&
2216 std17::is_swappable<T7>::value&& std::is_move_constructible<
2217 T8>::value&& std17::is_swappable<T8>::
2218 value&& std::is_move_constructible<
2219 T9>::value&& std17::is_swappable<T9>::
2220 value&& std::is_move_constructible<
2221 T10>::value&& std17::is_swappable<T10>::
2222 value&& std::is_move_constructible<
2223 T11>::value&& std17::is_swappable<T11>::
2224 value&& std::is_move_constructible<
2226 std17::is_swappable<
2228 is_move_constructible<
2230 std17::is_swappable<
2232 is_move_constructible<
2234 std17::is_swappable<
2236 std::is_move_constructible<
2238 std17::is_swappable<
2243inline void swap(
variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
2245 variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
2247#if variant_CPP11_OR_GREATER
2248 noexcept(
noexcept(a.swap(b)))
2261 template <
typename Visitor,
typename T>
2262 static R apply(Visitor
const& v, T
const& arg) {
2268 template <
typename Visitor,
typename T>
static R apply(Visitor
const&, T) {
2276template <
typename R,
typename Visitor,
typename V1>
struct VisitorUnwrapper;
2278#if variant_CPP11_OR_GREATER
2279template <
size_t NumVars,
typename R,
typename Visitor,
typename... T>
2281template <
size_t NumVars,
typename R,
typename Visitor,
typename T1,
2282 typename T2 =
S0,
typename T3 =
S0,
typename T4 =
S0,
2287template <
typename R,
typename Visitor,
typename T2>
2288struct TypedVisitorUnwrapper<2, R, Visitor, T2> {
2289 const Visitor& visitor;
2292 TypedVisitorUnwrapper(
const Visitor& visitor_, T2
const& val2_)
2293 : visitor(visitor_), val2(val2_)
2297 template <
typename T> R operator()(
const T& val1)
const {
2298 return visitor(val1, val2);
2302template <
typename R,
typename Visitor,
typename T2,
typename T3>
2303struct TypedVisitorUnwrapper<3, R, Visitor, T2, T3> {
2304 const Visitor& visitor;
2308 TypedVisitorUnwrapper(
const Visitor& visitor_, T2
const& val2_,
2310 : visitor(visitor_), val2(val2_), val3(val3_)
2314 template <
typename T> R operator()(
const T& val1)
const {
2315 return visitor(val1, val2, val3);
2319template <
typename R,
typename Visitor,
typename T2,
typename T3,
typename T4>
2320struct TypedVisitorUnwrapper<4, R, Visitor, T2, T3, T4> {
2321 const Visitor& visitor;
2326 TypedVisitorUnwrapper(
const Visitor& visitor_, T2
const& val2_,
2327 T3
const& val3_, T4
const& val4_)
2328 : visitor(visitor_), val2(val2_), val3(val3_), val4(val4_)
2332 template <
typename T> R operator()(
const T& val1)
const {
2333 return visitor(val1, val2, val3, val4);
2337template <
typename R,
typename Visitor,
typename T2,
typename T3,
typename T4,
2339struct TypedVisitorUnwrapper<5, R, Visitor, T2, T3, T4, T5> {
2340 const Visitor& visitor;
2346 TypedVisitorUnwrapper(
const Visitor& visitor_, T2
const& val2_,
2347 T3
const& val3_, T4
const& val4_, T5
const& val5_)
2348 : visitor(visitor_), val2(val2_), val3(val3_), val4(val4_), val5(val5_)
2352 template <
typename T> R operator()(
const T& val1)
const {
2353 return visitor(val1, val2, val3, val4, val5);
2357template <
typename R,
typename Visitor,
typename V2>
struct VisitorUnwrapper {
2358 const Visitor& visitor;
2361 VisitorUnwrapper(
const Visitor& visitor_,
const V2& r_)
2362 : visitor(visitor_), r(r_) {}
2364 template <
typename T1> R operator()(T1
const& val1)
const {
2366 return VisitorApplicator<R>::apply(visitor_type(visitor, val1), r);
2369 template <
typename T1,
typename T2>
2370 R operator()(T1
const& val1, T2
const& val2)
const {
2372 return VisitorApplicator<R>::apply(visitor_type(visitor, val1, val2),
2376 template <
typename T1,
typename T2,
typename T3>
2377 R operator()(T1
const& val1, T2
const& val2, T3
const& val3)
const {
2379 return VisitorApplicator<R>::apply(
2380 visitor_type(visitor, val1, val2, val3), r);
2383 template <
typename T1,
typename T2,
typename T3,
typename T4>
2384 R operator()(T1
const& val1, T2
const& val2, T3
const& val3,
2385 T4
const& val4)
const {
2388 return VisitorApplicator<R>::apply(
2389 visitor_type(visitor, val1, val2, val3, val4), r);
2392 template <
typename T1,
typename T2,
typename T3,
typename T4,
typename T5>
2393 R operator()(T1
const& val1, T2
const& val2, T3
const& val3, T4
const& val4,
2394 T5
const& val5)
const {
2397 return VisitorApplicator<R>::apply(
2398 visitor_type(visitor, val1, val2, val3, val4, val5), r);
2403 template <
typename Visitor,
typename V1>
2404 static R apply(
const Visitor& v,
const V1& arg) {
2405 switch (arg.index()) {
2407 return apply_visitor<0>(v, arg);
2409 return apply_visitor<1>(v, arg);
2411 return apply_visitor<2>(v, arg);
2413 return apply_visitor<3>(v, arg);
2415 return apply_visitor<4>(v, arg);
2417 return apply_visitor<5>(v, arg);
2419 return apply_visitor<6>(v, arg);
2421 return apply_visitor<7>(v, arg);
2423 return apply_visitor<8>(v, arg);
2425 return apply_visitor<9>(v, arg);
2427 return apply_visitor<10>(v, arg);
2429 return apply_visitor<11>(v, arg);
2431 return apply_visitor<12>(v, arg);
2433 return apply_visitor<13>(v, arg);
2435 return apply_visitor<14>(v, arg);
2437 return apply_visitor<15>(v, arg);
2445 template <
size_t Idx,
typename Visitor,
typename V1>
2446 static R apply_visitor(
const Visitor& v,
const V1& arg) {
2448#if variant_CPP11_OR_GREATER
2450 Idx,
typename std::decay<V1>::type>
::type value_type;
2454 return VisitorApplicatorImpl<R, value_type>::apply(v, get<Idx>(arg));
2457#if variant_CPP11_OR_GREATER
2458 template <
typename Visitor,
typename V1,
typename V2,
typename... V>
2459 static R apply(
const Visitor& v,
const V1& arg1,
const V2& arg2,
2462 Unwrapper unwrapper(v, arg1);
2463 return apply(unwrapper, arg2, args...);
2467 template <
typename Visitor,
typename V1,
typename V2>
2468 static R apply(
const Visitor& v, V1
const& arg1, V2
const& arg2) {
2470 Unwrapper unwrapper(v, arg1);
2471 return apply(unwrapper, arg2);
2474 template <
typename Visitor,
typename V1,
typename V2,
typename V3>
2475 static R apply(
const Visitor& v, V1
const& arg1, V2
const& arg2,
2478 Unwrapper unwrapper(v, arg1);
2479 return apply(unwrapper, arg2, arg3);
2482 template <
typename Visitor,
typename V1,
typename V2,
typename V3,
2484 static R apply(
const Visitor& v, V1
const& arg1, V2
const& arg2,
2485 V3
const& arg3, V4
const& arg4) {
2487 Unwrapper unwrapper(v, arg1);
2488 return apply(unwrapper, arg2, arg3, arg4);
2491 template <
typename Visitor,
typename V1,
typename V2,
typename V3,
2492 typename V4,
typename V5>
2493 static R apply(
const Visitor& v, V1
const& arg1, V2
const& arg2,
2494 V3
const& arg3, V4
const& arg4, V5
const& arg5) {
2496 Unwrapper unwrapper(v, arg1);
2497 return apply(unwrapper, arg2, arg3, arg4, arg5);
2503#if variant_CPP11_OR_GREATER
2504template <
size_t NumVars,
typename Visitor,
typename... V>
struct VisitorImpl {
2505 typedef decltype(std::declval<Visitor>()(
2506 get<0>(
static_cast<const V&
>(std::declval<V>()))...)) result_type;
2512#if variant_CPP11_OR_GREATER
2514template <
typename Visitor,
typename... V>
2515inline auto visit(Visitor
const& v, V
const&... vars) ->
2516 typename detail::VisitorImpl<
sizeof...(V), Visitor, V...>::result_type {
2517 typedef detail::VisitorImpl<
sizeof...(V), Visitor, V...> impl_type;
2518 return impl_type::applicator_type::apply(v, vars...);
2522template <
typename R,
typename Visitor,
typename V1>
2523inline R visit(
const Visitor& v, V1
const& arg1) {
2524 return detail::VisitorApplicator<R>::apply(v, arg1);
2527template <
typename R,
typename Visitor,
typename V1,
typename V2>
2528inline R visit(
const Visitor& v, V1
const& arg1, V2
const& arg2) {
2529 return detail::VisitorApplicator<R>::apply(v, arg1, arg2);
2532template <
typename R,
typename Visitor,
typename V1,
typename V2,
typename V3>
2533inline R visit(
const Visitor& v, V1
const& arg1, V2
const& arg2,
2535 return detail::VisitorApplicator<R>::apply(v, arg1, arg2, arg3);
2538template <
typename R,
typename Visitor,
typename V1,
typename V2,
typename V3,
2540inline R visit(
const Visitor& v, V1
const& arg1, V2
const& arg2, V3
const& arg3,
2542 return detail::VisitorApplicator<R>::apply(v, arg1, arg2, arg3, arg4);
2545template <
typename R,
typename Visitor,
typename V1,
typename V2,
typename V3,
2546 typename V4,
typename V5>
2547inline R visit(
const Visitor& v, V1
const& arg1, V2
const& arg2, V3
const& arg3,
2548 V4
const& arg4, V5
const& arg5) {
2549 return detail::VisitorApplicator<R>::apply(v, arg1, arg2, arg3, arg4, arg5);
2559 static inline bool equal(Variant
const& v, Variant
const& w) {
2560 switch (v.index()) {
2562 return get<0>(v) == get<0>(w);
2564 return get<1>(v) == get<1>(w);
2566 return get<2>(v) == get<2>(w);
2568 return get<3>(v) == get<3>(w);
2570 return get<4>(v) == get<4>(w);
2572 return get<5>(v) == get<5>(w);
2574 return get<6>(v) == get<6>(w);
2576 return get<7>(v) == get<7>(w);
2578 return get<8>(v) == get<8>(w);
2580 return get<9>(v) == get<9>(w);
2582 return get<10>(v) == get<10>(w);
2584 return get<11>(v) == get<11>(w);
2586 return get<12>(v) == get<12>(w);
2588 return get<13>(v) == get<13>(w);
2590 return get<14>(v) == get<14>(w);
2592 return get<15>(v) == get<15>(w);
2599 static inline bool less_than(Variant
const& v, Variant
const& w) {
2600 switch (v.index()) {
2602 return get<0>(v) < get<0>(w);
2604 return get<1>(v) < get<1>(w);
2606 return get<2>(v) < get<2>(w);
2608 return get<3>(v) < get<3>(w);
2610 return get<4>(v) < get<4>(w);
2612 return get<5>(v) < get<5>(w);
2614 return get<6>(v) < get<6>(w);
2616 return get<7>(v) < get<7>(w);
2618 return get<8>(v) < get<8>(w);
2620 return get<9>(v) < get<9>(w);
2622 return get<10>(v) < get<10>(w);
2624 return get<11>(v) < get<11>(w);
2626 return get<12>(v) < get<12>(w);
2628 return get<13>(v) < get<13>(w);
2630 return get<14>(v) < get<14>(w);
2632 return get<15>(v) < get<15>(w);
2642template <
class T0,
class T1,
class T2,
class T3,
class T4,
class T5,
class T6,
2643 class T7,
class T8,
class T9,
class T10,
class T11,
class T12,
2644 class T13,
class T14,
class T15>
2645inline bool operator==(
variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
2646 T12, T13, T14, T15>
const& v,
2647 variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
2648 T12, T13, T14, T15>
const& w) {
2649 if (v.index() != w.index())
2651 else if (v.valueless_by_exception())
2655 variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
2656 T14, T15>>::equal(v, w);
2659template <
class T0,
class T1,
class T2,
class T3,
class T4,
class T5,
class T6,
2660 class T7,
class T8,
class T9,
class T10,
class T11,
class T12,
2661 class T13,
class T14,
class T15>
2662inline bool operator!=(
variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
2663 T12, T13, T14, T15>
const& v,
2664 variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
2665 T12, T13, T14, T15>
const& w) {
2669template <
class T0,
class T1,
class T2,
class T3,
class T4,
class T5,
class T6,
2670 class T7,
class T8,
class T9,
class T10,
class T11,
class T12,
2671 class T13,
class T14,
class T15>
2672inline bool operator<(variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
2673 T12, T13, T14, T15>
const& v,
2674 variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
2675 T12, T13, T14, T15>
const& w) {
2676 if (w.valueless_by_exception())
2678 else if (v.valueless_by_exception())
2680 else if (v.index() < w.index())
2682 else if (v.index() > w.index())
2685 return detail::Comparator<
2686 variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
2687 T14, T15>>::less_than(v, w);
2690template <
class T0,
class T1,
class T2,
class T3,
class T4,
class T5,
class T6,
2691 class T7,
class T8,
class T9,
class T10,
class T11,
class T12,
2692 class T13,
class T14,
class T15>
2693inline bool operator>(
variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
2694 T12, T13, T14, T15>
const& v,
2695 variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
2696 T12, T13, T14, T15>
const& w) {
2700template <
class T0,
class T1,
class T2,
class T3,
class T4,
class T5,
class T6,
2701 class T7,
class T8,
class T9,
class T10,
class T11,
class T12,
2702 class T13,
class T14,
class T15>
2703inline bool operator<=(
variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
2704 T12, T13, T14, T15>
const& v,
2705 variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
2706 T12, T13, T14, T15>
const& w) {
2710template <
class T0,
class T1,
class T2,
class T3,
class T4,
class T5,
class T6,
2711 class T7,
class T8,
class T9,
class T10,
class T11,
class T12,
2712 class T13,
class T14,
class T15>
2713inline bool operator>=(
variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
2714 T12, T13, T14, T15>
const& v,
2715 variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
2716 T12, T13, T14, T15>
const& w) {
2722using namespace variants;
2726#if variant_CPP11_OR_GREATER
2732template <>
struct hash<nonstd::monostate> {
2733 std::size_t operator()(nonstd::monostate)
const variant_noexcept {
2738template <
class T0,
class T1,
class T2,
class T3,
class T4,
class T5,
class T6,
2739 class T7,
class T8,
class T9,
class T10,
class T11,
class T12,
2740 class T13,
class T14,
class T15>
2741struct hash<nonstd::variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
2742 T12, T13, T14, T15>> {
2743 std::size_t operator()(
2744 nonstd::variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
2745 T13, T14, T15>
const& v)
const variant_noexcept {
2746 namespace nvd = nonstd::variants::detail;
2748 switch (v.index()) {
2750 return nvd::hash(0) ^ nvd::hash(get<0>(v));
2752 return nvd::hash(1) ^ nvd::hash(get<1>(v));
2754 return nvd::hash(2) ^ nvd::hash(get<2>(v));
2756 return nvd::hash(3) ^ nvd::hash(get<3>(v));
2758 return nvd::hash(4) ^ nvd::hash(get<4>(v));
2760 return nvd::hash(5) ^ nvd::hash(get<5>(v));
2762 return nvd::hash(6) ^ nvd::hash(get<6>(v));
2764 return nvd::hash(7) ^ nvd::hash(get<7>(v));
2766 return nvd::hash(8) ^ nvd::hash(get<8>(v));
2768 return nvd::hash(9) ^ nvd::hash(get<9>(v));
2770 return nvd::hash(10) ^ nvd::hash(get<10>(v));
2772 return nvd::hash(11) ^ nvd::hash(get<11>(v));
2774 return nvd::hash(12) ^ nvd::hash(get<12>(v));
2776 return nvd::hash(13) ^ nvd::hash(get<13>(v));
2778 return nvd::hash(14) ^ nvd::hash(get<14>(v));
2780 return nvd::hash(15) ^ nvd::hash(get<15>(v));
2792#if variant_BETWEEN(variant_COMPILER_MSVC_VER, 1300, 1900)
2810#ifndef NONSTD_OPTIONAL_LITE_HPP
2811#define NONSTD_OPTIONAL_LITE_HPP
2813#define optional_lite_MAJOR 3
2814#define optional_lite_MINOR 2
2815#define optional_lite_PATCH 0
2817#define optional_lite_VERSION \
2818 optional_STRINGIFY(optional_lite_MAJOR) "." optional_STRINGIFY( \
2819 optional_lite_MINOR) "." optional_STRINGIFY(optional_lite_PATCH)
2821#define optional_STRINGIFY(x) optional_STRINGIFY_(x)
2822#define optional_STRINGIFY_(x) #x
2826#define optional_OPTIONAL_DEFAULT 0
2827#define optional_OPTIONAL_NONSTD 1
2828#define optional_OPTIONAL_STD 2
2830#if !defined(optional_CONFIG_SELECT_OPTIONAL)
2831#define optional_CONFIG_SELECT_OPTIONAL \
2832 (optional_HAVE_STD_OPTIONAL ? optional_OPTIONAL_STD \
2833 : optional_OPTIONAL_NONSTD)
2838#ifndef optional_CONFIG_NO_EXCEPTIONS
2839#if defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)
2840#define optional_CONFIG_NO_EXCEPTIONS 0
2842#define optional_CONFIG_NO_EXCEPTIONS 1
2849#ifndef optional_CPLUSPLUS
2850#if defined(_MSVC_LANG) && !defined(__clang__)
2851#define optional_CPLUSPLUS (_MSC_VER == 1900 ? 201103L : _MSVC_LANG)
2853#define optional_CPLUSPLUS __cplusplus
2857#define optional_CPP98_OR_GREATER (optional_CPLUSPLUS >= 199711L)
2858#define optional_CPP11_OR_GREATER (optional_CPLUSPLUS >= 201103L)
2859#define optional_CPP11_OR_GREATER_ (optional_CPLUSPLUS >= 201103L)
2860#define optional_CPP14_OR_GREATER (optional_CPLUSPLUS >= 201402L)
2861#define optional_CPP17_OR_GREATER (optional_CPLUSPLUS >= 201703L)
2862#define optional_CPP20_OR_GREATER (optional_CPLUSPLUS >= 202000L)
2866#define optional_CPLUSPLUS_V \
2867 (optional_CPLUSPLUS / 100 - (optional_CPLUSPLUS > 200000 ? 2000 : 1994))
2871#if optional_CPP17_OR_GREATER && defined(__has_include)
2872#if __has_include(<optional> )
2873#define optional_HAVE_STD_OPTIONAL 1
2875#define optional_HAVE_STD_OPTIONAL 0
2878#define optional_HAVE_STD_OPTIONAL 0
2881#define optional_USES_STD_OPTIONAL \
2882 ((optional_CONFIG_SELECT_OPTIONAL == optional_OPTIONAL_STD) || \
2883 ((optional_CONFIG_SELECT_OPTIONAL == optional_OPTIONAL_DEFAULT) && \
2884 optional_HAVE_STD_OPTIONAL))
2891#ifndef nonstd_lite_HAVE_IN_PLACE_TYPES
2892#define nonstd_lite_HAVE_IN_PLACE_TYPES 1
2896#if optional_CPP17_OR_GREATER
2903using std::in_place_index;
2904using std::in_place_index_t;
2905using std::in_place_t;
2906using std::in_place_type;
2907using std::in_place_type_t;
2909#define nonstd_lite_in_place_t(T) std::in_place_t
2910#define nonstd_lite_in_place_type_t(T) std::in_place_type_t<T>
2911#define nonstd_lite_in_place_index_t(K) std::in_place_index_t<K>
2913#define nonstd_lite_in_place(T) \
2915#define nonstd_lite_in_place_type(T) \
2916 std::in_place_type_t<T> {}
2917#define nonstd_lite_in_place_index(K) \
2918 std::in_place_index_t<K> {}
2943template <std::
size_t K>
2955template <std::
size_t K>
2963#define nonstd_lite_in_place_t(T) \
2964 nonstd::in_place_t (&)(nonstd::detail::in_place_type_tag<T>)
2965#define nonstd_lite_in_place_type_t(T) \
2966 nonstd::in_place_t (&)(nonstd::detail::in_place_type_tag<T>)
2967#define nonstd_lite_in_place_index_t(K) \
2968 nonstd::in_place_t (&)(nonstd::detail::in_place_index_tag<K>)
2970#define nonstd_lite_in_place(T) nonstd::in_place_type<T>
2971#define nonstd_lite_in_place_type(T) nonstd::in_place_type<T>
2972#define nonstd_lite_in_place_index(K) nonstd::in_place_index<K>
2983#if optional_USES_STD_OPTIONAL
2989using std::bad_optional_access;
2994using std::nullopt_t;
2996using std::operator==;
2997using std::operator!=;
2998using std::operator<;
2999using std::operator<=;
3000using std::operator>;
3001using std::operator>=;
3002using std::make_optional;
3013#ifndef optional_CONFIG_MAX_ALIGN_HACK
3014#define optional_CONFIG_MAX_ALIGN_HACK 0
3017#ifndef optional_CONFIG_ALIGN_AS
3021#ifndef optional_CONFIG_ALIGN_AS_FALLBACK
3022#define optional_CONFIG_ALIGN_AS_FALLBACK double
3027#if defined(__clang__)
3028#pragma clang diagnostic push
3029#pragma clang diagnostic ignored "-Wundef"
3030#elif defined(__GNUC__)
3031#pragma GCC diagnostic push
3032#pragma GCC diagnostic ignored "-Wundef"
3033#elif defined(_MSC_VER)
3034#pragma warning(push)
3038#define optional_BETWEEN(v, lo, hi) ((lo) <= (v) && (v) < (hi))
3057#if defined(_MSC_VER) && !defined(__clang__)
3058#define optional_COMPILER_MSVC_VER (_MSC_VER)
3059#define optional_COMPILER_MSVC_VERSION \
3060 (_MSC_VER / 10 - 10 * (5 + (_MSC_VER < 1900)))
3062#define optional_COMPILER_MSVC_VER 0
3063#define optional_COMPILER_MSVC_VERSION 0
3066#define optional_COMPILER_VERSION(major, minor, patch) \
3067 (10 * (10 * (major) + (minor)) + (patch))
3069#if defined(__GNUC__) && !defined(__clang__)
3070#define optional_COMPILER_GNUC_VERSION \
3071 optional_COMPILER_VERSION(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
3073#define optional_COMPILER_GNUC_VERSION 0
3076#if defined(__clang__)
3077#define optional_COMPILER_CLANG_VERSION \
3078 optional_COMPILER_VERSION(__clang_major__, __clang_minor__, \
3079 __clang_patchlevel__)
3081#define optional_COMPILER_CLANG_VERSION 0
3084#if optional_BETWEEN(optional_COMPILER_MSVC_VERSION, 70, 140)
3085#pragma warning(disable : 4345)
3088#if optional_BETWEEN(optional_COMPILER_MSVC_VERSION, 70, 150)
3089#pragma warning(disable : 4814)
3094#define optional_HAVE(FEATURE) (optional_HAVE_##FEATURE)
3097#define optional_HAS_CPP0X _HAS_CPP0X
3099#define optional_HAS_CPP0X 0
3104#if optional_COMPILER_MSVC_VER >= 1900
3105#undef optional_CPP11_OR_GREATER
3106#define optional_CPP11_OR_GREATER 1
3109#define optional_CPP11_90 \
3110 (optional_CPP11_OR_GREATER_ || optional_COMPILER_MSVC_VER >= 1500)
3111#define optional_CPP11_100 \
3112 (optional_CPP11_OR_GREATER_ || optional_COMPILER_MSVC_VER >= 1600)
3113#define optional_CPP11_110 \
3114 (optional_CPP11_OR_GREATER_ || optional_COMPILER_MSVC_VER >= 1700)
3115#define optional_CPP11_120 \
3116 (optional_CPP11_OR_GREATER_ || optional_COMPILER_MSVC_VER >= 1800)
3117#define optional_CPP11_140 \
3118 (optional_CPP11_OR_GREATER_ || optional_COMPILER_MSVC_VER >= 1900)
3119#define optional_CPP11_141 \
3120 (optional_CPP11_OR_GREATER_ || optional_COMPILER_MSVC_VER >= 1910)
3122#define optional_CPP11_140_490 \
3123 ((optional_CPP11_OR_GREATER_ && optional_COMPILER_GNUC_VERSION >= 490) || \
3124 (optional_COMPILER_MSVC_VER >= 1910))
3126#define optional_CPP14_000 (optional_CPP14_OR_GREATER)
3127#define optional_CPP17_000 (optional_CPP17_OR_GREATER)
3131#define optional_HAVE_CONSTEXPR_11 optional_CPP11_140
3132#define optional_HAVE_IS_DEFAULT optional_CPP11_140
3133#define optional_HAVE_NOEXCEPT optional_CPP11_140
3134#define optional_HAVE_NULLPTR optional_CPP11_100
3135#define optional_HAVE_REF_QUALIFIER optional_CPP11_140_490
3136#define optional_HAVE_INITIALIZER_LIST optional_CPP11_140
3140#define optional_HAVE_CONSTEXPR_14 optional_CPP14_000
3144#define optional_HAVE_NODISCARD optional_CPP17_000
3148#define optional_HAVE_CONDITIONAL optional_CPP11_120
3149#define optional_HAVE_REMOVE_CV optional_CPP11_120
3150#define optional_HAVE_TYPE_TRAITS optional_CPP11_90
3152#define optional_HAVE_TR1_TYPE_TRAITS (!!optional_COMPILER_GNUC_VERSION)
3153#define optional_HAVE_TR1_ADD_POINTER (!!optional_COMPILER_GNUC_VERSION)
3157#if optional_HAVE(CONSTEXPR_11)
3158#define optional_constexpr constexpr
3160#define optional_constexpr
3163#if optional_HAVE(IS_DEFAULT)
3164#define optional_is_default = default;
3166#define optional_is_default \
3171#if optional_HAVE(CONSTEXPR_14)
3172#define optional_constexpr14 constexpr
3174#define optional_constexpr14
3177#if optional_HAVE(NODISCARD)
3178#define optional_nodiscard [[nodiscard]]
3180#define optional_nodiscard
3183#if optional_HAVE(NOEXCEPT)
3184#define optional_noexcept noexcept
3186#define optional_noexcept
3189#if optional_HAVE(NULLPTR)
3190#define optional_nullptr nullptr
3192#define optional_nullptr NULL
3195#if optional_HAVE(REF_QUALIFIER)
3197#define optional_ref_qual &
3198#define optional_refref_qual &&
3200#define optional_ref_qual
3201#define optional_refref_qual
3206#if optional_CONFIG_NO_EXCEPTIONS
3212#if optional_CPP11_OR_GREATER
3213#include <functional>
3216#if optional_HAVE(INITIALIZER_LIST)
3217#include <initializer_list>
3220#if optional_HAVE(TYPE_TRAITS)
3221#include <type_traits>
3222#elif optional_HAVE(TR1_TYPE_TRAITS)
3223#include <tr1/type_traits>
3228#if optional_CPP11_OR_GREATER
3230#define optional_REQUIRES_0(...) \
3231 template <bool B = (__VA_ARGS__), typename std::enable_if<B, int>::type = 0>
3233#define optional_REQUIRES_T(...) \
3234 , typename std::enable_if<(__VA_ARGS__), int>::type = 0
3236#define optional_REQUIRES_R(R, ...) \
3237 typename std::enable_if<(__VA_ARGS__), R>::type
3239#define optional_REQUIRES_A(...) \
3240 , typename std::enable_if<(__VA_ARGS__), void*>::type = nullptr
3249namespace optional_lite {
3253#if optional_CPP11_OR_GREATER
3256template <
typename T> T& move(T& t) {
3261#if optional_HAVE(CONDITIONAL)
3262using std::conditional;
3264template <
bool B,
typename T,
typename F>
struct conditional {
3267template <
typename T,
typename F>
struct conditional<false, T, F> {
3273#if optional_CPP11_OR_GREATER
3274#if optional_BETWEEN(optional_COMPILER_GNUC_VERSION, 1, 500)
3275template <
typename T>
3276struct is_trivially_copy_constructible : std::true_type {};
3277template <
typename T>
3278struct is_trivially_move_constructible : std::true_type {};
3280using std::is_trivially_copy_constructible;
3281using std::is_trivially_move_constructible;
3286#if optional_CPP11_OR_GREATER
3292#if optional_CPP17_OR_GREATER
3294using std::is_nothrow_swappable;
3295using std::is_swappable;
3297#elif optional_CPP11_OR_GREATER
3303struct is_swappable {
3304 template <
typename T,
3305 typename =
decltype(swap(std::declval<T&>(), std::declval<T&>()))>
3306 static std::true_type test(
int );
3308 template <
typename>
static std::false_type test(...);
3311struct is_nothrow_swappable {
3315 template <
typename T>
static constexpr bool satisfies() {
3316 return noexcept(swap(std::declval<T&>(), std::declval<T&>()));
3319 template <
typename T>
3320 static auto test(
int )
3321 -> std::integral_constant<bool, satisfies<T>()> {}
3323 template <
typename>
static auto test(...) -> std::false_type;
3330template <
typename T>
3331struct is_swappable : decltype(detail::is_swappable::test<T>(0)) {};
3333template <
typename T>
3334struct is_nothrow_swappable
3335 : decltype(detail::is_nothrow_swappable::test<T>(0)) {};
3345template <
typename T>
struct remove_cvref {
3347 typename std::remove_cv<typename std::remove_reference<T>::type>::type
3357template <
typename T>
class optional;
3365template <
typename Head,
typename Tail>
struct typelist {
3370#if optional_CONFIG_MAX_ALIGN_HACK
3374#define optional_UNIQUE(name) optional_UNIQUE2(name, __LINE__)
3375#define optional_UNIQUE2(name, line) optional_UNIQUE3(name, line)
3376#define optional_UNIQUE3(name, line) name##line
3378#define optional_ALIGN_TYPE(type) \
3379 type optional_UNIQUE(_t); \
3380 struct_t<type> optional_UNIQUE(_st)
3382template <
typename T>
struct struct_t {
3387 optional_ALIGN_TYPE(
char);
3388 optional_ALIGN_TYPE(
short int);
3389 optional_ALIGN_TYPE(
int);
3390 optional_ALIGN_TYPE(
long int);
3391 optional_ALIGN_TYPE(
float);
3392 optional_ALIGN_TYPE(
double);
3393 optional_ALIGN_TYPE(
long double);
3394 optional_ALIGN_TYPE(
char*);
3395 optional_ALIGN_TYPE(
short int*);
3396 optional_ALIGN_TYPE(
int*);
3397 optional_ALIGN_TYPE(
long int*);
3398 optional_ALIGN_TYPE(
float*);
3399 optional_ALIGN_TYPE(
double*);
3400 optional_ALIGN_TYPE(
long double*);
3401 optional_ALIGN_TYPE(
void*);
3403#ifdef HAVE_LONG_LONG
3404 optional_ALIGN_TYPE(
long long);
3409 Unknown (*optional_UNIQUE(_))(Unknown);
3410 Unknown* Unknown::* optional_UNIQUE(_);
3411 Unknown (Unknown::* optional_UNIQUE(_))(Unknown);
3413 struct_t<Unknown (*)(Unknown)> optional_UNIQUE(_);
3414 struct_t<Unknown * Unknown::*> optional_UNIQUE(_);
3415 struct_t<Unknown (Unknown::*)(Unknown)> optional_UNIQUE(_);
3418#undef optional_UNIQUE
3419#undef optional_UNIQUE2
3420#undef optional_UNIQUE3
3422#undef optional_ALIGN_TYPE
3424#elif defined(optional_CONFIG_ALIGN_AS)
3428#define optional_ALIGN_AS(unused) optional_CONFIG_ALIGN_AS
3434#define optional_ALIGN_AS(to_align) \
3435 typename type_of_size<alignment_types, alignment_of<to_align>::value>::type
3437template <
typename T>
struct alignment_of;
3439template <
typename T>
struct alignment_of_hack {
3442 alignment_of_hack();
3445template <
size_t A,
size_t S>
struct alignment_logic {
3446 enum { value = A < S ? A : S };
3449template <
typename T>
struct alignment_of {
3451 value = alignment_logic<
sizeof(alignment_of_hack<T>) -
sizeof(T),
3456template <
typename List,
size_t N>
struct type_of_size {
3457 typedef typename std11::conditional<
3458 N ==
sizeof(
typename List::head),
typename List::head,
3459 typename type_of_size<typename List::tail, N>::type>::type type;
3462template <
size_t N>
struct type_of_size<nulltype, N> {
3463 typedef optional_CONFIG_ALIGN_AS_FALLBACK type;
3466template <
typename T>
struct struct_t {
3470#define optional_ALIGN_TYPE(type) typelist < type, typelist < struct_t<type>
3474typedef optional_ALIGN_TYPE(
char), optional_ALIGN_TYPE(
short),
3475 optional_ALIGN_TYPE(
int), optional_ALIGN_TYPE(
long),
3476 optional_ALIGN_TYPE(
float), optional_ALIGN_TYPE(
double),
3477 optional_ALIGN_TYPE(
long double),
3479 optional_ALIGN_TYPE(
char*), optional_ALIGN_TYPE(
short*),
3480 optional_ALIGN_TYPE(
int*), optional_ALIGN_TYPE(
long*),
3481 optional_ALIGN_TYPE(
float*), optional_ALIGN_TYPE(
double*),
3482 optional_ALIGN_TYPE(
long double*),
3484 optional_ALIGN_TYPE(Unknown (*)(Unknown)),
3485 optional_ALIGN_TYPE(Unknown* Unknown::*),
3486 optional_ALIGN_TYPE(Unknown (Unknown::*)(Unknown)),
3488 nulltype >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> alignment_types;
3490#undef optional_ALIGN_TYPE
3496template <
typename T>
union storage_t {
3500 typedef T value_type;
3502 storage_t() optional_is_default
3504 explicit storage_t(value_type const& v) {
3508 void construct_value(value_type
const& v) {
3509 ::new (value_ptr()) value_type(v);
3512#if optional_CPP11_OR_GREATER
3514 explicit storage_t(value_type&& v) { construct_value(std::move(v)); }
3516 void construct_value(value_type&& v) {
3517 ::new (value_ptr()) value_type(std::move(v));
3520 template <class... Args>
void emplace(Args&&... args) {
3521 ::new (value_ptr()) value_type(std::forward<Args>(args)...);
3524 template <class U, class... Args>
3525 void emplace(std::initializer_list<U> il, Args&&... args) {
3526 ::new (value_ptr()) value_type(il, std::forward<Args>(args)...);
3531 void destruct_value() { value_ptr()->~T(); }
3533 optional_nodiscard value_type
const* value_ptr()
const {
3534 return as<value_type>();
3537 value_type* value_ptr() {
return as<value_type>(); }
3539 optional_nodiscard value_type
const& value() const optional_ref_qual {
3540 return *value_ptr();
3543 value_type& value() optional_ref_qual {
return *value_ptr(); }
3545#if optional_HAVE(REF_QUALIFIER)
3547 optional_nodiscard value_type
const&& value() const optional_refref_qual {
3548 return std::move(value());
3551 value_type&& value() optional_refref_qual {
return std::move(value()); }
3555#if optional_CPP11_OR_GREATER
3557 using aligned_storage_t =
3558 typename std::aligned_storage<
sizeof(value_type),
3559 alignof(value_type)>::type;
3560 aligned_storage_t data;
3562#elif optional_CONFIG_MAX_ALIGN_HACK
3565 unsigned char data[
sizeof(value_type)];
3566 } aligned_storage_t;
3569 aligned_storage_t data;
3572 typedef optional_ALIGN_AS(value_type) align_as_type;
3576 data[1 + (
sizeof(value_type) - 1) /
sizeof(align_as_type)];
3577 } aligned_storage_t;
3578 aligned_storage_t data;
3580#undef optional_ALIGN_AS
3584 optional_nodiscard
void* ptr() optional_noexcept {
return &data; }
3586 optional_nodiscard
void const* ptr() const optional_noexcept {
3590 template <
typename U> optional_nodiscard U* as() {
3591 return reinterpret_cast<U*
>(ptr());
3594 template <
typename U> optional_nodiscard U
const* as()
const {
3595 return reinterpret_cast<U const*
>(ptr());
3605 explicit optional_constexpr nullopt_t(init ) optional_noexcept {}
3608#if optional_HAVE(CONSTEXPR_11)
3609constexpr nullopt_t nullopt{nullopt_t::init{}};
3612const nullopt_t nullopt((nullopt_t::init()));
3617#if !optional_CONFIG_NO_EXCEPTIONS
3619class bad_optional_access :
public std::logic_error {
3621 explicit bad_optional_access() : logic_error(
"bad optional access") {}
3628template <
typename T>
class optional {
3630 template <
typename>
friend class optional;
3632 typedef void (optional::*safe_bool)()
const;
3635 typedef T value_type;
3640 optional_constexpr optional() optional_noexcept : has_value_(false),
3645 optional_constexpr optional(nullopt_t ) optional_noexcept
3646 : has_value_(
false),
3650#if optional_CPP11_OR_GREATER
3658 optional_constexpr14 optional(optional
const& other)
3659 : has_value_(other.has_value()) {
3660 if (other.has_value()) {
3661 contained.construct_value(other.contained.value());
3665#if optional_CPP11_OR_GREATER
3668 template <
typename U = T optional_REQUIRES_T(
3669 std::is_move_constructible<U>::value ||
3670 std11::is_trivially_move_constructible<U>::value)>
3671 optional_constexpr14 optional(optional&& other)
3673 noexcept(std::is_nothrow_move_constructible<T>::value)
3674 : has_value_(other.has_value()) {
3675 if (other.has_value()) {
3676 contained.construct_value(std::move(other.contained.value()));
3681 template <
typename U optional_REQUIRES_T(
3682 std::is_constructible<T, U const&>::value &&
3683 !std::is_constructible<T, optional<U>&>::value &&
3684 !std::is_constructible<T, optional<U>&&>::value &&
3685 !std::is_constructible<T, optional<U>
const&>::value &&
3686 !std::is_constructible<T, optional<U>
const&&>::value &&
3687 !std::is_convertible<optional<U>&, T>::value &&
3688 !std::is_convertible<optional<U>&&, T>::value &&
3689 !std::is_convertible<optional<U>
const&, T>::value &&
3690 !std::is_convertible<optional<U>
const&&, T>::value &&
3691 !std::is_convertible<U const&, T>::value
3694 explicit optional(optional<U>
const& other)
3695 : has_value_(other.has_value()) {
3696 if (other.has_value()) {
3697 contained.construct_value(T{other.contained.value()});
3704 template <
typename U
3705#if optional_CPP11_OR_GREATER
3706 optional_REQUIRES_T(
3707 std::is_constructible<T, U const&>::value &&
3708 !std::is_constructible<T, optional<U>&>::value &&
3709 !std::is_constructible<T, optional<U>&&>::value &&
3710 !std::is_constructible<T, optional<U>
const&>::value &&
3711 !std::is_constructible<T, optional<U>
const&&>::value &&
3712 !std::is_convertible<optional<U>&, T>::value &&
3713 !std::is_convertible<optional<U>&&, T>::value &&
3714 !std::is_convertible<optional<U>
const&, T>::value &&
3715 !std::is_convertible<optional<U>
const&&, T>::value &&
3716 std::is_convertible<U const&, T>::value
3722 optional(optional<U>
const& other)
3723 : has_value_(other.has_value()) {
3724 if (other.has_value()) {
3725 contained.construct_value(other.contained.value());
3729#if optional_CPP11_OR_GREATER
3732 template <
typename U optional_REQUIRES_T(
3733 std::is_constructible<T, U&&>::value &&
3734 !std::is_constructible<T, optional<U>&>::value &&
3735 !std::is_constructible<T, optional<U>&&>::value &&
3736 !std::is_constructible<T, optional<U>
const&>::value &&
3737 !std::is_constructible<T, optional<U>
const&&>::value &&
3738 !std::is_convertible<optional<U>&, T>::value &&
3739 !std::is_convertible<optional<U>&&, T>::value &&
3740 !std::is_convertible<optional<U>
const&, T>::value &&
3741 !std::is_convertible<optional<U>
const&&, T>::value &&
3742 !std::is_convertible<U&&, T>::value
3744 explicit optional(optional<U>&& other) : has_value_(other.has_value()) {
3745 if (other.has_value()) {
3746 contained.construct_value(T{std::move(other.contained.value())});
3751 template <
typename U optional_REQUIRES_T(
3752 std::is_constructible<T, U&&>::value &&
3753 !std::is_constructible<T, optional<U>&>::value &&
3754 !std::is_constructible<T, optional<U>&&>::value &&
3755 !std::is_constructible<T, optional<U>
const&>::value &&
3756 !std::is_constructible<T, optional<U>
const&&>::value &&
3757 !std::is_convertible<optional<U>&, T>::value &&
3758 !std::is_convertible<optional<U>&&, T>::value &&
3759 !std::is_convertible<optional<U>
const&, T>::value &&
3760 !std::is_convertible<optional<U>
const&&, T>::value &&
3761 std::is_convertible<U&&, T>::value
3764 optional(optional<U>&& other)
3765 : has_value_(other.has_value()) {
3766 if (other.has_value()) {
3767 contained.construct_value(std::move(other.contained.value()));
3772 template <
typename... Args optional_REQUIRES_T(
3773 std::is_constructible<T, Args&&...>::value)>
3774 optional_constexpr
explicit optional(nonstd_lite_in_place_t(T),
3776 : has_value_(true), contained(T(std::forward<Args>(args)...)) {}
3779 template <
typename U,
3780 typename... Args optional_REQUIRES_T(
3781 std::is_constructible<T, std::initializer_list<U>&,
3783 optional_constexpr
explicit optional(nonstd_lite_in_place_t(T),
3784 std::initializer_list<U> il,
3786 : has_value_(true), contained(T(il, std::forward<Args>(args)...)) {}
3789 template <
typename U = T optional_REQUIRES_T(
3790 std::is_constructible<T, U&&>::value &&
3791 !std::is_same<
typename std20::remove_cvref<U>::type,
3792 nonstd_lite_in_place_t(U)>::value &&
3793 !std::is_same<
typename std20::remove_cvref<U>::type,
3794 optional<T>>::value &&
3795 !std::is_convertible<U&&, T>::value
3797 optional_constexpr
explicit optional(U&& value)
3798 : has_value_(true), contained(T{std::forward<U>(value)}) {}
3801 template <
typename U = T optional_REQUIRES_T(
3802 std::is_constructible<T, U&&>::value &&
3803 !std::is_same<
typename std20::remove_cvref<U>::type,
3804 nonstd_lite_in_place_t(U)>::value &&
3805 !std::is_same<
typename std20::remove_cvref<U>::type,
3806 optional<T>>::value &&
3807 std::is_convertible<U&&, T>::value
3810 optional_constexpr optional(U&& value)
3811 : has_value_(true), contained(std::forward<U>(value)) {}
3816 optional(value_type
const& value) : has_value_(true), contained(value) {}
3824 contained.destruct_value();
3831 optional& operator=(nullopt_t ) optional_noexcept {
3837#if optional_CPP11_OR_GREATER
3840 optional_REQUIRES_R(optional&,
true
3844 operator=(optional const& other) noexcept(
3845 std::is_nothrow_move_assignable<T>::value &&
3846 std::is_nothrow_move_constructible<T>::value)
3848 optional& operator=(optional
const& other)
3851 if ((has_value() ==
true) && (other.has_value() ==
false)) {
3853 }
else if ((has_value() ==
false) && (other.has_value() ==
true)) {
3855 }
else if ((has_value() ==
true) && (other.has_value() ==
true)) {
3856 contained.value() = *other;
3861#if optional_CPP11_OR_GREATER
3866 optional_REQUIRES_R(optional&,
true
3869 ) operator=(optional && other) noexcept {
3870 if ((has_value() ==
true) && (other.has_value() ==
false)) {
3872 }
else if ((has_value() ==
false) && (other.has_value() ==
true)) {
3873 initialize(std::move(*other));
3874 }
else if ((has_value() ==
true) && (other.has_value() ==
true)) {
3875 contained.value() = std::move(*other);
3881 template <
typename U = T>
3884 optional_REQUIRES_R(
3886 std::is_constructible<T, U>::value&& std::is_assignable<T&, U>::value &&
3887 !std::is_same<
typename std20::remove_cvref<U>::type,
3888 nonstd_lite_in_place_t(U)>::value &&
3889 !std::is_same<
typename std20::remove_cvref<U>::type,
3890 optional<T>>::value &&
3891 !(std::is_scalar<T>::value &&
3892 std::is_same<T,
typename std::decay<U>::type>::value))
3893 operator=(U && value) {
3895 contained.value() = std::forward<U>(value);
3897 initialize(T(std::forward<U>(value)));
3905 template <
typename U > optional& operator=(U
const& value) {
3907 contained.value() = value;
3909 initialize(T(value));
3916 template <
typename U>
3917#if optional_CPP11_OR_GREATER
3920 optional_REQUIRES_R(
3921 optional&, std::is_constructible<T, U const&>::value&&
3922 std::is_assignable<T&, U const&>::value &&
3923 !std::is_constructible<T, optional<U>&>::value &&
3924 !std::is_constructible<T, optional<U>&&>::value &&
3925 !std::is_constructible<T, optional<U>
const&>::value &&
3926 !std::is_constructible<T, optional<U>
const&&>::value &&
3927 !std::is_convertible<optional<U>&, T>::value &&
3928 !std::is_convertible<optional<U>&&, T>::value &&
3929 !std::is_convertible<optional<U>
const&, T>::value &&
3930 !std::is_convertible<optional<U>
const&&, T>::value &&
3931 !std::is_assignable<T&, optional<U>&>::value &&
3932 !std::is_assignable<T&, optional<U>&&>::value &&
3933 !std::is_assignable<T&, optional<U>
const&>::value &&
3934 !std::is_assignable<T&, optional<U>
const&&>::value)
3938 operator=(optional<U>
const& other) {
3939 return *
this = optional(other);
3942#if optional_CPP11_OR_GREATER
3945 template <
typename U>
3948 optional_REQUIRES_R(
3950 std::is_constructible<T, U>::value&& std::is_assignable<T&, U>::value &&
3951 !std::is_constructible<T, optional<U>&>::value &&
3952 !std::is_constructible<T, optional<U>&&>::value &&
3953 !std::is_constructible<T, optional<U>
const&>::value &&
3954 !std::is_constructible<T, optional<U>
const&&>::value &&
3955 !std::is_convertible<optional<U>&, T>::value &&
3956 !std::is_convertible<optional<U>&&, T>::value &&
3957 !std::is_convertible<optional<U>
const&, T>::value &&
3958 !std::is_convertible<optional<U>
const&&, T>::value &&
3959 !std::is_assignable<T&, optional<U>&>::value &&
3960 !std::is_assignable<T&, optional<U>&&>::value &&
3961 !std::is_assignable<T&, optional<U>
const&>::value &&
3962 !std::is_assignable<T&, optional<U>
const&&>::value)
3963 operator=(optional<U>&& other) {
3964 return *
this = optional(std::move(other));
3968 template <
typename... Args optional_REQUIRES_T(
3969 std::is_constructible<T, Args&&...>::value)>
3970 T& emplace(Args&&... args) {
3972 contained.emplace(std::forward<Args>(args)...);
3974 return contained.value();
3978 template <
typename U,
3979 typename... Args optional_REQUIRES_T(
3980 std::is_constructible<T, std::initializer_list<U>&,
3982 T& emplace(std::initializer_list<U> il, Args&&... args) {
3984 contained.emplace(il, std::forward<Args>(args)...);
3986 return contained.value();
3993 void swap(optional& other)
3994#if optional_CPP11_OR_GREATER
3995 noexcept(std::is_nothrow_move_constructible<T>::value &&
3996 std17::is_nothrow_swappable<T>::value)
4000 if ((has_value() ==
true) && (other.has_value() ==
true)) {
4001 swap(**
this, *other);
4002 }
else if ((has_value() ==
false) && (other.has_value() ==
true)) {
4003 initialize(std11::move(*other));
4005 }
else if ((has_value() ==
true) && (other.has_value() ==
false)) {
4006 other.initialize(std11::move(**
this));
4013 optional_constexpr value_type
const* operator->()
const {
4014 return assert(has_value()), contained.value_ptr();
4017 optional_constexpr14 value_type* operator->() {
4018 return assert(has_value()), contained.value_ptr();
4021 optional_constexpr value_type
const& operator*() const optional_ref_qual {
4022 return assert(has_value()), contained.value();
4025 optional_constexpr14 value_type& operator*() optional_ref_qual {
4026 return assert(has_value()), contained.value();
4029#if optional_HAVE(REF_QUALIFIER)
4031 optional_constexpr value_type
const&&
4032 operator*() const optional_refref_qual {
4033 return std::move(**
this);
4036 optional_constexpr14 value_type&& operator*() optional_refref_qual {
4037 return std::move(**
this);
4042#if optional_CPP11_OR_GREATER
4043 optional_constexpr
explicit operator bool() const optional_noexcept {
4047 optional_constexpr
operator safe_bool() const optional_noexcept {
4048 return has_value() ? &optional::this_type_does_not_support_comparisons
4054 optional_constexpr
bool
4055 has_value() const optional_noexcept {
4060 optional_constexpr14 value_type
const&
4061 value() const optional_ref_qual {
4062#if optional_CONFIG_NO_EXCEPTIONS
4063 assert(has_value());
4066 throw bad_optional_access();
4069 return contained.value();
4072 optional_constexpr14 value_type& value() optional_ref_qual {
4073#if optional_CONFIG_NO_EXCEPTIONS
4074 assert(has_value());
4077 throw bad_optional_access();
4080 return contained.value();
4083#if optional_HAVE(REF_QUALIFIER) && \
4084 (!optional_COMPILER_GNUC_VERSION || optional_COMPILER_GNUC_VERSION >= 490)
4087 optional_constexpr value_type
const&&
4088 value() const optional_refref_qual {
4089 return std::move(value());
4092 optional_constexpr14 value_type&& value() optional_refref_qual {
4093 return std::move(value());
4098#if optional_CPP11_OR_GREATER
4100 template <
typename U>
4101 optional_constexpr value_type value_or(U&& v)
const optional_ref_qual {
4102 return has_value() ? contained.value()
4103 :
static_cast<T
>(std::forward<U>(v));
4106 template <
typename U>
4107 optional_constexpr14 value_type value_or(U&& v) optional_refref_qual {
4108 return has_value() ? std::move(contained.value())
4109 : static_cast<T>(std::forward<U>(v));
4114 template <
typename U>
4115 optional_constexpr value_type value_or(U
const& v)
const {
4116 return has_value() ? contained.value() :
static_cast<value_type
>(v);
4123 void reset() optional_noexcept {
4125 contained.destruct_value();
4132 void this_type_does_not_support_comparisons()
const {}
4134 template <
typename V>
void initialize(V
const& value) {
4135 assert(!has_value());
4136 contained.construct_value(value);
4140#if optional_CPP11_OR_GREATER
4141 template <
typename V>
void initialize(V&& value) {
4142 assert(!has_value());
4143 contained.construct_value(std::move(value));
4151 detail::storage_t<value_type> contained;
4156template <
typename T,
typename U>
4157inline optional_constexpr
bool operator==(optional<T>
const& x,
4158 optional<U>
const& y) {
4159 return bool(x) != bool(y) ? false : !bool(x) ? true : *x == *y;
4162template <
typename T,
typename U>
4163inline optional_constexpr
bool operator!=(optional<T>
const& x,
4164 optional<U>
const& y) {
4168template <
typename T,
typename U>
4169inline optional_constexpr
bool operator<(optional<T>
const& x,
4170 optional<U>
const& y) {
4171 return (!y) ? false : (!x) ?
true : *x < *y;
4174template <
typename T,
typename U>
4175inline optional_constexpr
bool operator>(optional<T>
const& x,
4176 optional<U>
const& y) {
4180template <
typename T,
typename U>
4181inline optional_constexpr
bool operator<=(optional<T>
const& x,
4182 optional<U>
const& y) {
4186template <
typename T,
typename U>
4187inline optional_constexpr
bool operator>=(optional<T>
const& x,
4188 optional<U>
const& y) {
4194template <
typename T>
4195inline optional_constexpr
bool
4196operator==(optional<T>
const& x, nullopt_t ) optional_noexcept {
4200template <
typename T>
4201inline optional_constexpr
bool
4202operator==(nullopt_t , optional<T>
const& x) optional_noexcept {
4206template <
typename T>
4207inline optional_constexpr
bool
4208operator!=(optional<T>
const& x, nullopt_t ) optional_noexcept {
4212template <
typename T>
4213inline optional_constexpr
bool
4214operator!=(nullopt_t , optional<T>
const& x) optional_noexcept {
4218template <
typename T>
4219inline optional_constexpr
bool
4220operator<(optional<T>
const& ,
4221 nullopt_t ) optional_noexcept {
4225template <
typename T>
4226inline optional_constexpr
bool
4227operator<(nullopt_t , optional<T>
const& x) optional_noexcept {
4231template <
typename T>
4232inline optional_constexpr
bool
4233operator<=(optional<T>
const& x, nullopt_t ) optional_noexcept {
4237template <
typename T>
4238inline optional_constexpr
bool
4239operator<=(nullopt_t ,
4240 optional<T>
const& ) optional_noexcept {
4244template <
typename T>
4245inline optional_constexpr
bool
4246operator>(optional<T>
const& x, nullopt_t ) optional_noexcept {
4250template <
typename T>
4251inline optional_constexpr
bool
4252operator>(nullopt_t ,
4253 optional<T>
const& ) optional_noexcept {
4257template <
typename T>
4258inline optional_constexpr
bool
4259operator>=(optional<T>
const& ,
4260 nullopt_t ) optional_noexcept {
4264template <
typename T>
4265inline optional_constexpr
bool
4266operator>=(nullopt_t , optional<T>
const& x) optional_noexcept {
4272template <
typename T,
typename U>
4273inline optional_constexpr
bool operator==(optional<T>
const& x, U
const& v) {
4274 return bool(x) ? *x == v :
false;
4277template <
typename T,
typename U>
4278inline optional_constexpr
bool operator==(U
const& v, optional<T>
const& x) {
4279 return bool(x) ? v == *x :
false;
4282template <
typename T,
typename U>
4283inline optional_constexpr
bool operator!=(optional<T>
const& x, U
const& v) {
4284 return bool(x) ? *x != v :
true;
4287template <
typename T,
typename U>
4288inline optional_constexpr
bool operator!=(U
const& v, optional<T>
const& x) {
4289 return bool(x) ? v != *x :
true;
4292template <
typename T,
typename U>
4293inline optional_constexpr
bool operator<(optional<T>
const& x, U
const& v) {
4294 return bool(x) ? *x < v :
true;
4297template <
typename T,
typename U>
4298inline optional_constexpr
bool operator<(U
const& v, optional<T>
const& x) {
4299 return bool(x) ? v < *x :
false;
4302template <
typename T,
typename U>
4303inline optional_constexpr
bool operator<=(optional<T>
const& x, U
const& v) {
4304 return bool(x) ? *x <= v :
true;
4307template <
typename T,
typename U>
4308inline optional_constexpr
bool operator<=(U
const& v, optional<T>
const& x) {
4309 return bool(x) ? v <= *x :
false;
4312template <
typename T,
typename U>
4313inline optional_constexpr
bool operator>(optional<T>
const& x, U
const& v) {
4314 return bool(x) ? *x > v :
false;
4317template <
typename T,
typename U>
4318inline optional_constexpr
bool operator>(U
const& v, optional<T>
const& x) {
4319 return bool(x) ? v > *x :
true;
4322template <
typename T,
typename U>
4323inline optional_constexpr
bool operator>=(optional<T>
const& x, U
const& v) {
4324 return bool(x) ? *x >= v :
false;
4327template <
typename T,
typename U>
4328inline optional_constexpr
bool operator>=(U
const& v, optional<T>
const& x) {
4329 return bool(x) ? v >= *x :
true;
4335#if optional_CPP11_OR_GREATER
4336 optional_REQUIRES_T(std::is_move_constructible<T>::value&&
4337 std17::is_swappable<T>::value)
4340void swap(optional<T>& x, optional<T>& y)
4341#if optional_CPP11_OR_GREATER
4342 noexcept(
noexcept(x.swap(y)))
4348#if optional_CPP11_OR_GREATER
4350template <
typename T>
4351optional_constexpr optional<typename std::decay<T>::type>
4352 make_optional(T&& value) {
4353 return optional<typename std::decay<T>::type>(std::forward<T>(value));
4356template <
typename T,
typename... Args>
4357optional_constexpr optional<T> make_optional(Args&&... args) {
4358 return optional<T>(nonstd_lite_in_place(T), std::forward<Args>(args)...);
4361template <
typename T,
typename U,
typename... Args>
4362optional_constexpr optional<T> make_optional(std::initializer_list<U> il,
4364 return optional<T>(nonstd_lite_in_place(T), il,
4365 std::forward<Args>(args)...);
4370template <
typename T> optional<T> make_optional(T
const& value) {
4371 return optional<T>(value);
4378using optional_lite::nullopt;
4379using optional_lite::nullopt_t;
4380using optional_lite::optional;
4382#if !optional_CONFIG_NO_EXCEPTIONS
4383using optional_lite::bad_optional_access;
4386using optional_lite::make_optional;
4390#if optional_CPP11_OR_GREATER
4396template <
class T>
struct hash<nonstd::optional<T>> {
4399 operator()(nonstd::optional<T>
const& v)
const optional_noexcept {
4400 return bool(v) ? std::hash<T>{}(*v) : 0;
4408#if defined(__clang__)
4409#pragma clang diagnostic pop
4410#elif defined(__GNUC__)
4411#pragma GCC diagnostic pop
4412#elif defined(_MSC_VER)
4430#ifndef NONSTD_SV_LITE_H_INCLUDED
4431#define NONSTD_SV_LITE_H_INCLUDED
4433#define string_view_lite_MAJOR 1
4434#define string_view_lite_MINOR 6
4435#define string_view_lite_PATCH 0
4437#define string_view_lite_VERSION \
4438 nssv_STRINGIFY(string_view_lite_MAJOR) "." nssv_STRINGIFY( \
4439 string_view_lite_MINOR) "." nssv_STRINGIFY(string_view_lite_PATCH)
4441#define nssv_STRINGIFY(x) nssv_STRINGIFY_(x)
4442#define nssv_STRINGIFY_(x) #x
4446#define nssv_STRING_VIEW_DEFAULT 0
4447#define nssv_STRING_VIEW_NONSTD 1
4448#define nssv_STRING_VIEW_STD 2
4453#if __has_include(<nonstd/string_view.tweak.hpp>)
4454#include <nonstd/string_view.tweak.hpp>
4456#define nssv_HAVE_TWEAK_HEADER 1
4458#define nssv_HAVE_TWEAK_HEADER 0
4464#if !defined(nssv_CONFIG_SELECT_STRING_VIEW)
4465#define nssv_CONFIG_SELECT_STRING_VIEW \
4466 (nssv_HAVE_STD_STRING_VIEW ? nssv_STRING_VIEW_STD : nssv_STRING_VIEW_NONSTD)
4469#ifndef nssv_CONFIG_STD_SV_OPERATOR
4470#define nssv_CONFIG_STD_SV_OPERATOR 0
4473#ifndef nssv_CONFIG_USR_SV_OPERATOR
4474#define nssv_CONFIG_USR_SV_OPERATOR 1
4477#ifdef nssv_CONFIG_CONVERSION_STD_STRING
4478#define nssv_CONFIG_CONVERSION_STD_STRING_CLASS_METHODS \
4479 nssv_CONFIG_CONVERSION_STD_STRING
4480#define nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS \
4481 nssv_CONFIG_CONVERSION_STD_STRING
4484#ifndef nssv_CONFIG_CONVERSION_STD_STRING_CLASS_METHODS
4485#define nssv_CONFIG_CONVERSION_STD_STRING_CLASS_METHODS 1
4488#ifndef nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS
4489#define nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS 1
4492#ifndef nssv_CONFIG_NO_STREAM_INSERTION
4493#define nssv_CONFIG_NO_STREAM_INSERTION 0
4498#ifndef nssv_CONFIG_NO_EXCEPTIONS
4499#if defined(_MSC_VER)
4502#if defined(__cpp_exceptions) || defined(__EXCEPTIONS) || (_HAS_EXCEPTIONS)
4503#define nssv_CONFIG_NO_EXCEPTIONS 0
4505#define nssv_CONFIG_NO_EXCEPTIONS 1
4512#ifndef nssv_CPLUSPLUS
4513#if defined(_MSVC_LANG) && !defined(__clang__)
4514#define nssv_CPLUSPLUS (_MSC_VER == 1900 ? 201103L : _MSVC_LANG)
4516#define nssv_CPLUSPLUS __cplusplus
4520#define nssv_CPP98_OR_GREATER (nssv_CPLUSPLUS >= 199711L)
4521#define nssv_CPP11_OR_GREATER (nssv_CPLUSPLUS >= 201103L)
4522#define nssv_CPP11_OR_GREATER_ (nssv_CPLUSPLUS >= 201103L)
4523#define nssv_CPP14_OR_GREATER (nssv_CPLUSPLUS >= 201402L)
4524#define nssv_CPP17_OR_GREATER (nssv_CPLUSPLUS >= 201703L)
4525#define nssv_CPP20_OR_GREATER (nssv_CPLUSPLUS >= 202000L)
4529#if nssv_CPP17_OR_GREATER && defined(__has_include)
4530#if __has_include(<string_view> )
4531#define nssv_HAVE_STD_STRING_VIEW 1
4533#define nssv_HAVE_STD_STRING_VIEW 0
4536#define nssv_HAVE_STD_STRING_VIEW 0
4539#define nssv_USES_STD_STRING_VIEW \
4540 ((nssv_CONFIG_SELECT_STRING_VIEW == nssv_STRING_VIEW_STD) || \
4541 ((nssv_CONFIG_SELECT_STRING_VIEW == nssv_STRING_VIEW_DEFAULT) && \
4542 nssv_HAVE_STD_STRING_VIEW))
4544#define nssv_HAVE_STARTS_WITH \
4545 (nssv_CPP20_OR_GREATER || !nssv_USES_STD_STRING_VIEW)
4546#define nssv_HAVE_ENDS_WITH nssv_HAVE_STARTS_WITH
4552#if nssv_USES_STD_STRING_VIEW
4554#include <string_view>
4558#if nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS
4562template <
class CharT,
class Traits,
class Allocator = std::allocator<CharT>>
4563std::basic_string<CharT, Traits, Allocator>
4564to_string(std::basic_string_view<CharT, Traits> v,
4565 Allocator
const& a = Allocator()) {
4566 return std::basic_string<CharT, Traits, Allocator>(v.begin(), v.end(), a);
4569template <
class CharT,
class Traits,
class Allocator>
4570std::basic_string_view<CharT, Traits>
4571to_string_view(std::basic_string<CharT, Traits, Allocator>
const& s) {
4572 return std::basic_string_view<CharT, Traits>(s.data(), s.size());
4577#if nssv_CONFIG_STD_SV_OPERATOR
4579using namespace std::literals::string_view_literals;
4583#if nssv_CONFIG_USR_SV_OPERATOR
4585inline namespace literals {
4586inline namespace string_view_literals {
4588constexpr std::string_view
operator"" _sv(
const char* str,
4589 size_t len)
noexcept
4591 return std::string_view{str, len};
4594constexpr std::u16string_view
operator"" _sv(
const char16_t* str,
4595 size_t len)
noexcept
4597 return std::u16string_view{str, len};
4600constexpr std::u32string_view
operator"" _sv(
const char32_t* str,
4601 size_t len)
noexcept
4603 return std::u32string_view{str, len};
4606constexpr std::wstring_view
operator"" _sv(
const wchar_t* str,
4607 size_t len)
noexcept
4609 return std::wstring_view{str, len};
4623using std::basic_string_view;
4624using std::string_view;
4625using std::u16string_view;
4626using std::u32string_view;
4627using std::wstring_view;
4631using std::operator==;
4632using std::operator!=;
4633using std::operator<;
4634using std::operator<=;
4635using std::operator>;
4636using std::operator>=;
4638using std::operator<<;
4665#if defined(_MSC_VER) && !defined(__clang__)
4666#define nssv_COMPILER_MSVC_VER (_MSC_VER)
4667#define nssv_COMPILER_MSVC_VERSION \
4668 (_MSC_VER / 10 - 10 * (5 + (_MSC_VER < 1900)))
4670#define nssv_COMPILER_MSVC_VER 0
4671#define nssv_COMPILER_MSVC_VERSION 0
4674#define nssv_COMPILER_VERSION(major, minor, patch) \
4675 (10 * (10 * (major) + (minor)) + (patch))
4677#if defined(__apple_build_version__)
4678#define nssv_COMPILER_APPLECLANG_VERSION \
4679 nssv_COMPILER_VERSION(__clang_major__, __clang_minor__, \
4680 __clang_patchlevel__)
4681#define nssv_COMPILER_CLANG_VERSION 0
4682#elif defined(__clang__)
4683#define nssv_COMPILER_APPLECLANG_VERSION 0
4684#define nssv_COMPILER_CLANG_VERSION \
4685 nssv_COMPILER_VERSION(__clang_major__, __clang_minor__, \
4686 __clang_patchlevel__)
4688#define nssv_COMPILER_APPLECLANG_VERSION 0
4689#define nssv_COMPILER_CLANG_VERSION 0
4692#if defined(__GNUC__) && !defined(__clang__)
4693#define nssv_COMPILER_GNUC_VERSION \
4694 nssv_COMPILER_VERSION(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
4696#define nssv_COMPILER_GNUC_VERSION 0
4700#define nssv_BETWEEN(v, lo, hi) ((lo) <= (v) && (v) < (hi))
4705#define nssv_HAS_CPP0X _HAS_CPP0X
4707#define nssv_HAS_CPP0X 0
4712#if nssv_COMPILER_MSVC_VER >= 1900
4713#undef nssv_CPP11_OR_GREATER
4714#define nssv_CPP11_OR_GREATER 1
4717#define nssv_CPP11_90 (nssv_CPP11_OR_GREATER_ || nssv_COMPILER_MSVC_VER >= 1500)
4718#define nssv_CPP11_100 \
4719 (nssv_CPP11_OR_GREATER_ || nssv_COMPILER_MSVC_VER >= 1600)
4720#define nssv_CPP11_110 \
4721 (nssv_CPP11_OR_GREATER_ || nssv_COMPILER_MSVC_VER >= 1700)
4722#define nssv_CPP11_120 \
4723 (nssv_CPP11_OR_GREATER_ || nssv_COMPILER_MSVC_VER >= 1800)
4724#define nssv_CPP11_140 \
4725 (nssv_CPP11_OR_GREATER_ || nssv_COMPILER_MSVC_VER >= 1900)
4726#define nssv_CPP11_141 \
4727 (nssv_CPP11_OR_GREATER_ || nssv_COMPILER_MSVC_VER >= 1910)
4729#define nssv_CPP14_000 (nssv_CPP14_OR_GREATER)
4730#define nssv_CPP17_000 (nssv_CPP17_OR_GREATER)
4734#define nssv_HAVE_CONSTEXPR_11 nssv_CPP11_140
4735#define nssv_HAVE_EXPLICIT_CONVERSION nssv_CPP11_140
4736#define nssv_HAVE_INLINE_NAMESPACE nssv_CPP11_140
4737#define nssv_HAVE_NOEXCEPT nssv_CPP11_140
4738#define nssv_HAVE_NULLPTR nssv_CPP11_100
4739#define nssv_HAVE_REF_QUALIFIER nssv_CPP11_140
4740#define nssv_HAVE_UNICODE_LITERALS nssv_CPP11_140
4741#define nssv_HAVE_USER_DEFINED_LITERALS nssv_CPP11_140
4742#define nssv_HAVE_WCHAR16_T nssv_CPP11_100
4743#define nssv_HAVE_WCHAR32_T nssv_CPP11_100
4745#if !((nssv_CPP11_OR_GREATER && nssv_COMPILER_CLANG_VERSION) || \
4746 nssv_BETWEEN(nssv_COMPILER_CLANG_VERSION, 300, 400))
4747#define nssv_HAVE_STD_DEFINED_LITERALS nssv_CPP11_140
4749#define nssv_HAVE_STD_DEFINED_LITERALS 0
4754#define nssv_HAVE_CONSTEXPR_14 nssv_CPP14_000
4758#define nssv_HAVE_NODISCARD nssv_CPP17_000
4762#define nssv_HAVE_STD_HASH nssv_CPP11_120
4779#define nssv_HAVE_BUILTIN_VER \
4780 ((nssv_CPP17_000 && nssv_COMPILER_MSVC_VERSION >= 142) || \
4781 nssv_COMPILER_GNUC_VERSION > 0 || nssv_COMPILER_CLANG_VERSION >= 400 || \
4782 nssv_COMPILER_APPLECLANG_VERSION >= 900)
4783#define nssv_HAVE_BUILTIN_CE (nssv_HAVE_BUILTIN_VER)
4785#define nssv_HAVE_BUILTIN_MEMCMP \
4786 ((nssv_HAVE_CONSTEXPR_14 && nssv_HAVE_BUILTIN_CE) || \
4787 !nssv_HAVE_CONSTEXPR_14)
4788#define nssv_HAVE_BUILTIN_STRLEN \
4789 ((nssv_HAVE_CONSTEXPR_11 && nssv_HAVE_BUILTIN_CE) || \
4790 !nssv_HAVE_CONSTEXPR_11)
4793#define nssv_HAVE_BUILTIN(x) __has_builtin(x)
4795#define nssv_HAVE_BUILTIN(x) 0
4798#if nssv_HAVE_BUILTIN(__builtin_memcmp) || nssv_HAVE_BUILTIN_VER
4799#define nssv_BUILTIN_MEMCMP __builtin_memcmp
4801#define nssv_BUILTIN_MEMCMP memcmp
4804#if nssv_HAVE_BUILTIN(__builtin_strlen) || nssv_HAVE_BUILTIN_VER
4805#define nssv_BUILTIN_STRLEN __builtin_strlen
4807#define nssv_BUILTIN_STRLEN strlen
4812#if nssv_HAVE_CONSTEXPR_11
4813#define nssv_constexpr constexpr
4815#define nssv_constexpr
4818#if nssv_HAVE_CONSTEXPR_14
4819#define nssv_constexpr14 constexpr
4821#define nssv_constexpr14
4824#if nssv_HAVE_EXPLICIT_CONVERSION
4825#define nssv_explicit explicit
4827#define nssv_explicit
4830#if nssv_HAVE_INLINE_NAMESPACE
4831#define nssv_inline_ns inline
4833#define nssv_inline_ns
4836#if nssv_HAVE_NOEXCEPT
4837#define nssv_noexcept noexcept
4839#define nssv_noexcept
4850#if nssv_HAVE_NULLPTR
4851#define nssv_nullptr nullptr
4853#define nssv_nullptr NULL
4856#if nssv_HAVE_NODISCARD
4857#define nssv_nodiscard [[nodiscard]]
4859#define nssv_nodiscard
4870#if !nssv_CONFIG_NO_STREAM_INSERTION
4874#if !nssv_CONFIG_NO_EXCEPTIONS
4878#if nssv_CPP11_OR_GREATER
4879#include <type_traits>
4884#if defined(__clang__)
4885#pragma clang diagnostic ignored "-Wreserved-user-defined-literal"
4886#pragma clang diagnostic push
4887#pragma clang diagnostic ignored "-Wuser-defined-literals"
4888#elif defined(__GNUC__)
4889#pragma GCC diagnostic push
4890#pragma GCC diagnostic ignored "-Wliteral-suffix"
4893#if nssv_COMPILER_MSVC_VERSION >= 140
4894#define nssv_SUPPRESS_MSGSL_WARNING(expr) [[gsl::suppress(expr)]]
4895#define nssv_SUPPRESS_MSVC_WARNING(code, descr) \
4896 __pragma(warning(suppress : code))
4897#define nssv_DISABLE_MSVC_WARNINGS(codes) \
4898 __pragma(warning(push)) __pragma(warning(disable : codes))
4900#define nssv_SUPPRESS_MSGSL_WARNING(expr)
4901#define nssv_SUPPRESS_MSVC_WARNING(code, descr)
4902#define nssv_DISABLE_MSVC_WARNINGS(codes)
4905#if defined(__clang__)
4906#define nssv_RESTORE_WARNINGS() _Pragma("clang diagnostic pop")
4907#elif defined(__GNUC__)
4908#define nssv_RESTORE_WARNINGS() _Pragma("GCC diagnostic pop")
4909#elif nssv_COMPILER_MSVC_VERSION >= 140
4910#define nssv_RESTORE_WARNINGS() __pragma(warning(pop))
4912#define nssv_RESTORE_WARNINGS()
4922nssv_DISABLE_MSVC_WARNINGS(4455 26481 26472)
4934 template <
typename CharT>
4935 inline nssv_constexpr14
int compare(CharT
const* s1, CharT
const* s2,
4936 std::size_t count) {
4937 while (count-- != 0) {
4948#if nssv_HAVE_BUILTIN_MEMCMP
4952 inline nssv_constexpr14
int compare(
char const* s1,
char const* s2,
4953 std::size_t count) {
4954 return nssv_BUILTIN_MEMCMP(s1, s2, count);
4959#if nssv_HAVE_BUILTIN_STRLEN
4964 inline nssv_constexpr std::size_t length(
char const* s) {
4965 return nssv_BUILTIN_STRLEN(s);
4970#if defined(__OPTIMIZE__)
4975 template <
typename CharT>
4976 inline nssv_constexpr std::size_t length(CharT* s, std::size_t result = 0) {
4977 return *s ==
'\0' ? result : length(s + 1, result + 1);
4984 template <
typename CharT>
4985 inline nssv_constexpr14 std::size_t length(CharT* s) {
4986 std::size_t result = 0;
4987 while (*s++ !=
'\0') {
4997 template <
class CharT,
class Traits = std::
char_traits<CharT>>
4998 class basic_string_view;
5004 template <
class CharT,
class Traits
5006 class basic_string_view {
5010 typedef Traits traits_type;
5011 typedef CharT value_type;
5013 typedef CharT* pointer;
5014 typedef CharT
const* const_pointer;
5015 typedef CharT& reference;
5016 typedef CharT
const& const_reference;
5018 typedef const_pointer iterator;
5019 typedef const_pointer const_iterator;
5020 typedef std::reverse_iterator<const_iterator> reverse_iterator;
5021 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
5023 typedef std::size_t size_type;
5024 typedef std::ptrdiff_t difference_type;
5028 nssv_constexpr basic_string_view() nssv_noexcept : data_(nssv_nullptr),
5031#if nssv_CPP11_OR_GREATER
5032 nssv_constexpr basic_string_view(basic_string_view
const& other)
5033 nssv_noexcept =
default;
5036 basic_string_view(basic_string_view
const& other) nssv_noexcept
5037 : data_(other.data_),
5038 size_(other.size_) {}
5041 nssv_constexpr basic_string_view(CharT
const* s, size_type count)
5047 basic_string_view(CharT
const* s) nssv_noexcept
5049#if nssv_CPP17_OR_GREATER
5051 size_(Traits::length(s))
5052#elif nssv_CPP11_OR_GREATER
5054 size_(detail::length(s))
5057 size_(Traits::length(s))
5064#if nssv_CPP11_OR_GREATER
5065 nssv_constexpr14 basic_string_view&
5066 operator=(basic_string_view
const& other) nssv_noexcept =
default;
5068 nssv_constexpr14 basic_string_view&
5069 operator=(basic_string_view
const& other) nssv_noexcept {
5070 data_ = other.data_;
5071 size_ = other.size_;
5078 nssv_constexpr const_iterator begin() const nssv_noexcept {
5081 nssv_constexpr const_iterator end() const nssv_noexcept {
5082 return data_ + size_;
5085 nssv_constexpr const_iterator cbegin() const nssv_noexcept {
5088 nssv_constexpr const_iterator cend() const nssv_noexcept {
5092 nssv_constexpr const_reverse_iterator rbegin() const nssv_noexcept {
5093 return const_reverse_iterator(end());
5095 nssv_constexpr const_reverse_iterator rend() const nssv_noexcept {
5096 return const_reverse_iterator(begin());
5099 nssv_constexpr const_reverse_iterator crbegin() const nssv_noexcept {
5102 nssv_constexpr const_reverse_iterator crend() const nssv_noexcept {
5108 nssv_constexpr size_type size() const nssv_noexcept {
return size_; }
5109 nssv_constexpr size_type length() const nssv_noexcept {
return size_; }
5110 nssv_constexpr size_type max_size() const nssv_noexcept {
5111 return (std::numeric_limits<size_type>::max)();
5115 nssv_nodiscard nssv_constexpr
bool empty() const nssv_noexcept {
5121 nssv_constexpr const_reference operator[](size_type pos)
const {
5122 return data_at(pos);
5125 nssv_constexpr14 const_reference at(size_type pos)
const {
5126#if nssv_CONFIG_NO_EXCEPTIONS
5127 assert(pos < size());
5129 if (pos >= size()) {
5130 throw std::out_of_range(
"nonstd::string_view::at()");
5133 return data_at(pos);
5136 nssv_constexpr const_reference front()
const {
return data_at(0); }
5137 nssv_constexpr const_reference back()
const {
5138 return data_at(size() - 1);
5141 nssv_constexpr const_pointer data() const nssv_noexcept {
5147 nssv_constexpr14
void remove_prefix(size_type n) {
5148 assert(n <= size());
5153 nssv_constexpr14
void remove_suffix(size_type n) {
5154 assert(n <= size());
5158 nssv_constexpr14
void swap(basic_string_view& other) nssv_noexcept {
5159 const basic_string_view tmp(other);
5166 size_type copy(CharT* dest, size_type n, size_type pos = 0)
const {
5167#if nssv_CONFIG_NO_EXCEPTIONS
5168 assert(pos <= size());
5171 throw std::out_of_range(
"nonstd::string_view::copy()");
5174 const size_type rlen = (std::min)(n, size() - pos);
5176 (void) Traits::copy(dest, data() + pos, rlen);
5181 nssv_constexpr14 basic_string_view substr(size_type pos = 0,
5182 size_type n = npos)
const {
5183#if nssv_CONFIG_NO_EXCEPTIONS
5184 assert(pos <= size());
5187 throw std::out_of_range(
"nonstd::string_view::substr()");
5190 return basic_string_view(data() + pos, (std::min)(n, size() - pos));
5195 nssv_constexpr14
int
5196 compare(basic_string_view other)
const nssv_noexcept
5198#if nssv_CPP17_OR_GREATER
5199 if (
const int result = Traits::compare(
5200 data(), other.data(), (std::min)(size(), other.size())))
5202 if (
const int result = detail::compare(
5203 data(), other.data(), (std::min)(size(), other.size())))
5209 return size() == other.size() ? 0 : size() < other.size() ? -1 : 1;
5212 nssv_constexpr
int compare(size_type pos1, size_type n1,
5213 basic_string_view other)
const
5215 return substr(pos1, n1).compare(other);
5218 nssv_constexpr
int compare(size_type pos1, size_type n1,
5219 basic_string_view other, size_type pos2,
5222 return substr(pos1, n1).compare(other.substr(pos2, n2));
5225 nssv_constexpr
int compare(CharT
const* s)
const
5227 return compare(basic_string_view(s));
5230 nssv_constexpr
int compare(size_type pos1, size_type n1,
5231 CharT
const* s)
const
5233 return substr(pos1, n1).compare(basic_string_view(s));
5236 nssv_constexpr
int compare(size_type pos1, size_type n1, CharT
const* s,
5239 return substr(pos1, n1).compare(basic_string_view(s, n2));
5247 starts_with(basic_string_view v)
const nssv_noexcept
5249 return size() >= v.size() && compare(0, v.size(), v) == 0;
5252 nssv_constexpr
bool starts_with(CharT c)
const nssv_noexcept
5254 return starts_with(basic_string_view(&c, 1));
5257 nssv_constexpr
bool starts_with(CharT
const* s)
const
5259 return starts_with(basic_string_view(s));
5265 ends_with(basic_string_view v)
const nssv_noexcept
5267 return size() >= v.size() &&
5268 compare(size() - v.size(), npos, v) == 0;
5271 nssv_constexpr
bool ends_with(CharT c)
const nssv_noexcept
5273 return ends_with(basic_string_view(&c, 1));
5276 nssv_constexpr
bool ends_with(CharT
const* s)
const
5278 return ends_with(basic_string_view(s));
5283 nssv_constexpr14 size_type
5284 find(basic_string_view v, size_type pos = 0) const nssv_noexcept
5286 return assert(v.size() == 0 || v.data() != nssv_nullptr),
5289 : to_pos(std::search(cbegin() + pos, cend(), v.cbegin(),
5290 v.cend(), Traits::eq));
5293 nssv_constexpr14 size_type
5294 find(CharT c, size_type pos = 0) const nssv_noexcept
5296 return find(basic_string_view(&c, 1), pos);
5299 nssv_constexpr14 size_type find(CharT
const* s, size_type pos,
5302 return find(basic_string_view(s, n), pos);
5305 nssv_constexpr14 size_type find(CharT
const* s,
5306 size_type pos = 0) const
5308 return find(basic_string_view(s), pos);
5313 nssv_constexpr14 size_type
5314 rfind(basic_string_view v,
5315 size_type pos = npos)
const nssv_noexcept
5317 if (size() < v.size()) {
5322 return (std::min)(size(), pos);
5325 const_iterator last =
5326 cbegin() + (std::min)(size() - v.size(), pos) + v.size();
5327 const_iterator result =
5328 std::find_end(cbegin(), last, v.cbegin(), v.cend(), Traits::eq);
5330 return result != last ? size_type(result - cbegin()) : npos;
5333 nssv_constexpr14 size_type
5334 rfind(CharT c, size_type pos = npos)
const nssv_noexcept
5336 return rfind(basic_string_view(&c, 1), pos);
5339 nssv_constexpr14 size_type rfind(CharT
const* s, size_type pos,
5342 return rfind(basic_string_view(s, n), pos);
5345 nssv_constexpr14 size_type rfind(CharT
const* s,
5346 size_type pos = npos)
const
5348 return rfind(basic_string_view(s), pos);
5353 nssv_constexpr size_type find_first_of(
5354 basic_string_view v, size_type pos = 0) const nssv_noexcept
5356 return pos >= size()
5358 : to_pos(std::find_first_of(cbegin() + pos, cend(),
5359 v.cbegin(), v.cend(),
5363 nssv_constexpr size_type
5364 find_first_of(CharT c, size_type pos = 0) const nssv_noexcept
5366 return find_first_of(basic_string_view(&c, 1), pos);
5369 nssv_constexpr size_type find_first_of(CharT
const* s, size_type pos,
5372 return find_first_of(basic_string_view(s, n), pos);
5375 nssv_constexpr size_type find_first_of(CharT
const* s,
5376 size_type pos = 0) const
5378 return find_first_of(basic_string_view(s), pos);
5383 nssv_constexpr size_type
5384 find_last_of(basic_string_view v,
5385 size_type pos = npos)
const nssv_noexcept
5387 return empty() ? npos
5389 ? find_last_of(v, size() - 1)
5390 : to_pos(std::find_first_of(
5391 const_reverse_iterator(cbegin() + pos + 1),
5392 crend(), v.cbegin(), v.cend(), Traits::eq));
5395 nssv_constexpr size_type
5396 find_last_of(CharT c, size_type pos = npos)
const nssv_noexcept
5398 return find_last_of(basic_string_view(&c, 1), pos);
5401 nssv_constexpr size_type find_last_of(CharT
const* s, size_type pos,
5402 size_type count)
const
5404 return find_last_of(basic_string_view(s, count), pos);
5407 nssv_constexpr size_type find_last_of(CharT
const* s,
5408 size_type pos = npos)
const
5410 return find_last_of(basic_string_view(s), pos);
5415 nssv_constexpr size_type find_first_not_of(
5416 basic_string_view v, size_type pos = 0) const nssv_noexcept
5418 return pos >= size() ? npos
5419 : to_pos(std::find_if(cbegin() + pos, cend(),
5423 nssv_constexpr size_type
5424 find_first_not_of(CharT c, size_type pos = 0) const nssv_noexcept
5426 return find_first_not_of(basic_string_view(&c, 1), pos);
5429 nssv_constexpr size_type find_first_not_of(CharT
const* s,
5431 size_type count)
const
5433 return find_first_not_of(basic_string_view(s, count), pos);
5436 nssv_constexpr size_type
5437 find_first_not_of(CharT
const* s, size_type pos = 0) const
5439 return find_first_not_of(basic_string_view(s), pos);
5444 nssv_constexpr size_type
5445 find_last_not_of(basic_string_view v,
5446 size_type pos = npos)
const nssv_noexcept
5448 return empty() ? npos
5450 ? find_last_not_of(v, size() - 1)
5451 : to_pos(std::find_if(
5452 const_reverse_iterator(cbegin() + pos + 1),
5453 crend(), not_in_view(v)));
5456 nssv_constexpr size_type find_last_not_of(
5457 CharT c, size_type pos = npos)
const nssv_noexcept
5459 return find_last_not_of(basic_string_view(&c, 1), pos);
5462 nssv_constexpr size_type find_last_not_of(CharT
const* s, size_type pos,
5463 size_type count)
const
5465 return find_last_not_of(basic_string_view(s, count), pos);
5468 nssv_constexpr size_type
5469 find_last_not_of(CharT
const* s, size_type pos = npos)
const
5471 return find_last_not_of(basic_string_view(s), pos);
5476#if nssv_CPP17_OR_GREATER
5477 static nssv_constexpr size_type npos = size_type(-1);
5478#elif nssv_CPP11_OR_GREATER
5479 enum : size_type { npos = size_type(-1) };
5481 enum { npos = size_type(-1) };
5485 struct not_in_view {
5486 const basic_string_view v;
5488 nssv_constexpr
explicit not_in_view(basic_string_view v_) : v(v_) {}
5490 nssv_constexpr
bool operator()(CharT c)
const {
5491 return npos == v.find_first_of(c);
5495 nssv_constexpr size_type to_pos(const_iterator it)
const {
5496 return it == cend() ? npos : size_type(it - cbegin());
5499 nssv_constexpr size_type to_pos(const_reverse_iterator it)
const {
5500 return it == crend() ? npos : size_type(crend() - it - 1);
5503 nssv_constexpr const_reference data_at(size_type pos)
const {
5504#if nssv_BETWEEN(nssv_COMPILER_GNUC_VERSION, 1, 500)
5507 return assert(pos < size()), data_[pos];
5512 const_pointer data_;
5516#if nssv_CONFIG_CONVERSION_STD_STRING_CLASS_METHODS
5518 template <
class Allocator>
5519 basic_string_view(std::basic_string<CharT, Traits, Allocator>
const& s)
5520 nssv_noexcept : data_(s.data()),
5523#if nssv_HAVE_EXPLICIT_CONVERSION
5525 template <
class Allocator>
5526 explicit operator std::basic_string<CharT, Traits, Allocator>()
const {
5527 return to_string(Allocator());
5532#if nssv_CPP11_OR_GREATER
5534 template <
class Allocator = std::allocator<CharT>>
5535 std::basic_string<CharT, Traits, Allocator>
5536 to_string(Allocator
const& a = Allocator())
const {
5537 return std::basic_string<CharT, Traits, Allocator>(begin(), end(),
5543 std::basic_string<CharT, Traits> to_string()
const {
5544 return std::basic_string<CharT, Traits>(begin(), end());
5547 template <
class Allocator>
5548 std::basic_string<CharT, Traits, Allocator>
5549 to_string(Allocator
const& a)
const {
5550 return std::basic_string<CharT, Traits, Allocator>(begin(), end(),
5566 template <
class CharT,
class Traits>
5568 operator==(basic_string_view<CharT, Traits> lhs,
5569 basic_string_view<CharT, Traits> rhs) nssv_noexcept {
5570 return lhs.size() == rhs.size() && lhs.compare(rhs) == 0;
5573 template <
class CharT,
class Traits>
5575 operator!=(basic_string_view<CharT, Traits> lhs,
5576 basic_string_view<CharT, Traits> rhs) nssv_noexcept {
5577 return !(lhs == rhs);
5580 template <
class CharT,
class Traits>
5582 operator<(basic_string_view<CharT, Traits> lhs,
5583 basic_string_view<CharT, Traits> rhs) nssv_noexcept {
5584 return lhs.compare(rhs) < 0;
5587 template <
class CharT,
class Traits>
5589 operator<=(basic_string_view<CharT, Traits> lhs,
5590 basic_string_view<CharT, Traits> rhs) nssv_noexcept {
5591 return lhs.compare(rhs) <= 0;
5594 template <
class CharT,
class Traits>
5596 operator>(basic_string_view<CharT, Traits> lhs,
5597 basic_string_view<CharT, Traits> rhs) nssv_noexcept {
5598 return lhs.compare(rhs) > 0;
5601 template <
class CharT,
class Traits>
5603 operator>=(basic_string_view<CharT, Traits> lhs,
5604 basic_string_view<CharT, Traits> rhs) nssv_noexcept {
5605 return lhs.compare(rhs) >= 0;
5613#if !nssv_CPP11_OR_GREATER || nssv_BETWEEN(nssv_COMPILER_MSVC_VERSION, 100, 141)
5619 template <
class CharT,
class Traits>
5620 nssv_constexpr
bool operator==(basic_string_view<CharT, Traits> lhs,
5621 CharT
const* rhs) nssv_noexcept {
5622 return lhs.size() == detail::length(rhs) && lhs.compare(rhs) == 0;
5625 template <
class CharT,
class Traits>
5627 operator==(CharT
const* lhs,
5628 basic_string_view<CharT, Traits> rhs) nssv_noexcept {
5629 return detail::length(lhs) == rhs.size() && rhs.compare(lhs) == 0;
5632 template <
class CharT,
class Traits>
5634 operator==(basic_string_view<CharT, Traits> lhs,
5635 std::basic_string<CharT, Traits> rhs) nssv_noexcept {
5636 return lhs.size() == rhs.size() && lhs.compare(rhs) == 0;
5639 template <
class CharT,
class Traits>
5641 operator==(std::basic_string<CharT, Traits> rhs,
5642 basic_string_view<CharT, Traits> lhs) nssv_noexcept {
5643 return lhs.size() == rhs.size() && lhs.compare(rhs) == 0;
5648 template <
class CharT,
class Traits>
5649 nssv_constexpr
bool operator!=(basic_string_view<CharT, Traits> lhs,
5650 CharT
const* rhs) nssv_noexcept {
5651 return !(lhs == rhs);
5654 template <
class CharT,
class Traits>
5656 operator!=(CharT
const* lhs,
5657 basic_string_view<CharT, Traits> rhs) nssv_noexcept {
5658 return !(lhs == rhs);
5661 template <
class CharT,
class Traits>
5663 operator!=(basic_string_view<CharT, Traits> lhs,
5664 std::basic_string<CharT, Traits> rhs) nssv_noexcept {
5665 return !(lhs == rhs);
5668 template <
class CharT,
class Traits>
5670 operator!=(std::basic_string<CharT, Traits> rhs,
5671 basic_string_view<CharT, Traits> lhs) nssv_noexcept {
5672 return !(lhs == rhs);
5677 template <
class CharT,
class Traits>
5678 nssv_constexpr
bool operator<(basic_string_view<CharT, Traits> lhs,
5679 CharT
const* rhs) nssv_noexcept {
5680 return lhs.compare(rhs) < 0;
5683 template <
class CharT,
class Traits>
5685 operator<(CharT
const* lhs,
5686 basic_string_view<CharT, Traits> rhs) nssv_noexcept {
5687 return rhs.compare(lhs) > 0;
5690 template <
class CharT,
class Traits>
5692 operator<(basic_string_view<CharT, Traits> lhs,
5693 std::basic_string<CharT, Traits> rhs) nssv_noexcept {
5694 return lhs.compare(rhs) < 0;
5697 template <
class CharT,
class Traits>
5699 operator<(std::basic_string<CharT, Traits> rhs,
5700 basic_string_view<CharT, Traits> lhs) nssv_noexcept {
5701 return rhs.compare(lhs) > 0;
5706 template <
class CharT,
class Traits>
5707 nssv_constexpr
bool operator<=(basic_string_view<CharT, Traits> lhs,
5708 CharT
const* rhs) nssv_noexcept {
5709 return lhs.compare(rhs) <= 0;
5712 template <
class CharT,
class Traits>
5714 operator<=(CharT
const* lhs,
5715 basic_string_view<CharT, Traits> rhs) nssv_noexcept {
5716 return rhs.compare(lhs) >= 0;
5719 template <
class CharT,
class Traits>
5721 operator<=(basic_string_view<CharT, Traits> lhs,
5722 std::basic_string<CharT, Traits> rhs) nssv_noexcept {
5723 return lhs.compare(rhs) <= 0;
5726 template <
class CharT,
class Traits>
5728 operator<=(std::basic_string<CharT, Traits> rhs,
5729 basic_string_view<CharT, Traits> lhs) nssv_noexcept {
5730 return rhs.compare(lhs) >= 0;
5735 template <
class CharT,
class Traits>
5736 nssv_constexpr
bool operator>(basic_string_view<CharT, Traits> lhs,
5737 CharT
const* rhs) nssv_noexcept {
5738 return lhs.compare(rhs) > 0;
5741 template <
class CharT,
class Traits>
5743 operator>(CharT
const* lhs,
5744 basic_string_view<CharT, Traits> rhs) nssv_noexcept {
5745 return rhs.compare(lhs) < 0;
5748 template <
class CharT,
class Traits>
5750 operator>(basic_string_view<CharT, Traits> lhs,
5751 std::basic_string<CharT, Traits> rhs) nssv_noexcept {
5752 return lhs.compare(rhs) > 0;
5755 template <
class CharT,
class Traits>
5757 operator>(std::basic_string<CharT, Traits> rhs,
5758 basic_string_view<CharT, Traits> lhs) nssv_noexcept {
5759 return rhs.compare(lhs) < 0;
5764 template <
class CharT,
class Traits>
5765 nssv_constexpr
bool operator>=(basic_string_view<CharT, Traits> lhs,
5766 CharT
const* rhs) nssv_noexcept {
5767 return lhs.compare(rhs) >= 0;
5770 template <
class CharT,
class Traits>
5772 operator>=(CharT
const* lhs,
5773 basic_string_view<CharT, Traits> rhs) nssv_noexcept {
5774 return rhs.compare(lhs) <= 0;
5777 template <
class CharT,
class Traits>
5779 operator>=(basic_string_view<CharT, Traits> lhs,
5780 std::basic_string<CharT, Traits> rhs) nssv_noexcept {
5781 return lhs.compare(rhs) >= 0;
5784 template <
class CharT,
class Traits>
5786 operator>=(std::basic_string<CharT, Traits> rhs,
5787 basic_string_view<CharT, Traits> lhs) nssv_noexcept {
5788 return rhs.compare(lhs) <= 0;
5793#define nssv_BASIC_STRING_VIEW_I(T, U) \
5794 typename std::decay<basic_string_view<T, U>>::type
5796#if defined(_MSC_VER)
5797#define nssv_MSVC_ORDER(x) , int = x
5799#define nssv_MSVC_ORDER(x)
5804 template <
class CharT,
class Traits nssv_MSVC_ORDER(1)>
5805 nssv_constexpr
bool operator==(basic_string_view<CharT, Traits> lhs,
5806 nssv_BASIC_STRING_VIEW_I(CharT, Traits)
5807 rhs) nssv_noexcept {
5808 return lhs.size() == rhs.size() && lhs.compare(rhs) == 0;
5811 template <
class CharT,
class Traits nssv_MSVC_ORDER(2)>
5813 operator==(nssv_BASIC_STRING_VIEW_I(CharT, Traits) lhs,
5814 basic_string_view<CharT, Traits> rhs) nssv_noexcept {
5815 return lhs.size() == rhs.size() && lhs.compare(rhs) == 0;
5820 template <
class CharT,
class Traits nssv_MSVC_ORDER(1)>
5821 nssv_constexpr
bool operator!=(basic_string_view<CharT, Traits> lhs,
5822 nssv_BASIC_STRING_VIEW_I(CharT, Traits)
5823 rhs) nssv_noexcept {
5824 return !(lhs == rhs);
5827 template <
class CharT,
class Traits nssv_MSVC_ORDER(2)>
5829 operator!=(nssv_BASIC_STRING_VIEW_I(CharT, Traits) lhs,
5830 basic_string_view<CharT, Traits> rhs) nssv_noexcept {
5831 return !(lhs == rhs);
5836 template <
class CharT,
class Traits nssv_MSVC_ORDER(1)>
5837 nssv_constexpr
bool operator<(basic_string_view<CharT, Traits> lhs,
5838 nssv_BASIC_STRING_VIEW_I(CharT, Traits)
5839 rhs) nssv_noexcept {
5840 return lhs.compare(rhs) < 0;
5843 template <
class CharT,
class Traits nssv_MSVC_ORDER(2)>
5845 operator<(nssv_BASIC_STRING_VIEW_I(CharT, Traits) lhs,
5846 basic_string_view<CharT, Traits> rhs) nssv_noexcept {
5847 return lhs.compare(rhs) < 0;
5852 template <
class CharT,
class Traits nssv_MSVC_ORDER(1)>
5853 nssv_constexpr
bool operator<=(basic_string_view<CharT, Traits> lhs,
5854 nssv_BASIC_STRING_VIEW_I(CharT, Traits)
5855 rhs) nssv_noexcept {
5856 return lhs.compare(rhs) <= 0;
5859 template <
class CharT,
class Traits nssv_MSVC_ORDER(2)>
5861 operator<=(nssv_BASIC_STRING_VIEW_I(CharT, Traits) lhs,
5862 basic_string_view<CharT, Traits> rhs) nssv_noexcept {
5863 return lhs.compare(rhs) <= 0;
5868 template <
class CharT,
class Traits nssv_MSVC_ORDER(1)>
5869 nssv_constexpr
bool operator>(basic_string_view<CharT, Traits> lhs,
5870 nssv_BASIC_STRING_VIEW_I(CharT, Traits)
5871 rhs) nssv_noexcept {
5872 return lhs.compare(rhs) > 0;
5875 template <
class CharT,
class Traits nssv_MSVC_ORDER(2)>
5877 operator>(nssv_BASIC_STRING_VIEW_I(CharT, Traits) lhs,
5878 basic_string_view<CharT, Traits> rhs) nssv_noexcept {
5879 return lhs.compare(rhs) > 0;
5884 template <
class CharT,
class Traits nssv_MSVC_ORDER(1)>
5885 nssv_constexpr
bool operator>=(basic_string_view<CharT, Traits> lhs,
5886 nssv_BASIC_STRING_VIEW_I(CharT, Traits)
5887 rhs) nssv_noexcept {
5888 return lhs.compare(rhs) >= 0;
5891 template <
class CharT,
class Traits nssv_MSVC_ORDER(2)>
5893 operator>=(nssv_BASIC_STRING_VIEW_I(CharT, Traits) lhs,
5894 basic_string_view<CharT, Traits> rhs) nssv_noexcept {
5895 return lhs.compare(rhs) >= 0;
5898#undef nssv_MSVC_ORDER
5899#undef nssv_BASIC_STRING_VIEW_I
5905#if !nssv_CONFIG_NO_STREAM_INSERTION
5909 template <
class Stream>
void write_padding(Stream& os, std::streamsize n) {
5910 for (std::streamsize i = 0; i < n; ++i)
5911 os.rdbuf()->sputc(os.fill());
5914 template <
class Stream,
class View>
5915 Stream& write_to_stream(Stream& os, View
const& sv) {
5916 typename Stream::sentry sentry(os);
5921 const std::streamsize length =
5922 static_cast<std::streamsize
>(sv.length());
5925 const bool pad = (length < os.width());
5926 const bool left_pad =
5928 (os.flags() & std::ios_base::adjustfield) == std::ios_base::right;
5931 write_padding(os, os.width() - length);
5934 os.rdbuf()->sputn(sv.begin(), length);
5936 if (pad && !left_pad)
5937 write_padding(os, os.width() - length);
5947 template <
class CharT,
class Traits>
5948 std::basic_ostream<CharT, Traits>&
5949 operator<<(std::basic_ostream<CharT, Traits>& os,
5950 basic_string_view<CharT, Traits> sv) {
5951 return detail::write_to_stream(os, sv);
5958 typedef basic_string_view<char> string_view;
5959 typedef basic_string_view<wchar_t> wstring_view;
5960#if nssv_HAVE_WCHAR16_T
5961 typedef basic_string_view<char16_t> u16string_view;
5962 typedef basic_string_view<char32_t> u32string_view;
5972#if nssv_HAVE_USER_DEFINED_LITERALS
5975nssv_inline_ns
namespace literals {
5976 nssv_inline_ns
namespace string_view_literals {
5978#if nssv_CONFIG_STD_SV_OPERATOR && nssv_HAVE_STD_DEFINED_LITERALS
5980 nssv_constexpr nonstd::sv_lite::string_view
operator"" sv(
5981 const char* str,
size_t len) nssv_noexcept
5983 return nonstd::sv_lite::string_view{str, len};
5986 nssv_constexpr nonstd::sv_lite::u16string_view
operator"" sv(
5987 const char16_t* str,
size_t len) nssv_noexcept
5989 return nonstd::sv_lite::u16string_view{str, len};
5992 nssv_constexpr nonstd::sv_lite::u32string_view
operator"" sv(
5993 const char32_t* str,
size_t len) nssv_noexcept
5995 return nonstd::sv_lite::u32string_view{str, len};
5998 nssv_constexpr nonstd::sv_lite::wstring_view
operator"" sv(
5999 const wchar_t* str,
size_t len) nssv_noexcept
6001 return nonstd::sv_lite::wstring_view{str, len};
6006#if nssv_CONFIG_USR_SV_OPERATOR
6008 nssv_constexpr nonstd::sv_lite::string_view
operator"" _sv(
6009 const char* str,
size_t len) nssv_noexcept
6011 return nonstd::sv_lite::string_view{str, len};
6014 nssv_constexpr nonstd::sv_lite::u16string_view
operator"" _sv(
6015 const char16_t* str,
size_t len) nssv_noexcept
6017 return nonstd::sv_lite::u16string_view{str, len};
6020 nssv_constexpr nonstd::sv_lite::u32string_view
operator"" _sv(
6021 const char32_t* str,
size_t len) nssv_noexcept
6023 return nonstd::sv_lite::u32string_view{str, len};
6026 nssv_constexpr nonstd::sv_lite::wstring_view
operator"" _sv(
6027 const wchar_t* str,
size_t len) nssv_noexcept
6029 return nonstd::sv_lite::wstring_view{str, len};
6043#if nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS
6050#if nssv_CPP11_OR_GREATER && nssv_COMPILER_MSVC_VERSION != 140
6052template <
class CharT,
class Traits,
class Allocator = std::allocator<CharT>>
6053std::basic_string<CharT, Traits, Allocator>
6054to_string(basic_string_view<CharT, Traits> v,
6055 Allocator
const& a = Allocator()) {
6056 return std::basic_string<CharT, Traits, Allocator>(v.begin(), v.end(), a);
6061template <
class CharT,
class Traits>
6062std::basic_string<CharT, Traits> to_string(basic_string_view<CharT, Traits> v) {
6063 return std::basic_string<CharT, Traits>(v.begin(), v.end());
6066template <
class CharT,
class Traits,
class Allocator>
6067std::basic_string<CharT, Traits, Allocator>
6068to_string(basic_string_view<CharT, Traits> v, Allocator
const& a) {
6069 return std::basic_string<CharT, Traits, Allocator>(v.begin(), v.end(), a);
6074template <
class CharT,
class Traits,
class Allocator>
6075basic_string_view<CharT, Traits>
6076to_string_view(std::basic_string<CharT, Traits, Allocator>
const& s) {
6077 return basic_string_view<CharT, Traits>(s.data(), s.size());
6091using sv_lite::basic_string_view;
6092using sv_lite::string_view;
6093using sv_lite::wstring_view;
6095#if nssv_HAVE_WCHAR16_T
6096using sv_lite::u16string_view;
6098#if nssv_HAVE_WCHAR32_T
6099using sv_lite::u32string_view;
6104using sv_lite::operator==;
6105using sv_lite::operator!=;
6106using sv_lite::operator<;
6107using sv_lite::operator<=;
6108using sv_lite::operator>;
6109using sv_lite::operator>=;
6111#if !nssv_CONFIG_NO_STREAM_INSERTION
6112using sv_lite::operator<<;
6115#if nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS
6116using sv_lite::to_string;
6117using sv_lite::to_string_view;
6127#if nssv_HAVE_STD_HASH
6129#include <functional>
6133template <>
struct hash<nonstd::string_view> {
6135 std::size_t operator()(nonstd::string_view v)
const nssv_noexcept {
6136 return std::hash<std::string>()(std::string(v.data(), v.size()));
6140template <>
struct hash<nonstd::wstring_view> {
6142 std::size_t operator()(nonstd::wstring_view v)
const nssv_noexcept {
6143 return std::hash<std::wstring>()(std::wstring(v.data(), v.size()));
6147template <>
struct hash<nonstd::u16string_view> {
6149 std::size_t operator()(nonstd::u16string_view v)
const nssv_noexcept {
6150 return std::hash<std::u16string>()(std::u16string(v.data(), v.size()));
6154template <>
struct hash<nonstd::u32string_view> {
6156 std::size_t operator()(nonstd::u32string_view v)
const nssv_noexcept {
6157 return std::hash<std::u32string>()(std::u32string(v.data(), v.size()));
6165nssv_RESTORE_WARNINGS()
6180#ifndef TERMCOLOR_HPP_
6181#define TERMCOLOR_HPP_
6186#if defined(_WIN32) || defined(_WIN64)
6187#define TERMCOLOR_OS_WINDOWS
6188#elif defined(__APPLE__)
6189#define TERMCOLOR_OS_MACOS
6190#elif defined(__unix__) || defined(__unix)
6191#define TERMCOLOR_OS_LINUX
6193#error unsupported platform
6200#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
6202#elif defined(TERMCOLOR_OS_WINDOWS)
6210namespace termcolor {
6213namespace _internal {
6216static int colorize_index = std::ios_base::xalloc();
6218inline FILE* get_standard_stream(
const std::ostream& stream);
6219inline bool is_colorized(std::ostream& stream);
6220inline bool is_atty(
const std::ostream& stream);
6222#if defined(TERMCOLOR_OS_WINDOWS)
6223inline void win_change_attributes(std::ostream& stream,
int foreground,
6224 int background = -1);
6228inline std::ostream& colorize(std::ostream& stream) {
6229 stream.iword(_internal::colorize_index) = 1L;
6233inline std::ostream& nocolorize(std::ostream& stream) {
6234 stream.iword(_internal::colorize_index) = 0L;
6238inline std::ostream& reset(std::ostream& stream) {
6239 if (_internal::is_colorized(stream)) {
6240#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
6241 stream <<
"\033[00m";
6242#elif defined(TERMCOLOR_OS_WINDOWS)
6243 _internal::win_change_attributes(stream, -1, -1);
6249inline std::ostream& bold(std::ostream& stream) {
6250 if (_internal::is_colorized(stream)) {
6251#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
6252 stream <<
"\033[1m";
6253#elif defined(TERMCOLOR_OS_WINDOWS)
6259inline std::ostream& dark(std::ostream& stream) {
6260 if (_internal::is_colorized(stream)) {
6261#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
6262 stream <<
"\033[2m";
6263#elif defined(TERMCOLOR_OS_WINDOWS)
6269inline std::ostream& italic(std::ostream& stream) {
6270 if (_internal::is_colorized(stream)) {
6271#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
6272 stream <<
"\033[3m";
6273#elif defined(TERMCOLOR_OS_WINDOWS)
6279inline std::ostream& underline(std::ostream& stream) {
6280 if (_internal::is_colorized(stream)) {
6281#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
6282 stream <<
"\033[4m";
6283#elif defined(TERMCOLOR_OS_WINDOWS)
6289inline std::ostream& blink(std::ostream& stream) {
6290 if (_internal::is_colorized(stream)) {
6291#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
6292 stream <<
"\033[5m";
6293#elif defined(TERMCOLOR_OS_WINDOWS)
6299inline std::ostream& reverse(std::ostream& stream) {
6300 if (_internal::is_colorized(stream)) {
6301#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
6302 stream <<
"\033[7m";
6303#elif defined(TERMCOLOR_OS_WINDOWS)
6309inline std::ostream& concealed(std::ostream& stream) {
6310 if (_internal::is_colorized(stream)) {
6311#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
6312 stream <<
"\033[8m";
6313#elif defined(TERMCOLOR_OS_WINDOWS)
6319inline std::ostream& crossed(std::ostream& stream) {
6320 if (_internal::is_colorized(stream)) {
6321#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
6322 stream <<
"\033[9m";
6323#elif defined(TERMCOLOR_OS_WINDOWS)
6329inline std::ostream& grey(std::ostream& stream) {
6330 if (_internal::is_colorized(stream)) {
6331#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
6332 stream <<
"\033[30m";
6333#elif defined(TERMCOLOR_OS_WINDOWS)
6334 _internal::win_change_attributes(stream,
6342inline std::ostream& red(std::ostream& stream) {
6343 if (_internal::is_colorized(stream)) {
6344#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
6345 stream <<
"\033[31m";
6346#elif defined(TERMCOLOR_OS_WINDOWS)
6347 _internal::win_change_attributes(stream, FOREGROUND_RED);
6353inline std::ostream& green(std::ostream& stream) {
6354 if (_internal::is_colorized(stream)) {
6355#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
6356 stream <<
"\033[32m";
6357#elif defined(TERMCOLOR_OS_WINDOWS)
6358 _internal::win_change_attributes(stream, FOREGROUND_GREEN);
6364inline std::ostream& yellow(std::ostream& stream) {
6365 if (_internal::is_colorized(stream)) {
6366#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
6367 stream <<
"\033[33m";
6368#elif defined(TERMCOLOR_OS_WINDOWS)
6369 _internal::win_change_attributes(stream,
6370 FOREGROUND_GREEN | FOREGROUND_RED);
6376inline std::ostream& blue(std::ostream& stream) {
6377 if (_internal::is_colorized(stream)) {
6378#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
6379 stream <<
"\033[34m";
6380#elif defined(TERMCOLOR_OS_WINDOWS)
6381 _internal::win_change_attributes(stream, FOREGROUND_BLUE);
6387inline std::ostream& magenta(std::ostream& stream) {
6388 if (_internal::is_colorized(stream)) {
6389#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
6390 stream <<
"\033[35m";
6391#elif defined(TERMCOLOR_OS_WINDOWS)
6392 _internal::win_change_attributes(stream,
6393 FOREGROUND_BLUE | FOREGROUND_RED);
6399inline std::ostream& cyan(std::ostream& stream) {
6400 if (_internal::is_colorized(stream)) {
6401#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
6402 stream <<
"\033[36m";
6403#elif defined(TERMCOLOR_OS_WINDOWS)
6404 _internal::win_change_attributes(stream, FOREGROUND_BLUE |
6411inline std::ostream& white(std::ostream& stream) {
6412 if (_internal::is_colorized(stream)) {
6413#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
6414 stream <<
"\033[37m";
6415#elif defined(TERMCOLOR_OS_WINDOWS)
6416 _internal::win_change_attributes(
6417 stream, FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED);
6423inline std::ostream& on_grey(std::ostream& stream) {
6424 if (_internal::is_colorized(stream)) {
6425#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
6426 stream <<
"\033[40m";
6427#elif defined(TERMCOLOR_OS_WINDOWS)
6428 _internal::win_change_attributes(stream, -1,
6436inline std::ostream& on_red(std::ostream& stream) {
6437 if (_internal::is_colorized(stream)) {
6438#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
6439 stream <<
"\033[41m";
6440#elif defined(TERMCOLOR_OS_WINDOWS)
6441 _internal::win_change_attributes(stream, -1, BACKGROUND_RED);
6447inline std::ostream& on_green(std::ostream& stream) {
6448 if (_internal::is_colorized(stream)) {
6449#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
6450 stream <<
"\033[42m";
6451#elif defined(TERMCOLOR_OS_WINDOWS)
6452 _internal::win_change_attributes(stream, -1, BACKGROUND_GREEN);
6458inline std::ostream& on_yellow(std::ostream& stream) {
6459 if (_internal::is_colorized(stream)) {
6460#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
6461 stream <<
"\033[43m";
6462#elif defined(TERMCOLOR_OS_WINDOWS)
6463 _internal::win_change_attributes(stream, -1,
6464 BACKGROUND_GREEN | BACKGROUND_RED);
6470inline std::ostream& on_blue(std::ostream& stream) {
6471 if (_internal::is_colorized(stream)) {
6472#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
6473 stream <<
"\033[44m";
6474#elif defined(TERMCOLOR_OS_WINDOWS)
6475 _internal::win_change_attributes(stream, -1, BACKGROUND_BLUE);
6481inline std::ostream& on_magenta(std::ostream& stream) {
6482 if (_internal::is_colorized(stream)) {
6483#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
6484 stream <<
"\033[45m";
6485#elif defined(TERMCOLOR_OS_WINDOWS)
6486 _internal::win_change_attributes(stream, -1,
6487 BACKGROUND_BLUE | BACKGROUND_RED);
6493inline std::ostream& on_cyan(std::ostream& stream) {
6494 if (_internal::is_colorized(stream)) {
6495#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
6496 stream <<
"\033[46m";
6497#elif defined(TERMCOLOR_OS_WINDOWS)
6498 _internal::win_change_attributes(
6499 stream, -1, BACKGROUND_GREEN | BACKGROUND_BLUE);
6505inline std::ostream& on_white(std::ostream& stream) {
6506 if (_internal::is_colorized(stream)) {
6507#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
6508 stream <<
"\033[47m";
6509#elif defined(TERMCOLOR_OS_WINDOWS)
6510 _internal::win_change_attributes(
6512 BACKGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_RED);
6523namespace _internal {
6527inline FILE* get_standard_stream(
const std::ostream& stream) {
6528 if (&stream == &std::cout)
6530 else if ((&stream == &std::cerr) || (&stream == &std::clog))
6539inline bool is_colorized(std::ostream& stream) {
6540 return is_atty(stream) ||
static_cast<bool>(stream.iword(colorize_index));
6545inline bool is_atty(
const std::ostream& stream) {
6546 FILE* std_stream = get_standard_stream(stream);
6555#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
6556 return ::isatty(fileno(std_stream));
6557#elif defined(TERMCOLOR_OS_WINDOWS)
6558 return ::_isatty(_fileno(std_stream));
6562#if defined(TERMCOLOR_OS_WINDOWS)
6565inline void win_change_attributes(std::ostream& stream,
int foreground,
6568 static WORD defaultAttributes = 0;
6574 if (!_internal::is_atty(stream))
6578 HANDLE hTerminal = INVALID_HANDLE_VALUE;
6579 if (&stream == &std::cout)
6580 hTerminal = GetStdHandle(STD_OUTPUT_HANDLE);
6581 else if (&stream == &std::cerr)
6582 hTerminal = GetStdHandle(STD_ERROR_HANDLE);
6585 if (!defaultAttributes) {
6586 CONSOLE_SCREEN_BUFFER_INFO info;
6587 if (!GetConsoleScreenBufferInfo(hTerminal, &info))
6589 defaultAttributes = info.wAttributes;
6593 if (foreground == -1 && background == -1) {
6594 SetConsoleTextAttribute(hTerminal, defaultAttributes);
6599 CONSOLE_SCREEN_BUFFER_INFO info;
6600 if (!GetConsoleScreenBufferInfo(hTerminal, &info))
6603 if (foreground != -1) {
6604 info.wAttributes &= ~(info.wAttributes & 0x0F);
6605 info.wAttributes |=
static_cast<WORD
>(foreground);
6608 if (background != -1) {
6609 info.wAttributes &= ~(info.wAttributes & 0xF0);
6610 info.wAttributes |=
static_cast<WORD
>(background);
6613 SetConsoleTextAttribute(hTerminal, info.wAttributes);
6621#undef TERMCOLOR_OS_WINDOWS
6622#undef TERMCOLOR_OS_MACOS
6623#undef TERMCOLOR_OS_LINUX
6673#if defined(__unix__) || defined(__unix) || defined(__APPLE__)
6674inline int get_wcswidth(
const std::string&
string,
const std::string& locale,
6675 size_t max_column_width) {
6676 if (
string.size() == 0)
6682 auto old_locale = std::locale::global(std::locale(locale));
6685 wchar_t* wide_string =
new wchar_t[
string.size()];
6686 std::mbstowcs(wide_string,
string.c_str(),
string.size());
6689 int result = wcswidth(wide_string, max_column_width);
6690 delete[] wide_string;
6693 std::locale::global(old_locale);
6700get_sequence_length(
const std::string& text,
const std::string& locale,
6701 bool is_multi_byte_character_support_enabled) {
6702 if (!is_multi_byte_character_support_enabled)
6703 return text.length();
6705#if defined(_WIN32) || defined(_WIN64)
6707 return (text.length() -
6708 std::count_if(text.begin(), text.end(),
6709 [](
char c) ->
bool { return (c & 0xC0) == 0x80; }));
6710#elif defined(__unix__) || defined(__unix) || defined(__APPLE__)
6711 auto result = get_wcswidth(text, locale, text.size());
6715 return (text.length() -
6716 std::count_if(text.begin(), text.end(), [](
char c) ->
bool {
6717 return (c & 0xC0) == 0x80;
6761enum class Color { none, grey, red, green, yellow, blue, magenta, cyan, white };
6800enum class FontAlign { left, right, center };
6839enum class FontStyle {
6931#if __cplusplus >= 201703L
6936using nonstd::optional;
6945 Format& width(
size_t value) {
6950 Format& height(
size_t value) {
6955 Format& padding(
size_t value) {
6956 padding_left_ = value;
6957 padding_right_ = value;
6958 padding_top_ = value;
6959 padding_bottom_ = value;
6963 Format& padding_left(
size_t value) {
6964 padding_left_ = value;
6968 Format& padding_right(
size_t value) {
6969 padding_right_ = value;
6973 Format& padding_top(
size_t value) {
6974 padding_top_ = value;
6978 Format& padding_bottom(
size_t value) {
6979 padding_bottom_ = value;
6983 Format& border(
const std::string& value) {
6984 border_left_ = value;
6985 border_right_ = value;
6986 border_top_ = value;
6987 border_bottom_ = value;
6991 Format& border_color(Color value) {
6992 border_left_color_ = value;
6993 border_right_color_ = value;
6994 border_top_color_ = value;
6995 border_bottom_color_ = value;
6999 Format& border_background_color(Color value) {
7000 border_left_background_color_ = value;
7001 border_right_background_color_ = value;
7002 border_top_background_color_ = value;
7003 border_bottom_background_color_ = value;
7007 Format& border_left(
const std::string& value) {
7008 border_left_ = value;
7012 Format& border_left_color(Color value) {
7013 border_left_color_ = value;
7017 Format& border_left_background_color(Color value) {
7018 border_left_background_color_ = value;
7022 Format& border_right(
const std::string& value) {
7023 border_right_ = value;
7027 Format& border_right_color(Color value) {
7028 border_right_color_ = value;
7032 Format& border_right_background_color(Color value) {
7033 border_right_background_color_ = value;
7037 Format& border_top(
const std::string& value) {
7038 border_top_ = value;
7042 Format& border_top_color(Color value) {
7043 border_top_color_ = value;
7047 Format& border_top_background_color(Color value) {
7048 border_top_background_color_ = value;
7052 Format& border_bottom(
const std::string& value) {
7053 border_bottom_ = value;
7057 Format& border_bottom_color(Color value) {
7058 border_bottom_color_ = value;
7062 Format& border_bottom_background_color(Color value) {
7063 border_bottom_background_color_ = value;
7067 Format& show_border() {
7068 show_border_top_ =
true;
7069 show_border_bottom_ =
true;
7070 show_border_left_ =
true;
7071 show_border_right_ =
true;
7075 Format& hide_border() {
7076 show_border_top_ =
false;
7077 show_border_bottom_ =
false;
7078 show_border_left_ =
false;
7079 show_border_right_ =
false;
7083 Format& show_border_top() {
7084 show_border_top_ =
true;
7088 Format& hide_border_top() {
7089 show_border_top_ =
false;
7093 Format& show_border_bottom() {
7094 show_border_bottom_ =
true;
7098 Format& hide_border_bottom() {
7099 show_border_bottom_ =
false;
7103 Format& show_border_left() {
7104 show_border_left_ =
true;
7108 Format& hide_border_left() {
7109 show_border_left_ =
false;
7113 Format& show_border_right() {
7114 show_border_right_ =
true;
7118 Format& hide_border_right() {
7119 show_border_right_ =
false;
7123 Format& show_row_separator() {
7124 show_border_top_ =
true;
7125 show_row_separator_ =
true;
7129 Format& corner(
const std::string& value) {
7130 corner_top_left_ = value;
7131 corner_top_right_ = value;
7132 corner_bottom_left_ = value;
7133 corner_bottom_right_ = value;
7137 Format& corner_color(Color value) {
7138 corner_top_left_color_ = value;
7139 corner_top_right_color_ = value;
7140 corner_bottom_left_color_ = value;
7141 corner_bottom_right_color_ = value;
7145 Format& corner_background_color(Color value) {
7146 corner_top_left_background_color_ = value;
7147 corner_top_right_background_color_ = value;
7148 corner_bottom_left_background_color_ = value;
7149 corner_bottom_right_background_color_ = value;
7153 Format& corner_top_left(
const std::string& value) {
7154 corner_top_left_ = value;
7158 Format& corner_top_left_color(Color value) {
7159 corner_top_left_color_ = value;
7163 Format& corner_top_left_background_color(Color value) {
7164 corner_top_left_background_color_ = value;
7168 Format& corner_top_right(
const std::string& value) {
7169 corner_top_right_ = value;
7173 Format& corner_top_right_color(Color value) {
7174 corner_top_right_color_ = value;
7178 Format& corner_top_right_background_color(Color value) {
7179 corner_top_right_background_color_ = value;
7183 Format& corner_bottom_left(
const std::string& value) {
7184 corner_bottom_left_ = value;
7188 Format& corner_bottom_left_color(Color value) {
7189 corner_bottom_left_color_ = value;
7193 Format& corner_bottom_left_background_color(Color value) {
7194 corner_bottom_left_background_color_ = value;
7198 Format& corner_bottom_right(
const std::string& value) {
7199 corner_bottom_right_ = value;
7203 Format& corner_bottom_right_color(Color value) {
7204 corner_bottom_right_color_ = value;
7208 Format& corner_bottom_right_background_color(Color value) {
7209 corner_bottom_right_background_color_ = value;
7213 Format& column_separator(
const std::string& value) {
7214 column_separator_ = value;
7218 Format& column_separator_color(Color value) {
7219 column_separator_color_ = value;
7223 Format& column_separator_background_color(Color value) {
7224 column_separator_background_color_ = value;
7228 Format& font_align(FontAlign value) {
7229 font_align_ = value;
7233 Format& font_style(
const std::vector<FontStyle>& style) {
7234 if (font_style_.has_value()) {
7235 for (
auto& s : style)
7236 font_style_->push_back(s);
7238 font_style_ = style;
7243 Format& font_color(Color value) {
7244 font_color_ = value;
7248 Format& font_background_color(Color value) {
7249 font_background_color_ = value;
7253 Format& color(Color value) {
7255 border_color(value);
7256 corner_color(value);
7260 Format& background_color(Color value) {
7261 font_background_color(value);
7262 border_background_color(value);
7263 corner_background_color(value);
7267 Format& multi_byte_characters(
bool value) {
7268 multi_byte_characters_ = value;
7272 Format& locale(
const std::string& value) {
7277 enum class TrimMode {
7281 kBoth = kLeft | kRight,
7284 Format& trim_mode(TrimMode trim_mode) {
7285 trim_mode_ = trim_mode;
7292 static std::string word_wrap(
const std::string& str,
size_t width,
7293 const std::string& locale,
7294 bool is_multi_byte_character_support_enabled) {
7295 std::vector<std::string> words = explode_string(str, {
" ",
"-",
"\t"});
7296 size_t current_line_length = 0;
7299 for (
size_t i = 0; i < words.size(); ++i) {
7300 std::string word = words[i];
7303 if (current_line_length +
7304 get_sequence_length(
7305 word, locale, is_multi_byte_character_support_enabled) >
7310 if (current_line_length > 0) {
7312 current_line_length = 0;
7317 while (get_sequence_length(
7319 is_multi_byte_character_support_enabled) > width) {
7320 result += word.substr(0, width - 1) +
"-";
7321 word = word.substr(width - 1);
7327 word = trim_left(word);
7330 current_line_length += get_sequence_length(
7331 word, locale, is_multi_byte_character_support_enabled);
7336 static std::vector<std::string>
7337 split_lines(
const std::string& text,
const std::string& delimiter,
7338 const std::string& locale,
7339 bool is_multi_byte_character_support_enabled) {
7340 std::vector<std::string> result{};
7341 std::string input = text;
7344 while ((pos = input.find(delimiter)) != std::string::npos) {
7345 token = input.substr(0, pos);
7346 result.push_back(token);
7347 input.erase(0, pos + delimiter.length());
7349 if (get_sequence_length(input, locale,
7350 is_multi_byte_character_support_enabled))
7351 result.push_back(input);
7361 static Format merge(Format first, Format second) {
7365 if (first.width_.has_value())
7366 result.width_ = first.width_;
7368 result.width_ = second.width_;
7370 if (first.height_.has_value())
7371 result.height_ = first.height_;
7373 result.height_ = second.height_;
7376 if (first.font_align_.has_value())
7377 result.font_align_ = first.font_align_;
7379 result.font_align_ = second.font_align_;
7381 if (first.font_style_.has_value()) {
7383 std::vector<FontStyle> merged_font_style(
7384 first.font_style_->size() + second.font_style_->size());
7385#if defined(_WIN32) || defined(_WIN64)
7387 std::sort(first.font_style_->begin(), first.font_style_->end());
7388 std::sort(second.font_style_->begin(), second.font_style_->end());
7390 std::set_union(first.font_style_->begin(), first.font_style_->end(),
7391 second.font_style_->begin(),
7392 second.font_style_->end(),
7393 merged_font_style.begin());
7394 result.font_style_ = merged_font_style;
7396 result.font_style_ = second.font_style_;
7398 if (first.font_color_.has_value())
7399 result.font_color_ = first.font_color_;
7401 result.font_color_ = second.font_color_;
7403 if (first.font_background_color_.has_value())
7404 result.font_background_color_ = first.font_background_color_;
7406 result.font_background_color_ = second.font_background_color_;
7409 if (first.padding_left_.has_value())
7410 result.padding_left_ = first.padding_left_;
7412 result.padding_left_ = second.padding_left_;
7414 if (first.padding_top_.has_value())
7415 result.padding_top_ = first.padding_top_;
7417 result.padding_top_ = second.padding_top_;
7419 if (first.padding_right_.has_value())
7420 result.padding_right_ = first.padding_right_;
7422 result.padding_right_ = second.padding_right_;
7424 if (first.padding_bottom_.has_value())
7425 result.padding_bottom_ = first.padding_bottom_;
7427 result.padding_bottom_ = second.padding_bottom_;
7430 if (first.border_left_.has_value())
7431 result.border_left_ = first.border_left_;
7433 result.border_left_ = second.border_left_;
7435 if (first.border_left_color_.has_value())
7436 result.border_left_color_ = first.border_left_color_;
7438 result.border_left_color_ = second.border_left_color_;
7440 if (first.border_left_background_color_.has_value())
7441 result.border_left_background_color_ =
7442 first.border_left_background_color_;
7444 result.border_left_background_color_ =
7445 second.border_left_background_color_;
7447 if (first.border_top_.has_value())
7448 result.border_top_ = first.border_top_;
7450 result.border_top_ = second.border_top_;
7452 if (first.border_top_color_.has_value())
7453 result.border_top_color_ = first.border_top_color_;
7455 result.border_top_color_ = second.border_top_color_;
7457 if (first.border_top_background_color_.has_value())
7458 result.border_top_background_color_ =
7459 first.border_top_background_color_;
7461 result.border_top_background_color_ =
7462 second.border_top_background_color_;
7464 if (first.border_bottom_.has_value())
7465 result.border_bottom_ = first.border_bottom_;
7467 result.border_bottom_ = second.border_bottom_;
7469 if (first.border_bottom_color_.has_value())
7470 result.border_bottom_color_ = first.border_bottom_color_;
7472 result.border_bottom_color_ = second.border_bottom_color_;
7474 if (first.border_bottom_background_color_.has_value())
7475 result.border_bottom_background_color_ =
7476 first.border_bottom_background_color_;
7478 result.border_bottom_background_color_ =
7479 second.border_bottom_background_color_;
7481 if (first.border_right_.has_value())
7482 result.border_right_ = first.border_right_;
7484 result.border_right_ = second.border_right_;
7486 if (first.border_right_color_.has_value())
7487 result.border_right_color_ = first.border_right_color_;
7489 result.border_right_color_ = second.border_right_color_;
7491 if (first.border_right_background_color_.has_value())
7492 result.border_right_background_color_ =
7493 first.border_right_background_color_;
7495 result.border_right_background_color_ =
7496 second.border_right_background_color_;
7498 if (first.show_border_top_.has_value())
7499 result.show_border_top_ = first.show_border_top_;
7501 result.show_border_top_ = second.show_border_top_;
7503 if (first.show_border_bottom_.has_value())
7504 result.show_border_bottom_ = first.show_border_bottom_;
7506 result.show_border_bottom_ = second.show_border_bottom_;
7508 if (first.show_border_left_.has_value())
7509 result.show_border_left_ = first.show_border_left_;
7511 result.show_border_left_ = second.show_border_left_;
7513 if (first.show_border_right_.has_value())
7514 result.show_border_right_ = first.show_border_right_;
7516 result.show_border_right_ = second.show_border_right_;
7519 if (first.corner_top_left_.has_value())
7520 result.corner_top_left_ = first.corner_top_left_;
7522 result.corner_top_left_ = second.corner_top_left_;
7524 if (first.corner_top_left_color_.has_value())
7525 result.corner_top_left_color_ = first.corner_top_left_color_;
7527 result.corner_top_left_color_ = second.corner_top_left_color_;
7529 if (first.corner_top_left_background_color_.has_value())
7530 result.corner_top_left_background_color_ =
7531 first.corner_top_left_background_color_;
7533 result.corner_top_left_background_color_ =
7534 second.corner_top_left_background_color_;
7536 if (first.corner_top_right_.has_value())
7537 result.corner_top_right_ = first.corner_top_right_;
7539 result.corner_top_right_ = second.corner_top_right_;
7541 if (first.corner_top_right_color_.has_value())
7542 result.corner_top_right_color_ = first.corner_top_right_color_;
7544 result.corner_top_right_color_ = second.corner_top_right_color_;
7546 if (first.corner_top_right_background_color_.has_value())
7547 result.corner_top_right_background_color_ =
7548 first.corner_top_right_background_color_;
7550 result.corner_top_right_background_color_ =
7551 second.corner_top_right_background_color_;
7553 if (first.corner_bottom_left_.has_value())
7554 result.corner_bottom_left_ = first.corner_bottom_left_;
7556 result.corner_bottom_left_ = second.corner_bottom_left_;
7558 if (first.corner_bottom_left_color_.has_value())
7559 result.corner_bottom_left_color_ = first.corner_bottom_left_color_;
7561 result.corner_bottom_left_color_ = second.corner_bottom_left_color_;
7563 if (first.corner_bottom_left_background_color_.has_value())
7564 result.corner_bottom_left_background_color_ =
7565 first.corner_bottom_left_background_color_;
7567 result.corner_bottom_left_background_color_ =
7568 second.corner_bottom_left_background_color_;
7570 if (first.corner_bottom_right_.has_value())
7571 result.corner_bottom_right_ = first.corner_bottom_right_;
7573 result.corner_bottom_right_ = second.corner_bottom_right_;
7575 if (first.corner_bottom_right_color_.has_value())
7576 result.corner_bottom_right_color_ =
7577 first.corner_bottom_right_color_;
7579 result.corner_bottom_right_color_ =
7580 second.corner_bottom_right_color_;
7582 if (first.corner_bottom_right_background_color_.has_value())
7583 result.corner_bottom_right_background_color_ =
7584 first.corner_bottom_right_background_color_;
7586 result.corner_bottom_right_background_color_ =
7587 second.corner_bottom_right_background_color_;
7589 if (first.column_separator_.has_value())
7590 result.column_separator_ = first.column_separator_;
7592 result.column_separator_ = second.column_separator_;
7594 if (first.column_separator_color_.has_value())
7595 result.column_separator_color_ = first.column_separator_color_;
7597 result.column_separator_color_ = second.column_separator_color_;
7599 if (first.column_separator_background_color_.has_value())
7600 result.column_separator_background_color_ =
7601 first.column_separator_background_color_;
7603 result.column_separator_background_color_ =
7604 second.column_separator_background_color_;
7607 if (first.multi_byte_characters_.has_value())
7608 result.multi_byte_characters_ = first.multi_byte_characters_;
7610 result.multi_byte_characters_ = second.multi_byte_characters_;
7612 if (first.locale_.has_value())
7613 result.locale_ = first.locale_;
7615 result.locale_ = second.locale_;
7617 if (first.trim_mode_.has_value())
7618 result.trim_mode_ = first.trim_mode_;
7620 result.trim_mode_ = second.trim_mode_;
7622 if (first.show_row_separator_.has_value())
7623 result.show_row_separator_ = first.show_row_separator_;
7625 result.show_row_separator_ = second.show_row_separator_;
7633 friend class Column;
7634 friend class TableInternal;
7635 friend class Printer;
7636 friend class MarkdownExporter;
7637 friend class LatexExporter;
7638 friend class AsciiDocExporter;
7640 void set_defaults() {
7642 font_align_ = FontAlign::left;
7643 font_style_ = std::vector<FontStyle>{};
7644 font_color_ = font_background_color_ = Color::none;
7645 padding_left_ = padding_right_ = 1;
7646 padding_top_ = padding_bottom_ = 0;
7647 border_top_ = border_bottom_ =
"-";
7648 border_left_ = border_right_ =
"|";
7649 show_border_left_ = show_border_right_ = show_border_top_ =
7650 show_border_bottom_ =
true;
7651 border_top_color_ = border_top_background_color_ =
7652 border_bottom_color_ = border_bottom_background_color_ =
7653 border_left_color_ = border_left_background_color_ =
7654 border_right_color_ = border_right_background_color_ =
7656 corner_top_left_ = corner_top_right_ = corner_bottom_left_ =
7657 corner_bottom_right_ =
"+";
7658 corner_top_left_color_ = corner_top_left_background_color_ =
7659 corner_top_right_color_ = corner_top_right_background_color_ =
7660 corner_bottom_left_color_ =
7661 corner_bottom_left_background_color_ =
7662 corner_bottom_right_color_ =
7663 corner_bottom_right_background_color_ = Color::none;
7664 column_separator_ =
"|";
7665 column_separator_color_ = column_separator_background_color_ =
7667 multi_byte_characters_ =
false;
7669 trim_mode_ = TrimMode::kBoth;
7670 show_row_separator_ =
false;
7676 static std::string trim_left(
const std::string& input_string) {
7677 std::string result = input_string;
7678 result.erase(result.begin(),
7679 std::find_if(result.begin(), result.end(),
7680 [](
int ch) { return !std::isspace(ch); }));
7685 static std::string trim_right(
const std::string& input_string) {
7686 std::string result = input_string;
7687 result.erase(std::find_if(result.rbegin(), result.rend(),
7688 [](
int ch) { return !std::isspace(ch); })
7695 static std::string trim(
const std::string& input_string) {
7696 return trim_left(trim_right(input_string));
7700 index_of_any(
const std::string& input,
size_t start_index,
7701 const std::vector<std::string>& split_characters) {
7702 std::vector<size_t> indices{};
7703 for (
auto& c : split_characters) {
7704 auto index = input.find(c, start_index);
7705 if (index != std::string::npos)
7706 indices.push_back(index);
7708 if (indices.size() > 0)
7709 return *std::min_element(indices.begin(), indices.end());
7711 return std::string::npos;
7714 static std::vector<std::string>
7715 explode_string(
const std::string& input,
7716 const std::vector<std::string>& split_characters) {
7717 std::vector<std::string> result{};
7718 size_t start_index{0};
7720 auto index = index_of_any(input, start_index, split_characters);
7722 if (index == std::string::npos) {
7723 result.push_back(input.substr(start_index));
7727 std::string word = input.substr(start_index, index - start_index);
7728 char next_character = input.substr(index, 1)[0];
7731 if (isspace(next_character)) {
7732 result.push_back(word);
7733 result.push_back(std::string(1, next_character));
7735 result.push_back(word + next_character);
7737 start_index = index + 1;
7744 optional<size_t> width_{};
7745 optional<size_t> height_{};
7748 optional<FontAlign> font_align_{};
7749 optional<std::vector<FontStyle>> font_style_{};
7750 optional<Color> font_color_{};
7751 optional<Color> font_background_color_{};
7754 optional<size_t> padding_left_{};
7755 optional<size_t> padding_top_{};
7756 optional<size_t> padding_right_{};
7757 optional<size_t> padding_bottom_{};
7760 optional<bool> show_border_top_{};
7761 optional<std::string> border_top_{};
7762 optional<Color> border_top_color_{};
7763 optional<Color> border_top_background_color_{};
7765 optional<bool> show_border_bottom_{};
7766 optional<std::string> border_bottom_{};
7767 optional<Color> border_bottom_color_{};
7768 optional<Color> border_bottom_background_color_{};
7770 optional<bool> show_border_left_{};
7771 optional<std::string> border_left_{};
7772 optional<Color> border_left_color_{};
7773 optional<Color> border_left_background_color_{};
7775 optional<bool> show_border_right_{};
7776 optional<std::string> border_right_{};
7777 optional<Color> border_right_color_{};
7778 optional<Color> border_right_background_color_{};
7781 optional<std::string> corner_top_left_{};
7782 optional<Color> corner_top_left_color_{};
7783 optional<Color> corner_top_left_background_color_{};
7785 optional<std::string> corner_top_right_{};
7786 optional<Color> corner_top_right_color_{};
7787 optional<Color> corner_top_right_background_color_{};
7789 optional<std::string> corner_bottom_left_{};
7790 optional<Color> corner_bottom_left_color_{};
7791 optional<Color> corner_bottom_left_background_color_{};
7793 optional<std::string> corner_bottom_right_{};
7794 optional<Color> corner_bottom_right_color_{};
7795 optional<Color> corner_bottom_right_background_color_{};
7798 optional<std::string> column_separator_{};
7799 optional<Color> column_separator_color_{};
7800 optional<Color> column_separator_background_color_{};
7803 optional<bool> multi_byte_characters_{};
7804 optional<std::string> locale_{};
7806 optional<TrimMode> trim_mode_{};
7808 optional<bool> show_row_separator_{};
7815#if __cplusplus >= 201703L
7820using nonstd::optional;
7829 explicit Cell(std::shared_ptr<class Row> parent) : parent_(parent) {}
7831 void set_text(
const std::string& text) { data_ = text; }
7833 const std::string& get_text() {
return data_; }
7836 return get_sequence_length(data_, locale(),
7837 is_multi_byte_character_support_enabled());
7840 std::string locale() {
return *format().locale_; }
7844 bool is_multi_byte_character_support_enabled();
7848 std::weak_ptr<class Row> parent_;
7849 optional<Format> format_;
7892#if __cplusplus >= 201703L
7897using nonstd::optional;
7912 explicit Row(std::shared_ptr<class TableInternal> parent)
7913 : parent_(parent) {}
7915 void add_cell(std::shared_ptr<Cell> cell) { cells_.push_back(cell); }
7917 Cell& operator[](
size_t index) {
return cell(index); }
7919 Cell& cell(
size_t index) {
return *(cells_[index]); }
7921 std::vector<std::shared_ptr<Cell>> cells()
const {
return cells_; }
7923 size_t size()
const {
return cells_.size(); }
7927 class CellIterator {
7929 explicit CellIterator(std::vector<std::shared_ptr<Cell>>::iterator ptr)
7932 CellIterator operator++() {
7936 bool operator!=(
const CellIterator& other)
const {
7937 return ptr != other.ptr;
7939 Cell& operator*() {
return **ptr; }
7942 std::vector<std::shared_ptr<Cell>>::iterator ptr;
7945 auto begin() -> CellIterator {
return CellIterator(cells_.begin()); }
7946 auto end() -> CellIterator {
return CellIterator(cells_.end()); }
7949 friend class Printer;
7956 size_t get_configured_height() {
7958 for (
size_t i = 0; i < size(); ++i) {
7959 auto cell = cells_[i];
7960 auto format = cell->format();
7961 if (format.height_.has_value())
7962 result = std::max(result, *format.height_);
7976 size_t get_computed_height(
const std::vector<size_t>& column_widths) {
7978 for (
size_t i = 0; i < size(); ++i) {
7979 result = std::max(result, get_cell_height(i, column_widths[i]));
7998 size_t get_cell_height(
size_t cell_index,
size_t column_width) {
8000 Cell& cell = *(cells_[cell_index]);
8001 auto format = cell.format();
8002 auto text = cell.get_text();
8004 auto padding_left = *format.padding_left_;
8005 auto padding_right = *format.padding_right_;
8007 result += *format.padding_top_;
8009 if (column_width > (padding_left + padding_right)) {
8010 column_width -= (padding_left + padding_right);
8014 auto newlines_in_text = std::count(text.begin(), text.end(),
'\n');
8015 std::string word_wrapped_text;
8016 if (newlines_in_text == 0) {
8019 word_wrapped_text = Format::word_wrap(
8020 text, column_width, cell.locale(),
8021 cell.is_multi_byte_character_support_enabled());
8025 word_wrapped_text = text;
8028 auto newlines_in_wrapped_text = std::count(
8029 word_wrapped_text.begin(), word_wrapped_text.end(),
'\n');
8030 auto estimated_row_height = newlines_in_wrapped_text;
8032 if (!word_wrapped_text.empty() &&
8033 word_wrapped_text[word_wrapped_text.size() - 1] !=
8035 estimated_row_height += 1;
8037 result += estimated_row_height;
8039 result += *format.padding_bottom_;
8044 std::vector<std::shared_ptr<Cell>> cells_;
8045 std::weak_ptr<class TableInternal> parent_;
8046 optional<Format> format_;
8087class ColumnFormat :
public Format {
8089 explicit ColumnFormat(
class Column& column) : column_(column) {}
8091 ColumnFormat& width(
size_t value);
8092 ColumnFormat& height(
size_t value);
8095 ColumnFormat& padding(
size_t value);
8096 ColumnFormat& padding_left(
size_t value);
8097 ColumnFormat& padding_right(
size_t value);
8098 ColumnFormat& padding_top(
size_t value);
8099 ColumnFormat& padding_bottom(
size_t value);
8102 ColumnFormat& border(
const std::string& value);
8103 ColumnFormat& border_color(Color value);
8104 ColumnFormat& border_background_color(Color value);
8105 ColumnFormat& border_left(
const std::string& value);
8106 ColumnFormat& border_left_color(Color value);
8107 ColumnFormat& border_left_background_color(Color value);
8108 ColumnFormat& border_right(
const std::string& value);
8109 ColumnFormat& border_right_color(Color value);
8110 ColumnFormat& border_right_background_color(Color value);
8111 ColumnFormat& border_top(
const std::string& value);
8112 ColumnFormat& border_top_color(Color value);
8113 ColumnFormat& border_top_background_color(Color value);
8114 ColumnFormat& border_bottom(
const std::string& value);
8115 ColumnFormat& border_bottom_color(Color value);
8116 ColumnFormat& border_bottom_background_color(Color value);
8119 ColumnFormat& corner(
const std::string& value);
8120 ColumnFormat& corner_color(Color value);
8121 ColumnFormat& corner_background_color(Color value);
8124 ColumnFormat& column_separator(
const std::string& value);
8125 ColumnFormat& column_separator_color(Color value);
8126 ColumnFormat& column_separator_background_color(Color value);
8129 ColumnFormat& font_align(FontAlign value);
8130 ColumnFormat& font_style(
const std::vector<FontStyle>& style);
8131 ColumnFormat& font_color(Color value);
8132 ColumnFormat& font_background_color(Color value);
8133 ColumnFormat& color(Color value);
8134 ColumnFormat& background_color(Color value);
8137 ColumnFormat& multi_byte_characters(
bool value);
8138 ColumnFormat& locale(
const std::string& value);
8141 std::reference_wrapper<class Column> column_;
8180#include <functional>
8184#if __cplusplus >= 201703L
8189using nonstd::optional;
8207 explicit Column(std::shared_ptr<class TableInternal> parent)
8208 : parent_(parent) {}
8210 void add_cell(Cell& cell) { cells_.push_back(cell); }
8212 Cell& operator[](
size_t index) {
return cells_[index]; }
8214 std::vector<std::reference_wrapper<Cell>> cells()
const {
return cells_; }
8216 size_t size()
const {
return cells_.size(); }
8218 ColumnFormat format() {
return ColumnFormat(*
this); }
8220 class CellIterator {
8222 explicit CellIterator(
8223 std::vector<std::reference_wrapper<Cell>>::iterator ptr)
8226 CellIterator operator++() {
8230 bool operator!=(
const CellIterator& other)
const {
8231 return ptr != other.ptr;
8233 Cell& operator*() {
return *ptr; }
8236 std::vector<std::reference_wrapper<Cell>>::iterator ptr;
8239 auto begin() -> CellIterator {
return CellIterator(cells_.begin()); }
8240 auto end() -> CellIterator {
return CellIterator(cells_.end()); }
8243 friend class ColumnFormat;
8244 friend class Printer;
8251 size_t get_configured_width() {
8253 for (
size_t i = 0; i < size(); ++i) {
8254 auto cell = cells_[i];
8255 auto format = cell.get().format();
8256 if (format.width_.has_value())
8257 result = std::max(result, *format.width_);
8270 size_t get_computed_width() {
8272 for (
size_t i = 0; i < size(); ++i) {
8273 result = std::max(result, get_cell_width(i));
8280 size_t get_cell_width(
size_t cell_index) {
8282 Cell& cell = cells_[cell_index].get();
8283 auto format = cell.format();
8284 if (format.padding_left_.has_value())
8285 result += *format.padding_left_;
8288 auto text = cell.get_text();
8290 Format::split_lines(text,
"\n", cell.locale(),
8291 cell.is_multi_byte_character_support_enabled());
8294 if (split_lines.size() == 1) {
8295 result += cell.size();
8299 size_t widest_sub_string_size{0};
8300 for (
auto& line : split_lines)
8301 if (get_sequence_length(
8302 line, cell.locale(),
8303 cell.is_multi_byte_character_support_enabled()) >
8304 widest_sub_string_size)
8305 widest_sub_string_size = get_sequence_length(
8306 line, cell.locale(),
8307 cell.is_multi_byte_character_support_enabled());
8308 result += widest_sub_string_size;
8311 if (format.padding_right_.has_value())
8312 result += *format.padding_right_;
8317 std::vector<std::reference_wrapper<Cell>> cells_;
8318 std::weak_ptr<class TableInternal> parent_;
8321inline ColumnFormat& ColumnFormat::width(
size_t value) {
8322 for (
auto& cell : column_.get().cells_)
8323 cell.get().format().width(value);
8327inline ColumnFormat& ColumnFormat::height(
size_t value) {
8328 for (
auto& cell : column_.get().cells_)
8329 cell.get().format().height(value);
8333inline ColumnFormat& ColumnFormat::padding(
size_t value) {
8334 for (
auto& cell : column_.get().cells_)
8335 cell.get().format().padding(value);
8339inline ColumnFormat& ColumnFormat::padding_left(
size_t value) {
8340 for (
auto& cell : column_.get().cells_)
8341 cell.get().format().padding_left(value);
8345inline ColumnFormat& ColumnFormat::padding_right(
size_t value) {
8346 for (
auto& cell : column_.get().cells_)
8347 cell.get().format().padding_right(value);
8351inline ColumnFormat& ColumnFormat::padding_top(
size_t value) {
8352 for (
auto& cell : column_.get().cells_)
8353 cell.get().format().padding_top(value);
8357inline ColumnFormat& ColumnFormat::padding_bottom(
size_t value) {
8358 for (
auto& cell : column_.get().cells_)
8359 cell.get().format().padding_bottom(value);
8363inline ColumnFormat& ColumnFormat::border(
const std::string& value) {
8364 for (
auto& cell : column_.get().cells_)
8365 cell.get().format().border(value);
8369inline ColumnFormat& ColumnFormat::border_color(Color value) {
8370 for (
auto& cell : column_.get().cells_)
8371 cell.get().format().border_color(value);
8375inline ColumnFormat& ColumnFormat::border_background_color(Color value) {
8376 for (
auto& cell : column_.get().cells_)
8377 cell.get().format().border_background_color(value);
8381inline ColumnFormat& ColumnFormat::border_left(
const std::string& value) {
8382 for (
auto& cell : column_.get().cells_)
8383 cell.get().format().border_left(value);
8387inline ColumnFormat& ColumnFormat::border_left_color(Color value) {
8388 for (
auto& cell : column_.get().cells_)
8389 cell.get().format().border_left_color(value);
8393inline ColumnFormat& ColumnFormat::border_left_background_color(Color value) {
8394 for (
auto& cell : column_.get().cells_)
8395 cell.get().format().border_left_background_color(value);
8399inline ColumnFormat& ColumnFormat::border_right(
const std::string& value) {
8400 for (
auto& cell : column_.get().cells_)
8401 cell.get().format().border_right(value);
8405inline ColumnFormat& ColumnFormat::border_right_color(Color value) {
8406 for (
auto& cell : column_.get().cells_)
8407 cell.get().format().border_right_color(value);
8411inline ColumnFormat& ColumnFormat::border_right_background_color(Color value) {
8412 for (
auto& cell : column_.get().cells_)
8413 cell.get().format().border_right_background_color(value);
8417inline ColumnFormat& ColumnFormat::border_top(
const std::string& value) {
8418 for (
auto& cell : column_.get().cells_)
8419 cell.get().format().border_top(value);
8423inline ColumnFormat& ColumnFormat::border_top_color(Color value) {
8424 for (
auto& cell : column_.get().cells_)
8425 cell.get().format().border_top_color(value);
8429inline ColumnFormat& ColumnFormat::border_top_background_color(Color value) {
8430 for (
auto& cell : column_.get().cells_)
8431 cell.get().format().border_top_background_color(value);
8435inline ColumnFormat& ColumnFormat::border_bottom(
const std::string& value) {
8436 for (
auto& cell : column_.get().cells_)
8437 cell.get().format().border_bottom(value);
8441inline ColumnFormat& ColumnFormat::border_bottom_color(Color value) {
8442 for (
auto& cell : column_.get().cells_)
8443 cell.get().format().border_bottom_color(value);
8447inline ColumnFormat& ColumnFormat::border_bottom_background_color(Color value) {
8448 for (
auto& cell : column_.get().cells_)
8449 cell.get().format().border_bottom_background_color(value);
8453inline ColumnFormat& ColumnFormat::corner(
const std::string& value) {
8454 for (
auto& cell : column_.get().cells_)
8455 cell.get().format().corner(value);
8459inline ColumnFormat& ColumnFormat::corner_color(Color value) {
8460 for (
auto& cell : column_.get().cells_)
8461 cell.get().format().corner_color(value);
8465inline ColumnFormat& ColumnFormat::corner_background_color(Color value) {
8466 for (
auto& cell : column_.get().cells_)
8467 cell.get().format().corner_background_color(value);
8471inline ColumnFormat& ColumnFormat::column_separator(
const std::string& value) {
8472 for (
auto& cell : column_.get().cells_)
8473 cell.get().format().column_separator(value);
8477inline ColumnFormat& ColumnFormat::column_separator_color(Color value) {
8478 for (
auto& cell : column_.get().cells_)
8479 cell.get().format().column_separator_color(value);
8484ColumnFormat::column_separator_background_color(Color value) {
8485 for (
auto& cell : column_.get().cells_)
8486 cell.get().format().column_separator_background_color(value);
8490inline ColumnFormat& ColumnFormat::font_align(FontAlign value) {
8491 for (
auto& cell : column_.get().cells_)
8492 cell.get().format().font_align(value);
8497ColumnFormat::font_style(
const std::vector<FontStyle>& style) {
8498 for (
auto& cell : column_.get().cells_)
8499 cell.get().format().font_style(style);
8503inline ColumnFormat& ColumnFormat::font_color(Color value) {
8504 for (
auto& cell : column_.get().cells_)
8505 cell.get().format().font_color(value);
8509inline ColumnFormat& ColumnFormat::font_background_color(Color value) {
8510 for (
auto& cell : column_.get().cells_)
8511 cell.get().format().font_background_color(value);
8515inline ColumnFormat& ColumnFormat::color(Color value) {
8516 for (
auto& cell : column_.get().cells_)
8517 cell.get().format().color(value);
8521inline ColumnFormat& ColumnFormat::background_color(Color value) {
8522 for (
auto& cell : column_.get().cells_)
8523 cell.get().format().background_color(value);
8527inline ColumnFormat& ColumnFormat::multi_byte_characters(
bool value) {
8528 for (
auto& cell : column_.get().cells_)
8529 cell.get().format().multi_byte_characters(value);
8533inline ColumnFormat& ColumnFormat::locale(
const std::string& value) {
8534 for (
auto& cell : column_.get().cells_)
8535 cell.get().format().locale(value);
8583 static std::pair<std::vector<size_t>, std::vector<size_t>>
8584 compute_cell_dimensions(TableInternal& table);
8586 static void print_table(std::ostream& stream, TableInternal& table);
8589 print_row_in_cell(std::ostream& stream, TableInternal& table,
8590 const std::pair<size_t, size_t>& index,
8591 const std::pair<size_t, size_t>& dimension,
8592 size_t num_columns,
size_t row_index,
8593 const std::vector<std::string>& splitted_cell_text);
8596 print_cell_border_top(std::ostream& stream, TableInternal& table,
8597 const std::pair<size_t, size_t>& index,
8598 const std::pair<size_t, size_t>& dimension,
8599 size_t num_columns);
8601 print_cell_border_bottom(std::ostream& stream, TableInternal& table,
8602 const std::pair<size_t, size_t>& index,
8603 const std::pair<size_t, size_t>& dimension,
8604 size_t num_columns);
8606 static void apply_element_style(std::ostream& stream,
8607 Color foreground_color,
8608 Color background_color,
8609 const std::vector<FontStyle>& font_style) {
8610 apply_foreground_color(stream, foreground_color);
8611 apply_background_color(stream, background_color);
8612 for (
auto& style : font_style)
8613 apply_font_style(stream, style);
8616 static void reset_element_style(std::ostream& stream) {
8617 stream << termcolor::reset;
8621 static void print_content_left_aligned(std::ostream& stream,
8622 const std::string& cell_content,
8623 const Format& format,
8624 size_t text_with_padding_size,
8625 size_t column_width) {
8628 apply_element_style(stream, *format.font_color_,
8629 *format.font_background_color_,
8630 *format.font_style_);
8631 stream << cell_content;
8634 reset_element_style(stream);
8635 apply_element_style(stream, *format.font_color_,
8636 *format.font_background_color_, {});
8638 if (text_with_padding_size < column_width) {
8639 for (
size_t j = 0; j < (column_width - text_with_padding_size);
8646 static void print_content_center_aligned(std::ostream& stream,
8647 const std::string& cell_content,
8648 const Format& format,
8649 size_t text_with_padding_size,
8650 size_t column_width) {
8651 auto num_spaces = column_width - text_with_padding_size;
8652 if (num_spaces % 2 == 0) {
8654 for (
size_t j = 0; j < num_spaces / 2; ++j)
8658 apply_element_style(stream, *format.font_color_,
8659 *format.font_background_color_,
8660 *format.font_style_);
8661 stream << cell_content;
8665 reset_element_style(stream);
8666 apply_element_style(stream, *format.font_color_,
8667 *format.font_background_color_, {});
8669 for (
size_t j = 0; j < num_spaces / 2; ++j)
8672 auto num_spaces_before = num_spaces / 2 + 1;
8673 for (
size_t j = 0; j < num_spaces_before; ++j)
8677 apply_element_style(stream, *format.font_color_,
8678 *format.font_background_color_,
8679 *format.font_style_);
8680 stream << cell_content;
8684 reset_element_style(stream);
8685 apply_element_style(stream, *format.font_color_,
8686 *format.font_background_color_, {});
8688 for (
size_t j = 0; j < num_spaces - num_spaces_before; ++j)
8693 static void print_content_right_aligned(std::ostream& stream,
8694 const std::string& cell_content,
8695 const Format& format,
8696 size_t text_with_padding_size,
8697 size_t column_width) {
8698 if (text_with_padding_size < column_width) {
8699 for (
size_t j = 0; j < (column_width - text_with_padding_size);
8706 apply_element_style(stream, *format.font_color_,
8707 *format.font_background_color_,
8708 *format.font_style_);
8709 stream << cell_content;
8712 reset_element_style(stream);
8713 apply_element_style(stream, *format.font_color_,
8714 *format.font_background_color_, {});
8717 static void apply_font_style(std::ostream& stream, FontStyle style) {
8719 case FontStyle::bold:
8720 stream << termcolor::bold;
8722 case FontStyle::dark:
8723 stream << termcolor::dark;
8725 case FontStyle::italic:
8726 stream << termcolor::italic;
8728 case FontStyle::underline:
8729 stream << termcolor::underline;
8731 case FontStyle::blink:
8732 stream << termcolor::blink;
8734 case FontStyle::reverse:
8735 stream << termcolor::reverse;
8737 case FontStyle::concealed:
8738 stream << termcolor::concealed;
8740 case FontStyle::crossed:
8741 stream << termcolor::crossed;
8748 static void apply_foreground_color(std::ostream& stream,
8749 Color foreground_color) {
8750 switch (foreground_color) {
8752 stream << termcolor::grey;
8755 stream << termcolor::red;
8758 stream << termcolor::green;
8761 stream << termcolor::yellow;
8764 stream << termcolor::blue;
8766 case Color::magenta:
8767 stream << termcolor::magenta;
8770 stream << termcolor::cyan;
8773 stream << termcolor::white;
8781 static void apply_background_color(std::ostream& stream,
8782 Color background_color) {
8783 switch (background_color) {
8785 stream << termcolor::on_grey;
8788 stream << termcolor::on_red;
8791 stream << termcolor::on_green;
8794 stream << termcolor::on_yellow;
8797 stream << termcolor::on_blue;
8799 case Color::magenta:
8800 stream << termcolor::on_magenta;
8803 stream << termcolor::on_cyan;
8806 stream << termcolor::on_white;
8868class TableInternal :
public std::enable_shared_from_this<TableInternal> {
8870 static std::shared_ptr<TableInternal> create() {
8871 auto result = std::shared_ptr<TableInternal>(
new TableInternal());
8872 result->format_.set_defaults();
8876 void add_row(
const std::vector<std::string>& cells) {
8877 auto row = std::make_shared<Row>(shared_from_this());
8878 for (
auto& c : cells) {
8879 auto cell = std::make_shared<Cell>(row);
8881 row->add_cell(cell);
8883 rows_.push_back(row);
8886 Row& operator[](
size_t index) {
return *(rows_[index]); }
8888 const Row& operator[](
size_t index)
const {
return *(rows_[index]); }
8890 Column column(
size_t index) {
8891 Column column(shared_from_this());
8892 for (
size_t i = 0; i < rows_.size(); ++i) {
8893 auto row = rows_[i];
8894 auto& cell = row->cell(index);
8895 column.add_cell(cell);
8900 size_t size()
const {
return rows_.size(); }
8902 std::pair<size_t, size_t> shape() {
8903 std::pair<size_t, size_t> result{0, 0};
8904 std::stringstream stream;
8906 auto buffer = stream.str();
8907 auto lines = Format::split_lines(buffer,
"\n",
"",
true);
8909 result = {get_sequence_length(lines[0],
"",
true), lines.size()};
8914 Format& format() {
return format_; }
8916 void print(std::ostream& stream) { Printer::print_table(stream, *
this); }
8918 size_t estimate_num_columns()
const {
8921 auto first_row = operator[](
size_t(0));
8922 result = first_row.size();
8929 friend class MarkdownExporter;
8932 TableInternal& operator=(
const TableInternal&);
8933 TableInternal(
const TableInternal&);
8935 std::vector<std::shared_ptr<Row>> rows_;
8939inline Format& Cell::format() {
8940 std::shared_ptr<Row> parent = parent_.lock();
8941 if (!format_.has_value()) {
8942 format_ = parent->format();
8946 format_ = Format::merge(*format_, parent->format());
8951inline bool Cell::is_multi_byte_character_support_enabled() {
8952 return (*format().multi_byte_characters_);
8955inline Format& Row::format() {
8956 std::shared_ptr<TableInternal> parent = parent_.lock();
8957 if (!format_.has_value()) {
8958 format_ = parent->format();
8962 format_ = Format::merge(*format_, parent->format());
8967inline std::pair<std::vector<size_t>, std::vector<size_t>>
8968Printer::compute_cell_dimensions(TableInternal& table) {
8969 std::pair<std::vector<size_t>, std::vector<size_t>> result;
8970 size_t num_rows = table.size();
8971 size_t num_columns = table.estimate_num_columns();
8973 std::vector<size_t> row_heights, column_widths{};
8975 for (
size_t i = 0; i < num_columns; ++i) {
8976 Column column = table.column(i);
8977 size_t configured_width = column.get_configured_width();
8978 size_t computed_width = column.get_computed_width();
8979 if (configured_width != 0)
8980 column_widths.push_back(configured_width);
8982 column_widths.push_back(computed_width);
8985 for (
size_t i = 0; i < num_rows; ++i) {
8987 size_t configured_height = row.get_configured_height();
8988 size_t computed_height = row.get_computed_height(column_widths);
9002 row_heights.push_back(std::max(configured_height, computed_height));
9005 result.first = row_heights;
9006 result.second = column_widths;
9011inline void Printer::print_table(std::ostream& stream, TableInternal& table) {
9012 size_t num_rows = table.size();
9013 size_t num_columns = table.estimate_num_columns();
9014 auto dimensions = compute_cell_dimensions(table);
9015 auto row_heights = dimensions.first;
9016 auto column_widths = dimensions.second;
9017 auto splitted_cells_text =
9018 std::vector<std::vector<std::vector<std::string>>>(
9019 num_rows, std::vector<std::vector<std::string>>(
9020 num_columns, std::vector<std::string>{}));
9024 for (
size_t i = 0; i < num_rows; ++i) {
9026 for (
size_t j = 0; j < num_columns; ++j) {
9027 Cell cell = row.cell(j);
9028 const std::string& text = cell.get_text();
9029 auto padding_left = *cell.format().padding_left_;
9030 auto padding_right = *cell.format().padding_right_;
9033 bool has_new_line = text.find_first_of(
'\n') != std::string::npos;
9037 splitted_cells_text[i][j] = Format::split_lines(
9038 text,
"\n", cell.locale(),
9039 cell.is_multi_byte_character_support_enabled());
9048 auto content_width =
9049 column_widths[j] > padding_left + padding_right
9050 ? column_widths[j] - padding_left - padding_right
9052 auto word_wrapped_text = Format::word_wrap(
9053 text, content_width, cell.locale(),
9054 cell.is_multi_byte_character_support_enabled());
9055 splitted_cells_text[i][j] = Format::split_lines(
9056 word_wrapped_text,
"\n", cell.locale(),
9057 cell.is_multi_byte_character_support_enabled());
9063 for (
size_t i = 0; i < num_rows; ++i) {
9066 bool border_top_printed{
true};
9067 for (
size_t j = 0; j < num_columns; ++j) {
9068 border_top_printed &= print_cell_border_top(
9069 stream, table, {i, j}, {row_heights[i], column_widths[j]},
9072 if (border_top_printed)
9073 stream << termcolor::reset <<
"\n";
9076 for (
size_t k = 0; k < row_heights[i]; ++k) {
9077 for (
size_t j = 0; j < num_columns; ++j) {
9078 print_row_in_cell(stream, table, {i, j},
9079 {row_heights[i], column_widths[j]},
9080 num_columns, k, splitted_cells_text[i][j]);
9082 if (k + 1 < row_heights[i])
9083 stream << termcolor::reset <<
"\n";
9086 if (i + 1 == num_rows) {
9089 auto bottom_border_needed{
true};
9090 for (
size_t j = 0; j < num_columns; ++j) {
9091 auto cell = table[i][j];
9092 auto format = cell.format();
9093 auto corner = *format.corner_bottom_left_;
9094 auto border_bottom = *format.border_bottom_;
9095 if (corner ==
"" && border_bottom ==
"") {
9096 bottom_border_needed =
false;
9101 if (bottom_border_needed)
9102 stream << termcolor::reset <<
"\n";
9104 for (
size_t j = 0; j < num_columns; ++j) {
9105 print_cell_border_bottom(stream, table, {i, j},
9106 {row_heights[i], column_widths[j]},
9110 if (i + 1 < num_rows)
9111 stream << termcolor::reset
9117Printer::print_row_in_cell(std::ostream& stream, TableInternal& table,
9118 const std::pair<size_t, size_t>& index,
9119 const std::pair<size_t, size_t>& dimension,
9120 size_t num_columns,
size_t row_index,
9121 const std::vector<std::string>& splitted_cell_text) {
9122 auto column_width = dimension.second;
9123 auto cell = table[index.first][index.second];
9124 auto locale = cell.locale();
9125 auto is_multi_byte_character_support_enabled =
9126 cell.is_multi_byte_character_support_enabled();
9127 auto old_locale = std::locale::global(std::locale(locale));
9128 auto format = cell.format();
9129 auto text_height = splitted_cell_text.size();
9130 auto padding_top = *format.padding_top_;
9132 if (*format.show_border_left_) {
9133 apply_element_style(stream, *format.border_left_color_,
9134 *format.border_left_background_color_, {});
9135 stream << *format.border_left_;
9136 reset_element_style(stream);
9139 apply_element_style(stream, *format.font_color_,
9140 *format.font_background_color_, {});
9141 if (row_index < padding_top) {
9143 stream << std::string(column_width,
' ');
9144 }
else if (row_index >= padding_top &&
9145 (row_index <= (padding_top + text_height))) {
9149 auto padding_left = *format.padding_left_;
9150 auto padding_right = *format.padding_right_;
9152 if (row_index - padding_top < text_height) {
9153 auto line = splitted_cell_text[row_index - padding_top];
9156 stream << std::string(padding_left,
' ');
9159 switch (*format.trim_mode_) {
9160 case Format::TrimMode::kBoth:
9161 line = Format::trim(line);
9163 case Format::TrimMode::kLeft:
9164 line = Format::trim_left(line);
9166 case Format::TrimMode::kRight:
9167 line = Format::trim_right(line);
9169 case Format::TrimMode::kNone:
9173 auto line_with_padding_size =
9174 get_sequence_length(line, cell.locale(),
9175 is_multi_byte_character_support_enabled) +
9176 padding_left + padding_right;
9177 switch (*format.font_align_) {
9178 case FontAlign::left:
9179 print_content_left_aligned(
9180 stream, line, format, line_with_padding_size, column_width);
9182 case FontAlign::center:
9183 print_content_center_aligned(
9184 stream, line, format, line_with_padding_size, column_width);
9186 case FontAlign::right:
9187 print_content_right_aligned(
9188 stream, line, format, line_with_padding_size, column_width);
9193 stream << std::string(padding_right,
' ');
9195 stream << std::string(column_width,
' ');
9199 stream << std::string(column_width,
' ');
9202 reset_element_style(stream);
9204 if (index.second + 1 == num_columns) {
9206 if (*format.show_border_right_) {
9207 apply_element_style(stream, *format.border_right_color_,
9208 *format.border_right_background_color_, {});
9209 stream << *format.border_right_;
9210 reset_element_style(stream);
9213 std::locale::global(old_locale);
9217Printer::print_cell_border_top(std::ostream& stream, TableInternal& table,
9218 const std::pair<size_t, size_t>& index,
9219 const std::pair<size_t, size_t>& dimension,
9220 size_t num_columns) {
9221 auto cell = table[index.first][index.second];
9222 auto locale = cell.locale();
9223 auto old_locale = std::locale::global(std::locale(locale));
9224 auto format = cell.format();
9225 auto column_width = dimension.second;
9227 auto corner = *format.corner_top_left_;
9228 auto corner_color = *format.corner_top_left_color_;
9229 auto corner_background_color = *format.corner_top_left_background_color_;
9230 auto border_top = *format.border_top_;
9232 if ((corner ==
"" && border_top ==
"") || !*format.show_border_top_)
9235 apply_element_style(stream, corner_color, corner_background_color, {});
9236 if (*format.show_row_separator_) {
9237 if (index.first != 0)
9243 reset_element_style(stream);
9245 for (
size_t i = 0; i < column_width; ++i) {
9246 apply_element_style(stream, *format.border_top_color_,
9247 *format.border_top_background_color_, {});
9248 if (*format.show_row_separator_) {
9249 if (index.first != 0)
9250 stream << border_top;
9254 stream << border_top;
9255 reset_element_style(stream);
9258 if (index.second + 1 == num_columns) {
9260 corner = *format.corner_top_right_;
9261 corner_color = *format.corner_top_right_color_;
9262 corner_background_color = *format.corner_top_right_background_color_;
9264 apply_element_style(stream, corner_color, corner_background_color, {});
9265 if (*format.show_row_separator_) {
9266 if (index.first != 0)
9272 reset_element_style(stream);
9274 std::locale::global(old_locale);
9279Printer::print_cell_border_bottom(std::ostream& stream, TableInternal& table,
9280 const std::pair<size_t, size_t>& index,
9281 const std::pair<size_t, size_t>& dimension,
9282 size_t num_columns) {
9283 auto cell = table[index.first][index.second];
9284 auto locale = cell.locale();
9285 auto old_locale = std::locale::global(std::locale(locale));
9286 auto format = cell.format();
9287 auto column_width = dimension.second;
9289 auto corner = *format.corner_bottom_left_;
9290 auto corner_color = *format.corner_bottom_left_color_;
9291 auto corner_background_color = *format.corner_bottom_left_background_color_;
9292 auto border_bottom = *format.border_bottom_;
9294 if ((corner ==
"" && border_bottom ==
"") || !*format.show_border_bottom_)
9297 apply_element_style(stream, corner_color, corner_background_color, {});
9299 reset_element_style(stream);
9301 for (
size_t i = 0; i < column_width; ++i) {
9302 apply_element_style(stream, *format.border_bottom_color_,
9303 *format.border_bottom_background_color_, {});
9304 stream << border_bottom;
9305 reset_element_style(stream);
9308 if (index.second + 1 == num_columns) {
9310 corner = *format.corner_bottom_right_;
9311 corner_color = *format.corner_bottom_right_color_;
9312 corner_background_color = *format.corner_bottom_right_background_color_;
9314 apply_element_style(stream, corner_color, corner_background_color, {});
9316 reset_element_style(stream);
9318 std::locale::global(old_locale);
9359#if __cplusplus >= 201703L
9360#include <string_view>
9363using std::holds_alternative;
9364using std::string_view;
9370using nonstd::get_if;
9371using nonstd::holds_alternative;
9372using nonstd::string_view;
9373using nonstd::variant;
9383 Table() : table_(TableInternal::create()) {}
9386 std::vector<variant<std::string, const char*, string_view, Table>>;
9388 Table& add_row(
const Row_t& cells) {
9393 cols_ = cells.size();
9396 std::vector<std::string> cell_strings;
9397 if (cells.size() < cols_) {
9398 cell_strings.resize(cols_);
9399 std::fill(cell_strings.begin(), cell_strings.end(),
"");
9401 cell_strings.resize(cells.size());
9402 std::fill(cell_strings.begin(), cell_strings.end(),
"");
9405 for (
size_t i = 0; i < cells.size(); ++i) {
9406 auto cell = cells[i];
9407 if (holds_alternative<std::string>(cell)) {
9408 cell_strings[i] = *get_if<std::string>(&cell);
9409 }
else if (holds_alternative<const char*>(cell)) {
9410 cell_strings[i] = *get_if<const char*>(&cell);
9411 }
else if (holds_alternative<string_view>(cell)) {
9412 cell_strings[i] = std::string{*get_if<string_view>(&cell)};
9414 auto table = *get_if<Table>(&cell);
9415 std::stringstream stream;
9416 table.print(stream);
9417 cell_strings[i] = stream.str();
9421 table_->add_row(cell_strings);
9426 Row& operator[](
size_t index) {
return row(index); }
9428 Row& row(
size_t index) {
return (*table_)[index]; }
9430 Column column(
size_t index) {
return table_->column(index); }
9432 Format& format() {
return table_->format(); }
9434 void print(std::ostream& stream) { table_->print(stream); }
9437 std::stringstream stream;
9439 return stream.str();
9442 size_t size()
const {
return table_->size(); }
9444 std::pair<size_t, size_t> shape() {
return table_->shape(); }
9448 explicit RowIterator(std::vector<std::shared_ptr<Row>>::iterator ptr)
9451 RowIterator operator++() {
9455 bool operator!=(
const RowIterator& other)
const {
9456 return ptr != other.ptr;
9458 Row& operator*() {
return **ptr; }
9461 std::vector<std::shared_ptr<Row>>::iterator ptr;
9464 auto begin() -> RowIterator {
return RowIterator(table_->rows_.begin()); }
9465 auto end() -> RowIterator {
return RowIterator(table_->rows_.end()); }
9468 friend class MarkdownExporter;
9469 friend class LatexExporter;
9470 friend class AsciiDocExporter;
9472 friend std::ostream& operator<<(std::ostream& stream,
const Table& table);
9475 std::shared_ptr<TableInternal> table_;
9478inline std::ostream& operator<<(std::ostream& stream,
const Table& table) {
9479 const_cast<Table&
>(table).print(stream);
9485 operator const Table::Row_t&()
const {
return row_; }
9487 template <
typename T,
9488 typename =
typename std::enable_if<!std::is_convertible<
9489 T, Table::Row_t::value_type>::value>::type>
9490 RowStream& operator<<(
const T& obj) {
9492 std::string cell{oss_.str()};
9494 if (!cell.empty()) {
9495 row_.push_back(cell);
9500 RowStream& operator<<(
const Table::Row_t::value_type& cell) {
9501 row_.push_back(cell);
9505 RowStream& copyfmt(
const RowStream& other) {
9506 oss_.copyfmt(other.oss_);
9510 RowStream& copyfmt(
const std::ios& other) {
9511 oss_.copyfmt(other);
9515 std::ostringstream::char_type fill()
const {
return oss_.fill(); }
9516 std::ostringstream::char_type fill(std::ostringstream::char_type ch) {
9517 return oss_.fill(ch);
9520 std::ios_base::iostate exceptions()
const {
return oss_.exceptions(); }
9521 void exceptions(std::ios_base::iostate except) { oss_.exceptions(except); }
9523 std::locale imbue(
const std::locale& loc) {
return oss_.imbue(loc); }
9524 std::locale getloc()
const {
return oss_.getloc(); }
9526 char narrow(std::ostringstream::char_type c,
char dfault)
const {
9527 return oss_.narrow(c, dfault);
9529 std::ostringstream::char_type widen(
char c)
const {
return oss_.widen(c); }
9531 std::ios::fmtflags flags()
const {
return oss_.flags(); }
9532 std::ios::fmtflags flags(std::ios::fmtflags flags) {
9533 return oss_.flags(flags);
9536 std::ios::fmtflags setf(std::ios::fmtflags flags) {
9537 return oss_.setf(flags);
9539 std::ios::fmtflags setf(std::ios::fmtflags flags, std::ios::fmtflags mask) {
9540 return oss_.setf(flags, mask);
9543 void unsetf(std::ios::fmtflags flags) { oss_.unsetf(flags); }
9545 std::streamsize precision()
const {
return oss_.precision(); }
9546 std::streamsize precision(std::streamsize new_precision) {
9547 return oss_.precision(new_precision);
9550 std::streamsize width()
const {
return oss_.width(); }
9551 std::streamsize width(std::streamsize new_width) {
9552 return oss_.width(new_width);
9557 std::ostringstream oss_;
9602 virtual std::string dump(Table& table) = 0;
9603 virtual ~Exporter() {}
9645class MarkdownExporter :
public Exporter {
9647 std::string dump(Table& table)
override {
9648 std::string result{
""};
9649 apply_markdown_format(table);
9650 result = table.str();
9651 restore_table_format(table);
9655 virtual ~MarkdownExporter() {}
9658 void add_alignment_header_row(Table& table) {
9659 auto& rows = table.table_->rows_;
9661 if (rows.size() >= 1) {
9662 auto alignment_row =
9663 std::make_shared<Row>(table.table_->shared_from_this());
9666 std::vector<std::string> alignment_cells{};
9667 for (
auto& cell : table[0]) {
9668 auto format = cell.format();
9669 if (format.font_align_.value() == FontAlign::left) {
9670 alignment_cells.push_back(
":----");
9671 }
else if (format.font_align_.value() == FontAlign::center) {
9672 alignment_cells.push_back(
":---:");
9673 }
else if (format.font_align_.value() == FontAlign::right) {
9674 alignment_cells.push_back(
"----:");
9679 for (
auto& c : alignment_cells) {
9680 auto cell = std::make_shared<Cell>(alignment_row);
9683 .hide_border_bottom()
9686 .column_separator(
"|")
9690 cell->format().font_align(FontAlign::center);
9691 else if (c ==
"----:")
9692 cell->format().font_align(FontAlign::right);
9693 alignment_row->add_cell(cell);
9697 if (rows.size() > 1)
9698 rows.insert(rows.begin() + 1, alignment_row);
9700 rows.push_back(alignment_row);
9704 void remove_alignment_header_row(Table& table) {
9705 auto& rows = table.table_->rows_;
9706 table.table_->rows_.erase(rows.begin() + 1);
9709 void apply_markdown_format(Table& table) {
9711 for (
auto row : table) {
9712 for (
auto& cell : row) {
9713 auto format = cell.format();
9714 formats_.push_back(format);
9717 .hide_border_bottom()
9720 .column_separator(
"|")
9725 add_alignment_header_row(table);
9728 void restore_table_format(Table& table) {
9730 remove_alignment_header_row(table);
9733 size_t format_index{0};
9734 for (
auto row : table) {
9735 for (
auto& cell : row) {
9736 cell.format() = formats_[format_index];
9742 std::vector<Format> formats_;
9782#if __cplusplus >= 201703L
9787using nonstd::optional;
9792class LatexExporter :
public Exporter {
9794 static const char new_line =
'\n';
9797 class ExportOptions {
9799 ExportOptions& indentation(std::size_t value) {
9800 indentation_ = value;
9805 friend class LatexExporter;
9806 optional<size_t> indentation_;
9809 ExportOptions& configure() {
return options_; }
9811 std::string dump(Table& table)
override {
9812 std::string result{
"\\begin{tabular}"};
9815 result += add_alignment_header(table);
9817 const auto rows = table.rows_;
9819 for (
size_t i = 0; i < rows; i++) {
9820 auto& row = table[i];
9822 if (options_.indentation_.has_value()) {
9823 result += std::string(options_.indentation_.value(),
' ');
9826 for (
size_t j = 0; j < row.size(); j++) {
9828 result += row[j].get_text();
9831 if (j < row.size() - 1) {
9840 result +=
"\\end{tabular}";
9844 virtual ~LatexExporter() {}
9847 std::string add_alignment_header(Table& table) {
9848 std::string result{
"{"};
9850 for (
auto& cell : table[0]) {
9851 auto format = cell.format();
9852 if (format.font_align_.value() == FontAlign::left) {
9854 }
else if (format.font_align_.value() == FontAlign::center) {
9856 }
else if (format.font_align_.value() == FontAlign::right) {
9864 ExportOptions options_;
9910class AsciiDocExporter :
public Exporter {
9912 static const char new_line =
'\n';
9915 std::string dump(Table& table)
override {
9916 std::stringstream ss;
9917 ss << add_alignment_header(table);
9920 const auto rows = table.rows_;
9922 for (
size_t row_index = 0; row_index < rows; row_index++) {
9923 auto& row = table[row_index];
9925 for (
size_t cell_index = 0; cell_index < row.size(); cell_index++) {
9927 ss << add_formatted_cell(row[cell_index]);
9930 if (row_index == 0) {
9939 virtual ~AsciiDocExporter() {}
9942 std::string add_formatted_cell(Cell& cell)
const {
9943 std::stringstream ss;
9944 auto format = cell.format();
9945 std::string cell_string = cell.get_text();
9947 auto font_style = format.font_style_.value();
9949 bool format_bold =
false;
9950 bool format_italic =
false;
9951 std::for_each(font_style.begin(), font_style.end(),
9952 [&](FontStyle& style) {
9953 if (style == FontStyle::bold) {
9955 }
else if (style == FontStyle::italic) {
9956 format_italic =
true;
9963 if (format_italic) {
9968 if (format_italic) {
9977 std::string add_alignment_header(Table& table) {
9978 std::stringstream ss;
9979 ss << (R
"([cols=")");
9981 size_t column_count = table[0].size();
9982 size_t column_index = 0;
9983 for (
auto& cell : table[0]) {
9984 auto format = cell.format();
9986 if (format.font_align_.value() == FontAlign::left) {
9988 }
else if (format.font_align_.value() == FontAlign::center) {
9990 }
else if (format.font_align_.value() == FontAlign::right) {
9995 if (column_index != column_count) {
10043#ifndef TABULATE_EXPORT_HPP
10044#define TABULATE_EXPORT_HPP
10061#define TABULATE_VERSION_MAJOR 1
10062#define TABULATE_VERSION_MINOR 5
10063#define TABULATE_VERSION_PATCH 0
10066#define TABULATE_CONCATENATE(A, B) TABULATE_CONCATENATE_IMPL(A, B)
10067#define TABULATE_CONCATENATE_IMPL(A, B) A##B
10068#define TABULATE_STRINGIFY(a) TABULATE_STRINGIFY_IMPL(a)
10069#define TABULATE_STRINGIFY_IMPL(a) #a
Definition tabulate.hpp:1362
Definition tabulate.hpp:1480
type traits C++17:
Definition tabulate.hpp:518
Definition tabulate.hpp:134
Definition tabulate.hpp:132
Definition tabulate.hpp:138
Definition tabulate.hpp:2558
Definition tabulate.hpp:668
Definition tabulate.hpp:688
Definition tabulate.hpp:690
Definition tabulate.hpp:692
Definition tabulate.hpp:694
Definition tabulate.hpp:696
Definition tabulate.hpp:698
Definition tabulate.hpp:670
Definition tabulate.hpp:672
Definition tabulate.hpp:674
Definition tabulate.hpp:676
Definition tabulate.hpp:678
Definition tabulate.hpp:680
Definition tabulate.hpp:682
Definition tabulate.hpp:684
Definition tabulate.hpp:686
Definition tabulate.hpp:614
Definition tabulate.hpp:2285
Definition tabulate.hpp:2260
Definition tabulate.hpp:2402
Definition tabulate.hpp:2357
Definition tabulate.hpp:931
Definition tabulate.hpp:925
Definition tabulate.hpp:935
Definition tabulate.hpp:1040
Definition tabulate.hpp:701
Definition tabulate.hpp:952
Definition tabulate.hpp:942
Definition tabulate.hpp:822
Definition tabulate.hpp:710
Definition tabulate.hpp:759
Definition tabulate.hpp:843
Definition tabulate.hpp:703
Definition tabulate.hpp:464
Definition tabulate.hpp:502
Definition tabulate.hpp:476
Definition tabulate.hpp:490
Definition tabulate.hpp:457
Definition tabulate.hpp:483
Definition tabulate.hpp:1418
Definition tabulate.hpp:1393
Definition tabulate.hpp:2000