From 4a80e6faf8d04b25cb3542bb09059401868b2cbb Mon Sep 17 00:00:00 2001 From: LebJe <51171427+LebJe@users.noreply.github.com> Date: Wed, 3 Jan 2024 15:22:07 -0500 Subject: [PATCH] Update to toml++ v3.4.0 --- .swiftformat | 2 +- CHANGELOG.md | 6 + LICENSE | 2 +- Sources/CTOML/Sources/toml.hpp | 8302 ++++++++++------- .../TOMLKit/Decoder/InternalTOMLDecoder.swift | 2 +- .../KeyedDecodingContainerProtocol.swift | 2 +- .../SingleValueDecodingContainer.swift | 2 +- Sources/TOMLKit/Decoder/TOMLDecoder.swift | 2 +- .../Decoder/UnkeyedDecodingContainer.swift | 2 +- .../TOMLKit/Encoder/InternalTOMLEncoder.swift | 2 +- .../Encoder/KeyedEncodingContainer.swift | 2 +- .../SingleValueEncodingContainer.swift | 2 +- Sources/TOMLKit/Encoder/TOMLEncoder.swift | 2 +- .../Encoder/UnkeyedEncodingContainer.swift | 2 +- Sources/TOMLKit/FormatOptions.swift | 2 +- Sources/TOMLKit/Operators&Extensions.swift | 2 +- .../TOMLArray+CollectionConformance.swift | 2 +- .../TOML Data Types/TOMLArray/TOMLArray.swift | 2 +- .../TOMLArray/TOMLArrayIterator.swift | 2 +- .../TOMLDate&Time&DateTime.swift | 2 +- Sources/TOMLKit/TOML Data Types/TOMLInt.swift | 2 +- .../TOMLTable+CollectionFunctions.swift | 2 +- .../TOML Data Types/TOMLTable/TOMLTable.swift | 2 +- .../TOMLTable/TOMLTableIterator.swift | 2 +- .../TOMLValueConvertible+Int.swift | 2 +- .../TOMLValueConvertible.swift | 2 +- Sources/TOMLKit/TOMLCodingKey.swift | 2 +- Sources/TOMLKit/TOMLParseError.swift | 2 +- Sources/TOMLKit/TOMLType.swift | 2 +- .../TOMLValue/TOMLValue+Initializers.swift | 2 +- Sources/TOMLKit/TOMLValue/TOMLValue.swift | 2 +- Sources/TOMLKit/ValueOptions.swift | 2 +- Tests/TOMLKitTests/TOMLKitTests.swift | 2 +- 33 files changed, 4963 insertions(+), 3407 deletions(-) diff --git a/.swiftformat b/.swiftformat index d1157d24..33f1d3b4 100644 --- a/.swiftformat +++ b/.swiftformat @@ -13,7 +13,7 @@ --wrapparameters before-first --disable trailingClosures, typeSugar --maxwidth 120 ---header "Copyright (c) 2023 Jeff Lebrun \n\n \ +--header "Copyright (c) 2024 Jeff Lebrun \n\n \ Licensed under the MIT License. \n\n \ The full text of the license can be found in the file named LICENSE. " diff --git a/CHANGELOG.md b/CHANGELOG.md index a8d16801..9e5770f1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.6.0](https://github.com/LebJe/TOMLKit/releases/tag/0.6.0) - 2024-01-03 + +### Changed + +- Updated to [v3.4.0](https://github.com/marzer/tomlplusplus/releases/tag/v3.4.0) of tomlplusplus. + ## [0.5.6](https://github.com/LebJe/TOMLKit/releases/tag/0.5.6) - 2023-12-10 ### Fixed diff --git a/LICENSE b/LICENSE index dadc8f24..79280201 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2021 Jeff Lebrun +Copyright (c) 2024 Jeff Lebrun Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/Sources/CTOML/Sources/toml.hpp b/Sources/CTOML/Sources/toml.hpp index d23ece17..0599bf5e 100644 --- a/Sources/CTOML/Sources/toml.hpp +++ b/Sources/CTOML/Sources/toml.hpp @@ -1,6 +1,6 @@ //---------------------------------------------------------------------------------------------------------------------- // -// toml++ v3.0.1 +// toml++ v3.4.0 // https://github.com/marzer/tomlplusplus // SPDX-License-Identifier: MIT // @@ -41,805 +41,1147 @@ // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // //---------------------------------------------------------------------------------------------------------------------- -#ifndef TOMLPLUSPLUS_H -#define TOMLPLUSPLUS_H +#ifndef TOMLPLUSPLUS_HPP +#define TOMLPLUSPLUS_HPP #define INCLUDE_TOMLPLUSPLUS_H // old guard name used pre-v3 +#define TOMLPLUSPLUS_H // guard name used in the legacy toml.h -//******** impl/preprocessor.h *************************************************************************************** - -// clang-format off +//******** impl/preprocessor.hpp ************************************************************************************* #ifndef __cplusplus - #error toml++ is a C++ library. +#error toml++ is a C++ library. +#endif + +#ifndef TOML_CPP +#ifdef _MSVC_LANG +#if _MSVC_LANG > __cplusplus +#define TOML_CPP _MSVC_LANG +#endif +#endif +#ifndef TOML_CPP +#define TOML_CPP __cplusplus +#endif +#if TOML_CPP >= 202900L +#undef TOML_CPP +#define TOML_CPP 29 +#elif TOML_CPP >= 202600L +#undef TOML_CPP +#define TOML_CPP 26 +#elif TOML_CPP >= 202302L +#undef TOML_CPP +#define TOML_CPP 23 +#elif TOML_CPP >= 202002L +#undef TOML_CPP +#define TOML_CPP 20 +#elif TOML_CPP >= 201703L +#undef TOML_CPP +#define TOML_CPP 17 +#elif TOML_CPP >= 201402L +#undef TOML_CPP +#define TOML_CPP 14 +#elif TOML_CPP >= 201103L +#undef TOML_CPP +#define TOML_CPP 11 +#else +#undef TOML_CPP +#define TOML_CPP 0 +#endif +#endif + +#if !TOML_CPP +#error toml++ requires C++17 or higher. For a pre-C++11 TOML library see https://github.com/ToruNiina/Boost.toml +#elif TOML_CPP < 17 +#error toml++ requires C++17 or higher. For a C++11 TOML library see https://github.com/ToruNiina/toml11 +#endif + +#ifndef TOML_MAKE_VERSION +#define TOML_MAKE_VERSION(major, minor, patch) (((major)*10000) + ((minor)*100) + ((patch))) #endif +#ifndef TOML_INTELLISENSE #ifdef __INTELLISENSE__ - #define TOML_INTELLISENSE 1 +#define TOML_INTELLISENSE 1 #else - #define TOML_INTELLISENSE 0 +#define TOML_INTELLISENSE 0 #endif -#ifdef __clang__ - #define TOML_CLANG __clang_major__ -#else - #define TOML_CLANG 0 #endif -#ifdef __INTEL_COMPILER - #define TOML_ICC __INTEL_COMPILER - #ifdef __ICL - #define TOML_ICC_CL TOML_ICC - #else - #define TOML_ICC_CL 0 - #endif + +#ifndef TOML_DOXYGEN +#if defined(DOXYGEN) || defined(__DOXYGEN) || defined(__DOXYGEN__) || defined(__doxygen__) || defined(__POXY__) \ + || defined(__poxy__) +#define TOML_DOXYGEN 1 #else - #define TOML_ICC 0 - #define TOML_ICC_CL 0 +#define TOML_DOXYGEN 0 #endif -#if defined(_MSC_VER) && !TOML_CLANG && !TOML_ICC - #define TOML_MSVC _MSC_VER -#else - #define TOML_MSVC 0 #endif -#if defined(__GNUC__) && !TOML_CLANG && !TOML_ICC - #define TOML_GCC __GNUC__ + +#ifndef TOML_CLANG +#ifdef __clang__ +#define TOML_CLANG __clang_major__ #else - #define TOML_GCC 0 +#define TOML_CLANG 0 #endif -#ifdef __has_include - #define TOML_HAS_INCLUDE(header) __has_include(header) +// special handling for apple clang; see: +// - https://github.com/marzer/tomlplusplus/issues/189 +// - https://en.wikipedia.org/wiki/Xcode +// - +// https://stackoverflow.com/questions/19387043/how-can-i-reliably-detect-the-version-of-clang-at-preprocessing-time +#if TOML_CLANG && defined(__apple_build_version__) +#undef TOML_CLANG +#define TOML_CLANG_VERSION TOML_MAKE_VERSION(__clang_major__, __clang_minor__, __clang_patchlevel__) +#if TOML_CLANG_VERSION >= TOML_MAKE_VERSION(15, 0, 0) +#define TOML_CLANG 16 +#elif TOML_CLANG_VERSION >= TOML_MAKE_VERSION(14, 3, 0) +#define TOML_CLANG 15 +#elif TOML_CLANG_VERSION >= TOML_MAKE_VERSION(14, 0, 0) +#define TOML_CLANG 14 +#elif TOML_CLANG_VERSION >= TOML_MAKE_VERSION(13, 1, 6) +#define TOML_CLANG 13 +#elif TOML_CLANG_VERSION >= TOML_MAKE_VERSION(13, 0, 0) +#define TOML_CLANG 12 +#elif TOML_CLANG_VERSION >= TOML_MAKE_VERSION(12, 0, 5) +#define TOML_CLANG 11 +#elif TOML_CLANG_VERSION >= TOML_MAKE_VERSION(12, 0, 0) +#define TOML_CLANG 10 +#elif TOML_CLANG_VERSION >= TOML_MAKE_VERSION(11, 0, 3) +#define TOML_CLANG 9 +#elif TOML_CLANG_VERSION >= TOML_MAKE_VERSION(11, 0, 0) +#define TOML_CLANG 8 +#elif TOML_CLANG_VERSION >= TOML_MAKE_VERSION(10, 0, 1) +#define TOML_CLANG 7 #else - #define TOML_HAS_INCLUDE(header) 0 +#define TOML_CLANG 6 // not strictly correct but doesn't matter below this +#endif +#undef TOML_CLANG_VERSION #endif - -#if TOML_CLANG - - #define TOML_PUSH_WARNINGS \ - _Pragma("clang diagnostic push") \ - static_assert(true) - - #define TOML_DISABLE_SWITCH_WARNINGS \ - _Pragma("clang diagnostic ignored \"-Wswitch\"") \ - static_assert(true) - - #define TOML_DISABLE_ARITHMETIC_WARNINGS \ - _Pragma("clang diagnostic ignored \"-Wfloat-equal\"") \ - _Pragma("clang diagnostic ignored \"-Wdouble-promotion\"") \ - _Pragma("clang diagnostic ignored \"-Wshift-sign-overflow\"") \ - static_assert(true) - - #if TOML_CLANG >= 10 - #define TOML_DISABLE_SPAM_WARNINGS_CLANG_10 \ - _Pragma("clang diagnostic ignored \"-Wzero-as-null-pointer-constant\"") \ - static_assert(true) - #else - #define TOML_DISABLE_SPAM_WARNINGS_CLANG_10 static_assert(true) - #endif - - #define TOML_DISABLE_SPAM_WARNINGS \ - TOML_DISABLE_SPAM_WARNINGS_CLANG_10; \ - _Pragma("clang diagnostic ignored \"-Wweak-vtables\"") \ - _Pragma("clang diagnostic ignored \"-Wweak-template-vtables\"") \ - _Pragma("clang diagnostic ignored \"-Wdouble-promotion\"") \ - _Pragma("clang diagnostic ignored \"-Wchar-subscripts\"") \ - _Pragma("clang diagnostic ignored \"-Wmissing-field-initializers\"") \ - _Pragma("clang diagnostic ignored \"-Wpadded\"") \ - static_assert(true) - - #define TOML_POP_WARNINGS \ - _Pragma("clang diagnostic pop") \ - static_assert(true) - - #define TOML_DISABLE_WARNINGS \ - TOML_PUSH_WARNINGS; \ - _Pragma("clang diagnostic ignored \"-Weverything\"") \ - static_assert(true) - - #define TOML_ENABLE_WARNINGS TOML_POP_WARNINGS - - #define TOML_ASSUME(expr) __builtin_assume(expr) - #define TOML_UNREACHABLE __builtin_unreachable() - #define TOML_ATTR(...) __attribute__((__VA_ARGS__)) - #if defined(_MSC_VER) // msvc compat mode - #ifdef __has_declspec_attribute - #if __has_declspec_attribute(novtable) - #define TOML_ABSTRACT_BASE __declspec(novtable) - #endif - #if __has_declspec_attribute(empty_bases) - #define TOML_EMPTY_BASES __declspec(empty_bases) - #endif - #ifndef TOML_ALWAYS_INLINE - #define TOML_ALWAYS_INLINE __forceinline - #endif - #if __has_declspec_attribute(noinline) - #define TOML_NEVER_INLINE __declspec(noinline) - #endif - #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_NEVER_INLINE) && __has_attribute(noinline) - #define TOML_NEVER_INLINE __attribute__((__noinline__)) - #endif - #if !defined(TOML_TRIVIAL_ABI) && __has_attribute(trivial_abi) - #define TOML_TRIVIAL_ABI __attribute__((__trivial_abi__)) - #endif - #if !defined(TOML_FLAGS_ENUM) && __has_attribute(flag_enum) - #define TOML_FLAGS_ENUM __attribute__((__flag_enum__)) - #endif - #if __has_attribute(enum_extensibility) - #ifndef TOML_OPEN_ENUM - #define TOML_OPEN_ENUM __attribute__((enum_extensibility(open))) - #endif - #ifndef TOML_CLOSED_ENUM - #define TOML_CLOSED_ENUM __attribute__((enum_extensibility(closed))) - #endif - #endif - #endif - #define TOML_LIKELY(...) (__builtin_expect(!!(__VA_ARGS__), 1) ) - #define TOML_UNLIKELY(...) (__builtin_expect(!!(__VA_ARGS__), 0) ) - - #define TOML_SIMPLE_STATIC_ASSERT_MESSAGES 1 - -#endif // clang - -#if TOML_MSVC || TOML_ICC_CL - - #define TOML_CPP_VERSION _MSVC_LANG - #if TOML_MSVC // !intel-cl - - #define TOML_PUSH_WARNINGS \ - __pragma(warning(push)) \ - static_assert(true) - - #if TOML_HAS_INCLUDE() - #pragma warning(push, 0) - #include - #pragma warning(pop) - #define TOML_DISABLE_CODE_ANALYSIS_WARNINGS \ - __pragma(warning(disable: ALL_CODE_ANALYSIS_WARNINGS)) \ - static_assert(true) - #else - #define TOML_DISABLE_CODE_ANALYSIS_WARNINGS - static_assert(true) - #endif - - #define TOML_DISABLE_SWITCH_WARNINGS \ - __pragma(warning(disable: 4061)) /* enumerator 'identifier' is not explicitly handled by a case label */ \ - __pragma(warning(disable: 4062)) /* enumerator 'identifier' is not handled */ \ - __pragma(warning(disable: 4063)) \ - __pragma(warning(disable: 26819)) \ - static_assert(true) - - #define TOML_DISABLE_SPAM_WARNINGS \ - __pragma(warning(disable: 4127)) /* conditional expr is constant */ \ - __pragma(warning(disable: 4324)) /* structure was padded due to alignment specifier */ \ - __pragma(warning(disable: 4348)) \ - __pragma(warning(disable: 4464)) /* relative include path contains '..' */ \ - __pragma(warning(disable: 4505)) /* unreferenced local function removed */ \ - __pragma(warning(disable: 4514)) /* unreferenced inline function has been removed */ \ - __pragma(warning(disable: 4582)) /* constructor is not implicitly called */ \ - __pragma(warning(disable: 4623)) /* default constructor was implicitly defined as deleted */ \ - __pragma(warning(disable: 4625)) /* copy constructor was implicitly defined as deleted */ \ - __pragma(warning(disable: 4626)) /* assignment operator was implicitly defined as deleted */ \ - __pragma(warning(disable: 4710)) /* function not inlined */ \ - __pragma(warning(disable: 4711)) /* function selected for automatic expansion */ \ - __pragma(warning(disable: 4820)) /* N bytes padding added */ \ - __pragma(warning(disable: 4946)) /* reinterpret_cast used between related classes */ \ - __pragma(warning(disable: 5026)) /* move constructor was implicitly defined as deleted */ \ - __pragma(warning(disable: 5027)) /* move assignment operator was implicitly defined as deleted */ \ - __pragma(warning(disable: 5039)) /* potentially throwing function passed to 'extern "C"' function */ \ - __pragma(warning(disable: 5045)) /* Compiler will insert Spectre mitigation */ \ - __pragma(warning(disable: 26451)) \ - __pragma(warning(disable: 26490)) \ - __pragma(warning(disable: 26495)) \ - __pragma(warning(disable: 26812)) \ - __pragma(warning(disable: 26819)) \ - static_assert(true) - - #define TOML_DISABLE_ARITHMETIC_WARNINGS \ - __pragma(warning(disable: 4365)) /* argument signed/unsigned mismatch */ \ - __pragma(warning(disable: 4738)) /* storing 32-bit float result in memory */ \ - __pragma(warning(disable: 5219)) /* implicit conversion from integral to float */ \ - static_assert(true) - - #define TOML_POP_WARNINGS \ - __pragma(warning(pop)) \ - static_assert(true) - - #define TOML_DISABLE_WARNINGS \ - __pragma(warning(push, 0)) \ - __pragma(warning(disable: 4348)) \ - __pragma(warning(disable: 4668)) \ - __pragma(warning(disable: 5105)) \ - TOML_DISABLE_CODE_ANALYSIS_WARNINGS;\ - TOML_DISABLE_SWITCH_WARNINGS; \ - TOML_DISABLE_SPAM_WARNINGS; \ - TOML_DISABLE_ARITHMETIC_WARNINGS; \ - static_assert(true) - - #define TOML_ENABLE_WARNINGS TOML_POP_WARNINGS - - #endif - #ifndef TOML_ALWAYS_INLINE - #define TOML_ALWAYS_INLINE __forceinline - #endif - #define TOML_NEVER_INLINE __declspec(noinline) - #define TOML_ASSUME(expr) __assume(expr) - #define TOML_UNREACHABLE __assume(0) - #define TOML_ABSTRACT_BASE __declspec(novtable) - #define TOML_EMPTY_BASES __declspec(empty_bases) - #ifdef _CPPUNWIND - #define TOML_COMPILER_EXCEPTIONS 1 - #else - #define TOML_COMPILER_EXCEPTIONS 0 - #endif - -#endif // msvc - -#if TOML_ICC - - #define TOML_PUSH_WARNINGS \ - __pragma(warning(push)) \ - static_assert(true) - - #define TOML_DISABLE_SPAM_WARNINGS \ - __pragma(warning(disable: 82)) /* storage class is not first */ \ - __pragma(warning(disable: 111)) /* statement unreachable (false-positive) */ \ - __pragma(warning(disable: 869)) /* unreferenced parameter */ \ - __pragma(warning(disable: 1011)) /* missing return (false-positive) */ \ - __pragma(warning(disable: 2261)) /* assume expr side-effects discarded */ \ - static_assert(true) - - #define TOML_POP_WARNINGS \ - __pragma(warning(pop)) \ - static_assert(true) - - #define TOML_DISABLE_WARNINGS \ - __pragma(warning(push, 0)) \ - static_assert(true) - - #define TOML_ENABLE_WARNINGS \ - TOML_POP_WARNINGS - -#endif // icc - -#if TOML_GCC - - #define TOML_PUSH_WARNINGS \ - _Pragma("GCC diagnostic push") \ - static_assert(true) - - #define TOML_DISABLE_SWITCH_WARNINGS \ - _Pragma("GCC diagnostic ignored \"-Wswitch\"") \ - _Pragma("GCC diagnostic ignored \"-Wswitch-enum\"") \ - _Pragma("GCC diagnostic ignored \"-Wswitch-default\"") \ - static_assert(true) - - #define TOML_DISABLE_ARITHMETIC_WARNINGS \ - _Pragma("GCC diagnostic ignored \"-Wfloat-equal\"") \ - _Pragma("GCC diagnostic ignored \"-Wsign-conversion\"") \ - static_assert(true) - - #define TOML_DISABLE_SUGGEST_ATTR_WARNINGS \ - _Pragma("GCC diagnostic ignored \"-Wsuggest-attribute=const\"") \ - _Pragma("GCC diagnostic ignored \"-Wsuggest-attribute=pure\"") \ - static_assert(true) - - #define TOML_DISABLE_SPAM_WARNINGS \ - _Pragma("GCC diagnostic ignored \"-Wpadded\"") \ - _Pragma("GCC diagnostic ignored \"-Wcast-align\"") \ - _Pragma("GCC diagnostic ignored \"-Wcomment\"") \ - _Pragma("GCC diagnostic ignored \"-Wtype-limits\"") \ - _Pragma("GCC diagnostic ignored \"-Wuseless-cast\"") \ - _Pragma("GCC diagnostic ignored \"-Wchar-subscripts\"") \ - _Pragma("GCC diagnostic ignored \"-Wsubobject-linkage\"") \ - _Pragma("GCC diagnostic ignored \"-Wmissing-field-initializers\"") \ - _Pragma("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") \ - static_assert(true) - - #define TOML_POP_WARNINGS \ - _Pragma("GCC diagnostic pop") \ - static_assert(true) - - #define TOML_DISABLE_WARNINGS \ - TOML_PUSH_WARNINGS; \ - _Pragma("GCC diagnostic ignored \"-Wall\"") \ - _Pragma("GCC diagnostic ignored \"-Wextra\"") \ - _Pragma("GCC diagnostic ignored \"-Wpedantic\"") \ - TOML_DISABLE_SWITCH_WARNINGS; \ - TOML_DISABLE_ARITHMETIC_WARNINGS; \ - TOML_DISABLE_SPAM_WARNINGS; \ - TOML_DISABLE_SUGGEST_ATTR_WARNINGS; \ - static_assert(true) - - #define TOML_ENABLE_WARNINGS \ - TOML_POP_WARNINGS - - #define TOML_ATTR(...) __attribute__((__VA_ARGS__)) - #ifndef TOML_ALWAYS_INLINE - #define TOML_ALWAYS_INLINE __attribute__((__always_inline__)) inline - #endif - #define TOML_NEVER_INLINE __attribute__((__noinline__)) - #define TOML_UNREACHABLE __builtin_unreachable() - #define TOML_LIKELY(...) (__builtin_expect(!!(__VA_ARGS__), 1) ) - #define TOML_UNLIKELY(...) (__builtin_expect(!!(__VA_ARGS__), 0) ) - #endif -#ifndef TOML_CPP_VERSION - #define TOML_CPP_VERSION __cplusplus +#ifndef TOML_ICC +#ifdef __INTEL_COMPILER +#define TOML_ICC __INTEL_COMPILER +#ifdef __ICL +#define TOML_ICC_CL TOML_ICC +#else +#define TOML_ICC_CL 0 #endif -#if TOML_CPP_VERSION < 201103L - #error toml++ requires C++17 or higher. For a TOML library 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 library supporting C++11 see https://github.com/ToruNiina/toml11 +#else +#define TOML_ICC 0 +#define TOML_ICC_CL 0 #endif - -#ifdef TOML_CONFIG_HEADER - #include TOML_CONFIG_HEADER #endif -// header-only mode -#if !defined(TOML_HEADER_ONLY) && defined(TOML_ALL_INLINE) // was TOML_ALL_INLINE pre-2.0 - #define TOML_HEADER_ONLY TOML_ALL_INLINE -#endif -#if !defined(TOML_HEADER_ONLY) || (defined(TOML_HEADER_ONLY) && TOML_HEADER_ONLY) || TOML_INTELLISENSE - #undef TOML_HEADER_ONLY - #define TOML_HEADER_ONLY 1 +#ifndef TOML_MSVC_LIKE +#ifdef _MSC_VER +#define TOML_MSVC_LIKE _MSC_VER +#else +#define TOML_MSVC_LIKE 0 #endif -#ifdef DOXYGEN - #undef TOML_HEADER_ONLY - #define TOML_HEADER_ONLY 0 #endif -// extern templates (for !TOML_HEADER_ONLY) -#ifndef TOML_EXTERN_TEMPLATES - #define TOML_EXTERN_TEMPLATES 1 +#ifndef TOML_MSVC +#if TOML_MSVC_LIKE && !TOML_CLANG && !TOML_ICC +#define TOML_MSVC TOML_MSVC_LIKE +#else +#define TOML_MSVC 0 #endif -#if (defined(DOXYGEN) || TOML_HEADER_ONLY) - #undef TOML_EXTERN_TEMPLATES - #define TOML_EXTERN_TEMPLATES 0 #endif -// internal implementation switch -#if defined(TOML_IMPLEMENTATION) || TOML_HEADER_ONLY - #undef TOML_IMPLEMENTATION - #define TOML_IMPLEMENTATION 1 +#ifndef TOML_GCC_LIKE +#ifdef __GNUC__ +#define TOML_GCC_LIKE __GNUC__ #else - #define TOML_IMPLEMENTATION 0 +#define TOML_GCC_LIKE 0 +#endif #endif -// dllexport etc -#ifndef TOML_API - #define TOML_API +#ifndef TOML_GCC +#if TOML_GCC_LIKE && !TOML_CLANG && !TOML_ICC +#define TOML_GCC TOML_GCC_LIKE +#else +#define TOML_GCC 0 +#endif #endif -// experimental language features -#if !defined(TOML_ENABLE_UNRELEASED_FEATURES) && defined(TOML_UNRELEASED_FEATURES) // was TOML_UNRELEASED_FEATURES pre-3.0 - #define TOML_ENABLE_UNRELEASED_FEATURES TOML_UNRELEASED_FEATURES +#ifndef TOML_CUDA +#if defined(__CUDACC__) || defined(__CUDA_ARCH__) || defined(__CUDA_LIBDEVICE__) +#define TOML_CUDA 1 +#else +#define TOML_CUDA 0 #endif -#if (defined(TOML_ENABLE_UNRELEASED_FEATURES) && TOML_ENABLE_UNRELEASED_FEATURES) || TOML_INTELLISENSE - #undef TOML_ENABLE_UNRELEASED_FEATURES - #define TOML_ENABLE_UNRELEASED_FEATURES 1 #endif -#ifndef TOML_ENABLE_UNRELEASED_FEATURES - #define TOML_ENABLE_UNRELEASED_FEATURES 0 + +#ifndef TOML_ARCH_ITANIUM +#if defined(__ia64__) || defined(__ia64) || defined(_IA64) || defined(__IA64__) || defined(_M_IA64) +#define TOML_ARCH_ITANIUM 1 +#define TOML_ARCH_BITNESS 64 +#else +#define TOML_ARCH_ITANIUM 0 +#endif #endif -// parser -#if !defined(TOML_ENABLE_PARSER) && defined(TOML_PARSER) // was TOML_PARSER pre-3.0 - #define TOML_ENABLE_PARSER TOML_PARSER +#ifndef TOML_ARCH_AMD64 +#if defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64) || defined(_M_AMD64) +#define TOML_ARCH_AMD64 1 +#define TOML_ARCH_BITNESS 64 +#else +#define TOML_ARCH_AMD64 0 #endif -#if !defined(TOML_ENABLE_PARSER) || (defined(TOML_ENABLE_PARSER) && TOML_ENABLE_PARSER) || TOML_INTELLISENSE - #undef TOML_ENABLE_PARSER - #define TOML_ENABLE_PARSER 1 #endif -// formatters -#if !defined(TOML_ENABLE_FORMATTERS) \ - || (defined(TOML_ENABLE_FORMATTERS) && TOML_ENABLE_FORMATTERS) \ - || TOML_INTELLISENSE - #undef TOML_ENABLE_FORMATTERS - #define TOML_ENABLE_FORMATTERS 1 +#ifndef TOML_ARCH_X86 +#if defined(__i386__) || defined(_M_IX86) +#define TOML_ARCH_X86 1 +#define TOML_ARCH_BITNESS 32 +#else +#define TOML_ARCH_X86 0 +#endif +#endif + +#ifndef TOML_ARCH_ARM +#if defined(__aarch64__) || defined(__ARM_ARCH_ISA_A64) || defined(_M_ARM64) || defined(__ARM_64BIT_STATE) \ + || defined(_M_ARM64EC) +#define TOML_ARCH_ARM32 0 +#define TOML_ARCH_ARM64 1 +#define TOML_ARCH_ARM 1 +#define TOML_ARCH_BITNESS 64 +#elif defined(__arm__) || defined(_M_ARM) || defined(__ARM_32BIT_STATE) +#define TOML_ARCH_ARM32 1 +#define TOML_ARCH_ARM64 0 +#define TOML_ARCH_ARM 1 +#define TOML_ARCH_BITNESS 32 +#else +#define TOML_ARCH_ARM32 0 +#define TOML_ARCH_ARM64 0 +#define TOML_ARCH_ARM 0 +#endif #endif -// SIMD -#if !defined(TOML_ENABLE_SIMD) \ - || (defined(TOML_ENABLE_SIMD) && TOML_ENABLE_SIMD) \ - || TOML_INTELLISENSE - #undef TOML_ENABLE_SIMD - #define TOML_ENABLE_SIMD 1 +#ifndef TOML_ARCH_BITNESS +#define TOML_ARCH_BITNESS 0 #endif -// windows compat -#if !defined(TOML_ENABLE_WINDOWS_COMPAT) && defined(TOML_WINDOWS_COMPAT) // was TOML_WINDOWS_COMPAT pre-3.0 - #define TOML_ENABLE_WINDOWS_COMPAT TOML_WINDOWS_COMPAT +#ifndef TOML_ARCH_X64 +#if TOML_ARCH_BITNESS == 64 +#define TOML_ARCH_X64 1 +#else +#define TOML_ARCH_X64 0 #endif -#if !defined(TOML_ENABLE_WINDOWS_COMPAT) \ - || (defined(TOML_ENABLE_WINDOWS_COMPAT) && TOML_ENABLE_WINDOWS_COMPAT) \ - || TOML_INTELLISENSE - #undef TOML_ENABLE_WINDOWS_COMPAT - #define TOML_ENABLE_WINDOWS_COMPAT 1 #endif -#ifndef _WIN32 - #undef TOML_ENABLE_WINDOWS_COMPAT - #define TOML_ENABLE_WINDOWS_COMPAT 0 +#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) || defined(__CYGWIN__) +#define TOML_WINDOWS 1 +#else +#define TOML_WINDOWS 0 #endif -#ifndef TOML_INCLUDE_WINDOWS_H - #define TOML_INCLUDE_WINDOWS_H 0 +#ifdef __unix__ +#define TOML_UNIX 1 +#else +#define TOML_UNIX 0 #endif -// custom optional -#ifdef TOML_OPTIONAL_TYPE - #define TOML_HAS_CUSTOM_OPTIONAL_TYPE 1 +#ifdef __linux__ +#define TOML_LINUX 1 #else - #define TOML_HAS_CUSTOM_OPTIONAL_TYPE 0 +#define TOML_LINUX 0 #endif -// exceptions (compiler support) -#ifndef TOML_COMPILER_EXCEPTIONS - #if defined(__EXCEPTIONS) || defined(__cpp_exceptions) - #define TOML_COMPILER_EXCEPTIONS 1 - #else - #define TOML_COMPILER_EXCEPTIONS 0 - #endif +// TOML_HAS_INCLUDE +#ifndef TOML_HAS_INCLUDE +#ifdef __has_include +#define TOML_HAS_INCLUDE(header) __has_include(header) +#else +#define TOML_HAS_INCLUDE(header) 0 +#endif #endif -// exceptions (library use) -#if TOML_COMPILER_EXCEPTIONS - #if !defined(TOML_EXCEPTIONS) || (defined(TOML_EXCEPTIONS) && TOML_EXCEPTIONS) - #undef TOML_EXCEPTIONS - #define TOML_EXCEPTIONS 1 - #endif +// TOML_HAS_BUILTIN +#ifndef TOML_HAS_BUILTIN +#ifdef __has_builtin +#define TOML_HAS_BUILTIN(name) __has_builtin(name) #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 +#define TOML_HAS_BUILTIN(name) 0 #endif - -#ifndef TOML_UNDEF_MACROS - #define TOML_UNDEF_MACROS 1 #endif -#ifndef TOML_MAX_NESTED_VALUES - #define TOML_MAX_NESTED_VALUES 256 - // this refers to the depth of nested values, e.g. inline tables and arrays. - // 256 is crazy high! if you're hitting this limit with real input, TOML is probably the wrong tool for the job... +// TOML_HAS_FEATURE +#ifndef TOML_HAS_FEATURE +#ifdef __has_feature +#define TOML_HAS_FEATURE(name) __has_feature(name) +#else +#define TOML_HAS_FEATURE(name) 0 +#endif #endif -#ifdef TOML_CHAR_8_STRINGS - #if TOML_CHAR_8_STRINGS - #error TOML_CHAR_8_STRINGS was removed in toml++ 2.0.0; all value setters and getters now work with char8_t strings implicitly. - #endif +// TOML_HAS_ATTR +#ifndef TOML_HAS_ATTR +#ifdef __has_attribute +#define TOML_HAS_ATTR(attr) __has_attribute(attr) +#else +#define TOML_HAS_ATTR(attr) 0 +#endif #endif -#ifdef TOML_LARGE_FILES - #if !TOML_LARGE_FILES - #error Support for !TOML_LARGE_FILES (i.e. 'small files') was removed in toml++ 3.0.0. - #endif +// TOML_HAS_CPP_ATTR +#ifndef TOML_HAS_CPP_ATTR +#ifdef __has_cpp_attribute +#define TOML_HAS_CPP_ATTR(attr) __has_cpp_attribute(attr) +#else +#define TOML_HAS_CPP_ATTR(attr) 0 +#endif #endif -#if !defined(TOML_FLOAT_CHARCONV) && (TOML_GCC || TOML_CLANG || (TOML_ICC && !TOML_ICC_CL)) - // not supported by any version of GCC or Clang as of 26/11/2020 - // not supported by any version of ICC on Linux as of 11/01/2021 - #define TOML_FLOAT_CHARCONV 0 +// TOML_ATTR (gnu attributes) +#ifndef TOML_ATTR +#if TOML_CLANG || TOML_GCC_LIKE +#define TOML_ATTR(...) __attribute__((__VA_ARGS__)) +#else +#define TOML_ATTR(...) #endif -#if !defined(TOML_INT_CHARCONV) && (defined(__EMSCRIPTEN__) || defined(__APPLE__)) - // causes link errors on emscripten - // causes Mac OS SDK version errors on some versions of Apple Clang - #define TOML_INT_CHARCONV 0 #endif -#ifndef TOML_INT_CHARCONV - #define TOML_INT_CHARCONV 1 + +// TOML_DECLSPEC (msvc attributes) +#ifndef TOML_DECLSPEC +#if TOML_MSVC_LIKE +#define TOML_DECLSPEC(...) __declspec(__VA_ARGS__) +#else +#define TOML_DECLSPEC(...) #endif -#ifndef TOML_FLOAT_CHARCONV - #define TOML_FLOAT_CHARCONV 1 #endif -#if (TOML_INT_CHARCONV || TOML_FLOAT_CHARCONV) && !TOML_HAS_INCLUDE() - #undef TOML_INT_CHARCONV - #undef TOML_FLOAT_CHARCONV - #define TOML_INT_CHARCONV 0 - #define TOML_FLOAT_CHARCONV 0 + +// TOML_COMPILER_HAS_EXCEPTIONS +#ifndef TOML_COMPILER_HAS_EXCEPTIONS +#if defined(__EXCEPTIONS) || defined(_CPPUNWIND) || defined(__cpp_exceptions) +#define TOML_COMPILER_HAS_EXCEPTIONS 1 +#else +#define TOML_COMPILER_HAS_EXCEPTIONS 0 +#endif #endif -#ifndef TOML_PUSH_WARNINGS - #define TOML_PUSH_WARNINGS static_assert(true) +// TOML_COMPILER_HAS_RTTI +#ifndef TOML_COMPILER_HAS_RTTI +#if defined(_CPPRTTI) || defined(__GXX_RTTI) || TOML_HAS_FEATURE(cxx_rtti) +#define TOML_COMPILER_HAS_RTTI 1 +#else +#define TOML_COMPILER_HAS_RTTI 0 #endif -#ifndef TOML_DISABLE_CODE_ANALYSIS_WARNINGS - #define TOML_DISABLE_CODE_ANALYSIS_WARNINGS static_assert(true) #endif -#ifndef TOML_DISABLE_SWITCH_WARNINGS - #define TOML_DISABLE_SWITCH_WARNINGS static_assert(true) + +// TOML_CONCAT +#define TOML_CONCAT_1(x, y) x##y +#define TOML_CONCAT(x, y) TOML_CONCAT_1(x, y) + +// TOML_MAKE_STRING +#define TOML_MAKE_STRING_1(s) #s +#define TOML_MAKE_STRING(s) TOML_MAKE_STRING_1(s) + +// TOML_PRAGMA_XXXX (compiler-specific pragmas) +#if TOML_CLANG +#define TOML_PRAGMA_CLANG(decl) _Pragma(TOML_MAKE_STRING(clang decl)) +#else +#define TOML_PRAGMA_CLANG(decl) #endif -#ifndef TOML_DISABLE_SUGGEST_ATTR_WARNINGS - #define TOML_DISABLE_SUGGEST_ATTR_WARNINGS static_assert(true) +#if TOML_CLANG >= 8 +#define TOML_PRAGMA_CLANG_GE_8(decl) TOML_PRAGMA_CLANG(decl) +#else +#define TOML_PRAGMA_CLANG_GE_8(decl) #endif -#ifndef TOML_DISABLE_SPAM_WARNINGS - #define TOML_DISABLE_SPAM_WARNINGS static_assert(true) +#if TOML_CLANG >= 9 +#define TOML_PRAGMA_CLANG_GE_9(decl) TOML_PRAGMA_CLANG(decl) +#else +#define TOML_PRAGMA_CLANG_GE_9(decl) #endif -#ifndef TOML_DISABLE_ARITHMETIC_WARNINGS - #define TOML_DISABLE_ARITHMETIC_WARNINGS static_assert(true) +#if TOML_CLANG >= 10 +#define TOML_PRAGMA_CLANG_GE_10(decl) TOML_PRAGMA_CLANG(decl) +#else +#define TOML_PRAGMA_CLANG_GE_10(decl) #endif -#ifndef TOML_POP_WARNINGS - #define TOML_POP_WARNINGS static_assert(true) +#if TOML_CLANG >= 11 +#define TOML_PRAGMA_CLANG_GE_11(decl) TOML_PRAGMA_CLANG(decl) +#else +#define TOML_PRAGMA_CLANG_GE_11(decl) #endif -#ifndef TOML_DISABLE_WARNINGS - #define TOML_DISABLE_WARNINGS static_assert(true) +#if TOML_GCC +#define TOML_PRAGMA_GCC(decl) _Pragma(TOML_MAKE_STRING(GCC decl)) +#else +#define TOML_PRAGMA_GCC(decl) #endif -#ifndef TOML_ENABLE_WARNINGS - #define TOML_ENABLE_WARNINGS static_assert(true) +#if TOML_MSVC +#define TOML_PRAGMA_MSVC(...) __pragma(__VA_ARGS__) +#else +#define TOML_PRAGMA_MSVC(...) #endif - -#ifndef TOML_ATTR - #define TOML_ATTR(...) +#if TOML_ICC +#define TOML_PRAGMA_ICC(...) __pragma(__VA_ARGS__) +#else +#define TOML_PRAGMA_ICC(...) #endif -#ifndef TOML_ABSTRACT_BASE - #define TOML_ABSTRACT_BASE +// TOML_ALWAYS_INLINE +#ifdef _MSC_VER +#define TOML_ALWAYS_INLINE __forceinline +#elif TOML_GCC || TOML_CLANG || TOML_HAS_ATTR(__always_inline__) +#define TOML_ALWAYS_INLINE \ + TOML_ATTR(__always_inline__) \ + inline +#else +#define TOML_ALWAYS_INLINE inline #endif -#ifndef TOML_EMPTY_BASES - #define TOML_EMPTY_BASES +// TOML_NEVER_INLINE +#ifdef _MSC_VER +#define TOML_NEVER_INLINE TOML_DECLSPEC(noinline) +#elif TOML_CUDA // https://gitlab.gnome.org/GNOME/glib/-/issues/2555 +#define TOML_NEVER_INLINE TOML_ATTR(noinline) +#else +#if TOML_GCC || TOML_CLANG || TOML_HAS_ATTR(__noinline__) +#define TOML_NEVER_INLINE TOML_ATTR(__noinline__) #endif - -#ifndef TOML_ALWAYS_INLINE - #define TOML_ALWAYS_INLINE inline #endif #ifndef TOML_NEVER_INLINE - #define TOML_NEVER_INLINE -#endif - -#ifndef TOML_ASSUME - #define TOML_ASSUME(expr) static_assert(true) +#define TOML_NEVER_INLINE #endif -#ifndef TOML_UNREACHABLE - #define TOML_UNREACHABLE TOML_ASSUME(false) -#endif +// MSVC attributes +#define TOML_ABSTRACT_INTERFACE TOML_DECLSPEC(novtable) +#define TOML_EMPTY_BASES TOML_DECLSPEC(empty_bases) -#ifndef TOML_FLAGS_ENUM - #define TOML_FLAGS_ENUM +// TOML_TRIVIAL_ABI +#if TOML_CLANG || TOML_HAS_ATTR(__trivial_abi__) +#define TOML_TRIVIAL_ABI TOML_ATTR(__trivial_abi__) +#else +#define TOML_TRIVIAL_ABI #endif -#ifndef TOML_OPEN_ENUM - #define TOML_OPEN_ENUM +// TOML_NODISCARD +#if TOML_CPP >= 17 && TOML_HAS_CPP_ATTR(nodiscard) >= 201603 +#define TOML_NODISCARD [[nodiscard]] +#elif TOML_CLANG || TOML_GCC || TOML_HAS_ATTR(__warn_unused_result__) +#define TOML_NODISCARD TOML_ATTR(__warn_unused_result__) +#else +#define TOML_NODISCARD #endif -#ifndef TOML_CLOSED_ENUM - #define TOML_CLOSED_ENUM +// TOML_NODISCARD_CTOR +#if TOML_CPP >= 17 && TOML_HAS_CPP_ATTR(nodiscard) >= 201907 +#define TOML_NODISCARD_CTOR [[nodiscard]] +#else +#define TOML_NODISCARD_CTOR #endif -#ifndef TOML_OPEN_FLAGS_ENUM - #define TOML_OPEN_FLAGS_ENUM TOML_OPEN_ENUM TOML_FLAGS_ENUM +// pure + const +#ifndef TOML_PURE +#ifdef NDEBUG +#define TOML_PURE \ + TOML_DECLSPEC(noalias) \ + TOML_ATTR(pure) +#else +#define TOML_PURE #endif - -#ifndef TOML_CLOSED_FLAGS_ENUM - #define TOML_CLOSED_FLAGS_ENUM TOML_CLOSED_ENUM TOML_FLAGS_ENUM #endif - -#ifdef __has_cpp_attribute - #define TOML_HAS_ATTR(...) __has_cpp_attribute(__VA_ARGS__) +#ifndef TOML_CONST +#ifdef NDEBUG +#define TOML_CONST \ + TOML_DECLSPEC(noalias) \ + TOML_ATTR(const) #else - #define TOML_HAS_ATTR(...) 0 +#define TOML_CONST #endif - -#if TOML_HAS_ATTR(likely) >= 201803 - #ifndef TOML_LIKELY - #define TOML_LIKELY(...) (__VA_ARGS__) [[likely]] - #endif - #ifndef TOML_LIKELY_CASE - #define TOML_LIKELY_CASE [[likely]] - #endif #endif -#ifndef TOML_LIKELY - #define TOML_LIKELY(...) (__VA_ARGS__) +#ifndef TOML_INLINE_GETTER +#define TOML_INLINE_GETTER \ + TOML_NODISCARD \ + TOML_ALWAYS_INLINE #endif -#ifndef TOML_LIKELY_CASE - #define TOML_LIKELY_CASE +#ifndef TOML_PURE_GETTER +#define TOML_PURE_GETTER \ + TOML_NODISCARD \ + TOML_PURE #endif - -#if TOML_HAS_ATTR(unlikely) >= 201803 - #ifndef TOML_UNLIKELY - #define TOML_UNLIKELY(...) (__VA_ARGS__) [[unlikely]] - #endif - #ifndef TOML_UNLIKELY_CASE - #define TOML_UNLIKELY_CASE [[unlikely]] - #endif +#ifndef TOML_PURE_INLINE_GETTER +#define TOML_PURE_INLINE_GETTER \ + TOML_NODISCARD \ + TOML_ALWAYS_INLINE \ + TOML_PURE #endif -#ifndef TOML_UNLIKELY - #define TOML_UNLIKELY(...) (__VA_ARGS__) +#ifndef TOML_CONST_GETTER +#define TOML_CONST_GETTER \ + TOML_NODISCARD \ + TOML_CONST #endif -#ifndef TOML_UNLIKELY_CASE - #define TOML_UNLIKELY_CASE +#ifndef TOML_CONST_INLINE_GETTER +#define TOML_CONST_INLINE_GETTER \ + TOML_NODISCARD \ + TOML_ALWAYS_INLINE \ + TOML_CONST #endif -#if TOML_HAS_ATTR(nodiscard) - #define TOML_NODISCARD [[nodiscard]] +// TOML_ASSUME +#ifdef _MSC_VER +#define TOML_ASSUME(expr) __assume(expr) +#elif TOML_ICC || TOML_CLANG || TOML_HAS_BUILTIN(__builtin_assume) +#define TOML_ASSUME(expr) __builtin_assume(expr) +#elif TOML_HAS_CPP_ATTR(assume) >= 202207 +#define TOML_ASSUME(expr) [[assume(expr)]] +#elif TOML_HAS_ATTR(__assume__) +#define TOML_ASSUME(expr) __attribute__((__assume__(expr))) #else - #define TOML_NODISCARD +#define TOML_ASSUME(expr) static_cast(0) #endif -#if TOML_HAS_ATTR(nodiscard) >= 201907 - #define TOML_NODISCARD_CTOR [[nodiscard]] +// TOML_UNREACHABLE +#ifdef _MSC_VER +#define TOML_UNREACHABLE __assume(0) +#elif TOML_ICC || TOML_CLANG || TOML_GCC || TOML_HAS_BUILTIN(__builtin_unreachable) +#define TOML_UNREACHABLE __builtin_unreachable() #else - #define TOML_NODISCARD_CTOR +#define TOML_UNREACHABLE static_cast(0) #endif -#ifndef TOML_TRIVIAL_ABI - #define TOML_TRIVIAL_ABI +// TOML_LIKELY +#if TOML_CPP >= 20 && TOML_HAS_CPP_ATTR(likely) >= 201803 +#define TOML_LIKELY(...) (__VA_ARGS__) [[likely]] +#define TOML_LIKELY_CASE [[likely]] +#elif TOML_GCC || TOML_CLANG || TOML_HAS_BUILTIN(__builtin_expect) +#define TOML_LIKELY(...) (__builtin_expect(!!(__VA_ARGS__), 1)) +#else +#define TOML_LIKELY(...) (__VA_ARGS__) #endif - -#define TOML_ASYMMETRICAL_EQUALITY_OPS(LHS, RHS, ...) \ - __VA_ARGS__ TOML_NODISCARD friend bool operator == (RHS rhs, LHS lhs) noexcept { return lhs == rhs; } \ - __VA_ARGS__ TOML_NODISCARD friend bool operator != (LHS lhs, RHS rhs) noexcept { return !(lhs == rhs); } \ - __VA_ARGS__ TOML_NODISCARD friend bool operator != (RHS rhs, LHS lhs) noexcept { return !(lhs == rhs); } \ - static_assert(true) - -#ifndef TOML_SIMPLE_STATIC_ASSERT_MESSAGES - #define TOML_SIMPLE_STATIC_ASSERT_MESSAGES 0 +#ifndef TOML_LIKELY_CASE +#define TOML_LIKELY_CASE #endif -#define TOML_CONCAT_1(x, y) x##y -#define TOML_CONCAT(x, y) TOML_CONCAT_1(x, y) - -#define TOML_EVAL_BOOL_1(T, F) T -#define TOML_EVAL_BOOL_0(T, F) F - -#if defined(__aarch64__) || defined(__ARM_ARCH_ISA_A64) || defined(_M_ARM64) || defined(__ARM_64BIT_STATE) \ - || defined(__arm__) || defined(_M_ARM) || defined(__ARM_32BIT_STATE) - #define TOML_ARM 1 +// TOML_UNLIKELY +#if TOML_CPP >= 20 && TOML_HAS_CPP_ATTR(unlikely) >= 201803 +#define TOML_UNLIKELY(...) (__VA_ARGS__) [[unlikely]] +#define TOML_UNLIKELY_CASE [[unlikely]] +#elif TOML_GCC || TOML_CLANG || TOML_HAS_BUILTIN(__builtin_expect) +#define TOML_UNLIKELY(...) (__builtin_expect(!!(__VA_ARGS__), 0)) #else - #define TOML_ARM 0 -#endif - -#define TOML_MAKE_FLAGS_(name, op) \ - TOML_CONST_INLINE_GETTER \ - constexpr name operator op(name lhs, name rhs) noexcept \ - { \ - using under = std::underlying_type_t; \ - return static_cast(static_cast(lhs) op static_cast(rhs)); \ - } \ - constexpr name& operator TOML_CONCAT(op, =)(name & lhs, name rhs) noexcept \ - { \ - return lhs = (lhs op rhs); \ - } \ - static_assert(true, "") - -#define TOML_MAKE_FLAGS(name) \ - TOML_MAKE_FLAGS_(name, &); \ - TOML_MAKE_FLAGS_(name, |); \ - TOML_MAKE_FLAGS_(name, ^); \ - TOML_CONST_INLINE_GETTER \ - constexpr name operator~(name val) noexcept \ - { \ - using under = std::underlying_type_t; \ - return static_cast(~static_cast(val)); \ - } \ - TOML_CONST_INLINE_GETTER \ - constexpr bool operator!(name val) noexcept \ - { \ - using under = std::underlying_type_t; \ - return !static_cast(val); \ - } \ - static_assert(true, "") - -#ifndef TOML_LIFETIME_HOOKS - #define TOML_LIFETIME_HOOKS 0 +#define TOML_UNLIKELY(...) (__VA_ARGS__) #endif - -#if !defined(__POXY__) && !defined(POXY_IMPLEMENTATION_DETAIL) - #define POXY_IMPLEMENTATION_DETAIL(...) __VA_ARGS__ +#ifndef TOML_UNLIKELY_CASE +#define TOML_UNLIKELY_CASE #endif -#if TOML_IMPLEMENTATION - #define TOML_EXTERN -#else - #define TOML_EXTERN extern -#endif -#if TOML_CLANG - #define TOML_EXTERN_NOEXCEPT(...) +// TOML_FLAGS_ENUM +#if TOML_CLANG || TOML_HAS_ATTR(flag_enum) +#define TOML_FLAGS_ENUM __attribute__((flag_enum)) #else - #define TOML_EXTERN_NOEXCEPT(...) noexcept(__VA_ARGS__) +#define TOML_FLAGS_ENUM #endif -#ifdef NDEBUG - #define TOML_PURE_GETTER TOML_NODISCARD TOML_ATTR(pure) - #define TOML_CONST_GETTER TOML_NODISCARD TOML_ATTR(const) - #define TOML_PURE_INLINE_GETTER TOML_NODISCARD TOML_ALWAYS_INLINE TOML_ATTR(pure) - #define TOML_CONST_INLINE_GETTER TOML_NODISCARD TOML_ALWAYS_INLINE TOML_ATTR(const) +// TOML_OPEN_ENUM + TOML_CLOSED_ENUM +#if TOML_CLANG || TOML_HAS_ATTR(enum_extensibility) +#define TOML_OPEN_ENUM __attribute__((enum_extensibility(open))) +#define TOML_CLOSED_ENUM __attribute__((enum_extensibility(closed))) #else - #define TOML_PURE_GETTER TOML_NODISCARD - #define TOML_CONST_GETTER TOML_NODISCARD - #define TOML_PURE_INLINE_GETTER TOML_NODISCARD TOML_ALWAYS_INLINE - #define TOML_CONST_INLINE_GETTER TOML_NODISCARD TOML_ALWAYS_INLINE +#define TOML_OPEN_ENUM +#define TOML_CLOSED_ENUM #endif +// TOML_OPEN_FLAGS_ENUM + TOML_CLOSED_FLAGS_ENUM +#define TOML_OPEN_FLAGS_ENUM TOML_OPEN_ENUM TOML_FLAGS_ENUM +#define TOML_CLOSED_FLAGS_ENUM TOML_CLOSED_ENUM TOML_FLAGS_ENUM + +// TOML_MAKE_FLAGS +#define TOML_MAKE_FLAGS_2(T, op, linkage) \ + TOML_CONST_INLINE_GETTER \ + linkage constexpr T operator op(T lhs, T rhs) noexcept \ + { \ + using under = std::underlying_type_t; \ + return static_cast(static_cast(lhs) op static_cast(rhs)); \ + } \ + \ + linkage constexpr T& operator TOML_CONCAT(op, =)(T & lhs, T rhs) noexcept \ + { \ + return lhs = (lhs op rhs); \ + } \ + \ + static_assert(true) +#define TOML_MAKE_FLAGS_1(T, linkage) \ + static_assert(std::is_enum_v); \ + \ + TOML_MAKE_FLAGS_2(T, &, linkage); \ + TOML_MAKE_FLAGS_2(T, |, linkage); \ + TOML_MAKE_FLAGS_2(T, ^, linkage); \ + \ + TOML_CONST_INLINE_GETTER \ + linkage constexpr T operator~(T val) noexcept \ + { \ + using under = std::underlying_type_t; \ + return static_cast(~static_cast(val)); \ + } \ + \ + TOML_CONST_INLINE_GETTER \ + linkage constexpr bool operator!(T val) noexcept \ + { \ + using under = std::underlying_type_t; \ + return !static_cast(val); \ + } \ + \ + static_assert(true) +#define TOML_MAKE_FLAGS(T) TOML_MAKE_FLAGS_1(T, ) + #define TOML_UNUSED(...) static_cast(__VA_ARGS__) #define TOML_DELETE_DEFAULTS(T) \ - T(const T&) = delete; \ - T(T&&) = delete; \ + T(const T&) = delete; \ + T(T&&) = delete; \ T& operator=(const T&) = delete; \ - T& operator=(T&&) = delete + T& operator=(T&&) = delete -// SFINAE -#if defined(__cpp_concepts) && __cpp_concepts >= 201907 - #define TOML_REQUIRES(...) requires(__VA_ARGS__) -#else - #define TOML_REQUIRES(...) -#endif -#define TOML_ENABLE_IF(...) , typename std::enable_if<(__VA_ARGS__), int>::type = 0 -#define TOML_CONSTRAINED_TEMPLATE(condition, ...) template <__VA_ARGS__ TOML_ENABLE_IF(condition)> TOML_REQUIRES(condition) -#define TOML_HIDDEN_CONSTRAINT(condition, ...) TOML_CONSTRAINED_TEMPLATE(condition, __VA_ARGS__) - -#ifdef __FLT16_MANT_DIG__ - #if __FLT_RADIX__ == 2 \ - && __FLT16_MANT_DIG__ == 11 \ - && __FLT16_DIG__ == 3 \ - && __FLT16_MIN_EXP__ == -13 \ - && __FLT16_MIN_10_EXP__ == -4 \ - && __FLT16_MAX_EXP__ == 16 \ - && __FLT16_MAX_10_EXP__ == 4 - #if TOML_ARM && (TOML_GCC || TOML_CLANG) - #define TOML_FP16 __fp16 - #endif - #if TOML_ARM && TOML_CLANG // not present in g++ - #define TOML_FLOAT16 _Float16 - #endif - #endif -#endif +#define TOML_ASYMMETRICAL_EQUALITY_OPS(LHS, RHS, ...) \ + __VA_ARGS__ TOML_NODISCARD \ + friend bool operator==(RHS rhs, LHS lhs) noexcept \ + { \ + return lhs == rhs; \ + } \ + __VA_ARGS__ TOML_NODISCARD \ + friend bool operator!=(LHS lhs, RHS rhs) noexcept \ + { \ + return !(lhs == rhs); \ + } \ + __VA_ARGS__ TOML_NODISCARD \ + friend bool operator!=(RHS rhs, LHS lhs) noexcept \ + { \ + return !(lhs == rhs); \ + } \ + static_assert(true) -#if defined(__SIZEOF_FLOAT128__) \ - && defined(__FLT128_MANT_DIG__) \ - && defined(__LDBL_MANT_DIG__) \ - && __FLT128_MANT_DIG__ > __LDBL_MANT_DIG__ - #define TOML_FLOAT128 __float128 -#endif +#define TOML_EVAL_BOOL_1(T, F) T +#define TOML_EVAL_BOOL_0(T, F) F -#ifdef __SIZEOF_INT128__ - #define TOML_INT128 __int128_t - #define TOML_UINT128 __uint128_t +#if !defined(__POXY__) && !defined(POXY_IMPLEMENTATION_DETAIL) +#define POXY_IMPLEMENTATION_DETAIL(...) __VA_ARGS__ #endif -#define TOML_LIB_MAJOR 3 -#define TOML_LIB_MINOR 0 -#define TOML_LIB_PATCH 1 +// COMPILER-SPECIFIC WARNING MANAGEMENT -#define TOML_LANG_MAJOR 1 -#define TOML_LANG_MINOR 0 -#define TOML_LANG_PATCH 0 +#if TOML_CLANG -#define TOML_LIB_SINGLE_HEADER 1 +#define TOML_PUSH_WARNINGS \ + TOML_PRAGMA_CLANG(diagnostic push) \ + TOML_PRAGMA_CLANG(diagnostic ignored "-Wunknown-warning-option") \ + static_assert(true) -#define TOML_MAKE_VERSION(major, minor, patch) \ - ((major) * 10000 + (minor) * 100 + (patch)) +#define TOML_DISABLE_SWITCH_WARNINGS \ + TOML_PRAGMA_CLANG(diagnostic ignored "-Wswitch") \ + static_assert(true) -#if TOML_ENABLE_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_DISABLE_ARITHMETIC_WARNINGS \ + TOML_PRAGMA_CLANG_GE_10(diagnostic ignored "-Wimplicit-int-float-conversion") \ + TOML_PRAGMA_CLANG(diagnostic ignored "-Wfloat-equal") \ + TOML_PRAGMA_CLANG(diagnostic ignored "-Wdouble-promotion") \ + TOML_PRAGMA_CLANG(diagnostic ignored "-Wchar-subscripts") \ + TOML_PRAGMA_CLANG(diagnostic ignored "-Wshift-sign-overflow") \ + static_assert(true) -#define TOML_LANG_HIGHER_THAN(major, minor, patch) \ - (TOML_LANG_EFFECTIVE_VERSION > TOML_MAKE_VERSION(major, minor, patch)) +#define TOML_DISABLE_SPAM_WARNINGS \ + TOML_PRAGMA_CLANG_GE_8(diagnostic ignored "-Wdefaulted-function-deleted") \ + TOML_PRAGMA_CLANG_GE_9(diagnostic ignored "-Wctad-maybe-unsupported") \ + TOML_PRAGMA_CLANG_GE_10(diagnostic ignored "-Wzero-as-null-pointer-constant") \ + TOML_PRAGMA_CLANG_GE_11(diagnostic ignored "-Wsuggest-destructor-override") \ + TOML_PRAGMA_CLANG(diagnostic ignored "-Wweak-vtables") \ + TOML_PRAGMA_CLANG(diagnostic ignored "-Wweak-template-vtables") \ + TOML_PRAGMA_CLANG(diagnostic ignored "-Wdouble-promotion") \ + TOML_PRAGMA_CLANG(diagnostic ignored "-Wchar-subscripts") \ + TOML_PRAGMA_CLANG(diagnostic ignored "-Wmissing-field-initializers") \ + TOML_PRAGMA_CLANG(diagnostic ignored "-Wpadded") \ + static_assert(true) -#define TOML_LANG_AT_LEAST(major, minor, patch) \ - (TOML_LANG_EFFECTIVE_VERSION >= TOML_MAKE_VERSION(major, minor, patch)) +#define TOML_POP_WARNINGS \ + TOML_PRAGMA_CLANG(diagnostic pop) \ + static_assert(true) -#define TOML_LANG_UNRELEASED \ - TOML_LANG_HIGHER_THAN(TOML_LANG_MAJOR, TOML_LANG_MINOR, TOML_LANG_PATCH) +#define TOML_DISABLE_WARNINGS \ + TOML_PRAGMA_CLANG(diagnostic push) \ + TOML_PRAGMA_CLANG(diagnostic ignored "-Weverything") \ + static_assert(true, "") -#ifndef TOML_ABI_NAMESPACES - #ifdef DOXYGEN +#define TOML_ENABLE_WARNINGS \ + TOML_PRAGMA_CLANG(diagnostic pop) \ + static_assert(true) + +#define TOML_SIMPLE_STATIC_ASSERT_MESSAGES 1 + +#elif TOML_MSVC + +#define TOML_PUSH_WARNINGS \ + __pragma(warning(push)) \ + static_assert(true) + +#if TOML_HAS_INCLUDE() +#pragma warning(push, 0) +#include +#pragma warning(pop) +#define TOML_DISABLE_CODE_ANALYSIS_WARNINGS \ + __pragma(warning(disable : ALL_CODE_ANALYSIS_WARNINGS)) \ + static_assert(true) +#else +#define TOML_DISABLE_CODE_ANALYSIS_WARNINGS static_assert(true) +#endif + +#define TOML_DISABLE_SWITCH_WARNINGS \ + __pragma(warning(disable : 4061)) \ + __pragma(warning(disable : 4062)) \ + __pragma(warning(disable : 4063)) \ + __pragma(warning(disable : 5262)) /* switch-case implicit fallthrough (false-positive) */ \ + __pragma(warning(disable : 26819)) /* cg: unannotated fallthrough */ \ + static_assert(true) + +#define TOML_DISABLE_SPAM_WARNINGS \ + __pragma(warning(disable : 4127)) /* conditional expr is constant */ \ + __pragma(warning(disable : 4324)) /* structure was padded due to alignment specifier */ \ + __pragma(warning(disable : 4348)) \ + __pragma(warning(disable : 4464)) /* relative include path contains '..' */ \ + __pragma(warning(disable : 4505)) /* unreferenced local function removed */ \ + __pragma(warning(disable : 4514)) /* unreferenced inline function has been removed */ \ + __pragma(warning(disable : 4582)) /* constructor is not implicitly called */ \ + __pragma(warning(disable : 4619)) /* there is no warning number 'XXXX' */ \ + __pragma(warning(disable : 4623)) /* default constructor was implicitly defined as deleted */ \ + __pragma(warning(disable : 4625)) /* copy constructor was implicitly defined as deleted */ \ + __pragma(warning(disable : 4626)) /* assignment operator was implicitly defined as deleted */ \ + __pragma(warning(disable : 4710)) /* function not inlined */ \ + __pragma(warning(disable : 4711)) /* function selected for automatic expansion */ \ + __pragma(warning(disable : 4820)) /* N bytes padding added */ \ + __pragma(warning(disable : 4946)) /* reinterpret_cast used between related classes */ \ + __pragma(warning(disable : 5026)) /* move constructor was implicitly defined as deleted */ \ + __pragma(warning(disable : 5027)) /* move assignment operator was implicitly defined as deleted */ \ + __pragma(warning(disable : 5039)) /* potentially throwing function passed to 'extern "C"' function */ \ + __pragma(warning(disable : 5045)) /* Compiler will insert Spectre mitigation */ \ + __pragma(warning(disable : 5264)) /* const variable is not used (false-positive) */ \ + __pragma(warning(disable : 26451)) \ + __pragma(warning(disable : 26490)) \ + __pragma(warning(disable : 26495)) \ + __pragma(warning(disable : 26812)) \ + __pragma(warning(disable : 26819)) \ + static_assert(true) + +#define TOML_DISABLE_ARITHMETIC_WARNINGS \ + __pragma(warning(disable : 4365)) /* argument signed/unsigned mismatch */ \ + __pragma(warning(disable : 4738)) /* storing 32-bit float result in memory */ \ + __pragma(warning(disable : 5219)) /* implicit conversion from integral to float */ \ + static_assert(true) + +#define TOML_POP_WARNINGS \ + __pragma(warning(pop)) \ + static_assert(true) + +#define TOML_DISABLE_WARNINGS \ + __pragma(warning(push, 0)) \ + __pragma(warning(disable : 4348)) \ + __pragma(warning(disable : 4668)) \ + __pragma(warning(disable : 5105)) \ + __pragma(warning(disable : 5264)) \ + TOML_DISABLE_CODE_ANALYSIS_WARNINGS; \ + TOML_DISABLE_SWITCH_WARNINGS; \ + TOML_DISABLE_SPAM_WARNINGS; \ + TOML_DISABLE_ARITHMETIC_WARNINGS; \ + static_assert(true) + +#define TOML_ENABLE_WARNINGS TOML_POP_WARNINGS + +#elif TOML_ICC + +#define TOML_PUSH_WARNINGS \ + __pragma(warning(push)) \ + static_assert(true) + +#define TOML_DISABLE_SPAM_WARNINGS \ + __pragma(warning(disable : 82)) /* storage class is not first */ \ + __pragma(warning(disable : 111)) /* statement unreachable (false-positive) */ \ + __pragma(warning(disable : 869)) /* unreferenced parameter */ \ + __pragma(warning(disable : 1011)) /* missing return (false-positive) */ \ + __pragma(warning(disable : 2261)) /* assume expr side-effects discarded */ \ + static_assert(true) + +#define TOML_POP_WARNINGS \ + __pragma(warning(pop)) \ + static_assert(true) + +#define TOML_DISABLE_WARNINGS \ + __pragma(warning(push, 0)) \ + TOML_DISABLE_SPAM_WARNINGS + +#define TOML_ENABLE_WARNINGS \ + __pragma(warning(pop)) \ + static_assert(true) + +#elif TOML_GCC + +#define TOML_PUSH_WARNINGS \ + TOML_PRAGMA_GCC(diagnostic push) \ + static_assert(true) + +#define TOML_DISABLE_SWITCH_WARNINGS \ + TOML_PRAGMA_GCC(diagnostic ignored "-Wswitch") \ + TOML_PRAGMA_GCC(diagnostic ignored "-Wswitch-enum") \ + TOML_PRAGMA_GCC(diagnostic ignored "-Wswitch-default") \ + static_assert(true) + +#define TOML_DISABLE_ARITHMETIC_WARNINGS \ + TOML_PRAGMA_GCC(diagnostic ignored "-Wfloat-equal") \ + TOML_PRAGMA_GCC(diagnostic ignored "-Wsign-conversion") \ + TOML_PRAGMA_GCC(diagnostic ignored "-Wchar-subscripts") \ + static_assert(true) + +#define TOML_DISABLE_SUGGEST_ATTR_WARNINGS \ + TOML_PRAGMA_GCC(diagnostic ignored "-Wsuggest-attribute=const") \ + TOML_PRAGMA_GCC(diagnostic ignored "-Wsuggest-attribute=pure") \ + static_assert(true) + +#define TOML_DISABLE_SPAM_WARNINGS \ + TOML_PRAGMA_GCC(diagnostic ignored "-Wpadded") \ + TOML_PRAGMA_GCC(diagnostic ignored "-Wcast-align") \ + TOML_PRAGMA_GCC(diagnostic ignored "-Wcomment") \ + TOML_PRAGMA_GCC(diagnostic ignored "-Wtype-limits") \ + TOML_PRAGMA_GCC(diagnostic ignored "-Wuseless-cast") \ + TOML_PRAGMA_GCC(diagnostic ignored "-Wchar-subscripts") \ + TOML_PRAGMA_GCC(diagnostic ignored "-Wsubobject-linkage") \ + TOML_PRAGMA_GCC(diagnostic ignored "-Wmissing-field-initializers") \ + TOML_PRAGMA_GCC(diagnostic ignored "-Wmaybe-uninitialized") \ + TOML_PRAGMA_GCC(diagnostic ignored "-Wnoexcept") \ + TOML_PRAGMA_GCC(diagnostic ignored "-Wnull-dereference") \ + TOML_PRAGMA_GCC(diagnostic ignored "-Wduplicated-branches") \ + static_assert(true) + +#define TOML_POP_WARNINGS \ + TOML_PRAGMA_GCC(diagnostic pop) \ + static_assert(true) + +#define TOML_DISABLE_WARNINGS \ + TOML_PRAGMA_GCC(diagnostic push) \ + TOML_PRAGMA_GCC(diagnostic ignored "-Wall") \ + TOML_PRAGMA_GCC(diagnostic ignored "-Wextra") \ + TOML_PRAGMA_GCC(diagnostic ignored "-Wpedantic") \ + TOML_DISABLE_SWITCH_WARNINGS; \ + TOML_DISABLE_ARITHMETIC_WARNINGS; \ + TOML_DISABLE_SUGGEST_ATTR_WARNINGS; \ + TOML_DISABLE_SPAM_WARNINGS; \ + static_assert(true) + +#define TOML_ENABLE_WARNINGS \ + TOML_PRAGMA_GCC(diagnostic pop) \ + static_assert(true) + +#endif + +#ifndef TOML_PUSH_WARNINGS +#define TOML_PUSH_WARNINGS static_assert(true) +#endif +#ifndef TOML_DISABLE_CODE_ANALYSIS_WARNINGS +#define TOML_DISABLE_CODE_ANALYSIS_WARNINGS static_assert(true) +#endif +#ifndef TOML_DISABLE_SWITCH_WARNINGS +#define TOML_DISABLE_SWITCH_WARNINGS static_assert(true) +#endif +#ifndef TOML_DISABLE_SUGGEST_ATTR_WARNINGS +#define TOML_DISABLE_SUGGEST_ATTR_WARNINGS static_assert(true) +#endif +#ifndef TOML_DISABLE_SPAM_WARNINGS +#define TOML_DISABLE_SPAM_WARNINGS static_assert(true) +#endif +#ifndef TOML_DISABLE_ARITHMETIC_WARNINGS +#define TOML_DISABLE_ARITHMETIC_WARNINGS static_assert(true) +#endif +#ifndef TOML_POP_WARNINGS +#define TOML_POP_WARNINGS static_assert(true) +#endif +#ifndef TOML_DISABLE_WARNINGS +#define TOML_DISABLE_WARNINGS static_assert(true) +#endif +#ifndef TOML_ENABLE_WARNINGS +#define TOML_ENABLE_WARNINGS static_assert(true) +#endif +#ifndef TOML_SIMPLE_STATIC_ASSERT_MESSAGES +#define TOML_SIMPLE_STATIC_ASSERT_MESSAGES 0 +#endif + +#ifdef TOML_CONFIG_HEADER +#include TOML_CONFIG_HEADER +#endif + +// is the library being built as a shared lib/dll using meson and friends? +#ifndef TOML_SHARED_LIB +#define TOML_SHARED_LIB 0 +#endif + +// header-only mode +#if !defined(TOML_HEADER_ONLY) && defined(TOML_ALL_INLINE) // was TOML_ALL_INLINE pre-2.0 +#define TOML_HEADER_ONLY TOML_ALL_INLINE +#endif +#if !defined(TOML_HEADER_ONLY) || (defined(TOML_HEADER_ONLY) && TOML_HEADER_ONLY) || TOML_INTELLISENSE +#undef TOML_HEADER_ONLY +#define TOML_HEADER_ONLY 1 +#endif +#if TOML_DOXYGEN || TOML_SHARED_LIB +#undef TOML_HEADER_ONLY +#define TOML_HEADER_ONLY 0 +#endif + +// internal implementation switch +#if defined(TOML_IMPLEMENTATION) || TOML_HEADER_ONLY +#undef TOML_IMPLEMENTATION +#define TOML_IMPLEMENTATION 1 +#else +#define TOML_IMPLEMENTATION 0 +#endif + +// dll/shared lib function exports (legacy - TOML_API was the old name for this setting) +#if !defined(TOML_EXPORTED_MEMBER_FUNCTION) && !defined(TOML_EXPORTED_STATIC_FUNCTION) \ + && !defined(TOML_EXPORTED_FREE_FUNCTION) && !defined(TOML_EXPORTED_CLASS) && defined(TOML_API) +#define TOML_EXPORTED_MEMBER_FUNCTION TOML_API +#define TOML_EXPORTED_STATIC_FUNCTION TOML_API +#define TOML_EXPORTED_FREE_FUNCTION TOML_API +#endif + +// dll/shared lib exports +#if TOML_SHARED_LIB +#undef TOML_API +#undef TOML_EXPORTED_CLASS +#undef TOML_EXPORTED_MEMBER_FUNCTION +#undef TOML_EXPORTED_STATIC_FUNCTION +#undef TOML_EXPORTED_FREE_FUNCTION +#if TOML_WINDOWS +#if TOML_IMPLEMENTATION +#define TOML_EXPORTED_CLASS __declspec(dllexport) +#define TOML_EXPORTED_FREE_FUNCTION __declspec(dllexport) +#else +#define TOML_EXPORTED_CLASS __declspec(dllimport) +#define TOML_EXPORTED_FREE_FUNCTION __declspec(dllimport) +#endif +#ifndef TOML_CALLCONV +#define TOML_CALLCONV __cdecl +#endif +#elif defined(__GNUC__) && __GNUC__ >= 4 +#define TOML_EXPORTED_CLASS __attribute__((visibility("default"))) +#define TOML_EXPORTED_MEMBER_FUNCTION __attribute__((visibility("default"))) +#define TOML_EXPORTED_STATIC_FUNCTION __attribute__((visibility("default"))) +#define TOML_EXPORTED_FREE_FUNCTION __attribute__((visibility("default"))) +#endif +#endif +#ifndef TOML_EXPORTED_CLASS +#define TOML_EXPORTED_CLASS +#endif +#ifndef TOML_EXPORTED_MEMBER_FUNCTION +#define TOML_EXPORTED_MEMBER_FUNCTION +#endif +#ifndef TOML_EXPORTED_STATIC_FUNCTION +#define TOML_EXPORTED_STATIC_FUNCTION +#endif +#ifndef TOML_EXPORTED_FREE_FUNCTION +#define TOML_EXPORTED_FREE_FUNCTION +#endif + +// experimental language features +#if !defined(TOML_ENABLE_UNRELEASED_FEATURES) && defined(TOML_UNRELEASED_FEATURES) // was TOML_UNRELEASED_FEATURES + // pre-3.0 +#define TOML_ENABLE_UNRELEASED_FEATURES TOML_UNRELEASED_FEATURES +#endif +#if (defined(TOML_ENABLE_UNRELEASED_FEATURES) && TOML_ENABLE_UNRELEASED_FEATURES) || TOML_INTELLISENSE +#undef TOML_ENABLE_UNRELEASED_FEATURES +#define TOML_ENABLE_UNRELEASED_FEATURES 1 +#endif +#ifndef TOML_ENABLE_UNRELEASED_FEATURES +#define TOML_ENABLE_UNRELEASED_FEATURES 0 +#endif + +// parser +#if !defined(TOML_ENABLE_PARSER) && defined(TOML_PARSER) // was TOML_PARSER pre-3.0 +#define TOML_ENABLE_PARSER TOML_PARSER +#endif +#if !defined(TOML_ENABLE_PARSER) || (defined(TOML_ENABLE_PARSER) && TOML_ENABLE_PARSER) || TOML_INTELLISENSE +#undef TOML_ENABLE_PARSER +#define TOML_ENABLE_PARSER 1 +#endif + +// formatters +#if !defined(TOML_ENABLE_FORMATTERS) || (defined(TOML_ENABLE_FORMATTERS) && TOML_ENABLE_FORMATTERS) || TOML_INTELLISENSE +#undef TOML_ENABLE_FORMATTERS +#define TOML_ENABLE_FORMATTERS 1 +#endif + +// SIMD +#if !defined(TOML_ENABLE_SIMD) || (defined(TOML_ENABLE_SIMD) && TOML_ENABLE_SIMD) || TOML_INTELLISENSE +#undef TOML_ENABLE_SIMD +#define TOML_ENABLE_SIMD 1 +#endif + +// windows compat +#if !defined(TOML_ENABLE_WINDOWS_COMPAT) && defined(TOML_WINDOWS_COMPAT) // was TOML_WINDOWS_COMPAT pre-3.0 +#define TOML_ENABLE_WINDOWS_COMPAT TOML_WINDOWS_COMPAT +#endif +#if !defined(TOML_ENABLE_WINDOWS_COMPAT) || (defined(TOML_ENABLE_WINDOWS_COMPAT) && TOML_ENABLE_WINDOWS_COMPAT) \ + || TOML_INTELLISENSE +#undef TOML_ENABLE_WINDOWS_COMPAT +#define TOML_ENABLE_WINDOWS_COMPAT 1 +#endif + +#if !TOML_WINDOWS +#undef TOML_ENABLE_WINDOWS_COMPAT +#define TOML_ENABLE_WINDOWS_COMPAT 0 +#endif + +#ifndef TOML_INCLUDE_WINDOWS_H +#define TOML_INCLUDE_WINDOWS_H 0 +#endif + +// custom optional +#ifdef TOML_OPTIONAL_TYPE +#define TOML_HAS_CUSTOM_OPTIONAL_TYPE 1 +#else +#define TOML_HAS_CUSTOM_OPTIONAL_TYPE 0 +#endif + +// exceptions (library use) +#if TOML_COMPILER_HAS_EXCEPTIONS +#if !defined(TOML_EXCEPTIONS) || (defined(TOML_EXCEPTIONS) && TOML_EXCEPTIONS) +#undef 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 + +// calling convention for static/free/friend functions +#ifndef TOML_CALLCONV +#define TOML_CALLCONV +#endif + +#ifndef TOML_UNDEF_MACROS +#define TOML_UNDEF_MACROS 1 +#endif + +#ifndef TOML_MAX_NESTED_VALUES +#define TOML_MAX_NESTED_VALUES 256 +// this refers to the depth of nested values, e.g. inline tables and arrays. +// 256 is crazy high! if you're hitting this limit with real input, TOML is probably the wrong tool for the job... +#endif + +#ifdef TOML_CHAR_8_STRINGS +#if TOML_CHAR_8_STRINGS +#error TOML_CHAR_8_STRINGS was removed in toml++ 2.0.0; all value setters and getters now work with char8_t strings implicitly. +#endif +#endif + +#ifdef TOML_LARGE_FILES +#if !TOML_LARGE_FILES +#error Support for !TOML_LARGE_FILES (i.e. 'small files') was removed in toml++ 3.0.0. +#endif +#endif + +#ifndef TOML_LIFETIME_HOOKS +#define TOML_LIFETIME_HOOKS 0 +#endif + +#ifdef NDEBUG +#undef TOML_ASSERT +#define TOML_ASSERT(expr) static_assert(true) +#endif +#ifndef TOML_ASSERT +#ifndef assert +TOML_DISABLE_WARNINGS; +#include +TOML_ENABLE_WARNINGS; +#endif +#define TOML_ASSERT(expr) assert(expr) +#endif +#ifdef NDEBUG +#define TOML_ASSERT_ASSUME(expr) TOML_ASSUME(expr) +#else +#define TOML_ASSERT_ASSUME(expr) TOML_ASSERT(expr) +#endif + +#ifndef TOML_ENABLE_FLOAT16 +#define TOML_ENABLE_FLOAT16 0 +#endif + +#if !defined(TOML_FLOAT_CHARCONV) && (TOML_GCC || TOML_CLANG || (TOML_ICC && !TOML_ICC_CL)) +// not supported by any version of GCC or Clang as of 26/11/2020 +// not supported by any version of ICC on Linux as of 11/01/2021 +#define TOML_FLOAT_CHARCONV 0 +#endif +#if !defined(TOML_INT_CHARCONV) && (defined(__EMSCRIPTEN__) || defined(__APPLE__)) +// causes link errors on emscripten +// causes Mac OS SDK version errors on some versions of Apple Clang +#define TOML_INT_CHARCONV 0 +#endif +#ifndef TOML_INT_CHARCONV +#define TOML_INT_CHARCONV 1 +#endif +#ifndef TOML_FLOAT_CHARCONV +#define TOML_FLOAT_CHARCONV 1 +#endif +#if (TOML_INT_CHARCONV || TOML_FLOAT_CHARCONV) && !TOML_HAS_INCLUDE() +#undef TOML_INT_CHARCONV +#undef TOML_FLOAT_CHARCONV +#define TOML_INT_CHARCONV 0 +#define TOML_FLOAT_CHARCONV 0 +#endif + +#if defined(__cpp_concepts) && __cpp_concepts >= 201907 +#define TOML_REQUIRES(...) requires(__VA_ARGS__) +#else +#define TOML_REQUIRES(...) +#endif +#define TOML_ENABLE_IF(...) , typename std::enable_if<(__VA_ARGS__), int>::type = 0 +#define TOML_CONSTRAINED_TEMPLATE(condition, ...) \ + template <__VA_ARGS__ TOML_ENABLE_IF(condition)> \ + TOML_REQUIRES(condition) +#define TOML_HIDDEN_CONSTRAINT(condition, ...) TOML_CONSTRAINED_TEMPLATE(condition, __VA_ARGS__) + +#if defined(__SIZEOF_FLOAT128__) && defined(__FLT128_MANT_DIG__) && defined(__LDBL_MANT_DIG__) \ + && __FLT128_MANT_DIG__ > __LDBL_MANT_DIG__ +#define TOML_FLOAT128 __float128 +#endif + +#ifdef __SIZEOF_INT128__ +#define TOML_INT128 __int128_t +#define TOML_UINT128 __uint128_t +#endif + +// clang-format off + +//******** impl/version.hpp ****************************************************************************************** + +#define TOML_LIB_MAJOR 3 +#define TOML_LIB_MINOR 4 +#define TOML_LIB_PATCH 0 + +#define TOML_LANG_MAJOR 1 +#define TOML_LANG_MINOR 0 +#define TOML_LANG_PATCH 0 + +//******** impl/preprocessor.hpp ************************************************************************************* + +#define TOML_LIB_SINGLE_HEADER 1 + +#if TOML_ENABLE_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(major, minor, patch) \ + (TOML_LANG_EFFECTIVE_VERSION > TOML_MAKE_VERSION(major, minor, patch)) + +#define TOML_LANG_AT_LEAST(major, minor, patch) \ + (TOML_LANG_EFFECTIVE_VERSION >= TOML_MAKE_VERSION(major, minor, patch)) + +#define TOML_LANG_UNRELEASED \ + TOML_LANG_HIGHER_THAN(TOML_LANG_MAJOR, TOML_LANG_MINOR, TOML_LANG_PATCH) + +#ifndef TOML_ABI_NAMESPACES + #if TOML_DOXYGEN #define TOML_ABI_NAMESPACES 0 #else #define TOML_ABI_NAMESPACES 1 @@ -878,23 +1220,9 @@ #define TOML_INTERNAL_LINKAGE static #endif -#ifdef NDEBUG - #undef TOML_ASSERT - #define TOML_ASSERT(expr) static_assert(true) -#endif -#ifndef TOML_ASSERT - #ifndef assert - TOML_DISABLE_WARNINGS; - #include - TOML_ENABLE_WARNINGS; - #endif - #define TOML_ASSERT(expr) assert(expr) -#endif -#ifdef NDEBUG - #define TOML_ASSERT_ASSUME(expr) TOML_ASSUME(expr) -#else - #define TOML_ASSERT_ASSUME(expr) TOML_ASSERT(expr) -#endif +// clang-format on + +// clang-format off #if TOML_SIMPLE_STATIC_ASSERT_MESSAGES @@ -955,23 +1283,26 @@ TOML_DISABLE_SUGGEST_ATTR_WARNINGS; // misc warning false-positives #if TOML_MSVC #pragma warning(disable : 5031) // #pragma warning(pop): likely mismatch +#if TOML_SHARED_LIB +#pragma warning(disable : 4251) // dll exports for std lib types +#endif #elif TOML_CLANG -#pragma clang diagnostic ignored "-Wheader-hygiene" +TOML_PRAGMA_CLANG(diagnostic ignored "-Wheader-hygiene") #if TOML_CLANG >= 12 -#pragma clang diagnostic ignored "-Wc++20-extensions" +TOML_PRAGMA_CLANG(diagnostic ignored "-Wc++20-extensions") #endif #if TOML_CLANG == 13 -#pragma clang diagnostic ignored "-Wreserved-identifier" +TOML_PRAGMA_CLANG(diagnostic ignored "-Wreserved-identifier") #endif #endif -//******** impl/std_new.h ******************************************************************************************** +//******** impl/std_new.hpp ****************************************************************************************** TOML_DISABLE_WARNINGS; #include TOML_ENABLE_WARNINGS; -#if TOML_CLANG >= 8 || TOML_GCC >= 7 || TOML_ICC >= 1910 || TOML_MSVC >= 1914 +#if (!defined(__apple_build_version__) && TOML_CLANG >= 8) || TOML_GCC >= 7 || TOML_ICC >= 1910 || TOML_MSVC >= 1914 #define TOML_LAUNDER(x) __builtin_launder(x) #elif defined(__cpp_lib_launder) && __cpp_lib_launder >= 201606 #define TOML_LAUNDER(x) std::launder(x) @@ -979,14 +1310,14 @@ TOML_ENABLE_WARNINGS; #define TOML_LAUNDER(x) x #endif -//******** impl/std_string.h ***************************************************************************************** +//******** impl/std_string.hpp *************************************************************************************** TOML_DISABLE_WARNINGS; #include #include TOML_ENABLE_WARNINGS; -#if defined(DOXYGEN) \ +#if TOML_DOXYGEN \ || (defined(__cpp_char8_t) && __cpp_char8_t >= 201811 && defined(__cpp_lib_char8_t) \ && __cpp_lib_char8_t >= 201907) #define TOML_HAS_CHAR8 1 @@ -1005,17 +1336,17 @@ namespace toml // non-abi namespace; this is not an error TOML_IMPL_NAMESPACE_START { TOML_NODISCARD - TOML_API + TOML_EXPORTED_FREE_FUNCTION std::string narrow(std::wstring_view); TOML_NODISCARD - TOML_API + TOML_EXPORTED_FREE_FUNCTION std::wstring widen(std::string_view); #if TOML_HAS_CHAR8 TOML_NODISCARD - TOML_API + TOML_EXPORTED_FREE_FUNCTION std::wstring widen(std::u8string_view); #endif @@ -1024,7 +1355,7 @@ TOML_IMPL_NAMESPACE_END; #endif // TOML_ENABLE_WINDOWS_COMPAT -//******** impl/std_optional.h *************************************************************************************** +//******** impl/std_optional.hpp ************************************************************************************* TOML_DISABLE_WARNINGS; #if !TOML_HAS_CUSTOM_OPTIONAL_TYPE @@ -1048,7 +1379,7 @@ TOML_NAMESPACE_START } TOML_NAMESPACE_END; -//******** impl/forward_declarations.h ******************************************************************************* +//******** impl/forward_declarations.hpp ***************************************************************************** TOML_DISABLE_WARNINGS; #include @@ -1064,6 +1395,9 @@ TOML_DISABLE_WARNINGS; TOML_ENABLE_WARNINGS; TOML_PUSH_WARNINGS; #ifdef _MSC_VER +#ifndef __clang__ +#pragma inline_recursion(on) +#endif #pragma push_macro("min") #pragma push_macro("max") #undef min @@ -1080,12 +1414,15 @@ TOML_PUSH_WARNINGS; "Thanks!" static_assert(CHAR_BIT == 8, TOML_ENV_MESSAGE); +#ifdef FLT_RADIX static_assert(FLT_RADIX == 2, TOML_ENV_MESSAGE); +#endif static_assert('A' == 65, TOML_ENV_MESSAGE); static_assert(sizeof(double) == 8, TOML_ENV_MESSAGE); static_assert(std::numeric_limits::is_iec559, TOML_ENV_MESSAGE); static_assert(std::numeric_limits::digits == 53, TOML_ENV_MESSAGE); static_assert(std::numeric_limits::digits10 == 15, TOML_ENV_MESSAGE); +static_assert(std::numeric_limits::radix == 2, TOML_ENV_MESSAGE); #undef TOML_ENV_MESSAGE #endif // !TOML_DISABLE_ENVIRONMENT_CHECKS @@ -1134,6 +1471,8 @@ TOML_NAMESPACE_START template class value; + class path; + class toml_formatter; class json_formatter; class yaml_formatter; @@ -1249,13 +1588,13 @@ TOML_NAMESPACE_START // abi namespace template inline std::basic_ostream& operator<<(std::basic_ostream& lhs, node_type rhs) { - using underlying_t = std::underlying_type_t; - const auto str = impl::node_type_friendly_names[static_cast(rhs)]; - if constexpr (std::is_same_v) + const auto str = impl::node_type_friendly_names[static_cast>(rhs)]; + using str_char_t = decltype(str)::value_type; + if constexpr (std::is_same_v) return lhs << str; else { - if constexpr (sizeof(Char) == 1) + if constexpr (sizeof(Char) == sizeof(str_char_t)) return lhs << std::basic_string_view{ reinterpret_cast(str.data()), str.length() }; else return lhs << str.data(); @@ -1290,6 +1629,7 @@ TOML_NAMESPACE_START // abi namespace indent_array_elements = (1ull << 10), indentation = indent_sub_tables | indent_array_elements, relaxed_float_precision = (1ull << 11), + terse_key_value_pairs = (1ull << 12), }; TOML_MAKE_FLAGS(format_flags); @@ -1301,7 +1641,7 @@ TOML_NAMESPACE_START // abi namespace T value; }; template - inserter(T &&) -> inserter; + inserter(T&&) -> inserter; template inserter(T&) -> inserter; @@ -1394,18 +1734,30 @@ TOML_IMPL_NAMESPACE_START using copy_cvref = copy_ref, std::remove_reference_t>, Dest>, Src>; - template - inline constexpr bool dependent_false = false; + template + inline constexpr bool always_false = false; template inline constexpr bool first_is_same = false; template inline constexpr bool first_is_same = true; + template > + struct underlying_type_ + { + using type = std::underlying_type_t; + }; + template + struct underlying_type_ + { + using type = T; + }; + template + using underlying_type = typename underlying_type_::type; + // general value traits // (as they relate to their equivalent native TOML type) - template - struct value_traits + struct default_value_traits { using native_type = void; static constexpr bool is_native = false; @@ -1416,9 +1768,30 @@ TOML_IMPL_NAMESPACE_START }; template - struct value_traits : value_traits - {}; - template + struct value_traits; + + template > + struct value_traits_base_selector + { + static_assert(!is_cvref); + + using type = default_value_traits; + }; + template + struct value_traits_base_selector + { + static_assert(!is_cvref); + + using type = value_traits>; + }; + + template + struct value_traits : value_traits_base_selector::type + {}; + template + struct value_traits : value_traits + {}; + template struct value_traits : value_traits {}; template @@ -1433,72 +1806,73 @@ TOML_IMPL_NAMESPACE_START // integer value_traits specializations - standard types template - struct integer_value_limits + struct integer_limits { - static constexpr auto min = (std::numeric_limits::min)(); - static constexpr auto max = (std::numeric_limits::max)(); + static constexpr T min = T{ (std::numeric_limits>::min)() }; + static constexpr T max = T{ (std::numeric_limits>::max)() }; }; template - struct integer_value_traits_base : integer_value_limits + struct integer_traits_base : integer_limits { using native_type = int64_t; - static constexpr bool is_native = std::is_same_v; - static constexpr bool is_signed = static_cast(-1) < T{}; // for impls not specializing std::is_signed + static constexpr bool is_native = std::is_same_v, native_type>; + static constexpr bool is_signed = static_cast>(-1) < underlying_type{}; static constexpr auto type = node_type::integer; static constexpr bool can_partially_represent_native = true; }; template - struct unsigned_integer_value_traits : integer_value_traits_base + struct unsigned_integer_traits : integer_traits_base { static constexpr bool is_losslessly_convertible_to_native = - integer_value_limits::max <= 9223372036854775807ULL; + integer_limits>::max <= 9223372036854775807ULL; static constexpr bool can_represent_native = false; }; template - struct signed_integer_value_traits : integer_value_traits_base + struct signed_integer_traits : integer_traits_base { using native_type = int64_t; static constexpr bool is_losslessly_convertible_to_native = - integer_value_limits::min >= (-9223372036854775807LL - 1LL) - && integer_value_limits::max <= 9223372036854775807LL; - static constexpr bool can_represent_native = integer_value_limits::min <= (-9223372036854775807LL - 1LL) - && integer_value_limits::max >= 9223372036854775807LL; + integer_limits>::min >= (-9223372036854775807LL - 1LL) + && integer_limits>::max <= 9223372036854775807LL; + static constexpr bool can_represent_native = + integer_limits>::min <= (-9223372036854775807LL - 1LL) + && integer_limits>::max >= 9223372036854775807LL; }; - template ::is_signed> - struct integer_value_traits : signed_integer_value_traits + template ::is_signed> + struct integer_traits : signed_integer_traits {}; template - struct integer_value_traits : unsigned_integer_value_traits + struct integer_traits : unsigned_integer_traits {}; template <> - struct value_traits : integer_value_traits + struct value_traits : integer_traits {}; template <> - struct value_traits : integer_value_traits + struct value_traits : integer_traits {}; template <> - struct value_traits : integer_value_traits + struct value_traits : integer_traits {}; template <> - struct value_traits : integer_value_traits + struct value_traits : integer_traits {}; template <> - struct value_traits : integer_value_traits + struct value_traits : integer_traits {}; template <> - struct value_traits : integer_value_traits + struct value_traits : integer_traits {}; template <> - struct value_traits : integer_value_traits + struct value_traits : integer_traits {}; template <> - struct value_traits : integer_value_traits + struct value_traits : integer_traits {}; template <> - struct value_traits : integer_value_traits + struct value_traits : integer_traits {}; template <> - struct value_traits : integer_value_traits + struct value_traits : integer_traits {}; static_assert(value_traits::is_native); static_assert(value_traits::is_signed); @@ -1509,117 +1883,100 @@ TOML_IMPL_NAMESPACE_START // integer value_traits specializations - non-standard types #ifdef TOML_INT128 template <> - struct integer_value_limits + struct integer_limits { static constexpr TOML_INT128 max = static_cast((TOML_UINT128{ 1u } << ((__SIZEOF_INT128__ * CHAR_BIT) - 1)) - 1); static constexpr TOML_INT128 min = -max - TOML_INT128{ 1 }; }; template <> - struct integer_value_limits + struct integer_limits { static constexpr TOML_UINT128 min = TOML_UINT128{}; - static constexpr TOML_UINT128 max = - (2u * static_cast(integer_value_limits::max)) + 1u; + static constexpr TOML_UINT128 max = (2u * static_cast(integer_limits::max)) + 1u; }; template <> - struct value_traits : integer_value_traits + struct value_traits : integer_traits {}; template <> - struct value_traits : integer_value_traits + struct value_traits : integer_traits {}; #endif #ifdef TOML_SMALL_INT_TYPE template <> - struct value_traits : signed_integer_value_traits + struct value_traits : signed_integer_traits {}; #endif - // floating-point value_traits specializations - standard types - template - struct float_value_limits - { - static constexpr bool is_iec559 = std::numeric_limits::is_iec559; - static constexpr int digits = std::numeric_limits::digits; - static constexpr int digits10 = std::numeric_limits::digits10; - }; - template - struct float_value_traits : float_value_limits + // floating-point traits base + template + struct float_traits_base { + static constexpr auto type = node_type::floating_point; using native_type = double; static constexpr bool is_native = std::is_same_v; static constexpr bool is_signed = true; - static constexpr bool is_losslessly_convertible_to_native = float_value_limits::is_iec559 - && float_value_limits::digits <= 53 - && float_value_limits::digits10 <= 15; + static constexpr int bits = static_cast(sizeof(T) * CHAR_BIT); + static constexpr int digits = MantissaDigits; + static constexpr int digits10 = DecimalDigits; - static constexpr bool can_represent_native = float_value_limits::is_iec559 - && float_value_limits::digits >= 53 // DBL_MANT_DIG - && float_value_limits::digits10 >= 15; // DBL_DIG + static constexpr bool is_losslessly_convertible_to_native = bits <= 64 // + && digits <= 53 // DBL_MANT_DIG + && digits10 <= 15; // DBL_DIG - static constexpr bool can_partially_represent_native // 32-bit float values - = float_value_limits::is_iec559 // - && float_value_limits::digits >= 24 // - && float_value_limits::digits10 >= 6; + static constexpr bool can_represent_native = digits >= 53 // DBL_MANT_DIG + && digits10 >= 15; // DBL_DIG - static constexpr auto type = node_type::floating_point; + static constexpr bool can_partially_represent_native = digits > 0 && digits10 > 0; }; - template <> - struct value_traits : float_value_traits + template + struct float_traits : float_traits_base::digits, std::numeric_limits::digits10> {}; +#if TOML_ENABLE_FLOAT16 template <> - struct value_traits : float_value_traits + struct float_traits<_Float16> : float_traits_base<_Float16, __FLT16_MANT_DIG__, __FLT16_DIG__> {}; +#endif +#ifdef TOML_FLOAT128 template <> - struct value_traits : float_value_traits + struct float_traits : float_traits_base {}; - template - struct extended_float_value_limits - { - static constexpr bool is_iec559 = true; - static constexpr int digits = mant_dig; - static constexpr int digits10 = dig; - }; - static_assert(value_traits::is_native); - static_assert(value_traits::is_losslessly_convertible_to_native); - static_assert(value_traits::can_represent_native); - static_assert(value_traits::can_partially_represent_native); +#endif - // floating-point value_traits specializations - non-standard types -#ifdef TOML_FP16 + // floating-point traits template <> - struct float_value_limits : extended_float_value_limits<__FLT16_MANT_DIG__, __FLT16_DIG__> + struct value_traits : float_traits {}; template <> - struct value_traits : float_value_traits + struct value_traits : float_traits {}; -#endif -#ifdef TOML_FLOAT16 template <> - struct float_value_limits : extended_float_value_limits<__FLT16_MANT_DIG__, __FLT16_DIG__> + struct value_traits : float_traits {}; +#if TOML_ENABLE_FLOAT16 template <> - struct value_traits : float_value_traits + struct value_traits<_Float16> : float_traits<_Float16> {}; #endif #ifdef TOML_FLOAT128 template <> - struct float_value_limits : extended_float_value_limits<__FLT128_MANT_DIG__, __FLT128_DIG__> - {}; - template <> - struct value_traits : float_value_traits + struct value_traits : float_traits {}; #endif #ifdef TOML_SMALL_FLOAT_TYPE template <> - struct value_traits : float_value_traits + struct value_traits : float_traits {}; #endif + static_assert(value_traits::is_native); + static_assert(value_traits::is_losslessly_convertible_to_native); + static_assert(value_traits::can_represent_native); + static_assert(value_traits::can_partially_represent_native); // string value_traits specializations - char-based strings template - struct string_value_traits + struct string_traits { using native_type = std::string; static constexpr bool is_native = std::is_same_v; @@ -1630,50 +1987,50 @@ TOML_IMPL_NAMESPACE_START static constexpr auto type = node_type::string; }; template <> - struct value_traits : string_value_traits + struct value_traits : string_traits {}; template <> - struct value_traits : string_value_traits + struct value_traits : string_traits {}; template <> - struct value_traits : string_value_traits + struct value_traits : string_traits {}; template - struct value_traits : string_value_traits + struct value_traits : string_traits {}; template <> - struct value_traits : string_value_traits + struct value_traits : string_traits {}; template - struct value_traits : string_value_traits + struct value_traits : string_traits {}; // string value_traits specializations - char8_t-based strings #if TOML_HAS_CHAR8 template <> - struct value_traits : string_value_traits + struct value_traits : string_traits {}; template <> - struct value_traits : string_value_traits + struct value_traits : string_traits {}; template <> - struct value_traits : string_value_traits + struct value_traits : string_traits {}; template - struct value_traits : string_value_traits + struct value_traits : string_traits {}; template <> - struct value_traits : string_value_traits + struct value_traits : string_traits {}; template - struct value_traits : string_value_traits + struct value_traits : string_traits {}; #endif // string value_traits specializations - wchar_t-based strings on Windows #if TOML_ENABLE_WINDOWS_COMPAT template - struct wstring_value_traits + struct wstring_traits { using native_type = std::string; static constexpr bool is_native = false; @@ -1683,22 +2040,22 @@ TOML_IMPL_NAMESPACE_START static constexpr auto type = node_type::string; }; template <> - struct value_traits : wstring_value_traits + struct value_traits : wstring_traits {}; template <> - struct value_traits : wstring_value_traits + struct value_traits : wstring_traits {}; template <> - struct value_traits : wstring_value_traits + struct value_traits : wstring_traits {}; template - struct value_traits : wstring_value_traits + struct value_traits : wstring_traits {}; template <> - struct value_traits : wstring_value_traits + struct value_traits : wstring_traits {}; template - struct value_traits : wstring_value_traits + struct value_traits : wstring_traits {}; #endif @@ -1850,6 +2207,10 @@ TOML_IMPL_NAMESPACE_START }; template inline constexpr node_type node_type_of = node_type_getter>>::value; + + template + inline constexpr bool is_constructible_or_convertible = std::is_constructible_v // + || std::is_convertible_v; } TOML_IMPL_NAMESPACE_END; @@ -1909,8 +2270,8 @@ TOML_NAMESPACE_START inline constexpr bool is_value = is_string || is_number || is_boolean || is_chronological; template - inline constexpr bool is_node = - std::is_same_v> || std::is_base_of_v>; + inline constexpr bool is_node = std::is_same_v> // + || std::is_base_of_v>; template inline constexpr bool is_node_view = impl::is_one_of, node_view, node_view>; @@ -1970,7 +2331,7 @@ TOML_IMPL_NAMESPACE_START } template - TOML_PURE_GETTER + TOML_PURE_INLINE_GETTER constexpr const T& min(const T& a, const T& b) noexcept // { return a < b ? a : b; @@ -1981,13 +2342,19 @@ TOML_IMPL_NAMESPACE_END; #ifdef _MSC_VER #pragma pop_macro("min") #pragma pop_macro("max") +#ifndef __clang__ +#pragma inline_recursion(off) +#endif #endif TOML_POP_WARNINGS; -//******** impl/print_to_stream.h ************************************************************************************ +//******** impl/print_to_stream.hpp ********************************************************************************** TOML_PUSH_WARNINGS; #ifdef _MSC_VER +#ifndef __clang__ +#pragma inline_recursion(on) +#endif #pragma push_macro("min") #pragma push_macro("max") #undef min @@ -1997,103 +2364,108 @@ TOML_PUSH_WARNINGS; TOML_IMPL_NAMESPACE_START { // Q: "why does print_to_stream() exist? why not just use ostream::write(), ostream::put() etc?" - // A: - I'm supporting C++20's char8_t as well; wrapping streams allows switching string modes transparently. - // - I'm using to format numerics. Faster and locale-independent. + // A: - I'm using to format numerics. Faster and locale-independent. // - I can (potentially) avoid forcing users to drag in and . // - Strings in C++. Honestly. - TOML_API + TOML_EXPORTED_FREE_FUNCTION TOML_ATTR(nonnull) - void print_to_stream(std::ostream&, const char*, size_t); + void TOML_CALLCONV print_to_stream(std::ostream&, const char*, size_t); + + TOML_EXPORTED_FREE_FUNCTION + void TOML_CALLCONV print_to_stream(std::ostream&, std::string_view); - TOML_API - void print_to_stream(std::ostream&, std::string_view); + TOML_EXPORTED_FREE_FUNCTION + void TOML_CALLCONV print_to_stream(std::ostream&, const std::string&); - TOML_API - void print_to_stream(std::ostream&, const std::string&); + TOML_EXPORTED_FREE_FUNCTION + void TOML_CALLCONV print_to_stream(std::ostream&, char); - TOML_API - void print_to_stream(std::ostream&, char); + TOML_EXPORTED_FREE_FUNCTION + void TOML_CALLCONV print_to_stream(std::ostream&, signed char, value_flags = {}, size_t min_digits = 0); - TOML_API - void print_to_stream(std::ostream&, int8_t, value_flags = {}, size_t min_digits = 0); + TOML_EXPORTED_FREE_FUNCTION + void TOML_CALLCONV print_to_stream(std::ostream&, signed short, value_flags = {}, size_t min_digits = 0); - TOML_API - void print_to_stream(std::ostream&, int16_t, value_flags = {}, size_t min_digits = 0); + TOML_EXPORTED_FREE_FUNCTION + void TOML_CALLCONV print_to_stream(std::ostream&, signed int, value_flags = {}, size_t min_digits = 0); - TOML_API - void print_to_stream(std::ostream&, int32_t, value_flags = {}, size_t min_digits = 0); + TOML_EXPORTED_FREE_FUNCTION + void TOML_CALLCONV print_to_stream(std::ostream&, signed long, value_flags = {}, size_t min_digits = 0); - TOML_API - void print_to_stream(std::ostream&, int64_t, value_flags = {}, size_t min_digits = 0); + TOML_EXPORTED_FREE_FUNCTION + void TOML_CALLCONV print_to_stream(std::ostream&, signed long long, value_flags = {}, size_t min_digits = 0); - TOML_API - void print_to_stream(std::ostream&, uint8_t, value_flags = {}, size_t min_digits = 0); + TOML_EXPORTED_FREE_FUNCTION + void TOML_CALLCONV print_to_stream(std::ostream&, unsigned char, value_flags = {}, size_t min_digits = 0); - TOML_API - void print_to_stream(std::ostream&, uint16_t, value_flags = {}, size_t min_digits = 0); + TOML_EXPORTED_FREE_FUNCTION + void TOML_CALLCONV print_to_stream(std::ostream&, unsigned short, value_flags = {}, size_t min_digits = 0); - TOML_API - void print_to_stream(std::ostream&, uint32_t, value_flags = {}, size_t min_digits = 0); + TOML_EXPORTED_FREE_FUNCTION + void TOML_CALLCONV print_to_stream(std::ostream&, unsigned int, value_flags = {}, size_t min_digits = 0); - TOML_API - void print_to_stream(std::ostream&, uint64_t, value_flags = {}, size_t min_digits = 0); + TOML_EXPORTED_FREE_FUNCTION + void TOML_CALLCONV print_to_stream(std::ostream&, unsigned long, value_flags = {}, size_t min_digits = 0); - TOML_API - void print_to_stream(std::ostream&, float, value_flags = {}, bool relaxed_precision = false); + TOML_EXPORTED_FREE_FUNCTION + void TOML_CALLCONV print_to_stream(std::ostream&, unsigned long long, value_flags = {}, size_t min_digits = 0); - TOML_API - void print_to_stream(std::ostream&, double, value_flags = {}, bool relaxed_precision = false); + TOML_EXPORTED_FREE_FUNCTION + void TOML_CALLCONV print_to_stream(std::ostream&, float, value_flags = {}, bool relaxed_precision = false); - TOML_API - void print_to_stream(std::ostream&, bool); + TOML_EXPORTED_FREE_FUNCTION + void TOML_CALLCONV print_to_stream(std::ostream&, double, value_flags = {}, bool relaxed_precision = false); - TOML_API - void print_to_stream(std::ostream&, const toml::date&); + TOML_EXPORTED_FREE_FUNCTION + void TOML_CALLCONV print_to_stream(std::ostream&, bool); - TOML_API - void print_to_stream(std::ostream&, const toml::time&); + TOML_EXPORTED_FREE_FUNCTION + void TOML_CALLCONV print_to_stream(std::ostream&, const toml::date&); - TOML_API - void print_to_stream(std::ostream&, const toml::time_offset&); + TOML_EXPORTED_FREE_FUNCTION + void TOML_CALLCONV print_to_stream(std::ostream&, const toml::time&); - TOML_API - void print_to_stream(std::ostream&, const toml::date_time&); + TOML_EXPORTED_FREE_FUNCTION + void TOML_CALLCONV print_to_stream(std::ostream&, const toml::time_offset&); - TOML_API - void print_to_stream(std::ostream&, const source_position&); + TOML_EXPORTED_FREE_FUNCTION + void TOML_CALLCONV print_to_stream(std::ostream&, const toml::date_time&); - TOML_API - void print_to_stream(std::ostream&, const source_region&); + TOML_EXPORTED_FREE_FUNCTION + void TOML_CALLCONV print_to_stream(std::ostream&, const source_position&); + + TOML_EXPORTED_FREE_FUNCTION + void TOML_CALLCONV print_to_stream(std::ostream&, const source_region&); #if TOML_ENABLE_FORMATTERS - TOML_API - void print_to_stream(std::ostream&, const array&); + TOML_EXPORTED_FREE_FUNCTION + void TOML_CALLCONV print_to_stream(std::ostream&, const array&); - TOML_API - void print_to_stream(std::ostream&, const table&); + TOML_EXPORTED_FREE_FUNCTION + void TOML_CALLCONV print_to_stream(std::ostream&, const table&); - TOML_API - void print_to_stream(std::ostream&, const value&); + TOML_EXPORTED_FREE_FUNCTION + void TOML_CALLCONV print_to_stream(std::ostream&, const value&); - TOML_API - void print_to_stream(std::ostream&, const value&); + TOML_EXPORTED_FREE_FUNCTION + void TOML_CALLCONV print_to_stream(std::ostream&, const value&); - TOML_API - void print_to_stream(std::ostream&, const value&); + TOML_EXPORTED_FREE_FUNCTION + void TOML_CALLCONV print_to_stream(std::ostream&, const value&); - TOML_API - void print_to_stream(std::ostream&, const value&); + TOML_EXPORTED_FREE_FUNCTION + void TOML_CALLCONV print_to_stream(std::ostream&, const value&); - TOML_API - void print_to_stream(std::ostream&, const value&); + TOML_EXPORTED_FREE_FUNCTION + void TOML_CALLCONV print_to_stream(std::ostream&, const value&); - TOML_API - void print_to_stream(std::ostream&, const value