// This file is a part of toml++ and is subject to the the terms of the MIT license. // Copyright (c) Mark Gillard // See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text. // SPDX-License-Identifier: MIT #include "settings.h" #if !TOML_HEADER_ONLY #define TOML_IMPLEMENTATION #endif #if USE_TARTANLLAMA_OPTIONAL #include "tloptional.h" #endif #if USE_SINGLE_HEADER #include "../toml.hpp" #else #include "../include/toml++/toml.h" #endif namespace toml { using std::declval; using std::is_same_v; #define CHECK_NODE_TYPE_MAPPING(T, expected) \ static_assert(impl::node_type_of == expected); \ static_assert(impl::node_type_of == expected); \ static_assert(impl::node_type_of == expected); \ static_assert(impl::node_type_of == expected); \ static_assert(impl::node_type_of == expected); \ static_assert(impl::node_type_of == expected); \ static_assert(impl::node_type_of == expected); \ static_assert(impl::node_type_of == expected); \ static_assert(impl::node_type_of == expected); \ static_assert(impl::node_type_of == expected); \ static_assert(impl::node_type_of == expected); \ static_assert(impl::node_type_of == expected) CHECK_NODE_TYPE_MAPPING(int64_t, node_type::integer); CHECK_NODE_TYPE_MAPPING(double, node_type::floating_point); CHECK_NODE_TYPE_MAPPING(std::string, node_type::string); CHECK_NODE_TYPE_MAPPING(bool, node_type::boolean); CHECK_NODE_TYPE_MAPPING(toml::date, node_type::date); CHECK_NODE_TYPE_MAPPING(toml::time, node_type::time); CHECK_NODE_TYPE_MAPPING(toml::date_time, node_type::date_time); CHECK_NODE_TYPE_MAPPING(toml::array, node_type::array); CHECK_NODE_TYPE_MAPPING(toml::table, node_type::table); #define CHECK_CAN_REPRESENT_NATIVE(T, expected) \ static_assert((impl::value_traits::is_native || impl::value_traits::can_represent_native) == expected) CHECK_CAN_REPRESENT_NATIVE(time, true); CHECK_CAN_REPRESENT_NATIVE(date, true); CHECK_CAN_REPRESENT_NATIVE(date_time, true); CHECK_CAN_REPRESENT_NATIVE(bool, true); CHECK_CAN_REPRESENT_NATIVE(int8_t, false); CHECK_CAN_REPRESENT_NATIVE(int16_t, false); CHECK_CAN_REPRESENT_NATIVE(int32_t, false); CHECK_CAN_REPRESENT_NATIVE(int64_t, true); CHECK_CAN_REPRESENT_NATIVE(uint8_t, false); CHECK_CAN_REPRESENT_NATIVE(uint16_t, false); CHECK_CAN_REPRESENT_NATIVE(uint32_t, false); CHECK_CAN_REPRESENT_NATIVE(uint64_t, false); CHECK_CAN_REPRESENT_NATIVE(float, false); CHECK_CAN_REPRESENT_NATIVE(double, true); #ifdef TOML_INT128 CHECK_CAN_REPRESENT_NATIVE(TOML_INT128, true); CHECK_CAN_REPRESENT_NATIVE(TOML_UINT128, false); #endif #ifdef TOML_FP16 CHECK_CAN_REPRESENT_NATIVE(TOML_FP16, false); #endif #ifdef TOML_FLOAT16 CHECK_CAN_REPRESENT_NATIVE(TOML_FLOAT16, false); #endif #ifdef TOML_FLOAT128 CHECK_CAN_REPRESENT_NATIVE(TOML_FLOAT128, true); #endif CHECK_CAN_REPRESENT_NATIVE(char*, false); CHECK_CAN_REPRESENT_NATIVE(char*const, false); CHECK_CAN_REPRESENT_NATIVE(char[2], false); CHECK_CAN_REPRESENT_NATIVE(const char[2], false); CHECK_CAN_REPRESENT_NATIVE(char(&)[2], false); CHECK_CAN_REPRESENT_NATIVE(const char(&)[2], false); CHECK_CAN_REPRESENT_NATIVE(char(&&)[2], false); CHECK_CAN_REPRESENT_NATIVE(const char(&&)[2], false); CHECK_CAN_REPRESENT_NATIVE(const char*, true); CHECK_CAN_REPRESENT_NATIVE(const char*const, true); CHECK_CAN_REPRESENT_NATIVE(std::string, true); CHECK_CAN_REPRESENT_NATIVE(std::string_view, true); #ifdef __cpp_lib_char8_t CHECK_CAN_REPRESENT_NATIVE(char8_t*, false); CHECK_CAN_REPRESENT_NATIVE(char8_t*const, false); CHECK_CAN_REPRESENT_NATIVE(char8_t[2], false); CHECK_CAN_REPRESENT_NATIVE(const char8_t[2], false); CHECK_CAN_REPRESENT_NATIVE(char8_t(&)[2], false); CHECK_CAN_REPRESENT_NATIVE(const char8_t(&)[2], false); CHECK_CAN_REPRESENT_NATIVE(char(&&)[2], false); CHECK_CAN_REPRESENT_NATIVE(const char8_t(&&)[2], false); CHECK_CAN_REPRESENT_NATIVE(const char8_t*, true); CHECK_CAN_REPRESENT_NATIVE(const char8_t*const, true); CHECK_CAN_REPRESENT_NATIVE(std::u8string, true); CHECK_CAN_REPRESENT_NATIVE(std::u8string_view, true); #endif CHECK_CAN_REPRESENT_NATIVE(wchar_t*, false); CHECK_CAN_REPRESENT_NATIVE(wchar_t*const, false); CHECK_CAN_REPRESENT_NATIVE(wchar_t[2], false); CHECK_CAN_REPRESENT_NATIVE(const wchar_t[2], false); CHECK_CAN_REPRESENT_NATIVE(wchar_t(&)[2], false); CHECK_CAN_REPRESENT_NATIVE(const wchar_t(&)[2], false); CHECK_CAN_REPRESENT_NATIVE(wchar_t(&&)[2], false); CHECK_CAN_REPRESENT_NATIVE(const wchar_t(&&)[2], false); CHECK_CAN_REPRESENT_NATIVE(const wchar_t*, false); CHECK_CAN_REPRESENT_NATIVE(const wchar_t*const, false); CHECK_CAN_REPRESENT_NATIVE(std::wstring, !!TOML_WINDOWS_COMPAT); CHECK_CAN_REPRESENT_NATIVE(std::wstring_view, false); #define CHECK_VALUE_EXACT(T, expected) \ static_assert(is_same_v().value_exact()), optional>); \ static_assert(is_same_v>().value_exact()), optional>); \ static_assert(is_same_v>().value_exact()), optional>) #define CHECK_VALUE_OR(T, expected) \ static_assert(is_same_v().value_or(declval())), expected>); \ static_assert(is_same_v>().value_or(declval())), expected>); \ static_assert(is_same_v>().value_or(declval())), expected>) CHECK_VALUE_EXACT( time, time); CHECK_VALUE_EXACT( date, date); CHECK_VALUE_EXACT( date_time, date_time); CHECK_VALUE_EXACT( bool, bool); CHECK_VALUE_EXACT( double, double); CHECK_VALUE_EXACT( int64_t, int64_t); CHECK_VALUE_EXACT( const char*, const char*); CHECK_VALUE_EXACT( std::string_view, std::string_view); CHECK_VALUE_EXACT( std::string, std::string); #ifdef __cpp_lib_char8_t CHECK_VALUE_EXACT( const char8_t*, const char8_t*); CHECK_VALUE_EXACT( std::u8string_view, std::u8string_view); CHECK_VALUE_EXACT( std::u8string, std::u8string); #endif CHECK_VALUE_OR( time, time); CHECK_VALUE_OR( time&, time); CHECK_VALUE_OR( time&&, time); CHECK_VALUE_OR( time const, time); CHECK_VALUE_OR( date, date); CHECK_VALUE_OR( date&, date); CHECK_VALUE_OR( date&&, date); CHECK_VALUE_OR( date const, date); CHECK_VALUE_OR( date_time, date_time); CHECK_VALUE_OR( date_time&, date_time); CHECK_VALUE_OR( date_time&&, date_time); CHECK_VALUE_OR( date_time const, date_time); CHECK_VALUE_OR( bool, bool); CHECK_VALUE_OR( bool&, bool); CHECK_VALUE_OR( bool&&, bool); CHECK_VALUE_OR( bool const, bool); CHECK_VALUE_OR( int32_t, int32_t); CHECK_VALUE_OR( int32_t&, int32_t); CHECK_VALUE_OR( int32_t&&, int32_t); CHECK_VALUE_OR( int32_t const, int32_t); CHECK_VALUE_OR( int64_t, int64_t); CHECK_VALUE_OR( int64_t&, int64_t); CHECK_VALUE_OR( int64_t&&, int64_t); CHECK_VALUE_OR( int64_t const, int64_t); #ifdef TOML_INT128 CHECK_VALUE_OR( TOML_INT128, TOML_INT128); CHECK_VALUE_OR( TOML_INT128&, TOML_INT128); CHECK_VALUE_OR( TOML_INT128&&, TOML_INT128); CHECK_VALUE_OR( TOML_INT128 const, TOML_INT128); CHECK_VALUE_OR( TOML_UINT128, TOML_UINT128); CHECK_VALUE_OR( TOML_UINT128&, TOML_UINT128); CHECK_VALUE_OR( TOML_UINT128&&, TOML_UINT128); CHECK_VALUE_OR( TOML_UINT128 const, TOML_UINT128); #endif CHECK_VALUE_OR( float, float); CHECK_VALUE_OR( float&, float); CHECK_VALUE_OR( float&&, float); CHECK_VALUE_OR( float const, float); CHECK_VALUE_OR( double, double); CHECK_VALUE_OR( double&, double); CHECK_VALUE_OR( double&&, double); CHECK_VALUE_OR( double const, double); #ifdef TOML_FLOAT128 CHECK_VALUE_OR( TOML_FLOAT128, TOML_FLOAT128); CHECK_VALUE_OR( TOML_FLOAT128&, TOML_FLOAT128); CHECK_VALUE_OR( TOML_FLOAT128&&, TOML_FLOAT128); CHECK_VALUE_OR( TOML_FLOAT128 const, TOML_FLOAT128); #endif CHECK_VALUE_OR( char*, const char*); CHECK_VALUE_OR( char*&, const char*); CHECK_VALUE_OR( char*&&, const char*); CHECK_VALUE_OR( char*const, const char*); CHECK_VALUE_OR( char[2], const char*); CHECK_VALUE_OR( char(&)[2], const char*); CHECK_VALUE_OR( char(&&)[2], const char*); CHECK_VALUE_OR( const char*, const char*); CHECK_VALUE_OR( const char*&, const char*); CHECK_VALUE_OR( const char*&&, const char*); CHECK_VALUE_OR( const char*const, const char*); CHECK_VALUE_OR( const char[2], const char*); CHECK_VALUE_OR( const char(&)[2], const char*); CHECK_VALUE_OR( const char(&&)[2], const char*); CHECK_VALUE_OR( std::string_view, std::string_view); CHECK_VALUE_OR( std::string_view&, std::string_view); CHECK_VALUE_OR( std::string_view&&, std::string_view); CHECK_VALUE_OR( const std::string_view, std::string_view); CHECK_VALUE_OR( const std::string_view&, std::string_view); CHECK_VALUE_OR( const std::string_view&&, std::string_view); CHECK_VALUE_OR( std::string, std::string); CHECK_VALUE_OR( std::string&, std::string); CHECK_VALUE_OR( std::string&&, std::string); CHECK_VALUE_OR( const std::string, std::string); CHECK_VALUE_OR( const std::string&, std::string); CHECK_VALUE_OR( const std::string&&, std::string); #ifdef __cpp_lib_char8_t CHECK_VALUE_OR( char8_t*, const char8_t*); CHECK_VALUE_OR( char8_t*&, const char8_t*); CHECK_VALUE_OR( char8_t*&&, const char8_t*); CHECK_VALUE_OR( char8_t*const, const char8_t*); CHECK_VALUE_OR( char8_t[2], const char8_t*); CHECK_VALUE_OR( char8_t(&)[2], const char8_t*); CHECK_VALUE_OR( char8_t(&&)[2], const char8_t*); CHECK_VALUE_OR( const char8_t*, const char8_t*); CHECK_VALUE_OR( const char8_t*&, const char8_t*); CHECK_VALUE_OR( const char8_t*&&, const char8_t*); CHECK_VALUE_OR( const char8_t*const, const char8_t*); CHECK_VALUE_OR( const char8_t[2], const char8_t*); CHECK_VALUE_OR( const char8_t(&)[2], const char8_t*); CHECK_VALUE_OR( const char8_t(&&)[2], const char8_t*); CHECK_VALUE_OR( std::u8string_view, std::u8string_view); CHECK_VALUE_OR( std::u8string_view&, std::u8string_view); CHECK_VALUE_OR( std::u8string_view&&, std::u8string_view); CHECK_VALUE_OR( const std::u8string_view, std::u8string_view); CHECK_VALUE_OR( const std::u8string_view&, std::u8string_view); CHECK_VALUE_OR( const std::u8string_view&&, std::u8string_view); CHECK_VALUE_OR( std::u8string, std::u8string); CHECK_VALUE_OR( std::u8string&, std::u8string); CHECK_VALUE_OR( std::u8string&&, std::u8string); CHECK_VALUE_OR( const std::u8string, std::u8string); CHECK_VALUE_OR( const std::u8string&, std::u8string); CHECK_VALUE_OR( const std::u8string&&, std::u8string); #endif #if TOML_WINDOWS_COMPAT CHECK_VALUE_OR( wchar_t*, std::wstring); CHECK_VALUE_OR( wchar_t*&, std::wstring); CHECK_VALUE_OR( wchar_t*&&, std::wstring); CHECK_VALUE_OR( wchar_t*const, std::wstring); CHECK_VALUE_OR( wchar_t[2], std::wstring); CHECK_VALUE_OR( wchar_t(&)[2], std::wstring); CHECK_VALUE_OR( wchar_t(&&)[2], std::wstring); CHECK_VALUE_OR( const wchar_t*, std::wstring); CHECK_VALUE_OR( const wchar_t*&, std::wstring); CHECK_VALUE_OR( const wchar_t*&&, std::wstring); CHECK_VALUE_OR( const wchar_t*const, std::wstring); CHECK_VALUE_OR( const wchar_t[2], std::wstring); CHECK_VALUE_OR( const wchar_t(&)[2], std::wstring); CHECK_VALUE_OR( const wchar_t(&&)[2], std::wstring); CHECK_VALUE_OR( std::wstring_view, std::wstring); CHECK_VALUE_OR( std::wstring_view&, std::wstring); CHECK_VALUE_OR( std::wstring_view&&, std::wstring); CHECK_VALUE_OR( const std::wstring_view, std::wstring); CHECK_VALUE_OR( const std::wstring_view&, std::wstring); CHECK_VALUE_OR( const std::wstring_view&&, std::wstring); CHECK_VALUE_OR( std::wstring, std::wstring); CHECK_VALUE_OR( std::wstring&, std::wstring); CHECK_VALUE_OR( std::wstring&&, std::wstring); CHECK_VALUE_OR( const std::wstring, std::wstring); CHECK_VALUE_OR( const std::wstring&, std::wstring); CHECK_VALUE_OR( const std::wstring&&, std::wstring); #endif static_assert(is_same_v().ref()), double&>); static_assert(is_same_v().ref()), double&&>); static_assert(is_same_v().ref()), const double&>); static_assert(is_same_v().ref>()), double&>); static_assert(is_same_v().ref>()), double&&>); static_assert(is_same_v().ref>()), const double&>); static_assert(is_same_v().ref()), table&>); static_assert(is_same_v().ref
()), table&&>); static_assert(is_same_v().ref
()), const table&>); static_assert(is_same_v().ref()), array&>); static_assert(is_same_v().ref()), array&&>); static_assert(is_same_v().ref()), const array&>); static_assert(is_same_v>().ref()), double&>); static_assert(is_same_v>().ref()), const double&>); static_assert(is_same_v>().ref>()), double&>); static_assert(is_same_v>().ref>()), const double&>); static_assert(is_same_v>().ref
()), table&>); static_assert(is_same_v>().ref
()), const table&>); static_assert(is_same_v>().ref()), array&>); static_assert(is_same_v>().ref()), const array&>); }