//# This file is a part of toml++ and is subject to the the terms of the MIT license. //# Copyright (c) 2019-2020 Mark Gillard //# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text. #pragma once ////////// CONFIGURATION // clang-format off #ifdef TOML_CONFIG_HEADER #include TOML_CONFIG_HEADER #undef TOML_CONFIG_HEADER #endif #if !defined(TOML_ALL_INLINE) || (defined(TOML_ALL_INLINE) && TOML_ALL_INLINE) #undef TOML_ALL_INLINE #define TOML_ALL_INLINE 1 #endif #if defined(TOML_IMPLEMENTATION) || TOML_ALL_INLINE || defined(__INTELLISENSE__) #undef TOML_IMPLEMENTATION #define TOML_IMPLEMENTATION 1 #else #define TOML_IMPLEMENTATION 0 #endif #ifndef TOML_API #define TOML_API #endif #ifndef TOML_CHAR_8_STRINGS #define TOML_CHAR_8_STRINGS 0 #endif #ifndef TOML_UNRELEASED_FEATURES #define TOML_UNRELEASED_FEATURES 1 #endif #ifndef TOML_LARGE_FILES #define TOML_LARGE_FILES 0 #endif #ifndef TOML_UNDEF_MACROS #define TOML_UNDEF_MACROS 1 #endif //TOML_ASSERT ////////// COMPILER & ENVIRONMENT STUFF #ifndef __cplusplus #error toml++ is a C++ library. #endif #ifdef __clang__ #define TOML_PUSH_WARNINGS _Pragma("clang diagnostic push") #define TOML_DISABLE_SWITCH_WARNINGS _Pragma("clang diagnostic ignored \"-Wswitch\"") #define TOML_DISABLE_INIT_WARNINGS _Pragma("clang diagnostic ignored \"-Wmissing-field-initializers\"") #define TOML_DISABLE_ALL_WARNINGS _Pragma("clang diagnostic ignored \"-Weverything\"") #define TOML_POP_WARNINGS _Pragma("clang diagnostic pop") #define TOML_ASSUME(cond) __builtin_assume(cond) #define TOML_UNREACHABLE __builtin_unreachable() #define TOML_GNU_ATTR(attr) __attribute__((attr)) #if defined(_MSC_VER) // msvc compat mode #ifdef __has_declspec_attribute #if __has_declspec_attribute(novtable) #define TOML_INTERFACE __declspec(novtable) #endif #if __has_declspec_attribute(empty_bases) #define TOML_EMPTY_BASES __declspec(empty_bases) #endif #define TOML_ALWAYS_INLINE __forceinline #endif #endif #ifdef __has_attribute #if !defined(TOML_ALWAYS_INLINE) && __has_attribute(always_inline) #define TOML_ALWAYS_INLINE __attribute__((__always_inline__)) inline #endif #if !defined(TOML_TRIVIAL_ABI) && __has_attribute(trivial_abi) #define TOML_TRIVIAL_ABI __attribute__((__trivial_abi__)) #endif #endif #ifdef __EXCEPTIONS #define TOML_COMPILER_EXCEPTIONS 1 #else #define TOML_COMPILER_EXCEPTIONS 0 #endif //floating-point from_chars and to_chars are not implemented in any version of clang as of 1/1/2020 #ifndef TOML_USE_STREAMS_FOR_FLOATS #define TOML_USE_STREAMS_FOR_FLOATS 1 #endif #elif defined(_MSC_VER) || (defined(__INTEL_COMPILER) && defined(__ICL)) #define TOML_CPP_VERSION _MSVC_LANG #define TOML_PUSH_WARNINGS __pragma(warning(push)) #define TOML_DISABLE_SWITCH_WARNINGS __pragma(warning(disable: 4063)) #define TOML_DISABLE_ALL_WARNINGS __pragma(warning(pop)) \ __pragma(warning(push, 0)) #define TOML_POP_WARNINGS __pragma(warning(pop)) #define TOML_ALWAYS_INLINE __forceinline #define TOML_ASSUME(cond) __assume(cond) #define TOML_UNREACHABLE __assume(0) #define TOML_INTERFACE __declspec(novtable) #define TOML_EMPTY_BASES __declspec(empty_bases) #if !defined(TOML_RELOPS_REORDERING) && defined(__cpp_impl_three_way_comparison) #define TOML_RELOPS_REORDERING 1 #endif #ifdef _CPPUNWIND #define TOML_COMPILER_EXCEPTIONS 1 #else #define TOML_COMPILER_EXCEPTIONS 0 #endif #elif defined(__GNUC__) #define TOML_PUSH_WARNINGS _Pragma("GCC diagnostic push") #define TOML_DISABLE_SWITCH_WARNINGS _Pragma("GCC diagnostic ignored \"-Wswitch\"") #define TOML_DISABLE_INIT_WARNINGS _Pragma("GCC diagnostic ignored \"-Wmissing-field-initializers\"") \ _Pragma("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") \ _Pragma("GCC diagnostic ignored \"-Wuninitialized\"") #define TOML_DISABLE_ALL_WARNINGS _Pragma("GCC diagnostic ignored \"-Wall\"") \ _Pragma("GCC diagnostic ignored \"-Wextra\"") \ _Pragma("GCC diagnostic ignored \"-Wchar-subscripts\"") \ _Pragma("GCC diagnostic ignored \"-Wtype-limits\"") #define TOML_POP_WARNINGS _Pragma("GCC diagnostic pop") #define TOML_GNU_ATTR(attr) __attribute__((attr)) #define TOML_ALWAYS_INLINE __attribute__((__always_inline__)) inline #define TOML_UNREACHABLE __builtin_unreachable() #if !defined(TOML_RELOPS_REORDERING) && defined(__cpp_impl_three_way_comparison) #define TOML_RELOPS_REORDERING 1 #endif #ifdef __cpp_exceptions #define TOML_COMPILER_EXCEPTIONS 1 #else #define TOML_COMPILER_EXCEPTIONS 0 #endif // these pass the __has_attribute() test but cause warnings on if/else branches =/ #define TOML_LIKELY #define TOML_UNLIKELY // floating-point from_chars and to_chars are not implemented in any version of gcc as of 1/1/2020 #ifndef TOML_USE_STREAMS_FOR_FLOATS #define TOML_USE_STREAMS_FOR_FLOATS 1 #endif #endif #ifndef TOML_CPP_VERSION #define TOML_CPP_VERSION __cplusplus #endif #if TOML_CPP_VERSION < 201103L #error toml++ requires C++17 or higher. For a TOML parser supporting pre-C++11 see https://github.com/ToruNiina/Boost.toml #elif TOML_CPP_VERSION < 201703L #error toml++ requires C++17 or higher. For a TOML parser supporting C++11 see https://github.com/skystrife/cpptoml #elif TOML_CPP_VERSION >= 202600L #define TOML_CPP 26 #elif TOML_CPP_VERSION >= 202300L #define TOML_CPP 23 #elif TOML_CPP_VERSION >= 202002L #define TOML_CPP 20 #elif TOML_CPP_VERSION >= 201703L #define TOML_CPP 17 #endif #ifndef TOML_COMPILER_EXCEPTIONS #define TOML_COMPILER_EXCEPTIONS 1 #endif #if TOML_COMPILER_EXCEPTIONS #ifndef TOML_EXCEPTIONS #define TOML_EXCEPTIONS 1 #endif #else #if defined(TOML_EXCEPTIONS) && TOML_EXCEPTIONS #error TOML_EXCEPTIONS was explicitly enabled but exceptions are disabled/unsupported by the compiler. #endif #undef TOML_EXCEPTIONS #define TOML_EXCEPTIONS 0 #endif #if TOML_EXCEPTIONS #define TOML_MAY_THROW #define TOML_MAY_THROW_UNLESS(...) noexcept(__VA_ARGS__) #define TOML_NS1_EX #else #define TOML_MAY_THROW noexcept #define TOML_MAY_THROW_UNLESS(...) noexcept #define TOML_NS1_EX _noex #endif #ifndef TOML_DISABLE_INIT_WARNINGS #define TOML_DISABLE_INIT_WARNINGS #endif #ifndef TOML_USE_STREAMS_FOR_FLOATS #define TOML_USE_STREAMS_FOR_FLOATS 0 #endif #ifndef TOML_PUSH_WARNINGS #define TOML_PUSH_WARNINGS #endif #ifndef TOML_DISABLE_ALL_WARNINGS #define TOML_DISABLE_ALL_WARNINGS #endif #ifndef TOML_POP_WARNINGS #define TOML_POP_WARNINGS #endif #ifndef TOML_GNU_ATTR #define TOML_GNU_ATTR(attr) #endif #ifndef TOML_INTERFACE #define TOML_INTERFACE #endif #ifndef TOML_EMPTY_BASES #define TOML_EMPTY_BASES #endif #ifndef TOML_ALWAYS_INLINE #define TOML_ALWAYS_INLINE inline #endif #ifndef TOML_ASSUME #define TOML_ASSUME(cond) (void)0 #endif #ifndef TOML_UNREACHABLE #define TOML_UNREACHABLE TOML_ASSERT(false) #endif #define TOML_NO_DEFAULT_CASE default: TOML_UNREACHABLE #ifdef __cpp_consteval #define TOML_CONSTEVAL consteval #else #define TOML_CONSTEVAL constexpr #endif #ifndef __INTELLISENSE__ #if !defined(TOML_LIKELY) && __has_cpp_attribute(likely) #define TOML_LIKELY [[likely]] #endif #if !defined(TOML_UNLIKELY) && __has_cpp_attribute(unlikely) #define TOML_UNLIKELY [[unlikely]] #endif #if __has_cpp_attribute(nodiscard) >= 201907L #define TOML_NODISCARD_CTOR [[nodiscard]] #endif #endif //__INTELLISENSE__ #ifndef TOML_LIKELY #define TOML_LIKELY #endif #ifndef TOML_UNLIKELY #define TOML_UNLIKELY #endif #ifndef TOML_TRIVIAL_ABI #define TOML_TRIVIAL_ABI #endif #ifndef TOML_NODISCARD_CTOR #define TOML_NODISCARD_CTOR #endif #ifndef TOML_RELOPS_REORDERING #define TOML_RELOPS_REORDERING 0 #endif #if TOML_RELOPS_REORDERING #define TOML_ASYMMETRICAL_EQUALITY_OPS(...) #else #define TOML_ASYMMETRICAL_EQUALITY_OPS(LHS, RHS, ...) \ __VA_ARGS__ [[nodiscard]] friend bool operator == (RHS rhs, LHS lhs) noexcept { return lhs == rhs; } \ __VA_ARGS__ [[nodiscard]] friend bool operator != (LHS lhs, RHS rhs) noexcept { return !(lhs == rhs); } \ __VA_ARGS__ [[nodiscard]] friend bool operator != (RHS rhs, LHS lhs) noexcept { return !(lhs == rhs); } #endif #if TOML_ALL_INLINE #define TOML_INLINE_FUNC_IMPL inline #else #define TOML_INLINE_FUNC_IMPL #endif #include "toml_version.h" #define TOML_MAKE_VERSION(maj, min, rev) \ ((maj) * 1000 + (min) * 25 + (rev)) #if TOML_UNRELEASED_FEATURES #define TOML_LANG_EFFECTIVE_VERSION \ TOML_MAKE_VERSION(TOML_LANG_MAJOR, TOML_LANG_MINOR, TOML_LANG_PATCH+1) #else #define TOML_LANG_EFFECTIVE_VERSION \ TOML_MAKE_VERSION(TOML_LANG_MAJOR, TOML_LANG_MINOR, TOML_LANG_PATCH) #endif #define TOML_LANG_HIGHER_THAN(maj, min, rev) \ (TOML_LANG_EFFECTIVE_VERSION > TOML_MAKE_VERSION(maj, min, rev)) #define TOML_LANG_AT_LEAST(maj, min, rev) \ (TOML_LANG_EFFECTIVE_VERSION >= TOML_MAKE_VERSION(maj, min, rev)) #define TOML_LANG_EXACTLY(maj, min, rev) \ (TOML_LANG_EFFECTIVE_VERSION == TOML_MAKE_VERSION(maj, min, rev)) #ifdef TOML_OPTIONAL_TYPE #define TOML_NS2_OPT _opt #else #define TOML_NS2_OPT #endif #if TOML_CHAR_8_STRINGS #define TOML_NS3_CHAR8 _char8 #else #define TOML_NS3_CHAR8 #endif #define TOML_NS4 #define TOML_NS5 #ifndef DOXYGEN #define TOML_START_2(VER, ARG1, ARG2, ARG3, ARG4, ARG5) \ namespace toml { inline namespace v##VER##ARG1##ARG2##ARG3##ARG4##ARG5 #define TOML_START_1(VER, ARG1, ARG2, ARG3, ARG4, ARG5) \ TOML_START_2(VER, ARG1, ARG2, ARG3, ARG4, ARG5) #define TOML_START \ TOML_START_1( \ TOML_LIB_MAJOR, TOML_NS1_EX, TOML_NS2_OPT, \ TOML_NS3_CHAR8, TOML_NS4, TOML_NS5 \ ) #define TOML_END } #endif #define TOML_IMPL_START TOML_START { namespace impl #define TOML_IMPL_END } TOML_END ////////// INCLUDES TOML_PUSH_WARNINGS TOML_DISABLE_ALL_WARNINGS #if __has_include() #include #endif #include #include //memcpy, memset #include #include #include #include #include #include #include #ifndef TOML_ASSERT #if !defined(NDEBUG) || defined(_DEBUG) || defined(DEBUG) #include #define TOML_ASSERT(expr) assert(expr) #else #define TOML_ASSERT(expr) (void)0 #endif #endif #ifndef TOML_OPTIONAL_TYPE #include #endif #if TOML_USE_STREAMS_FOR_FLOATS #include #endif #if TOML_EXCEPTIONS #include #endif TOML_POP_WARNINGS #if TOML_CHAR_8_STRINGS #if !defined(__cpp_lib_char8_t) #error toml++ requires implementation support to use char8_t strings, but yours does not provide it. #endif #define TOML_STRING_PREFIX_1(S) u8##S #define TOML_STRING_PREFIX(S) TOML_STRING_PREFIX_1(S) #else #define TOML_STRING_PREFIX(S) S #endif #ifdef __cpp_lib_launder #define TOML_LAUNDER(x) std::launder(x) #else #define TOML_LAUNDER(x) x #endif ////////// FORWARD DECLARATIONS & TYPEDEFS // clang-format on /// \brief The root namespace for all toml++ functions and types. namespace toml { } TOML_START { using namespace std::string_literals; using namespace std::string_view_literals; using size_t = std::size_t; using ptrdiff_t = std::ptrdiff_t; [[nodiscard]] TOML_ALWAYS_INLINE TOML_CONSTEVAL size_t operator"" _sz(unsigned long long n) noexcept { return static_cast(n); } #if TOML_CHAR_8_STRINGS using string_char = char8_t; using string = std::u8string; using string_view = std::u8string_view; #else /// \brief The base character type for keys and string values. /// \remarks This will be an alias for char8_t if `TOML_CHAR_8_STRINGS` is `1`. using string_char = char; /// \brief The string type for keys and string values. /// \remarks This will be an alias for std::u8string if `TOML_CHAR_8_STRINGS` is `1`. using string = std::string; /// \brief The string type for keys and string values. /// \remarks This will be an alias for std::u8string_view if `TOML_CHAR_8_STRINGS` is `1`. using string_view = std::string_view; #endif #ifndef DOXYGEN // foward declarations are hidden from doxygen // because they fuck it up =/ struct date; struct time; struct time_offset; struct date_time; class node; class array; class table; template class node_view; template class value; template class default_formatter; template class json_formatter; #endif // !DOXYGEN /// \brief TOML node type identifiers. enum class node_type : uint8_t { none, ///< Not-a-node. table, ///< The node is a toml::table. array, ///< The node is a toml::array. string, ///< The node is a toml::value. integer, ///< The node is a toml::value. floating_point, ///< The node is a toml::value. boolean, ///< The node is a toml::value. date, ///< The node is a toml::value. time, ///< The node is a toml::value