summaryrefslogtreecommitdiffhomepage
path: root/vendor/toml++/impl/forward_declarations.hpp
diff options
context:
space:
mode:
authorAmlal El Mahrouss <amlal@nekernel.org>2026-03-08 15:50:45 +0100
committerGitHub <noreply@github.com>2026-03-08 15:50:45 +0100
commit386b6ba6702aaf121a8667b68fba86385dad68ed (patch)
tree985c7eda4fafa827eaad88b6b469b0baba791817 /vendor/toml++/impl/forward_declarations.hpp
parent7a469801ecb55fcde0199d4e41b1cec3a17dcb05 (diff)
parentddb1cbc831b6d13b985d91022f01e955e24ae871 (diff)
Merge pull request #25 from ne-foss-org/nebuild-patches-deref
[CHORE] Patching TOML manifest parser to avoid null deref.
Diffstat (limited to 'vendor/toml++/impl/forward_declarations.hpp')
-rw-r--r--vendor/toml++/impl/forward_declarations.hpp1786
1 files changed, 851 insertions, 935 deletions
diff --git a/vendor/toml++/impl/forward_declarations.hpp b/vendor/toml++/impl/forward_declarations.hpp
index 386a9e0..b755855 100644
--- a/vendor/toml++/impl/forward_declarations.hpp
+++ b/vendor/toml++/impl/forward_declarations.hpp
@@ -1,38 +1,43 @@
-//# This file is a part of toml++ and is subject to the the terms of the MIT license.
-//# Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
-//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
-// SPDX-License-Identifier: MIT
+// # This file is a part of toml++ and is subject to the the terms of the MIT license.
+// # Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
+// # See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
+// SPDX-License-Identifier: MIT
#pragma once
-#include "std_string.hpp"
#include "std_new.hpp"
+#include "std_string.hpp"
TOML_DISABLE_WARNINGS;
-#include <cstdint>
-#include <cstddef>
-#include <cstring>
#include <cfloat>
#include <climits>
#include <cmath>
+#include <cstddef>
+#include <cstdint>
+#include <cstring>
+#include <iosfwd>
#include <limits>
#include <memory>
-#include <iosfwd>
#include <type_traits>
TOML_ENABLE_WARNINGS;
#include "header_start.hpp"
-//#---------------------------------------------------------------------------------------------------------------------
-//# ENVIRONMENT GROUND-TRUTHS
-//#---------------------------------------------------------------------------------------------------------------------
+// #---------------------------------------------------------------------------------------------------------------------
+// # ENVIRONMENT GROUND-TRUTHS
+// #---------------------------------------------------------------------------------------------------------------------
/// \cond
#ifndef TOML_DISABLE_ENVIRONMENT_CHECKS
-#define TOML_ENV_MESSAGE \
- "If you're seeing this error it's because you're building toml++ for an environment that doesn't conform to " \
- "one of the 'ground truths' assumed by the library. Essentially this just means that I don't have the " \
- "resources to test on more platforms, but I wish I did! You can try disabling the checks by defining " \
- "TOML_DISABLE_ENVIRONMENT_CHECKS, but your mileage may vary. Please consider filing an issue at " \
- "https://github.com/marzer/tomlplusplus/issues to help me improve support for your target environment. " \
- "Thanks!"
+#define TOML_ENV_MESSAGE \
+ "If you're seeing this error it's because you're building toml++ for an environment that " \
+ "doesn't conform to " \
+ "one of the 'ground truths' assumed by the library. Essentially this just means that I don't " \
+ "have the " \
+ "resources to test on more platforms, but I wish I did! You can try disabling the checks by " \
+ "defining " \
+ "TOML_DISABLE_ENVIRONMENT_CHECKS, but your mileage may vary. Please consider filing an issue " \
+ "at " \
+ "https://github.com/marzer/tomlplusplus/issues to help me improve support for your target " \
+ "environment. " \
+ "Thanks!"
static_assert(CHAR_BIT == 8, TOML_ENV_MESSAGE);
#ifdef FLT_RADIX
@@ -46,83 +51,81 @@ static_assert(std::numeric_limits<double>::digits10 == 15, TOML_ENV_MESSAGE);
static_assert(std::numeric_limits<double>::radix == 2, TOML_ENV_MESSAGE);
#undef TOML_ENV_MESSAGE
-#endif // !TOML_DISABLE_ENVIRONMENT_CHECKS
+#endif // !TOML_DISABLE_ENVIRONMENT_CHECKS
/// \endcond
-//#---------------------------------------------------------------------------------------------------------------------
-//# UNDOCUMENTED TYPEDEFS AND FORWARD DECLARATIONS
-//#---------------------------------------------------------------------------------------------------------------------
+// #---------------------------------------------------------------------------------------------------------------------
+// # UNDOCUMENTED TYPEDEFS AND FORWARD DECLARATIONS
+// #---------------------------------------------------------------------------------------------------------------------
/// \cond
// undocumented forward declarations are hidden from doxygen because they fuck it up =/
-namespace toml // non-abi namespace; this is not an error
-{
- using ::std::size_t;
- using ::std::intptr_t;
- using ::std::uintptr_t;
- using ::std::ptrdiff_t;
- using ::std::nullptr_t;
- using ::std::int8_t;
- using ::std::int16_t;
- using ::std::int32_t;
- using ::std::int64_t;
- using ::std::uint8_t;
- using ::std::uint16_t;
- using ::std::uint32_t;
- using ::std::uint64_t;
- using ::std::uint_least32_t;
- using ::std::uint_least64_t;
-}
-
-TOML_NAMESPACE_START
+namespace toml // non-abi namespace; this is not an error
{
- struct date;
- struct time;
- struct time_offset;
-
- TOML_ABI_NAMESPACE_BOOL(TOML_HAS_CUSTOM_OPTIONAL_TYPE, custopt, stdopt);
- struct date_time;
- TOML_ABI_NAMESPACE_END;
-
- struct source_position;
- struct source_region;
-
- class node;
- template <typename>
- class node_view;
-
- class key;
- class array;
- class table;
- template <typename>
- class value;
-
- class path;
-
- class toml_formatter;
- class json_formatter;
- class yaml_formatter;
-
- TOML_ABI_NAMESPACE_BOOL(TOML_EXCEPTIONS, ex, noex);
+using ::std::int16_t;
+using ::std::int32_t;
+using ::std::int64_t;
+using ::std::int8_t;
+using ::std::intptr_t;
+using ::std::nullptr_t;
+using ::std::ptrdiff_t;
+using ::std::size_t;
+using ::std::uint16_t;
+using ::std::uint32_t;
+using ::std::uint64_t;
+using ::std::uint8_t;
+using ::std::uint_least32_t;
+using ::std::uint_least64_t;
+using ::std::uintptr_t;
+} // namespace toml
+
+TOML_NAMESPACE_START {
+ struct date;
+ struct time;
+ struct time_offset;
+
+ TOML_ABI_NAMESPACE_BOOL(TOML_HAS_CUSTOM_OPTIONAL_TYPE, custopt, stdopt);
+ struct date_time;
+ TOML_ABI_NAMESPACE_END;
+
+ struct source_position;
+ struct source_region;
+
+ class node;
+ template <typename>
+ class node_view;
+
+ class key;
+ class array;
+ class table;
+ template <typename>
+ class value;
+
+ class path;
+
+ class toml_formatter;
+ class json_formatter;
+ class yaml_formatter;
+
+ TOML_ABI_NAMESPACE_BOOL(TOML_EXCEPTIONS, ex, noex);
#if TOML_EXCEPTIONS
- using parse_result = table;
+ using parse_result = table;
#else
- class parse_result;
+ class parse_result;
#endif
- TOML_ABI_NAMESPACE_END; // TOML_EXCEPTIONS
+ TOML_ABI_NAMESPACE_END; // TOML_EXCEPTIONS
}
TOML_NAMESPACE_END;
-TOML_IMPL_NAMESPACE_START
-{
- using node_ptr = std::unique_ptr<node>;
+TOML_IMPL_NAMESPACE_START {
+ using node_ptr = std::unique_ptr<node>;
- TOML_ABI_NAMESPACE_BOOL(TOML_EXCEPTIONS, impl_ex, impl_noex);
- class parser;
- TOML_ABI_NAMESPACE_END; // TOML_EXCEPTIONS
+ TOML_ABI_NAMESPACE_BOOL(TOML_EXCEPTIONS, impl_ex, impl_noex);
+ class parser;
+ TOML_ABI_NAMESPACE_END; // TOML_EXCEPTIONS
- // clang-format off
+ // clang-format off
inline constexpr std::string_view control_char_escapes[] =
{
@@ -174,7 +177,7 @@ TOML_IMPL_NAMESPACE_START
"date-time"sv
};
- // clang-format on
+ // clang-format on
}
TOML_IMPL_NAMESPACE_END;
@@ -190,906 +193,819 @@ TOML_IMPL_NAMESPACE_END;
/// \endcond
-//#---------------------------------------------------------------------------------------------------------------------
-//# DOCUMENTED TYPEDEFS AND FORWARD DECLARATIONS
-//#---------------------------------------------------------------------------------------------------------------------
+// #---------------------------------------------------------------------------------------------------------------------
+// # DOCUMENTED TYPEDEFS AND FORWARD DECLARATIONS
+// #---------------------------------------------------------------------------------------------------------------------
/// \brief The root namespace for all toml++ functions and types.
-namespace toml
-{
-}
+namespace toml {}
-TOML_NAMESPACE_START // abi namespace
+TOML_NAMESPACE_START // abi namespace
{
- /// \brief Convenience literal operators for working with toml++.
- ///
- /// \detail This namespace exists so you can safely hoist the toml++ literal operators into another scope
- /// without dragging in everything from the toml namespace: \cpp
- ///
- /// #include <toml++/toml.hpp>
- /// using namespace toml::literals;
- ///
- /// int main()
- /// {
- /// toml::table tbl = "vals = [1, 2, 3]"_toml;
- ///
- /// // ... do stuff with the table generated by the "_toml" literal ...
- ///
- /// return 0;
- /// }
- /// \ecpp
- ///
- inline namespace literals
- {
- }
-
- /// \brief TOML node type identifiers.
- enum class TOML_CLOSED_ENUM node_type : uint8_t
- {
- none, ///< Not-a-node.
- table, ///< The node is a toml::table.
- array, ///< The node is a toml::array.
- string, ///< The node is a toml::value<std::string>.
- integer, ///< The node is a toml::value<int64_t>.
- floating_point, ///< The node is a toml::value<double>.
- boolean, ///< The node is a toml::value<bool>.
- date, ///< The node is a toml::value<date>.
- time, ///< The node is a toml::value<time>.
- date_time ///< The node is a toml::value<date_time>.
- };
-
- /// \brief Pretty-prints the value of a node_type to a stream.
- ///
- /// \detail \cpp
- /// auto arr = toml::array{ 1, 2.0, "3", false };
- /// for (size_t i = 0; i < arr.size() i++)
- /// std::cout << "Element ["sv << i << "] is: "sv << arr[i].type() << "\n";
- /// \ecpp
- ///
- /// \out
- /// Element [0] is: integer
- /// Element [1] is: floating-point
- /// Element [2] is: string
- /// Element [3] is: boolean
- /// \eout
- template <typename Char>
- inline std::basic_ostream<Char>& operator<<(std::basic_ostream<Char>& lhs, node_type rhs)
- {
- const auto str = impl::node_type_friendly_names[static_cast<std::underlying_type_t<node_type>>(rhs)];
- using str_char_t = decltype(str)::value_type;
- if constexpr (std::is_same_v<Char, str_char_t>)
- return lhs << str;
- else
- {
- if constexpr (sizeof(Char) == sizeof(str_char_t))
- return lhs << std::basic_string_view<Char>{ reinterpret_cast<const Char*>(str.data()), str.length() };
- else
- return lhs << str.data();
- }
- }
-
- /// \brief Metadata associated with TOML values.
- enum class TOML_OPEN_FLAGS_ENUM value_flags : uint16_t // being an "OPEN" flags enum is not an error
- {
- /// \brief None.
- none,
-
- /// \brief Format integer values as binary.
- format_as_binary = 1,
-
- /// \brief Format integer values as octal.
- format_as_octal = 2,
-
- /// \brief Format integer values as hexadecimal.
- format_as_hexadecimal = 3,
- };
- TOML_MAKE_FLAGS(value_flags);
-
- /// \brief Special #toml::value_flags constant used for array + table insert functions to specify that any value
- /// nodes being copied should not have their flags property overridden by the inserting function's `flags` argument.
- inline constexpr value_flags preserve_source_value_flags =
- POXY_IMPLEMENTATION_DETAIL(value_flags{ static_cast<std::underlying_type_t<value_flags>>(-1) });
-
- /// \brief Format flags for modifying how TOML data is printed to streams.
- ///
- /// \note Formatters may disregard/override any of these flags according to the requirements of their
- /// output target (e.g. #toml::json_formatter will always apply quotes to dates and times).
- enum class TOML_CLOSED_FLAGS_ENUM format_flags : uint64_t
- {
- /// \brief None.
- none,
-
- /// \brief Dates and times will be emitted as quoted strings.
- quote_dates_and_times = (1ull << 0),
-
- /// \brief Infinities and NaNs will be emitted as quoted strings.
- quote_infinities_and_nans = (1ull << 1),
-
- /// \brief Strings will be emitted as single-quoted literal strings where possible.
- allow_literal_strings = (1ull << 2),
-
- /// \brief Strings containing newlines will be emitted as triple-quoted 'multi-line' strings where possible.
- allow_multi_line_strings = (1ull << 3),
-
- /// \brief Allow real tab characters in string literals (as opposed to the escaped form `\t`).
- allow_real_tabs_in_strings = (1ull << 4),
-
- /// \brief Allow non-ASCII characters in strings (as opposed to their escaped form, e.g. `\u00DA`).
- allow_unicode_strings = (1ull << 5),
-
- /// \brief Allow integers with #value_flags::format_as_binary to be emitted as binary.
- allow_binary_integers = (1ull << 6),
-
- /// \brief Allow integers with #value_flags::format_as_octal to be emitted as octal.
- allow_octal_integers = (1ull << 7),
-
- /// \brief Allow integers with #value_flags::format_as_hexadecimal to be emitted as hexadecimal.
- allow_hexadecimal_integers = (1ull << 8),
-
- /// \brief Apply indentation to tables nested within other tables/arrays.
- indent_sub_tables = (1ull << 9),
-
- /// \brief Apply indentation to array elements when the array is forced to wrap over multiple lines.
- indent_array_elements = (1ull << 10),
-
- /// \brief Combination mask of all indentation-enabling flags.
- indentation = indent_sub_tables | indent_array_elements,
-
- /// \brief Emit floating-point values with relaxed (human-friendly) precision.
- /// \warning Setting this flag may cause serialized documents to no longer round-trip correctly
- /// since floats might have a less precise value upon being written out than they did when being
- /// read in. Use this flag at your own risk.
- relaxed_float_precision = (1ull << 11),
-
- /// \brief Avoids the use of whitespace around key-value pairs.
- terse_key_value_pairs = (1ull << 12),
- };
- TOML_MAKE_FLAGS(format_flags);
-
- /// \brief Helper class for suppressing move-construction in single-argument array constructors.
- ///
- /// \detail \cpp
- /// // desired result: [ [ 42 ] ]
- /// auto bad = toml::array{ toml::array{ 42 } };
- /// auto good = toml::array{ toml::inserter{ toml::array{ 42 } } };
- /// std::cout << "bad: " << bad << "\n";
- /// std::cout << "good:" << good << "\n";
- /// \ecpp
- /// \out
- /// bad: [ 42 ]
- /// good: [ [ 42 ] ]
- /// \eout
- ///
- /// \see toml::array
- template <typename T>
- struct TOML_TRIVIAL_ABI inserter
- {
- static_assert(std::is_reference_v<T>);
-
- T value;
- };
- template <typename T>
- inserter(T&&) -> inserter<T&&>;
- template <typename T>
- inserter(T&) -> inserter<T&>;
-
- /// \brief The 'default' formatter used by TOML objects when they are printed to a stream.
- /// \detail This is an alias for #toml::toml_formatter.
- using default_formatter = toml_formatter;
+ /// \brief Convenience literal operators for working with toml++.
+ ///
+ /// \detail This namespace exists so you can safely hoist the toml++ literal operators into
+ /// another scope without dragging in everything from the toml namespace: \cpp
+ ///
+ /// #include <toml++/toml.hpp>
+ /// using namespace toml::literals;
+ ///
+ /// int main()
+ /// {
+ /// toml::table tbl = "vals = [1, 2, 3]"_toml;
+ ///
+ /// // ... do stuff with the table generated by the "_toml" literal ...
+ ///
+ /// return 0;
+ /// }
+ /// \ecpp
+ ///
+ inline namespace literals {}
+
+ /// \brief TOML node type identifiers.
+ enum class TOML_CLOSED_ENUM node_type : uint8_t {
+ none, ///< Not-a-node.
+ table, ///< The node is a toml::table.
+ array, ///< The node is a toml::array.
+ string, ///< The node is a toml::value<std::string>.
+ integer, ///< The node is a toml::value<int64_t>.
+ floating_point, ///< The node is a toml::value<double>.
+ boolean, ///< The node is a toml::value<bool>.
+ date, ///< The node is a toml::value<date>.
+ time, ///< The node is a toml::value<time>.
+ date_time ///< The node is a toml::value<date_time>.
+ };
+
+ /// \brief Pretty-prints the value of a node_type to a stream.
+ ///
+ /// \detail \cpp
+ /// auto arr = toml::array{ 1, 2.0, "3", false };
+ /// for (size_t i = 0; i < arr.size() i++)
+ /// std::cout << "Element ["sv << i << "] is: "sv << arr[i].type() << "\n";
+ /// \ecpp
+ ///
+ /// \out
+ /// Element [0] is: integer
+ /// Element [1] is: floating-point
+ /// Element [2] is: string
+ /// Element [3] is: boolean
+ /// \eout
+ template <typename Char>
+ inline std::basic_ostream<Char>& operator<<(std::basic_ostream<Char>& lhs, node_type rhs) {
+ const auto str =
+ impl::node_type_friendly_names[static_cast<std::underlying_type_t<node_type>>(rhs)];
+ using str_char_t = decltype(str)::value_type;
+ if constexpr (std::is_same_v<Char, str_char_t>)
+ return lhs << str;
+ else {
+ if constexpr (sizeof(Char) == sizeof(str_char_t))
+ return lhs << std::basic_string_view<Char>{reinterpret_cast<const Char*>(str.data()),
+ str.length()};
+ else
+ return lhs << str.data();
+ }
+ }
+
+ /// \brief Metadata associated with TOML values.
+ enum class TOML_OPEN_FLAGS_ENUM
+ value_flags : uint16_t // being an "OPEN" flags enum is not an error
+ {
+ /// \brief None.
+ none,
+
+ /// \brief Format integer values as binary.
+ format_as_binary = 1,
+
+ /// \brief Format integer values as octal.
+ format_as_octal = 2,
+
+ /// \brief Format integer values as hexadecimal.
+ format_as_hexadecimal = 3,
+ };
+ TOML_MAKE_FLAGS(value_flags);
+
+ /// \brief Special #toml::value_flags constant used for array + table insert functions to specify
+ /// that any value nodes being copied should not have their flags property overridden by the
+ /// inserting function's `flags` argument.
+ inline constexpr value_flags preserve_source_value_flags =
+ POXY_IMPLEMENTATION_DETAIL(value_flags{static_cast<std::underlying_type_t<value_flags>>(-1)});
+
+ /// \brief Format flags for modifying how TOML data is printed to streams.
+ ///
+ /// \note Formatters may disregard/override any of these flags according to the requirements of
+ /// their
+ /// output target (e.g. #toml::json_formatter will always apply quotes to dates and times).
+ enum class TOML_CLOSED_FLAGS_ENUM format_flags : uint64_t {
+ /// \brief None.
+ none,
+
+ /// \brief Dates and times will be emitted as quoted strings.
+ quote_dates_and_times = (1ull << 0),
+
+ /// \brief Infinities and NaNs will be emitted as quoted strings.
+ quote_infinities_and_nans = (1ull << 1),
+
+ /// \brief Strings will be emitted as single-quoted literal strings where possible.
+ allow_literal_strings = (1ull << 2),
+
+ /// \brief Strings containing newlines will be emitted as triple-quoted 'multi-line' strings
+ /// where possible.
+ allow_multi_line_strings = (1ull << 3),
+
+ /// \brief Allow real tab characters in string literals (as opposed to the escaped form `\t`).
+ allow_real_tabs_in_strings = (1ull << 4),
+
+ /// \brief Allow non-ASCII characters in strings (as opposed to their escaped form, e.g.
+ /// `\u00DA`).
+ allow_unicode_strings = (1ull << 5),
+
+ /// \brief Allow integers with #value_flags::format_as_binary to be emitted as binary.
+ allow_binary_integers = (1ull << 6),
+
+ /// \brief Allow integers with #value_flags::format_as_octal to be emitted as octal.
+ allow_octal_integers = (1ull << 7),
+
+ /// \brief Allow integers with #value_flags::format_as_hexadecimal to be emitted as hexadecimal.
+ allow_hexadecimal_integers = (1ull << 8),
+
+ /// \brief Apply indentation to tables nested within other tables/arrays.
+ indent_sub_tables = (1ull << 9),
+
+ /// \brief Apply indentation to array elements when the array is forced to wrap over multiple
+ /// lines.
+ indent_array_elements = (1ull << 10),
+
+ /// \brief Combination mask of all indentation-enabling flags.
+ indentation = indent_sub_tables | indent_array_elements,
+
+ /// \brief Emit floating-point values with relaxed (human-friendly) precision.
+ /// \warning Setting this flag may cause serialized documents to no longer round-trip correctly
+ /// since floats might have a less precise value upon being written out than they did when
+ ///being read in. Use this flag at your own risk.
+ relaxed_float_precision = (1ull << 11),
+
+ /// \brief Avoids the use of whitespace around key-value pairs.
+ terse_key_value_pairs = (1ull << 12),
+ };
+ TOML_MAKE_FLAGS(format_flags);
+
+ /// \brief Helper class for suppressing move-construction in single-argument array constructors.
+ ///
+ /// \detail \cpp
+ /// // desired result: [ [ 42 ] ]
+ /// auto bad = toml::array{ toml::array{ 42 } };
+ /// auto good = toml::array{ toml::inserter{ toml::array{ 42 } } };
+ /// std::cout << "bad: " << bad << "\n";
+ /// std::cout << "good:" << good << "\n";
+ /// \ecpp
+ /// \out
+ /// bad: [ 42 ]
+ /// good: [ [ 42 ] ]
+ /// \eout
+ ///
+ /// \see toml::array
+ template <typename T>
+ struct TOML_TRIVIAL_ABI inserter {
+ static_assert(std::is_reference_v<T>);
+
+ T value;
+ };
+ template <typename T>
+ inserter(T&&) -> inserter<T&&>;
+ template <typename T>
+ inserter(T&) -> inserter<T&>;
+
+ /// \brief The 'default' formatter used by TOML objects when they are printed to a stream.
+ /// \detail This is an alias for #toml::toml_formatter.
+ using default_formatter = toml_formatter;
}
TOML_NAMESPACE_END;
-//#---------------------------------------------------------------------------------------------------------------------
-//# METAFUNCTIONS & TYPE TRAITS
-//#---------------------------------------------------------------------------------------------------------------------
+// #---------------------------------------------------------------------------------------------------------------------
+// # METAFUNCTIONS & TYPE TRAITS
+// #---------------------------------------------------------------------------------------------------------------------
/// \cond
-TOML_IMPL_NAMESPACE_START
-{
- template <typename T>
- using remove_cvref = std::remove_cv_t<std::remove_reference_t<T>>;
+TOML_IMPL_NAMESPACE_START {
+ template <typename T>
+ using remove_cvref = std::remove_cv_t<std::remove_reference_t<T>>;
- template <typename... T>
- using common_signed_type = std::common_type_t<std::make_signed_t<T>...>;
+ template <typename... T>
+ using common_signed_type = std::common_type_t<std::make_signed_t<T>...>;
- template <typename T, typename... U>
- inline constexpr bool is_one_of = (false || ... || std::is_same_v<T, U>);
+ template <typename T, typename... U>
+ inline constexpr bool is_one_of = (false || ... || std::is_same_v<T, U>);
- template <typename... T>
- inline constexpr bool all_integral = (std::is_integral_v<T> && ...);
+ template <typename... T>
+ inline constexpr bool all_integral = (std::is_integral_v<T> && ...);
- template <typename T>
- inline constexpr bool is_cvref = std::is_reference_v<T> || std::is_const_v<T> || std::is_volatile_v<T>;
+ template <typename T>
+ inline constexpr bool is_cvref =
+ std::is_reference_v<T> || std::is_const_v<T> || std::is_volatile_v<T>;
- template <typename T>
- inline constexpr bool is_wide_string =
- is_one_of<std::decay_t<T>, const wchar_t*, wchar_t*, std::wstring_view, std::wstring>;
+ template <typename T>
+ inline constexpr bool is_wide_string =
+ is_one_of<std::decay_t<T>, const wchar_t*, wchar_t*, std::wstring_view, std::wstring>;
- template <typename T>
- inline constexpr bool value_retrieval_is_nothrow = !std::is_same_v<remove_cvref<T>, std::string>
+ template <typename T>
+ inline constexpr bool value_retrieval_is_nothrow =
+ !std::is_same_v<remove_cvref<T>, std::string>
#if TOML_HAS_CHAR8
- && !std::is_same_v<remove_cvref<T>, std::u8string>
+ && !std::is_same_v<remove_cvref<T>, std::u8string>
#endif
- && !is_wide_string<T>;
-
- template <typename, typename>
- struct copy_ref_;
- template <typename Dest, typename Src>
- using copy_ref = typename copy_ref_<Dest, Src>::type;
-
- template <typename Dest, typename Src>
- struct copy_ref_
- {
- using type = Dest;
- };
-
- template <typename Dest, typename Src>
- struct copy_ref_<Dest, Src&>
- {
- using type = std::add_lvalue_reference_t<Dest>;
- };
-
- template <typename Dest, typename Src>
- struct copy_ref_<Dest, Src&&>
- {
- using type = std::add_rvalue_reference_t<Dest>;
- };
-
- template <typename, typename>
- struct copy_cv_;
- template <typename Dest, typename Src>
- using copy_cv = typename copy_cv_<Dest, Src>::type;
-
- template <typename Dest, typename Src>
- struct copy_cv_
- {
- using type = Dest;
- };
-
- template <typename Dest, typename Src>
- struct copy_cv_<Dest, const Src>
- {
- using type = std::add_const_t<Dest>;
- };
-
- template <typename Dest, typename Src>
- struct copy_cv_<Dest, volatile Src>
- {
- using type = std::add_volatile_t<Dest>;
- };
-
- template <typename Dest, typename Src>
- struct copy_cv_<Dest, const volatile Src>
- {
- using type = std::add_cv_t<Dest>;
- };
-
- template <typename Dest, typename Src>
- using copy_cvref =
- copy_ref<copy_ref<copy_cv<std::remove_reference_t<Dest>, std::remove_reference_t<Src>>, Dest>, Src>;
-
- template <typename...>
- inline constexpr bool always_false = false;
-
- template <typename T, typename... U>
- inline constexpr bool first_is_same = false;
- template <typename T, typename... U>
- inline constexpr bool first_is_same<T, T, U...> = true;
-
- template <typename T, bool = std::is_enum_v<T>>
- struct underlying_type_
- {
- using type = std::underlying_type_t<T>;
- };
- template <typename T>
- struct underlying_type_<T, false>
- {
- using type = T;
- };
- template <typename T>
- using underlying_type = typename underlying_type_<T>::type;
-
- // general value traits
- // (as they relate to their equivalent native TOML type)
- struct default_value_traits
- {
- using native_type = void;
- static constexpr bool is_native = false;
- static constexpr bool is_losslessly_convertible_to_native = false;
- static constexpr bool can_represent_native = false;
- static constexpr bool can_partially_represent_native = false;
- static constexpr auto type = node_type::none;
- };
-
- template <typename T>
- struct value_traits;
-
- template <typename T, bool = std::is_enum_v<T>>
- struct value_traits_base_selector
- {
- static_assert(!is_cvref<T>);
-
- using type = default_value_traits;
- };
- template <typename T>
- struct value_traits_base_selector<T, true>
- {
- static_assert(!is_cvref<T>);
-
- using type = value_traits<underlying_type<T>>;
- };
-
- template <typename T>
- struct value_traits : value_traits_base_selector<T>::type
- {};
- template <typename T>
- struct value_traits<const T> : value_traits<T>
- {};
- template <typename T>
- struct value_traits<volatile T> : value_traits<T>
- {};
- template <typename T>
- struct value_traits<const volatile T> : value_traits<T>
- {};
- template <typename T>
- struct value_traits<T&> : value_traits<T>
- {};
- template <typename T>
- struct value_traits<T&&> : value_traits<T>
- {};
-
- // integer value_traits specializations - standard types
- template <typename T>
- struct integer_limits
- {
- static constexpr T min = T{ (std::numeric_limits<underlying_type<T>>::min)() };
- static constexpr T max = T{ (std::numeric_limits<underlying_type<T>>::max)() };
- };
- template <typename T>
- struct integer_traits_base : integer_limits<T>
- {
- using native_type = int64_t;
- static constexpr bool is_native = std::is_same_v<underlying_type<T>, native_type>;
- static constexpr bool is_signed = static_cast<underlying_type<T>>(-1) < underlying_type<T>{};
- static constexpr auto type = node_type::integer;
- static constexpr bool can_partially_represent_native = true;
- };
- template <typename T>
- struct unsigned_integer_traits : integer_traits_base<T>
- {
- static constexpr bool is_losslessly_convertible_to_native =
- integer_limits<underlying_type<T>>::max <= 9223372036854775807ULL;
- static constexpr bool can_represent_native = false;
- };
- template <typename T>
- struct signed_integer_traits : integer_traits_base<T>
- {
- using native_type = int64_t;
- static constexpr bool is_losslessly_convertible_to_native =
- integer_limits<underlying_type<T>>::min >= (-9223372036854775807LL - 1LL)
- && integer_limits<underlying_type<T>>::max <= 9223372036854775807LL;
- static constexpr bool can_represent_native =
- integer_limits<underlying_type<T>>::min <= (-9223372036854775807LL - 1LL)
- && integer_limits<underlying_type<T>>::max >= 9223372036854775807LL;
- };
- template <typename T, bool S = integer_traits_base<T>::is_signed>
- struct integer_traits : signed_integer_traits<T>
- {};
- template <typename T>
- struct integer_traits<T, false> : unsigned_integer_traits<T>
- {};
- template <>
- struct value_traits<signed char> : integer_traits<signed char>
- {};
- template <>
- struct value_traits<unsigned char> : integer_traits<unsigned char>
- {};
- template <>
- struct value_traits<signed short> : integer_traits<signed short>
- {};
- template <>
- struct value_traits<unsigned short> : integer_traits<unsigned short>
- {};
- template <>
- struct value_traits<signed int> : integer_traits<signed int>
- {};
- template <>
- struct value_traits<unsigned int> : integer_traits<unsigned int>
- {};
- template <>
- struct value_traits<signed long> : integer_traits<signed long>
- {};
- template <>
- struct value_traits<unsigned long> : integer_traits<unsigned long>
- {};
- template <>
- struct value_traits<signed long long> : integer_traits<signed long long>
- {};
- template <>
- struct value_traits<unsigned long long> : integer_traits<unsigned long long>
- {};
- static_assert(value_traits<int64_t>::is_native);
- static_assert(value_traits<int64_t>::is_signed);
- static_assert(value_traits<int64_t>::is_losslessly_convertible_to_native);
- static_assert(value_traits<int64_t>::can_represent_native);
- static_assert(value_traits<int64_t>::can_partially_represent_native);
-
- // integer value_traits specializations - non-standard types
+ && !is_wide_string<T>;
+
+ template <typename, typename>
+ struct copy_ref_;
+ template <typename Dest, typename Src>
+ using copy_ref = typename copy_ref_<Dest, Src>::type;
+
+ template <typename Dest, typename Src>
+ struct copy_ref_ {
+ using type = Dest;
+ };
+
+ template <typename Dest, typename Src>
+ struct copy_ref_<Dest, Src&> {
+ using type = std::add_lvalue_reference_t<Dest>;
+ };
+
+ template <typename Dest, typename Src>
+ struct copy_ref_<Dest, Src&&> {
+ using type = std::add_rvalue_reference_t<Dest>;
+ };
+
+ template <typename, typename>
+ struct copy_cv_;
+ template <typename Dest, typename Src>
+ using copy_cv = typename copy_cv_<Dest, Src>::type;
+
+ template <typename Dest, typename Src>
+ struct copy_cv_ {
+ using type = Dest;
+ };
+
+ template <typename Dest, typename Src>
+ struct copy_cv_<Dest, const Src> {
+ using type = std::add_const_t<Dest>;
+ };
+
+ template <typename Dest, typename Src>
+ struct copy_cv_<Dest, volatile Src> {
+ using type = std::add_volatile_t<Dest>;
+ };
+
+ template <typename Dest, typename Src>
+ struct copy_cv_<Dest, const volatile Src> {
+ using type = std::add_cv_t<Dest>;
+ };
+
+ template <typename Dest, typename Src>
+ using copy_cvref =
+ copy_ref<copy_ref<copy_cv<std::remove_reference_t<Dest>, std::remove_reference_t<Src>>, Dest>,
+ Src>;
+
+ template <typename...>
+ inline constexpr bool always_false = false;
+
+ template <typename T, typename... U>
+ inline constexpr bool first_is_same = false;
+ template <typename T, typename... U>
+ inline constexpr bool first_is_same<T, T, U...> = true;
+
+ template <typename T, bool = std::is_enum_v<T>>
+ struct underlying_type_ {
+ using type = std::underlying_type_t<T>;
+ };
+ template <typename T>
+ struct underlying_type_<T, false> {
+ using type = T;
+ };
+ template <typename T>
+ using underlying_type = typename underlying_type_<T>::type;
+
+ // general value traits
+ // (as they relate to their equivalent native TOML type)
+ struct default_value_traits {
+ using native_type = void;
+ static constexpr bool is_native = false;
+ static constexpr bool is_losslessly_convertible_to_native = false;
+ static constexpr bool can_represent_native = false;
+ static constexpr bool can_partially_represent_native = false;
+ static constexpr auto type = node_type::none;
+ };
+
+ template <typename T>
+ struct value_traits;
+
+ template <typename T, bool = std::is_enum_v<T>>
+ struct value_traits_base_selector {
+ static_assert(!is_cvref<T>);
+
+ using type = default_value_traits;
+ };
+ template <typename T>
+ struct value_traits_base_selector<T, true> {
+ static_assert(!is_cvref<T>);
+
+ using type = value_traits<underlying_type<T>>;
+ };
+
+ template <typename T>
+ struct value_traits : value_traits_base_selector<T>::type {};
+ template <typename T>
+ struct value_traits<const T> : value_traits<T> {};
+ template <typename T>
+ struct value_traits<volatile T> : value_traits<T> {};
+ template <typename T>
+ struct value_traits<const volatile T> : value_traits<T> {};
+ template <typename T>
+ struct value_traits<T&> : value_traits<T> {};
+ template <typename T>
+ struct value_traits<T&&> : value_traits<T> {};
+
+ // integer value_traits specializations - standard types
+ template <typename T>
+ struct integer_limits {
+ static constexpr T min = T{(std::numeric_limits<underlying_type<T>>::min)()};
+ static constexpr T max = T{(std::numeric_limits<underlying_type<T>>::max)()};
+ };
+ template <typename T>
+ struct integer_traits_base : integer_limits<T> {
+ using native_type = int64_t;
+ static constexpr bool is_native = std::is_same_v<underlying_type<T>, native_type>;
+ static constexpr bool is_signed = static_cast<underlying_type<T>>(-1) < underlying_type<T>{};
+ static constexpr auto type = node_type::integer;
+ static constexpr bool can_partially_represent_native = true;
+ };
+ template <typename T>
+ struct unsigned_integer_traits : integer_traits_base<T> {
+ static constexpr bool is_losslessly_convertible_to_native =
+ integer_limits<underlying_type<T>>::max <= 9223372036854775807ULL;
+ static constexpr bool can_represent_native = false;
+ };
+ template <typename T>
+ struct signed_integer_traits : integer_traits_base<T> {
+ using native_type = int64_t;
+ static constexpr bool is_losslessly_convertible_to_native =
+ integer_limits<underlying_type<T>>::min >= (-9223372036854775807LL - 1LL) &&
+ integer_limits<underlying_type<T>>::max <= 9223372036854775807LL;
+ static constexpr bool can_represent_native =
+ integer_limits<underlying_type<T>>::min <= (-9223372036854775807LL - 1LL) &&
+ integer_limits<underlying_type<T>>::max >= 9223372036854775807LL;
+ };
+ template <typename T, bool S = integer_traits_base<T>::is_signed>
+ struct integer_traits : signed_integer_traits<T> {};
+ template <typename T>
+ struct integer_traits<T, false> : unsigned_integer_traits<T> {};
+ template <>
+ struct value_traits<signed char> : integer_traits<signed char> {};
+ template <>
+ struct value_traits<unsigned char> : integer_traits<unsigned char> {};
+ template <>
+ struct value_traits<signed short> : integer_traits<signed short> {};
+ template <>
+ struct value_traits<unsigned short> : integer_traits<unsigned short> {};
+ template <>
+ struct value_traits<signed int> : integer_traits<signed int> {};
+ template <>
+ struct value_traits<unsigned int> : integer_traits<unsigned int> {};
+ template <>
+ struct value_traits<signed long> : integer_traits<signed long> {};
+ template <>
+ struct value_traits<unsigned long> : integer_traits<unsigned long> {};
+ template <>
+ struct value_traits<signed long long> : integer_traits<signed long long> {};
+ template <>
+ struct value_traits<unsigned long long> : integer_traits<unsigned long long> {};
+ static_assert(value_traits<int64_t>::is_native);
+ static_assert(value_traits<int64_t>::is_signed);
+ static_assert(value_traits<int64_t>::is_losslessly_convertible_to_native);
+ static_assert(value_traits<int64_t>::can_represent_native);
+ static_assert(value_traits<int64_t>::can_partially_represent_native);
+
+ // integer value_traits specializations - non-standard types
#ifdef TOML_INT128
- template <>
- struct integer_limits<TOML_INT128>
- {
- static constexpr TOML_INT128 max =
- static_cast<TOML_INT128>((TOML_UINT128{ 1u } << ((__SIZEOF_INT128__ * CHAR_BIT) - 1)) - 1);
- static constexpr TOML_INT128 min = -max - TOML_INT128{ 1 };
- };
- template <>
- struct integer_limits<TOML_UINT128>
- {
- static constexpr TOML_UINT128 min = TOML_UINT128{};
- static constexpr TOML_UINT128 max = (2u * static_cast<TOML_UINT128>(integer_limits<TOML_INT128>::max)) + 1u;
- };
- template <>
- struct value_traits<TOML_INT128> : integer_traits<TOML_INT128>
- {};
- template <>
- struct value_traits<TOML_UINT128> : integer_traits<TOML_UINT128>
- {};
+ template <>
+ struct integer_limits<TOML_INT128> {
+ static constexpr TOML_INT128 max =
+ static_cast<TOML_INT128>((TOML_UINT128{1u} << ((__SIZEOF_INT128__ * CHAR_BIT) - 1)) - 1);
+ static constexpr TOML_INT128 min = -max - TOML_INT128{1};
+ };
+ template <>
+ struct integer_limits<TOML_UINT128> {
+ static constexpr TOML_UINT128 min = TOML_UINT128{};
+ static constexpr TOML_UINT128 max =
+ (2u * static_cast<TOML_UINT128>(integer_limits<TOML_INT128>::max)) + 1u;
+ };
+ template <>
+ struct value_traits<TOML_INT128> : integer_traits<TOML_INT128> {};
+ template <>
+ struct value_traits<TOML_UINT128> : integer_traits<TOML_UINT128> {};
#endif
#ifdef TOML_SMALL_INT_TYPE
- template <>
- struct value_traits<TOML_SMALL_INT_TYPE> : signed_integer_traits<TOML_SMALL_INT_TYPE>
- {};
+ template <>
+ struct value_traits<TOML_SMALL_INT_TYPE> : signed_integer_traits<TOML_SMALL_INT_TYPE> {};
#endif
- // floating-point traits base
- template <typename T, int MantissaDigits, int DecimalDigits>
- 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<T, native_type>;
- static constexpr bool is_signed = true;
-
- static constexpr int bits = static_cast<int>(sizeof(T) * CHAR_BIT);
- static constexpr int digits = MantissaDigits;
- static constexpr int digits10 = DecimalDigits;
-
- static constexpr bool is_losslessly_convertible_to_native = bits <= 64 //
- && digits <= 53 // DBL_MANT_DIG
- && digits10 <= 15; // DBL_DIG
-
- static constexpr bool can_represent_native = digits >= 53 // DBL_MANT_DIG
- && digits10 >= 15; // DBL_DIG
-
- static constexpr bool can_partially_represent_native = digits > 0 && digits10 > 0;
- };
- template <typename T>
- struct float_traits : float_traits_base<T, std::numeric_limits<T>::digits, std::numeric_limits<T>::digits10>
- {};
+ // floating-point traits base
+ template <typename T, int MantissaDigits, int DecimalDigits>
+ 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<T, native_type>;
+ static constexpr bool is_signed = true;
+
+ static constexpr int bits = static_cast<int>(sizeof(T) * CHAR_BIT);
+ static constexpr int digits = MantissaDigits;
+ static constexpr int digits10 = DecimalDigits;
+
+ static constexpr bool is_losslessly_convertible_to_native = bits <= 64 //
+ && digits <= 53 // DBL_MANT_DIG
+ && digits10 <= 15; // DBL_DIG
+
+ static constexpr bool can_represent_native = digits >= 53 // DBL_MANT_DIG
+ && digits10 >= 15; // DBL_DIG
+
+ static constexpr bool can_partially_represent_native = digits > 0 && digits10 > 0;
+ };
+ template <typename T>
+ struct float_traits
+ : float_traits_base<T, std::numeric_limits<T>::digits, std::numeric_limits<T>::digits10> {};
#if TOML_ENABLE_FLOAT16
- template <>
- struct float_traits<_Float16> : float_traits_base<_Float16, __FLT16_MANT_DIG__, __FLT16_DIG__>
- {};
+ template <>
+ struct float_traits<_Float16> : float_traits_base<_Float16, __FLT16_MANT_DIG__, __FLT16_DIG__> {};
#endif
#ifdef TOML_FLOAT128
- template <>
- struct float_traits<TOML_FLOAT128> : float_traits_base<TOML_FLOAT128, __FLT128_MANT_DIG__, __FLT128_DIG__>
- {};
+ template <>
+ struct float_traits<TOML_FLOAT128>
+ : float_traits_base<TOML_FLOAT128, __FLT128_MANT_DIG__, __FLT128_DIG__> {};
#endif
- // floating-point traits
- template <>
- struct value_traits<float> : float_traits<float>
- {};
- template <>
- struct value_traits<double> : float_traits<double>
- {};
- template <>
- struct value_traits<long double> : float_traits<long double>
- {};
+ // floating-point traits
+ template <>
+ struct value_traits<float> : float_traits<float> {};
+ template <>
+ struct value_traits<double> : float_traits<double> {};
+ template <>
+ struct value_traits<long double> : float_traits<long double> {};
#if TOML_ENABLE_FLOAT16
- template <>
- struct value_traits<_Float16> : float_traits<_Float16>
- {};
+ template <>
+ struct value_traits<_Float16> : float_traits<_Float16> {};
#endif
#ifdef TOML_FLOAT128
- template <>
- struct value_traits<TOML_FLOAT128> : float_traits<TOML_FLOAT128>
- {};
+ template <>
+ struct value_traits<TOML_FLOAT128> : float_traits<TOML_FLOAT128> {};
#endif
#ifdef TOML_SMALL_FLOAT_TYPE
- template <>
- struct value_traits<TOML_SMALL_FLOAT_TYPE> : float_traits<TOML_SMALL_FLOAT_TYPE>
- {};
+ template <>
+ struct value_traits<TOML_SMALL_FLOAT_TYPE> : float_traits<TOML_SMALL_FLOAT_TYPE> {};
#endif
- static_assert(value_traits<double>::is_native);
- static_assert(value_traits<double>::is_losslessly_convertible_to_native);
- static_assert(value_traits<double>::can_represent_native);
- static_assert(value_traits<double>::can_partially_represent_native);
-
- // string value_traits specializations - char-based strings
- template <typename T>
- struct string_traits
- {
- using native_type = std::string;
- static constexpr bool is_native = std::is_same_v<T, native_type>;
- static constexpr bool is_losslessly_convertible_to_native = true;
- static constexpr bool can_represent_native =
- !std::is_array_v<T> && (!std::is_pointer_v<T> || std::is_const_v<std::remove_pointer_t<T>>);
- static constexpr bool can_partially_represent_native = can_represent_native;
- static constexpr auto type = node_type::string;
- };
- template <>
- struct value_traits<std::string> : string_traits<std::string>
- {};
- template <>
- struct value_traits<std::string_view> : string_traits<std::string_view>
- {};
- template <>
- struct value_traits<const char*> : string_traits<const char*>
- {};
- template <size_t N>
- struct value_traits<const char[N]> : string_traits<const char[N]>
- {};
- template <>
- struct value_traits<char*> : string_traits<char*>
- {};
- template <size_t N>
- struct value_traits<char[N]> : string_traits<char[N]>
- {};
-
- // string value_traits specializations - char8_t-based strings
+ static_assert(value_traits<double>::is_native);
+ static_assert(value_traits<double>::is_losslessly_convertible_to_native);
+ static_assert(value_traits<double>::can_represent_native);
+ static_assert(value_traits<double>::can_partially_represent_native);
+
+ // string value_traits specializations - char-based strings
+ template <typename T>
+ struct string_traits {
+ using native_type = std::string;
+ static constexpr bool is_native = std::is_same_v<T, native_type>;
+ static constexpr bool is_losslessly_convertible_to_native = true;
+ static constexpr bool can_represent_native =
+ !std::is_array_v<T> && (!std::is_pointer_v<T> || std::is_const_v<std::remove_pointer_t<T>>);
+ static constexpr bool can_partially_represent_native = can_represent_native;
+ static constexpr auto type = node_type::string;
+ };
+ template <>
+ struct value_traits<std::string> : string_traits<std::string> {};
+ template <>
+ struct value_traits<std::string_view> : string_traits<std::string_view> {};
+ template <>
+ struct value_traits<const char*> : string_traits<const char*> {};
+ template <size_t N>
+ struct value_traits<const char[N]> : string_traits<const char[N]> {};
+ template <>
+ struct value_traits<char*> : string_traits<char*> {};
+ template <size_t N>
+ struct value_traits<char[N]> : string_traits<char[N]> {};
+
+ // string value_traits specializations - char8_t-based strings
#if TOML_HAS_CHAR8
- template <>
- struct value_traits<std::u8string> : string_traits<std::u8string>
- {};
- template <>
- struct value_traits<std::u8string_view> : string_traits<std::u8string_view>
- {};
- template <>
- struct value_traits<const char8_t*> : string_traits<const char8_t*>
- {};
- template <size_t N>
- struct value_traits<const char8_t[N]> : string_traits<const char8_t[N]>
- {};
- template <>
- struct value_traits<char8_t*> : string_traits<char8_t*>
- {};
- template <size_t N>
- struct value_traits<char8_t[N]> : string_traits<char8_t[N]>
- {};
+ template <>
+ struct value_traits<std::u8string> : string_traits<std::u8string> {};
+ template <>
+ struct value_traits<std::u8string_view> : string_traits<std::u8string_view> {};
+ template <>
+ struct value_traits<const char8_t*> : string_traits<const char8_t*> {};
+ template <size_t N>
+ struct value_traits<const char8_t[N]> : string_traits<const char8_t[N]> {};
+ template <>
+ struct value_traits<char8_t*> : string_traits<char8_t*> {};
+ template <size_t N>
+ struct value_traits<char8_t[N]> : string_traits<char8_t[N]> {};
#endif
- // string value_traits specializations - wchar_t-based strings on Windows
+ // string value_traits specializations - wchar_t-based strings on Windows
#if TOML_ENABLE_WINDOWS_COMPAT
- template <typename T>
- struct wstring_traits
- {
- using native_type = std::string;
- static constexpr bool is_native = false;
- static constexpr bool is_losslessly_convertible_to_native = true; // narrow
- static constexpr bool can_represent_native = std::is_same_v<T, std::wstring>; // widen
- static constexpr bool can_partially_represent_native = can_represent_native;
- static constexpr auto type = node_type::string;
- };
- template <>
- struct value_traits<std::wstring> : wstring_traits<std::wstring>
- {};
- template <>
- struct value_traits<std::wstring_view> : wstring_traits<std::wstring_view>
- {};
- template <>
- struct value_traits<const wchar_t*> : wstring_traits<const wchar_t*>
- {};
- template <size_t N>
- struct value_traits<const wchar_t[N]> : wstring_traits<const wchar_t[N]>
- {};
- template <>
- struct value_traits<wchar_t*> : wstring_traits<wchar_t*>
- {};
- template <size_t N>
- struct value_traits<wchar_t[N]> : wstring_traits<wchar_t[N]>
- {};
+ template <typename T>
+ struct wstring_traits {
+ using native_type = std::string;
+ static constexpr bool is_native = false;
+ static constexpr bool is_losslessly_convertible_to_native = true; // narrow
+ static constexpr bool can_represent_native = std::is_same_v<T, std::wstring>; // widen
+ static constexpr bool can_partially_represent_native = can_represent_native;
+ static constexpr auto type = node_type::string;
+ };
+ template <>
+ struct value_traits<std::wstring> : wstring_traits<std::wstring> {};
+ template <>
+ struct value_traits<std::wstring_view> : wstring_traits<std::wstring_view> {};
+ template <>
+ struct value_traits<const wchar_t*> : wstring_traits<const wchar_t*> {};
+ template <size_t N>
+ struct value_traits<const wchar_t[N]> : wstring_traits<const wchar_t[N]> {};
+ template <>
+ struct value_traits<wchar_t*> : wstring_traits<wchar_t*> {};
+ template <size_t N>
+ struct value_traits<wchar_t[N]> : wstring_traits<wchar_t[N]> {};
#endif
- // other 'native' value_traits specializations
- template <typename T, node_type NodeType>
- struct native_value_traits
- {
- using native_type = T;
- static constexpr bool is_native = true;
- static constexpr bool is_losslessly_convertible_to_native = true;
- static constexpr bool can_represent_native = true;
- static constexpr bool can_partially_represent_native = true;
- static constexpr auto type = NodeType;
- };
- template <>
- struct value_traits<bool> : native_value_traits<bool, node_type::boolean>
- {};
- template <>
- struct value_traits<date> : native_value_traits<date, node_type::date>
- {};
- template <>
- struct value_traits<time> : native_value_traits<time, node_type::time>
- {};
- template <>
- struct value_traits<date_time> : native_value_traits<date_time, node_type::date_time>
- {};
-
- // native value category queries
- template <typename T>
- using native_type_of = typename value_traits<T>::native_type;
- template <typename T>
- inline constexpr bool is_native = value_traits<T>::is_native;
- template <typename T>
- inline constexpr bool can_represent_native = value_traits<T>::can_represent_native;
- template <typename T>
- inline constexpr bool can_partially_represent_native = value_traits<T>::can_partially_represent_native;
- template <typename T>
- inline constexpr bool is_losslessly_convertible_to_native = value_traits<T>::is_losslessly_convertible_to_native;
- template <typename T, typename... U>
- inline constexpr bool is_natively_one_of = is_one_of<native_type_of<T>, U...>;
-
- // native value types => nodes
- template <typename T>
- struct node_wrapper
- {
- using type = T;
- };
- template <typename T>
- struct node_wrapper<const T>
- {
- using type = std::add_const_t<typename node_wrapper<T>::type>;
- };
- template <typename T>
- struct node_wrapper<volatile T>
- {
- using type = std::add_volatile_t<typename node_wrapper<T>::type>;
- };
- template <typename T>
- struct node_wrapper<const volatile T>
- {
- using type = std::add_const_t<std::add_volatile_t<typename node_wrapper<T>::type>>;
- };
- template <>
- struct node_wrapper<std::string>
- {
- using type = value<std::string>;
- };
- template <>
- struct node_wrapper<int64_t>
- {
- using type = value<int64_t>;
- };
- template <>
- struct node_wrapper<double>
- {
- using type = value<double>;
- };
- template <>
- struct node_wrapper<bool>
- {
- using type = value<bool>;
- };
- template <>
- struct node_wrapper<date>
- {
- using type = value<date>;
- };
- template <>
- struct node_wrapper<time>
- {
- using type = value<time>;
- };
- template <>
- struct node_wrapper<date_time>
- {
- using type = value<date_time>;
- };
- template <typename T>
- using wrap_node = typename node_wrapper<std::remove_reference_t<T>>::type;
-
- // nodes => native value types
- template <typename T>
- struct node_unwrapper
- {
- using type = T;
- };
- template <typename T>
- struct node_unwrapper<value<T>>
- {
- using type = T;
- };
- template <typename T>
- struct node_unwrapper<const value<T>>
- {
- using type = std::add_const_t<T>;
- };
- template <typename T>
- struct node_unwrapper<volatile value<T>>
- {
- using type = std::add_volatile_t<T>;
- };
- template <typename T>
- struct node_unwrapper<const volatile value<T>>
- {
- using type = std::add_volatile_t<std::add_const_t<T>>;
- };
- template <typename T>
- using unwrap_node = typename node_unwrapper<std::remove_reference_t<T>>::type;
-
- template <typename T>
- struct node_type_getter
- {
- static constexpr auto value = value_traits<T>::type;
- };
- template <>
- struct node_type_getter<table>
- {
- static constexpr auto value = node_type::table;
- };
- template <>
- struct node_type_getter<array>
- {
- static constexpr auto value = node_type::array;
- };
- template <>
- struct node_type_getter<void>
- {
- static constexpr auto value = node_type::none;
- };
- template <typename T>
- inline constexpr node_type node_type_of = node_type_getter<unwrap_node<remove_cvref<T>>>::value;
-
- template <typename T, typename ConvertFrom>
- inline constexpr bool is_constructible_or_convertible = std::is_constructible_v<T, ConvertFrom> //
- || std::is_convertible_v<ConvertFrom, T>;
+ // other 'native' value_traits specializations
+ template <typename T, node_type NodeType>
+ struct native_value_traits {
+ using native_type = T;
+ static constexpr bool is_native = true;
+ static constexpr bool is_losslessly_convertible_to_native = true;
+ static constexpr bool can_represent_native = true;
+ static constexpr bool can_partially_represent_native = true;
+ static constexpr auto type = NodeType;
+ };
+ template <>
+ struct value_traits<bool> : native_value_traits<bool, node_type::boolean> {};
+ template <>
+ struct value_traits<date> : native_value_traits<date, node_type::date> {};
+ template <>
+ struct value_traits<time> : native_value_traits<time, node_type::time> {};
+ template <>
+ struct value_traits<date_time> : native_value_traits<date_time, node_type::date_time> {};
+
+ // native value category queries
+ template <typename T>
+ using native_type_of = typename value_traits<T>::native_type;
+ template <typename T>
+ inline constexpr bool is_native = value_traits<T>::is_native;
+ template <typename T>
+ inline constexpr bool can_represent_native = value_traits<T>::can_represent_native;
+ template <typename T>
+ inline constexpr bool can_partially_represent_native =
+ value_traits<T>::can_partially_represent_native;
+ template <typename T>
+ inline constexpr bool is_losslessly_convertible_to_native =
+ value_traits<T>::is_losslessly_convertible_to_native;
+ template <typename T, typename... U>
+ inline constexpr bool is_natively_one_of = is_one_of<native_type_of<T>, U...>;
+
+ // native value types => nodes
+ template <typename T>
+ struct node_wrapper {
+ using type = T;
+ };
+ template <typename T>
+ struct node_wrapper<const T> {
+ using type = std::add_const_t<typename node_wrapper<T>::type>;
+ };
+ template <typename T>
+ struct node_wrapper<volatile T> {
+ using type = std::add_volatile_t<typename node_wrapper<T>::type>;
+ };
+ template <typename T>
+ struct node_wrapper<const volatile T> {
+ using type = std::add_const_t<std::add_volatile_t<typename node_wrapper<T>::type>>;
+ };
+ template <>
+ struct node_wrapper<std::string> {
+ using type = value<std::string>;
+ };
+ template <>
+ struct node_wrapper<int64_t> {
+ using type = value<int64_t>;
+ };
+ template <>
+ struct node_wrapper<double> {
+ using type = value<double>;
+ };
+ template <>
+ struct node_wrapper<bool> {
+ using type = value<bool>;
+ };
+ template <>
+ struct node_wrapper<date> {
+ using type = value<date>;
+ };
+ template <>
+ struct node_wrapper<time> {
+ using type = value<time>;
+ };
+ template <>
+ struct node_wrapper<date_time> {
+ using type = value<date_time>;
+ };
+ template <typename T>
+ using wrap_node = typename node_wrapper<std::remove_reference_t<T>>::type;
+
+ // nodes => native value types
+ template <typename T>
+ struct node_unwrapper {
+ using type = T;
+ };
+ template <typename T>
+ struct node_unwrapper<value<T>> {
+ using type = T;
+ };
+ template <typename T>
+ struct node_unwrapper<const value<T>> {
+ using type = std::add_const_t<T>;
+ };
+ template <typename T>
+ struct node_unwrapper<volatile value<T>> {
+ using type = std::add_volatile_t<T>;
+ };
+ template <typename T>
+ struct node_unwrapper<const volatile value<T>> {
+ using type = std::add_volatile_t<std::add_const_t<T>>;
+ };
+ template <typename T>
+ using unwrap_node = typename node_unwrapper<std::remove_reference_t<T>>::type;
+
+ template <typename T>
+ struct node_type_getter {
+ static constexpr auto value = value_traits<T>::type;
+ };
+ template <>
+ struct node_type_getter<table> {
+ static constexpr auto value = node_type::table;
+ };
+ template <>
+ struct node_type_getter<array> {
+ static constexpr auto value = node_type::array;
+ };
+ template <>
+ struct node_type_getter<void> {
+ static constexpr auto value = node_type::none;
+ };
+ template <typename T>
+ inline constexpr node_type node_type_of = node_type_getter<unwrap_node<remove_cvref<T>>>::value;
+
+ template <typename T, typename ConvertFrom>
+ inline constexpr bool is_constructible_or_convertible =
+ std::is_constructible_v<T, ConvertFrom> //
+ || std::is_convertible_v<ConvertFrom, T>;
}
TOML_IMPL_NAMESPACE_END;
/// \endcond
-TOML_NAMESPACE_START
-{
- /// \brief Metafunction for determining if a type is, or is a reference to, a toml::table.
- template <typename T>
- inline constexpr bool is_table = std::is_same_v<impl::remove_cvref<T>, table>;
-
- /// \brief Metafunction for determining if a type is, or is a reference to, a toml::array.
- template <typename T>
- inline constexpr bool is_array = std::is_same_v<impl::remove_cvref<T>, array>;
-
- /// \brief Metafunction for determining if a type satisfies either toml::is_table or toml::is_array.
- template <typename T>
- inline constexpr bool is_container = is_table<T> || is_array<T>;
-
- /// \brief Metafunction for determining if a type is, or is a reference to, a std::string or toml::value<std::string>.
- template <typename T>
- inline constexpr bool is_string = std::is_same_v< //
- impl::remove_cvref<impl::wrap_node<impl::remove_cvref<T>>>, //
- value<std::string>>;
-
- /// \brief Metafunction for determining if a type is, or is a reference to, a int64_t or toml::value<int64_t>.
- template <typename T>
- inline constexpr bool is_integer = std::is_same_v< //
- impl::remove_cvref<impl::wrap_node<impl::remove_cvref<T>>>, //
- value<int64_t>>;
-
- /// \brief Metafunction for determining if a type is, or is a reference to, a double or toml::value<double>.
- template <typename T>
- inline constexpr bool is_floating_point = std::is_same_v< //
- impl::remove_cvref<impl::wrap_node<impl::remove_cvref<T>>>, //
- value<double>>;
-
- /// \brief Metafunction for determining if a type satisfies either toml::is_integer or toml::is_floating_point.
- template <typename T>
- inline constexpr bool is_number = is_integer<T> || is_floating_point<T>;
-
- /// \brief Metafunction for determining if a type is, or is a reference to, a bool or toml::value<bool>.
- template <typename T>
- inline constexpr bool is_boolean = std::is_same_v< //
- impl::remove_cvref<impl::wrap_node<impl::remove_cvref<T>>>, //
- value<bool>>;
-
- /// \brief Metafunction for determining if a type is, or is a reference to, a toml::date or toml::value<date>.
- template <typename T>
- inline constexpr bool is_date = std::is_same_v< //
- impl::remove_cvref<impl::wrap_node<impl::remove_cvref<T>>>, //
- value<date>>;
-
- /// \brief Metafunction for determining if a type is, or is a reference to, a toml::time or toml::value<time>.
- template <typename T>
- inline constexpr bool is_time = std::is_same_v< //
- impl::remove_cvref<impl::wrap_node<impl::remove_cvref<T>>>, //
- value<time>>;
-
- /// \brief Metafunction for determining if a type is, or is a reference to, a toml::date_time or toml::value<date_time>.
- template <typename T>
- inline constexpr bool is_date_time = std::is_same_v< //
- impl::remove_cvref<impl::wrap_node<impl::remove_cvref<T>>>, //
- value<date_time>>;
-
- /// \brief Metafunction for determining if a type satisfies any of toml::is_date, toml::is_time or toml::is_date_time.
- template <typename T>
- inline constexpr bool is_chronological = is_date<T> || is_time<T> || is_date_time<T>;
-
- /// \brief Metafunction for determining if a type is, or is a reference to, any of the toml value types. Excludes tables and arrays.
- template <typename T>
- inline constexpr bool is_value = is_string<T> || is_number<T> || is_boolean<T> || is_chronological<T>;
-
- /// \brief Metafunction for determining if a type is, or is a reference to, a toml::node (or one of its subclasses).
- template <typename T>
- inline constexpr bool is_node = std::is_same_v<toml::node, impl::remove_cvref<T>> //
- || std::is_base_of_v<toml::node, impl::remove_cvref<T>>;
-
- /// \brief Metafunction for determining if a type is, or is a reference to, a toml::node_view.
- template <typename T>
- inline constexpr bool is_node_view = impl::is_one_of<impl::remove_cvref<T>, node_view<node>, node_view<const node>>;
+TOML_NAMESPACE_START {
+ /// \brief Metafunction for determining if a type is, or is a reference to, a toml::table.
+ template <typename T>
+ inline constexpr bool is_table = std::is_same_v<impl::remove_cvref<T>, table>;
+
+ /// \brief Metafunction for determining if a type is, or is a reference to, a toml::array.
+ template <typename T>
+ inline constexpr bool is_array = std::is_same_v<impl::remove_cvref<T>, array>;
+
+ /// \brief Metafunction for determining if a type satisfies either toml::is_table or
+ /// toml::is_array.
+ template <typename T>
+ inline constexpr bool is_container = is_table<T> || is_array<T>;
+
+ /// \brief Metafunction for determining if a type is, or is a reference to, a std::string or
+ /// toml::value<std::string>.
+ template <typename T>
+ inline constexpr bool is_string = std::is_same_v< //
+ impl::remove_cvref<impl::wrap_node<impl::remove_cvref<T>>>, //
+ value<std::string>>;
+
+ /// \brief Metafunction for determining if a type is, or is a reference to, a int64_t or
+ /// toml::value<int64_t>.
+ template <typename T>
+ inline constexpr bool is_integer = std::is_same_v< //
+ impl::remove_cvref<impl::wrap_node<impl::remove_cvref<T>>>, //
+ value<int64_t>>;
+
+ /// \brief Metafunction for determining if a type is, or is a reference to, a double or
+ /// toml::value<double>.
+ template <typename T>
+ inline constexpr bool is_floating_point = std::is_same_v< //
+ impl::remove_cvref<impl::wrap_node<impl::remove_cvref<T>>>, //
+ value<double>>;
+
+ /// \brief Metafunction for determining if a type satisfies either toml::is_integer or
+ /// toml::is_floating_point.
+ template <typename T>
+ inline constexpr bool is_number = is_integer<T> || is_floating_point<T>;
+
+ /// \brief Metafunction for determining if a type is, or is a reference to, a bool or
+ /// toml::value<bool>.
+ template <typename T>
+ inline constexpr bool is_boolean = std::is_same_v< //
+ impl::remove_cvref<impl::wrap_node<impl::remove_cvref<T>>>, //
+ value<bool>>;
+
+ /// \brief Metafunction for determining if a type is, or is a reference to, a toml::date or
+ /// toml::value<date>.
+ template <typename T>
+ inline constexpr bool is_date = std::is_same_v< //
+ impl::remove_cvref<impl::wrap_node<impl::remove_cvref<T>>>, //
+ value<date>>;
+
+ /// \brief Metafunction for determining if a type is, or is a reference to, a toml::time or
+ /// toml::value<time>.
+ template <typename T>
+ inline constexpr bool is_time = std::is_same_v< //
+ impl::remove_cvref<impl::wrap_node<impl::remove_cvref<T>>>, //
+ value<time>>;
+
+ /// \brief Metafunction for determining if a type is, or is a reference to, a toml::date_time or
+ /// toml::value<date_time>.
+ template <typename T>
+ inline constexpr bool is_date_time = std::is_same_v< //
+ impl::remove_cvref<impl::wrap_node<impl::remove_cvref<T>>>, //
+ value<date_time>>;
+
+ /// \brief Metafunction for determining if a type satisfies any of toml::is_date, toml::is_time
+ /// or toml::is_date_time.
+ template <typename T>
+ inline constexpr bool is_chronological = is_date<T> || is_time<T> || is_date_time<T>;
+
+ /// \brief Metafunction for determining if a type is, or is a reference to, any of the toml value
+ /// types. Excludes tables and arrays.
+ template <typename T>
+ inline constexpr bool is_value =
+ is_string<T> || is_number<T> || is_boolean<T> || is_chronological<T>;
+
+ /// \brief Metafunction for determining if a type is, or is a reference to, a toml::node (or one
+ /// of its subclasses).
+ template <typename T>
+ inline constexpr bool is_node = std::is_same_v<toml::node, impl::remove_cvref<T>> //
+ || std::is_base_of_v<toml::node, impl::remove_cvref<T>>;
+
+ /// \brief Metafunction for determining if a type is, or is a reference to, a toml::node_view.
+ template <typename T>
+ inline constexpr bool is_node_view =
+ impl::is_one_of<impl::remove_cvref<T>, node_view<node>, node_view<const node>>;
}
TOML_NAMESPACE_END;
-//#---------------------------------------------------------------------------------------------------------------------
-//# INTERNAL HELPERS
-//#---------------------------------------------------------------------------------------------------------------------
+// #---------------------------------------------------------------------------------------------------------------------
+// # INTERNAL HELPERS
+// #---------------------------------------------------------------------------------------------------------------------
/// \cond
-TOML_IMPL_NAMESPACE_START
-{
- template <typename T>
- TOML_CONST_INLINE_GETTER
- constexpr std::underlying_type_t<T> unwrap_enum(T val) noexcept
- {
- return static_cast<std::underlying_type_t<T>>(val);
- }
-
- // Q: "why not use std::fpclassify?"
- // A: Because it gets broken by -ffast-math and friends
- enum class TOML_CLOSED_ENUM fp_class : unsigned
- {
- ok,
- neg_inf,
- pos_inf,
- nan
- };
-
- TOML_PURE_GETTER
- inline fp_class fpclassify(const double& val) noexcept
- {
- static_assert(sizeof(uint64_t) == sizeof(double));
-
- static constexpr uint64_t sign = 0b1000000000000000000000000000000000000000000000000000000000000000ull;
- static constexpr uint64_t exponent = 0b0111111111110000000000000000000000000000000000000000000000000000ull;
- static constexpr uint64_t mantissa = 0b0000000000001111111111111111111111111111111111111111111111111111ull;
-
- uint64_t val_bits;
- std::memcpy(&val_bits, &val, sizeof(val));
- if ((val_bits & exponent) != exponent)
- return fp_class::ok;
- if ((val_bits & mantissa))
- return fp_class::nan;
- return (val_bits & sign) ? fp_class::neg_inf : fp_class::pos_inf;
- }
-
- // Q: "why not use std::find and std::min?"
- // A: Because <algorithm> is _huge_ and these would be the only things I used from it.
- // I don't want to impose such a heavy compile-time burden on users.
-
- template <typename Iterator, typename T>
- TOML_PURE_GETTER
- inline auto find(Iterator start, Iterator end, const T& needle) noexcept //
- ->decltype(&(*start))
- {
- for (; start != end; start++)
- if (*start == needle)
- return &(*start);
- return nullptr;
- }
-
- template <typename T>
- TOML_PURE_INLINE_GETTER
- constexpr const T& min(const T& a, const T& b) noexcept //
- {
- return a < b ? a : b;
- }
+TOML_IMPL_NAMESPACE_START {
+ template <typename T>
+ TOML_CONST_INLINE_GETTER constexpr std::underlying_type_t<T> unwrap_enum(T val) noexcept {
+ return static_cast<std::underlying_type_t<T>>(val);
+ }
+
+ // Q: "why not use std::fpclassify?"
+ // A: Because it gets broken by -ffast-math and friends
+ enum class TOML_CLOSED_ENUM fp_class : unsigned { ok, neg_inf, pos_inf, nan };
+
+ TOML_PURE_GETTER
+ inline fp_class fpclassify(const double& val) noexcept {
+ static_assert(sizeof(uint64_t) == sizeof(double));
+
+ static constexpr uint64_t sign =
+ 0b1000000000000000000000000000000000000000000000000000000000000000ull;
+ static constexpr uint64_t exponent =
+ 0b0111111111110000000000000000000000000000000000000000000000000000ull;
+ static constexpr uint64_t mantissa =
+ 0b0000000000001111111111111111111111111111111111111111111111111111ull;
+
+ uint64_t val_bits;
+ std::memcpy(&val_bits, &val, sizeof(val));
+ if ((val_bits & exponent) != exponent) return fp_class::ok;
+ if ((val_bits & mantissa)) return fp_class::nan;
+ return (val_bits & sign) ? fp_class::neg_inf : fp_class::pos_inf;
+ }
+
+ // Q: "why not use std::find and std::min?"
+ // A: Because <algorithm> is _huge_ and these would be the only things I used from it.
+ // I don't want to impose such a heavy compile-time burden on users.
+
+ template <typename Iterator, typename T>
+ TOML_PURE_GETTER inline auto find(Iterator start, Iterator end, const T& needle) noexcept //
+ -> decltype(&(*start)) {
+ for (; start != end; start++)
+ if (*start == needle) return &(*start);
+ return nullptr;
+ }
+
+ template <typename T>
+ TOML_PURE_INLINE_GETTER constexpr const T& min(const T& a, const T& b) noexcept //
+ {
+ return a < b ? a : b;
+ }
}
TOML_IMPL_NAMESPACE_END;
/// \endcond