44#ifndef TOMLPLUSPLUS_HPP
45#define TOMLPLUSPLUS_HPP
47#define INCLUDE_TOMLPLUSPLUS_H
53#error toml++ is a C++ library.
58#if _MSVC_LANG > __cplusplus
59#define TOML_CPP _MSVC_LANG
63#define TOML_CPP __cplusplus
65#if TOML_CPP >= 202900L
68#elif TOML_CPP >= 202600L
71#elif TOML_CPP >= 202302L
74#elif TOML_CPP >= 202002L
77#elif TOML_CPP >= 201703L
80#elif TOML_CPP >= 201402L
83#elif TOML_CPP >= 201103L
93#error toml++ requires C++17 or higher. For a pre-C++11 TOML library see https:
95#error toml++ requires C++17 or higher. For a C++11 TOML library see https:
98#ifndef TOML_MAKE_VERSION
99#define TOML_MAKE_VERSION(major, minor, patch) (((major)*10000) + ((minor)*100) + ((patch)))
102#ifndef TOML_INTELLISENSE
103#ifdef __INTELLISENSE__
104#define TOML_INTELLISENSE 1
106#define TOML_INTELLISENSE 0
111#if defined(DOXYGEN) || defined(__DOXYGEN) || defined(__DOXYGEN__) || defined(__doxygen__) || defined(__POXY__) \
113#define TOML_DOXYGEN 1
115#define TOML_DOXYGEN 0
121#define TOML_CLANG __clang_major__
131#if TOML_CLANG && defined(__apple_build_version__)
133#define TOML_CLANG_VERSION TOML_MAKE_VERSION(__clang_major__, __clang_minor__, __clang_patchlevel__)
134#if TOML_CLANG_VERSION >= TOML_MAKE_VERSION(15, 0, 0)
136#elif TOML_CLANG_VERSION >= TOML_MAKE_VERSION(14, 3, 0)
138#elif TOML_CLANG_VERSION >= TOML_MAKE_VERSION(14, 0, 0)
140#elif TOML_CLANG_VERSION >= TOML_MAKE_VERSION(13, 1, 6)
142#elif TOML_CLANG_VERSION >= TOML_MAKE_VERSION(13, 0, 0)
144#elif TOML_CLANG_VERSION >= TOML_MAKE_VERSION(12, 0, 5)
146#elif TOML_CLANG_VERSION >= TOML_MAKE_VERSION(12, 0, 0)
148#elif TOML_CLANG_VERSION >= TOML_MAKE_VERSION(11, 0, 3)
150#elif TOML_CLANG_VERSION >= TOML_MAKE_VERSION(11, 0, 0)
152#elif TOML_CLANG_VERSION >= TOML_MAKE_VERSION(10, 0, 1)
157#undef TOML_CLANG_VERSION
162#ifdef __INTEL_COMPILER
163#define TOML_ICC __INTEL_COMPILER
165#define TOML_ICC_CL TOML_ICC
175#ifndef TOML_MSVC_LIKE
177#define TOML_MSVC_LIKE _MSC_VER
179#define TOML_MSVC_LIKE 0
184#if TOML_MSVC_LIKE && !TOML_CLANG && !TOML_ICC
185#define TOML_MSVC TOML_MSVC_LIKE
193#define TOML_GCC_LIKE __GNUC__
195#define TOML_GCC_LIKE 0
200#if TOML_GCC_LIKE && !TOML_CLANG && !TOML_ICC
201#define TOML_GCC TOML_GCC_LIKE
208#if defined(__CUDACC__) || defined(__CUDA_ARCH__) || defined(__CUDA_LIBDEVICE__)
215#ifndef TOML_ARCH_ITANIUM
216#if defined(__ia64__) || defined(__ia64) || defined(_IA64) || defined(__IA64__) || defined(_M_IA64)
217#define TOML_ARCH_ITANIUM 1
218#define TOML_ARCH_BITNESS 64
220#define TOML_ARCH_ITANIUM 0
224#ifndef TOML_ARCH_AMD64
225#if defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64) || defined(_M_AMD64)
226#define TOML_ARCH_AMD64 1
227#define TOML_ARCH_BITNESS 64
229#define TOML_ARCH_AMD64 0
234#if defined(__i386__) || defined(_M_IX86)
235#define TOML_ARCH_X86 1
236#define TOML_ARCH_BITNESS 32
238#define TOML_ARCH_X86 0
243#if defined(__aarch64__) || defined(__ARM_ARCH_ISA_A64) || defined(_M_ARM64) || defined(__ARM_64BIT_STATE) \
244 || defined(_M_ARM64EC)
245#define TOML_ARCH_ARM32 0
246#define TOML_ARCH_ARM64 1
247#define TOML_ARCH_ARM 1
248#define TOML_ARCH_BITNESS 64
249#elif defined(__arm__) || defined(_M_ARM) || defined(__ARM_32BIT_STATE)
250#define TOML_ARCH_ARM32 1
251#define TOML_ARCH_ARM64 0
252#define TOML_ARCH_ARM 1
253#define TOML_ARCH_BITNESS 32
255#define TOML_ARCH_ARM32 0
256#define TOML_ARCH_ARM64 0
257#define TOML_ARCH_ARM 0
261#ifndef TOML_ARCH_BITNESS
262#define TOML_ARCH_BITNESS 0
266#if TOML_ARCH_BITNESS == 64
267#define TOML_ARCH_X64 1
269#define TOML_ARCH_X64 0
273#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) || defined(__CYGWIN__)
274#define TOML_WINDOWS 1
276#define TOML_WINDOWS 0
292#ifndef TOML_HAS_INCLUDE
294#define TOML_HAS_INCLUDE(header) __has_include(header)
296#define TOML_HAS_INCLUDE(header) 0
301#ifndef TOML_HAS_BUILTIN
303#define TOML_HAS_BUILTIN(name) __has_builtin(name)
305#define TOML_HAS_BUILTIN(name) 0
310#ifndef TOML_HAS_FEATURE
312#define TOML_HAS_FEATURE(name) __has_feature(name)
314#define TOML_HAS_FEATURE(name) 0
320#ifdef __has_attribute
321#define TOML_HAS_ATTR(attr) __has_attribute(attr)
323#define TOML_HAS_ATTR(attr) 0
328#ifndef TOML_HAS_CPP_ATTR
329#ifdef __has_cpp_attribute
330#define TOML_HAS_CPP_ATTR(attr) __has_cpp_attribute(attr)
332#define TOML_HAS_CPP_ATTR(attr) 0
338#if TOML_CLANG || TOML_GCC_LIKE
339#define TOML_ATTR(...) __attribute__((__VA_ARGS__))
341#define TOML_ATTR(...)
348#define TOML_DECLSPEC(...) __declspec(__VA_ARGS__)
350#define TOML_DECLSPEC(...)
355#ifndef TOML_COMPILER_HAS_EXCEPTIONS
356#if defined(__EXCEPTIONS) || defined(_CPPUNWIND) || defined(__cpp_exceptions)
357#define TOML_COMPILER_HAS_EXCEPTIONS 1
359#define TOML_COMPILER_HAS_EXCEPTIONS 0
364#ifndef TOML_COMPILER_HAS_RTTI
365#if defined(_CPPRTTI) || defined(__GXX_RTTI) || TOML_HAS_FEATURE(cxx_rtti)
366#define TOML_COMPILER_HAS_RTTI 1
368#define TOML_COMPILER_HAS_RTTI 0
373#define TOML_CONCAT_1(x, y) x##y
374#define TOML_CONCAT(x, y) TOML_CONCAT_1(x, y)
377#define TOML_MAKE_STRING_1(s) #s
378#define TOML_MAKE_STRING(s) TOML_MAKE_STRING_1(s)
382#define TOML_PRAGMA_CLANG(decl) _Pragma(TOML_MAKE_STRING(clang decl))
384#define TOML_PRAGMA_CLANG(decl)
387#define TOML_PRAGMA_CLANG_GE_8(decl) TOML_PRAGMA_CLANG(decl)
389#define TOML_PRAGMA_CLANG_GE_8(decl)
392#define TOML_PRAGMA_CLANG_GE_9(decl) TOML_PRAGMA_CLANG(decl)
394#define TOML_PRAGMA_CLANG_GE_9(decl)
397#define TOML_PRAGMA_CLANG_GE_10(decl) TOML_PRAGMA_CLANG(decl)
399#define TOML_PRAGMA_CLANG_GE_10(decl)
402#define TOML_PRAGMA_CLANG_GE_11(decl) TOML_PRAGMA_CLANG(decl)
404#define TOML_PRAGMA_CLANG_GE_11(decl)
407#define TOML_PRAGMA_GCC(decl) _Pragma(TOML_MAKE_STRING(GCC decl))
409#define TOML_PRAGMA_GCC(decl)
412#define TOML_PRAGMA_MSVC(...) __pragma(__VA_ARGS__)
414#define TOML_PRAGMA_MSVC(...)
417#define TOML_PRAGMA_ICC(...) __pragma(__VA_ARGS__)
419#define TOML_PRAGMA_ICC(...)
424#define TOML_ALWAYS_INLINE __forceinline
425#elif TOML_GCC || TOML_CLANG || TOML_HAS_ATTR(__always_inline__)
426#define TOML_ALWAYS_INLINE \
427 TOML_ATTR(__always_inline__) \
430#define TOML_ALWAYS_INLINE inline
435#define TOML_NEVER_INLINE TOML_DECLSPEC(noinline)
437#define TOML_NEVER_INLINE TOML_ATTR(noinline)
439#if TOML_GCC || TOML_CLANG || TOML_HAS_ATTR(__noinline__)
440#define TOML_NEVER_INLINE TOML_ATTR(__noinline__)
443#ifndef TOML_NEVER_INLINE
444#define TOML_NEVER_INLINE
448#define TOML_ABSTRACT_INTERFACE TOML_DECLSPEC(novtable)
449#define TOML_EMPTY_BASES TOML_DECLSPEC(empty_bases)
452#if TOML_CLANG || TOML_HAS_ATTR(__trivial_abi__)
453#define TOML_TRIVIAL_ABI TOML_ATTR(__trivial_abi__)
455#define TOML_TRIVIAL_ABI
459#if TOML_CPP >= 17 && TOML_HAS_CPP_ATTR(nodiscard) >= 201603
460#define TOML_NODISCARD [[nodiscard]]
461#elif TOML_CLANG || TOML_GCC || TOML_HAS_ATTR(__warn_unused_result__)
462#define TOML_NODISCARD TOML_ATTR(__warn_unused_result__)
464#define TOML_NODISCARD
468#if TOML_CPP >= 17 && TOML_HAS_CPP_ATTR(nodiscard) >= 201907
469#define TOML_NODISCARD_CTOR [[nodiscard]]
471#define TOML_NODISCARD_CTOR
478 TOML_DECLSPEC(noalias) \
487 TOML_DECLSPEC(noalias) \
493#ifndef TOML_INLINE_GETTER
494#define TOML_INLINE_GETTER \
498#ifndef TOML_PURE_GETTER
499#define TOML_PURE_GETTER \
503#ifndef TOML_PURE_INLINE_GETTER
504#define TOML_PURE_INLINE_GETTER \
509#ifndef TOML_CONST_GETTER
510#define TOML_CONST_GETTER \
514#ifndef TOML_CONST_INLINE_GETTER
515#define TOML_CONST_INLINE_GETTER \
523#define TOML_ASSUME(expr) __assume(expr)
524#elif TOML_ICC || TOML_CLANG || TOML_HAS_BUILTIN(__builtin_assume)
525#define TOML_ASSUME(expr) __builtin_assume(expr)
526#elif TOML_HAS_CPP_ATTR(assume) >= 202207
527#define TOML_ASSUME(expr) [[assume(expr)]]
528#elif TOML_HAS_ATTR(__assume__)
529#define TOML_ASSUME(expr) __attribute__((__assume__(expr)))
531#define TOML_ASSUME(expr) static_cast<void>(0)
536#define TOML_UNREACHABLE __assume(0)
537#elif TOML_ICC || TOML_CLANG || TOML_GCC || TOML_HAS_BUILTIN(__builtin_unreachable)
538#define TOML_UNREACHABLE __builtin_unreachable()
540#define TOML_UNREACHABLE static_cast<void>(0)
544#if TOML_CPP >= 20 && TOML_HAS_CPP_ATTR(likely) >= 201803
545#define TOML_LIKELY(...) (__VA_ARGS__) [[likely]]
546#define TOML_LIKELY_CASE [[likely]]
547#elif TOML_GCC || TOML_CLANG || TOML_HAS_BUILTIN(__builtin_expect)
548#define TOML_LIKELY(...) (__builtin_expect(!!(__VA_ARGS__), 1))
550#define TOML_LIKELY(...) (__VA_ARGS__)
552#ifndef TOML_LIKELY_CASE
553#define TOML_LIKELY_CASE
557#if TOML_CPP >= 20 && TOML_HAS_CPP_ATTR(unlikely) >= 201803
558#define TOML_UNLIKELY(...) (__VA_ARGS__) [[unlikely]]
559#define TOML_UNLIKELY_CASE [[unlikely]]
560#elif TOML_GCC || TOML_CLANG || TOML_HAS_BUILTIN(__builtin_expect)
561#define TOML_UNLIKELY(...) (__builtin_expect(!!(__VA_ARGS__), 0))
563#define TOML_UNLIKELY(...) (__VA_ARGS__)
565#ifndef TOML_UNLIKELY_CASE
566#define TOML_UNLIKELY_CASE
570#if TOML_CLANG || TOML_HAS_ATTR(flag_enum)
571#define TOML_FLAGS_ENUM __attribute__((flag_enum))
573#define TOML_FLAGS_ENUM
577#if TOML_CLANG || TOML_HAS_ATTR(enum_extensibility)
578#define TOML_OPEN_ENUM __attribute__((enum_extensibility(open)))
579#define TOML_CLOSED_ENUM __attribute__((enum_extensibility(closed)))
581#define TOML_OPEN_ENUM
582#define TOML_CLOSED_ENUM
586#define TOML_OPEN_FLAGS_ENUM TOML_OPEN_ENUM TOML_FLAGS_ENUM
587#define TOML_CLOSED_FLAGS_ENUM TOML_CLOSED_ENUM TOML_FLAGS_ENUM
590#define TOML_MAKE_FLAGS_2(T, op, linkage) \
591 TOML_CONST_INLINE_GETTER \
592 linkage constexpr T operator op(T lhs, T rhs) noexcept \
594 using under = std::underlying_type_t<T>; \
595 return static_cast<T>(static_cast<under>(lhs) op static_cast<under>(rhs)); \
598 linkage constexpr T& operator TOML_CONCAT(op, =)(T & lhs, T rhs) noexcept \
600 return lhs = (lhs op rhs); \
604#define TOML_MAKE_FLAGS_1(T, linkage) \
605 static_assert(std::is_enum_v<T>); \
607 TOML_MAKE_FLAGS_2(T, &, linkage); \
608 TOML_MAKE_FLAGS_2(T, |, linkage); \
609 TOML_MAKE_FLAGS_2(T, ^, linkage); \
611 TOML_CONST_INLINE_GETTER \
612 linkage constexpr T operator~(T val) noexcept \
614 using under = std::underlying_type_t<T>; \
615 return static_cast<T>(~static_cast<under>(val)); \
618 TOML_CONST_INLINE_GETTER \
619 linkage constexpr bool operator!(T val) noexcept \
621 using under = std::underlying_type_t<T>; \
622 return !static_cast<under>(val); \
626#define TOML_MAKE_FLAGS(T) TOML_MAKE_FLAGS_1(T, )
628#define TOML_UNUSED(...) static_cast<void>(__VA_ARGS__)
630#define TOML_DELETE_DEFAULTS(T) \
631 T(const T&) = delete; \
633 T& operator=(const T&) = delete; \
634 T& operator=(T&&) = delete
636#define TOML_ASYMMETRICAL_EQUALITY_OPS(LHS, RHS, ...) \
637 __VA_ARGS__ TOML_NODISCARD \
638 friend bool operator==(RHS rhs, LHS lhs) noexcept \
642 __VA_ARGS__ TOML_NODISCARD \
643 friend bool operator!=(LHS lhs, RHS rhs) noexcept \
645 return !(lhs == rhs); \
647 __VA_ARGS__ TOML_NODISCARD \
648 friend bool operator!=(RHS rhs, LHS lhs) noexcept \
650 return !(lhs == rhs); \
654#define TOML_EVAL_BOOL_1(T, F) T
655#define TOML_EVAL_BOOL_0(T, F) F
657#if !defined(__POXY__) && !defined(POXY_IMPLEMENTATION_DETAIL)
658#define POXY_IMPLEMENTATION_DETAIL(...) __VA_ARGS__
665#define TOML_PUSH_WARNINGS \
666 TOML_PRAGMA_CLANG(diagnostic push) \
667 TOML_PRAGMA_CLANG(diagnostic ignored "-Wunknown-warning-option") \
670#define TOML_DISABLE_SWITCH_WARNINGS \
671 TOML_PRAGMA_CLANG(diagnostic ignored "-Wswitch") \
674#define TOML_DISABLE_ARITHMETIC_WARNINGS \
675 TOML_PRAGMA_CLANG_GE_10(diagnostic ignored "-Wimplicit-int-float-conversion") \
676 TOML_PRAGMA_CLANG(diagnostic ignored "-Wfloat-equal") \
677 TOML_PRAGMA_CLANG(diagnostic ignored "-Wdouble-promotion") \
678 TOML_PRAGMA_CLANG(diagnostic ignored "-Wchar-subscripts") \
679 TOML_PRAGMA_CLANG(diagnostic ignored "-Wshift-sign-overflow") \
682#define TOML_DISABLE_SPAM_WARNINGS \
683 TOML_PRAGMA_CLANG_GE_8(diagnostic ignored "-Wdefaulted-function-deleted") \
684 TOML_PRAGMA_CLANG_GE_9(diagnostic ignored "-Wctad-maybe-unsupported") \
685 TOML_PRAGMA_CLANG_GE_10(diagnostic ignored "-Wzero-as-null-pointer-constant") \
686 TOML_PRAGMA_CLANG_GE_11(diagnostic ignored "-Wsuggest-destructor-override") \
687 TOML_PRAGMA_CLANG(diagnostic ignored "-Wweak-vtables") \
688 TOML_PRAGMA_CLANG(diagnostic ignored "-Wweak-template-vtables") \
689 TOML_PRAGMA_CLANG(diagnostic ignored "-Wdouble-promotion") \
690 TOML_PRAGMA_CLANG(diagnostic ignored "-Wchar-subscripts") \
691 TOML_PRAGMA_CLANG(diagnostic ignored "-Wmissing-field-initializers") \
692 TOML_PRAGMA_CLANG(diagnostic ignored "-Wpadded") \
695#define TOML_POP_WARNINGS \
696 TOML_PRAGMA_CLANG(diagnostic pop) \
699#define TOML_DISABLE_WARNINGS \
700 TOML_PRAGMA_CLANG(diagnostic push) \
701 TOML_PRAGMA_CLANG(diagnostic ignored "-Weverything") \
702 static_assert(true, "")
704#define TOML_ENABLE_WARNINGS \
705 TOML_PRAGMA_CLANG(diagnostic pop) \
708#define TOML_SIMPLE_STATIC_ASSERT_MESSAGES 1
712#define TOML_PUSH_WARNINGS \
713 __pragma(warning(push)) \
716#if TOML_HAS_INCLUDE(<CodeAnalysis/Warnings.h>)
717#pragma warning(push, 0)
718#include <CodeAnalysis/Warnings.h>
720#define TOML_DISABLE_CODE_ANALYSIS_WARNINGS \
721 __pragma(warning(disable : ALL_CODE_ANALYSIS_WARNINGS)) \
724#define TOML_DISABLE_CODE_ANALYSIS_WARNINGS static_assert(true)
727#define TOML_DISABLE_SWITCH_WARNINGS \
728 __pragma(warning(disable : 4061)) \
729 __pragma(warning(disable : 4062)) \
730 __pragma(warning(disable : 4063)) \
731 __pragma(warning(disable : 5262)) \
732 __pragma(warning(disable : 26819)) \
735#define TOML_DISABLE_SPAM_WARNINGS \
736 __pragma(warning(disable : 4127)) \
737 __pragma(warning(disable : 4324)) \
738 __pragma(warning(disable : 4348)) \
739 __pragma(warning(disable : 4464)) \
740 __pragma(warning(disable : 4505)) \
741 __pragma(warning(disable : 4514)) \
742 __pragma(warning(disable : 4582)) \
743 __pragma(warning(disable : 4619)) \
744 __pragma(warning(disable : 4623)) \
745 __pragma(warning(disable : 4625)) \
746 __pragma(warning(disable : 4626)) \
747 __pragma(warning(disable : 4710)) \
748 __pragma(warning(disable : 4711)) \
749 __pragma(warning(disable : 4820)) \
750 __pragma(warning(disable : 4946)) \
751 __pragma(warning(disable : 5026)) \
752 __pragma(warning(disable : 5027)) \
753 __pragma(warning(disable : 5039)) \
754 __pragma(warning(disable : 5045)) \
755 __pragma(warning(disable : 5264)) \
756 __pragma(warning(disable : 26451)) \
757 __pragma(warning(disable : 26490)) \
758 __pragma(warning(disable : 26495)) \
759 __pragma(warning(disable : 26812)) \
760 __pragma(warning(disable : 26819)) \
763#define TOML_DISABLE_ARITHMETIC_WARNINGS \
764 __pragma(warning(disable : 4365)) \
765 __pragma(warning(disable : 4738)) \
766 __pragma(warning(disable : 5219)) \
769#define TOML_POP_WARNINGS \
770 __pragma(warning(pop)) \
773#define TOML_DISABLE_WARNINGS \
774 __pragma(warning(push, 0)) \
775 __pragma(warning(disable : 4348)) \
776 __pragma(warning(disable : 4668)) \
777 __pragma(warning(disable : 5105)) \
778 __pragma(warning(disable : 5264)) \
779 TOML_DISABLE_CODE_ANALYSIS_WARNINGS; \
780 TOML_DISABLE_SWITCH_WARNINGS; \
781 TOML_DISABLE_SPAM_WARNINGS; \
782 TOML_DISABLE_ARITHMETIC_WARNINGS; \
785#define TOML_ENABLE_WARNINGS TOML_POP_WARNINGS
789#define TOML_PUSH_WARNINGS \
790 __pragma(warning(push)) \
793#define TOML_DISABLE_SPAM_WARNINGS \
794 __pragma(warning(disable : 82)) \
795 __pragma(warning(disable : 111)) \
796 __pragma(warning(disable : 869)) \
797 __pragma(warning(disable : 1011)) \
798 __pragma(warning(disable : 2261)) \
801#define TOML_POP_WARNINGS \
802 __pragma(warning(pop)) \
805#define TOML_DISABLE_WARNINGS \
806 __pragma(warning(push, 0)) \
807 TOML_DISABLE_SPAM_WARNINGS
809#define TOML_ENABLE_WARNINGS \
810 __pragma(warning(pop)) \
815#define TOML_PUSH_WARNINGS \
816 TOML_PRAGMA_GCC(diagnostic push) \
819#define TOML_DISABLE_SWITCH_WARNINGS \
820 TOML_PRAGMA_GCC(diagnostic ignored "-Wswitch") \
821 TOML_PRAGMA_GCC(diagnostic ignored "-Wswitch-enum") \
822 TOML_PRAGMA_GCC(diagnostic ignored "-Wswitch-default") \
825#define TOML_DISABLE_ARITHMETIC_WARNINGS \
826 TOML_PRAGMA_GCC(diagnostic ignored "-Wfloat-equal") \
827 TOML_PRAGMA_GCC(diagnostic ignored "-Wsign-conversion") \
828 TOML_PRAGMA_GCC(diagnostic ignored "-Wchar-subscripts") \
831#define TOML_DISABLE_SUGGEST_ATTR_WARNINGS \
832 TOML_PRAGMA_GCC(diagnostic ignored "-Wsuggest-attribute=const") \
833 TOML_PRAGMA_GCC(diagnostic ignored "-Wsuggest-attribute=pure") \
836#define TOML_DISABLE_SPAM_WARNINGS \
837 TOML_PRAGMA_GCC(diagnostic ignored "-Wpadded") \
838 TOML_PRAGMA_GCC(diagnostic ignored "-Wcast-align") \
839 TOML_PRAGMA_GCC(diagnostic ignored "-Wcomment") \
840 TOML_PRAGMA_GCC(diagnostic ignored "-Wtype-limits") \
841 TOML_PRAGMA_GCC(diagnostic ignored "-Wuseless-cast") \
842 TOML_PRAGMA_GCC(diagnostic ignored "-Wchar-subscripts") \
843 TOML_PRAGMA_GCC(diagnostic ignored "-Wsubobject-linkage") \
844 TOML_PRAGMA_GCC(diagnostic ignored "-Wmissing-field-initializers") \
845 TOML_PRAGMA_GCC(diagnostic ignored "-Wmaybe-uninitialized") \
846 TOML_PRAGMA_GCC(diagnostic ignored "-Wnoexcept") \
847 TOML_PRAGMA_GCC(diagnostic ignored "-Wnull-dereference") \
848 TOML_PRAGMA_GCC(diagnostic ignored "-Wduplicated-branches") \
851#define TOML_POP_WARNINGS \
852 TOML_PRAGMA_GCC(diagnostic pop) \
855#define TOML_DISABLE_WARNINGS \
856 TOML_PRAGMA_GCC(diagnostic push) \
857 TOML_PRAGMA_GCC(diagnostic ignored "-Wall") \
858 TOML_PRAGMA_GCC(diagnostic ignored "-Wextra") \
859 TOML_PRAGMA_GCC(diagnostic ignored "-Wpedantic") \
860 TOML_DISABLE_SWITCH_WARNINGS; \
861 TOML_DISABLE_ARITHMETIC_WARNINGS; \
862 TOML_DISABLE_SUGGEST_ATTR_WARNINGS; \
863 TOML_DISABLE_SPAM_WARNINGS; \
866#define TOML_ENABLE_WARNINGS \
867 TOML_PRAGMA_GCC(diagnostic pop) \
872#ifndef TOML_PUSH_WARNINGS
873#define TOML_PUSH_WARNINGS static_assert(true)
875#ifndef TOML_DISABLE_CODE_ANALYSIS_WARNINGS
876#define TOML_DISABLE_CODE_ANALYSIS_WARNINGS static_assert(true)
878#ifndef TOML_DISABLE_SWITCH_WARNINGS
879#define TOML_DISABLE_SWITCH_WARNINGS static_assert(true)
881#ifndef TOML_DISABLE_SUGGEST_ATTR_WARNINGS
882#define TOML_DISABLE_SUGGEST_ATTR_WARNINGS static_assert(true)
884#ifndef TOML_DISABLE_SPAM_WARNINGS
885#define TOML_DISABLE_SPAM_WARNINGS static_assert(true)
887#ifndef TOML_DISABLE_ARITHMETIC_WARNINGS
888#define TOML_DISABLE_ARITHMETIC_WARNINGS static_assert(true)
890#ifndef TOML_POP_WARNINGS
891#define TOML_POP_WARNINGS static_assert(true)
893#ifndef TOML_DISABLE_WARNINGS
894#define TOML_DISABLE_WARNINGS static_assert(true)
896#ifndef TOML_ENABLE_WARNINGS
897#define TOML_ENABLE_WARNINGS static_assert(true)
899#ifndef TOML_SIMPLE_STATIC_ASSERT_MESSAGES
900#define TOML_SIMPLE_STATIC_ASSERT_MESSAGES 0
903#ifdef TOML_CONFIG_HEADER
904#include TOML_CONFIG_HEADER
908#ifndef TOML_SHARED_LIB
909#define TOML_SHARED_LIB 0
913#if !defined(TOML_HEADER_ONLY) && defined(TOML_ALL_INLINE)
914#define TOML_HEADER_ONLY TOML_ALL_INLINE
916#if !defined(TOML_HEADER_ONLY) || (defined(TOML_HEADER_ONLY) && TOML_HEADER_ONLY) || TOML_INTELLISENSE
917#undef TOML_HEADER_ONLY
918#define TOML_HEADER_ONLY 1
920#if TOML_DOXYGEN || TOML_SHARED_LIB
921#undef TOML_HEADER_ONLY
922#define TOML_HEADER_ONLY 0
926#if defined(TOML_IMPLEMENTATION) || TOML_HEADER_ONLY
927#undef TOML_IMPLEMENTATION
928#define TOML_IMPLEMENTATION 1
930#define TOML_IMPLEMENTATION 0
934#if !defined(TOML_EXPORTED_MEMBER_FUNCTION) && !defined(TOML_EXPORTED_STATIC_FUNCTION) \
935 && !defined(TOML_EXPORTED_FREE_FUNCTION) && !defined(TOML_EXPORTED_CLASS) && defined(TOML_API)
936#define TOML_EXPORTED_MEMBER_FUNCTION TOML_API
937#define TOML_EXPORTED_STATIC_FUNCTION TOML_API
938#define TOML_EXPORTED_FREE_FUNCTION TOML_API
944#undef TOML_EXPORTED_CLASS
945#undef TOML_EXPORTED_MEMBER_FUNCTION
946#undef TOML_EXPORTED_STATIC_FUNCTION
947#undef TOML_EXPORTED_FREE_FUNCTION
949#if TOML_IMPLEMENTATION
950#define TOML_EXPORTED_CLASS __declspec(dllexport)
951#define TOML_EXPORTED_FREE_FUNCTION __declspec(dllexport)
953#define TOML_EXPORTED_CLASS __declspec(dllimport)
954#define TOML_EXPORTED_FREE_FUNCTION __declspec(dllimport)
957#define TOML_CALLCONV __cdecl
959#elif defined(__GNUC__) && __GNUC__ >= 4
960#define TOML_EXPORTED_CLASS __attribute__((visibility("default")))
961#define TOML_EXPORTED_MEMBER_FUNCTION __attribute__((visibility("default")))
962#define TOML_EXPORTED_STATIC_FUNCTION __attribute__((visibility("default")))
963#define TOML_EXPORTED_FREE_FUNCTION __attribute__((visibility("default")))
966#ifndef TOML_EXPORTED_CLASS
967#define TOML_EXPORTED_CLASS
969#ifndef TOML_EXPORTED_MEMBER_FUNCTION
970#define TOML_EXPORTED_MEMBER_FUNCTION
972#ifndef TOML_EXPORTED_STATIC_FUNCTION
973#define TOML_EXPORTED_STATIC_FUNCTION
975#ifndef TOML_EXPORTED_FREE_FUNCTION
976#define TOML_EXPORTED_FREE_FUNCTION
980#if !defined(TOML_ENABLE_UNRELEASED_FEATURES) && defined(TOML_UNRELEASED_FEATURES)
982#define TOML_ENABLE_UNRELEASED_FEATURES TOML_UNRELEASED_FEATURES
984#if (defined(TOML_ENABLE_UNRELEASED_FEATURES) && TOML_ENABLE_UNRELEASED_FEATURES) || TOML_INTELLISENSE
985#undef TOML_ENABLE_UNRELEASED_FEATURES
986#define TOML_ENABLE_UNRELEASED_FEATURES 1
988#ifndef TOML_ENABLE_UNRELEASED_FEATURES
989#define TOML_ENABLE_UNRELEASED_FEATURES 0
993#if !defined(TOML_ENABLE_PARSER) && defined(TOML_PARSER)
994#define TOML_ENABLE_PARSER TOML_PARSER
996#if !defined(TOML_ENABLE_PARSER) || (defined(TOML_ENABLE_PARSER) && TOML_ENABLE_PARSER) || TOML_INTELLISENSE
997#undef TOML_ENABLE_PARSER
998#define TOML_ENABLE_PARSER 1
1002#if !defined(TOML_ENABLE_FORMATTERS) || (defined(TOML_ENABLE_FORMATTERS) && TOML_ENABLE_FORMATTERS) || TOML_INTELLISENSE
1003#undef TOML_ENABLE_FORMATTERS
1004#define TOML_ENABLE_FORMATTERS 1
1008#if !defined(TOML_ENABLE_SIMD) || (defined(TOML_ENABLE_SIMD) && TOML_ENABLE_SIMD) || TOML_INTELLISENSE
1009#undef TOML_ENABLE_SIMD
1010#define TOML_ENABLE_SIMD 1
1014#if !defined(TOML_ENABLE_WINDOWS_COMPAT) && defined(TOML_WINDOWS_COMPAT)
1015#define TOML_ENABLE_WINDOWS_COMPAT TOML_WINDOWS_COMPAT
1017#if !defined(TOML_ENABLE_WINDOWS_COMPAT) || (defined(TOML_ENABLE_WINDOWS_COMPAT) && TOML_ENABLE_WINDOWS_COMPAT) \
1018 || TOML_INTELLISENSE
1019#undef TOML_ENABLE_WINDOWS_COMPAT
1020#define TOML_ENABLE_WINDOWS_COMPAT 1
1024#undef TOML_ENABLE_WINDOWS_COMPAT
1025#define TOML_ENABLE_WINDOWS_COMPAT 0
1028#ifndef TOML_INCLUDE_WINDOWS_H
1029#define TOML_INCLUDE_WINDOWS_H 0
1033#ifdef TOML_OPTIONAL_TYPE
1034#define TOML_HAS_CUSTOM_OPTIONAL_TYPE 1
1036#define TOML_HAS_CUSTOM_OPTIONAL_TYPE 0
1040#if TOML_COMPILER_HAS_EXCEPTIONS
1041#if !defined(TOML_EXCEPTIONS) || (defined(TOML_EXCEPTIONS) && TOML_EXCEPTIONS)
1042#undef TOML_EXCEPTIONS
1043#define TOML_EXCEPTIONS 1
1046#if defined(TOML_EXCEPTIONS) && TOML_EXCEPTIONS
1047#error TOML_EXCEPTIONS was explicitly enabled but exceptions are disabled/unsupported by the compiler.
1049#undef TOML_EXCEPTIONS
1050#define TOML_EXCEPTIONS 0
1054#ifndef TOML_CALLCONV
1055#define TOML_CALLCONV
1058#ifndef TOML_UNDEF_MACROS
1059#define TOML_UNDEF_MACROS 1
1062#ifndef TOML_MAX_NESTED_VALUES
1063#define TOML_MAX_NESTED_VALUES 256
1068#ifdef TOML_CHAR_8_STRINGS
1069#if TOML_CHAR_8_STRINGS
1070#error TOML_CHAR_8_STRINGS was removed in toml++ 2.0.0; all value setters and getters now work with char8_t strings implicitly.
1074#ifdef TOML_LARGE_FILES
1075#if !TOML_LARGE_FILES
1076#error Support for !TOML_LARGE_FILES (i.e. 'small files') was removed in toml++ 3.0.0.
1080#ifndef TOML_LIFETIME_HOOKS
1081#define TOML_LIFETIME_HOOKS 0
1086#define TOML_ASSERT(expr) static_assert(true)
1094#define TOML_ASSERT(expr) assert(expr)
1097#define TOML_ASSERT_ASSUME(expr) TOML_ASSUME(expr)
1099#define TOML_ASSERT_ASSUME(expr) TOML_ASSERT(expr)
1102#ifndef TOML_ENABLE_FLOAT16
1103#define TOML_ENABLE_FLOAT16 0
1106#if !defined(TOML_FLOAT_CHARCONV) && (TOML_GCC || TOML_CLANG || (TOML_ICC && !TOML_ICC_CL))
1109#define TOML_FLOAT_CHARCONV 0
1111#if !defined(TOML_INT_CHARCONV) && (defined(__EMSCRIPTEN__) || defined(__APPLE__))
1114#define TOML_INT_CHARCONV 0
1116#ifndef TOML_INT_CHARCONV
1117#define TOML_INT_CHARCONV 1
1119#ifndef TOML_FLOAT_CHARCONV
1120#define TOML_FLOAT_CHARCONV 1
1122#if (TOML_INT_CHARCONV || TOML_FLOAT_CHARCONV) && !TOML_HAS_INCLUDE(<charconv>)
1123#undef TOML_INT_CHARCONV
1124#undef TOML_FLOAT_CHARCONV
1125#define TOML_INT_CHARCONV 0
1126#define TOML_FLOAT_CHARCONV 0
1129#if defined(__cpp_concepts) && __cpp_concepts >= 201907
1130#define TOML_REQUIRES(...) requires(__VA_ARGS__)
1132#define TOML_REQUIRES(...)
1134#define TOML_ENABLE_IF(...) , typename std::enable_if<(__VA_ARGS__), int>::type = 0
1135#define TOML_CONSTRAINED_TEMPLATE(condition, ...) \
1136 template <__VA_ARGS__ TOML_ENABLE_IF(condition)> \
1137 TOML_REQUIRES(condition)
1138#define TOML_HIDDEN_CONSTRAINT(condition, ...) TOML_CONSTRAINED_TEMPLATE(condition, __VA_ARGS__)
1140#if defined(__SIZEOF_FLOAT128__) && defined(__FLT128_MANT_DIG__) && defined(__LDBL_MANT_DIG__) \
1141 && __FLT128_MANT_DIG__ > __LDBL_MANT_DIG__
1142#define TOML_FLOAT128 __float128
1145#ifdef __SIZEOF_INT128__
1146#define TOML_INT128 __int128_t
1147#define TOML_UINT128 __uint128_t
1154#define TOML_LIB_MAJOR 3
1155#define TOML_LIB_MINOR 4
1156#define TOML_LIB_PATCH 0
1158#define TOML_LANG_MAJOR 1
1159#define TOML_LANG_MINOR 0
1160#define TOML_LANG_PATCH 0
1164#define TOML_LIB_SINGLE_HEADER 1
1166#if TOML_ENABLE_UNRELEASED_FEATURES
1167 #define TOML_LANG_EFFECTIVE_VERSION \
1168 TOML_MAKE_VERSION(TOML_LANG_MAJOR, TOML_LANG_MINOR, TOML_LANG_PATCH+1)
1170 #define TOML_LANG_EFFECTIVE_VERSION \
1171 TOML_MAKE_VERSION(TOML_LANG_MAJOR, TOML_LANG_MINOR, TOML_LANG_PATCH)
1174#define TOML_LANG_HIGHER_THAN(major, minor, patch) \
1175 (TOML_LANG_EFFECTIVE_VERSION > TOML_MAKE_VERSION(major, minor, patch))
1177#define TOML_LANG_AT_LEAST(major, minor, patch) \
1178 (TOML_LANG_EFFECTIVE_VERSION >= TOML_MAKE_VERSION(major, minor, patch))
1180#define TOML_LANG_UNRELEASED \
1181 TOML_LANG_HIGHER_THAN(TOML_LANG_MAJOR, TOML_LANG_MINOR, TOML_LANG_PATCH)
1183#ifndef TOML_ABI_NAMESPACES
1185 #define TOML_ABI_NAMESPACES 0
1187 #define TOML_ABI_NAMESPACES 1
1190#if TOML_ABI_NAMESPACES
1191 #define TOML_NAMESPACE_START namespace toml { inline namespace TOML_CONCAT(v, TOML_LIB_MAJOR)
1192 #define TOML_NAMESPACE_END } static_assert(true)
1193 #define TOML_NAMESPACE ::toml::TOML_CONCAT(v, TOML_LIB_MAJOR)
1194 #define TOML_ABI_NAMESPACE_START(name) inline namespace name { static_assert(true)
1195 #define TOML_ABI_NAMESPACE_BOOL(cond, T, F) TOML_ABI_NAMESPACE_START(TOML_CONCAT(TOML_EVAL_BOOL_, cond)(T, F))
1196 #define TOML_ABI_NAMESPACE_END } static_assert(true)
1198 #define TOML_NAMESPACE_START namespace toml
1199 #define TOML_NAMESPACE_END static_assert(true)
1200 #define TOML_NAMESPACE toml
1201 #define TOML_ABI_NAMESPACE_START(...) static_assert(true)
1202 #define TOML_ABI_NAMESPACE_BOOL(...) static_assert(true)
1203 #define TOML_ABI_NAMESPACE_END static_assert(true)
1205#define TOML_IMPL_NAMESPACE_START TOML_NAMESPACE_START { namespace impl
1206#define TOML_IMPL_NAMESPACE_END } TOML_NAMESPACE_END
1208 #define TOML_ANON_NAMESPACE_START static_assert(TOML_IMPLEMENTATION); TOML_IMPL_NAMESPACE_START
1209 #define TOML_ANON_NAMESPACE_END TOML_IMPL_NAMESPACE_END
1210 #define TOML_ANON_NAMESPACE TOML_NAMESPACE::impl
1211 #define TOML_EXTERNAL_LINKAGE inline
1212 #define TOML_INTERNAL_LINKAGE inline
1214 #define TOML_ANON_NAMESPACE_START static_assert(TOML_IMPLEMENTATION); \
1215 using namespace toml; \
1217 #define TOML_ANON_NAMESPACE_END static_assert(true)
1218 #define TOML_ANON_NAMESPACE
1219 #define TOML_EXTERNAL_LINKAGE
1220 #define TOML_INTERNAL_LINKAGE static
1227#if TOML_SIMPLE_STATIC_ASSERT_MESSAGES
1229 #define TOML_SA_NEWLINE " "
1230 #define TOML_SA_LIST_SEP ", "
1231 #define TOML_SA_LIST_BEG " ("
1232 #define TOML_SA_LIST_END ")"
1233 #define TOML_SA_LIST_NEW " "
1234 #define TOML_SA_LIST_NXT ", "
1238 #define TOML_SA_NEWLINE "\n| "
1239 #define TOML_SA_LIST_SEP TOML_SA_NEWLINE " - "
1240 #define TOML_SA_LIST_BEG TOML_SA_LIST_SEP
1241 #define TOML_SA_LIST_END
1242 #define TOML_SA_LIST_NEW TOML_SA_NEWLINE TOML_SA_NEWLINE
1243 #define TOML_SA_LIST_NXT TOML_SA_LIST_NEW
1247#define TOML_SA_NATIVE_VALUE_TYPE_LIST \
1248 TOML_SA_LIST_BEG "std::string" \
1249 TOML_SA_LIST_SEP "int64_t" \
1250 TOML_SA_LIST_SEP "double" \
1251 TOML_SA_LIST_SEP "bool" \
1252 TOML_SA_LIST_SEP "toml::date" \
1253 TOML_SA_LIST_SEP "toml::time" \
1254 TOML_SA_LIST_SEP "toml::date_time" \
1257#define TOML_SA_NODE_TYPE_LIST \
1258 TOML_SA_LIST_BEG "toml::table" \
1259 TOML_SA_LIST_SEP "toml::array" \
1260 TOML_SA_LIST_SEP "toml::value<std::string>" \
1261 TOML_SA_LIST_SEP "toml::value<int64_t>" \
1262 TOML_SA_LIST_SEP "toml::value<double>" \
1263 TOML_SA_LIST_SEP "toml::value<bool>" \
1264 TOML_SA_LIST_SEP "toml::value<toml::date>" \
1265 TOML_SA_LIST_SEP "toml::value<toml::time>" \
1266 TOML_SA_LIST_SEP "toml::value<toml::date_time>" \
1269#define TOML_SA_UNWRAPPED_NODE_TYPE_LIST \
1270 TOML_SA_LIST_NEW "A native TOML value type" \
1271 TOML_SA_NATIVE_VALUE_TYPE_LIST \
1273 TOML_SA_LIST_NXT "A TOML node type" \
1274 TOML_SA_NODE_TYPE_LIST
1285#pragma warning(disable : 5031)
1287#pragma warning(disable : 4251)
1305#if (!defined(__apple_build_version__) && TOML_CLANG >= 8) || TOML_GCC >= 7 || TOML_ICC >= 1910 || TOML_MSVC >= 1914
1306#define TOML_LAUNDER(x) __builtin_launder(x)
1307#elif defined(__cpp_lib_launder) && __cpp_lib_launder >= 201606
1308#define TOML_LAUNDER(x) std::launder(x)
1310#define TOML_LAUNDER(x) x
1316#include <string_view>
1321 || (defined(__cpp_char8_t) && __cpp_char8_t >= 201811 && defined(__cpp_lib_char8_t) \
1322 && __cpp_lib_char8_t >= 201907)
1323#define TOML_HAS_CHAR8 1
1325#define TOML_HAS_CHAR8 0
1330 using namespace std::string_literals;
1331 using namespace std::string_view_literals;
1334#if TOML_ENABLE_WINDOWS_COMPAT
1340 std::string narrow(std::wstring_view);
1344 std::wstring widen(std::string_view);
1350 std::wstring widen(std::u8string_view);
1361#if !TOML_HAS_CUSTOM_OPTIONAL_TYPE
1368#if TOML_HAS_CUSTOM_OPTIONAL_TYPE
1370 template <
typename T>
1371 using optional = TOML_OPTIONAL_TYPE<T>;
1375 template <
typename T>
1376 using optional = std::optional<T>;
1394#include <type_traits>
1399#pragma inline_recursion(on)
1401#pragma push_macro("min")
1402#pragma push_macro("max")
1407#ifndef TOML_DISABLE_ENVIRONMENT_CHECKS
1408#define TOML_ENV_MESSAGE \
1409 "If you're seeing this error it's because you're building toml++ for an environment that doesn't conform to " \
1410 "one of the 'ground truths' assumed by the library. Essentially this just means that I don't have the " \
1411 "resources to test on more platforms, but I wish I did! You can try disabling the checks by defining " \
1412 "TOML_DISABLE_ENVIRONMENT_CHECKS, but your mileage may vary. Please consider filing an issue at " \
1413 "https://github.com/marzer/tomlplusplus/issues to help me improve support for your target environment. " \
1424static_assert(std::numeric_limits<double>::digits10 == 15,
TOML_ENV_MESSAGE);
1427#undef TOML_ENV_MESSAGE
1434 using ::std::size_t;
1435 using ::std::intptr_t;
1436 using ::std::uintptr_t;
1437 using ::std::ptrdiff_t;
1438 using ::std::nullptr_t;
1439 using ::std::int8_t;
1440 using ::std::int16_t;
1441 using ::std::int32_t;
1442 using ::std::int64_t;
1443 using ::std::uint8_t;
1444 using ::std::uint16_t;
1445 using ::std::uint32_t;
1446 using ::std::uint64_t;
1447 using ::std::uint_least32_t;
1448 using ::std::uint_least64_t;
1476 class toml_formatter;
1477 class json_formatter;
1478 class yaml_formatter;
1492 using node_ptr = std::unique_ptr<node>;
1554#if TOML_ABI_NAMESPACES
1556#define TOML_PARSER_TYPENAME TOML_NAMESPACE::impl::impl_ex::parser
1558#define TOML_PARSER_TYPENAME TOML_NAMESPACE::impl::impl_noex::parser
1561#define TOML_PARSER_TYPENAME TOML_NAMESPACE::impl::parser
1588 template <
typename Char>
1589 inline std::basic_ostream<Char>&
operator<<(std::basic_ostream<Char>& lhs, node_type
rhs)
1591 const auto str = impl::node_type_friendly_names[
static_cast<std::underlying_type_t<node_type>
>(
rhs)];
1593 if constexpr (std::is_same_v<Char, str_char_t>)
1597 if constexpr (
sizeof(Char) ==
sizeof(str_char_t))
1598 return lhs << std::basic_string_view<Char>{
reinterpret_cast<const Char*
>(str.data()), str.length() };
1600 return lhs << str.data();
1636 template <
typename T>
1639 static_assert(std::is_reference_v<T>);
1643 template <
typename T>
1645 template <
typename T>
1654 template <
typename T>
1655 using remove_cvref = std::remove_cv_t<std::remove_reference_t<T>>;
1657 template <
typename...
T>
1660 template <
typename T,
typename... U>
1661 inline constexpr bool is_one_of = (
false || ... || std::is_same_v<T, U>);
1663 template <
typename... T>
1666 template <
typename T>
1667 inline constexpr bool is_cvref = std::is_reference_v<T> || std::is_const_v<T> || std::is_volatile_v<T>;
1669 template <
typename T>
1673 template <
typename T>
1676 && !std::is_same_v<remove_cvref<T>, std::u8string>
1681 template <
typename,
typename>
1683 template <
typename Dest,
typename Src>
1686 template <
typename Dest,
typename Src>
1692 template <
typename Dest,
typename Src>
1695 using type = std::add_lvalue_reference_t<Dest>;
1698 template <
typename Dest,
typename Src>
1701 using type = std::add_rvalue_reference_t<Dest>;
1704 template <
typename,
typename>
1706 template <
typename Dest,
typename Src>
1709 template <
typename Dest,
typename Src>
1715 template <
typename Dest,
typename Src>
1718 using type = std::add_const_t<Dest>;
1721 template <
typename Dest,
typename Src>
1724 using type = std::add_volatile_t<Dest>;
1727 template <
typename Dest,
typename Src>
1733 template <
typename Dest,
typename Src>
1737 template <
typename...>
1740 template <
typename T,
typename... U>
1742 template <
typename T,
typename... U>
1745 template <
typename T,
bool = std::is_enum_v<T>>
1748 using type = std::underlying_type_t<T>;
1750 template <
typename T>
1755 template <
typename T>
1767 static constexpr auto type = node_type::none;
1770 template <
typename T>
1773 template <
typename T,
bool = std::is_enum_v<T>>
1780 template <
typename T>
1788 template <
typename T>
1791 template <
typename T>
1794 template <
typename T>
1797 template <
typename T>
1800 template <
typename T>
1803 template <
typename T>
1808 template <
typename T>
1811 static constexpr T
min = T{ (std::numeric_limits<underlying_type<T>>
::min)() };
1812 static constexpr T
max = T{ (std::numeric_limits<underlying_type<T>>
::max)() };
1814 template <
typename T>
1820 static constexpr auto type = node_type::integer;
1823 template <
typename T>
1830 template <
typename T>
1841 template <typename T, bool S = integer_traits_base<T>::is_signed>
1844 template <
typename T>
1888 static constexpr TOML_INT128
max =
1889 static_cast<TOML_INT128
>((TOML_UINT128{ 1u } << ((__SIZEOF_INT128__ * CHAR_BIT) - 1)) - 1);
1890 static constexpr TOML_INT128
min = -
max - TOML_INT128{ 1 };
1895 static constexpr TOML_UINT128
min = TOML_UINT128{};
1905#ifdef TOML_SMALL_INT_TYPE
1912 template <
typename T,
int MantissaDigits,
int DecimalDigits>
1915 static constexpr auto type = node_type::floating_point;
1917 static constexpr bool is_native = std::is_same_v<T, native_type>;
1920 static constexpr int bits =
static_cast<int>(
sizeof(T) * CHAR_BIT);
1921 static constexpr int digits = MantissaDigits;
1933 template <
typename T>
1936#if TOML_ENABLE_FLOAT16
1957#if TOML_ENABLE_FLOAT16
1967#ifdef TOML_SMALL_FLOAT_TYPE
1978 template <
typename T>
1982 static constexpr bool is_native = std::is_same_v<T, native_type>;
1985 !std::is_array_v<T> && (!std::is_pointer_v<T> || std::is_const_v<std::remove_pointer_t<T>>);
1987 static constexpr auto type = node_type::string;
2031#if TOML_ENABLE_WINDOWS_COMPAT
2032 template <
typename T>
2033 struct wstring_traits
2035 using native_type = std::string;
2036 static constexpr bool is_native =
false;
2040 static constexpr auto type = node_type::string;
2046 struct value_traits<
std::wstring_view> : wstring_traits<std::wstring_view>
2049 struct value_traits<const wchar_t*> : wstring_traits<const wchar_t*>
2052 struct value_traits<const wchar_t[
N]> : wstring_traits<const wchar_t[N]>
2055 struct value_traits<wchar_t*> : wstring_traits<wchar_t*>
2058 struct value_traits<wchar_t[
N]> : wstring_traits<wchar_t[N]>
2063 template <
typename T, node_type NodeType>
2071 static constexpr auto type = NodeType;
2087 template <
typename T>
2089 template <
typename T>
2091 template <
typename T>
2093 template <
typename T>
2095 template <
typename T>
2097 template <
typename T,
typename... U>
2101 template <
typename T>
2106 template <
typename T>
2109 using type = std::add_const_t<typename node_wrapper<T>::type>;
2111 template <
typename T>
2114 using type = std::add_volatile_t<typename node_wrapper<T>::type>;
2116 template <
typename T>
2119 using type = std::add_const_t<std::add_volatile_t<typename node_wrapper<T>::type>>;
2156 template <
typename T>
2160 template <
typename T>
2165 template <
typename T>
2170 template <
typename T>
2175 template <
typename T>
2178 using type = std::add_volatile_t<T>;
2180 template <
typename T>
2183 using type = std::add_volatile_t<std::add_const_t<T>>;
2185 template <
typename T>
2188 template <
typename T>
2196 static constexpr auto value = node_type::table;
2201 static constexpr auto value = node_type::array;
2206 static constexpr auto value = node_type::none;
2208 template <
typename T>
2211 template <
typename T,
typename ConvertFrom>
2213 || std::is_convertible_v<ConvertFrom, T>;
2219 template <
typename T>
2220 inline constexpr bool is_table = std::is_same_v<impl::remove_cvref<T>,
table>;
2222 template <
typename T>
2225 template <
typename T>
2228 template <
typename T>
2230 impl::remove_cvref<impl::wrap_node<impl::remove_cvref<T>>>,
2233 template <
typename T>
2235 impl::remove_cvref<impl::wrap_node<impl::remove_cvref<T>>>,
2238 template <
typename T>
2240 impl::remove_cvref<impl::wrap_node<impl::remove_cvref<T>>>,
2243 template <
typename T>
2246 template <
typename T>
2248 impl::remove_cvref<impl::wrap_node<impl::remove_cvref<T>>>,
2251 template <
typename T>
2253 impl::remove_cvref<impl::wrap_node<impl::remove_cvref<T>>>,
2256 template <
typename T>
2258 impl::remove_cvref<impl::wrap_node<impl::remove_cvref<T>>>,
2261 template <
typename T>
2263 impl::remove_cvref<impl::wrap_node<impl::remove_cvref<T>>>,
2266 template <
typename T>
2269 template <
typename T>
2272 template <
typename T>
2273 inline constexpr bool is_node = std::is_same_v<toml::node, impl::remove_cvref<T>>
2274 || std::is_base_of_v<toml::node, impl::remove_cvref<T>>;
2276 template <
typename T>
2283 template <
typename T>
2285 constexpr std::underlying_type_t<T> unwrap_enum(
T val)
noexcept
2287 return static_cast<std::underlying_type_t<T>
>(val);
2303 static_assert(
sizeof(uint64_t) ==
sizeof(double));
2305 static constexpr uint64_t sign = 0b1000000000000000000000000000000000000000000000000000000000000000ull;
2306 static constexpr uint64_t exponent = 0b0111111111110000000000000000000000000000000000000000000000000000ull;
2307 static constexpr uint64_t mantissa = 0b0000000000001111111111111111111111111111111111111111111111111111ull;
2310 std::memcpy(&val_bits, &val,
sizeof(val));
2311 if ((val_bits & exponent) != exponent)
2312 return fp_class::ok;
2313 if ((val_bits & mantissa))
2314 return fp_class::nan;
2315 return (val_bits & sign) ? fp_class::neg_inf : fp_class::pos_inf;
2322 template <
typename Iterator,
typename T>
2325 ->decltype(&(*
start))
2328 if (*
start == needle)
2333 template <
typename T>
2335 constexpr const T&
min(
const T&
a,
const T&
b)
noexcept
2337 return a <
b ?
a :
b;
2343#pragma pop_macro("min")
2344#pragma pop_macro("max")
2346#pragma inline_recursion(off)
2356#pragma inline_recursion(on)
2358#pragma push_macro("min")
2359#pragma push_macro("max")
2441#if TOML_ENABLE_FORMATTERS
2472 template <
typename T,
typename U>
2483#pragma pop_macro("min")
2484#pragma pop_macro("max")
2486#pragma inline_recursion(off)
2496#pragma inline_recursion(on)
2498#pragma push_macro("min")
2499#pragma push_macro("max")
2506 using source_index = uint32_t;
2517 explicit constexpr operator bool() const noexcept
2519 return line > source_index{}
2520 &&
column > source_index{};
2526 return lhs.line ==
rhs.line
2527 && lhs.column ==
rhs.column;
2533 return !(lhs ==
rhs);
2541 return static_cast<uint64_t
>(pos.line) << 32 |
static_cast<uint64_t
>(pos.column);
2572 impl::print_to_stream(lhs,
rhs);
2585#if TOML_ENABLE_WINDOWS_COMPAT
2588 optional<std::wstring> wide_path()
const
2592 return { impl::widen(*
path) };
2599 impl::print_to_stream(lhs,
rhs);
2607#pragma pop_macro("min")
2608#pragma pop_macro("max")
2610#pragma inline_recursion(off)
2620#pragma inline_recursion(on)
2622#pragma push_macro("min")
2623#pragma push_macro("max")
2639 date() noexcept = default;
2643 constexpr date(Y y, M m, D d) noexcept
2644 : year{
static_cast<uint16_t
>(
y) },
2645 month{
static_cast<uint8_t
>(m) },
2646 day{
static_cast<uint8_t
>(d) }
2650 friend constexpr bool operator==(
const date& lhs,
const date&
rhs)
noexcept
2652 return lhs.year ==
rhs.year
2653 && lhs.month ==
rhs.month
2654 && lhs.day ==
rhs.day;
2658 friend constexpr bool operator!=(
const date& lhs,
const date&
rhs)
noexcept
2660 return !(lhs ==
rhs);
2666 static constexpr uint32_t pack(
const date& d)
noexcept
2668 return (
static_cast<uint32_t
>(d.year) << 16) | (
static_cast<uint32_t
>(d.month) << 8)
2669 |
static_cast<uint32_t
>(d.day);
2675 friend constexpr bool operator<(
const date& lhs,
const date&
rhs)
noexcept
2677 return pack(lhs) < pack(
rhs);
2681 friend constexpr bool operator<=(
const date& lhs,
const date&
rhs)
noexcept
2683 return pack(lhs) <= pack(
rhs);
2687 friend constexpr bool operator>(
const date& lhs,
const date&
rhs)
noexcept
2689 return pack(lhs) > pack(
rhs);
2693 friend constexpr bool operator>=(
const date& lhs,
const date&
rhs)
noexcept
2695 return pack(lhs) >= pack(
rhs);
2698 friend std::ostream&
operator<<(std::ostream& lhs,
const date&
rhs)
2700 impl::print_to_stream(lhs,
rhs);
2721 typename S = uint8_t,
2722 typename NS = uint32_t)
2724 constexpr
time(H h, M
m, S
s = S{}, NS ns = NS{})
noexcept
2725 : hour{
static_cast<uint8_t
>(h) },
2726 minute{
static_cast<uint8_t
>(m) },
2727 second{
static_cast<uint8_t
>(s) },
2728 nanosecond{
static_cast<uint32_t
>(ns) }
2732 friend constexpr bool operator==(
const time& lhs,
const time&
rhs)
noexcept
2734 return lhs.hour ==
rhs.hour
2735 && lhs.minute ==
rhs.minute
2736 && lhs.second ==
rhs.second
2737 && lhs.nanosecond ==
rhs.nanosecond;
2741 friend constexpr bool operator!=(
const time& lhs,
const time&
rhs)
noexcept
2743 return !(lhs ==
rhs);
2749 static constexpr uint64_t pack(
const time& t)
noexcept
2751 return static_cast<uint64_t
>(
t.hour) << 48 |
static_cast<uint64_t
>(
t.minute) << 40
2752 |
static_cast<uint64_t
>(
t.second) << 32 |
static_cast<uint64_t
>(
t.nanosecond);
2758 friend constexpr bool operator<(
const time& lhs,
const time&
rhs)
noexcept
2760 return pack(lhs) < pack(
rhs);
2764 friend constexpr bool operator<=(
const time& lhs,
const time&
rhs)
noexcept
2766 return pack(lhs) <= pack(
rhs);
2770 friend constexpr bool operator>(
const time& lhs,
const time&
rhs)
noexcept
2772 return pack(lhs) > pack(
rhs);
2776 friend constexpr bool operator>=(
const time& lhs,
const time&
rhs)
noexcept
2778 return pack(lhs) >= pack(
rhs);
2781 friend std::ostream&
operator<<(std::ostream& lhs,
const time&
rhs)
2783 impl::print_to_stream(lhs,
rhs);
2798 :
minutes{
static_cast<int16_t
>(
static_cast<impl::common_signed_type<H, M>
>(h)
2799 * impl::common_signed_type<H, M>{ 60 }
2800 +
static_cast<impl::common_signed_type<H, M>
>(m)) }
2806 return lhs.minutes ==
rhs.minutes;
2812 return lhs.minutes !=
rhs.minutes;
2818 return lhs.minutes <
rhs.minutes;
2824 return lhs.minutes <=
rhs.minutes;
2830 return lhs.minutes >
rhs.minutes;
2836 return lhs.minutes >=
rhs.minutes;
2841 impl::print_to_stream(lhs,
rhs);
2881 constexpr date_time(
const toml::date& d,
const toml::time& t,
const toml::time_offset& off) noexcept
2890 return !
offset.has_value();
2896 return lhs.date ==
rhs.date
2897 && lhs.time ==
rhs.time
2898 && lhs.offset ==
rhs.offset;
2904 return !(lhs ==
rhs);
2910 if (lhs.date !=
rhs.date)
2911 return lhs.date <
rhs.date;
2912 if (lhs.time !=
rhs.time)
2913 return lhs.time <
rhs.time;
2914 return lhs.offset <
rhs.offset;
2920 if (lhs.date !=
rhs.date)
2921 return lhs.date <
rhs.date;
2922 if (lhs.time !=
rhs.time)
2923 return lhs.time <
rhs.time;
2924 return lhs.offset <=
rhs.offset;
2930 return !(lhs <=
rhs);
2936 return !(lhs <
rhs);
2941 impl::print_to_stream(lhs,
rhs);
2951#pragma pop_macro("min")
2952#pragma pop_macro("max")
2954#pragma inline_recursion(off)
2963 template <
typename T>
2969 parse_path_callback<std::string_view>,
2970 parse_path_callback<size_t>);
2984#if TOML_ENABLE_WINDOWS_COMPAT
3010#pragma inline_recursion(on)
3012#pragma push_macro("min")
3013#pragma push_macro("max")
3031 (
sizeof(size_t) <
sizeof(std::string) ?
sizeof(std::string) :
sizeof(size_t));
3033 (
alignof(size_t) <
alignof(std::string) ?
alignof(std::string) :
alignof(size_t));
3045 template <
typename Type>
3054 ::new (
static_cast<void*
>(storage_.
bytes)) std::string{
key };
3059 ::new (
static_cast<void*
>(storage_.bytes)) std::size_t{
index };
3064 if (
type_ == path_component_type::key)
3096#if TOML_ENABLE_WINDOWS_COMPAT
3124#if TOML_ENABLE_WINDOWS_COMPAT
3144 explicit operator size_t() const noexcept
3150 const std::string&
key() const noexcept
3157 explicit operator const std::string&()
const noexcept
3163 path_component_type
type() const noexcept
3203#if TOML_ENABLE_WINDOWS_COMPAT
3207 explicit path(std::wstring_view);
3226 explicit operator bool() const noexcept
3258#if TOML_ENABLE_WINDOWS_COMPAT
3274 return *
this = std::move(
p);
3283#if TOML_ENABLE_WINDOWS_COMPAT
3286 path& assign(std::wstring_view str)
3302#if TOML_ENABLE_WINDOWS_COMPAT
3318 return *
this += std::move(
p);
3324 return *
this +=
str;
3327#if TOML_ENABLE_WINDOWS_COMPAT
3330 path& append(std::wstring_view str)
3332 return *
this += str;
3346#if TOML_ENABLE_WINDOWS_COMPAT
3377#if TOML_ENABLE_WINDOWS_COMPAT
3380 friend path operator+(
const path& lhs, std::wstring_view
rhs)
3388 friend path operator+(std::wstring_view lhs,
const path&
rhs)
3410 explicit operator std::string()
const
3415#if TOML_ENABLE_WINDOWS_COMPAT
3419 std::wstring wide_str()
const;
3423 explicit operator std::wstring()
const
3470#if TOML_ENABLE_WINDOWS_COMPAT
3481 friend bool operator==(std::wstring_view lhs,
const path&
rhs)
3488 friend bool operator!=(
const path& lhs, std::wstring_view
rhs)
3495 friend bool operator!=(std::wstring_view lhs,
const path&
rhs)
3502 using iterator = std::vector<path_component>::iterator;
3573 path operator"" _tpath(
const char* str,
size_t len)
3575 return path(std::string_view{ str, len });
3590#pragma pop_macro("min")
3591#pragma pop_macro("max")
3593#pragma inline_recursion(off)
3609#pragma inline_recursion(on)
3611#pragma push_macro("min")
3612#pragma push_macro("max")
3624 source_region source_{};
3626 template <
typename T>
3628 decltype(
auto) get_value_exact()
const noexcept(impl::value_retrieval_is_nothrow<T>);
3630 template <
typename T,
typename N>
3631 using ref_type_ = std::conditional_t<
3632 std::is_reference_v<T>,
3633 impl::copy_ref<impl::copy_cv<impl::unwrap_node<T>, std::remove_reference_t<N>>,
T>,
3634 impl::copy_cvref<impl::unwrap_node<T>,
N>
3637 template <
typename T,
typename N>
3638 using ref_type = std::conditional_t<
3639 std::is_reference_v<N>,
3641 ref_type_<T, std::add_lvalue_reference_t<N>>
3644 template <
typename T,
typename N>
3646 static ref_type<T, N&&> do_ref(
N&&
n)
noexcept
3648 using unwrapped_type = impl::unwrap_node<T>;
3649 static_assert(toml::is_value<unwrapped_type> || toml::is_container<unwrapped_type>,
3653 n.template is<unwrapped_type>()
3654 &&
"template type argument provided to toml::node::ref() didn't match the node's actual type");
3656 using node_ref = std::remove_volatile_t<std::remove_reference_t<N>>&;
3657 using val_type = std::remove_volatile_t<unwrapped_type>;
3658 using out_ref = ref_type<T, N&&>;
3659 static_assert(std::is_reference_v<out_ref>);
3661 if constexpr (toml::is_value<unwrapped_type>)
3662 return static_cast<out_ref
>(
const_cast<node_ref
>(
n).
template ref_cast<val_type>().
get());
3664 return static_cast<out_ref
>(
const_cast<node_ref
>(
n).template ref_cast<val_type>());
3678 node& operator=(
const node&)
noexcept;
3683 template <
typename T,
typename N>
3684 using ref_cast_type_ = std::conditional_t<
3685 std::is_reference_v<T>,
3686 impl::copy_ref<impl::copy_cv<impl::wrap_node<T>, std::remove_reference_t<N>>,
T>,
3687 impl::copy_cvref<impl::wrap_node<T>,
N>
3690 template <
typename T,
typename N>
3691 using ref_cast_type = std::conditional_t<
3692 std::is_reference_v<N>,
3693 ref_cast_type_<T, N>,
3694 ref_cast_type_<T, std::add_lvalue_reference_t<N>>
3697 template <
typename T>
3699 ref_cast_type<T, node&> ref_cast() &
noexcept
3701 using out_ref = ref_cast_type<T, node&>;
3702 using out_type = std::remove_reference_t<out_ref>;
3703 return static_cast<out_ref
>(*
reinterpret_cast<out_type*
>(
this));
3706 template <
typename T>
3708 ref_cast_type<T, node&&> ref_cast() &&
noexcept
3710 using out_ref = ref_cast_type<T, node&&>;
3711 using out_type = std::remove_reference_t<out_ref>;
3712 return static_cast<out_ref
>(*
reinterpret_cast<out_type*
>(
this));
3715 template <
typename T>
3717 ref_cast_type<T, const node&> ref_cast()
const&
noexcept
3719 using out_ref = ref_cast_type<T, const node&>;
3720 using out_type = std::remove_reference_t<out_ref>;
3721 return static_cast<out_ref
>(*
reinterpret_cast<out_type*
>(
this));
3724 template <
typename T>
3726 ref_cast_type<T, const node&&> ref_cast()
const&&
noexcept
3728 using out_ref = ref_cast_type<T, const node&&>;
3729 using out_type = std::remove_reference_t<out_ref>;
3730 return static_cast<out_ref
>(*
reinterpret_cast<out_type*
>(
this));
3735 virtual ~node()
noexcept;
3738 virtual bool is_homogeneous(node_type ntype,
node*& first_nonmatch)
noexcept = 0;
3741 virtual bool is_homogeneous(node_type ntype,
const node*& first_nonmatch)
const noexcept = 0;
3744 virtual bool is_homogeneous(node_type ntype)
const noexcept = 0;
3746 template <
typename ElemType =
void>
3748 bool is_homogeneous()
const noexcept
3750 using type = impl::remove_cvref<impl::unwrap_node<ElemType>>;
3751 static_assert(std::is_void_v<type> || toml::is_value<type> || toml::is_container<type>,
3752 "The template type argument of node::is_homogeneous() must be void or one "
3755 return is_homogeneous(impl::node_type_of<type>);
3759 virtual node_type type()
const noexcept = 0;
3762 virtual bool is_table()
const noexcept = 0;
3765 virtual bool is_array()
const noexcept = 0;
3768 virtual bool is_array_of_tables()
const noexcept = 0;
3771 virtual bool is_value()
const noexcept = 0;
3774 virtual bool is_string()
const noexcept = 0;
3777 virtual bool is_integer()
const noexcept = 0;
3783 virtual bool is_number()
const noexcept = 0;
3786 virtual bool is_boolean()
const noexcept = 0;
3789 virtual bool is_date()
const noexcept = 0;
3792 virtual bool is_time()
const noexcept = 0;
3797 template <
typename T>
3799 bool is()
const noexcept
3801 using type = impl::remove_cvref<impl::unwrap_node<T>>;
3802 static_assert(toml::is_value<type> || toml::is_container<type>,
3805 if constexpr (std::is_same_v<type, table>)
3807 else if constexpr (std::is_same_v<type, array>)
3809 else if constexpr (std::is_same_v<type, std::string>)
3811 else if constexpr (std::is_same_v<type, int64_t>)
3813 else if constexpr (std::is_same_v<type, double>)
3815 else if constexpr (std::is_same_v<type, bool>)
3817 else if constexpr (std::is_same_v<type, date>)
3819 else if constexpr (std::is_same_v<type, time>)
3821 else if constexpr (std::is_same_v<type, date_time>)
3826 virtual table* as_table()
noexcept = 0;
3829 virtual array* as_array()
noexcept = 0;
3832 virtual toml::value<std::string>* as_string()
noexcept = 0;
3835 virtual toml::value<int64_t>* as_integer()
noexcept = 0;
3838 virtual toml::value<double>* as_floating_point()
noexcept = 0;
3841 virtual toml::value<bool>* as_boolean()
noexcept = 0;
3844 virtual toml::value<date>* as_date()
noexcept = 0;
3847 virtual toml::value<time>* as_time()
noexcept = 0;
3850 virtual toml::value<date_time>* as_date_time()
noexcept = 0;
3853 virtual const table* as_table()
const noexcept = 0;
3856 virtual const array* as_array()
const noexcept = 0;
3859 virtual const toml::value<std::string>* as_string()
const noexcept = 0;
3862 virtual const toml::value<int64_t>* as_integer()
const noexcept = 0;
3865 virtual const toml::value<double>* as_floating_point()
const noexcept = 0;
3868 virtual const toml::value<bool>* as_boolean()
const noexcept = 0;
3871 virtual const toml::value<date>* as_date()
const noexcept = 0;
3874 virtual const toml::value<time>* as_time()
const noexcept = 0;
3877 virtual const toml::value<date_time>* as_date_time()
const noexcept = 0;
3879 template <
typename T>
3881 impl::wrap_node<T>* as()
noexcept
3883 using unwrapped_type = impl::unwrap_node<impl::remove_cvref<T>>;
3884 static_assert(toml::is_value<unwrapped_type> || toml::is_container<unwrapped_type>,
3887 if constexpr (std::is_same_v<unwrapped_type, table>)
3889 else if constexpr (std::is_same_v<unwrapped_type, array>)
3891 else if constexpr (std::is_same_v<unwrapped_type, std::string>)
3893 else if constexpr (std::is_same_v<unwrapped_type, int64_t>)
3894 return as_integer();
3895 else if constexpr (std::is_same_v<unwrapped_type, double>)
3896 return as_floating_point();
3897 else if constexpr (std::is_same_v<unwrapped_type, bool>)
3898 return as_boolean();
3899 else if constexpr (std::is_same_v<unwrapped_type, date>)
3901 else if constexpr (std::is_same_v<unwrapped_type, time>)
3903 else if constexpr (std::is_same_v<unwrapped_type, date_time>)
3904 return as_date_time();
3907 template <
typename T>
3909 const impl::wrap_node<T>* as()
const noexcept
3911 using unwrapped_type = impl::unwrap_node<impl::remove_cvref<T>>;
3912 static_assert(toml::is_value<unwrapped_type> || toml::is_container<unwrapped_type>,
3915 if constexpr (std::is_same_v<unwrapped_type, table>)
3917 else if constexpr (std::is_same_v<unwrapped_type, array>)
3919 else if constexpr (std::is_same_v<unwrapped_type, std::string>)
3921 else if constexpr (std::is_same_v<unwrapped_type, int64_t>)
3922 return as_integer();
3923 else if constexpr (std::is_same_v<unwrapped_type, double>)
3924 return as_floating_point();
3925 else if constexpr (std::is_same_v<unwrapped_type, bool>)
3926 return as_boolean();
3927 else if constexpr (std::is_same_v<unwrapped_type, date>)
3929 else if constexpr (std::is_same_v<unwrapped_type, time>)
3931 else if constexpr (std::is_same_v<unwrapped_type, date_time>)
3932 return as_date_time();
3935 template <
typename T>
3937 optional<T> value_exact()
const noexcept(impl::value_retrieval_is_nothrow<T>);
3939 template <
typename T>
3941 optional<T>
value()
const noexcept(impl::value_retrieval_is_nothrow<T>);
3943 template <
typename T>
3945 auto value_or(
T&& default_value)
const noexcept(impl::value_retrieval_is_nothrow<T>);
3947 template <
typename T>
3949 decltype(
auto) ref() &
noexcept
3951 return do_ref<T>(*
this);
3954 template <
typename T>
3956 decltype(
auto) ref() &&
noexcept
3958 return do_ref<T>(std::move(*
this));
3961 template <
typename T>
3963 decltype(
auto) ref()
const&
noexcept
3965 return do_ref<T>(*
this);
3968 template <
typename T>
3970 decltype(
auto) ref()
const&&
noexcept
3972 return do_ref<T>(std::move(*
this));
3976 const source_region& source()
const noexcept
3983 template <
typename Func,
typename Node,
typename T>
3984 static constexpr bool can_visit = std::is_invocable_v<Func, ref_cast_type<T, Node>>;
3986 template <
typename Func,
typename Node,
typename T>
3987 static constexpr bool can_visit_nothrow = std::is_nothrow_invocable_v<Func, ref_cast_type<T, Node>>;
3989 template <
typename Func,
typename Node>
3990 static constexpr bool can_visit_any = can_visit<Func, Node, table>
3991 || can_visit<Func, Node, array>
3992 || can_visit<Func, Node, std::string>
3993 || can_visit<Func, Node, int64_t>
3994 || can_visit<Func, Node, double>
3995 || can_visit<Func, Node, bool>
3996 || can_visit<Func, Node, date>
3997 || can_visit<Func, Node, time>
3998 || can_visit<Func, Node, date_time>;
4002 template <
typename Func,
typename Node>
4003 static constexpr bool can_visit_all = can_visit<Func, Node, table>
4004 && can_visit<Func, Node, array>
4005 && can_visit<Func, Node, std::string>
4006 && can_visit<Func, Node, int64_t>
4007 && can_visit<Func, Node, double>
4008 && can_visit<Func, Node, bool>
4009 && can_visit<Func, Node, date>
4010 && can_visit<Func, Node, time>
4011 && can_visit<Func, Node, date_time>;
4013 template <
typename Func,
typename Node,
typename T>
4014 static constexpr bool visit_is_nothrow_one = !can_visit<Func, Node, T> || can_visit_nothrow<Func, Node, T>;
4016 template <
typename Func,
typename Node>
4017 static constexpr bool visit_is_nothrow = visit_is_nothrow_one<Func, Node, table>
4018 && visit_is_nothrow_one<Func, Node, array>
4019 && visit_is_nothrow_one<Func, Node, std::string>
4020 && visit_is_nothrow_one<Func, Node, int64_t>
4021 && visit_is_nothrow_one<Func, Node, double>
4022 && visit_is_nothrow_one<Func, Node, bool>
4023 && visit_is_nothrow_one<Func, Node, date>
4024 && visit_is_nothrow_one<Func, Node, time>
4025 && visit_is_nothrow_one<Func, Node, date_time>;
4029 template <
typename Func,
typename Node,
typename T,
bool = can_visit<Func, Node, T>>
4030 struct visit_return_type_
4032 using type =
decltype(std::declval<Func>()(std::declval<ref_cast_type<T, Node>>()));
4034 template <
typename Func,
typename Node,
typename T>
4035 struct visit_return_type_<Func, Node,
T, false>
4040 template <
typename Func,
typename Node,
typename T>
4041 using visit_return_type =
typename visit_return_type_<Func, Node, T>::type;
4043 template <
typename A,
typename B>
4044 using nonvoid = std::conditional_t<std::is_void_v<A>,
B,
A>;
4046 template <
typename Func,
typename Node>
4047 static decltype(
auto) do_visit(Func&& visitor, Node&&
n)
noexcept(visit_is_nothrow<Func&&, Node&&>)
4049 static_assert(can_visit_any<Func&&, Node&&>,
4050 "TOML node visitors must be invocable for at least one of the toml::node "
4055 case node_type::table:
4056 if constexpr (can_visit<Func&&, Node&&, table>)
4057 return static_cast<Func&&
>(visitor)(
static_cast<Node&&
>(
n).template ref_cast<table>());
4060 case node_type::array:
4061 if constexpr (can_visit<Func&&, Node&&, array>)
4062 return static_cast<Func&&
>(visitor)(
static_cast<Node&&
>(
n).template ref_cast<array>());
4065 case node_type::string:
4066 if constexpr (can_visit<Func&&, Node&&, std::string>)
4067 return static_cast<Func&&
>(visitor)(
static_cast<Node&&
>(
n).template ref_cast<std::string>());
4070 case node_type::integer:
4071 if constexpr (can_visit<Func&&, Node&&, int64_t>)
4072 return static_cast<Func&&
>(visitor)(
static_cast<Node&&
>(
n).template ref_cast<int64_t>());
4075 case node_type::floating_point:
4076 if constexpr (can_visit<Func&&, Node&&, double>)
4077 return static_cast<Func&&
>(visitor)(
static_cast<Node&&
>(
n).template ref_cast<double>());
4080 case node_type::boolean:
4081 if constexpr (can_visit<Func&&, Node&&, bool>)
4082 return static_cast<Func&&
>(visitor)(
static_cast<Node&&
>(
n).template ref_cast<bool>());
4085 case node_type::date:
4086 if constexpr (can_visit<Func&&, Node&&, date>)
4087 return static_cast<Func&&
>(visitor)(
static_cast<Node&&
>(
n).template ref_cast<date>());
4090 case node_type::time:
4091 if constexpr (can_visit<Func&&, Node&&, time>)
4092 return static_cast<Func&&
>(visitor)(
static_cast<Node&&
>(
n).template ref_cast<time>());
4095 case node_type::date_time:
4096 if constexpr (can_visit<Func&&, Node&&, date_time>)
4097 return static_cast<Func&&
>(visitor)(
static_cast<Node&&
>(
n).template ref_cast<date_time>());
4104 if constexpr (!can_visit_all<Func&&, Node&&>)
4109 nonvoid<visit_return_type<Func&&, Node&&, table>,
4110 nonvoid<visit_return_type<Func&&, Node&&, array>,
4111 nonvoid<visit_return_type<Func&&, Node&&, std::string>,
4112 nonvoid<visit_return_type<Func&&, Node&&, int64_t>,
4113 nonvoid<visit_return_type<Func&&, Node&&, double>,
4114 nonvoid<visit_return_type<Func&&, Node&&, bool>,
4115 nonvoid<visit_return_type<Func&&, Node&&, date>,
4116 nonvoid<visit_return_type<Func&&, Node&&, time>,
4117 visit_return_type<Func&&, Node&&, date_time>
4122 if constexpr (!std::is_void_v<return_type>)
4124 static_assert(std::is_default_constructible_v<return_type>,
4125 "Non-exhaustive visitors must return a default-constructible type, or void");
4126 return return_type{};
4133 template <
typename Func>
4134 decltype(
auto) visit(Func&& visitor) &
noexcept(visit_is_nothrow<Func&&, node&>)
4136 return do_visit(
static_cast<Func&&
>(visitor), *
this);
4139 template <
typename Func>
4140 decltype(
auto) visit(Func&& visitor) &&
noexcept(visit_is_nothrow<Func&&, node&&>)
4142 return do_visit(
static_cast<Func&&
>(visitor),
static_cast<node&&
>(*
this));
4145 template <
typename Func>
4146 decltype(
auto) visit(Func&& visitor)
const&
noexcept(visit_is_nothrow<Func&&, const node&>)
4148 return do_visit(
static_cast<Func&&
>(visitor), *
this);
4151 template <
typename Func>
4152 decltype(
auto) visit(Func&& visitor)
const&&
noexcept(visit_is_nothrow<Func&&, const node&&>)
4154 return do_visit(
static_cast<Func&&
>(visitor),
static_cast<const node&&
>(*
this));
4179#if TOML_ENABLE_WINDOWS_COMPAT
4206 bool TOML_CALLCONV node_deep_equality(
const node*,
const node*)
noexcept;
4211#pragma pop_macro("min")
4212#pragma pop_macro("max")
4214#pragma inline_recursion(off)
4222#include <initializer_list>
4230#pragma inline_recursion(on)
4232#pragma push_macro("min")
4233#pragma push_macro("max")
4242 template <
typename ViewedType>
4245 static_assert(impl::is_one_of<ViewedType, toml::node, const toml::node>,
4246 "A toml::node_view<> must wrap toml::node or const toml::node.");
4250 using viewed_type = ViewedType;
4253 template <
typename T>
4256 mutable viewed_type* node_ =
nullptr;
4264 explicit node_view(viewed_type* node)
noexcept
4269 explicit node_view(viewed_type& node)
noexcept
4284 explicit operator bool()
const noexcept
4286 return node_ !=
nullptr;
4290 viewed_type* node()
const noexcept
4296 node_type type()
const noexcept
4298 return node_ ? node_->type() : node_type::none;
4302 bool is_table()
const noexcept
4304 return node_ && node_->is_table();
4310 return node_ && node_->is_array();
4316 return node_ && node_->is_value();
4322 return node_ && node_->is_string();
4328 return node_ && node_->is_integer();
4334 return node_ && node_->is_floating_point();
4340 return node_ && node_->is_number();
4346 return node_ && node_->is_boolean();
4352 return node_ && node_->is_date();
4358 return node_ && node_->is_time();
4364 return node_ && node_->is_date_time();
4368 bool is_array_of_tables()
const noexcept
4370 return node_ && node_->is_array_of_tables();
4373 template <
typename T>
4375 bool is()
const noexcept
4377 return node_ ? node_->template is<impl::unwrap_node<impl::remove_cvref<T>>>() :
false;
4381 bool is_homogeneous(node_type ntype, viewed_type*& first_nonmatch)
const noexcept
4385 first_nonmatch = {};
4388 return node_->is_homogeneous(ntype, first_nonmatch);
4392 bool is_homogeneous(node_type ntype)
const noexcept
4394 return node_ ? node_->is_homogeneous(ntype) :
false;
4397 template <
typename ElemType =
void>
4399 bool is_homogeneous()
const noexcept
4401 return node_ ? node_->template is_homogeneous<impl::unwrap_node<impl::remove_cvref<ElemType>>>() :
false;
4404 template <
typename T>
4406 auto* as()
const noexcept
4408 return node_ ? node_->template as<T>() :
nullptr;
4412 auto* as_table()
const noexcept
4418 auto* as_array()
const noexcept
4424 auto* as_string()
const noexcept
4426 return as<std::string>();
4430 auto* as_integer()
const noexcept
4432 return as<int64_t>();
4436 auto* as_floating_point()
const noexcept
4438 return as<double>();
4442 auto* as_boolean()
const noexcept
4448 auto* as_date()
const noexcept
4454 auto* as_time()
const noexcept
4460 auto* as_date_time()
const noexcept
4462 return as<date_time>();
4465 template <
typename T>
4467 optional<T> value_exact()
const noexcept(impl::value_retrieval_is_nothrow<T>)
4470 return node_->template value_exact<T>();
4474 template <
typename T>
4476 optional<T>
value()
const noexcept(impl::value_retrieval_is_nothrow<T>)
4483 template <
typename T>
4485 auto value_or(T&& default_value)
const noexcept(impl::value_retrieval_is_nothrow<T>)
4487 using namespace ::toml::impl;
4490 "Retrieving values as wide-character strings is only "
4491 "supported on Windows with TOML_ENABLE_WINDOWS_COMPAT enabled.");
4495#if TOML_ENABLE_WINDOWS_COMPAT
4498 return node_->value_or(
static_cast<T&&
>(default_value));
4499 return std::wstring{
static_cast<T&&
>(default_value) };
4503 static_assert(impl::always_false<T>,
"Evaluated unreachable branch!");
4510 std::conditional_t<std::is_pointer_v<std::decay_t<T>>,
4511 std::add_pointer_t<std::add_const_t<std::remove_pointer_t<std::decay_t<T>>>>,
4515 return node_->value_or(
static_cast<T&&
>(default_value));
4516 if constexpr (std::is_pointer_v<value_type>)
4519 return static_cast<T&&
>(default_value);
4523 template <
typename T>
4525 decltype(
auto) ref()
const noexcept
4527 TOML_ASSERT_ASSUME(node_ &&
"toml::node_view::ref() called on a node_view that did not reference a node");
4528 return node_->template ref<T>();
4533 template <
typename Func>
4534 static constexpr bool visit_is_nothrow =
noexcept(std::declval<viewed_type*>()->visit(std::declval<Func>()));
4538 template <
typename Func>
4539 decltype(
auto) visit(Func&& visitor)
const noexcept(visit_is_nothrow<Func&&>)
4541 using return_type =
decltype(node_->visit(
static_cast<Func&&
>(visitor)));
4543 return node_->visit(
static_cast<Func&&
>(visitor));
4544 if constexpr (!std::is_void_v<return_type>)
4545 return return_type{};
4550 template <
typename T>
4554 return impl::node_deep_equality(lhs.node_,
rhs.node_);
4557 template <
typename T>
4561 return !impl::node_deep_equality(lhs.node_,
rhs.node_);
4567 if (lhs.node_ == &
rhs)
4569 const auto tbl = lhs.as<
table>();
4570 return tbl && *tbl ==
rhs;
4577 if (lhs.node_ == &
rhs)
4579 const auto arr = lhs.as<
array>();
4580 return arr && *arr ==
rhs;
4584 template <
typename T>
4588 if (lhs.node_ == &
rhs)
4590 const auto val = lhs.as<T>();
4591 return val && *val ==
rhs;
4600 "Comparison with wide-character strings is only "
4601 "supported on Windows with TOML_ENABLE_WINDOWS_COMPAT enabled.");
4603 if constexpr (impl::is_wide_string<T>)
4605#if TOML_ENABLE_WINDOWS_COMPAT
4606 return lhs == impl::narrow(
rhs);
4608 static_assert(impl::always_false<T>,
"Evaluated unreachable branch!");
4613 const auto val = lhs.as<impl::native_type_of<T>>();
4614 return val && *val ==
rhs;
4622 template <
typename T>
4625 const std::initializer_list<T>&
rhs)
noexcept(!impl::is_wide_string<T>)
4627 const auto arr = lhs.as<
array>();
4628 return arr && *arr ==
rhs;
4632 template <
typename T>
4634 friend bool operator==(
const node_view& lhs,
const std::vector<T>&
rhs)
noexcept(!impl::is_wide_string<T>)
4636 const auto arr = lhs.as<
array>();
4637 return arr && *arr ==
rhs;
4644 if (
auto tbl = this->as_table())
4667#if TOML_ENABLE_WINDOWS_COMPAT
4672 if (
auto tbl = this->as_table())
4688 if (
auto arr = this->as_array())
4693#if TOML_ENABLE_FORMATTERS
4698 nv.node_->visit([&os](
const auto&
n) { os <<
n; });
4705 template <
typename T>
4708 template <
typename T>
4711 template <
typename T>
4714 template <
typename T>
4734#pragma pop_macro("min")
4735#pragma pop_macro("max")
4737#pragma inline_recursion(off)
4747#pragma inline_recursion(on)
4749#pragma push_macro("min")
4750#pragma push_macro("max")
4759#if TOML_ENABLE_WINDOWS_COMPAT
4760 #define TOML_SA_VALUE_MESSAGE_WSTRING TOML_SA_LIST_SEP "std::wstring"
4762 #define TOML_SA_VALUE_MESSAGE_WSTRING
4765 #define TOML_SA_VALUE_MESSAGE_U8STRING_VIEW TOML_SA_LIST_SEP "std::u8string_view"
4766 #define TOML_SA_VALUE_MESSAGE_CONST_CHAR8 TOML_SA_LIST_SEP "const char8_t*"
4768 #define TOML_SA_VALUE_MESSAGE_U8STRING_VIEW
4769 #define TOML_SA_VALUE_MESSAGE_CONST_CHAR8
4772#define TOML_SA_VALUE_EXACT_FUNC_MESSAGE(type_arg) \
4773 "The " type_arg " must be one of:" \
4774 TOML_SA_LIST_NEW "A native TOML value type" \
4775 TOML_SA_NATIVE_VALUE_TYPE_LIST \
4777 TOML_SA_LIST_NXT "A non-view type capable of losslessly representing a native TOML value type" \
4778 TOML_SA_LIST_BEG "std::string" \
4779 TOML_SA_VALUE_MESSAGE_WSTRING \
4780 TOML_SA_LIST_SEP "any signed integer type >= 64 bits" \
4781 TOML_SA_LIST_SEP "any floating-point type >= 64 bits" \
4784 TOML_SA_LIST_NXT "An immutable view type not requiring additional temporary storage" \
4785 TOML_SA_LIST_BEG "std::string_view" \
4786 TOML_SA_VALUE_MESSAGE_U8STRING_VIEW \
4787 TOML_SA_LIST_SEP "const char*" \
4788 TOML_SA_VALUE_MESSAGE_CONST_CHAR8 \
4791#define TOML_SA_VALUE_FUNC_MESSAGE(type_arg) \
4792 "The " type_arg " must be one of:" \
4793 TOML_SA_LIST_NEW "A native TOML value type" \
4794 TOML_SA_NATIVE_VALUE_TYPE_LIST \
4796 TOML_SA_LIST_NXT "A non-view type capable of losslessly representing a native TOML value type" \
4797 TOML_SA_LIST_BEG "std::string" \
4798 TOML_SA_VALUE_MESSAGE_WSTRING \
4799 TOML_SA_LIST_SEP "any signed integer type >= 64 bits" \
4800 TOML_SA_LIST_SEP "any floating-point type >= 64 bits" \
4803 TOML_SA_LIST_NXT "A non-view type capable of (reasonably) representing a native TOML value type" \
4804 TOML_SA_LIST_BEG "any other integral type" \
4805 TOML_SA_LIST_SEP "any floating-point type" \
4808 TOML_SA_LIST_NXT "An immutable view type not requiring additional temporary storage" \
4809 TOML_SA_LIST_BEG "std::string_view" \
4810 TOML_SA_VALUE_MESSAGE_U8STRING_VIEW \
4811 TOML_SA_LIST_SEP "const char*" \
4812 TOML_SA_VALUE_MESSAGE_CONST_CHAR8 \
4818 template <
typename T,
typename...>
4819 struct native_value_maker
4821 template <
typename... Args>
4823 static T
make(Args&&... args)
noexcept(std::is_nothrow_constructible_v<T, Args&&...>)
4825 if constexpr (std::is_aggregate_v<T>)
4826 return T{
static_cast<Args&&
>(args)... };
4828 return T(
static_cast<Args&&
>(args)...);
4832 template <
typename T>
4833 struct native_value_maker<T, T>
4835 template <
typename U>
4840 return static_cast<U&&
>(val);
4844#if TOML_HAS_CHAR8 || TOML_ENABLE_WINDOWS_COMPAT
4848 template <
typename T>
4850 static std::string
make(T&& arg)
4852 using arg_type = std::decay_t<T>;
4856 return std::string(
reinterpret_cast<const char*
>(
static_cast<const char8_t*
>(arg)));
4860 return std::string(
reinterpret_cast<const char*
>(
static_cast<const char8_t*
>(arg.data())),
4865#if TOML_ENABLE_WINDOWS_COMPAT
4868 return narrow(
static_cast<T&&
>(arg));
4876 struct native_value_maker<
std::
string, char8_t*> : string_maker
4879 struct native_value_maker<
std::
string, const char8_t*> : string_maker
4882 struct native_value_maker<
std::
string, std::u8string> : string_maker
4885 struct native_value_maker<
std::
string, std::u8string_view> : string_maker
4889#if TOML_ENABLE_WINDOWS_COMPAT
4891 struct native_value_maker<
std::
string, wchar_t*> : string_maker
4894 struct native_value_maker<
std::
string, const wchar_t*> : string_maker
4897 struct native_value_maker<
std::
string, std::wstring> : string_maker
4900 struct native_value_maker<
std::
string, std::wstring_view> : string_maker
4906 template <
typename T>
4914 if constexpr (!traits::is_signed)
4916 if constexpr ((
sizeof(T) * CHAR_BIT) < 63)
4918 using common_t =
decltype(int64_t{} + T{});
4919 if (val < int64_t{} ||
static_cast<common_t
>(val) >
static_cast<common_t
>(traits::max))
4924 if (val < int64_t{})
4930 if (val < traits::min || val > traits::max)
4933 return {
static_cast<T
>(val) };
4936 template <
typename...>
4940 template <
typename T,
typename... Args>
4948 template <
typename ValueType>
4949 class value :
public node
4951 static_assert(impl::is_native<ValueType> && !impl::is_cvref<ValueType>,
4958 template <
typename T,
typename U>
4960 static auto as_value([[maybe_unused]] U*
ptr)
noexcept
4962 if constexpr (std::is_same_v<value_type, T>)
4977 std::is_same_v<value_type, std::string>,
4979 std::conditional_t<impl::is_one_of<value_type, double, int64_t, bool>,
value_type,
const value_type&>>);
4986 impl::native_value_maker<
value_type, std::decay_t<Args>...>
::make(
static_cast<Args&&
>(args)...))))
4987 : val_(impl::native_value_maker<
value_type, std::decay_t<Args>...>::
make(static_cast<Args&&>(
args)...))
4989#if TOML_LIFETIME_HOOKS
4998 flags_{ other.flags_ }
5000#if TOML_LIFETIME_HOOKS
5011#if TOML_LIFETIME_HOOKS
5018 :
node(std::move(other)),
5019 val_{ std::move(other.val_) },
5020 flags_{ std::exchange(other.flags_,
value_flags{}) }
5022#if TOML_LIFETIME_HOOKS
5029 :
node(std::move(other)),
5030 val_{ std::move(other.val_) },
5033#if TOML_LIFETIME_HOOKS
5041 node::operator=(
rhs);
5043 flags_ =
rhs.flags_;
5051 node::operator=(std::move(
rhs));
5052 val_ = std::move(
rhs.val_);
5058#if TOML_LIFETIME_HOOKS
5061 TOML_VALUE_DESTROYED;
5066 node_type type() const noexcept final
5068 return impl::node_type_of<value_type>;
5072 bool is_homogeneous(node_type ntype)
const noexcept final
5074 return ntype == node_type::none || ntype == impl::node_type_of<value_type>;
5078 bool is_homogeneous(node_type ntype, node*& first_nonmatch)
noexcept final
5080 if (ntype != node_type::none && ntype != impl::node_type_of<value_type>)
5082 first_nonmatch =
this;
5089 bool is_homogeneous(node_type ntype,
const node*& first_nonmatch)
const noexcept final
5091 if (ntype != node_type::none && ntype != impl::node_type_of<value_type>)
5093 first_nonmatch =
this;
5099 template <
typename ElemType =
void>
5101 bool is_homogeneous() const noexcept
5103 using type = impl::remove_cvref<impl::unwrap_node<ElemType>>;
5104 static_assert(std::is_void_v<type> || toml::is_value<type> || toml::is_container<type>,
5105 "The template type argument of value::is_homogeneous() must be void or one "
5108 if constexpr (std::is_void_v<type>)
5111 return impl::node_type_of<type> == impl::node_type_of<value_type>;
5114 bool is_table() const noexcept final
5120 bool is_array() const noexcept final
5126 bool is_array_of_tables() const noexcept final
5132 bool is_value() const noexcept final
5140 return std::is_same_v<value_type, std::string>;
5146 return std::is_same_v<value_type, int64_t>;
5152 return std::is_same_v<value_type, double>;
5158 return impl::is_one_of<value_type, int64_t, double>;
5164 return std::is_same_v<value_type, bool>;
5168 bool is_date() const noexcept final
5170 return std::is_same_v<value_type, date>;
5174 bool is_time() const noexcept final
5176 return std::is_same_v<value_type, time>;
5182 return std::is_same_v<value_type, date_time>;
5186 table* as_table() noexcept final
5192 array* as_array() noexcept final
5198 value<std::string>* as_string() noexcept final
5200 return as_value<std::string>(
this);
5204 value<int64_t>* as_integer() noexcept final
5206 return as_value<int64_t>(
this);
5210 value<double>* as_floating_point() noexcept final
5212 return as_value<double>(
this);
5216 value<bool>* as_boolean() noexcept final
5218 return as_value<bool>(
this);
5222 value<date>* as_date() noexcept final
5224 return as_value<date>(
this);
5228 value<time>* as_time() noexcept final
5230 return as_value<time>(
this);
5234 value<date_time>* as_date_time() noexcept final
5236 return as_value<date_time>(
this);
5240 const table* as_table() const noexcept final
5246 const array* as_array() const noexcept final
5252 const value<std::string>* as_string() const noexcept final
5254 return as_value<std::string>(
this);
5258 const value<int64_t>* as_integer() const noexcept final
5260 return as_value<int64_t>(
this);
5264 const value<double>* as_floating_point() const noexcept final
5266 return as_value<double>(
this);
5270 const value<bool>* as_boolean() const noexcept final
5272 return as_value<bool>(
this);
5276 const value<date>* as_date() const noexcept final
5278 return as_value<date>(
this);
5282 const value<time>* as_time() const noexcept final
5284 return as_value<time>(
this);
5288 const value<date_time>* as_date_time() const noexcept final
5290 return as_value<date_time>(
this);
5314 return static_cast<const value_type&&
>(val_);
5330 const value_type& operator*() const& noexcept
5336 const value_type&& operator*() const&& noexcept
5338 return static_cast<const value_type&&
>(val_);
5354 explicit operator const value_type&()
const&
noexcept
5360 explicit operator const value_type&&() &&
noexcept
5362 return static_cast<const value_type&&
>(val_);
5374 const value_type* operator->() const noexcept
5391 value& operator=(value_arg
rhs)
noexcept
5393 if constexpr (std::is_same_v<value_type, std::string>)
5401 value& operator=(std::string&&
rhs)
noexcept
5403 val_ = std::move(
rhs);
5410 if constexpr (std::is_same_v<value_type, double>)
5412 const auto lhs_nan = impl::fpclassify(lhs.val_) == impl::fp_class::nan;
5413 const auto rhs_nan = impl::fpclassify(
rhs) == impl::fp_class::nan;
5414 if (lhs_nan != rhs_nan)
5419 return lhs.val_ ==
rhs;
5426 return lhs.val_ <
rhs;
5432 return lhs <
rhs.val_;
5436 friend bool operator<=(
const value& lhs, value_arg
rhs)
noexcept
5438 return lhs.val_ <=
rhs;
5442 friend bool operator<=(value_arg lhs,
const value&
rhs)
noexcept
5444 return lhs <=
rhs.val_;
5448 friend bool operator>(
const value& lhs, value_arg
rhs)
noexcept
5450 return lhs.val_ >
rhs;
5454 friend bool operator>(value_arg lhs,
const value&
rhs)
noexcept
5456 return lhs >
rhs.val_;
5460 friend bool operator>=(
const value& lhs, value_arg
rhs)
noexcept
5462 return lhs.val_ >=
rhs;
5466 friend bool operator>=(value_arg lhs,
const value&
rhs)
noexcept
5468 return lhs >=
rhs.val_;
5471 template <
typename T>
5475 if constexpr (std::is_same_v<value_type, T>)
5476 return lhs ==
rhs.val_;
5481 template <
typename T>
5485 return !(lhs ==
rhs);
5488 template <
typename T>
5492 if constexpr (std::is_same_v<value_type, T>)
5493 return lhs.val_ <
rhs.val_;
5495 return impl::node_type_of<value_type> < impl::node_type_of<T>;
5498 template <
typename T>
5502 if constexpr (std::is_same_v<value_type, T>)
5503 return lhs.val_ <=
rhs.val_;
5505 return impl::node_type_of<value_type> <= impl::node_type_of<T>;
5508 template <
typename T>
5512 if constexpr (std::is_same_v<value_type, T>)
5513 return lhs.val_ >
rhs.val_;
5515 return impl::node_type_of<value_type> > impl::node_type_of<T>;
5518 template <
typename T>
5522 if constexpr (std::is_same_v<value_type, T>)
5523 return lhs.val_ >=
rhs.val_;
5525 return impl::node_type_of<value_type> >= impl::node_type_of<T>;
5528#if TOML_ENABLE_FORMATTERS
5532 impl::print_to_stream(lhs,
rhs);
5539 template <
typename T>
5541 template <
typename T>
5544 template <
typename T>
5548 using namespace impl;
5559 const auto& str = *ref_cast<std::string>();
5560 if constexpr (std::is_same_v<T, std::string>)
5562 else if constexpr (std::is_same_v<T, std::string_view>)
5564 else if constexpr (std::is_same_v<T, const char*>)
5567 else if constexpr (std::is_same_v<T, std::wstring>)
5569#if TOML_ENABLE_WINDOWS_COMPAT
5580 return T(
reinterpret_cast<const char8_t*
>(str.c_str()), str.length());
5581 else if constexpr (std::is_same_v<T, const char8_t*>)
5582 return reinterpret_cast<const char8_t*
>(str.c_str());
5589 return static_cast<T
>(*ref_cast<native_type_of<T>>());
5592 template <
typename T>
5596 using namespace impl;
5599 "Retrieving values as wide-character strings with node::value_exact() is only "
5600 "supported on Windows with TOML_ENABLE_WINDOWS_COMPAT enabled.");
5609 return { this->get_value_exact<T>() };
5615 template <
typename T>
5619 using namespace impl;
5622 "Retrieving values as wide-character strings with node::value() is only "
5623 "supported on Windows with TOML_ENABLE_WINDOWS_COMPAT enabled.");
5632 return { this->get_value_exact<T>() };
5643 case node_type::integer:
5649 return static_cast<T>(*ref_cast<int64_t>());
5657 const int64_t val = *ref_cast<int64_t>();
5658 if constexpr (std::numeric_limits<T>::digits < 64)
5660 constexpr auto largest_whole_float = (int64_t{ 1 } << std::numeric_limits<T>::digits);
5661 if (val < -largest_whole_float || val > largest_whole_float)
5664 return static_cast<T>(val);
5669 return static_cast<bool>(*ref_cast<int64_t>());
5677 case node_type::floating_point:
5683 return {
static_cast<T>(*ref_cast<double>()) };
5686 const double val = *ref_cast<double>();
5687 if (impl::fpclassify(val) == fp_class::ok
5688 && (val < (std::numeric_limits<T>::lowest)() || val > (std::numeric_limits<T>::max)()))
5690 return {
static_cast<T>(val) };
5697 const double val = *ref_cast<double>();
5698 if (impl::fpclassify(val) == fp_class::ok
5699 &&
static_cast<double>(
static_cast<int64_t
>(val)) == val)
5711 case node_type::boolean:
5715 return { *ref_cast<bool>() };
5719 return {
static_cast<T>(*ref_cast<bool>()) };
5732 template <
typename T>
5734 inline auto node::value_or(T && default_value)
const noexcept(impl::value_retrieval_is_nothrow<T>)
5736 using namespace impl;
5739 "Retrieving values as wide-character strings with node::value_or() is only "
5740 "supported on Windows with TOML_ENABLE_WINDOWS_COMPAT enabled.");
5744#if TOML_ENABLE_WINDOWS_COMPAT
5746 if (type() == node_type::string)
5747 return widen(*ref_cast<std::string>());
5748 return std::wstring{
static_cast<T&&
>(default_value) };
5759 std::conditional_t<std::is_pointer_v<std::decay_t<T>>,
5760 std::add_pointer_t<std::add_const_t<std::remove_pointer_t<std::decay_t<T>>>>,
5767 traits::is_native || traits::can_represent_native || traits::can_partially_represent_native,
5768 "The default value type of node::value_or() must be one of:"
5772 TOML_SA_LIST_NXT "A non-view type capable of losslessly representing a native TOML value type"
5774 #if TOML_ENABLE_WINDOWS_COMPAT
5781 TOML_SA_LIST_NXT "A non-view type capable of (reasonably) representing a native TOML value type"
5791 #if TOML_ENABLE_WINDOWS_COMPAT
5798 #if TOML_ENABLE_WINDOWS_COMPAT
5807 if constexpr (traits::is_native || traits::can_represent_native || traits::can_partially_represent_native)
5809 if constexpr (traits::is_native)
5812 return *ref_cast<typename traits::native_type>();
5816 if constexpr (std::is_pointer_v<value_type>)
5819 return static_cast<T&&
>(default_value);
5827#pragma pop_macro("min")
5828#pragma pop_macro("max")
5830#pragma inline_recursion(off)
5840#pragma inline_recursion(on)
5842#pragma push_macro("min")
5843#pragma push_macro("max")
5850 template <
typename T>
5853 auto* make_node_impl_specialized(T && val, [[maybe_unused]]
value_flags flags)
5856 static_assert(!std::is_same_v<unwrapped_type, node>);
5862 return new unwrapped_type(
static_cast<T&&
>(val));
5874 if constexpr (std::is_same_v<remove_cvref<T>,
value_type>)
5883 "Instantiating values from wide-character strings is only "
5884 "supported on Windows with TOML_ENABLE_WINDOWS_COMPAT enabled.");
5888 if constexpr (std::is_same_v<native_type, int64_t>)
5890 "Integral value initializers must be losslessly convertible to int64_t");
5891 else if constexpr (std::is_same_v<native_type, double>)
5893 "Floating-point value initializers must be losslessly convertible to double");
5897 "Value initializers must be losslessly convertible to one of the TOML value types");
5902#if TOML_ENABLE_WINDOWS_COMPAT
5919 template <
typename T>
5929 return static_cast<toml::node*
>(
nullptr);
5932 return static_cast<T&&
>(val).visit(
5933 [flags](
auto&& concrete) {
5934 return static_cast<toml::node*
>(
5935 make_node_impl_specialized(
static_cast<decltype(concrete)&&
>(concrete), flags));
5939 return make_node_impl_specialized(
static_cast<T&&
>(val), flags);
5942 template <
typename T>
5946 return make_node_impl(
static_cast<T&&
>(val.value), flags);
5949 template <
typename T,
bool = (is_node<T> || is_node_view<T> || is_value<T> || can_partially_represent_native<T>)>
5950 struct inserted_type_of_
5952 using type = std::remove_pointer_t<decltype(make_node_impl(std::declval<T>()))>;
5955 template <
typename T>
5961 template <
typename T>
5962 struct inserted_type_of_<T, false>
5967 template <
typename T>
5971 return node_ptr{ make_node_impl(
static_cast<T&&
>(val), flags) };
5974 template <
typename...
T>
5980 template <
typename T>
5985 typename inserted_type_of_<T>::type>;
5988 template <
typename T>
5994 template <
typename... T>
6001 template <
typename T>
6007#pragma pop_macro("min")
6008#pragma pop_macro("max")
6010#pragma inline_recursion(off)
6020#pragma inline_recursion(on)
6022#pragma push_macro("min")
6023#pragma push_macro("max")
6028#ifndef TOML_RETURN_BOOL_FROM_FOR_EACH_BROKEN
6029#if TOML_GCC && TOML_GCC <= 7
6030#define TOML_RETURN_BOOL_FROM_FOR_EACH_BROKEN 1
6032#define TOML_RETURN_BOOL_FROM_FOR_EACH_BROKEN 0
6036#if TOML_RETURN_BOOL_FROM_FOR_EACH_BROKEN && !defined(TOML_RETURN_BOOL_FROM_FOR_EACH_BROKEN_ACKNOWLEDGED)
6037#define TOML_RETURN_BOOL_FROM_FOR_EACH_BROKEN_MESSAGE \
6038 "If you're seeing this error it's because you're using one of toml++'s for_each() functions on a compiler with " \
6039 "known bugs in that area (e.g. GCC 7). On these compilers returning a bool (or bool-convertible) value from the " \
6040 "for_each() callable causes spurious compilation failures, while returning nothing (void) works fine. " \
6041 "If you believe this message is incorrect for your compiler, you can try your luck by #defining " \
6042 "TOML_RETURN_BOOL_FROM_FOR_EACH_BROKEN as 0 and recompiling - if it works, great! Let me know at " \
6043 "https://github.com/marzer/tomlplusplus/issues. Alternatively, if you don't have any need for early-exiting from " \
6044 "for_each(), you can suppress this error by #defining TOML_RETURN_BOOL_FROM_FOR_EACH_BROKEN_ACKNOWLEDGED " \
6045 "and moving on with your life."
6050 template <
bool IsConst>
6055 friend class array_iterator;
6057 using mutable_vector_iterator = std::vector<node_ptr>::iterator;
6058 using const_vector_iterator = std::vector<node_ptr>::const_iterator;
6059 using vector_iterator = std::conditional_t<IsConst, const_vector_iterator, mutable_vector_iterator>;
6061 mutable vector_iterator iter_;
6064 using value_type = std::conditional_t<IsConst, const node, node>;
6067 using difference_type = ptrdiff_t;
6068 using iterator_category =
typename std::iterator_traits<vector_iterator>::iterator_category;
6071 array_iterator()
noexcept =
default;
6074 explicit array_iterator(mutable_vector_iterator iter)
noexcept
6080 explicit array_iterator(const_vector_iterator iter)
noexcept
6086 array_iterator(
const array_iterator<false>& other)
noexcept
6087 : iter_{ other.iter_ }
6091 array_iterator(
const array_iterator&)
noexcept =
default;
6093 array_iterator& operator=(
const array_iterator&)
noexcept =
default;
6095 array_iterator& operator++()
noexcept
6101 array_iterator operator++(
int)
noexcept
6103 array_iterator out{ iter_ };
6108 array_iterator& operator--()
noexcept
6114 array_iterator operator--(
int)
noexcept
6116 array_iterator out{ iter_ };
6122 reference operator*()
const noexcept
6124 return *iter_->get();
6128 pointer operator->()
const noexcept
6130 return iter_->get();
6134 explicit operator const vector_iterator&()
const noexcept
6141 explicit operator const const_vector_iterator()
const noexcept
6146 array_iterator& operator+=(ptrdiff_t
rhs)
noexcept
6152 array_iterator& operator-=(ptrdiff_t
rhs)
noexcept
6159 friend array_iterator operator+(
const array_iterator& lhs, ptrdiff_t
rhs)
noexcept
6161 return array_iterator{ lhs.iter_ +
rhs };
6165 friend array_iterator operator+(ptrdiff_t lhs,
const array_iterator&
rhs)
noexcept
6167 return array_iterator{
rhs.iter_ + lhs };
6171 friend array_iterator operator-(
const array_iterator& lhs, ptrdiff_t
rhs)
noexcept
6173 return array_iterator{ lhs.iter_ -
rhs };
6177 friend ptrdiff_t operator-(
const array_iterator& lhs,
const array_iterator&
rhs)
noexcept
6179 return lhs.iter_ -
rhs.iter_;
6183 friend bool operator==(
const array_iterator& lhs,
const array_iterator&
rhs)
noexcept
6185 return lhs.iter_ ==
rhs.iter_;
6189 friend bool operator!=(
const array_iterator& lhs,
const array_iterator&
rhs)
noexcept
6191 return lhs.iter_ !=
rhs.iter_;
6195 friend bool operator<(
const array_iterator& lhs,
const array_iterator&
rhs)
noexcept
6197 return lhs.iter_ <
rhs.iter_;
6201 friend bool operator<=(
const array_iterator& lhs,
const array_iterator&
rhs)
noexcept
6203 return lhs.iter_ <=
rhs.iter_;
6207 friend bool operator>(
const array_iterator& lhs,
const array_iterator&
rhs)
noexcept
6209 return lhs.iter_ >
rhs.iter_;
6213 friend bool operator>=(
const array_iterator& lhs,
const array_iterator&
rhs)
noexcept
6215 return lhs.iter_ >=
rhs.iter_;
6219 reference
operator[](ptrdiff_t idx)
const noexcept
6221 return *(iter_ + idx)->get();
6229 template <
typename T>
6255 array(
const impl::array_init_elem*,
const impl::array_init_elem*);
6258 array(std::false_type, std::initializer_list<impl::array_init_elem> elems)
6271 template <
typename T>
6313 typename... ElemTypes)
6316 :
array{ std::false_type{},
6317 std::initializer_list<impl::array_init_elem>{
static_cast<ElemType&&
>(val),
6318 static_cast<ElemTypes&&
>(
vals)... } }
6322 array& operator=(
const array&);
6328 node_type
type() const noexcept final
6330 return node_type::array;
6343 bool is_homogeneous(node_type ntype,
const node*& first_nonmatch)
const noexcept final;
6345 template <
typename ElemType =
void>
6349 using type = impl::remove_cvref<impl::unwrap_node<ElemType>>;
6350 static_assert(std::is_void_v<type> || toml::is_value<type> || toml::is_container<type>,
6351 "The template type argument of array::is_homogeneous() must be void or one "
6495 const toml::value<std::string>*
as_string() const noexcept final
6519 const toml::value<date>*
as_date() const noexcept final
6525 const toml::value<time>*
as_time() const noexcept final
6537 node*
get(
size_t index)
noexcept
6539 return index <
elems_.size() ?
elems_[index].get() :
nullptr;
6543 const node*
get(
size_t index)
const noexcept
6545 return const_cast<array&
>(*this).get(index);
6548 template <
typename ElemType>
6550 impl::wrap_node<ElemType>*
get_as(
size_t index)
noexcept
6552 if (
auto val =
get(index))
6553 return val->template as<ElemType>();
6557 template <
typename ElemType>
6559 const impl::wrap_node<ElemType>*
get_as(
size_t index)
const noexcept
6564 using node::operator[];
6582 const node&
at(
size_t index)
const
6584 return const_cast<array&
>(*this).at(index);
6653 template <
typename T,
typename Array>
6654 using for_each_elem_ref = impl::copy_cvref<impl::wrap_node<impl::remove_cvref<impl::unwrap_node<T>>>, Array>;
6656 template <
typename Func,
typename Array,
typename T>
6657 using can_for_each = std::disjunction<std::is_invocable<Func, for_each_elem_ref<T, Array>,
size_t>,
6658 std::is_invocable<Func, size_t, for_each_elem_ref<T, Array>>,
6659 std::is_invocable<Func, for_each_elem_ref<T, Array>>>;
6661 template <
typename Func,
typename Array,
typename T>
6664 std::is_invocable_v<Func, for_each_elem_ref<T, Array>,
size_t>,
6665 std::is_nothrow_invocable<Func, for_each_elem_ref<T, Array>,
size_t>,
6668 std::is_invocable_v<Func, size_t, for_each_elem_ref<T, Array>>,
6669 std::is_nothrow_invocable<Func, size_t, for_each_elem_ref<T, Array>>,
6672 std::is_invocable_v<Func, for_each_elem_ref<T, Array>>,
6673 std::is_nothrow_invocable<Func, for_each_elem_ref<T, Array>>,
6676 template <
typename Func,
typename Array>
6687 template <
typename Func,
typename Array,
typename T>
6691 template <
typename Func,
typename Array>
6702 template <
typename Func,
typename Array>
6707 "TOML array for_each visitors must be invocable for at least one of the toml::node "
6710 for (
size_t i = 0; i < arr.size(); i++)
6712 using node_ref = impl::copy_cvref<toml::node, Array&&>;
6713 static_assert(std::is_reference_v<node_ref>);
6715#if TOML_RETURN_BOOL_FROM_FOR_EACH_BROKEN
6717#ifndef TOML_RETURN_BOOL_FROM_FOR_EACH_BROKEN_ACKNOWLEDGED
6718 static_assert(impl::always_false<Func, Array, node_ref>,
6719 TOML_RETURN_BOOL_FROM_FOR_EACH_BROKEN_MESSAGE);
6722 static_cast<node_ref
>(
static_cast<Array&&
>(arr)[i])
6724 [&]([[maybe_unused]]
auto&& elem)
6728 static_assert(std::is_reference_v<elem_ref>);
6731 if constexpr (std::is_invocable_v<Func&&, elem_ref, size_t>)
6733 static_cast<Func&&
>(visitor)(
static_cast<elem_ref
>(elem), i);
6737 else if constexpr (std::is_invocable_v<Func&&, size_t, elem_ref>)
6739 static_cast<Func&&
>(visitor)(i,
static_cast<elem_ref
>(elem));
6743 else if constexpr (std::is_invocable_v<Func&&, elem_ref>)
6745 static_cast<Func&&
>(visitor)(
static_cast<elem_ref
>(elem));
6750 const auto keep_going =
6751 static_cast<node_ref
>(
static_cast<Array&&
>(arr)[i])
6753 [&]([[maybe_unused]]
auto&& elem)
6757 static_assert(std::is_reference_v<elem_ref>);
6760 if constexpr (std::is_invocable_v<Func&&, elem_ref, size_t>)
6763 decltype(
static_cast<Func&&
>(visitor)(
static_cast<elem_ref
>(elem), i));
6765 if constexpr (impl::is_constructible_or_convertible<bool, return_type>)
6767 return static_cast<bool>(
6768 static_cast<Func&&
>(visitor)(
static_cast<elem_ref
>(elem), i));
6772 static_cast<Func&&
>(visitor)(
static_cast<elem_ref
>(elem), i);
6778 else if constexpr (std::is_invocable_v<Func&&, size_t, elem_ref>)
6781 decltype(
static_cast<Func&&
>(visitor)(i,
static_cast<elem_ref
>(elem)));
6783 if constexpr (impl::is_constructible_or_convertible<bool, return_type>)
6785 return static_cast<bool>(
6786 static_cast<Func&&
>(visitor)(i,
static_cast<elem_ref
>(elem)));
6790 static_cast<Func&&
>(visitor)(i,
static_cast<elem_ref
>(elem));
6796 else if constexpr (std::is_invocable_v<Func&&, elem_ref>)
6799 decltype(
static_cast<Func&&
>(visitor)(
static_cast<elem_ref
>(elem)));
6801 if constexpr (impl::is_constructible_or_convertible<bool, return_type>)
6803 return static_cast<bool>(
6804 static_cast<Func&&
>(visitor)(
static_cast<elem_ref
>(elem)));
6808 static_cast<Func&&
>(visitor)(
static_cast<elem_ref
>(elem));
6826 template <
typename Func>
6834 template <
typename Func>
6839 return static_cast<array&&
>(*this);
6842 template <
typename Func>
6850 template <
typename Func>
6854 do_for_each(
static_cast<Func&&
>(visitor),
static_cast<const array&&
>(*
this));
6855 return static_cast<const array&&
>(*this);
6873 return elems_.max_size();
6879 return elems_.capacity();
6891 template <
typename ElemType>
6893 ElemType&& default_init_val,
6897 "The default element type argument to toml::array::resize may not be toml::node_view.");
6901 else if (new_size >
elems_.size())
6902 insert(
cend(), new_size -
elems_.size(),
static_cast<ElemType&&
>(default_init_val), default_init_flags);
6918 return static_cast<toml::array&&
>(this->
flatten());
6926 return static_cast<toml::array&&
>(this->
prune(recursive));
6935 template <typename ElemType>
6944 impl::make_node(
static_cast<ElemType&&
>(val), flags)) };
6947 template <
typename ElemType>
6961 case 1:
return insert(pos,
static_cast<ElemType&&
>(val), flags);
6966 size_t i = start_idx;
6967 for (
size_t e = start_idx +
count - 1u; i < e; i++)
6968 elems_[i] = impl::make_node(val, flags);
6970 elems_[i] = impl::make_node(
static_cast<ElemType&&
>(val), flags);
6971 return iterator{
elems_.begin() +
static_cast<ptrdiff_t
>(start_idx) };
6976 template <
typename Iter>
6979 const auto distance = std::distance(first, last);
6984 auto count = distance;
6985 using deref_type =
decltype(*first);
6988 for (
auto it = first; it != last; it++)
6996 size_t i = start_idx;
6997 for (
auto it = first; it != last; it++)
7004 if constexpr (std::is_rvalue_reference_v<deref_type>)
7005 elems_[i++] = impl::make_node(std::move(*it), flags);
7007 elems_[i++] = impl::make_node(*it, flags);
7009 return iterator{
elems_.begin() +
static_cast<ptrdiff_t
>(start_idx) };
7013 template <
typename ElemType>
7015 std::initializer_list<ElemType> ilist,
7018 return insert(pos, ilist.begin(), ilist.end(), flags);
7021 template <
typename ElemType = void,
typename... Args>
7024 using raw_elem_type = impl::remove_cvref<ElemType>;
7025 using elem_type = std::conditional_t<std::is_void_v<raw_elem_type>,
7026 impl::emplaced_type_of<Args&&...>,
7029 using type = impl::remove_cvref<impl::unwrap_node<elem_type>>;
7030 static_assert(impl::is_native<type> || impl::is_one_of<type, table, array>,
7034 impl::node_ptr{
new impl::wrap_node<type>{
static_cast<Args&&
>(args)... } }) };
7037 template <
typename ElemType>
7049 *it = impl::make_node(
static_cast<ElemType&&
>(val), flags);
7053 template <
typename ElemType>
7059 template <
typename ElemType = void,
typename... Args>
7062 using raw_elem_type = impl::remove_cvref<ElemType>;
7063 using elem_type = std::conditional_t<std::is_void_v<raw_elem_type>,
7064 impl::emplaced_type_of<Args&&...>,
7067 static constexpr auto moving_node_ptr = std::is_same_v<elem_type, impl::node_ptr>
7068 &&
sizeof...(Args) == 1u
7069 && impl::first_is_same<impl::node_ptr&&, Args&&...>;
7071 using unwrapped_type = impl::remove_cvref<impl::unwrap_node<elem_type>>;
7075 || impl::is_native<unwrapped_type>
7076 || impl::is_one_of<unwrapped_type, table, array>,
7079 if constexpr (moving_node_ptr)
7086 auto ptr =
new impl::wrap_node<unwrapped_type>{
static_cast<Args&&
>(args)... };
7098 template <
typename T>
7102 using element_type = std::remove_const_t<typename T::value_type>;
7103 static_assert(impl::is_losslessly_convertible_to_native<element_type>,
7104 "Container element type must be losslessly convertible one of the native TOML value types");
7106 if (lhs.size() !=
rhs.size())
7108 if (
rhs.size() == 0u)
7112 for (
auto& list_elem :
rhs)
7114 const auto elem = lhs.get_as<impl::native_type_of<element_type>>(i++);
7115 if (!elem || *elem != list_elem)
7136 template <
typename T>
7144 template <
typename T>
7152#if TOML_ENABLE_FORMATTERS
7156 impl::print_to_stream(lhs,
rhs);
7166#pragma pop_macro("min")
7167#pragma pop_macro("max")
7169#pragma inline_recursion(off)
7179#pragma inline_recursion(on)
7181#pragma push_macro("min")
7182#pragma push_macro("max")
7193 source_region source_;
7198 key() noexcept = default;
7201 explicit key(std::string_view k, source_region&& src = {})
7203 source_{ std::move(src) }
7207 explicit key(std::string_view k,
const source_region& src)
7213 explicit key(std::string&& k, source_region&& src = {})
noexcept
7214 : key_{ std::move(k) },
7215 source_{ std::move(src) }
7219 explicit key(std::string&& k,
const source_region& src)
noexcept
7220 : key_{ std::move(k) },
7225 explicit key(
const char* k, source_region&& src = {})
7227 source_{ std::move(src) }
7231 explicit key(
const char* k,
const source_region& src)
7236#if TOML_ENABLE_WINDOWS_COMPAT
7239 explicit key(std::wstring_view k, source_region&& src = {})
7240 : key_{ impl::narrow(k) },
7241 source_{ std::move(src) }
7245 explicit key(std::wstring_view k,
const source_region& src)
7246 : key_{ impl::narrow(k) },
7253 std::string_view str() const noexcept
7255 return std::string_view{ key_ };
7259 operator std::string_view() const noexcept
7265 bool empty() const noexcept
7267 return key_.empty();
7271 const char*
data() const noexcept
7277 size_t length() const noexcept
7279 return key_.length();
7283 const source_region& source() const noexcept
7289 friend bool operator==(
const key& lhs,
const key&
rhs)
noexcept
7291 return lhs.key_ ==
rhs.key_;
7295 friend bool operator!=(
const key& lhs,
const key&
rhs)
noexcept
7297 return lhs.key_ !=
rhs.key_;
7301 friend bool operator<(
const key& lhs,
const key&
rhs)
noexcept
7303 return lhs.key_ <
rhs.key_;
7307 friend bool operator<=(
const key& lhs,
const key&
rhs)
noexcept
7309 return lhs.key_ <=
rhs.key_;
7313 friend bool operator>(
const key& lhs,
const key&
rhs)
noexcept
7315 return lhs.key_ >
rhs.key_;
7319 friend bool operator>=(
const key& lhs,
const key&
rhs)
noexcept
7321 return lhs.key_ >=
rhs.key_;
7325 friend bool operator==(
const key& lhs, std::string_view
rhs)
noexcept
7327 return lhs.key_ ==
rhs;
7331 friend bool operator!=(
const key& lhs, std::string_view
rhs)
noexcept
7333 return lhs.key_ !=
rhs;
7337 friend bool operator<(
const key& lhs, std::string_view
rhs)
noexcept
7339 return lhs.key_ <
rhs;
7343 friend bool operator<=(
const key& lhs, std::string_view
rhs)
noexcept
7345 return lhs.key_ <=
rhs;
7349 friend bool operator>(
const key& lhs, std::string_view
rhs)
noexcept
7351 return lhs.key_ >
rhs;
7355 friend bool operator>=(
const key& lhs, std::string_view
rhs)
noexcept
7357 return lhs.key_ >=
rhs;
7361 friend bool operator==(std::string_view lhs,
const key&
rhs)
noexcept
7363 return lhs ==
rhs.key_;
7367 friend bool operator!=(std::string_view lhs,
const key&
rhs)
noexcept
7369 return lhs !=
rhs.key_;
7373 friend bool operator<(std::string_view lhs,
const key&
rhs)
noexcept
7375 return lhs <
rhs.key_;
7379 friend bool operator<=(std::string_view lhs,
const key&
rhs)
noexcept
7381 return lhs <=
rhs.key_;
7385 friend bool operator>(std::string_view lhs,
const key&
rhs)
noexcept
7387 return lhs >
rhs.key_;
7391 friend bool operator>=(std::string_view lhs,
const key&
rhs)
noexcept
7393 return lhs >=
rhs.key_;
7409 return key_.data() + key_.length();
7412 friend std::ostream&
operator<<(std::ostream& lhs,
const key&
rhs)
7414 impl::print_to_stream(lhs,
rhs.key_);
7419 template <
typename T>
7420 inline constexpr bool is_key = std::is_same_v<impl::remove_cvref<T>, toml::key>;
7422 template <
typename T>
7424 || impl::is_constructible_or_convertible<toml::key, T>;
7429#pragma pop_macro("min")
7430#pragma pop_macro("max")
7432#pragma inline_recursion(off)
7449#pragma inline_recursion(on)
7451#pragma push_macro("min")
7452#pragma push_macro("max")
7459 template <
bool IsConst>
7460 struct table_proxy_pair
7462 using value_type = std::conditional_t<IsConst, const node, node>;
7464 const toml::key& first;
7468 template <
bool IsConst>
7478 using map_iterator = std::conditional_t<IsConst, const_map_iterator, mutable_map_iterator>;
7515 :
iter_{ other.iter_ }
7520 :
iter_{ other.iter_ }
7594 return lhs.iter_ ==
rhs.iter_;
7600 return lhs.iter_ !=
rhs.iter_;
7609 template <
typename K,
typename V>
7612 :
key{ static_cast<K&&>(k) },
7629 using map_type = std::map<toml::key, impl::node_ptr, std::less<>>;
7630 using map_pair = std::pair<const toml::key, impl::node_ptr>;
7639 table(
const impl::table_init_pair*,
const impl::table_init_pair*);
7671 node_type
type() const noexcept final
7673 return node_type::table;
7686 bool is_homogeneous(node_type ntype,
const node*& first_nonmatch)
const noexcept final;
7688 template <
typename ElemType =
void>
7692 using type = impl::remove_cvref<impl::unwrap_node<ElemType>>;
7693 static_assert(std::is_void_v<type> || toml::is_value<type> || toml::is_container<type>,
7694 "The template type argument of table::is_homogeneous() must be void or one "
7838 const toml::value<std::string>*
as_string() const noexcept final
7862 const toml::value<date>*
as_date() const noexcept final
7868 const toml::value<time>*
as_time() const noexcept final
7895 const node*
get(std::string_view
key)
const noexcept
7897 return const_cast<table&
>(*this).get(
key);
7900#if TOML_ENABLE_WINDOWS_COMPAT
7903 node* get(std::wstring_view key)
7908 return get(impl::narrow(key));
7912 const node*
get(std::wstring_view key)
const
7914 return const_cast<table&
>(*this).get(key);
7919 template <
typename T>
7923 const auto n = this->
get(
key);
7924 return n ?
n->template as<T>() :
nullptr;
7927 template <
typename T>
7929 const impl::wrap_node<T>*
get_as(std::string_view
key)
const noexcept
7934#if TOML_ENABLE_WINDOWS_COMPAT
7936 template <
typename T>
7938 impl::wrap_node<T>* get_as(std::wstring_view key)
7943 return get_as<T>(impl::narrow(key));
7946 template <
typename T>
7948 const impl::wrap_node<T>* get_as(std::wstring_view key)
const
7950 return const_cast<table&
>(*this).template get_as<T>(key);
7960 const node&
at(std::string_view
key)
const
7962 return const_cast<table&
>(*this).at(
key);
7965#if TOML_ENABLE_WINDOWS_COMPAT
7968 node&
at(std::wstring_view key)
7970 return at(impl::narrow(key));
7974 const node&
at(std::wstring_view key)
const
7976 return const_cast<table&
>(*this).at(key);
8023 template <
typename T,
typename Table>
8024 using for_each_value_ref = impl::copy_cvref<impl::wrap_node<impl::remove_cvref<impl::unwrap_node<T>>>, Table>;
8026 template <
typename Func,
typename Table,
typename T>
8027 using can_for_each = std::disjunction<std::is_invocable<Func, const key&, for_each_value_ref<T, Table>>,
8028 std::is_invocable<Func, for_each_value_ref<T, Table>>>;
8030 template <
typename Func,
typename Table,
typename T>
8033 std::is_invocable_v<Func, const key&, for_each_value_ref<T, Table>>,
8034 std::is_nothrow_invocable<Func, const key&, for_each_value_ref<T, Table>>,
8037 std::is_invocable_v<Func, for_each_value_ref<T, Table>>,
8038 std::is_nothrow_invocable<Func, for_each_value_ref<T, Table>>,
8041 template <
typename Func,
typename Table>
8052 template <
typename Func,
typename Table,
typename T>
8056 template <
typename Func,
typename Table>
8067 template <
typename Func,
typename Table>
8072 "TOML table for_each visitors must be invocable for at least one of the toml::node "
8075 using kvp_type = impl::copy_cv<map_pair, std::remove_reference_t<Table>>;
8077 for (kvp_type& kvp : tbl.map_)
8079 using node_ref = impl::copy_cvref<toml::node, Table&&>;
8080 static_assert(std::is_reference_v<node_ref>);
8082#if TOML_RETURN_BOOL_FROM_FOR_EACH_BROKEN
8084#ifndef TOML_RETURN_BOOL_FROM_FOR_EACH_BROKEN_ACKNOWLEDGED
8085 static_assert(impl::always_false<Func, Table, kvp_type, node_ref>,
8086 TOML_RETURN_BOOL_FROM_FOR_EACH_BROKEN_MESSAGE);
8089 static_cast<node_ref
>(*kvp.second)
8091 [&]([[maybe_unused]]
auto&& v)
8095 static_assert(std::is_reference_v<value_ref>);
8098 if constexpr (std::is_invocable_v<Func&&, const key&, value_ref>)
8100 static_cast<Func&&
>(visitor)(
static_cast<const key&
>(kvp.first),
8101 static_cast<value_ref
>(v));
8105 else if constexpr (std::is_invocable_v<Func&&, value_ref>)
8107 static_cast<Func&&
>(visitor)(
static_cast<value_ref
>(v));
8112 const auto keep_going =
8113 static_cast<node_ref
>(*kvp.second)
8115 [&]([[maybe_unused]]
auto&& v)
8119 static_assert(std::is_reference_v<value_ref>);
8122 if constexpr (std::is_invocable_v<Func&&, const key&, value_ref>)
8124 using return_type =
decltype(
static_cast<Func&&
>(
8125 visitor)(
static_cast<const key&
>(kvp.first),
static_cast<value_ref
>(v)));
8127 if constexpr (impl::is_constructible_or_convertible<bool, return_type>)
8129 return static_cast<bool>(
static_cast<Func&&
>(
8130 visitor)(
static_cast<const key&
>(kvp.first),
static_cast<value_ref
>(v)));
8134 static_cast<Func&&
>(visitor)(
static_cast<const key&
>(kvp.first),
8135 static_cast<value_ref
>(v));
8141 else if constexpr (std::is_invocable_v<Func&&, value_ref>)
8144 decltype(
static_cast<Func&&
>(visitor)(
static_cast<value_ref
>(v)));
8146 if constexpr (impl::is_constructible_or_convertible<bool, return_type>)
8148 return static_cast<bool>(
8149 static_cast<Func&&
>(visitor)(
static_cast<value_ref
>(v)));
8153 static_cast<Func&&
>(visitor)(
static_cast<value_ref
>(v));
8171 template <
typename Func>
8179 template <
typename Func>
8184 return static_cast<table&&
>(*this);
8187 template <
typename Func>
8195 template <
typename Func>
8199 do_for_each(
static_cast<Func&&
>(visitor),
static_cast<const table&&
>(*
this));
8200 return static_cast<const table&&
>(*this);
8206 return map_.empty();
8235#if TOML_ENABLE_WINDOWS_COMPAT
8238 iterator lower_bound(std::wstring_view key)
8243 return lower_bound(impl::narrow(key));
8252 return lower_bound(impl::narrow(key));
8268 return get(
key) !=
nullptr;
8271#if TOML_ENABLE_WINDOWS_COMPAT
8279 return find(impl::narrow(key));
8285 return find(impl::narrow(key));
8289 bool contains(std::wstring_view key)
const
8291 return contains(impl::narrow(key));
8324#if TOML_ENABLE_WINDOWS_COMPAT
8326 size_t erase(std::wstring_view
key)
8341 return static_cast<toml::table&&
>(this->
prune(recursive));
8355 typename ValueType =
void,
8357 typename... ValueArgs)
8361 "Emplacement using wide-character keys is only supported on Windows with "
8362 "TOML_ENABLE_WINDOWS_COMPAT enabled.");
8366 conditional_t<std::is_void_v<raw_value_type>, impl::emplaced_type_of<ValueArgs&&...>,
raw_value_type>;
8368 if constexpr (impl::is_wide_string<KeyType>)
8370#if TOML_ENABLE_WINDOWS_COMPAT
8371 return emplace_hint<value_type>(hint,
8372 impl::narrow(
static_cast<KeyType&&
>(
key)),
8373 static_cast<ValueArgs&&
>(
args)...);
8375 static_assert(impl::always_false<KeyType>,
"Evaluated unreachable branch!");
8380 static constexpr auto moving_node_ptr = std::is_same_v<value_type, impl::node_ptr>
8381 &&
sizeof...(ValueArgs) == 1u
8382 && impl::first_is_same<impl::node_ptr&&, ValueArgs&&...>;
8385 static_assert(moving_node_ptr
8386 || impl::is_native<unwrapped_type>
8387 || impl::is_one_of<unwrapped_type, table, array>,
8388 "ValueType argument of table::emplace_hint() must be one "
8397 if constexpr (moving_node_ptr)
8398 ipos->second = std::move(
static_cast<ValueArgs&&
>(
args)...);
8401#if TOML_COMPILER_HAS_EXCEPTIONS
8406 new impl::wrap_node<unwrapped_type>{
static_cast<ValueArgs&&
>(
args)... });
8407#if TOML_COMPILER_HAS_EXCEPTIONS
8424 std::pair<iterator, bool>
insert(KeyType&&
key,
8429 "Insertion using wide-character keys is only supported on Windows with "
8430 "TOML_ENABLE_WINDOWS_COMPAT enabled.");
8435 return {
end(),
false };
8438 if constexpr (impl::is_wide_string<KeyType>)
8440#if TOML_ENABLE_WINDOWS_COMPAT
8441 return insert(impl::narrow(
static_cast<KeyType&&
>(
key)),
static_cast<ValueType&&
>(val), flags);
8443 static_assert(impl::always_false<KeyType>,
"Evaluated unreachable branch!");
8448 const auto key_view = std::string_view{
key };
8453 toml::key{
static_cast<KeyType&&
>(
key) },
8454 impl::make_node(
static_cast<ValueType&&
>(val), flags));
8466 for (
auto it =
begin; it !=
end; it++)
8468 if constexpr (std::is_rvalue_reference_v<
decltype(*it)>)
8469 insert(std::move((*it).first), std::move((*it).second), flags);
8471 insert((*it).first, (*it).second, flags);
8478 std::pair<iterator, bool> insert_or_assign(KeyType&&
key,
8483 "Insertion using wide-character keys is only supported on Windows with "
8484 "TOML_ENABLE_WINDOWS_COMPAT enabled.");
8489 return {
end(),
false };
8492 if constexpr (impl::is_wide_string<KeyType>)
8494#if TOML_ENABLE_WINDOWS_COMPAT
8495 return insert_or_assign(impl::narrow(
static_cast<KeyType&&
>(
key)),
8496 static_cast<ValueType&&
>(val),
8499 static_assert(impl::always_false<KeyType>,
"Evaluated unreachable branch!");
8504 const auto key_view = std::string_view{
key };
8509 toml::key{
static_cast<KeyType&&
>(
key) },
8510 impl::make_node(
static_cast<ValueType&&
>(val), flags));
8515 (*ipos).second = impl::make_node(
static_cast<ValueType&&
>(val), flags);
8522 typename ValueType =
void,
8524 typename... ValueArgs)
8525 std::pair<iterator, bool>
emplace(KeyType&&
key, ValueArgs&&...
args)
8528 "Emplacement using wide-character keys is only supported on Windows with "
8529 "TOML_ENABLE_WINDOWS_COMPAT enabled.");
8533 conditional_t<std::is_void_v<raw_value_type>, impl::emplaced_type_of<ValueArgs&&...>,
raw_value_type>;
8535 if constexpr (impl::is_wide_string<KeyType>)
8537#if TOML_ENABLE_WINDOWS_COMPAT
8539 static_cast<ValueArgs&&
>(
args)...);
8541 static_assert(impl::always_false<KeyType>,
"Evaluated unreachable branch!");
8546 using unwrapped_type = impl::remove_cvref<impl::unwrap_node<value_type>>;
8547 static_assert((impl::is_native<unwrapped_type> || impl::is_one_of<unwrapped_type, table, array>),
8548 "ValueType argument of table::emplace() must be one "
8551 const auto key_view = std::string_view{
key };
8557 toml::key{
static_cast<KeyType&&
>(
key) },
8558 impl::node_ptr{
new impl::wrap_node<unwrapped_type>{
static_cast<ValueArgs&&
>(
args)... } });
8565 using node::operator[];
8579#if TOML_ENABLE_WINDOWS_COMPAT
8615#if TOML_ENABLE_FORMATTERS
8619 impl::print_to_stream(lhs,
rhs);
8629#pragma pop_macro("min")
8630#pragma pop_macro("max")
8632#pragma inline_recursion(off)
8642#pragma inline_recursion(on)
8644#pragma push_macro("min")
8645#pragma push_macro("max")
8650#if TOML_GCC && TOML_GCC < 9
8651#pragma GCC push_options
8652#pragma GCC optimize("O1")
8660 constexpr bool is_ascii_horizontal_whitespace(
char32_t c)
noexcept
8662 return c == U
'\t' || c == U
' ';
8666 constexpr bool is_non_ascii_horizontal_whitespace(
char32_t c)
noexcept
8670 if (c < U
'\xA0' || c > U
'\uFEFF')
8673 const auto child_index_0 = (
static_cast<uint_least64_t
>(c) - 0xA0ull) / 0x3FAull;
8674 if ((1ull << child_index_0) & 0x7FFFFFFFFFFFF75Eull)
8676 if (c == U
'\xA0' || c == U
'\u3000' || c == U
'\uFEFF')
8678 switch (child_index_0)
8680 case 0x05:
return c == U
'\u1680' || c == U
'\u180E';
8682 return (U
'\u2000' <= c && c <= U
'\u200B') || (U
'\u205F' <= c && c <= U
'\u2060') || c == U
'\u202F';
8690 constexpr bool is_ascii_vertical_whitespace(
char32_t c)
noexcept
8692 return c >= U
'\n' && c <= U
'\r';
8696 constexpr bool is_non_ascii_vertical_whitespace(
char32_t c)
noexcept
8698 return (U
'\u2028' <= c && c <= U
'\u2029') || c == U
'\x85';
8702 constexpr bool is_ascii_bare_key_character(
char32_t c)
noexcept
8704#if TOML_LANG_UNRELEASED
8710 if (c < U
'-' || c > U
'z')
8713 return (((
static_cast<uint_least64_t
>(c) - 0x2Dull) / 0x40ull) != 0ull)
8714 || ((1ull << (
static_cast<uint_least64_t
>(c) - 0x2Dull)) & 0xFFF43FFFFFF01FF9ull);
8717#if TOML_LANG_UNRELEASED
8720 constexpr bool is_non_ascii_bare_key_character(
char32_t c)
noexcept
8724 if (c < U
'\xB2' || c > U
'\U000EFFFF')
8727 const auto child_index_0 = (
static_cast<uint_least64_t
>(c) - 0xB2ull) / 0x3BFEull;
8728 if ((1ull << child_index_0) & 0xFFFFFFFFFFFFFFE6ull)
8730 switch (child_index_0)
8738 constexpr uint_least64_t bitmask_table_1[] = {
8739 0xFFFFFFDFFFFFDC83u, 0xFFFFFFFFFFFFFFDFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
8740 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
8741 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFEFFFu,
8742 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
8743 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
8744 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
8745 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
8746 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
8747 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
8748 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
8749 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
8750 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
8751 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
8752 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
8753 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
8754 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
8755 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
8756 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
8757 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
8758 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
8759 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
8760 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
8761 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
8762 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
8763 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
8764 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
8765 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
8766 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
8767 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
8768 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
8769 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
8770 0xFFFFFFFFFFFFFFFFu, 0x000000000C003FFFu, 0xC000000000006000u, 0xFFFFFFFFFFFFFFFFu,
8771 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0x000000003FFFFFFFu,
8772 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
8773 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
8774 0x0000000000000000u, 0x0000000000000000u, 0xFFFFC00000000000u, 0xFFFFFFFFFFFFFFFFu,
8775 0xFFFFFFFFFFFFFFFFu, 0x0000000000003FFFu, 0x0000000000000000u, 0x0000000000000000u,
8776 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
8777 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
8778 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
8779 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
8780 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
8781 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
8782 0x0000000000000000u, 0xFFFFFFFFFFFFC000u, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
8783 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
8784 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
8785 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
8786 0x3FFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFF8000u, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
8787 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
8788 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
8789 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
8790 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
8791 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
8792 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
8793 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
8794 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
8795 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
8796 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
8797 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
8798 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0x3FFFFFFFFFFFFFFFu,
8800 return bitmask_table_1[(
static_cast<uint_least64_t
>(c) - 0xB2ull) / 0x40ull]
8801 & (0x1ull << ((
static_cast<uint_least64_t
>(c) - 0xB2ull) % 0x40ull));
8803 case 0x03:
return c <= U
'\uD7FF';
8805 return (U
'\uF900' <= c && c <= U
'\uFDCF') || (U
'\uFDF0' <= c && c <= U
'\uFFFD') || U
'\U00010000' <= c;
8816#if TOML_GCC && TOML_GCC < 9
8817#pragma GCC pop_options
8821#pragma pop_macro("min")
8822#pragma pop_macro("max")
8824#pragma inline_recursion(off)
8834#pragma inline_recursion(on)
8836#pragma push_macro("min")
8837#pragma push_macro("max")
8845 constexpr bool is_string_delimiter(
char32_t c)
noexcept
8847 return c == U
'"' || c == U
'\'';
8851 constexpr bool is_ascii_letter(
char32_t c)
noexcept
8853 return (c >= U
'a' && c <= U
'z') || (c >= U
'A' && c <= U
'Z');
8857 constexpr bool is_binary_digit(
char32_t c)
noexcept
8859 return c == U
'0' || c == U
'1';
8863 constexpr bool is_octal_digit(
char32_t c)
noexcept
8865 return (c >= U
'0' && c <= U
'7');
8869 constexpr bool is_decimal_digit(
char32_t c)
noexcept
8871 return (c >= U
'0' && c <= U
'9');
8875 constexpr bool is_hexadecimal_digit(
char32_t c)
noexcept
8877 return U
'0' <= c && c <= U'f' && (1ull << (static_cast<uint_least64_t>(c) - 0x30u)) & 0x7E0000007E03FFull;
8880 template <
typename T>
8882 constexpr uint_least32_t hex_to_dec(
const T c)
noexcept
8884 if constexpr (std::is_same_v<remove_cvref<T>, uint_least32_t>)
8886 ? 10u + (c | 0x20u) - 0x61u
8890 return hex_to_dec(
static_cast<uint_least32_t
>(c));
8894 constexpr bool is_horizontal_whitespace(
char32_t c)
noexcept
8896 return is_ascii_horizontal_whitespace(c) || is_non_ascii_horizontal_whitespace(c);
8900 constexpr bool is_vertical_whitespace(
char32_t c)
noexcept
8902 return is_ascii_vertical_whitespace(c) || is_non_ascii_vertical_whitespace(c);
8906 constexpr bool is_whitespace(
char32_t c)
noexcept
8908 return is_horizontal_whitespace(c) || is_vertical_whitespace(c);
8912 constexpr bool is_bare_key_character(
char32_t c)
noexcept
8914 return is_ascii_bare_key_character(c)
8915#if TOML_LANG_UNRELEASED
8916 || is_non_ascii_bare_key_character(c)
8922 constexpr bool is_value_terminator(
char32_t c)
noexcept
8924 return is_whitespace(c) || c == U
']' || c == U
'}' || c == U
',' || c == U
'#';
8928 constexpr bool is_control_character(
char c)
noexcept
8930 return c <=
'\u001F' || c ==
'\u007F';
8934 constexpr bool is_control_character(
char32_t c)
noexcept
8936 return c <= U
'\u001F' || c == U
'\u007F';
8940 constexpr bool is_nontab_control_character(
char32_t c)
noexcept
8942 return c <= U
'\u0008' || (c >= U
'\u000A' && c <= U
'\u001F') || c == U
'\u007F';
8946 constexpr bool is_unicode_surrogate(
char32_t c)
noexcept
8948 return c >= 0xD800u && c <= 0xDFFF;
8956 uint_least32_t
state{};
8957 char32_t codepoint{};
8959 static constexpr uint8_t state_table[]{
8960 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8961 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8962 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8963 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8964 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1,
8965 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 7, 7,
8966 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
8967 7, 7, 7, 8, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
8968 2, 2, 2, 2, 2, 2, 2, 2, 10, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 3, 3, 11, 6, 6,
8969 6, 5, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8970 0, 12, 24, 36, 60, 96, 84, 12, 12, 12, 48, 72, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 0, 12,
8971 12, 12, 12, 12, 0, 12, 0, 12, 12, 12, 24, 12, 12, 12, 12, 12, 24, 12, 24, 12, 12, 12, 12, 12, 12, 12, 12,
8972 12, 24, 12, 12, 12, 12, 12, 24, 12, 12, 12, 12, 12, 12, 12, 24, 12, 12, 12, 12, 12, 12, 12, 12, 12, 36, 12,
8973 36, 12, 12, 12, 36, 12, 12, 12, 12, 12, 36, 12, 36, 12, 12, 12, 36, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12
8977 constexpr bool error() const noexcept
8979 return state == uint_least32_t{ 12u };
8983 constexpr bool has_code_point() const noexcept
8985 return state == uint_least32_t{};
8989 constexpr bool needs_more_input() const noexcept
8991 return !has_code_point() && !
error();
8994 constexpr void operator()(uint8_t
byte)
noexcept
8998 const auto type = state_table[
byte];
9000 codepoint =
static_cast<char32_t>(has_code_point() ? (uint_least32_t{ 255u } >> type) &
byte
9001 : (
byte & uint_least32_t{ 63u })
9002 | (static_cast<uint_least32_t>(codepoint) << 6));
9004 state = state_table[
state + uint_least32_t{ 256u } + type];
9008 constexpr void operator()(
char c)
noexcept
9010 operator()(
static_cast<uint8_t
>(c));
9014 constexpr void reset() noexcept
9027#pragma pop_macro("min")
9028#pragma pop_macro("max")
9030#pragma inline_recursion(off)
9037#if TOML_ENABLE_PARSER
9052#pragma inline_recursion(on)
9054#pragma push_macro("min")
9055#pragma push_macro("max")
9060#if TOML_DOXYGEN || !TOML_EXCEPTIONS
9061#define TOML_PARSE_ERROR_BASE
9063#define TOML_PARSE_ERROR_BASE : public std::runtime_error
9084 : std::runtime_error{ desc },
9085 source_{ std::move(src) }
9090 parse_error(
const char* desc,
const source_region& src)
noexcept
9091 : parse_error{ desc, source_region{ src } }
9096 parse_error(
const char* desc,
const source_position& position,
const source_path_ptr& path = {})
noexcept
9097 : parse_error{ desc, source_region{ position, position,
path } }
9105 source_{ std::move(src) }
9124 return std::string_view{ what() };
9138 impl::print_to_stream(lhs,
rhs.description());
9139 impl::print_to_stream(lhs,
"\n\t(error occurred at "sv);
9140 impl::print_to_stream(lhs,
rhs.source());
9141 impl::print_to_stream(lhs,
")"sv);
9150#undef TOML_PARSE_ERROR_BASE
9153#pragma pop_macro("min")
9154#pragma pop_macro("max")
9156#pragma inline_recursion(off)
9165#if TOML_DOXYGEN || (TOML_ENABLE_PARSER && !TOML_EXCEPTIONS)
9170#pragma inline_recursion(on)
9172#pragma push_macro("min")
9173#pragma push_macro("max")
9188 (
sizeof(toml::table) <
sizeof(parse_error) ?
sizeof(parse_error) :
sizeof(toml::table));
9190 (
alignof(toml::table) <
alignof(parse_error) ?
alignof(parse_error) :
alignof(toml::table));
9198 template <
typename Type>
9220 ::new (
static_cast<void*
>(
storage_.
bytes)) parse_error{ std::string{}, source_region{} };
9234 ::new (
static_cast<void*
>(
storage_.
bytes)) parse_error{ std::move(err) };
9242 ::new (
static_cast<void*
>(
storage_.
bytes)) parse_error{ std::move(
res).error() };
9244 ::new (
static_cast<void*
>(
storage_.bytes)) toml::
table{ std::move(
res).table() };
9254 ::new (
static_cast<void*
>(
storage_.bytes)) parse_error{ std::move(
rhs).error() };
9256 ::new (
static_cast<void*
>(
storage_.bytes)) toml::table{ std::move(
rhs).table() };
9286 explicit operator bool() const noexcept
9306 const toml::table&
table() const& noexcept
9313 operator toml::table&()
noexcept
9319 operator toml::table&&()
noexcept
9321 return std::move(
table());
9325 operator const toml::table&()
const noexcept
9345 const parse_error&
error() const& noexcept
9352 explicit operator parse_error&()
noexcept
9358 explicit operator parse_error&&()
noexcept
9360 return std::move(
error());
9364 explicit operator const parse_error&()
const noexcept
9433#if TOML_ENABLE_WINDOWS_COMPAT
9473#if TOML_ENABLE_WINDOWS_COMPAT
9489#if TOML_ENABLE_FORMATTERS
9504#pragma pop_macro("min")
9505#pragma pop_macro("max")
9507#pragma inline_recursion(off)
9516#if TOML_ENABLE_PARSER
9521#pragma inline_recursion(on)
9523#pragma push_macro("min")
9524#pragma push_macro("max")
9561#if TOML_ENABLE_WINDOWS_COMPAT
9577#if TOML_HAS_CHAR8 && TOML_ENABLE_WINDOWS_COMPAT
9603 return parse(std::string_view{ str, len });
9610 parse_result
operator"" _toml(
const char8_t* str,
size_t len)
9612 return parse(std::u8string_view{ str, len });
9623#pragma pop_macro("min")
9624#pragma pop_macro("max")
9626#pragma inline_recursion(off)
9635#if TOML_ENABLE_FORMATTERS
9640#pragma inline_recursion(on)
9642#pragma push_macro("min")
9643#pragma push_macro("max")
9650 struct formatter_constants
9655 std::string_view float_pos_inf;
9656 std::string_view float_neg_inf;
9657 std::string_view float_nan;
9659 std::string_view bool_true;
9660 std::string_view bool_false;
9673#if TOML_ENABLE_PARSER && !TOML_EXCEPTIONS
9727 return !!(
config_.flags & format_flags::indent_array_elements);
9733 return !!(
config_.flags & format_flags::indent_sub_tables);
9739 return !!(
config_.flags & format_flags::allow_literal_strings);
9745 return !!(
config_.flags & format_flags::allow_multi_line_strings);
9751 return !!(
config_.flags & format_flags::allow_real_tabs_in_strings);
9757 return !!(
config_.flags & format_flags::allow_unicode_strings);
9763 return !!(
config_.flags & format_flags::terse_key_value_pairs);
9767 void attach(std::ostream& stream)
noexcept;
9770 void detach() noexcept;
9773 void print_newline(
bool force = false);
9776 void print_indent();
9779 void print_unformatted(
char);
9782 void print_unformatted(
std::string_view);
9785 void print_string(
std::string_view str,
9786 bool allow_multi_line = true,
9787 bool allow_bare = false,
9788 bool allow_literal_whitespace = true);
9791 void print(const
value<
std::
string>&);
9794 void print(const
value<int64_t>&);
9797 void print(const
value<
double>&);
9800 void print(const
value<
bool>&);
9803 void print(const
value<date>&);
9812 void print_value(const node&, node_type);
9816 bool dump_failed_parse_result();
9826#pragma pop_macro("min")
9827#pragma pop_macro("max")
9829#pragma inline_recursion(off)
9838#if TOML_ENABLE_FORMATTERS
9843#pragma inline_recursion(on)
9845#pragma push_macro("min")
9846#pragma push_macro("max")
9857 using base = impl::formatter;
9858 std::vector<const key*> key_path_;
9859 bool pending_table_separator_ =
false;
9862 void print_pending_table_separator();
9865 void print(
const key&);
9868 void print_inline(
const toml::table&);
9871 void print(
const toml::array&);
9874 void print(
const toml::table&);
9879 static constexpr impl::formatter_constants constants = { format_flags::none,
9889 static constexpr format_flags default_flags = constants.mandatory_flags
9890 | format_flags::allow_literal_strings
9891 | format_flags::allow_multi_line_strings
9892 | format_flags::allow_unicode_strings
9893 | format_flags::allow_real_tabs_in_strings
9894 | format_flags::allow_binary_integers
9895 | format_flags::allow_octal_integers
9896 | format_flags::allow_hexadecimal_integers
9897 | format_flags::indentation;
9901 : base{ &source,
nullptr, constants, {
flags,
" "sv } }
9904#if TOML_DOXYGEN || (TOML_ENABLE_PARSER && !TOML_EXCEPTIONS)
9908 : base{
nullptr, &
result, constants, {
flags,
" "sv } }
9913 friend std::ostream&
operator<<(std::ostream& lhs, toml_formatter&
rhs)
9916 rhs.key_path_.clear();
9922 friend std::ostream&
operator<<(std::ostream& lhs, toml_formatter&&
rhs)
9931#pragma pop_macro("min")
9932#pragma pop_macro("max")
9934#pragma inline_recursion(off)
9943#if TOML_ENABLE_FORMATTERS
9948#pragma inline_recursion(on)
9950#pragma push_macro("min")
9951#pragma push_macro("max")
9962 using base = impl::formatter;
9965 void print(
const toml::table&);
9968 void print(
const toml::array&);
9973 static constexpr impl::formatter_constants constants = {
9974 format_flags::quote_dates_and_times,
9975 format_flags::allow_literal_strings | format_flags::allow_multi_line_strings,
9985 static constexpr format_flags default_flags = constants.mandatory_flags
9986 | format_flags::quote_infinities_and_nans
9987 | format_flags::allow_unicode_strings
9988 | format_flags::indentation;
9992 : base{ &source,
nullptr, constants, {
flags,
" "sv } }
9995#if TOML_DOXYGEN || (TOML_ENABLE_PARSER && !TOML_EXCEPTIONS)
9999 : base{
nullptr, &
result, constants, {
flags,
" "sv } }
10004 friend std::ostream&
operator<<(std::ostream& lhs, json_formatter&
rhs)
10012 friend std::ostream&
operator<<(std::ostream& lhs, json_formatter&&
rhs)
10021#pragma pop_macro("min")
10022#pragma pop_macro("max")
10024#pragma inline_recursion(off)
10033#if TOML_ENABLE_FORMATTERS
10038#pragma inline_recursion(on)
10040#pragma push_macro("min")
10041#pragma push_macro("max")
10052 using base = impl::formatter;
10055 void print_yaml_string(
const value<std::string>&);
10058 void print(
const toml::table&,
bool =
false);
10061 void print(
const toml::array&,
bool =
false);
10066 static constexpr impl::formatter_constants constants = {
10068 format_flags::quote_dates_and_times | format_flags::indentation,
10069 format_flags::allow_multi_line_strings,
10079 static constexpr format_flags default_flags = constants.mandatory_flags
10080 | format_flags::allow_literal_strings
10081 | format_flags::allow_unicode_strings
10082 | format_flags::allow_octal_integers
10083 | format_flags::allow_hexadecimal_integers;
10086 explicit yaml_formatter(
const toml::node& source,
format_flags flags = default_flags)
noexcept
10087 : base{ &source,
nullptr, constants, {
flags,
" "sv } }
10090#if TOML_DOXYGEN || (TOML_ENABLE_PARSER && !TOML_EXCEPTIONS)
10094 : base{
nullptr, &
result, constants, {
flags,
" "sv } }
10116#pragma pop_macro("min")
10117#pragma pop_macro("max")
10119#pragma inline_recursion(off)
10126#if TOML_IMPLEMENTATION
10133#if TOML_INCLUDE_WINDOWS_H
10134#include <Windows.h>
10137extern "C" __declspec(dllimport)
int __stdcall WideCharToMultiByte(
unsigned int CodePage,
10138 unsigned long dwFlags,
10139 const wchar_t* lpWideCharStr,
10141 char* lpMultiByteStr,
10143 const char* lpDefaultChar,
10144 int* lpUsedDefaultChar);
10146extern "C" __declspec(dllimport)
int __stdcall MultiByteToWideChar(
unsigned int CodePage,
10147 unsigned long dwFlags,
10148 const char* lpMultiByteStr,
10150 wchar_t* lpWideCharStr,
10159#pragma inline_recursion(on)
10161#pragma push_macro("min")
10162#pragma push_macro("max")
10170 std::string narrow(std::wstring_view str)
10177 ::WideCharToMultiByte(65001, 0, str.data(),
static_cast<int>(str.length()),
nullptr, 0,
nullptr,
nullptr);
10180 s.resize(
static_cast<size_t>(len));
10181 ::WideCharToMultiByte(65001,
10184 static_cast<int>(str.length()),
10194 std::wstring widen(std::string_view str)
10200 const auto len = ::MultiByteToWideChar(65001, 0, str.data(),
static_cast<int>(str.length()),
nullptr, 0);
10203 s.resize(
static_cast<size_t>(len));
10204 ::MultiByteToWideChar(65001, 0, str.data(),
static_cast<int>(str.length()), s.data(), len);
10212 std::wstring widen(std::u8string_view str)
10217 return widen(std::string_view{
reinterpret_cast<const char*
>(str.data()), str.length() });
10225#pragma pop_macro("min")
10226#pragma pop_macro("max")
10228#pragma inline_recursion(off)
10239#if TOML_INT_CHARCONV || TOML_FLOAT_CHARCONV
10242#if !TOML_INT_CHARCONV || !TOML_FLOAT_CHARCONV
10245#if !TOML_INT_CHARCONV
10252#pragma inline_recursion(on)
10254#pragma push_macro("min")
10255#pragma push_macro("max")
10262 template <
typename T>
10263 inline constexpr size_t charconv_buffer_length = 0;
10295 template <
typename T>
10304 for (
size_t i = 0; i < min_digits; i++)
10310 static constexpr auto value_flags_mask =
10311 value_flags::format_as_binary | value_flags::format_as_octal | value_flags::format_as_hexadecimal;
10312 format &= value_flags_mask;
10315 if (
format != value_flags::none && val > T{})
10319 case value_flags::format_as_binary: base = 2;
break;
10320 case value_flags::format_as_octal: base = 8;
break;
10321 case value_flags::format_as_hexadecimal: base = 16;
break;
10326#if TOML_INT_CHARCONV
10328 char buf[(
sizeof(
T) * CHAR_BIT)];
10329 const auto res = std::to_chars(buf, buf +
sizeof(buf), val, base);
10330 const auto len =
static_cast<size_t>(
res.ptr - buf);
10331 for (
size_t i = len; i < min_digits; i++)
10335 for (
size_t i = 0; i < len; i++)
10339 impl::print_to_stream(stream, buf, len);
10343 using unsigned_type = std::conditional_t<(
sizeof(
T) >
sizeof(unsigned)), std::make_unsigned_t<T>,
unsigned>;
10344 using cast_type = std::conditional_t<std::is_signed_v<T>, std::make_signed_t<unsigned_type>, unsigned_type>;
10348 const auto len =
sizeof(
T) * CHAR_BIT;
10349 for (
size_t i = len; i < min_digits; i++)
10352 bool found_one =
false;
10353 const auto v =
static_cast<unsigned_type
>(val);
10354 unsigned_type mask = unsigned_type{ 1 } << (len - 1u);
10355 for (
size_t i = 0; i < len; i++)
10362 else if (found_one)
10369 std::ostringstream ss;
10370 ss.imbue(std::locale::classic());
10371 ss << std::uppercase << std::setbase(base);
10373 ss << std::setfill('0') << std::setw(static_cast<int>(min_digits));
10374 ss << static_cast<cast_type>(val);
10375 const auto str = std::move(ss).str();
10376 impl::print_to_stream(stream, str);
10382 template <
typename T>
10387 [[maybe_unused]]
bool relaxed_precision)
10389 switch (impl::fpclassify(val))
10391 case impl::fp_class::neg_inf: impl::print_to_stream(stream,
"-inf"sv);
break;
10393 case impl::fp_class::pos_inf: impl::print_to_stream(stream,
"inf"sv);
break;
10395 case impl::fp_class::nan: impl::print_to_stream(stream,
"nan"sv);
break;
10397 case impl::fp_class::ok:
10399 static constexpr auto needs_decimal_point = [](
auto&& s)
noexcept
10402 if (c ==
'.' || c ==
'E' || c ==
'e')
10407#if TOML_FLOAT_CHARCONV
10409 const auto hex = !!(
format & value_flags::format_as_hexadecimal);
10410 char buf[charconv_buffer_length<T>];
10411 auto res = hex ? std::to_chars(buf, buf +
sizeof(buf), val, std::chars_format::hex)
10412 : std::to_chars(buf, buf +
sizeof(buf), val);
10413 auto str = std::string_view{ buf,
static_cast<size_t>(
res.ptr - buf) };
10415 char buf2[charconv_buffer_length<T>];
10416 if (!hex && relaxed_precision)
10418 res = std::to_chars(buf2, buf2 +
sizeof(buf2), val, std::chars_format::general, 6);
10419 const auto str2 = std::string_view{ buf2,
static_cast<size_t>(
res.ptr - buf2) };
10420 if (str2.length() < str.length())
10424 impl::print_to_stream(stream, str);
10425 if (!hex && needs_decimal_point(str))
10426 toml::impl::print_to_stream(stream,
".0"sv);
10430 std::ostringstream ss;
10431 ss.imbue(std::locale::classic());
10432 if (!relaxed_precision)
10433 ss.precision(std::numeric_limits<T>::max_digits10);
10434 if (!!(
format & value_flags::format_as_hexadecimal))
10435 ss << std::hexfloat;
10437 const auto str = std::move(ss).str();
10438 impl::print_to_stream(stream, str);
10439 if (!(
format & value_flags::format_as_hexadecimal) && needs_decimal_point(str))
10440 impl::print_to_stream(stream,
".0"sv);
10458 stream.write(val,
static_cast<std::streamsize
>(len));
10464 stream.write(val.data(),
static_cast<std::streamsize
>(val.length()));
10470 stream.write(val.data(),
static_cast<std::streamsize
>(val.length()));
10482 TOML_ANON_NAMESPACE::print_integer_to_stream(stream, val,
format, min_digits);
10488 TOML_ANON_NAMESPACE::print_integer_to_stream(stream, val,
format, min_digits);
10494 TOML_ANON_NAMESPACE::print_integer_to_stream(stream, val,
format, min_digits);
10500 TOML_ANON_NAMESPACE::print_integer_to_stream(stream, val,
format, min_digits);
10505 signed long long val,
10509 TOML_ANON_NAMESPACE::print_integer_to_stream(stream, val,
format, min_digits);
10515 TOML_ANON_NAMESPACE::print_integer_to_stream(stream, val,
format, min_digits);
10521 TOML_ANON_NAMESPACE::print_integer_to_stream(stream, val,
format, min_digits);
10527 TOML_ANON_NAMESPACE::print_integer_to_stream(stream, val,
format, min_digits);
10533 TOML_ANON_NAMESPACE::print_integer_to_stream(stream, val,
format, min_digits);
10538 unsigned long long val,
10542 TOML_ANON_NAMESPACE::print_integer_to_stream(stream, val,
format, min_digits);
10548 TOML_ANON_NAMESPACE::print_floating_point_to_stream(stream, val,
format, relaxed_precision);
10554 TOML_ANON_NAMESPACE::print_floating_point_to_stream(stream, val,
format, relaxed_precision);
10581 if (val.nanosecond && val.nanosecond <= 999999999u)
10584 auto ns = val.nanosecond;
10585 size_t digits = 9u;
10586 while (ns % 10u == 0u)
10604 auto mins =
static_cast<int>(val.minutes);
10612 const auto hours = mins / 60;
10616 mins -= hours * 60;
10655#if TOML_ENABLE_FORMATTERS
10660 stream << toml_formatter{ arr };
10666 stream << toml_formatter{ tbl };
10672 stream << toml_formatter{ val };
10678 stream << toml_formatter{ val };
10684 stream << toml_formatter{ val };
10690 stream << toml_formatter{ val };
10696 stream << toml_formatter{ val };
10702 stream << toml_formatter{ val };
10708 stream << toml_formatter{ val };
10716#pragma pop_macro("min")
10717#pragma pop_macro("max")
10719#pragma inline_recursion(off)
10729#pragma inline_recursion(on)
10731#pragma push_macro("min")
10732#pragma push_macro("max")
10740 node::node() noexcept = default;
10743 node::~node() noexcept = default;
10746 node::node(node && other) noexcept
10747 : source_{ std::exchange(other.source_, {}) }
10751 node::node(
const node& )
noexcept
10759 node& node::operator=(
const node& )
noexcept
10770 node& node::operator=(node&&
rhs)
noexcept
10773 source_ = std::exchange(
rhs.source_, {});
10780 return toml::at_path(*
this, path);
10786 return toml::at_path(*
this, path);
10792 return toml::at_path(*
this,
p);
10798 return toml::at_path(*
this,
p);
10801#if TOML_ENABLE_WINDOWS_COMPAT
10806 return toml::at_path(*
this, path);
10812 return toml::at_path(*
this, path);
10820 return toml::at_path(*
this,
p);
10826 return toml::at_path(*
this,
p);
10835 bool TOML_CALLCONV node_deep_equality(
const node* lhs,
const node*
rhs)
noexcept
10842 if ((!lhs != !
rhs) || lhs->type() !=
rhs->type())
10846 [=](
auto& l)
noexcept
10848 using concrete_type = remove_cvref<
decltype(l)>;
10850 return l == *(
rhs->as<concrete_type>());
10857#pragma pop_macro("min")
10858#pragma pop_macro("max")
10860#pragma inline_recursion(off)
10868#if TOML_INT_CHARCONV
10877#pragma inline_recursion(on)
10879#pragma push_macro("min")
10880#pragma push_macro("max")
10890 const parse_path_callback<std::string_view> on_key,
10891 const parse_path_callback<size_t> on_index)
10895 return on_key(data,
""sv);
10898 const auto end =
path.length();
10899 bool prev_was_array_indexer =
false;
10900 bool prev_was_dot =
true;
10905 if (path[pos] ==
'[')
10908 size_t index_start = pos + 1u;
10914 const auto c = path[index_start];
10917 else if (c ==
' ' || c ==
'\t')
10926 size_t index_end = index_start + 1u;
10933 const auto c = path[index_end];
10934 if (c >=
'0' && c <=
'9')
10936 else if (c ==
']' || c ==
' ' || c ==
'\t' || c ==
'.' || c ==
'[')
10951 const auto c = path[pos];
10959 else if (c ==
'\t' || c ==
' ')
10966 auto index_str = path.substr(index_start, index_end - index_start);
10970 if (index_str.length() == 1u)
10971 index = static_cast<
size_t>(index_str[0] -
'0');
10974#if TOML_INT_CHARCONV
10976 auto fc_result = std::from_chars(index_str.data(), index_str.data() + index_str.length(), index);
10977 if (fc_result.ec != std::errc{})
10982 std::stringstream ss;
10983 ss.imbue(std::locale::classic());
10984 ss.write(index_str.data(),
static_cast<std::streamsize
>(index_str.length()));
10985 if (!(ss >> index))
10991 prev_was_dot =
false;
10992 prev_was_array_indexer =
true;
10994 if (!on_index(data, index))
10999 else if (path[pos] ==
'.')
11010 if (prev_was_dot && !on_key(data,
""sv))
11014 prev_was_dot =
true;
11015 prev_was_array_indexer =
false;
11025 const auto subkey_start = pos;
11026 const auto subkey_len =
11027 impl::min(
path.find_first_of(
".[]"sv, subkey_start + 1u),
path.length()) - subkey_start;
11028 const auto subkey =
path.substr(subkey_start, subkey_len);
11036 if (prev_was_array_indexer)
11038 auto non_ws = subkey.find_first_not_of(
" \t");
11039 if (non_ws == std::string_view::npos)
11042 prev_was_dot =
false;
11043 prev_was_array_indexer =
false;
11051 prev_was_dot =
false;
11052 prev_was_array_indexer =
false;
11054 if (!on_key(data, subkey))
11060 if (prev_was_dot && !on_key(data,
""sv))
11074 if (
root.is_value())
11076 if (
auto tbl =
root.as_table(); tbl && tbl->empty())
11078 if (
auto arr =
root.as_array(); arr &&
arr->empty())
11083 static constexpr auto on_key = [](
void*
data, std::string_view
key)
noexcept ->
bool
11085 auto& curr = *
static_cast<node**
>(
data);
11088 const auto current_table = curr->as<
table>();
11089 if (!current_table)
11092 curr = current_table->get(key);
11093 return curr !=
nullptr;
11096 static constexpr auto on_index = [](
void*
data,
size_t index)
noexcept ->
bool
11098 auto& curr = *
static_cast<node**
>(
data);
11101 const auto current_array = curr->as<
array>();
11102 if (!current_array)
11105 curr = current_array->get(index);
11106 return curr !=
nullptr;
11109 if (!impl::parse_path(path, ¤t, on_key, on_index))
11121#if TOML_ENABLE_WINDOWS_COMPAT
11129 if (
root.is_value())
11131 if (
auto tbl =
root.as_table(); tbl && tbl->empty())
11133 if (
auto arr =
root.as_array(); arr &&
arr->empty())
11136 return at_path(root, impl::narrow(path));
11150#pragma pop_macro("min")
11151#pragma pop_macro("max")
11153#pragma inline_recursion(off)
11161#if TOML_INT_CHARCONV
11169#pragma inline_recursion(on)
11171#pragma push_macro("min")
11172#pragma push_macro("max")
11181 : type_{ path_component_type::
key }
11183 store_key(
"", value_storage_);
11188 : type_(path_component_type::array_index)
11190 store_index(index, value_storage_);
11195 : type_(path_component_type::
key)
11197 store_key(key, value_storage_);
11200#if TOML_ENABLE_WINDOWS_COMPAT
11211 : type_{ pc.type_ }
11213 if (type_ == path_component_type::array_index)
11214 store_index(pc.
index(), value_storage_);
11216 store_key(pc.
key(), value_storage_);
11221 : type_{ pc.
type_ }
11223 if (type_ == path_component_type::array_index)
11224 store_index(pc.
index_ref(), value_storage_);
11226 store_key(std::move(pc.
key_ref()), value_storage_);
11237 if (
type_ == path_component_type::array_index)
11244 if (
type_ == path_component_type::array_index)
11255 if (type_ !=
rhs.type_)
11260 if (type_ == path_component_type::array_index)
11261 store_index(
rhs.index(), value_storage_);
11263 store_key(std::move(
rhs.key_ref()), value_storage_);
11267 if (type_ == path_component_type::array_index)
11268 index_ref() =
rhs.index();
11270 key_ref() = std::move(
rhs.key_ref());
11280 if (lhs.type_ !=
rhs.type_)
11283 if (lhs.type_ == path_component_type::array_index)
11284 return lhs.index() ==
rhs.index();
11286 return lhs.key() ==
rhs.key();
11295 type_ = path_component_type::array_index;
11296 store_index(new_index, value_storage_);
11304 if (
type_ == path_component_type::key)
11308 type_ = path_component_type::key;
11315#if TOML_ENABLE_WINDOWS_COMPAT
11320 if (
type_ == path_component_type::key)
11321 key_ref() = impl::narrow(new_key);
11324 type_ = path_component_type::key;
11338 bool parse_path_into(std::string_view path_str, std::vector<path_component> & components)
11340 using components_type = std::remove_reference_t<
decltype(components)>;
11342 const auto original_size = components.size();
11344 static constexpr auto on_key = [](
void*
data, std::string_view
key) ->
bool
11346 auto& comps = *
static_cast<components_type*
>(
data);
11347 comps.emplace_back(key);
11351 static constexpr auto on_index = [](
void*
data,
size_t index) ->
bool
11353 auto& comps = *
static_cast<components_type*
>(
data);
11354 comps.emplace_back(index);
11358 if (!impl::parse_path(path_str, &components, on_key, on_index))
11360 components.resize(original_size);
11377 if (component.type() == path_component_type::key)
11380 impl::print_to_stream(os,
'.');
11381 impl::print_to_stream(os, component.key());
11383 else if (component.type() == path_component_type::array_index)
11385 impl::print_to_stream(os,
'[');
11386 impl::print_to_stream(os, component.index());
11387 impl::print_to_stream(os,
']');
11397 return lhs.components_ ==
rhs.components_;
11406#if TOML_ENABLE_WINDOWS_COMPAT
11410 :
path(impl::narrow(str))
11423#if TOML_ENABLE_WINDOWS_COMPAT
11444 std::make_move_iterator(
rhs.components_.begin()),
11445 std::make_move_iterator(
rhs.components_.end()));
11456#if TOML_ENABLE_WINDOWS_COMPAT
11461 return *
this += impl::narrow(
str);
11477 std::make_move_iterator(source.
components_.begin()),
11478 std::make_move_iterator(source.
components_.end()));
11488#if TOML_ENABLE_WINDOWS_COMPAT
11493 return prepend(impl::narrow(source));
11504 std::ostringstream ss;
11506 return std::move(ss).str();
11509#if TOML_ENABLE_WINDOWS_COMPAT
11512 std::wstring path::wide_str()
const
11514 return impl::widen(
str());
11531 components_.erase(it_end -
static_cast<int>(
n), it_end);
11539 path truncated_path{};
11550 return truncated_path;
11578 std::vector<path_component>::const_iterator
end)
const
11602 if (
root.is_value())
11604 if (
auto tbl =
root.as_table(); tbl && tbl->empty())
11606 if (
auto arr =
root.as_array(); arr &&
arr->empty())
11609 node* current = &
root;
11611 for (
const auto& component :
path)
11613 auto type = component.type();
11614 if (type == path_component_type::array_index)
11616 const auto current_array = current->as<
array>();
11617 if (!current_array)
11620 current = current_array->get(component.index());
11622 else if (type == path_component_type::key)
11624 const auto current_table = current->as<
table>();
11625 if (!current_table)
11628 current = current_table->get(component.key());
11652#pragma pop_macro("min")
11653#pragma pop_macro("max")
11655#pragma inline_recursion(off)
11665#pragma inline_recursion(on)
11667#pragma push_macro("min")
11668#pragma push_macro("max")
11678#if TOML_LIFETIME_HOOKS
11679 TOML_ARRAY_CREATED;
11686#if TOML_LIFETIME_HOOKS
11687 TOML_ARRAY_DESTROYED;
11692 array::array(
const impl::array_init_elem*
b,
const impl::array_init_elem* e)
11694#if TOML_LIFETIME_HOOKS
11695 TOML_ARRAY_CREATED;
11706 for (
auto it =
b; it != e; it++)
11715 for (;
b != e;
b++)
11718 elems_.push_back(std::move(
b->value));
11726 elems_.reserve(other.
elems_.size());
11727 for (
const auto& elem : other)
11728 elems_.emplace_back(impl::make_node(elem));
11731 TOML_ARRAY_CREATED;
11737 : node(std::move(other)),
11738 elems_(std::move(other.
elems_))
11740#if TOML_LIFETIME_HOOKS
11741 TOML_ARRAY_CREATED;
11750 node::operator=(
rhs);
11753 for (
const auto& elem :
rhs)
11754 elems_.emplace_back(impl::make_node(elem));
11764 node::operator=(std::move(
rhs));
11765 elems_ = std::move(
rhs.elems_);
11775 const auto old_size =
elems_.size();
11776 const auto new_size = old_size +
count;
11777 const auto inserting_at_end =
idx == old_size;
11778 elems_.resize(new_size);
11779 if (!inserting_at_end)
11781 for (
size_t left = old_size, right = new_size - 1u; left-- >
idx; right--)
11790 elems_.push_back(std::move(elem));
11796 return elems_.insert(pos, std::move(elem));
11803 if (elems_.empty())
11806 if (ntype == node_type::none)
11807 ntype = elems_[0]->type();
11809 for (
const auto& val : elems_)
11810 if (val->type() != ntype)
11820 if (elems_.empty())
11822 first_nonmatch = {};
11825 if (ntype == node_type::none)
11826 ntype = elems_[0]->type();
11827 for (
const auto& val : elems_)
11829 if (val->type() != ntype)
11831 first_nonmatch = val.get();
11842 node* fnm =
nullptr;
11844 first_nonmatch = fnm;
11851#if TOML_COMPILER_HAS_EXCEPTIONS
11853 return *
elems_.at(index);
11857 auto n =
get(index);
11867 elems_.reserve(new_capacity);
11879 if (new_size <
elems_.size())
11880 elems_.resize(new_size);
11886 return iterator{ elems_.erase(const_vector_iterator{ pos }) };
11892 return iterator{ elems_.erase(const_vector_iterator{ first }, const_vector_iterator{ last }) };
11899 for (
size_t i = 0, e =
elems_.size(); i < e; i++)
11902 leaves +=
arr ?
arr->total_leaf_count() :
size_t{ 1 };
11910 for (
size_t i = 0, e = child.size(); i < e; i++)
11912 auto type = child.elems_[i]->type();
11913 if (type == node_type::array)
11915 array&
arr = *
reinterpret_cast<array*
>(child.elems_[i].get());
11917 flatten_child(std::move(arr), dest_index);
11920 elems_[dest_index++] = std::move(child.elems_[i]);
11927 if (elems_.empty())
11930 bool requires_flattening =
false;
11931 size_t size_after_flattening = elems_.size();
11932 for (
size_t i = elems_.size(); i-- > 0u;)
11934 auto arr = elems_[i]->as_array();
11937 size_after_flattening--;
11938 const auto leaf_count =
arr->total_leaf_count();
11939 if (leaf_count > 0u)
11941 requires_flattening =
true;
11942 size_after_flattening += leaf_count;
11945 elems_.erase(elems_.cbegin() +
static_cast<ptrdiff_t
>(i));
11948 if (!requires_flattening)
11951 elems_.reserve(size_after_flattening);
11954 while (i < elems_.size())
11956 auto arr = elems_[i]->as_array();
11963 impl::node_ptr arr_storage = std::move(elems_[i]);
11964 const auto leaf_count =
arr->total_leaf_count();
11965 if (leaf_count > 1u)
11966 preinsertion_resize(i + 1u, leaf_count - 1u);
11967 flatten_child(std::move(*arr), i);
11976 if (elems_.empty())
11979 for (
size_t i = elems_.size(); i-- > 0u;)
11981 if (
auto arr = elems_[i]->as_array())
11986 elems_.erase(elems_.cbegin() +
static_cast<ptrdiff_t
>(i));
11988 else if (
auto tbl = elems_[i]->as_table())
11993 elems_.erase(elems_.cbegin() +
static_cast<ptrdiff_t
>(i));
12017 if (lhs.elems_.size() !=
rhs.elems_.size())
12019 for (
size_t i = 0, e = lhs.elems_.size(); i < e; i++)
12021 const auto lhs_type = lhs.elems_[i]->type();
12022 const node& rhs_ = *
rhs.elems_[i];
12023 const auto rhs_type = rhs_.type();
12024 if (lhs_type != rhs_type)
12027 const bool equal = lhs.elems_[i]->visit(
12028 [&](
const auto& lhs_)
noexcept
12029 {
return lhs_ == *
reinterpret_cast<std::remove_reference_t<decltype(lhs_)
>*>(&rhs_); });
12039#pragma pop_macro("min")
12040#pragma pop_macro("max")
12042#pragma inline_recursion(off)
12052#pragma inline_recursion(on)
12054#pragma push_macro("min")
12055#pragma push_macro("max")
12065#if TOML_LIFETIME_HOOKS
12066 TOML_TABLE_CREATED;
12073#if TOML_LIFETIME_HOOKS
12074 TOML_TABLE_DESTROYED;
12079 table::table(
const impl::table_init_pair*
b,
const impl::table_init_pair* e)
12081#if TOML_LIFETIME_HOOKS
12082 TOML_TABLE_CREATED;
12092 for (;
b != e;
b++)
12097 map_.insert_or_assign(std::move(
b->key), std::move(
b->value));
12104 inline_{ other.inline_ }
12106 for (
auto&& [k, v] : other.
map_)
12107 map_.emplace_hint(map_.end(), k, impl::make_node(*v));
12110 TOML_TABLE_CREATED;
12116 : node(std::move(other)),
12117 map_{ std::move(other.
map_) },
12120#if TOML_LIFETIME_HOOKS
12121 TOML_TABLE_CREATED;
12130 node::operator=(
rhs);
12132 for (
auto&& [k, v] :
rhs.map_)
12133 map_.emplace_hint(
map_.end(), k, impl::make_node(*v));
12144 node::operator=(std::move(
rhs));
12145 map_ = std::move(
rhs.map_);
12146 inline_ =
rhs.inline_;
12158 if (ntype == node_type::none)
12159 ntype = map_.cbegin()->second->type();
12161 for (
auto&& [k, v] : map_)
12164 if (v->type() != ntype)
12177 first_nonmatch = {};
12180 if (ntype == node_type::none)
12181 ntype = map_.cbegin()->second->type();
12182 for (
const auto& [k, v] : map_)
12185 if (v->type() != ntype)
12187 first_nonmatch = v.get();
12198 node* fnm =
nullptr;
12200 first_nonmatch = fnm;
12206 node*
table::get(std::string_view key)
noexcept
12208 if (
auto it = map_.find(key); it != map_.end())
12209 return it->second.get();
12218#if TOML_COMPILER_HAS_EXCEPTIONS
12222 auto err =
"key '"s;
12224 err.append(
"' not found in table"sv);
12225 throw std::out_of_range{ err };
12241 return map_.lower_bound(key);
12248 return iterator{ map_.find(key) };
12261 return map_.erase(pos);
12273 if (
auto it = map_.find(key); it != map_.end())
12276 return size_t{ 1 };
12287 for (
auto it = map_.begin(); it != map_.end();)
12289 if (
auto arr = it->second->as_array())
12296 it = map_.erase(it);
12300 else if (
auto tbl = it->second->as_table())
12307 it = map_.erase(it);
12335 if (lhs.map_.size() !=
rhs.map_.size())
12338 for (
auto l = lhs.map_.begin(),
r =
rhs.map_.begin(), e = lhs.map_.end(); l != e; l++,
r++)
12340 if (l->first !=
r->first)
12343 const auto lhs_type = l->second->type();
12344 const node& rhs_ = *
r->second;
12345 const auto rhs_type = rhs_.type();
12346 if (lhs_type != rhs_type)
12349 const bool equal = l->second->visit(
12350 [&](
const auto& lhs_)
noexcept
12351 {
return lhs_ == *
reinterpret_cast<std::remove_reference_t<decltype(lhs_)
>*>(&rhs_); });
12361#pragma pop_macro("min")
12362#pragma pop_macro("max")
12364#pragma inline_recursion(off)
12371#if TOML_ENABLE_SIMD
12373#if defined(__SSE2__) \
12374 || (defined(_MSC_VER) && (defined(_M_AMD64) || defined(_M_X64) || (defined(_M_IX86_FP) && _M_IX86_FP >= 2)))
12375#define TOML_HAS_SSE2 1
12378#if defined(__SSE4_1__) || (defined(_MSC_VER) && (defined(__AVX__) || defined(__AVX2__)))
12379#define TOML_HAS_SSE4_1 1
12384#ifndef TOML_HAS_SSE2
12385#define TOML_HAS_SSE2 0
12387#ifndef TOML_HAS_SSE4_1
12388#define TOML_HAS_SSE4_1 0
12393#include <smmintrin.h>
12396#include <emmintrin.h>
12405#pragma inline_recursion(on)
12407#pragma push_macro("min")
12408#pragma push_macro("max")
12417 bool is_ascii(
const char* str,
size_t len)
noexcept
12419 const char*
const end = str + len;
12421#if TOML_HAS_SSE2 && (128 % CHAR_BIT) == 0
12423 constexpr size_t chars_per_vector = 128u / CHAR_BIT;
12425 if (
const size_t simdable = len - (len % chars_per_vector))
12427 __m128i mask = _mm_setzero_si128();
12428 for (
const char*
const e = str + simdable; str < e; str += chars_per_vector)
12430 const __m128i current_bytes = _mm_loadu_si128(
reinterpret_cast<const __m128i*
>(str));
12431 mask = _mm_or_si128(mask, current_bytes);
12433 const __m128i
has_error = _mm_cmpgt_epi8(_mm_setzero_si128(), mask);
12439 if (_mm_movemask_epi8(_mm_cmpeq_epi8(
has_error, _mm_setzero_si128())) != 0xFFFF)
12446 for (; str <
end; str++)
12447 if (
static_cast<unsigned char>(*str) > 127u)
12456#pragma pop_macro("min")
12457#pragma pop_macro("max")
12459#pragma inline_recursion(off)
12466#if TOML_ENABLE_PARSER
12471#if TOML_INT_CHARCONV || TOML_FLOAT_CHARCONV
12474#if !TOML_INT_CHARCONV || !TOML_FLOAT_CHARCONV
12477#if !TOML_INT_CHARCONV
12484#pragma inline_recursion(on)
12486#pragma push_macro("min")
12487#pragma push_macro("max")
12494 template <
typename T>
12495 class utf8_byte_stream;
12500 template <
typename Char>
12503 static_assert(
sizeof(Char) == 1);
12526 constexpr bool eof() const noexcept
12532 explicit constexpr operator bool() const noexcept
12545 size_t operator()(
void* dest,
size_t num) noexcept
12570 const auto initial_pos =
source_->tellg();
12577 source_->seekg(initial_pos, std::istream::beg);
12583 return !!(
source_->rdstate() & std::istream::badbit);
12589 return !!(
source_->rdstate() & std::istream::eofbit);
12593 explicit operator bool() const noexcept
12595 return !(
source_->rdstate() & (std::istream::badbit | std::istream::eofbit));
12601 return eof() ||
source_->peek() == std::istream::traits_type::eof();
12610 source_->read(
static_cast<char*
>(dest),
static_cast<std::streamsize
>(num));
12611 return static_cast<size_t>(
source_->gcount());
12623 constexpr operator const char32_t&()
const noexcept
12634 static_assert(std::is_trivial_v<utf8_codepoint>);
12635 static_assert(std::is_standard_layout_v<utf8_codepoint>);
12648#if !TOML_EXCEPTIONS
12651 virtual optional<parse_error>&&
error() noexcept = 0;
12659#define utf8_reader_error(...) throw parse_error(__VA_ARGS__)
12660#define utf8_reader_return_after_error(...) static_assert(true)
12661#define utf8_reader_error_check(...) static_assert(true)
12663#define utf8_reader_error(...) err_.emplace(__VA_ARGS__)
12664#define utf8_reader_return_after_error(...) return __VA_ARGS__
12665#define utf8_reader_error_check(...) \
12668 if TOML_UNLIKELY(err_) \
12669 return __VA_ARGS__; \
12675#if defined(__APPLE__) || defined(__MINGW32__) || defined(__MINGW64__)
12676#define TOML_OVERALIGNED
12678#define TOML_OVERALIGNED alignas(32)
12681 template <
typename T>
12694 } currently_decoding_;
12705#if !TOML_EXCEPTIONS
12714 size_t raw_bytes_read;
12728 catch (
const std::exception& exc)
12748 utf8_reader_error(
"Encountered EOF during incomplete utf-8 code point sequence",
12754 utf8_reader_error(
"Reading from the underlying stream failed - zero bytes read",
12765 const auto calc_positions = [&]()
noexcept
12783 const auto ascii_fast_path = !
decoder_.needs_more_input() && impl::is_ascii(raw_bytes, raw_bytes_read);
12786 if (ascii_fast_path)
12795 cp.value =
static_cast<char32_t>(raw_bytes[i]);
12796 cp.bytes[0] = raw_bytes[i];
12810 for (
size_t i = 0; i < raw_bytes_read; i++)
12812 decoder_(
static_cast<uint8_t
>(raw_bytes[i]));
12841 utf8_reader_error(
"Encountered EOF during incomplete utf-8 code point sequence",
12855 utf8_reader_error(
"An I/O error occurred while reading from the underlying stream",
12865 template <
typename U,
typename String = std::
string_view>
12868 std::is_nothrow_constructible_v<utf8_byte_stream<T>, U&&>)
12869 : stream_{ static_cast<U&&>(source) }
12871 currently_decoding_.count = {};
12873 codepoints_.current = {};
12874 codepoints_.count = {};
12876 if (!source_path.empty())
12877 source_path_ = std::make_shared<const std::string>(
static_cast<String&&
>(source_path));
12911#if !TOML_EXCEPTIONS
12914 optional<parse_error>&&
error() noexcept final
12916 return std::move(
err_);
12922 template <
typename Char>
12924 template <
typename Char>
12926 template <
typename Char>
12928 template <
typename Char>
12932#define utf8_buffered_reader_error_check(...) static_assert(true)
12934#define utf8_buffered_reader_error_check(...) \
12937 if TOML_UNLIKELY(reader_.error()) \
12938 return __VA_ARGS__; \
12969 return reader_.source_path();
13032#if !TOML_EXCEPTIONS
13046#define TOML_RETURNS_BY_THROWING [[noreturn]]
13048#define TOML_RETURNS_BY_THROWING
13053 template <
typename... T>
13056 constexpr bool is_match(
char32_t codepoint, T... vals)
noexcept
13058 static_assert((std::is_same_v<char32_t, T> && ...));
13059 return ((codepoint == vals) || ...);
13062 template <u
int64_t>
13063 struct parse_integer_traits;
13065 struct parse_integer_traits<2>
13076 struct parse_integer_traits<8>
13087 struct parse_integer_traits<10>
13096 struct parse_integer_traits<16>
13099 static constexpr auto is_digit = impl::is_hexadecimal_digit;
13109 std::string_view
to_sv(node_type val)
noexcept
13111 return impl::node_type_friendly_names[impl::unwrap_enum(val)];
13116 std::string_view
to_sv(
const std::string& str)
noexcept
13118 return std::string_view{ str };
13125 using namespace std::string_view_literals;
13127 return val ?
"true"sv :
"false"sv;
13134 if (cp.value <= U
'\x1F')
13135 return impl::control_char_escapes[cp.value];
13136 else if (cp.value == U
'\x7F')
13137 return "\\u007F"sv;
13139 return std::string_view{ cp.bytes, cp.count };
13156 template <
typename T>
13159 void concatenate(
char*& write_pos,
char*
const buf_end,
const T& arg)
noexcept
13164 using arg_type = impl::remove_cvref<T>;
13167 if constexpr (std::is_same_v<arg_type, std::string_view>)
13169 const auto max_chars =
static_cast<size_t>(buf_end - write_pos);
13170 const auto len = max_chars < arg.length() ? max_chars : arg.length();
13171 std::memcpy(write_pos, arg.data(), len);
13176 else if constexpr (std::is_same_v<arg_type, double>)
13178#if TOML_FLOAT_CHARCONV
13179 const auto result = std::to_chars(write_pos, buf_end, arg);
13182 std::ostringstream ss;
13183 ss.imbue(std::locale::classic());
13184 ss.precision(std::numeric_limits<arg_type>::max_digits10);
13191 else if constexpr (impl::is_one_of<arg_type, int64_t, uint64_t>)
13193#if TOML_INT_CHARCONV
13194 const auto result = std::to_chars(write_pos, buf_end, arg);
13197 std::ostringstream ss;
13198 ss.imbue(std::locale::classic());
13199 using cast_type = std::conditional_t<std::is_signed_v<arg_type>, int64_t, uint64_t>;
13200 ss << static_cast<cast_type>(arg);
13206 else if constexpr (std::is_same_v<arg_type, escaped_codepoint>)
13208 if (arg.cp.value <= U
'\x7F')
13212 auto val =
static_cast<uint_least32_t
>(arg.cp.value);
13213 const auto digits = val > 0xFFFFu ? 8u : 4u;
13214 constexpr auto mask = uint_least32_t{ 0xFu };
13215 char buf[10] = {
'\\', digits > 4 ?
'U' :
'u' };
13216 for (
auto i = 2u + digits; i-- > 2u;)
13218 const auto hexdig = val & mask;
13219 buf[i] =
static_cast<char>(hexdig >= 0xAu ? (
'A' + (hexdig - 0xAu)) : (
'0' + hexdig));
13222 concatenate(write_pos, buf_end, std::string_view{ buf, digits + 2u });
13227 else if constexpr (std::is_floating_point_v<arg_type>)
13228 concatenate(write_pos, buf_end,
static_cast<double>(arg));
13231 else if constexpr (std::is_arithmetic_v<arg_type> && std::is_integral_v<arg_type>)
13233 using cast_type = std::conditional_t<std::is_unsigned_v<arg_type>, uint64_t, int64_t>;
13234 concatenate(write_pos, buf_end,
static_cast<cast_type
>(arg));
13240 impl::always_false<T>,
13241 "concatenate() inputs are limited to std::string_views, integers, floats, and escaped_codepoint");
13260 template <
typename T>
13272 throw parse_error{
buf, pos, source_path };
13274 return parse_error{ std::string(
buf,
static_cast<size_t>(
write_pos -
buf)), pos, source_path };
13287 explicit parse_scope(std::string_view& current_scope, std::string_view new_scope) noexcept
13301#define push_parse_scope_2(scope, line) parse_scope ps_##line(current_scope, scope)
13302#define push_parse_scope_1(scope, line) push_parse_scope_2(scope, line)
13303#define push_parse_scope(scope) push_parse_scope_1(scope, __LINE__)
13337 return (*
this)[
segments.size() - 1u];
13409#define is_eof() !cp
13410#define assert_not_eof() TOML_ASSERT_ASSUME(cp != nullptr)
13411#define return_if_eof(...) \
13414 if TOML_UNLIKELY(is_eof()) \
13415 return __VA_ARGS__; \
13420#define is_error() false
13421#define return_after_error(...) TOML_UNREACHABLE
13422#define assert_not_error() static_assert(true)
13423#define return_if_error(...) static_assert(true)
13424#define return_if_error_or_eof(...) return_if_eof(__VA_ARGS__)
13426#define is_error() !!err
13427#define return_after_error(...) return __VA_ARGS__
13428#define assert_not_error() TOML_ASSERT(!is_error())
13429#define return_if_error(...) \
13432 if TOML_UNLIKELY(is_error()) \
13433 return __VA_ARGS__; \
13436#define return_if_error_or_eof(...) \
13439 if TOML_UNLIKELY(is_eof() || is_error()) \
13440 return __VA_ARGS__; \
13445#if defined(TOML_BREAK_AT_PARSE_ERRORS) && TOML_BREAK_AT_PARSE_ERRORS
13446#if defined(__has_builtin)
13447#if __has_builtin(__builtin_debugtrap)
13448#define parse_error_break() __builtin_debugtrap()
13449#elif __has_builtin(__debugbreak)
13450#define parse_error_break() __debugbreak()
13453#ifndef parse_error_break
13454#if TOML_MSVC || TOML_ICC
13455#define parse_error_break() __debugbreak()
13457#define parse_error_break() TOML_ASSERT(false)
13461#define parse_error_break() static_assert(true)
13464#define set_error_and_return(ret, ...) \
13468 set_error(__VA_ARGS__); \
13469 return_after_error(ret); \
13473#define set_error_and_return_default(...) set_error_and_return({}, __VA_ARGS__)
13475#define set_error_and_return_if_eof(...) \
13478 if TOML_UNLIKELY(is_eof()) \
13479 set_error_and_return(__VA_ARGS__, "encountered end-of-file"sv); \
13483#define advance_and_return_if_error(...) \
13486 assert_not_eof(); \
13488 return_if_error(__VA_ARGS__); \
13492#define advance_and_return_if_error_or_eof(...) \
13495 assert_not_eof(); \
13497 return_if_error(__VA_ARGS__); \
13498 set_error_and_return_if_eof(__VA_ARGS__); \
13527#if !TOML_EXCEPTIONS
13528 mutable optional<parse_error>
err;
13535 return cp->position;
13536 return {
prev_pos.line,
static_cast<source_index
>(
prev_pos.column + fallback_offset) };
13539 template <
typename... T>
13544 static_assert(
sizeof...(T) > 0);
13548 (builder.append(reason), ...);
13553 builder.finish(pos,
reader.source_path());
13555 err.emplace(builder.finish(pos,
reader.source_path()));
13559 template <
typename... T>
13583#if !TOML_EXCEPTIONS
13605 if (include_current && !
is_eof())
13618 else if (pop_bytes == 1u)
13631 bool consumed =
false;
13632 while (!
is_eof() && is_horizontal_whitespace(*
cp))
13649 R
"(vertical tabs '\v' and form-feeds '\f' are not legal line breaks in TOML)"sv);
13663 else if (*
cp != U
'\n')
13676 if (is_ascii_vertical_whitespace(*
cp))
13704#if TOML_LANG_AT_LEAST(1, 0, 0)
13709 "control characters other than TAB (U+0009) are explicitly prohibited in comments"sv);
13714 "unicode surrogates (U+D800 to U+DFFF) are explicitly prohibited in comments"sv);
13739 template <
typename T>
13747 for (
size_t i = 0; i < len; i++)
13750 if (!is_decimal_digit(*
cp))
13753 digits[i] =
static_cast<T
>(*
cp - U
'0');
13759 template <
typename T>
13768 for (; i < max_len; i++)
13770 if (
is_eof() || !is_decimal_digit(*
cp))
13773 buffer[i] =
static_cast<T
>(*
cp - U
'0');
13801 bool escaped =
false;
13802 bool skipping_whitespace =
false;
13810 if (multi_line && is_whitespace(*
cp))
13816 "line-ending backslashes must be the last non-whitespace character on the line"sv);
13818 skipping_whitespace =
true;
13823 bool skip_escaped_codepoint =
true;
13828 case U
'b': str +=
'\b';
break;
13829 case U
'f': str +=
'\f';
break;
13830 case U
'n': str +=
'\n';
break;
13831 case U
'r': str +=
'\r';
break;
13832 case U
't': str +=
'\t';
break;
13833 case U
'"': str +=
'"';
break;
13834 case U
'\\': str +=
'\\';
break;
13836#if TOML_LANG_UNRELEASED
13837 case U
'e': str +=
'\x1B';
break;
13841 "escape sequence '\\e' is not supported in TOML 1.0.0 and earlier"sv);
13844#if TOML_LANG_UNRELEASED
13845 case U
'x': [[fallthrough]];
13849 "escape sequence '\\x' is not supported in TOML 1.0.0 and earlier"sv);
13853 case U
'u': [[fallthrough]];
13858 skip_escaped_codepoint =
false;
13860 uint32_t place_value =
13862 uint32_t sequence_value{};
13863 while (place_value)
13870 sequence_value += place_value * hex_to_dec(*
cp);
13871 place_value /= 16u;
13877 "unicode surrogates (U+D800 - U+DFFF) are explicitly prohibited"sv);
13881 if (sequence_value < 0x80)
13883 str +=
static_cast<char>(sequence_value);
13885 else if (sequence_value < 0x800u)
13887 str +=
static_cast<char>((sequence_value >> 6) | 0xC0u);
13888 str +=
static_cast<char>((sequence_value & 0x3Fu) | 0x80u);
13890 else if (sequence_value < 0x10000u)
13892 str +=
static_cast<char>((sequence_value >> 12) | 0xE0u);
13893 str +=
static_cast<char>(((sequence_value >> 6) & 0x3Fu) | 0x80u);
13894 str +=
static_cast<char>((sequence_value & 0x3Fu) | 0x80u);
13896 else if (sequence_value < 0x110000u)
13898 str +=
static_cast<char>((sequence_value >> 18) | 0xF0u);
13899 str +=
static_cast<char>(((sequence_value >> 12) & 0x3Fu) | 0x80u);
13900 str +=
static_cast<char>(((sequence_value >> 6) & 0x3Fu) | 0x80u);
13901 str +=
static_cast<char>((sequence_value & 0x3Fu) | 0x80u);
13911 if (skip_escaped_codepoint)
13921 size_t lookaheads = {};
13922 size_t consecutive_delimiters = 1;
13928 consecutive_delimiters++;
13932 while (lookaheads < 4u);
13934 switch (consecutive_delimiters)
13939 skipping_whitespace =
false;
13944 str.append(
"\"\""sv);
13945 skipping_whitespace =
false;
13949 case 3:
return str;
13952 case 4: str +=
'"';
return str;
13956 str.append(
"\"\""sv);
13971 else if (*
cp == U
'\\')
13974 skipping_whitespace =
false;
13980 if (multi_line && is_ascii_vertical_whitespace(*
cp))
13984 if (!skipping_whitespace)
13992 "unescaped control characters other than TAB (U+0009) are explicitly prohibited"sv);
13994#if TOML_LANG_AT_LEAST(1, 0, 0)
13999 "unescaped unicode surrogates (U+D800 to U+DFFF) are explicitly prohibited"sv);
14004 if (!skipping_whitespace || !is_horizontal_whitespace(*
cp))
14006 skipping_whitespace =
false;
14007 str.append(
cp->bytes,
cp->count);
14011 str.append(
cp->bytes,
cp->count);
14052 size_t lookaheads = {};
14053 size_t consecutive_delimiters = 1;
14059 consecutive_delimiters++;
14063 while (lookaheads < 4u);
14065 switch (consecutive_delimiters)
14068 case 1: str +=
'\'';
continue;
14071 case 2: str.append(
"''"sv);
continue;
14074 case 3:
return str;
14077 case 4: str +=
'\'';
return str;
14081 str.append(
"''"sv);
14096 if (multi_line && is_ascii_vertical_whitespace(*
cp))
14107 "control characters other than TAB (U+0009) are explicitly prohibited"sv);
14109#if TOML_LANG_AT_LEAST(1, 0, 0)
14116 str.append(
cp->bytes,
cp->count);
14134 const auto first =
cp->value;
14136 const auto second =
cp->value;
14138 const auto third =
cp ?
cp->value : U
'\0';
14144 if (second == first)
14152 else if (first == second && first == third)
14180 if (!is_bare_key_character(*
cp))
14200 auto result = is_match(*
cp, U
't', U
'T');
14209 if (
cp && !is_value_terminator(*
cp))
14225 const bool negative = *
cp == U
'-';
14226 if (negative || *
cp == U
'+')
14229 const bool inf = is_match(*
cp, U
'i', U
'I');
14232 inf ?
"inf"sv :
"nan"sv,
14238 if (
cp && !is_value_terminator(*
cp))
14241 return inf ? (negative ? -std::numeric_limits<double>::infinity() : std::numeric_limits<double>::infinity())
14242 : std::numeric_limits<double>::quiet_NaN();
14255 const int sign = *
cp == U
'-' ? -1 : 1;
14256 if (is_match(*
cp, U
'+', U
'-'))
14261 size_t length = {};
14263 bool seen_decimal =
false, seen_exponent =
false;
14264 char first_integer_part =
'\0';
14265 while (!
is_eof() && !is_value_terminator(*
cp))
14269 if (!prev || !is_decimal_digit(*prev))
14276 else if TOML_UNLIKELY(prev && *prev == U
'_' && !is_decimal_digit(*
cp))
14282 (seen_exponent ?
""sv :
" (consider using exponent notation)"sv));
14283 else if (*
cp == U
'.')
14288 if (!first_integer_part)
14292 else if (seen_exponent)
14298 else if (seen_decimal)
14301 seen_decimal =
true;
14303 else if (is_match(*
cp, U
'e', U
'E'))
14305 if (prev && !is_decimal_digit(*prev))
14309 else if (seen_exponent)
14312 seen_decimal =
true;
14313 seen_exponent =
true;
14315 else if (is_match(*
cp, U
'+', U
'-'))
14318 if (!seen_exponent)
14322 else if (!is_match(*prev, U
'e', U
'E'))
14325 else if (is_decimal_digit(*
cp))
14329 if (!first_integer_part)
14330 first_integer_part =
static_cast<char>(
cp->bytes[0]);
14331 else if (first_integer_part ==
'0')
14338 chars[length++] =
static_cast<char>(
cp->bytes[0]);
14351 else if (is_match(*prev, U
'e', U
'E', U
'+', U
'-', U
'.'))
14360#if TOML_FLOAT_CHARCONV
14362 auto fc_result = std::from_chars(chars, chars + length,
result);
14363 switch (fc_result.ec)
14369 case std::errc::invalid_argument:
14371 std::string_view{ chars, length },
14372 "' could not be interpreted as a value"sv);
14375 case std::errc::result_out_of_range:
14377 std::string_view{ chars, length },
14378 "' is not representable in 64 bits"sv);
14383 std::string_view{ chars, length },
14389 std::stringstream ss;
14390 ss.imbue(std::locale::classic());
14391 ss.write(chars,
static_cast<std::streamsize
>(length));
14396 std::string_view{ chars, length },
14397 "' could not be interpreted as a value"sv);
14411#if TOML_LANG_UNRELEASED
14414 const int sign = *
cp == U
'-' ? -1 : 1;
14415 if (is_match(*
cp, U
'+', U
'-'))
14424 if (!is_match(*
cp, U
'x', U
'X'))
14437 fragment fragments[] = {
14442 fragment* current_fragment = fragments;
14444 int exponent_sign = 1;
14445 while (!
is_eof() && !is_value_terminator(*
cp))
14449 if (!prev || !is_hexadecimal_digit(*prev))
14456 else if (prev && *prev == U
'_' && !is_hexadecimal_digit(*
cp))
14458 else if (*
cp == U
'.')
14461 if (current_fragment == fragments + 2)
14465 else if (current_fragment == fragments + 1)
14469 current_fragment++;
14471 else if (is_match(*
cp, U
'p', U
'P'))
14474 if (current_fragment == fragments + 2)
14478 else if (fragments[0].length == 0u && fragments[1].length == 0u)
14482 current_fragment = fragments + 2;
14484 else if (is_match(*
cp, U
'+', U
'-'))
14487 if (current_fragment != fragments + 2)
14491 else if (!is_match(*prev, U
'p', U
'P'))
14495 exponent_sign = *
cp == U
'-' ? -1 : 1;
14497 else if (current_fragment < fragments + 2 && !is_hexadecimal_digit(*
cp))
14499 else if (current_fragment == fragments + 2 && !is_decimal_digit(*
cp))
14501 else if (current_fragment->length ==
sizeof(fragment::chars))
14503 sizeof(fragment::chars),
14506 current_fragment->chars[current_fragment->length++] =
static_cast<char>(
cp->bytes[0]);
14513 if (current_fragment != fragments + 2 || current_fragment->length == 0u)
14518 else if (prev && *prev == U
'_')
14525 for (
int fragment_idx = 0; fragment_idx < 3; fragment_idx++)
14527 auto& f = fragments[fragment_idx];
14528 const uint32_t base = fragment_idx == 2 ? 10u : 16u;
14531 const char* c = f.chars;
14533 while (f.length && *c ==
'0')
14544 for (
size_t i = 0; i < f.length - 1u; i++)
14550 val += place * hex_to_dec(*c);
14552 val += place *
static_cast<uint32_t
>(*c -
'0');
14553 if (fragment_idx == 1)
14558 f.value =
static_cast<double>(val);
14561 if (fragment_idx == 1)
14568 return (fragments[0].
value + fragments[1].
value) * pow(2.0, fragments[2].
value * exponent_sign) * sign;
14573 "in TOML 1.0.0 and earlier"sv);
14578 template <u
int64_t base>
14585 using traits = parse_integer_traits<base>;
14588 [[maybe_unused]] int64_t sign = 1;
14589 if constexpr (traits::is_signed)
14591 sign = *
cp == U
'-' ? -1 : 1;
14592 if (is_match(*
cp, U
'+', U
'-'))
14596 if constexpr (base == 10)
14598 if (!traits::is_digit(*
cp))
14609 if (*
cp != traits::prefix_codepoint)
14613 if (!traits::is_digit(*
cp))
14619 size_t length = {};
14621 while (!
is_eof() && !is_value_terminator(*
cp))
14625 if (!prev || !traits::is_digit(*prev))
14632 else if TOML_UNLIKELY(prev && *prev == U
'_' && !traits::is_digit(*
cp))
14639 digits[length++] =
static_cast<char>(
cp->bytes[0]);
14646 if (prev && *prev == U
'_')
14657 if constexpr (base == 16)
14658 result =
static_cast<int64_t
>(hex_to_dec(digits[0]));
14660 result =
static_cast<int64_t
>(digits[0] -
'0');
14662 if constexpr (traits::is_signed)
14669 const char*
end = digits + length;
14670 const char* msd = digits;
14671 if constexpr (base != 10)
14673 while (msd <
end && *msd ==
'0')
14689 traits::full_prefix,
14690 std::string_view{ digits, length },
14691 "' is not representable in 64 bits"sv);
14697 uint64_t power = 1;
14698 while (--
end >= msd)
14700 if constexpr (base == 16)
14703 result += power *
static_cast<uint64_t
>(*
end -
'0');
14710 static constexpr auto i64_max =
static_cast<uint64_t
>((std::numeric_limits<int64_t>::max)());
14713 traits::full_prefix,
14714 std::string_view{ digits, length },
14715 "' is not representable in 64 bits"sv);
14717 if constexpr (traits::is_signed)
14721 return (std::numeric_limits<int64_t>::min)();
14723 return static_cast<int64_t
>(
result) * sign;
14726 return static_cast<int64_t
>(
result);
14740 uint32_t digits[4];
14743 const auto year = digits[3] + digits[2] * 10u + digits[1] * 100u + digits[0] * 1000u;
14744 const auto is_leap_year = (year % 4u == 0u) && ((year % 100u != 0u) || (year % 400u == 0u));
14755 const auto month = digits[1] + digits[0] * 10u;
14756 if (month == 0u || month > 12u)
14758 const auto max_days_in_month = month == 2u
14759 ? (is_leap_year ? 29u : 28u)
14760 : (month == 4u || month == 6u || month == 9u || month == 11u ? 30u : 31u);
14771 const auto day = digits[1] + digits[0] * 10u;
14772 if (day == 0u || day > max_days_in_month)
14775 " (inclusive), saw "sv,
14778 if (!part_of_datetime && !
is_eof() && !is_value_terminator(*
cp))
14781 return { year, month, day };
14793 static constexpr size_t max_digits = 64;
14795 uint32_t digits[max_digits];
14800 const auto hour = digits[1] + digits[0] * 10u;
14813 const auto minute = digits[1] + digits[0] * 10u;
14816 auto time = toml::time{ hour, minute };
14821 if (
is_eof() || is_value_terminator(*
cp) || (part_of_datetime && is_match(*
cp, U
'+', U
'-', U
'Z', U
'z')))
14833 const auto second = digits[1] + digits[0] * 10u;
14839 if (
is_eof() || is_value_terminator(*
cp) || (part_of_datetime && is_match(*
cp, U
'+', U
'-', U
'Z', U
'z')))
14854 if (digit_count == max_digits && is_decimal_digit(*
cp))
14856 else if (!part_of_datetime && !is_value_terminator(*
cp))
14859 uint32_t
value = 0u;
14860 uint32_t place = 1u;
14861 for (
auto i = impl::min<size_t>(digit_count, 9u); i-- > 0u;)
14863 value += digits[i] * place;
14866 for (
auto i = digit_count; i < 9u; i++)
14886 if (!is_match(*
cp, U
' ', U
'T', U
't'))
14895 if (
is_eof() || is_value_terminator(*
cp))
14896 return { date,
time };
14900 if (is_match(*
cp, U
'Z', U
'z'))
14904 else if (is_match(*
cp, U
'+', U
'-'))
14909 int sign = *
cp == U
'-' ? -1 : 1;
14916 const auto hour = digits[1] + digits[0] * 10;
14929 const auto minute = digits[1] + digits[0] * 10;
14932 offset.
minutes =
static_cast<decltype(offset.minutes)
>((hour * 60 + minute) * sign);
14935 if (!
is_eof() && !is_value_terminator(*
cp))
14938 return { date,
time, offset };
14967 case U
'"': [[fallthrough]];
14972 const auto cp_upper =
static_cast<uint_least32_t
>(
cp->value) & ~0x20u;
14975 if (cp_upper == 70u || cp_upper == 84u)
14979 else if (cp_upper == 73u || cp_upper == 78u)
15001 " (TOML_MAX_NESTED_VALUES)"sv);
15010 else if (*
cp == U
'_')
15013 const auto begin_pos =
cp->position;
15043 has_colon = 1 << 8,
15045 has_minus = 1 << 10,
15047 begins_sign = 1 << 12,
15048 begins_digit = 1 << 13,
15049 begins_zero = 1 << 14,
15050 signs_msk = has_plus | has_minus,
15051 bdigit_msk = has_digits | begins_digit,
15052 bzero_msk = bdigit_msk | begins_zero,
15055 const auto has_any = [&](
auto t)
noexcept {
return (traits & t) != has_nothing; };
15056 const auto has_none = [&](
auto t)
noexcept {
return (traits & t) == has_nothing; };
15057 const auto add_trait = [&](
auto t)
noexcept { traits =
static_cast<value_traits>(traits | t); };
15061 if (is_decimal_digit(*
cp))
15063 add_trait(begins_digit);
15065 add_trait(begins_zero);
15067 else if (is_match(*
cp, U
'+', U
'-'))
15068 add_trait(begins_sign);
15074 size_t char_count = {}, advance_count = {};
15075 bool eof_while_scanning =
false;
15084 if (
const auto c = **
cp; c != U
'_')
15086 chars[char_count++] = c;
15088 if (is_decimal_digit(c))
15089 add_trait(has_digits);
15090 else if (is_ascii_letter(c))
15093 switch (
static_cast<char32_t>(c | 32u))
15096 if (char_count == 2u && has_any(begins_zero))
15101 if (char_count > 1u
15102 && has_none(has_b | has_o | has_p | has_t | has_x | has_z | has_colon)
15103 && (has_none(has_plus | has_minus) || has_any(begins_sign)))
15108 if (char_count == 2u && has_any(begins_zero))
15113 if (has_any(has_x))
15118 if ((char_count == 2u && has_any(begins_zero))
15119 || (char_count == 3u && has_any(begins_sign) && chars[1] == U
'0'))
15123 case U
't': add_trait(has_t);
break;
15124 case U
'z': add_trait(has_z);
break;
15127 else if (c <= U
':')
15132 case U
'+': add_trait(has_plus);
break;
15133 case U
'-': add_trait(has_minus);
break;
15134 case U
'.': add_trait(has_dot);
break;
15135 case U
':': add_trait(has_colon);
break;
15142 eof_while_scanning =
is_eof();
15145 && !is_value_terminator(*
cp));
15151 if (char_count == 10u
15152 && (traits | begins_zero) == (bzero_msk | has_minus)
15153 && chars[4] == U
'-'
15154 && chars[7] == U
'-'
15158 const auto pre_advance_count = advance_count;
15159 const auto pre_scan_traits = traits;
15160 chars[char_count++] = *
cp;
15163 const auto backpedal = [&]()
noexcept
15165 go_back(advance_count - pre_advance_count);
15166 advance_count = pre_advance_count;
15167 traits = pre_scan_traits;
15174 if (
is_eof() || !is_decimal_digit(*
cp))
15178 chars[char_count++] = *
cp;
15186 if (char_count == 12u)
15196 if (char_count == 1u)
15198 if (has_any(begins_digit))
15200 val.reset(
new value{
static_cast<int64_t
>(chars[0] - U
'0') });
15208 :
"could not determine value type"sv);
15218 if (has_any(has_p))
15220 else if (has_any(has_x | has_o | has_b))
15224 if (has_any(has_x))
15227 flags = value_flags::format_as_hexadecimal;
15229 else if (has_any(has_o))
15232 flags = value_flags::format_as_octal;
15237 flags = value_flags::format_as_binary;
15241 val.reset(
new value{ i });
15242 val->ref_cast<int64_t>().flags(flags);
15244 else if (has_any(has_e) || (has_any(begins_digit) && chars[1] == U
'.'))
15246 else if (has_any(begins_sign))
15249 if (char_count == 2u && has_any(has_digits))
15251 val.reset(
new value{
static_cast<int64_t
>(chars[1] - U
'0') * (chars[0] == U
'-' ? -1LL : 1LL) });
15258 if (is_decimal_digit(chars[1]) && chars[2] == U
'.')
15262 else if (is_match(chars[1], U
'i', U
'n', U
'I', U
'N'))
15274 switch (unwrap_enum(traits))
15278 case bzero_msk | has_b:
15280 val->ref_cast<int64_t>().flags(value_flags::format_as_binary);
15285 case bzero_msk | has_o:
15287 val->ref_cast<int64_t>().flags(value_flags::format_as_octal);
15295 case bzero_msk: [[fallthrough]];
15296 case bdigit_msk: [[fallthrough]];
15297 case begins_sign | has_digits | has_minus: [[fallthrough]];
15298 case begins_sign | has_digits | has_plus:
15305 static constexpr size_t max_numeric_value_length =
15307 if TOML_UNLIKELY(!eof_while_scanning && advance_count > max_numeric_value_length)
15309 max_numeric_value_length,
15318 case bzero_msk | has_x:
15320 val->ref_cast<int64_t>().flags(value_flags::format_as_hexadecimal);
15331 case bzero_msk | has_e: [[fallthrough]];
15332 case bzero_msk | has_e | has_minus: [[fallthrough]];
15333 case bzero_msk | has_e | has_plus: [[fallthrough]];
15334 case bzero_msk | has_dot: [[fallthrough]];
15335 case bzero_msk | has_dot | has_e: [[fallthrough]];
15336 case bzero_msk | has_dot | has_e | has_minus: [[fallthrough]];
15337 case bzero_msk | has_dot | has_e | has_plus: [[fallthrough]];
15345 case bdigit_msk | has_e: [[fallthrough]];
15346 case bdigit_msk | has_e | has_minus: [[fallthrough]];
15347 case bdigit_msk | has_e | has_plus: [[fallthrough]];
15348 case bdigit_msk | has_dot: [[fallthrough]];
15349 case bdigit_msk | has_dot | has_e: [[fallthrough]];
15350 case bdigit_msk | has_dot | has_e | has_minus: [[fallthrough]];
15351 case bdigit_msk | has_dot | has_e | has_plus: [[fallthrough]];
15358 case begins_sign | has_digits | has_e | has_plus: [[fallthrough]];
15359 case begins_sign | has_digits | has_dot | has_plus: [[fallthrough]];
15360 case begins_sign | has_digits | has_dot | has_e | has_plus: [[fallthrough]];
15361 case begins_sign | has_digits | has_dot | has_e | signs_msk: [[fallthrough]];
15368 case begins_sign | has_digits | has_e | has_minus: [[fallthrough]];
15369 case begins_sign | has_digits | has_e | signs_msk: [[fallthrough]];
15370 case begins_sign | has_digits | has_dot | has_minus: [[fallthrough]];
15371 case begins_sign | has_digits | has_dot | has_e | has_minus:
15379 case bzero_msk | has_x | has_p: [[fallthrough]];
15380 case bzero_msk | has_x | has_p | has_minus: [[fallthrough]];
15381 case bzero_msk | has_x | has_p | has_plus: [[fallthrough]];
15388 case begins_sign | has_digits | has_x | has_p | has_minus: [[fallthrough]];
15389 case begins_sign | has_digits | has_x | has_p | has_plus: [[fallthrough]];
15390 case begins_sign | has_digits | has_x | has_p | signs_msk: [[fallthrough]];
15394 case bzero_msk | has_x | has_dot | has_p: [[fallthrough]];
15395 case bzero_msk | has_x | has_dot | has_p | has_minus: [[fallthrough]];
15396 case bzero_msk | has_x | has_dot | has_p | has_plus: [[fallthrough]];
15403 case begins_sign | has_digits | has_x | has_dot | has_p | has_minus: [[fallthrough]];
15404 case begins_sign | has_digits | has_x | has_dot | has_p | has_plus: [[fallthrough]];
15405 case begins_sign | has_digits | has_x | has_dot | has_p | signs_msk:
15413 case bzero_msk | has_colon: [[fallthrough]];
15414 case bzero_msk | has_colon | has_dot: [[fallthrough]];
15415 case bdigit_msk | has_colon: [[fallthrough]];
15416 case bdigit_msk | has_colon | has_dot: val.reset(
new value{
parse_time() });
break;
15420 case bzero_msk | has_minus: [[fallthrough]];
15421 case bdigit_msk | has_minus: val.reset(
new value{
parse_date() });
break;
15436 case bzero_msk | has_minus | has_colon | has_t: [[fallthrough]];
15437 case bzero_msk | signs_msk | has_colon | has_t: [[fallthrough]];
15438 case bdigit_msk | has_minus | has_colon | has_t: [[fallthrough]];
15439 case bdigit_msk | signs_msk | has_colon | has_t: [[fallthrough]];
15446 case bzero_msk | has_minus | has_colon | has_dot | has_t: [[fallthrough]];
15447 case bzero_msk | signs_msk | has_colon | has_dot | has_t: [[fallthrough]];
15448 case bdigit_msk | has_minus | has_colon | has_dot | has_t: [[fallthrough]];
15449 case bdigit_msk | signs_msk | has_colon | has_dot | has_t: [[fallthrough]];
15456 case bzero_msk | has_minus | has_colon | has_z | has_t: [[fallthrough]];
15457 case bzero_msk | has_minus | has_colon | has_dot | has_z | has_t: [[fallthrough]];
15458 case bdigit_msk | has_minus | has_colon | has_z | has_t: [[fallthrough]];
15459 case bdigit_msk | has_minus | has_colon | has_dot | has_z | has_t:
15468 set_error_at(begin_pos,
"could not determine value type"sv);
15489 std::string_view key_segment;
15493 if (is_bare_key_character(*
cp))
15497 else if (is_string_delimiter(*
cp))
15499 const auto begin_pos =
cp->position;
15509 "multi-line strings are prohibited in "sv,
15515 key_segment = str.
value;
15530 key_buffer.push_back(key_segment, key_begin, key_end);
15568 bool is_arr =
false;
15582 if (had_leading_whitespace)
15584 "[[array-of-table]] brackets must be contiguous (i.e. [ [ this ] ] is prohibited)"sv);
15630 for (
size_t i = 0, e =
key_buffer.size() - 1u; i < e; i++)
15632 const std::string_view segment =
key_buffer[i];
15633 auto pit =
parent->lower_bound(segment);
15636 if (pit !=
parent->end() && pit->first == segment)
15638 node&
p = pit->second;
15640 if (
auto tbl =
p.as_table())
15646 "' into existing inline table"sv);
15660 if (!is_arr &&
p.type() == node_type::table)
15670 is_arr ?
"array-of-tables"sv :
"table"sv);
15679 p.source_ = { header_begin_pos, header_end_pos,
reader.source_path() };
15686 const auto last_segment =
key_buffer.back();
15687 auto it =
parent->lower_bound(last_segment);
15693 if (it !=
parent->end() && it->first == last_segment)
15695 node& matching_node = it->second;
15696 if (
auto arr = matching_node.as_array();
15700 tbl.source_ = { header_begin_pos, header_end_pos,
reader.source_path() };
15704 else if (
auto tbl = matching_node.as_table(); !is_arr && tbl && !
implicit_tables.empty())
15711 for (
auto& [_, child] : *tbl)
15713 if (!child.is_table() && !child.is_array_of_tables())
15724 tbl->source_.begin = header_begin_pos;
15725 tbl->source_.end = header_end_pos;
15732 if (!is_arr && matching_node.type() == node_type::table)
15735 "cannot redefine existing table '"sv,
15743 "cannot redefine existing "sv,
15744 to_sv(matching_node.type()),
15748 is_arr ?
"array-of-tables"sv :
"table"sv);
15762 it =
parent->emplace_hint<
array>(it, std::move(last_key));
15763 array& tbl_arr = it->second.ref_cast<
array>();
15765 tbl_arr.source_ = { header_begin_pos, header_end_pos,
reader.source_path() };
15768 tbl.source_ = { header_begin_pos, header_end_pos,
reader.source_path() };
15775 it =
parent->emplace_hint<
table>(it, std::move(last_key));
15777 tbl.source_ = { header_begin_pos, header_end_pos,
reader.source_path() };
15813 if (is_value_terminator(*
cp))
15820 for (
size_t i = 0; i <
key_buffer.size() - 1u; i++)
15822 const std::string_view segment =
key_buffer[i];
15826 if (pit != tbl->
end() && pit->first == segment)
15828 table*
p = pit->second.as_table();
15836 "cannot redefine existing "sv,
15837 to_sv(pit->second.type()),
15838 " as dotted key-value pair"sv);
15850 p.source_ = pit->first.source();
15859 const std::string_view last_segment =
key_buffer.back();
15861 if (it != tbl->
end() && it->first == last_segment)
15863 set_error(
"cannot redefine existing "sv,
15864 to_sv(it->second.type()),
15879 tbl->emplace_hint<node_ptr>(it, std::move(last_key), std::move(val));
15908 else if (is_bare_key_character(*
cp) || is_string_delimiter(*
cp))
15923 set_error(
"expected keys, tables, whitespace or comments, saw '"sv,
to_sv(
cp),
"'"sv);
15928 root.source_.end = eof_pos;
15929 if (current_table && current_table != &
root && current_table->source_.
end <= current_table->source_.
begin)
15930 current_table->source_.
end = eof_pos;
15935 const auto type = nde.type();
15936 if (type > node_type::array)
15939 if (type == node_type::table)
15941 auto& tbl = nde.ref_cast<
table>();
15942 if (tbl.is_inline())
15946 auto end = nde.source_.end;
15947 for (
auto&& [k, v] : tbl)
15951 if (
end < v.source_.end)
15952 end = v.source_.end;
15957 auto& arr = nde.ref_cast<
array>();
15958 auto end = nde.source_.end;
15959 for (
auto&& v : arr)
15962 if (
end < v.source_.end)
15963 end = v.source_.end;
15965 nde.source_.end =
end;
15979#if !TOML_EXCEPTIONS
15999 return { std::move(
root) };
16023 node_ptr arr_ptr{
new array{} };
16031 parse_type prev = parse_type::none;
16042 if (prev == parse_type::val)
16044 prev = parse_type::comma;
16052 else if (*
cp == U
']')
16061 if (prev == parse_type::val)
16066 prev = parse_type::val;
16071 if (!arr.capacity())
16073 arr.emplace_back<node_ptr>(std::move(val));
16092 node_ptr tbl_ptr{
new table{} };
16103 parse_type prev = parse_type::none;
16122 if (prev == parse_type::kvp)
16124 prev = parse_type::comma;
16132 else if (*
cp == U
'}')
16136 if (prev == parse_type::comma)
16147 else if (is_string_delimiter(*
cp) || is_bare_key_character(*
cp))
16149 if (prev == parse_type::kvp)
16153 prev = parse_type::kvp;
16170#undef TOML_RETURNS_BY_THROWING
16171#undef advance_and_return_if_error
16172#undef advance_and_return_if_error_or_eof
16173#undef assert_not_eof
16174#undef assert_not_error
16177#undef parse_error_break
16178#undef push_parse_scope
16179#undef push_parse_scope_1
16180#undef push_parse_scope_2
16181#undef return_after_error
16182#undef return_if_eof
16183#undef return_if_error
16184#undef return_if_error_or_eof
16185#undef set_error_and_return
16186#undef set_error_and_return_default
16187#undef set_error_and_return_if_eof
16188#undef utf8_buffered_reader_error_check
16189#undef utf8_reader_error
16190#undef utf8_reader_error_check
16191#undef utf8_reader_return_after_error
16199 return impl::parser{ std::move(reader) };
16204 parse_result do_parse_file(std::string_view file_path)
16207#define TOML_PARSE_FILE_ERROR(msg, path) \
16208 throw parse_error{ msg, source_position{}, std::make_shared<const std::string>(std::move(path)) }
16210#define TOML_PARSE_FILE_ERROR(msg, path) \
16211 return parse_result \
16215 msg, source_position{}, std::make_shared<const std::string>(std::move(path)) \
16220 std::string file_path_str(file_path);
16223 std::ifstream file;
16225 file.rdbuf()->pubsetbuf(file_buffer,
sizeof(file_buffer));
16227 file.open(impl::widen(file_path_str).c_str(), std::ifstream::in | std::ifstream::binary | std::ifstream::ate);
16229 file.open(file_path_str, std::ifstream::in | std::ifstream::binary | std::ifstream::ate);
16231 if (!file.is_open())
16235 const auto file_size = file.tellg();
16236 if (file_size == -1)
16238 file.seekg(0, std::ifstream::beg);
16241 constexpr auto large_file_threshold = 1024 * 1024 * 2;
16242 if (file_size <= large_file_threshold)
16244 std::vector<char> file_data;
16245 file_data.resize(
static_cast<size_t>(file_size));
16246 file.read(file_data.data(),
static_cast<std::streamsize
>(file_size));
16247 return parse(std::string_view{ file_data.data(), file_data.size() }, std::move(file_path_str));
16252 return parse(file, std::move(file_path_str));
16254#undef TOML_PARSE_FILE_ERROR
16266 return TOML_ANON_NAMESPACE::do_parse(TOML_ANON_NAMESPACE::utf8_reader{ doc, source_path });
16272 return TOML_ANON_NAMESPACE::do_parse(TOML_ANON_NAMESPACE::utf8_reader{ doc, std::move(source_path) });
16278 return TOML_ANON_NAMESPACE::do_parse(TOML_ANON_NAMESPACE::utf8_reader{ doc, source_path });
16284 return TOML_ANON_NAMESPACE::do_parse(TOML_ANON_NAMESPACE::utf8_reader{ doc, std::move(source_path) });
16290 return TOML_ANON_NAMESPACE::do_parse_file(file_path);
16298 return TOML_ANON_NAMESPACE::do_parse(TOML_ANON_NAMESPACE::utf8_reader{ doc, source_path });
16304 return TOML_ANON_NAMESPACE::do_parse(TOML_ANON_NAMESPACE::utf8_reader{ doc, std::move(source_path) });
16310 std::string file_path_str;
16311 file_path_str.resize(file_path.length());
16312 memcpy(file_path_str.data(), file_path.data(), file_path.length());
16313 return TOML_ANON_NAMESPACE::do_parse_file(file_path_str);
16318#if TOML_ENABLE_WINDOWS_COMPAT
16323 return TOML_ANON_NAMESPACE::do_parse(TOML_ANON_NAMESPACE::utf8_reader{ doc, impl::narrow(source_path) });
16329 return TOML_ANON_NAMESPACE::do_parse(TOML_ANON_NAMESPACE::utf8_reader{ doc, impl::narrow(source_path) });
16335 return TOML_ANON_NAMESPACE::do_parse_file(impl::narrow(file_path));
16340#if TOML_HAS_CHAR8 && TOML_ENABLE_WINDOWS_COMPAT
16345 return TOML_ANON_NAMESPACE::do_parse(TOML_ANON_NAMESPACE::utf8_reader{ doc, impl::narrow(source_path) });
16354#undef TOML_OVERALIGNED
16357#pragma pop_macro("min")
16358#pragma pop_macro("max")
16360#pragma inline_recursion(off)
16369#if TOML_ENABLE_FORMATTERS
16374#pragma inline_recursion(on)
16376#pragma push_macro("min")
16377#pragma push_macro("max")
16387 line_breaks = 1u << 0,
16389 control_chars = 1u << 2,
16390 single_quotes = 1u << 3,
16391 non_bare = 1u << 4,
16392 non_ascii = 1u << 5,
16394 all = (non_ascii << 1u) - 1u
16401 const formatter_constants& constants,
16403#if TOML_ENABLE_PARSER && !TOML_EXCEPTIONS
16404 :
source_{ source_pr && *source_pr ? &source_pr->table() : source_node },
16405 result_{ source_pr },
16407 : source_{ source_pr ? source_pr : source_node },
16409 constants_{ &constants },
16414 config_.
flags = (config_.
flags | constants_->mandatory_flags) & ~constants_->ignored_flags;
16416 indent_columns_ = {};
16417 for (
auto c : config_.
indent)
16418 indent_columns_ += c ==
'\t' ? 4u : 1u;
16420 int_format_mask_ = config_.
flags
16421 & (format_flags::allow_binary_integers | format_flags::allow_octal_integers
16422 | format_flags::allow_hexadecimal_integers);
16452 for (
int i = 0; i <
indent_; i++)
16475 bool allow_multi_line,
16477 bool allow_literal_whitespace)
16486 formatted_string_traits traits = {};
16489 traits |= formatted_string_traits::non_bare;
16493 if (
is_ascii(str.data(), str.length()))
16499 case '\n': traits |= formatted_string_traits::line_breaks;
break;
16500 case '\t': traits |= formatted_string_traits::tabs;
break;
16501 case '\'': traits |= formatted_string_traits::single_quotes;
break;
16505 traits |= formatted_string_traits::control_chars;
16507 if (!is_ascii_bare_key_character(
static_cast<char32_t>(c)))
16508 traits |= formatted_string_traits::non_bare;
16513 static constexpr auto all_ascii_traits =
16514 formatted_string_traits::all & ~formatted_string_traits::non_ascii;
16515 if (traits == all_ascii_traits)
16523 traits |= formatted_string_traits::non_ascii;
16524 utf8_decoder decoder;
16528 const auto bad_unicode = [&]()
noexcept
16530 traits &= ~formatted_string_traits::line_breaks;
16531 traits |= formatted_string_traits::control_chars | formatted_string_traits::non_bare;
16532 unicode_allowed =
false;
16545 if (!decoder.has_code_point())
16548 switch (decoder.codepoint)
16550 case U
'\n': traits |= formatted_string_traits::line_breaks;
break;
16551 case U
'\t': traits |= formatted_string_traits::tabs;
break;
16552 case U
'\'': traits |= formatted_string_traits::single_quotes;
break;
16556 || is_non_ascii_vertical_whitespace(decoder.codepoint))
16557 traits |= formatted_string_traits::control_chars;
16559 if (!is_bare_key_character(decoder.codepoint))
16560 traits |= formatted_string_traits::non_bare;
16566 if (decoder.needs_more_input())
16572 & (formatted_string_traits::line_breaks | formatted_string_traits::tabs
16573 | formatted_string_traits::single_quotes)))
16574 traits |= formatted_string_traits::non_bare;
16578 if (!(traits & formatted_string_traits::non_bare)
16579 && (!(traits & formatted_string_traits::non_ascii) || unicode_allowed))
16587 const auto multi_line = allow_literal_whitespace
16588 && allow_multi_line
16590 && !!(traits & formatted_string_traits::line_breaks);
16594 && !(traits & formatted_string_traits::control_chars)
16595 && (!(traits & formatted_string_traits::single_quotes) || multi_line)
16596 && (!(traits & formatted_string_traits::tabs) || real_tabs_allowed)
16597 && (!(traits & formatted_string_traits::line_breaks) || multi_line)
16598 && (!(traits & formatted_string_traits::non_ascii) || unicode_allowed);
16603 const auto quot = multi_line ? R
"(''')"sv : R"(')"sv;
16614 if (!(traits & formatted_string_traits::non_ascii))
16642 utf8_decoder decoder;
16643 const char* cp_start = str.data();
16644 const char* cp_end = cp_start;
16651 if (decoder.error())
16653 while (cp_start != cp_end)
16657 static_cast<uint8_t
>(*cp_start),
16658 value_flags::format_as_hexadecimal,
16666 if (!decoder.has_code_point())
16669 switch (decoder.codepoint)
16684 else if (decoder.codepoint > U
'\x7F'
16685 && (!unicode_allowed || is_non_ascii_vertical_whitespace(decoder.codepoint)))
16687 if (
static_cast<uint_least32_t
>(decoder.codepoint) > 0xFFFFu)
16691 static_cast<uint_least32_t
>(decoder.codepoint),
16692 value_flags::format_as_hexadecimal,
16699 static_cast<uint_least32_t
>(decoder.codepoint),
16700 value_flags::format_as_hexadecimal,
16731 static constexpr auto value_flags_mask =
16732 value_flags::format_as_binary | value_flags::format_as_octal | value_flags::format_as_hexadecimal;
16734 const auto fmt = val.flags() & value_flags_mask;
16737 case value_flags::format_as_binary:
16746 case value_flags::format_as_octal:
16755 case value_flags::format_as_hexadecimal:
16775 const std::string_view* inf_nan =
nullptr;
16778 case fp_class::neg_inf: inf_nan = &
constants_->float_neg_inf;
break;
16779 case fp_class::pos_inf: inf_nan = &
constants_->float_pos_inf;
break;
16780 case fp_class::nan: inf_nan = &
constants_->float_nan;
break;
16785 !!(
config_.flags & format_flags::relaxed_float_precision));
16792 if (!!(
config_.flags & format_flags::quote_infinities_and_nans))
16810 if (!!(
config_.flags & format_flags::quote_dates_and_times))
16820 if (!!(
config_.flags & format_flags::quote_dates_and_times))
16830 if (!!(
config_.flags & format_flags::quote_dates_and_times))
16844 case node_type::integer:
print(*
reinterpret_cast<const value<int64_t>*
>(&val_node));
break;
16845 case node_type::floating_point:
print(*
reinterpret_cast<const value<double>*
>(&val_node));
break;
16846 case node_type::boolean:
print(*
reinterpret_cast<const value<bool>*
>(&val_node));
break;
16847 case node_type::date:
print(*
reinterpret_cast<const value<date>*
>(&val_node));
break;
16848 case node_type::time:
print(*
reinterpret_cast<const value<time>*
>(&val_node));
break;
16854#if TOML_ENABLE_PARSER && !TOML_EXCEPTIONS
16871 bool
formatter::dump_failed_parse_result()
16881#pragma pop_macro("min")
16882#pragma pop_macro("max")
16884#pragma inline_recursion(off)
16893#if TOML_ENABLE_FORMATTERS
16898#pragma inline_recursion(on)
16900#pragma push_macro("min")
16901#pragma push_macro("max")
16911 size_t toml_formatter_count_inline_columns(
const node& node,
size_t line_wrap_cols)
noexcept
16913 switch (node.type())
16915 case node_type::table:
16917 auto& tbl = *
reinterpret_cast<const table*
>(&node);
16920 size_t weight = 3u;
16921 for (
auto&& [k, v] : tbl)
16923 weight += k.length() + toml_formatter_count_inline_columns(v, line_wrap_cols) + 2u;
16924 if (weight >= line_wrap_cols)
16930 case node_type::array:
16932 auto&
arr = *
reinterpret_cast<const array*
>(&node);
16935 size_t weight = 3u;
16936 for (
auto& elem : arr)
16938 weight += toml_formatter_count_inline_columns(elem, line_wrap_cols) + 2u;
16939 if (weight >= line_wrap_cols)
16945 case node_type::string:
16950 return str.length() + 2u;
16953 case node_type::integer:
16958 size_t weight = {};
16964 return weight +
static_cast<size_t>(log10(
static_cast<double>(val))) + 1u;
16967 case node_type::floating_point:
16972 size_t weight = 2u;
16978 return weight +
static_cast<size_t>(log10(val)) + 1u;
16982 case node_type::boolean:
return 5u;
16983 case node_type::date: [[fallthrough]];
16984 case node_type::time:
return 10u;
16985 case node_type::date_time:
return 30u;
16994 bool toml_formatter_forces_multiline(
const node& node,
size_t line_wrap_cols,
size_t starting_column_bias)
noexcept
16996 return (toml_formatter_count_inline_columns(node, line_wrap_cols) + starting_column_bias) >= line_wrap_cols;
17004 void toml_formatter::print_pending_table_separator()
17006 if (pending_table_separator_)
17008 print_newline(
true);
17009 print_newline(
true);
17010 pending_table_separator_ =
false;
17015 void toml_formatter::print(
const key& k)
17017 print_string(k.str(),
false,
true,
false);
17021 void toml_formatter::print_inline(
const table& tbl)
17025 print_unformatted(
"{}"sv);
17029 print_unformatted(
"{ "sv);
17031 bool first =
false;
17032 for (
auto&& [k, v] : tbl)
17035 print_unformatted(
", "sv);
17040 print_unformatted(
"="sv);
17042 print_unformatted(
" = "sv);
17044 const auto type = v.type();
17048 case node_type::table: print_inline(*
reinterpret_cast<const table*
>(&v));
break;
17049 case node_type::array:
print(*
reinterpret_cast<const array*
>(&v));
break;
17050 default: print_value(v, type);
17054 print_unformatted(
" }"sv);
17058 void toml_formatter::print(
const array& arr)
17062 print_unformatted(
"[]"sv);
17066 const auto original_indent = indent();
17067 const auto multiline = TOML_ANON_NAMESPACE::toml_formatter_forces_multiline(
17070 indent_columns() *
static_cast<size_t>(original_indent < 0 ? 0 : original_indent));
17072 print_unformatted(
"["sv);
17076 if (original_indent < 0)
17082 print_unformatted(
' ');
17084 for (
size_t i = 0; i <
arr.size(); i++)
17088 print_unformatted(
',');
17090 print_unformatted(
' ');
17095 print_newline(
true);
17100 const auto type = v.type();
17104 case node_type::table: print_inline(*
reinterpret_cast<const table*
>(&v));
break;
17105 case node_type::array:
print(*
reinterpret_cast<const array*
>(&v));
break;
17106 default: print_value(v, type);
17111 indent(original_indent);
17112 print_newline(
true);
17116 print_unformatted(
' ');
17118 print_unformatted(
"]"sv);
17122 void toml_formatter::print(
const table& tbl)
17124 static constexpr auto is_non_inline_array_of_tables = [](
const node&
n)
noexcept
17126 const auto arr =
n.as_array();
17127 if (!arr || !
arr->is_array_of_tables())
17130 return !
reinterpret_cast<const table*
>(&(*arr)[0])->is_inline();
17134 for (
auto&& [k, v] : tbl)
17136 const auto type = v.type();
17137 if ((type == node_type::table && !
reinterpret_cast<const table*
>(&v)->is_inline())
17138 || (type == node_type::array && is_non_inline_array_of_tables(v)))
17141 pending_table_separator_ =
true;
17146 print_unformatted(
"="sv);
17148 print_unformatted(
" = "sv);
17152 case node_type::table: print_inline(*
reinterpret_cast<const table*
>(&v));
break;
17153 case node_type::array:
print(*
reinterpret_cast<const array*
>(&v));
break;
17154 default: print_value(v, type);
17158 const auto print_key_path = [&]()
17161 for (
const auto k : key_path_)
17164 print_unformatted(
'.');
17170 for (
auto&& [k, v] : tbl)
17172 const auto type = v.type();
17173 if (type != node_type::table ||
reinterpret_cast<const table*
>(&v)->is_inline())
17175 auto& child_tbl = *
reinterpret_cast<const table*
>(&v);
17179 size_t child_value_count{};
17180 size_t child_table_count{};
17181 size_t child_table_array_count{};
17182 for (
auto&& [child_k, child_v] : child_tbl)
17185 const auto child_type = child_v.type();
17187 switch (child_type)
17189 case node_type::table:
17190 if (
reinterpret_cast<const table*
>(&child_v)->is_inline())
17191 child_value_count++;
17193 child_table_count++;
17196 case node_type::array:
17197 if (is_non_inline_array_of_tables(child_v))
17198 child_table_array_count++;
17200 child_value_count++;
17203 default: child_value_count++;
17206 bool skip_self =
false;
17207 if (child_value_count == 0u && (child_table_count > 0u || child_table_array_count > 0u))
17210 key_path_.push_back(&k);
17214 print_pending_table_separator();
17218 print_unformatted(
"["sv);
17220 print_unformatted(
"]"sv);
17221 pending_table_separator_ =
true;
17226 key_path_.pop_back();
17232 for (
auto&& [k, v] : tbl)
17234 if (!is_non_inline_array_of_tables(v))
17236 auto&
arr = *
reinterpret_cast<const array*
>(&v);
17240 key_path_.push_back(&k);
17242 for (
size_t i = 0; i <
arr.size(); i++)
17244 print_pending_table_separator();
17246 print_unformatted(
"[["sv);
17248 print_unformatted(
"]]"sv);
17249 pending_table_separator_ =
true;
17250 print(*
reinterpret_cast<const table*
>(&arr[i]));
17253 key_path_.pop_back();
17260 void toml_formatter::print()
17262 if (dump_failed_parse_result())
17265 switch (
auto source_type = source().type())
17267 case node_type::table:
17269 auto& tbl = *
reinterpret_cast<const table*
>(&source());
17270 if (tbl.is_inline())
17280 case node_type::array:
print(*
reinterpret_cast<const array*
>(&source()));
break;
17282 default: print_value(source(), source_type);
17289#pragma pop_macro("min")
17290#pragma pop_macro("max")
17292#pragma inline_recursion(off)
17301#if TOML_ENABLE_FORMATTERS
17306#pragma inline_recursion(on)
17308#pragma push_macro("min")
17309#pragma push_macro("max")
17317 void json_formatter::print(
const toml::table& tbl)
17321 print_unformatted(
"{}"sv);
17325 print_unformatted(
'{');
17329 bool first =
false;
17330 for (
auto&& [k, v] : tbl)
17333 print_unformatted(
',');
17335 print_newline(
true);
17338 print_string(k.str(),
false);
17340 print_unformatted(
":"sv);
17342 print_unformatted(
" : "sv);
17344 const auto type = v.type();
17348 case node_type::table:
print(*
reinterpret_cast<const table*
>(&v));
break;
17349 case node_type::array:
print(*
reinterpret_cast<const array*
>(&v));
break;
17350 default: print_value(v, type);
17355 print_newline(
true);
17358 print_unformatted(
'}');
17362 void json_formatter::print(
const toml::array& arr)
17366 print_unformatted(
"[]"sv);
17370 print_unformatted(
'[');
17373 for (
size_t i = 0; i <
arr.size(); i++)
17376 print_unformatted(
',');
17377 print_newline(
true);
17381 const auto type = v.type();
17385 case node_type::table:
print(*
reinterpret_cast<const table*
>(&v));
break;
17386 case node_type::array:
print(*
reinterpret_cast<const array*
>(&v));
break;
17387 default: print_value(v, type);
17392 print_newline(
true);
17394 print_unformatted(
']');
17398 void json_formatter::print()
17400 if (dump_failed_parse_result())
17403 switch (
auto source_type = source().type())
17405 case node_type::table:
print(*
reinterpret_cast<const table*
>(&source()));
break;
17406 case node_type::array:
print(*
reinterpret_cast<const array*
>(&source()));
break;
17407 default: print_value(source(), source_type);
17414#pragma pop_macro("min")
17415#pragma pop_macro("max")
17417#pragma inline_recursion(off)
17426#if TOML_ENABLE_FORMATTERS
17431#pragma inline_recursion(on)
17433#pragma push_macro("min")
17434#pragma push_macro("max")
17450 bool contains_newline =
false;
17451 for (
auto c = str->c_str(), e = str->c_str() + str->length(); c < e && !contains_newline; c++)
17452 contains_newline = *c ==
'\n';
17454 if (contains_newline)
17456 print_unformatted(
"|-"sv);
17460 auto line_end = str->c_str() - 1u;
17461 const auto end = str->c_str() + str->length();
17462 while (line_end !=
end)
17464 auto line_start = line_end + 1u;
17465 line_end = line_start;
17466 for (; line_end !=
end && *line_end !=
'\n'; line_end++)
17473 print_unformatted(std::string_view{ line_start,
static_cast<size_t>(line_end - line_start) });
17480 print_string(*str,
false,
true);
17484 void yaml_formatter::print(
const toml::table& tbl,
bool parent_is_array)
17488 print_unformatted(
"{}"sv);
17494 for (
auto&& [k, v] : tbl)
17496 if (!parent_is_array)
17501 parent_is_array =
false;
17503 print_string(k.str(),
false,
true);
17505 print_unformatted(
":"sv);
17507 print_unformatted(
": "sv);
17509 const auto type = v.type();
17513 case node_type::table:
print(*
reinterpret_cast<const table*
>(&v));
break;
17514 case node_type::array:
print(*
reinterpret_cast<const array*
>(&v));
break;
17515 case node_type::string: print_yaml_string(*
reinterpret_cast<const value<std::string>*
>(&v));
break;
17516 default: print_value(v, type);
17524 void yaml_formatter::print(
const toml::array& arr,
bool parent_is_array)
17528 print_unformatted(
"[]"sv);
17534 for (
auto&& v : arr)
17536 if (!parent_is_array)
17541 parent_is_array =
false;
17543 print_unformatted(
"- "sv);
17545 const auto type = v.type();
17549 case node_type::table:
print(*
reinterpret_cast<const table*
>(&v),
true);
break;
17550 case node_type::array:
print(*
reinterpret_cast<const array*
>(&v),
true);
break;
17551 case node_type::string: print_yaml_string(*
reinterpret_cast<const value<std::string>*
>(&v));
break;
17552 default: print_value(v, type);
17560 void yaml_formatter::print()
17562 if (dump_failed_parse_result())
17565 switch (
auto source_type = source().type())
17567 case node_type::table:
17569 print(*
reinterpret_cast<const table*
>(&source()));
17572 case node_type::array:
print(*
reinterpret_cast<const array*
>(&source()));
break;
17574 case node_type::string: print_yaml_string(*
reinterpret_cast<const value<std::string>*
>(&source()));
break;
17576 default: print_value(source(), source_type);
17583#pragma pop_macro("min")
17584#pragma pop_macro("max")
17586#pragma inline_recursion(off)
17598#if TOML_UNDEF_MACROS
17599#undef TOML_ABI_NAMESPACE_BOOL
17600#undef TOML_ABI_NAMESPACE_END
17601#undef TOML_ABI_NAMESPACE_START
17602#undef TOML_ABI_NAMESPACES
17603#undef TOML_ABSTRACT_INTERFACE
17604#undef TOML_ALWAYS_INLINE
17605#undef TOML_ANON_NAMESPACE
17606#undef TOML_ANON_NAMESPACE_END
17607#undef TOML_ANON_NAMESPACE_START
17608#undef TOML_ARCH_AMD64
17609#undef TOML_ARCH_ARM
17610#undef TOML_ARCH_ARM32
17611#undef TOML_ARCH_ARM64
17612#undef TOML_ARCH_BITNESS
17613#undef TOML_ARCH_ITANIUM
17614#undef TOML_ARCH_X64
17615#undef TOML_ARCH_X86
17617#undef TOML_ASSERT_ASSUME
17619#undef TOML_ASYMMETRICAL_EQUALITY_OPS
17622#undef TOML_CLANG_VERSION
17623#undef TOML_CLOSED_ENUM
17624#undef TOML_CLOSED_FLAGS_ENUM
17625#undef TOML_COMPILER_HAS_EXCEPTIONS
17626#undef TOML_COMPILER_HAS_RTTI
17628#undef TOML_CONST_GETTER
17629#undef TOML_CONST_INLINE_GETTER
17630#undef TOML_CONSTRAINED_TEMPLATE
17632#undef TOML_DECLSPEC
17633#undef TOML_DELETE_DEFAULTS
17634#undef TOML_DISABLE_ARITHMETIC_WARNINGS
17635#undef TOML_DISABLE_CODE_ANALYSIS_WARNINGS
17636#undef TOML_DISABLE_SPAM_WARNINGS
17637#undef TOML_DISABLE_SPAM_WARNINGS_CLANG_10
17638#undef TOML_DISABLE_SPAM_WARNINGS_CLANG_11
17639#undef TOML_DISABLE_SUGGEST_ATTR_WARNINGS
17640#undef TOML_DISABLE_SWITCH_WARNINGS
17641#undef TOML_DISABLE_WARNINGS
17643#undef TOML_EMPTY_BASES
17644#undef TOML_ENABLE_IF
17645#undef TOML_ENABLE_WARNINGS
17646#undef TOML_EVAL_BOOL_0
17647#undef TOML_EVAL_BOOL_1
17648#undef TOML_EXTERNAL_LINKAGE
17649#undef TOML_FLAGS_ENUM
17650#undef TOML_FLOAT_CHARCONV
17651#undef TOML_FLOAT128
17652#undef TOML_FLOAT16_DIG
17653#undef TOML_FLOAT16_LIMITS_SET
17654#undef TOML_FLOAT16_MANT_DIG
17655#undef TOML_FLOAT16_MAX_10_EXP
17656#undef TOML_FLOAT16_MAX_EXP
17657#undef TOML_FLOAT16_MIN_10_EXP
17658#undef TOML_FLOAT16_MIN_EXP
17660#undef TOML_GCC_LIKE
17661#undef TOML_HAS_ATTR
17662#undef TOML_HAS_BUILTIN
17663#undef TOML_HAS_CHAR8
17664#undef TOML_HAS_CPP_ATTR
17665#undef TOML_HAS_CUSTOM_OPTIONAL_TYPE
17666#undef TOML_HAS_FEATURE
17667#undef TOML_HAS_INCLUDE
17668#undef TOML_HAS_SSE2
17669#undef TOML_HAS_SSE4_1
17670#undef TOML_HIDDEN_CONSTRAINT
17673#undef TOML_IMPL_NAMESPACE_END
17674#undef TOML_IMPL_NAMESPACE_START
17675#undef TOML_IMPLEMENTATION
17676#undef TOML_INCLUDE_WINDOWS_H
17677#undef TOML_INLINE_GETTER
17678#undef TOML_INT_CHARCONV
17680#undef TOML_INTELLISENSE
17681#undef TOML_INTERNAL_LINKAGE
17682#undef TOML_LANG_AT_LEAST
17683#undef TOML_LANG_EFFECTIVE_VERSION
17684#undef TOML_LANG_HIGHER_THAN
17685#undef TOML_LANG_UNRELEASED
17687#undef TOML_LIFETIME_HOOKS
17689#undef TOML_LIKELY_CASE
17691#undef TOML_MAKE_FLAGS
17692#undef TOML_MAKE_FLAGS_
17693#undef TOML_MAKE_FLAGS_1
17694#undef TOML_MAKE_FLAGS_2
17695#undef TOML_MAKE_STRING
17696#undef TOML_MAKE_STRING_1
17697#undef TOML_MAKE_VERSION
17699#undef TOML_MSVC_LIKE
17700#undef TOML_NAMESPACE
17701#undef TOML_NEVER_INLINE
17702#undef TOML_NODISCARD
17703#undef TOML_NODISCARD_CTOR
17704#undef TOML_OPEN_ENUM
17705#undef TOML_OPEN_FLAGS_ENUM
17706#undef TOML_PARSER_TYPENAME
17707#undef TOML_POP_WARNINGS
17708#undef TOML_PRAGMA_CLANG
17709#undef TOML_PRAGMA_CLANG_GE_10
17710#undef TOML_PRAGMA_CLANG_GE_11
17711#undef TOML_PRAGMA_CLANG_GE_8
17712#undef TOML_PRAGMA_CLANG_GE_9
17713#undef TOML_PRAGMA_GCC
17714#undef TOML_PRAGMA_ICC
17715#undef TOML_PRAGMA_MSVC
17717#undef TOML_PURE_GETTER
17718#undef TOML_PURE_INLINE_GETTER
17719#undef TOML_PUSH_WARNINGS
17720#undef TOML_REQUIRES
17721#undef TOML_RETURN_BOOL_FROM_FOR_EACH_BROKEN
17722#undef TOML_RETURN_BOOL_FROM_FOR_EACH_BROKEN_MESSAGE
17723#undef TOML_SA_LIST_BEG
17724#undef TOML_SA_LIST_END
17725#undef TOML_SA_LIST_NEW
17726#undef TOML_SA_LIST_NXT
17727#undef TOML_SA_LIST_SEP
17728#undef TOML_SA_NATIVE_VALUE_TYPE_LIST
17729#undef TOML_SA_NEWLINE
17730#undef TOML_SA_NODE_TYPE_LIST
17731#undef TOML_SA_UNWRAPPED_NODE_TYPE_LIST
17732#undef TOML_SA_VALUE_EXACT_FUNC_MESSAGE
17733#undef TOML_SA_VALUE_FUNC_MESSAGE
17734#undef TOML_SA_VALUE_MESSAGE_CONST_CHAR8
17735#undef TOML_SA_VALUE_MESSAGE_U8STRING_VIEW
17736#undef TOML_SA_VALUE_MESSAGE_WSTRING
17737#undef TOML_SIMPLE_STATIC_ASSERT_MESSAGES
17738#undef TOML_TRIVIAL_ABI
17741#undef TOML_UNLIKELY
17742#undef TOML_UNLIKELY_CASE
17743#undef TOML_UNREACHABLE
uint8_t byte
Minimal Arduino.h stub for native unit tests.
static route_t * find(uint16_t pin)
TOML_NODISCARD_CTOR parse_error(std::string &&desc, source_region &&src) noexcept
TOML_NODISCARD_CTOR parse_error(std::string &&desc, const source_region &src) noexcept
friend std::ostream & operator<<(std::ostream &lhs, const parse_error &rhs)
TOML_NODISCARD const source_region & source() const noexcept
TOML_NODISCARD_CTOR parse_error(std::string &&desc, const source_position &position, const source_path_ptr &path={}) noexcept
TOML_NODISCARD std::string_view description() const noexcept
TOML_NODISCARD iterator begin() noexcept
TOML_CONST_INLINE_GETTER table * as_table() noexcept final
TOML_NODISCARD_CTOR TOML_EXPORTED_MEMBER_FUNCTION array(const impl::array_init_elem *, const impl::array_init_elem *)
TOML_PURE_INLINE_GETTER node * get(size_t index) noexcept
const node & const_reference
TOML_PURE_GETTER bool is_homogeneous() const noexcept
TOML_EXPORTED_MEMBER_FUNCTION void reserve(size_t new_capacity)
TOML_NODISCARD friend bool operator==(const array &lhs, const std::initializer_list< T > &rhs) noexcept
TOML_CONST_INLINE_GETTER bool is_boolean() const noexcept final
std::disjunction< can_for_each< Func, Array, table >, can_for_each< Func, Array, array >, can_for_each< Func, Array, std::string >, can_for_each< Func, Array, int64_t >, can_for_each< Func, Array, double >, can_for_each< Func, Array, bool >, can_for_each< Func, Array, date >, can_for_each< Func, Array, time >, can_for_each< Func, Array, date_time > > can_for_each_any
TOML_CONST_INLINE_GETTER bool is_array() const noexcept final
TOML_CONST_INLINE_GETTER bool is_date_time() const noexcept final
TOML_NODISCARD friend bool operator==(const array &lhs, const std::vector< T > &rhs) noexcept
TOML_CONSTRAINED_TEMPLATE((sizeof...(ElemTypes) > 0||!std::is_same_v< impl::remove_cvref< ElemType >, array >), typename ElemType, typename... ElemTypes) TOML_NODISCARD_CTOR explicit array(ElemType &&val
TOML_EXPORTED_MEMBER_FUNCTION ~array() noexcept
TOML_EXPORTED_MEMBER_FUNCTION array & operator=(array &&rhs) noexcept
TOML_CONST_INLINE_GETTER toml::value< double > * as_floating_point() noexcept final
TOML_CONST_INLINE_GETTER const toml::value< bool > * as_boolean() const noexcept final
TOML_NODISCARD iterator end() noexcept
const array & for_each(Func &&visitor) const &noexcept(for_each_is_nothrow< Func &&, const array & >::value)
TOML_CONST_INLINE_GETTER bool is_string() const noexcept final
std::vector< impl::node_ptr > vector_type
std::conditional_t< std::is_invocable_v< Func, for_each_elem_ref< T, Array >, size_t >, std::is_nothrow_invocable< Func, for_each_elem_ref< T, Array >, size_t >, std::conditional_t< std::is_invocable_v< Func, size_t, for_each_elem_ref< T, Array > >, std::is_nothrow_invocable< Func, size_t, for_each_elem_ref< T, Array > >, std::conditional_t< std::is_invocable_v< Func, for_each_elem_ref< T, Array > >, std::is_nothrow_invocable< Func, for_each_elem_ref< T, Array > >, std::false_type > > > can_for_each_nothrow
TOML_NODISCARD const_iterator cbegin() const noexcept
TOML_CONST_INLINE_GETTER toml::value< std::string > * as_string() noexcept final
TOML_NODISCARD_CTOR array(std::false_type, std::initializer_list< impl::array_init_elem > elems)
void emplace_back_if_not_empty_view(T &&val, value_flags flags)
TOML_PURE_GETTER TOML_EXPORTED_MEMBER_FUNCTION bool is_homogeneous(node_type ntype, const node *&first_nonmatch) const noexcept final
TOML_EXPORTED_MEMBER_FUNCTION void insert_at_back(impl::node_ptr &&)
TOML_NODISCARD node & back() noexcept
array && prune(bool recursive=true) &&noexcept
TOML_NODISCARD size_t capacity() const noexcept
iterator insert(const_iterator pos, size_t count, ElemType &&val, value_flags flags=preserve_source_value_flags)
TOML_NODISCARD friend bool operator!=(const array &lhs, const array &rhs) noexcept
TOML_CONST_INLINE_GETTER bool is_floating_point() const noexcept final
TOML_CONST_INLINE_GETTER toml::value< bool > * as_boolean() noexcept final
TOML_PURE_INLINE_GETTER const node * get(size_t index) const noexcept
TOML_EXPORTED_MEMBER_FUNCTION iterator erase(const_iterator pos) noexcept
TOML_ASYMMETRICAL_EQUALITY_OPS(const array &, const std::vector< T > &, template< typename T >)
static TOML_NODISCARD bool equal_to_container(const array &lhs, const T &rhs) noexcept
array && for_each(Func &&visitor) &&noexcept(for_each_is_nothrow< Func &&, array && >::value)
TOML_NODISCARD TOML_EXPORTED_MEMBER_FUNCTION size_t total_leaf_count() const noexcept
decltype(auto) emplace_back(Args &&... args)
TOML_ASYMMETRICAL_EQUALITY_OPS(const array &, const std::initializer_list< T > &, template< typename T >)
TOML_NODISCARD const node & operator[](size_t index) const noexcept
TOML_NODISCARD const_iterator cend() const noexcept
std::disjunction< std::is_invocable< Func, for_each_elem_ref< T, Array >, size_t >, std::is_invocable< Func, size_t, for_each_elem_ref< T, Array > >, std::is_invocable< Func, for_each_elem_ref< T, Array > > > can_for_each
TOML_EXPORTED_MEMBER_FUNCTION void pop_back() noexcept
TOML_CONST_INLINE_GETTER const toml::value< time > * as_time() const noexcept final
TOML_CONST_INLINE_GETTER bool is_time() const noexcept final
TOML_NODISCARD TOML_EXPORTED_MEMBER_FUNCTION node & at(size_t index)
TOML_CONST_INLINE_GETTER const toml::value< date_time > * as_date_time() const noexcept final
TOML_CONST_INLINE_GETTER bool is_integer() const noexcept final
TOML_EXPORTED_MEMBER_FUNCTION void flatten_child(array &&child, size_t &dest_index) noexcept
TOML_EXPORTED_MEMBER_FUNCTION array & prune(bool recursive=true) &noexcept
TOML_EXPORTED_MEMBER_FUNCTION void clear() noexcept
TOML_CONST_INLINE_GETTER toml::value< int64_t > * as_integer() noexcept final
TOML_PURE_GETTER bool is_array_of_tables() const noexcept final
TOML_NODISCARD const_iterator begin() const noexcept
TOML_NODISCARD const_iterator end() const noexcept
TOML_CONST_INLINE_GETTER const array * as_array() const noexcept final
std::disjunction< std::negation< can_for_each< Func, Array, T > >, can_for_each_nothrow< Func, Array, T > > for_each_is_nothrow_one
iterator insert(const_iterator pos, std::initializer_list< ElemType > ilist, value_flags flags=preserve_source_value_flags)
const array && for_each(Func &&visitor) const &&noexcept(for_each_is_nothrow< Func &&, const array && >::value)
TOML_EXPORTED_MEMBER_FUNCTION iterator erase(const_iterator first, const_iterator last) noexcept
static void do_for_each(Func &&visitor, Array &&arr) noexcept(for_each_is_nothrow< Func &&, Array && >::value)
TOML_EXPORTED_MEMBER_FUNCTION void truncate(size_t new_size)
TOML_NODISCARD static TOML_EXPORTED_STATIC_FUNCTION bool TOML_CALLCONV equal(const array &, const array &) noexcept
std::conjunction< for_each_is_nothrow_one< Func, Array, table >, for_each_is_nothrow_one< Func, Array, array >, for_each_is_nothrow_one< Func, Array, std::string >, for_each_is_nothrow_one< Func, Array, int64_t >, for_each_is_nothrow_one< Func, Array, double >, for_each_is_nothrow_one< Func, Array, bool >, for_each_is_nothrow_one< Func, Array, date >, for_each_is_nothrow_one< Func, Array, time >, for_each_is_nothrow_one< Func, Array, date_time > > for_each_is_nothrow
TOML_NODISCARD friend bool operator==(const array &lhs, const array &rhs) noexcept
TOML_CONST_INLINE_GETTER toml::value< date_time > * as_date_time() noexcept final
TOML_CONST_INLINE_GETTER node_type type() const noexcept final
TOML_CONST_INLINE_GETTER const table * as_table() const noexcept final
TOML_EXPORTED_MEMBER_FUNCTION void preinsertion_resize(size_t idx, size_t count)
array & for_each(Func &&visitor) &noexcept(for_each_is_nothrow< Func &&, array & >::value)
TOML_CONST_INLINE_GETTER bool is_value() const noexcept final
TOML_NODISCARD node & operator[](size_t index) noexcept
TOML_NODISCARD bool empty() const noexcept
TOML_NODISCARD size_t max_size() const noexcept
TOML_CONST_INLINE_GETTER const toml::value< double > * as_floating_point() const noexcept final
TOML_CONST_INLINE_GETTER const toml::value< int64_t > * as_integer() const noexcept final
TOML_PURE_GETTER TOML_EXPORTED_MEMBER_FUNCTION bool is_homogeneous(node_type ntype) const noexcept final
TOML_CONST_INLINE_GETTER const toml::value< std::string > * as_string() const noexcept final
TOML_CONST_INLINE_GETTER toml::value< time > * as_time() noexcept final
ptrdiff_t difference_type
TOML_NODISCARD const node & at(size_t index) const
void resize(size_t new_size, ElemType &&default_init_val, value_flags default_init_flags=preserve_source_value_flags)
TOML_NODISCARD node & front() noexcept
TOML_EXPORTED_MEMBER_FUNCTION array & flatten() &
iterator replace(const_iterator pos, ElemType &&val, value_flags flags=preserve_source_value_flags)
typename vector_type::const_iterator const_vector_iterator
TOML_CONST_INLINE_GETTER const toml::value< date > * as_date() const noexcept final
TOML_CONST_INLINE_GETTER toml::value< date > * as_date() noexcept final
friend std::ostream & operator<<(std::ostream &lhs, const array &rhs)
TOML_CONST_INLINE_GETTER bool is_number() const noexcept final
impl::copy_cvref< impl::wrap_node< impl::remove_cvref< impl::unwrap_node< T > > >, Array > for_each_elem_ref
TOML_PURE_GETTER TOML_EXPORTED_MEMBER_FUNCTION bool is_homogeneous(node_type ntype, node *&first_nonmatch) noexcept final
const_array_iterator const_iterator
iterator emplace(const_iterator pos, Args &&... args)
iterator insert(const_iterator pos, Iter first, Iter last, value_flags flags=preserve_source_value_flags)
TOML_CONST_INLINE_GETTER array * as_array() noexcept final
TOML_NODISCARD impl::wrap_node< ElemType > * get_as(size_t index) noexcept
TOML_EXPORTED_MEMBER_FUNCTION void shrink_to_fit()
TOML_NODISCARD_CTOR TOML_EXPORTED_MEMBER_FUNCTION array() noexcept
TOML_NODISCARD const node & front() const noexcept
TOML_NODISCARD const node & back() const noexcept
TOML_NODISCARD size_t size() const noexcept
iterator insert(const_iterator pos, ElemType &&val, value_flags flags=preserve_source_value_flags)
TOML_CONST_INLINE_GETTER bool is_table() const noexcept final
TOML_NODISCARD const impl::wrap_node< ElemType > * get_as(size_t index) const noexcept
typename vector_type::iterator vector_iterator
TOML_CONST_INLINE_GETTER bool is_date() const noexcept final
void push_back(ElemType &&val, value_flags flags=preserve_source_value_flags)
TOML_EXPORTED_MEMBER_FUNCTION vector_iterator insert_at(const_vector_iterator, impl::node_ptr &&)
TOML_NODISCARD toml::table && table() &&noexcept
TOML_NODISCARD toml::table & table() &noexcept
TOML_NODISCARD node_view< const node > operator[](const toml::path &path) const noexcept
TOML_NODISCARD node_view< node > at_path(std::string_view path) noexcept
TOML_NODISCARD node_view< node > at_path(const toml::path &path) noexcept
TOML_NODISCARD const toml::table & table() const &noexcept
TOML_NODISCARD const_table_iterator begin() const noexcept
TOML_NODISCARD bool failed() const noexcept
friend std::ostream & operator<<(std::ostream &os, const parse_result &result)
TOML_NODISCARD_CTOR parse_result(parse_result &&res) noexcept
TOML_NODISCARD node_view< const node > at_path(const toml::path &path) const noexcept
TOML_NODISCARD table_iterator end() noexcept
TOML_NODISCARD_CTOR parse_result(toml::table &&tbl) noexcept
TOML_NODISCARD table_iterator begin() noexcept
const_table_iterator const_iterator
parse_result & operator=(parse_result &&rhs) noexcept
TOML_NODISCARD_CTOR parse_result() noexcept
TOML_NODISCARD node_view< node > operator[](std::string_view key) noexcept
TOML_NODISCARD const_table_iterator end() const noexcept
TOML_NODISCARD node_view< const node > operator[](std::string_view key) const noexcept
TOML_NODISCARD static TOML_ALWAYS_INLINE Type * get_as(storage_t &s) noexcept
TOML_NODISCARD_CTOR parse_result(parse_error &&err) noexcept
TOML_NODISCARD const_table_iterator cend() const noexcept
TOML_NODISCARD node_view< node > operator[](const toml::path &path) noexcept
TOML_NODISCARD parse_error && error() &&noexcept
TOML_NODISCARD const parse_error & error() const &noexcept
TOML_NODISCARD node_view< const node > at_path(std::string_view path) const noexcept
TOML_NODISCARD bool succeeded() const noexcept
TOML_NODISCARD parse_error & error() &noexcept
TOML_NODISCARD const_table_iterator cbegin() const noexcept
std::vector< table * > implicit_tables
TOML_NODISCARD key make_key(size_t segment_index) const
optional< parse_error > err
TOML_NODISCARD node_ptr parse_value_known_prefixes()
TOML_NODISCARD TOML_NEVER_INLINE date parse_date(bool part_of_datetime=false)
utf8_buffered_reader reader
parser(utf8_reader_interface &&reader_)
TOML_NODISCARD TOML_NEVER_INLINE bool parse_boolean()
TOML_NODISCARD TOML_NEVER_INLINE date_time parse_date_time()
TOML_RETURNS_BY_THROWING void set_error(const T &... reason) const
TOML_NODISCARD node_ptr parse_value()
TOML_NODISCARD node_ptr parse_inline_table()
parse_key_buffer key_buffer
std::string_view current_scope
std::string string_buffer
bool consume_leading_whitespace()
bool consume_rest_of_line()
std::string recording_buffer
TOML_NODISCARD node_ptr parse_array()
TOML_NODISCARD TOML_NEVER_INLINE double parse_float()
TOML_NODISCARD TOML_NEVER_INLINE int64_t parse_integer()
TOML_NODISCARD size_t consume_variable_length_digit_sequence(T *buffer, size_t max_len)
void go_back(size_t count=1) noexcept
TOML_NODISCARD bool consume_digit_sequence(T *digits, size_t len)
TOML_NODISCARD bool consume_expected_sequence(std::u32string_view seq)
bool recording_whitespace
TOML_NEVER_INLINE bool parse_key_value_pair_and_insert(table *tbl)
TOML_NODISCARD TOML_NEVER_INLINE std::string_view parse_basic_string(bool multi_line)
std::vector< array * > table_arrays
std::vector< table * > open_inline_tables
TOML_NODISCARD source_position current_position(source_index fallback_offset=0) const noexcept
TOML_NODISCARD TOML_NEVER_INLINE time parse_time(bool part_of_datetime=false)
TOML_NODISCARD TOML_NEVER_INLINE table * parse_table_header()
static constexpr size_t max_nested_values
const utf8_codepoint * cp
TOML_NODISCARD TOML_NEVER_INLINE double parse_inf_or_nan()
static void update_region_ends(node &nde) noexcept
TOML_NEVER_INLINE bool parse_key()
void stop_recording(size_t pop_bytes=0) noexcept
TOML_NODISCARD TOML_NEVER_INLINE std::string_view parse_literal_string(bool multi_line)
TOML_RETURNS_BY_THROWING TOML_NEVER_INLINE void set_error_at(source_position pos, const T &... reason) const
TOML_NODISCARD TOML_NEVER_INLINE parsed_string parse_string()
TOML_NODISCARD TOML_NEVER_INLINE std::string_view parse_bare_key_segment()
TOML_NODISCARD TOML_NEVER_INLINE double parse_hex_float()
bool consume_line_break()
void start_recording(bool include_current=true) noexcept
std::vector< table * > dotted_key_tables
TOML_NODISCARD_CTOR TOML_EXPORTED_MEMBER_FUNCTION path_component()
static void store_index(size_t index, storage_t &storage_) noexcept
TOML_NODISCARD size_t & index_ref() noexcept
TOML_EXPORTED_MEMBER_FUNCTION path_component & operator=(const path_component &rhs)
TOML_NODISCARD std::string & key_ref() noexcept
TOML_NODISCARD_CTOR TOML_EXPORTED_MEMBER_FUNCTION path_component(const path_component &pc)
TOML_PURE_GETTER const std::string & key() const noexcept
TOML_PURE_INLINE_GETTER friend bool operator==(const path_component &lhs, const path_component &rhs) noexcept
~path_component() noexcept
TOML_PURE_INLINE_GETTER friend bool operator!=(const path_component &lhs, const path_component &rhs) noexcept
path_component_type type_
static void store_key(std::string_view key, storage_t &storage_)
TOML_EXPORTED_MEMBER_FUNCTION path_component & operator=(std::string_view new_key)
TOML_EXPORTED_MEMBER_FUNCTION path_component & operator=(size_t new_index) noexcept
TOML_PURE_GETTER size_t index() const noexcept
TOML_NODISCARD_CTOR TOML_EXPORTED_MEMBER_FUNCTION path_component(size_t index) noexcept
TOML_PURE_GETTER static TOML_EXPORTED_STATIC_FUNCTION bool TOML_CALLCONV equal(const path_component &, const path_component &) noexcept
TOML_NODISCARD_CTOR TOML_EXPORTED_MEMBER_FUNCTION path_component(std::string_view key)
TOML_PURE_INLINE_GETTER path_component_type type() const noexcept
TOML_NODISCARD_CTOR TOML_EXPORTED_MEMBER_FUNCTION path_component(path_component &&pc) noexcept
TOML_EXPORTED_MEMBER_FUNCTION path_component & operator=(path_component &&rhs) noexcept
static TOML_PURE_INLINE_GETTER Type * get_as(storage_t &s) noexcept
TOML_NODISCARD TOML_ALWAYS_INLINE friend bool operator!=(std::string_view lhs, const path &rhs)
TOML_EXPORTED_MEMBER_FUNCTION void clear() noexcept
TOML_NODISCARD TOML_EXPORTED_MEMBER_FUNCTION path parent() const
TOML_EXPORTED_MEMBER_FUNCTION path & truncate(size_t n)
TOML_PURE_INLINE_GETTER friend bool operator!=(const path &lhs, const path &rhs) noexcept
TOML_NODISCARD TOML_ALWAYS_INLINE friend bool operator!=(const path &lhs, std::string_view rhs)
std::vector< path_component >::const_iterator const_iterator
TOML_PURE_INLINE_GETTER friend bool operator==(const path &lhs, const path &rhs) noexcept
TOML_PURE_INLINE_GETTER const path_component & operator[](size_t index) const noexcept
TOML_ALWAYS_INLINE friend std::ostream & operator<<(std::ostream &os, const path &rhs)
TOML_NODISCARD TOML_EXPORTED_MEMBER_FUNCTION path truncated(size_t n) const
TOML_PURE_INLINE_GETTER iterator end() noexcept
TOML_ALWAYS_INLINE path & append(std::string_view str)
TOML_EXPORTED_MEMBER_FUNCTION path & prepend(path &&)
std::vector< path_component >::iterator iterator
TOML_NODISCARD friend path operator+(const path &lhs, std::string_view rhs)
TOML_PURE_INLINE_GETTER size_t size() const noexcept
TOML_NODISCARD friend path operator+(std::string_view lhs, const path &rhs)
TOML_EXPORTED_MEMBER_FUNCTION void print_to(std::ostream &) const
TOML_NODISCARD TOML_EXPORTED_MEMBER_FUNCTION std::string str() const
TOML_EXPORTED_MEMBER_FUNCTION path & operator+=(path &&)
TOML_NODISCARD_CTOR path() noexcept=default
TOML_PURE_INLINE_GETTER iterator begin() noexcept
TOML_PURE_GETTER static TOML_EXPORTED_STATIC_FUNCTION bool TOML_CALLCONV equal(const path &, const path &) noexcept
TOML_PURE_INLINE_GETTER const_iterator begin() const noexcept
path & operator=(path &&) noexcept=default
TOML_PURE_INLINE_GETTER path_component & operator[](size_t index) noexcept
TOML_EXPORTED_MEMBER_FUNCTION path & prepend(std::string_view)
TOML_ALWAYS_INLINE path & append(const path &p)
std::vector< path_component > components_
TOML_EXPORTED_MEMBER_FUNCTION path & prepend(const path &)
TOML_PURE_INLINE_GETTER const_iterator end() const noexcept
TOML_NODISCARD TOML_ALWAYS_INLINE friend bool operator==(std::string_view lhs, const path &rhs)
TOML_PURE_INLINE_GETTER const_iterator cbegin() const noexcept
TOML_EXPORTED_MEMBER_FUNCTION path & operator+=(const path &)
TOML_PURE_INLINE_GETTER bool empty() const noexcept
TOML_NODISCARD TOML_EXPORTED_MEMBER_FUNCTION path leaf(size_t n=1) const
TOML_ALWAYS_INLINE path & assign(const path &p)
TOML_PURE_INLINE_GETTER const_iterator cend() const noexcept
TOML_NODISCARD friend path operator+(const path &lhs, const path &rhs)
TOML_EXPORTED_MEMBER_FUNCTION path & operator+=(std::string_view)
TOML_ALWAYS_INLINE path & assign(path &&p) noexcept
TOML_ALWAYS_INLINE path & append(path &&p)
path & operator=(const path &)=default
TOML_ALWAYS_INLINE path & assign(std::string_view str)
TOML_NODISCARD TOML_EXPORTED_MEMBER_FUNCTION path subpath(const_iterator start, const_iterator end) const
TOML_NODISCARD TOML_ALWAYS_INLINE friend bool operator==(const path &lhs, std::string_view rhs)
table_iterator & operator=(const table_iterator &rhs) noexcept
table_iterator & operator--() noexcept
TOML_NODISCARD proxy_type * get_proxy() const noexcept
table_proxy_pair< IsConst > value_type
TOML_NODISCARD_CTOR table_iterator(const table_iterator &other) noexcept
typename std::iterator_traits< map_iterator >::iterator_category iterator_category
table_iterator & operator++() noexcept
std::map< toml::key, node_ptr, std::less<> >::const_iterator const_map_iterator
TOML_NODISCARD_CTOR table_iterator(const table_iterator< false > &other) noexcept
table_proxy_pair< IsConst > proxy_type
TOML_PURE_INLINE_GETTER friend bool operator==(const table_iterator &lhs, const table_iterator &rhs) noexcept
TOML_NODISCARD_CTOR table_iterator() noexcept=default
table_iterator operator++(int) noexcept
std::conditional_t< IsConst, const_map_iterator, mutable_map_iterator > map_iterator
unsigned char proxy_[sizeof(proxy_type)]
typename std::iterator_traits< map_iterator >::difference_type difference_type
table_iterator operator--(int) noexcept
TOML_PURE_INLINE_GETTER pointer operator->() const noexcept
TOML_NODISCARD_CTOR table_iterator(const_map_iterator iter) noexcept
TOML_PURE_INLINE_GETTER friend bool operator!=(const table_iterator &lhs, const table_iterator &rhs) noexcept
TOML_PURE_INLINE_GETTER reference operator*() const noexcept
friend class table_iterator
std::map< toml::key, node_ptr, std::less<> >::iterator mutable_map_iterator
TOML_PURE_INLINE_GETTER const_iterator begin() const noexcept
std:: conditional_t< std::is_void_v< raw_value_type >, impl::emplaced_type_of< ValueArgs &&... >, raw_value_type > value_type
void insert(Iter begin, Iter end, value_flags flags=preserve_source_value_flags)
TOML_EXPORTED_MEMBER_FUNCTION table & prune(bool recursive=true) &noexcept
TOML_PURE_GETTER TOML_EXPORTED_MEMBER_FUNCTION bool is_homogeneous(node_type ntype, node *&first_nonmatch) noexcept final
typename map_type::const_iterator const_map_iterator
TOML_CONST_INLINE_GETTER bool is_date_time() const noexcept final
TOML_NODISCARD const node & at(std::string_view key) const
TOML_NODISCARD TOML_EXPORTED_MEMBER_FUNCTION node & at(std::string_view key)
std::disjunction< can_for_each< Func, Table, table >, can_for_each< Func, Table, array >, can_for_each< Func, Table, std::string >, can_for_each< Func, Table, int64_t >, can_for_each< Func, Table, double >, can_for_each< Func, Table, bool >, can_for_each< Func, Table, date >, can_for_each< Func, Table, time >, can_for_each< Func, Table, date_time > > can_for_each_any
TOML_CONST_INLINE_GETTER bool is_string() const noexcept final
TOML_PURE_INLINE_GETTER const node * get(std::string_view key) const noexcept
TOML_CONST_INLINE_GETTER const toml::value< std::string > * as_string() const noexcept final
impl::remove_cvref< impl::unwrap_node< value_type > > unwrapped_type
TOML_CONST_INLINE_GETTER bool is_number() const noexcept final
TOML_NODISCARD_CTOR TOML_EXPORTED_MEMBER_FUNCTION table() noexcept
iterator erase(const_iterator pos) noexcept
std::disjunction< std::is_invocable< Func, const key &, for_each_value_ref< T, Table > >, std::is_invocable< Func, for_each_value_ref< T, Table > > > can_for_each
std::conjunction< for_each_is_nothrow_one< Func, Table, table >, for_each_is_nothrow_one< Func, Table, array >, for_each_is_nothrow_one< Func, Table, std::string >, for_each_is_nothrow_one< Func, Table, int64_t >, for_each_is_nothrow_one< Func, Table, double >, for_each_is_nothrow_one< Func, Table, bool >, for_each_is_nothrow_one< Func, Table, date >, for_each_is_nothrow_one< Func, Table, time >, for_each_is_nothrow_one< Func, Table, date_time > > for_each_is_nothrow
table && for_each(Func &&visitor) &&noexcept(for_each_is_nothrow< Func &&, table && >::value)
TOML_CONST_INLINE_GETTER const toml::value< double > * as_floating_point() const noexcept final
TOML_CONST_INLINE_GETTER toml::value< bool > * as_boolean() noexcept final
TOML_PURE_GETTER TOML_EXPORTED_MEMBER_FUNCTION node * get(std::string_view key) noexcept
TOML_CONST_INLINE_GETTER const toml::value< int64_t > * as_integer() const noexcept final
table & for_each(Func &&visitor) &noexcept(for_each_is_nothrow< Func &&, table & >::value)
TOML_PURE_INLINE_GETTER bool empty() const noexcept
TOML_CONST_INLINE_GETTER const toml::value< time > * as_time() const noexcept final
TOML_PURE_GETTER bool contains(std::string_view key) const noexcept
TOML_NODISCARD_CTOR TOML_EXPORTED_MEMBER_FUNCTION table(const impl::table_init_pair *, const impl::table_init_pair *)
const table && for_each(Func &&visitor) const &&noexcept(for_each_is_nothrow< Func &&, const table && >::value)
TOML_PURE_GETTER TOML_EXPORTED_MEMBER_FUNCTION map_iterator get_lower_bound(std::string_view) noexcept
TOML_CONST_INLINE_GETTER bool is_array() const noexcept final
TOML_CONST_INLINE_GETTER node_type type() const noexcept final
TOML_CONST_INLINE_GETTER array * as_array() noexcept final
TOML_EXPORTED_MEMBER_FUNCTION map_iterator insert_with_hint(const_iterator, key &&, impl::node_ptr &&)
iterator erase(const_iterator begin, const_iterator end) noexcept
TOML_PURE_GETTER bool is_homogeneous() const noexcept
toml::const_table_iterator const_iterator
TOML_EXPORTED_MEMBER_FUNCTION table & operator=(table &&rhs) noexcept
TOML_EXPORTED_MEMBER_FUNCTION size_t erase(std::string_view key) noexcept
TOML_PURE_GETTER impl::wrap_node< T > * get_as(std::string_view key) noexcept
TOML_EXPORTED_MEMBER_FUNCTION map_iterator erase(const_map_iterator) noexcept
TOML_EXPORTED_MEMBER_FUNCTION void clear() noexcept
toml::table_iterator iterator
TOML_NODISCARD node_view< node > operator[](std::string_view key) noexcept
impl::remove_cvref< ValueType > raw_value_type
impl::copy_cvref< impl::wrap_node< impl::remove_cvref< impl::unwrap_node< T > > >, Table > for_each_value_ref
TOML_CONSTRAINED_TEMPLATE((is_key_or_convertible< KeyType && >||impl::is_wide_string< KeyType >), typename ValueType=void, typename KeyType, typename... ValueArgs) std
TOML_PURE_GETTER const_iterator lower_bound(std::string_view key) const noexcept
TOML_PURE_GETTER TOML_EXPORTED_MEMBER_FUNCTION bool is_homogeneous(node_type ntype) const noexcept final
TOML_CONST_INLINE_GETTER table * as_table() noexcept final
TOML_EXPORTED_MEMBER_FUNCTION table & operator=(const table &)
TOML_CONST_INLINE_GETTER toml::value< time > * as_time() noexcept final
TOML_PURE_INLINE_GETTER const_iterator end() const noexcept
TOML_CONST_INLINE_GETTER const toml::value< date_time > * as_date_time() const noexcept final
TOML_PURE_INLINE_GETTER iterator begin() noexcept
TOML_NODISCARD node_view< const node > operator[](std::string_view key) const noexcept
TOML_CONST_INLINE_GETTER bool is_table() const noexcept final
TOML_EXPORTED_MEMBER_FUNCTION ~table() noexcept
TOML_CONST_INLINE_GETTER bool is_value() const noexcept final
TOML_NODISCARD friend bool operator==(const table &lhs, const table &rhs) noexcept
TOML_CONST_INLINE_GETTER const table * as_table() const noexcept final
friend std::ostream & operator<<(std::ostream &lhs, const table &rhs)
TOML_CONST_INLINE_GETTER bool is_boolean() const noexcept final
TOML_CONSTRAINED_TEMPLATE((is_key_or_convertible< KeyType && >||impl::is_wide_string< KeyType >), typename KeyType, typename ValueType) std
TOML_PURE_GETTER TOML_EXPORTED_MEMBER_FUNCTION const_iterator find(std::string_view key) const noexcept
TOML_PURE_GETTER TOML_EXPORTED_MEMBER_FUNCTION iterator find(std::string_view key) noexcept
TOML_CONST_INLINE_GETTER toml::value< int64_t > * as_integer() noexcept final
const table & for_each(Func &&visitor) const &noexcept(for_each_is_nothrow< Func &&, const table & >::value)
table && prune(bool recursive=true) &&noexcept
TOML_CONST_INLINE_GETTER bool is_floating_point() const noexcept final
TOML_PURE_INLINE_GETTER const_iterator cbegin() const noexcept
TOML_CONST_INLINE_GETTER bool is_date() const noexcept final
TOML_EXPORTED_MEMBER_FUNCTION map_iterator erase(const_map_iterator, const_map_iterator) noexcept
TOML_PURE_INLINE_GETTER iterator end() noexcept
TOML_CONST_INLINE_GETTER toml::value< date > * as_date() noexcept final
std::map< toml::key, impl::node_ptr, std::less<> > map_type
TOML_CONSTRAINED_TEMPLATE((is_key_or_convertible< KeyType && >||impl::is_wide_string< KeyType >), typename ValueType=void, typename KeyType, typename... ValueArgs) iterator emplace_hint(const_iterator hint
TOML_PURE_INLINE_GETTER bool is_inline() const noexcept
TOML_CONST_INLINE_GETTER const array * as_array() const noexcept final
TOML_PURE_GETTER const impl::wrap_node< T > * get_as(std::string_view key) const noexcept
typename map_type::iterator map_iterator
KeyType ValueArgs && args
TOML_NODISCARD friend bool operator!=(const table &lhs, const table &rhs) noexcept
static void do_for_each(Func &&visitor, Table &&tbl) noexcept(for_each_is_nothrow< Func &&, Table && >::value)
TOML_CONST_INLINE_GETTER const toml::value< date > * as_date() const noexcept final
TOML_CONST_INLINE_GETTER toml::value< double > * as_floating_point() noexcept final
TOML_PURE_GETTER iterator lower_bound(std::string_view key) noexcept
TOML_CONST_INLINE_GETTER toml::value< date_time > * as_date_time() noexcept final
TOML_PURE_GETTER TOML_EXPORTED_MEMBER_FUNCTION bool is_homogeneous(node_type ntype, const node *&first_nonmatch) const noexcept final
TOML_PURE_GETTER bool is_array_of_tables() const noexcept final
TOML_CONST_INLINE_GETTER bool is_integer() const noexcept final
TOML_CONST_INLINE_GETTER const toml::value< bool > * as_boolean() const noexcept final
TOML_PURE_GETTER static TOML_EXPORTED_STATIC_FUNCTION bool TOML_CALLCONV equal(const table &, const table &) noexcept
std::conditional_t< std::is_invocable_v< Func, const key &, for_each_value_ref< T, Table > >, std::is_nothrow_invocable< Func, const key &, for_each_value_ref< T, Table > >, std::conditional_t< std::is_invocable_v< Func, for_each_value_ref< T, Table > >, std::is_nothrow_invocable< Func, for_each_value_ref< T, Table > >, std::false_type > > can_for_each_nothrow
void is_inline(bool val) noexcept
std::pair< const toml::key, impl::node_ptr > map_pair
TOML_PURE_INLINE_GETTER const_iterator cend() const noexcept
TOML_CONST_INLINE_GETTER bool is_time() const noexcept final
TOML_CONST_INLINE_GETTER toml::value< std::string > * as_string() noexcept final
iterator erase(iterator pos) noexcept
std::disjunction< std::negation< can_for_each< Func, Table, T > >, can_for_each_nothrow< Func, Table, T > > for_each_is_nothrow_one
TOML_PURE_INLINE_GETTER size_t size() const noexcept
static constexpr size_t history_buffer_size
struct utf8_buffered_reader::@061365031327232150223023347207336074216106371060 history_
utf8_reader_interface & reader_
utf8_codepoint buffer[history_buffer_size]
TOML_PURE_INLINE_GETTER const source_path_ptr & source_path() const noexcept
TOML_NODISCARD const utf8_codepoint * read_next() noexcept(!TOML_COMPILER_HAS_EXCEPTIONS)
TOML_NODISCARD bool peek_eof() const noexcept(!TOML_COMPILER_HAS_EXCEPTIONS)
const utf8_codepoint * head_
TOML_NODISCARD const utf8_codepoint * step_back(size_t count) noexcept
TOML_NODISCARD optional< parse_error > && error() noexcept
static constexpr size_t max_history_length
TOML_NODISCARD_CTOR utf8_buffered_reader(utf8_reader_interface &reader) noexcept
TOML_PURE_INLINE_GETTER constexpr bool peek_eof() const noexcept
TOML_NODISCARD_CTOR constexpr utf8_byte_stream(std::basic_string_view< Char > sv) noexcept
TOML_CONST_INLINE_GETTER constexpr bool error() const noexcept
TOML_PURE_INLINE_GETTER constexpr bool eof() const noexcept
std::basic_string_view< Char > source_
TOML_PURE_INLINE_GETTER bool eof() const noexcept
TOML_NODISCARD_CTOR utf8_byte_stream(std::istream &stream) noexcept(!TOML_COMPILER_HAS_EXCEPTIONS)
TOML_NODISCARD bool peek_eof() const noexcept(!TOML_COMPILER_HAS_EXCEPTIONS)
TOML_PURE_INLINE_GETTER bool error() const noexcept
TOML_NODISCARD_CTOR utf8_reader(U &&source, String &&source_path={}) noexcept(std::is_nothrow_constructible_v< utf8_byte_stream< T >, U && >)
struct utf8_reader::currently_decoding_t currently_decoding_
utf8_byte_stream< T > stream_
source_position next_pos_
source_path_ptr source_path_
optional< parse_error > err_
impl::utf8_decoder decoder_
TOML_NODISCARD optional< parse_error > && error() noexcept final
TOML_PURE_INLINE_GETTER const source_path_ptr & source_path() const noexcept final
bool read_next_block() noexcept(!TOML_COMPILER_HAS_EXCEPTIONS)
static constexpr size_t block_capacity
struct utf8_reader::codepoints_t codepoints_
TOML_NODISCARD bool peek_eof() const noexcept(!TOML_COMPILER_HAS_EXCEPTIONS) final
TOML_NODISCARD const utf8_codepoint * read_next() noexcept(!TOML_COMPILER_HAS_EXCEPTIONS) final
static emmc_status_t format(emmc_log_t *log)
static ActuatorControllerState state
static void start(gnss_frame_parser_t *p, uint8_t byte)
static const idle_config_t config
typename Container::iterator iterator
*brief create JSON pointer *sa reference_tokens const string_t const string_t & b
*brief append another JSON pointer at the end of this JSON pointer *sa ptr reference_tokens begin()
typename Container::const_iterator const_iterator
*brief create JSON pointer *sa reference_tokens const string_t & a
std::pair< iterator, bool > insert(value_type &&value)
*brief compares two JSON pointer for less than friend bool operator<(const json_pointer< RefStringTypeLhs > &lhs, const json_pointer< RefStringTypeRhs > &rhs) noexcept
size_type count(const key_type &key) const
*brief remove last reference token *sa JSON pointer has no parent
bool contains(const BasicJsonType *ptr) const
*brief create JSON pointer *sa reference_tokens end()
typename Container::value_type value_type
*brief compares two JSON pointers for inequality *sa RefStringTypeRhs friend bool operator!=(const json_pointer< RefStringTypeLhs > &lhs, const json_pointer< RefStringTypeRhs > &rhs) noexcept
static BasicJsonType::size_type array_index(const string_t &s)
*brief write string representation of the JSON pointer to stream *sa const json_pointer & ptr
std::pair< iterator, bool > emplace(const key_type &key, T &&t)
T & operator[](const key_type &key)
T & at(const key_type &key)
*brief compares two JSON pointers for equality *sa RefStringTypeRhs friend bool operator==(const json_pointer< RefStringTypeLhs > &lhs, const json_pointer< RefStringTypeRhs > &rhs) noexcept
*brief create a new JSON pointer by appending the right JSON pointer at the end of the left JSON pointer *sa const json_pointer & rhs
size_type erase(const key_type &key)
static void flatten(const string_t &reference_string, const BasicJsonType &value, BasicJsonType &result)
@ error
throw a parse_error exception in case of a tag
@ array
array (ordered collection of values)
List[Optional[float]] out(Iterable[float] values, Optional[int] digits=None)
np.ndarray arr(Optional[Iterable[Any]] values, Optional[int] n=None)
*brief user defined string literal for JSON values *sa std::size_t n
void reset(bool chip_present)
*brief exchanges the values of two JSON objects *sa nlohmann::NLOHMANN_BASIC_JSON_TPL &j2 noexcept(is_nothrow_move_constructible< nlohmann::NLOHMANN_BASIC_JSON_TPL >::value &&is_nothrow_move_assignable< nlohmann::NLOHMANN_BASIC_JSON_TPL >::value)
Table2D table(fn, x=(0.0, 1.0, 5), y=(0.0, 2.0, 4))
dict[str, object] node(str nid, str ctype, str label, **object data)
TOML_NODISCARD_CTOR array_init_elem(T &&val, value_flags flags=preserve_source_value_flags)
std::add_const_t< Dest > type
std::add_cv_t< Dest > type
std::add_volatile_t< Dest > type
std::add_lvalue_reference_t< Dest > type
std::add_rvalue_reference_t< Dest > type
TOML_NODISCARD_CTOR constexpr date_time(const toml::date &d) noexcept
TOML_PURE_INLINE_GETTER friend constexpr bool operator>(const date_time &lhs, const date_time &rhs) noexcept
TOML_PURE_INLINE_GETTER friend constexpr bool operator!=(const date_time &lhs, const date_time &rhs) noexcept
TOML_PURE_GETTER friend constexpr bool operator==(const date_time &lhs, const date_time &rhs) noexcept
TOML_PURE_GETTER friend constexpr bool operator<(const date_time &lhs, const date_time &rhs) noexcept
TOML_PURE_GETTER friend constexpr bool operator<=(const date_time &lhs, const date_time &rhs) noexcept
TOML_NODISCARD_CTOR date_time() noexcept=default
TOML_PURE_INLINE_GETTER constexpr bool is_local() const noexcept
TOML_PURE_INLINE_GETTER friend constexpr bool operator>=(const date_time &lhs, const date_time &rhs) noexcept
friend std::ostream & operator<<(std::ostream &lhs, const date_time &rhs)
TOML_NODISCARD_CTOR constexpr date_time(const toml::date &d, const toml::time &t, const toml::time_offset &off) noexcept
optional< toml::time_offset > offset
TOML_NODISCARD_CTOR constexpr date_time(const toml::time &t) noexcept
static constexpr auto type
static constexpr bool can_represent_native
static constexpr bool is_losslessly_convertible_to_native
static constexpr bool can_partially_represent_native
static constexpr bool is_native
~depth_counter_scope() noexcept
TOML_DELETE_DEFAULTS(depth_counter_scope)
TOML_NODISCARD_CTOR depth_counter_scope(size_t &depth) noexcept
std::conditional_t< is_one_of< T, node, node_view< node >, node_view< const node > >, void, typename inserted_type_of_< T >::type > type
typename emplaced_type_of_< remove_cvref< T > >::type type
void append(const T &arg) noexcept
static constexpr std::size_t buf_size
TOML_NODISCARD_CTOR error_builder(std::string_view scope) noexcept
TOML_DELETE_DEFAULTS(error_builder)
TOML_RETURNS_BY_THROWING auto finish(const source_position &pos, const source_path_ptr &source_path) const
char *const max_write_pos
const utf8_codepoint & cp
static constexpr int bits
static constexpr bool is_losslessly_convertible_to_native
static constexpr bool can_represent_native
static constexpr bool is_signed
static constexpr int digits10
static constexpr auto type
static constexpr bool is_native
static constexpr int digits
static constexpr bool can_partially_represent_native
typename inserted_type_of_< remove_cvref< T > >::type type
static constexpr auto type
static constexpr bool is_signed
static constexpr bool is_native
static constexpr bool can_partially_represent_native
TOML_NODISCARD static TOML_ALWAYS_INLINE U && make(U &&val) noexcept
static constexpr bool is_native
static constexpr bool is_losslessly_convertible_to_native
static constexpr bool can_partially_represent_native
static constexpr auto type
static constexpr bool can_represent_native
static constexpr auto value
static constexpr auto value
static constexpr auto value
static constexpr auto value
std::add_const_t< T > type
std::add_volatile_t< std::add_const_t< T > > type
std::add_volatile_t< T > type
std::add_const_t< typename node_wrapper< T >::type > type
std::add_const_t< std::add_volatile_t< typename node_wrapper< T >::type > > type
value< std::string > type
std::add_volatile_t< typename node_wrapper< T >::type > type
static constexpr auto full_prefix
static constexpr auto scope_qualifier
static constexpr auto is_signed
static constexpr auto is_digit
static constexpr auto max_digits
static constexpr auto max_digits
static constexpr auto is_signed
static constexpr auto full_prefix
static constexpr auto scope_qualifier
static constexpr auto prefix
static constexpr auto is_digit
static constexpr auto prefix_codepoint
static constexpr auto prefix
static constexpr auto full_prefix
static constexpr auto is_digit
static constexpr auto prefix_codepoint
static constexpr auto is_signed
static constexpr auto scope_qualifier
static constexpr auto max_digits
static constexpr auto max_digits
static constexpr auto prefix_codepoint
static constexpr auto is_signed
static constexpr auto prefix
static constexpr auto is_digit
static constexpr auto scope_qualifier
static constexpr auto full_prefix
TOML_PURE_INLINE_GETTER size_t size() const noexcept
std::vector< std::pair< size_t, size_t > > segments
std::vector< source_position > starts
std::vector< source_position > ends
TOML_PURE_INLINE_GETTER std::string_view back() const noexcept
void push_back(std::string_view segment, source_position b, source_position e)
TOML_PURE_INLINE_GETTER bool empty() const noexcept
TOML_PURE_INLINE_GETTER std::string_view operator[](size_t i) const noexcept
unsigned char bytes[size]
static constexpr size_t align
static constexpr size_t size
TOML_DELETE_DEFAULTS(parse_scope)
TOML_NODISCARD_CTOR parse_scope(std::string_view ¤t_scope, std::string_view new_scope) noexcept
std::string_view & storage_
unsigned char bytes[size]
static constexpr size_t align
static constexpr size_t size
static constexpr bool can_represent_native
static constexpr bool is_losslessly_convertible_to_native
TOML_PURE_GETTER friend constexpr bool operator>=(const source_position &lhs, const source_position &rhs) noexcept
TOML_PURE_INLINE_GETTER friend constexpr bool operator!=(const source_position &lhs, const source_position &rhs) noexcept
TOML_PURE_GETTER friend constexpr bool operator==(const source_position &lhs, const source_position &rhs) noexcept
static TOML_PURE_GETTER constexpr uint64_t pack(const source_position &pos) noexcept
TOML_PURE_GETTER friend constexpr bool operator>(const source_position &lhs, const source_position &rhs) noexcept
TOML_PURE_GETTER friend constexpr bool operator<(const source_position &lhs, const source_position &rhs) noexcept
TOML_PURE_GETTER friend constexpr bool operator<=(const source_position &lhs, const source_position &rhs) noexcept
friend std::ostream & operator<<(std::ostream &lhs, const source_position &rhs)
friend std::ostream & operator<<(std::ostream &lhs, const source_region &rhs)
static constexpr auto type
static constexpr bool is_native
static constexpr bool is_losslessly_convertible_to_native
static constexpr bool can_partially_represent_native
static constexpr bool can_represent_native
TOML_NODISCARD_CTOR table_init_pair(K &&k, V &&v, value_flags flags=preserve_source_value_flags)
std::vector< table * > & tables
~table_vector_scope() noexcept
TOML_DELETE_DEFAULTS(table_vector_scope)
TOML_NODISCARD_CTOR table_vector_scope(std::vector< table * > &tables_, table &tbl)
TOML_PURE_INLINE_GETTER friend constexpr bool operator<=(time_offset lhs, time_offset rhs) noexcept
friend std::ostream & operator<<(std::ostream &lhs, const time_offset &rhs)
TOML_PURE_INLINE_GETTER friend constexpr bool operator>(time_offset lhs, time_offset rhs) noexcept
TOML_PURE_INLINE_GETTER friend constexpr bool operator<(time_offset lhs, time_offset rhs) noexcept
TOML_PURE_INLINE_GETTER friend constexpr bool operator>=(time_offset lhs, time_offset rhs) noexcept
TOML_PURE_INLINE_GETTER friend constexpr bool operator==(time_offset lhs, time_offset rhs) noexcept
TOML_PURE_INLINE_GETTER friend constexpr bool operator!=(time_offset lhs, time_offset rhs) noexcept
TOML_NODISCARD_CTOR time_offset() noexcept=default
TOML_CONSTRAINED_TEMPLATE((impl::all_integral< H, M, S, NS >), typename H, typename M, typename S=uint8_t, typename NS=uint32_t) TOML_NODISCARD_CTOR const expr time(H h
TOML_NODISCARD_CTOR time() noexcept=default
std::underlying_type_t< T > type
static constexpr bool is_losslessly_convertible_to_native
static constexpr bool can_represent_native
TOML_PURE_INLINE_GETTER constexpr const char32_t & operator*() const noexcept
TOML_OVERALIGNED utf8_codepoint buffer[block_capacity]
virtual TOML_NODISCARD optional< parse_error > && error() noexcept=0
virtual TOML_NODISCARD const source_path_ptr & source_path() const noexcept=0
virtual ~utf8_reader_interface() noexcept=default
virtual TOML_NODISCARD bool peek_eof() const noexcept(!TOML_COMPILER_HAS_EXCEPTIONS)=0
virtual TOML_NODISCARD const utf8_codepoint * read_next() noexcept(!TOML_COMPILER_HAS_EXCEPTIONS)=0
value_traits< underlying_type< T > > type
default_value_traits type
static void make(uint8_t *out, uint64_t ts, uint8_t type, uint16_t sensor, float ref)
static bool has_error(const Config &c, const std::string &needle)
enum TOML_OPEN_FLAGS_ENUM format_as_hexadecimal
typename underlying_type_< T >::type underlying_type
#define TOML_ANON_NAMESPACE_END
#define TOML_PARSER_TYPENAME
#define TOML_NODISCARD_CTOR
toml_formatter default_formatter
constexpr bool is_constructible_or_convertible
enum TOML_OPEN_FLAGS_ENUM value_flags
constexpr size_t charconv_buffer_length< int16_t >
#define TOML_DISABLE_ARITHMETIC_WARNINGS
#define TOML_HAS_CUSTOM_OPTIONAL_TYPE
constexpr size_t charconv_buffer_length< uint8_t >
#define TOML_LIFETIME_HOOKS
#define POXY_IMPLEMENTATION_DETAIL(...)
constexpr bool value_retrieval_is_nothrow
#define TOML_UNLIKELY(...)
#define TOML_ABI_NAMESPACE_BOOL(cond, T, F)
#define TOML_SA_UNWRAPPED_NODE_TYPE_LIST
#define TOML_RETURNS_BY_THROWING
enum TOML_OPEN_FLAGS_ENUM format_as_octal
enum TOML_CLOSED_FLAGS_ENUM allow_multi_line_strings
enum TOML_CLOSED_FLAGS_ENUM quote_dates_and_times
#define TOML_PUSH_WARNINGS
#define TOML_CONSTRAINED_TEMPLATE(condition,...)
#define TOML_SA_NODE_TYPE_LIST
TOML_PURE_GETTER fp_class fpclassify(const double &val) noexcept
constexpr node_type node_type_of
#define TOML_ABI_NAMESPACE_END
enum TOML_CLOSED_FLAGS_ENUM allow_unicode_strings
#define TOML_NEVER_INLINE
#define TOML_INTERNAL_LINKAGE
TOML_PURE_GETTER auto find(Iterator start, Iterator end, const T &needle) noexcept -> decltype(&(*start))
typename value_traits< T >::native_type native_type_of
#define set_error_and_return_if_eof(...)
constexpr size_t charconv_buffer_length< int64_t >
std::common_type_t< std::make_signed_t< T >... > common_signed_type
#define TOML_EXPORTED_CLASS
constexpr bool is_boolean
enum TOML_CLOSED_FLAGS_ENUM allow_real_tabs_in_strings
TOML_EXPORTED_FREE_FUNCTION void TOML_CALLCONV print_to_stream(std::ostream &, std::string_view)
#define TOML_UNLIKELY_CASE
constexpr bool is_floating_point
constexpr bool can_partially_represent_native
#define TOML_EXTERNAL_LINKAGE
TOML_NODISCARD node_ptr make_node(T &&val, value_flags flags=preserve_source_value_flags)
typename node_wrapper< std::remove_reference_t< T > >::type wrap_node
#define set_error_and_return_default(...)
#define TOML_DISABLE_WARNINGS
TOML_NODISCARD TOML_EXPORTED_FREE_FUNCTION parse_result TOML_CALLCONV parse_file(std::string_view file_path)
enum TOML_CLOSED_FLAGS_ENUM allow_octal_integers
#define TOML_ANON_NAMESPACE_START
#define TOML_DISABLE_SWITCH_WARNINGS
TOML_PURE_GETTER bool is_ascii(const char *str, size_t len) noexcept
typename copy_cv_< Dest, Src >::type copy_cv
enum TOML_CLOSED_FLAGS_ENUM allow_binary_integers
#define return_if_error_or_eof(...)
#define TOML_CONST_GETTER
#define TOML_LANG_UNRELEASED
#define TOML_DISABLE_SUGGEST_ATTR_WARNINGS
constexpr std::string_view control_char_escapes[]
TOML_NODISCARD TOML_EXPORTED_FREE_FUNCTION parse_result TOML_CALLCONV parse(std::string_view doc, std::string_view source_path={})
TOML_INTERNAL_LINKAGE void print_floating_point_to_stream(std::ostream &stream, T val, value_flags format, bool relaxed_precision)
#define TOML_COMPILER_HAS_EXCEPTIONS
constexpr bool first_is_same
constexpr size_t charconv_buffer_length< uint16_t >
constexpr bool all_integral
#define utf8_reader_error(...)
utf8_reader(std::basic_string_view< Char >, std::string_view) -> utf8_reader< std::basic_string_view< Char > >
TOML_PURE_GETTER TOML_INTERNAL_LINKAGE std::string_view to_sv(node_type val) noexcept
enum TOML_CLOSED_FLAGS_ENUM quote_infinities_and_nans
constexpr bool is_chronological
constexpr bool is_date_time
enum TOML_CLOSED_FLAGS_ENUM allow_hexadecimal_integers
#define TOML_PARSE_FILE_ERROR(msg, path)
constexpr size_t charconv_buffer_length< int8_t >
typename emplaced_type_of_< remove_cvref< T >... >::type emplaced_type_of
#define TOML_EXPORTED_STATIC_FUNCTION
#define TOML_POP_WARNINGS
#define return_if_error(...)
enum TOML_CLOSED_FLAGS_ENUM allow_literal_strings
TOML_NODISCARD bool TOML_CALLCONV parse_path(std::string_view, void *, parse_path_callback< std::string_view >, parse_path_callback< size_t >)
constexpr bool is_integer
#define TOML_ASSERT(expr)
TOML_CONST_GETTER optional< T > node_integer_cast(int64_t val) noexcept
constexpr bool is_losslessly_convertible_to_native
#define return_after_error(...)
TOML_NODISCARD TOML_EXPORTED_FREE_FUNCTION node_view< const node > TOML_CALLCONV at_path(const node &root, std::string_view path) noexcept
std::shared_ptr< const std::string > source_path_ptr
constexpr bool always_false
enum TOML_CLOSED_FLAGS_ENUM terse_key_value_pairs
#define TOML_ENABLE_WINDOWS_COMPAT
constexpr bool is_natively_one_of
#define TOML_ABI_NAMESPACE_START(name)
#define push_parse_scope(scope)
#define utf8_reader_error_check(...)
constexpr size_t charconv_buffer_length< uint32_t >
#define TOML_ASSERT_ASSUME(expr)
#define TOML_NAMESPACE_START
#define TOML_MAX_NESTED_VALUES
#define assert_not_error()
constexpr size_t charconv_buffer_length< int32_t >
POXY_IMPLEMENTATION_DETAIL(impl::table_iterator< true >) const_table_iterator
#define TOML_OPEN_FLAGS_ENUM
#define advance_and_return_if_error_or_eof(...)
constexpr bool is_container
constexpr size_t charconv_buffer_length< uint64_t >
#define TOML_PRAGMA_CLANG(decl)
#define TOML_NAMESPACE_END
#define TOML_CLOSED_FLAGS_ENUM
constexpr value_flags preserve_source_value_flags
#define TOML_HIDDEN_CONSTRAINT(condition,...)
enum TOML_CLOSED_FLAGS_ENUM relaxed_float_precision
#define TOML_PURE_INLINE_GETTER
enum TOML_OPEN_FLAGS_ENUM format_as_binary
#define TOML_ALWAYS_INLINE
#define TOML_IMPL_NAMESPACE_END
constexpr bool is_node_view
#define TOML_DISABLE_SPAM_WARNINGS
enum TOML_CLOSED_FLAGS_ENUM format_flags
#define TOML_EXPORTED_FREE_FUNCTION
#define parse_error_break()
#define utf8_buffered_reader_error_check(...)
node_view(const T &) -> node_view< const node >
#define TOML_IMPL_NAMESPACE_START
#define TOML_ASYMMETRICAL_EQUALITY_OPS(LHS, RHS,...)
#define TOML_SA_VALUE_FUNC_MESSAGE(type_arg)
#define advance_and_return_if_error(...)
constexpr size_t charconv_buffer_length< double >
#define TOML_CONST_INLINE_GETTER
#define TOML_ENABLE_WARNINGS
constexpr bool can_represent_native
TOML_INTERNAL_LINKAGE constexpr auto utf8_byte_order_mark
value(T) -> value< impl::native_type_of< impl::remove_cvref< T > > >
constexpr size_t charconv_buffer_length< float >
std::basic_ostream< Char > & operator<<(std::basic_ostream< Char > &lhs, node_type rhs)
#define TOML_EXPORTED_MEMBER_FUNCTION
TOML_INTERNAL_LINKAGE void print_integer_to_stream(std::ostream &stream, T val, value_flags format={}, size_t min_digits=0)
enum TOML_CLOSED_FLAGS_ENUM indent_sub_tables
copy_ref< copy_ref< copy_cv< std::remove_reference_t< Dest >, std::remove_reference_t< Src > >, Dest >, Src > copy_cvref
POXY_IMPLEMENTATION_DETAIL(impl::array_iterator< true >) const_array_iterator
#define TOML_SA_NATIVE_VALUE_TYPE_LIST
typename node_unwrapper< std::remove_reference_t< T > >::type unwrap_node
enum TOML_CLOSED_FLAGS_ENUM indentation
inserter(T &&) -> inserter< T && >
constexpr bool is_key_or_convertible
#define TOML_MAKE_FLAGS(T)
#define TOML_SA_VALUE_EXACT_FUNC_MESSAGE(type_arg)
enum TOML_CLOSED_FLAGS_ENUM indent_array_elements
TOML_INTERNAL_LINKAGE void concatenate(char *&write_pos, char *const buf_end, const T &arg) noexcept
constexpr std::string_view node_type_friendly_names[]
constexpr bool is_wide_string
#define utf8_reader_return_after_error(...)
#define TOML_ASSUME(expr)
typename copy_ref_< Dest, Src >::type copy_ref
void print_to_stream_bookended(std::ostream &stream, const T &val, const U &bookend)
#define TOML_ABSTRACT_INTERFACE