mirror of
https://github.com/marzer/tomlplusplus.git
synced 2024-09-15 15:13:21 +00:00
fixed dotted kvps being unable to add subtables (fixes #61)
also: - fixed extremely weird linker error on linux ICC (fixes #83) - added some missing GNU attributes - added additional tests
This commit is contained in:
parent
5a9166bce8
commit
b11f28af78
@ -348,7 +348,7 @@ PREDEFINED = \
|
|||||||
"TOML_EXTERNAL_LINKAGE=" \
|
"TOML_EXTERNAL_LINKAGE=" \
|
||||||
"TOML_TRIVIAL_ABI=" \
|
"TOML_TRIVIAL_ABI=" \
|
||||||
"TOML_EMPTY_BASES=" \
|
"TOML_EMPTY_BASES=" \
|
||||||
"TOML_INTERFACE" \
|
"TOML_ABSTRACT_BASE" \
|
||||||
"TOML_INTERNAL_LINKAGE=static"
|
"TOML_INTERNAL_LINKAGE=static"
|
||||||
EXPAND_AS_DEFINED =
|
EXPAND_AS_DEFINED =
|
||||||
SKIP_FUNCTION_MACROS = NO
|
SKIP_FUNCTION_MACROS = NO
|
||||||
|
@ -58,6 +58,7 @@ TOML_POP_WARNINGS // TOML_DISABLE_SPAM_WARNINGS
|
|||||||
#undef TOML_ABI_NAMESPACE_BOOL
|
#undef TOML_ABI_NAMESPACE_BOOL
|
||||||
#undef TOML_ABI_NAMESPACE_END
|
#undef TOML_ABI_NAMESPACE_END
|
||||||
#undef TOML_ABI_NAMESPACE_START
|
#undef TOML_ABI_NAMESPACE_START
|
||||||
|
#undef TOML_ABSTRACT_BASE
|
||||||
#undef TOML_ALWAYS_INLINE
|
#undef TOML_ALWAYS_INLINE
|
||||||
#undef TOML_ANON_NAMESPACE
|
#undef TOML_ANON_NAMESPACE
|
||||||
#undef TOML_ANON_NAMESPACE_END
|
#undef TOML_ANON_NAMESPACE_END
|
||||||
@ -100,7 +101,6 @@ TOML_POP_WARNINGS // TOML_DISABLE_SPAM_WARNINGS
|
|||||||
#undef TOML_IMPL_NAMESPACE_START
|
#undef TOML_IMPL_NAMESPACE_START
|
||||||
#undef TOML_INT128
|
#undef TOML_INT128
|
||||||
#undef TOML_INTELLISENSE
|
#undef TOML_INTELLISENSE
|
||||||
#undef TOML_INTERFACE
|
|
||||||
#undef TOML_INTERNAL_LINKAGE
|
#undef TOML_INTERNAL_LINKAGE
|
||||||
#undef TOML_INT_CHARCONV
|
#undef TOML_INT_CHARCONV
|
||||||
#undef TOML_LANG_AT_LEAST
|
#undef TOML_LANG_AT_LEAST
|
||||||
|
@ -22,6 +22,7 @@ TOML_IMPL_NAMESPACE_START
|
|||||||
|
|
||||||
mutable raw_iterator raw_;
|
mutable raw_iterator raw_;
|
||||||
|
|
||||||
|
TOML_NODISCARD_CTOR
|
||||||
array_iterator(raw_mutable_iterator raw) noexcept
|
array_iterator(raw_mutable_iterator raw) noexcept
|
||||||
: raw_{ raw }
|
: raw_{ raw }
|
||||||
{}
|
{}
|
||||||
@ -40,8 +41,12 @@ TOML_IMPL_NAMESPACE_START
|
|||||||
using difference_type = ptrdiff_t;
|
using difference_type = ptrdiff_t;
|
||||||
using iterator_category = typename std::iterator_traits<raw_iterator>::iterator_category;
|
using iterator_category = typename std::iterator_traits<raw_iterator>::iterator_category;
|
||||||
|
|
||||||
|
TOML_NODISCARD_CTOR
|
||||||
array_iterator() noexcept = default;
|
array_iterator() noexcept = default;
|
||||||
|
|
||||||
|
TOML_NODISCARD_CTOR
|
||||||
array_iterator(const array_iterator&) noexcept = default;
|
array_iterator(const array_iterator&) noexcept = default;
|
||||||
|
|
||||||
array_iterator& operator = (const array_iterator&) noexcept = default;
|
array_iterator& operator = (const array_iterator&) noexcept = default;
|
||||||
|
|
||||||
array_iterator& operator++() noexcept // ++pre
|
array_iterator& operator++() noexcept // ++pre
|
||||||
@ -429,6 +434,7 @@ TOML_NAMESPACE_START
|
|||||||
[[nodiscard]] bool is_homogeneous(node_type ntype) const noexcept override;
|
[[nodiscard]] bool is_homogeneous(node_type ntype) const noexcept override;
|
||||||
[[nodiscard]] bool is_homogeneous(node_type ntype, node*& first_nonmatch) noexcept override;
|
[[nodiscard]] bool is_homogeneous(node_type ntype, node*& first_nonmatch) noexcept override;
|
||||||
[[nodiscard]] bool is_homogeneous(node_type ntype, const node*& first_nonmatch) const noexcept override;
|
[[nodiscard]] bool is_homogeneous(node_type ntype, const node*& first_nonmatch) const noexcept override;
|
||||||
|
|
||||||
template <typename ElemType = void>
|
template <typename ElemType = void>
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
bool is_homogeneous() const noexcept
|
bool is_homogeneous() const noexcept
|
||||||
|
@ -61,7 +61,7 @@ TOML_NAMESPACE_START
|
|||||||
///
|
///
|
||||||
/// \detail A parsed TOML document forms a tree made up of tables, arrays and values.
|
/// \detail A parsed TOML document forms a tree made up of tables, arrays and values.
|
||||||
/// This type is the base of each of those, providing a lot of the polymorphic plumbing.
|
/// This type is the base of each of those, providing a lot of the polymorphic plumbing.
|
||||||
class TOML_INTERFACE TOML_API node
|
class TOML_ABSTRACT_BASE TOML_API node
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
friend class TOML_PARSER_TYPENAME;
|
friend class TOML_PARSER_TYPENAME;
|
||||||
@ -78,6 +78,7 @@ TOML_NAMESPACE_START
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
TOML_ALWAYS_INLINE
|
TOML_ALWAYS_INLINE
|
||||||
|
TOML_ATTR(pure)
|
||||||
impl::wrap_node<T>& ref_cast() & noexcept
|
impl::wrap_node<T>& ref_cast() & noexcept
|
||||||
{
|
{
|
||||||
return *reinterpret_cast<impl::wrap_node<T>*>(this);
|
return *reinterpret_cast<impl::wrap_node<T>*>(this);
|
||||||
@ -86,6 +87,7 @@ TOML_NAMESPACE_START
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
TOML_ALWAYS_INLINE
|
TOML_ALWAYS_INLINE
|
||||||
|
TOML_ATTR(pure)
|
||||||
impl::wrap_node<T>&& ref_cast() && noexcept
|
impl::wrap_node<T>&& ref_cast() && noexcept
|
||||||
{
|
{
|
||||||
return std::move(*reinterpret_cast<impl::wrap_node<T>*>(this));
|
return std::move(*reinterpret_cast<impl::wrap_node<T>*>(this));
|
||||||
@ -94,6 +96,7 @@ TOML_NAMESPACE_START
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
TOML_ALWAYS_INLINE
|
TOML_ALWAYS_INLINE
|
||||||
|
TOML_ATTR(pure)
|
||||||
const impl::wrap_node<T>& ref_cast() const & noexcept
|
const impl::wrap_node<T>& ref_cast() const & noexcept
|
||||||
{
|
{
|
||||||
return *reinterpret_cast<const impl::wrap_node<T>*>(this);
|
return *reinterpret_cast<const impl::wrap_node<T>*>(this);
|
||||||
@ -106,9 +109,26 @@ TOML_NAMESPACE_START
|
|||||||
|
|
||||||
virtual ~node() noexcept = default;
|
virtual ~node() noexcept = default;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(DOXYGEN) || !TOML_ICC || TOML_ICC_CL
|
||||||
|
|
||||||
/// \brief Returns the node's type identifier.
|
/// \brief Returns the node's type identifier.
|
||||||
[[nodiscard]] virtual node_type type() const noexcept = 0;
|
[[nodiscard]] virtual node_type type() const noexcept = 0;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
[[nodiscard]] virtual node_type type() const noexcept
|
||||||
|
{
|
||||||
|
// Q: "what the fuck?"
|
||||||
|
// A: https://github.com/marzer/tomlplusplus/issues/83
|
||||||
|
// tl,dr: go home ICC, you're drunk.
|
||||||
|
|
||||||
|
return type();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
/// \brief Returns true if this node is a table.
|
/// \brief Returns true if this node is a table.
|
||||||
[[nodiscard]] virtual bool is_table() const noexcept = 0;
|
[[nodiscard]] virtual bool is_table() const noexcept = 0;
|
||||||
/// \brief Returns true if this node is an array.
|
/// \brief Returns true if this node is an array.
|
||||||
@ -142,6 +162,7 @@ TOML_NAMESPACE_START
|
|||||||
/// \returns Returns true if this node is an instance of the specified type.
|
/// \returns Returns true if this node is an instance of the specified type.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
|
TOML_ATTR(pure)
|
||||||
bool is() const noexcept
|
bool is() const noexcept
|
||||||
{
|
{
|
||||||
using type = impl::unwrap_node<T>;
|
using type = impl::unwrap_node<T>;
|
||||||
@ -278,6 +299,7 @@ TOML_NAMESPACE_START
|
|||||||
/// \remarks Always returns `false` for empty tables and arrays.
|
/// \remarks Always returns `false` for empty tables and arrays.
|
||||||
template <typename ElemType = void>
|
template <typename ElemType = void>
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
|
TOML_ATTR(pure)
|
||||||
bool is_homogeneous() const noexcept
|
bool is_homogeneous() const noexcept
|
||||||
{
|
{
|
||||||
using type = impl::unwrap_node<ElemType>;
|
using type = impl::unwrap_node<ElemType>;
|
||||||
@ -501,6 +523,7 @@ TOML_NAMESPACE_START
|
|||||||
/// \returns A pointer to the node as the given type, or nullptr if it was a different type.
|
/// \returns A pointer to the node as the given type, or nullptr if it was a different type.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
|
TOML_ATTR(pure)
|
||||||
impl::wrap_node<T>* as() noexcept
|
impl::wrap_node<T>* as() noexcept
|
||||||
{
|
{
|
||||||
using type = impl::unwrap_node<T>;
|
using type = impl::unwrap_node<T>;
|
||||||
@ -524,6 +547,7 @@ TOML_NAMESPACE_START
|
|||||||
/// \brief Gets a pointer to the node as a more specific node type (const overload).
|
/// \brief Gets a pointer to the node as a more specific node type (const overload).
|
||||||
template <typename T>
|
template <typename T>
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
|
TOML_ATTR(pure)
|
||||||
const impl::wrap_node<T>* as() const noexcept
|
const impl::wrap_node<T>* as() const noexcept
|
||||||
{
|
{
|
||||||
using type = impl::unwrap_node<T>;
|
using type = impl::unwrap_node<T>;
|
||||||
@ -702,6 +726,7 @@ TOML_NAMESPACE_START
|
|||||||
|
|
||||||
template <typename T, typename N>
|
template <typename T, typename N>
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
|
TOML_ATTR(pure)
|
||||||
static decltype(auto) do_ref(N&& n) noexcept
|
static decltype(auto) do_ref(N&& n) noexcept
|
||||||
{
|
{
|
||||||
using type = impl::unwrap_node<T>;
|
using type = impl::unwrap_node<T>;
|
||||||
@ -794,6 +819,7 @@ TOML_NAMESPACE_START
|
|||||||
/// \returns A reference to the underlying data.
|
/// \returns A reference to the underlying data.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
|
TOML_ATTR(pure)
|
||||||
impl::unwrap_node<T>& ref() & noexcept
|
impl::unwrap_node<T>& ref() & noexcept
|
||||||
{
|
{
|
||||||
return do_ref<T>(*this);
|
return do_ref<T>(*this);
|
||||||
@ -802,6 +828,7 @@ TOML_NAMESPACE_START
|
|||||||
/// \brief Gets a raw reference to a value node's underlying data (rvalue overload).
|
/// \brief Gets a raw reference to a value node's underlying data (rvalue overload).
|
||||||
template <typename T>
|
template <typename T>
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
|
TOML_ATTR(pure)
|
||||||
impl::unwrap_node<T>&& ref() && noexcept
|
impl::unwrap_node<T>&& ref() && noexcept
|
||||||
{
|
{
|
||||||
return do_ref<T>(std::move(*this));
|
return do_ref<T>(std::move(*this));
|
||||||
@ -810,6 +837,7 @@ TOML_NAMESPACE_START
|
|||||||
/// \brief Gets a raw reference to a value node's underlying data (const lvalue overload).
|
/// \brief Gets a raw reference to a value node's underlying data (const lvalue overload).
|
||||||
template <typename T>
|
template <typename T>
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
|
TOML_ATTR(pure)
|
||||||
const impl::unwrap_node<T>& ref() const& noexcept
|
const impl::unwrap_node<T>& ref() const& noexcept
|
||||||
{
|
{
|
||||||
return do_ref<T>(*this);
|
return do_ref<T>(*this);
|
||||||
|
@ -2659,6 +2659,9 @@ TOML_IMPL_NAMESPACE_START
|
|||||||
return_if_error();
|
return_if_error();
|
||||||
|
|
||||||
TOML_ASSERT(kvp.key.segments.size() >= 1_sz);
|
TOML_ASSERT(kvp.key.segments.size() >= 1_sz);
|
||||||
|
|
||||||
|
// if it's a dotted kvp we need to spawn the sub-tables if necessary,
|
||||||
|
// and set the target table to the second-to-last one in the chain
|
||||||
if (kvp.key.segments.size() > 1_sz)
|
if (kvp.key.segments.size() > 1_sz)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < kvp.key.segments.size() - 1_sz; i++)
|
for (size_t i = 0; i < kvp.key.segments.size() - 1_sz; i++)
|
||||||
@ -2671,13 +2674,14 @@ TOML_IMPL_NAMESPACE_START
|
|||||||
new toml::table{}
|
new toml::table{}
|
||||||
).first->second.get();
|
).first->second.get();
|
||||||
dotted_key_tables.push_back(&child->ref_cast<table>());
|
dotted_key_tables.push_back(&child->ref_cast<table>());
|
||||||
dotted_key_tables.back()->inline_ = true;
|
|
||||||
child->source_ = kvp.value.get()->source_;
|
child->source_ = kvp.value.get()->source_;
|
||||||
}
|
}
|
||||||
else if (!child->is_table() || !find(dotted_key_tables, &child->ref_cast<table>()))
|
else if (!child->is_table()
|
||||||
|
|| !(find(dotted_key_tables, &child->ref_cast<table>()) || find(implicit_tables, &child->ref_cast<table>())))
|
||||||
set_error("cannot redefine existing "sv, to_sv(child->type()), " as dotted key-value pair"sv);
|
set_error("cannot redefine existing "sv, to_sv(child->type()), " as dotted key-value pair"sv);
|
||||||
else
|
else
|
||||||
child->source_.end = kvp.value.get()->source_.end;
|
child->source_.end = kvp.value.get()->source_.end;
|
||||||
|
|
||||||
return_if_error();
|
return_if_error();
|
||||||
tab = &child->ref_cast<table>();
|
tab = &child->ref_cast<table>();
|
||||||
}
|
}
|
||||||
|
@ -73,7 +73,7 @@
|
|||||||
#if defined(_MSC_VER) // msvc compat mode
|
#if defined(_MSC_VER) // msvc compat mode
|
||||||
#ifdef __has_declspec_attribute
|
#ifdef __has_declspec_attribute
|
||||||
#if __has_declspec_attribute(novtable)
|
#if __has_declspec_attribute(novtable)
|
||||||
#define TOML_INTERFACE __declspec(novtable)
|
#define TOML_ABSTRACT_BASE __declspec(novtable)
|
||||||
#endif
|
#endif
|
||||||
#if __has_declspec_attribute(empty_bases)
|
#if __has_declspec_attribute(empty_bases)
|
||||||
#define TOML_EMPTY_BASES __declspec(empty_bases)
|
#define TOML_EMPTY_BASES __declspec(empty_bases)
|
||||||
@ -125,7 +125,7 @@
|
|||||||
#define TOML_NEVER_INLINE __declspec(noinline)
|
#define TOML_NEVER_INLINE __declspec(noinline)
|
||||||
#define TOML_ASSUME(cond) __assume(cond)
|
#define TOML_ASSUME(cond) __assume(cond)
|
||||||
#define TOML_UNREACHABLE __assume(0)
|
#define TOML_UNREACHABLE __assume(0)
|
||||||
#define TOML_INTERFACE __declspec(novtable)
|
#define TOML_ABSTRACT_BASE __declspec(novtable)
|
||||||
#define TOML_EMPTY_BASES __declspec(empty_bases)
|
#define TOML_EMPTY_BASES __declspec(empty_bases)
|
||||||
|
|
||||||
#endif // msvc
|
#endif // msvc
|
||||||
@ -374,8 +374,8 @@ is no longer necessary.
|
|||||||
#define TOML_ATTR(...)
|
#define TOML_ATTR(...)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef TOML_INTERFACE
|
#ifndef TOML_ABSTRACT_BASE
|
||||||
#define TOML_INTERFACE
|
#define TOML_ABSTRACT_BASE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef TOML_EMPTY_BASES
|
#ifndef TOML_EMPTY_BASES
|
||||||
|
@ -47,6 +47,7 @@ TOML_IMPL_NAMESPACE_START
|
|||||||
return TOML_LAUNDER(reinterpret_cast<proxy_type*>(&proxy));
|
return TOML_LAUNDER(reinterpret_cast<proxy_type*>(&proxy));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TOML_NODISCARD_CTOR
|
||||||
table_iterator(raw_mutable_iterator raw) noexcept
|
table_iterator(raw_mutable_iterator raw) noexcept
|
||||||
: raw_{ raw }
|
: raw_{ raw }
|
||||||
{}
|
{}
|
||||||
@ -59,8 +60,10 @@ TOML_IMPL_NAMESPACE_START
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
TOML_NODISCARD_CTOR
|
||||||
table_iterator() noexcept = default;
|
table_iterator() noexcept = default;
|
||||||
|
|
||||||
|
TOML_NODISCARD_CTOR
|
||||||
table_iterator(const table_iterator& other) noexcept
|
table_iterator(const table_iterator& other) noexcept
|
||||||
: raw_{ other.raw_ }
|
: raw_{ other.raw_ }
|
||||||
{}
|
{}
|
||||||
|
@ -174,7 +174,7 @@ TOML_IMPL_NAMESPACE_START
|
|||||||
#define TOML_ERROR err.emplace
|
#define TOML_ERROR err.emplace
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct TOML_INTERFACE utf8_reader_interface
|
struct TOML_ABSTRACT_BASE utf8_reader_interface
|
||||||
{
|
{
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
virtual const source_path_ptr& source_path() const noexcept = 0;
|
virtual const source_path_ptr& source_path() const noexcept = 0;
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
#define TOML_LIB_MAJOR 2
|
#define TOML_LIB_MAJOR 2
|
||||||
#define TOML_LIB_MINOR 3
|
#define TOML_LIB_MINOR 3
|
||||||
#define TOML_LIB_PATCH 0
|
#define TOML_LIB_PATCH 1
|
||||||
|
|
||||||
#define TOML_LANG_MAJOR 1
|
#define TOML_LANG_MAJOR 1
|
||||||
#define TOML_LANG_MINOR 0
|
#define TOML_LANG_MINOR 0
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
project(
|
project(
|
||||||
'tomlplusplus',
|
'tomlplusplus',
|
||||||
'cpp',
|
'cpp',
|
||||||
version : '2.3.0',
|
version : '2.3.1',
|
||||||
meson_version : '>=0.53.0',
|
meson_version : '>=0.53.0',
|
||||||
license : 'MIT',
|
license : 'MIT',
|
||||||
default_options : [ # https://mesonbuild.com/Builtin-options.html
|
default_options : [ # https://mesonbuild.com/Builtin-options.html
|
||||||
|
@ -7,219 +7,364 @@
|
|||||||
|
|
||||||
TEST_CASE("parsing - tables")
|
TEST_CASE("parsing - tables")
|
||||||
{
|
{
|
||||||
|
// these are the examples from https://toml.io/en/v1.0.0#table
|
||||||
|
|
||||||
|
// "Tables are defined by headers, with square brackets on a line by themselves."
|
||||||
|
parsing_should_succeed(
|
||||||
|
FILE_LINE_ARGS, "[table]"sv,
|
||||||
|
[](table&& tbl)
|
||||||
|
{
|
||||||
|
REQUIRE(tbl["table"].as_table());
|
||||||
|
CHECK(tbl["table"].as_table()->empty());
|
||||||
|
CHECK(tbl["table"].as_table()->size() == 0u);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
parsing_should_fail(FILE_LINE_ARGS, "[]"sv);
|
||||||
|
|
||||||
|
// "Under that, and until the next header or EOF, are the key/values of that table.
|
||||||
|
// Key/value pairs within tables are not guaranteed to be in any specific order."
|
||||||
parsing_should_succeed(
|
parsing_should_succeed(
|
||||||
FILE_LINE_ARGS,
|
FILE_LINE_ARGS,
|
||||||
R"(
|
R"(
|
||||||
[table]
|
[table-1]
|
||||||
|
key1 = "some string"
|
||||||
|
key2 = 123
|
||||||
|
|
||||||
[table-1]
|
[table-2]
|
||||||
key1 = "some string"
|
key1 = "another string"
|
||||||
key2 = 123
|
key2 = 456
|
||||||
|
)"sv,
|
||||||
[table-2]
|
|
||||||
key1 = "another string"
|
|
||||||
key2 = 456
|
|
||||||
|
|
||||||
[dog."tater.man"]
|
|
||||||
type.name = "pug"
|
|
||||||
|
|
||||||
[a.b.c] # this is best practice
|
|
||||||
[ d.e.f ] # same as [d.e.f]
|
|
||||||
[ g . h . i ] # same as [g.h.i]
|
|
||||||
[ j . "k" . 'l' ] # same as [j."k".'l']
|
|
||||||
|
|
||||||
# [x] you
|
|
||||||
# [x.y] don't
|
|
||||||
# [x.y.z] need these
|
|
||||||
[x.y.z.w] # for this to work
|
|
||||||
|
|
||||||
[x] # defining a super-table afterwards is ok
|
|
||||||
|
|
||||||
[fruit]
|
|
||||||
apple.color = "red"
|
|
||||||
apple.taste.sweet = true
|
|
||||||
|
|
||||||
[fruit.apple.texture] # you can add sub-tables
|
|
||||||
smooth = true
|
|
||||||
|
|
||||||
)"sv,
|
|
||||||
[](table&& tbl)
|
[](table&& tbl)
|
||||||
{
|
{
|
||||||
REQUIRE(tbl["table"].as<table>());
|
REQUIRE(tbl["table-1"].as_table());
|
||||||
CHECK(tbl["table"].as<table>()->size() == 0u);
|
CHECK(tbl["table-1"].as_table()->size() == 2u);
|
||||||
|
|
||||||
REQUIRE(tbl["table-1"].as<table>());
|
|
||||||
CHECK(tbl["table-1"].as<table>()->size() == 2u);
|
|
||||||
CHECK(tbl["table-1"]["key1"] == "some string"sv);
|
CHECK(tbl["table-1"]["key1"] == "some string"sv);
|
||||||
CHECK(tbl["table-1"]["key2"] == 123);
|
CHECK(tbl["table-1"]["key2"] == 123);
|
||||||
|
|
||||||
REQUIRE(tbl["table-2"].as<table>());
|
REQUIRE(tbl["table-2"].as_table());
|
||||||
CHECK(tbl["table-2"].as<table>()->size() == 2u);
|
CHECK(tbl["table-2"].as_table()->size() == 2u);
|
||||||
CHECK(tbl["table-2"]["key1"] == "another string"sv);
|
CHECK(tbl["table-2"]["key1"] == "another string"sv);
|
||||||
CHECK(tbl["table-2"]["key2"] == 456);
|
CHECK(tbl["table-2"]["key2"] == 456);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
REQUIRE(tbl["dog"].as<table>());
|
// "Naming rules for tables are the same as for keys." (i.e. can be quoted)
|
||||||
CHECK(tbl["dog"].as<table>()->size() == 1u);
|
parsing_should_succeed(
|
||||||
|
FILE_LINE_ARGS,
|
||||||
|
R"(
|
||||||
|
[dog."tater.man"]
|
||||||
|
type.name = "pug"
|
||||||
|
)"sv,
|
||||||
|
[](table&& tbl)
|
||||||
|
{
|
||||||
|
REQUIRE(tbl["dog"].as_table());
|
||||||
|
CHECK(tbl["dog"].as_table()->size() == 1u);
|
||||||
|
|
||||||
REQUIRE(tbl["dog"]["tater.man"].as<table>());
|
REQUIRE(tbl["dog"]["tater.man"].as_table());
|
||||||
CHECK(tbl["dog"]["tater.man"].as<table>()->size() == 1u);
|
CHECK(tbl["dog"]["tater.man"].as_table()->size() == 1u);
|
||||||
CHECK(tbl["dog"]["tater.man"]["type"]["name"] == "pug"sv);
|
CHECK(tbl["dog"]["tater.man"]["type"]["name"] == "pug"sv);
|
||||||
|
|
||||||
CHECK(tbl["a"].as<table>());
|
|
||||||
CHECK(tbl["a"]["b"].as<table>());
|
|
||||||
CHECK(tbl["a"]["b"]["c"].as<table>());
|
|
||||||
|
|
||||||
CHECK(tbl["d"].as<table>());
|
|
||||||
CHECK(tbl["d"]["e"].as<table>());
|
|
||||||
CHECK(tbl["d"]["e"]["f"].as<table>());
|
|
||||||
|
|
||||||
CHECK(tbl["g"].as<table>());
|
|
||||||
CHECK(tbl["g"]["h"].as<table>());
|
|
||||||
CHECK(tbl["g"]["h"]["i"].as<table>());
|
|
||||||
|
|
||||||
CHECK(tbl["j"].as<table>());
|
|
||||||
CHECK(tbl["j"]["k"].as<table>());
|
|
||||||
CHECK(tbl["j"]["k"]["l"].as<table>());
|
|
||||||
|
|
||||||
REQUIRE(tbl["fruit"].as<table>());
|
|
||||||
CHECK(tbl["fruit"]["apple"]["color"] == "red"sv);
|
|
||||||
CHECK(tbl["fruit"]["apple"]["taste"]["sweet"] == true);
|
|
||||||
CHECK(tbl["fruit"]["apple"]["texture"]["smooth"] == true);
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// "Whitespace around the key is ignored. However, best practice is to not use any extraneous whitespace."
|
||||||
parsing_should_fail(FILE_LINE_ARGS, R"(
|
|
||||||
# DO NOT DO THIS
|
|
||||||
|
|
||||||
[fruit]
|
|
||||||
apple = "red"
|
|
||||||
|
|
||||||
[fruit]
|
|
||||||
orange = "orange"
|
|
||||||
)"sv);
|
|
||||||
|
|
||||||
parsing_should_fail(FILE_LINE_ARGS, R"(
|
|
||||||
# DO NOT DO THIS EITHER
|
|
||||||
|
|
||||||
[fruit]
|
|
||||||
apple = "red"
|
|
||||||
|
|
||||||
[fruit.apple]
|
|
||||||
texture = "smooth"
|
|
||||||
)"sv);
|
|
||||||
|
|
||||||
parsing_should_fail(FILE_LINE_ARGS, R"(
|
|
||||||
[fruit]
|
|
||||||
apple.color = "red"
|
|
||||||
apple.taste.sweet = true
|
|
||||||
|
|
||||||
[fruit.apple]
|
|
||||||
)"sv);
|
|
||||||
|
|
||||||
parsing_should_fail(FILE_LINE_ARGS, R"(
|
|
||||||
[fruit]
|
|
||||||
apple.color = "red"
|
|
||||||
apple.taste.sweet = true
|
|
||||||
|
|
||||||
[fruit.apple.taste]
|
|
||||||
)"sv);
|
|
||||||
|
|
||||||
parsing_should_succeed(
|
parsing_should_succeed(
|
||||||
FILE_LINE_ARGS,
|
FILE_LINE_ARGS,
|
||||||
R"(
|
R"(
|
||||||
# VALID BUT DISCOURAGED
|
[a.b.c] # this is best practice
|
||||||
[fruit.apple]
|
[ d.e.f ] # same as [d.e.f]
|
||||||
[animal]
|
[ g . h . i ] # same as [g.h.i]
|
||||||
[fruit.orange]
|
[ j . "k" . 'l' ] # same as [j."k".'l']
|
||||||
)"sv,
|
)"sv,
|
||||||
[](table&& tbl)
|
[](table&& tbl)
|
||||||
{
|
{
|
||||||
REQUIRE(tbl["animal"].as<table>());
|
CHECK(tbl["a"].as_table());
|
||||||
CHECK(tbl["animal"].as<table>()->size() == 0u);
|
CHECK(tbl["a"]["b"].as_table());
|
||||||
|
CHECK(tbl["a"]["b"]["c"].as_table());
|
||||||
|
|
||||||
REQUIRE(tbl["fruit"].as<table>());
|
CHECK(tbl["d"].as_table());
|
||||||
CHECK(tbl["fruit"].as<table>()->size() == 2u);
|
CHECK(tbl["d"]["e"].as_table());
|
||||||
|
CHECK(tbl["d"]["e"]["f"].as_table());
|
||||||
|
|
||||||
REQUIRE(tbl["fruit"]["apple"].as<table>());
|
CHECK(tbl["g"].as_table());
|
||||||
REQUIRE(tbl["fruit"]["orange"].as<table>());
|
CHECK(tbl["g"]["h"].as_table());
|
||||||
|
CHECK(tbl["g"]["h"]["i"].as_table());
|
||||||
|
|
||||||
|
CHECK(tbl["j"].as_table());
|
||||||
|
CHECK(tbl["j"]["k"].as_table());
|
||||||
|
CHECK(tbl["j"]["k"]["l"].as_table());
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// "You don't need to specify all the super-tables if you don't want to. TOML knows how to do it for you."
|
||||||
parsing_should_succeed(
|
parsing_should_succeed(
|
||||||
FILE_LINE_ARGS,
|
FILE_LINE_ARGS,
|
||||||
R"(
|
R"(
|
||||||
# RECOMMENDED
|
# [x] you
|
||||||
[fruit.apple]
|
# [x.y] don't
|
||||||
[fruit.orange]
|
# [x.y.z] need these
|
||||||
[animal]
|
[x.y.z.w] # for this to work
|
||||||
)"sv,
|
|
||||||
|
[x] # defining a super-table afterwards is ok
|
||||||
|
)"sv,
|
||||||
[](table&& tbl)
|
[](table&& tbl)
|
||||||
{
|
{
|
||||||
REQUIRE(tbl["animal"].as<table>());
|
CHECK(tbl["x"].as_table());
|
||||||
CHECK(tbl["animal"].as<table>()->size() == 0u);
|
CHECK(tbl["x"]["y"].as_table());
|
||||||
|
CHECK(tbl["x"]["y"]["z"].as_table());
|
||||||
REQUIRE(tbl["fruit"].as<table>());
|
CHECK(tbl["x"]["y"]["z"]["w"].as_table());
|
||||||
CHECK(tbl["fruit"].as<table>()->size() == 2u);
|
|
||||||
|
|
||||||
REQUIRE(tbl["fruit"]["apple"].as<table>());
|
|
||||||
REQUIRE(tbl["fruit"]["orange"].as<table>());
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
parsing_should_fail(FILE_LINE_ARGS, R"([])"sv);
|
// "Like keys, you cannot define a table more than once. Doing so is invalid."
|
||||||
|
parsing_should_fail(FILE_LINE_ARGS, R"(
|
||||||
|
# DO NOT DO THIS
|
||||||
|
|
||||||
|
[fruit]
|
||||||
|
apple = "red"
|
||||||
|
|
||||||
|
[fruit]
|
||||||
|
orange = "orange"
|
||||||
|
)"sv);
|
||||||
|
parsing_should_fail(FILE_LINE_ARGS, R"(
|
||||||
|
# DO NOT DO THIS EITHER
|
||||||
|
|
||||||
|
[fruit]
|
||||||
|
apple = "red"
|
||||||
|
|
||||||
|
[fruit.apple]
|
||||||
|
texture = "smooth"
|
||||||
|
)"sv);
|
||||||
|
|
||||||
|
// "Defining tables out-of-order is discouraged."
|
||||||
|
parsing_should_succeed(
|
||||||
|
FILE_LINE_ARGS,
|
||||||
|
R"(
|
||||||
|
# VALID BUT DISCOURAGED
|
||||||
|
[fruit.apple]
|
||||||
|
[animal]
|
||||||
|
[fruit.orange]
|
||||||
|
)"sv,
|
||||||
|
[](table&& tbl)
|
||||||
|
{
|
||||||
|
CHECK(tbl["fruit"].as_table());
|
||||||
|
CHECK(tbl["fruit"]["apple"].as_table());
|
||||||
|
CHECK(tbl["animal"].as_table());
|
||||||
|
CHECK(tbl["fruit"]["orange"].as_table());
|
||||||
|
}
|
||||||
|
);
|
||||||
|
parsing_should_succeed(
|
||||||
|
FILE_LINE_ARGS,
|
||||||
|
R"(
|
||||||
|
# RECOMMENDED
|
||||||
|
[fruit.apple]
|
||||||
|
[fruit.orange]
|
||||||
|
[animal]
|
||||||
|
)"sv,
|
||||||
|
[](table&& tbl)
|
||||||
|
{
|
||||||
|
CHECK(tbl["fruit"].as_table());
|
||||||
|
CHECK(tbl["fruit"]["apple"].as_table());
|
||||||
|
CHECK(tbl["fruit"]["orange"].as_table());
|
||||||
|
CHECK(tbl["animal"].as_table());
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// "The top-level table, also called the root table, starts at the beginning of the document
|
||||||
|
// and ends just before the first table header (or EOF)."
|
||||||
|
parsing_should_succeed(
|
||||||
|
FILE_LINE_ARGS,
|
||||||
|
R"(
|
||||||
|
# Top-level table begins.
|
||||||
|
name = "Fido"
|
||||||
|
breed = "pug"
|
||||||
|
|
||||||
|
# Top-level table ends.
|
||||||
|
[owner]
|
||||||
|
name = "Regina Dogman"
|
||||||
|
member_since = 1999-08-04
|
||||||
|
)"sv,
|
||||||
|
[](table&& tbl)
|
||||||
|
{
|
||||||
|
CHECK(tbl["name"].as_string());
|
||||||
|
CHECK(*tbl["name"].as_string() == "Fido"sv);
|
||||||
|
CHECK(tbl["breed"].as_string());
|
||||||
|
CHECK(*tbl["breed"].as_string() == "pug"sv);
|
||||||
|
|
||||||
|
CHECK(tbl["owner"].as_table());
|
||||||
|
CHECK(*tbl["owner"]["name"].as_string() == "Regina Dogman"sv);
|
||||||
|
|
||||||
|
static constexpr auto member_since = toml::date{ 1999, 8, 4 };
|
||||||
|
CHECK(*tbl["owner"]["member_since"].as_date() == member_since);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// "Dotted keys create and define a table for each key part before the last one,
|
||||||
|
// provided that such tables were not previously created."
|
||||||
|
parsing_should_succeed(
|
||||||
|
FILE_LINE_ARGS,
|
||||||
|
R"(
|
||||||
|
fruit.apple.color = "red"
|
||||||
|
# Defines a table named fruit
|
||||||
|
# Defines a table named fruit.apple
|
||||||
|
|
||||||
|
fruit.apple.taste.sweet = true
|
||||||
|
# Defines a table named fruit.apple.taste
|
||||||
|
# fruit and fruit.apple were already created
|
||||||
|
)"sv,
|
||||||
|
[](table&& tbl)
|
||||||
|
{
|
||||||
|
CHECK(tbl["fruit"].as_table());
|
||||||
|
CHECK(tbl["fruit"]["apple"].as_table());
|
||||||
|
CHECK(tbl["fruit"]["apple"]["color"].as_string());
|
||||||
|
CHECK(*tbl["fruit"]["apple"]["color"].as_string() == "red"sv);
|
||||||
|
|
||||||
|
CHECK(tbl["fruit"]["apple"]["taste"].as_table());
|
||||||
|
CHECK(tbl["fruit"]["apple"]["taste"]["sweet"].as_boolean());
|
||||||
|
CHECK(*tbl["fruit"]["apple"]["taste"]["sweet"].as_boolean() == true);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// "Since tables cannot be defined more than once, redefining such tables using a [table] header is not allowed."
|
||||||
|
parsing_should_fail(FILE_LINE_ARGS, R"(
|
||||||
|
[fruit]
|
||||||
|
apple.color = "red"
|
||||||
|
apple.taste.sweet = true
|
||||||
|
|
||||||
|
[fruit.apple] # INVALID
|
||||||
|
)"sv);
|
||||||
|
parsing_should_fail(FILE_LINE_ARGS, R"(
|
||||||
|
[fruit]
|
||||||
|
apple.color = "red"
|
||||||
|
apple.taste.sweet = true
|
||||||
|
|
||||||
|
[fruit.apple.taste] # INVALID
|
||||||
|
)"sv);
|
||||||
|
|
||||||
|
// "Likewise, using dotted keys to redefine tables already defined in [table] form is not allowed."
|
||||||
|
parsing_should_fail(FILE_LINE_ARGS, R"(
|
||||||
|
[fruit.apple.taste]
|
||||||
|
sweet = true
|
||||||
|
|
||||||
|
[fruit]
|
||||||
|
apple.taste = { sweet = false } # INVALID
|
||||||
|
)"sv);
|
||||||
|
parsing_should_fail(FILE_LINE_ARGS, R"(
|
||||||
|
[fruit.apple.taste]
|
||||||
|
sweet = true
|
||||||
|
|
||||||
|
[fruit]
|
||||||
|
apple.taste.foo = "bar" # INVALID
|
||||||
|
)"sv);
|
||||||
|
|
||||||
|
// "The [table] form can, however, be used to define sub-tables within tables defined via dotted keys."
|
||||||
|
parsing_should_succeed(
|
||||||
|
FILE_LINE_ARGS,
|
||||||
|
R"(
|
||||||
|
[fruit]
|
||||||
|
apple.color = "red"
|
||||||
|
apple.taste.sweet = true
|
||||||
|
|
||||||
|
[fruit.apple.texture] # you can add sub-tables
|
||||||
|
smooth = true
|
||||||
|
)"sv,
|
||||||
|
[](table&& tbl)
|
||||||
|
{
|
||||||
|
CHECK(tbl["fruit"].as_table());
|
||||||
|
CHECK(tbl["fruit"]["apple"].as_table());
|
||||||
|
CHECK(tbl["fruit"]["apple"]["color"].as_string());
|
||||||
|
CHECK(*tbl["fruit"]["apple"]["color"].as_string() == "red"sv);
|
||||||
|
|
||||||
|
CHECK(tbl["fruit"]["apple"]["texture"].as_table());
|
||||||
|
CHECK(tbl["fruit"]["apple"]["texture"]["smooth"].as_boolean());
|
||||||
|
CHECK(*tbl["fruit"]["apple"]["texture"]["smooth"].as_boolean() == true);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
parsing_should_fail(FILE_LINE_ARGS, R"(
|
||||||
|
[fruit]
|
||||||
|
apple.color = "red"
|
||||||
|
apple.taste.sweet = true
|
||||||
|
|
||||||
|
[fruit.apple]
|
||||||
|
shape = "round"
|
||||||
|
|
||||||
|
[fruit.apple.texture]
|
||||||
|
smooth = true
|
||||||
|
)"sv);
|
||||||
|
|
||||||
|
// same as above but the table order is reversed.
|
||||||
|
// see: https://github.com/toml-lang/toml/issues/769
|
||||||
|
parsing_should_succeed(
|
||||||
|
FILE_LINE_ARGS,
|
||||||
|
R"(
|
||||||
|
[fruit.apple.texture]
|
||||||
|
smooth = true
|
||||||
|
|
||||||
|
[fruit]
|
||||||
|
apple.color = "red"
|
||||||
|
apple.taste.sweet = true
|
||||||
|
)"sv,
|
||||||
|
[](table&& tbl)
|
||||||
|
{
|
||||||
|
CHECK(tbl["fruit"].as_table());
|
||||||
|
CHECK(tbl["fruit"]["apple"].as_table());
|
||||||
|
CHECK(tbl["fruit"]["apple"]["color"].as_string());
|
||||||
|
CHECK(*tbl["fruit"]["apple"]["color"].as_string() == "red"sv);
|
||||||
|
|
||||||
|
CHECK(tbl["fruit"]["apple"]["texture"].as_table());
|
||||||
|
CHECK(tbl["fruit"]["apple"]["texture"]["smooth"].as_boolean());
|
||||||
|
CHECK(*tbl["fruit"]["apple"]["texture"]["smooth"].as_boolean() == true);
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("parsing - inline tables")
|
TEST_CASE("parsing - inline tables")
|
||||||
{
|
{
|
||||||
|
// these are the examples from https://toml.io/en/v1.0.0#inline-table
|
||||||
|
|
||||||
parsing_should_succeed(
|
parsing_should_succeed(
|
||||||
FILE_LINE_ARGS,
|
FILE_LINE_ARGS,
|
||||||
R"(
|
R"(
|
||||||
name = { first = "Tom", last = "Preston-Werner" }
|
name = { first = "Tom", last = "Preston-Werner" }
|
||||||
point = { x = 1, y = 2 }
|
point = { x = 1, y = 2 }
|
||||||
animal = { type.name = "pug" }
|
animal = { type.name = "pug" }
|
||||||
|
)"sv,
|
||||||
[product]
|
|
||||||
type = { name = "Nail" }
|
|
||||||
)"sv,
|
|
||||||
[](table&& tbl)
|
[](table&& tbl)
|
||||||
{
|
{
|
||||||
REQUIRE(tbl["name"].as<table>());
|
REQUIRE(tbl["name"].as_table());
|
||||||
CHECK(tbl["name"].as<table>()->size() == 2u);
|
CHECK(tbl["name"].as_table()->size() == 2u);
|
||||||
|
CHECK(tbl["name"].as_table()->is_inline());
|
||||||
CHECK(tbl["name"]["first"] == "Tom"sv);
|
CHECK(tbl["name"]["first"] == "Tom"sv);
|
||||||
CHECK(tbl["name"]["last"] == "Preston-Werner"sv);
|
CHECK(tbl["name"]["last"] == "Preston-Werner"sv);
|
||||||
|
|
||||||
REQUIRE(tbl["point"].as<table>());
|
REQUIRE(tbl["point"].as_table());
|
||||||
CHECK(tbl["point"].as<table>()->size() == 2u);
|
CHECK(tbl["point"].as_table()->size() == 2u);
|
||||||
|
CHECK(tbl["point"].as_table()->is_inline());
|
||||||
CHECK(tbl["point"]["x"] == 1);
|
CHECK(tbl["point"]["x"] == 1);
|
||||||
CHECK(tbl["point"]["y"] == 2);
|
CHECK(tbl["point"]["y"] == 2);
|
||||||
|
|
||||||
REQUIRE(tbl["animal"].as<table>());
|
REQUIRE(tbl["animal"].as_table());
|
||||||
CHECK(tbl["animal"].as<table>()->size() == 1u);
|
CHECK(tbl["animal"].as_table()->size() == 1u);
|
||||||
REQUIRE(tbl["animal"]["type"].as<table>());
|
CHECK(tbl["animal"].as_table()->is_inline());
|
||||||
CHECK(tbl["animal"]["type"].as<table>()->size() == 1u);
|
REQUIRE(tbl["animal"]["type"].as_table());
|
||||||
|
CHECK(tbl["animal"]["type"].as_table()->size() == 1u);
|
||||||
CHECK(tbl["animal"]["type"]["name"] == "pug"sv);
|
CHECK(tbl["animal"]["type"]["name"] == "pug"sv);
|
||||||
|
|
||||||
REQUIRE(tbl["product"].as<table>());
|
|
||||||
CHECK(tbl["product"].as<table>()->size() == 1u);
|
|
||||||
REQUIRE(tbl["product"]["type"].as<table>());
|
|
||||||
CHECK(tbl["product"]["type"].as<table>()->size() == 1u);
|
|
||||||
CHECK(tbl["product"]["type"]["name"] == "Nail"sv);
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// "Inline tables are fully self-contained and define all keys and sub-tables within them.
|
||||||
|
// Keys and sub-tables cannot be added outside the braces."
|
||||||
parsing_should_fail(FILE_LINE_ARGS, R"(
|
parsing_should_fail(FILE_LINE_ARGS, R"(
|
||||||
[product]
|
[product]
|
||||||
type = { name = "Nail" }
|
type = { name = "Nail" }
|
||||||
type.edible = false # INVALID
|
type.edible = false # INVALID
|
||||||
)"sv);
|
)"sv);
|
||||||
|
|
||||||
|
// "Similarly, inline tables cannot be used to add keys or sub-tables to an already-defined table."
|
||||||
parsing_should_fail(FILE_LINE_ARGS, R"(
|
parsing_should_fail(FILE_LINE_ARGS, R"(
|
||||||
[product]
|
[product]
|
||||||
type.name = "Nail"
|
type.name = "Nail"
|
||||||
type = { edible = false } # INVALID
|
type = { edible = false } # INVALID
|
||||||
)"sv);
|
)"sv);
|
||||||
|
|
||||||
// "newlines are allowed between the curly braces [if] they are valid within a value."
|
// "newlines are allowed between the curly braces [if] they are valid within a value."
|
||||||
parsing_should_succeed(
|
parsing_should_succeed(
|
||||||
@ -232,8 +377,8 @@ test = { val1 = "foo", val2 = [
|
|||||||
)"sv,
|
)"sv,
|
||||||
[](table&& tbl)
|
[](table&& tbl)
|
||||||
{
|
{
|
||||||
REQUIRE(tbl["test"].as<table>());
|
REQUIRE(tbl["test"].as_table());
|
||||||
CHECK(tbl["test"].as<table>()->size() == 3u);
|
CHECK(tbl["test"].as_table()->size() == 3u);
|
||||||
CHECK(tbl["test"]["val1"] == "foo"sv);
|
CHECK(tbl["test"]["val1"] == "foo"sv);
|
||||||
REQUIRE(tbl["test"]["val2"].as<array>());
|
REQUIRE(tbl["test"]["val2"].as<array>());
|
||||||
CHECK(tbl["test"]["val2"].as<array>()->size() == 3u);
|
CHECK(tbl["test"]["val2"].as<array>()->size() == 3u);
|
||||||
@ -257,8 +402,8 @@ name = {
|
|||||||
)"sv,
|
)"sv,
|
||||||
[](table&& tbl)
|
[](table&& tbl)
|
||||||
{
|
{
|
||||||
REQUIRE(tbl["name"].as<table>());
|
REQUIRE(tbl["name"].as_table());
|
||||||
CHECK(tbl["name"].as<table>()->size() == 2u);
|
CHECK(tbl["name"].as_table()->size() == 2u);
|
||||||
CHECK(tbl["name"]["first"] == "Tom"sv);
|
CHECK(tbl["name"]["first"] == "Tom"sv);
|
||||||
CHECK(tbl["name"]["last"] == "Preston-Werner"sv);
|
CHECK(tbl["name"]["last"] == "Preston-Werner"sv);
|
||||||
}
|
}
|
||||||
@ -345,16 +490,16 @@ color = "gray"
|
|||||||
CHECK(tbl["products"].as<array>()->is_homogeneous());
|
CHECK(tbl["products"].as<array>()->is_homogeneous());
|
||||||
CHECK(tbl["products"].as<array>()->is_array_of_tables());
|
CHECK(tbl["products"].as<array>()->is_array_of_tables());
|
||||||
|
|
||||||
REQUIRE(tbl["products"][0].as<table>());
|
REQUIRE(tbl["products"][0].as_table());
|
||||||
CHECK(tbl["products"][0].as<table>()->size() == 2u);
|
CHECK(tbl["products"][0].as_table()->size() == 2u);
|
||||||
CHECK(tbl["products"][0]["name"] == "Hammer"sv);
|
CHECK(tbl["products"][0]["name"] == "Hammer"sv);
|
||||||
CHECK(tbl["products"][0]["sku"] == 738594937);
|
CHECK(tbl["products"][0]["sku"] == 738594937);
|
||||||
|
|
||||||
REQUIRE(tbl["products"][1].as<table>());
|
REQUIRE(tbl["products"][1].as_table());
|
||||||
CHECK(tbl["products"][1].as<table>()->size() == 0u);
|
CHECK(tbl["products"][1].as_table()->size() == 0u);
|
||||||
|
|
||||||
REQUIRE(tbl["products"][2].as<table>());
|
REQUIRE(tbl["products"][2].as_table());
|
||||||
CHECK(tbl["products"][2].as<table>()->size() == 3u);
|
CHECK(tbl["products"][2].as_table()->size() == 3u);
|
||||||
CHECK(tbl["products"][2]["name"] == "Nail"sv);
|
CHECK(tbl["products"][2]["name"] == "Nail"sv);
|
||||||
CHECK(tbl["products"][2]["sku"] == 284758393);
|
CHECK(tbl["products"][2]["sku"] == 284758393);
|
||||||
CHECK(tbl["products"][2]["color"] == "gray"sv);
|
CHECK(tbl["products"][2]["color"] == "gray"sv);
|
||||||
@ -365,12 +510,12 @@ color = "gray"
|
|||||||
CHECK(tbl["fruit"].as<array>()->is_homogeneous());
|
CHECK(tbl["fruit"].as<array>()->is_homogeneous());
|
||||||
CHECK(tbl["fruit"].as<array>()->is_array_of_tables());
|
CHECK(tbl["fruit"].as<array>()->is_array_of_tables());
|
||||||
|
|
||||||
REQUIRE(tbl["fruit"][0].as<table>());
|
REQUIRE(tbl["fruit"][0].as_table());
|
||||||
CHECK(tbl["fruit"][0].as<table>()->size() == 3u);
|
CHECK(tbl["fruit"][0].as_table()->size() == 3u);
|
||||||
CHECK(tbl["fruit"][0]["name"] == "apple"sv);
|
CHECK(tbl["fruit"][0]["name"] == "apple"sv);
|
||||||
|
|
||||||
REQUIRE(tbl["fruit"][0]["physical"].as<table>());
|
REQUIRE(tbl["fruit"][0]["physical"].as_table());
|
||||||
CHECK(tbl["fruit"][0]["physical"].as<table>()->size() == 2u);
|
CHECK(tbl["fruit"][0]["physical"].as_table()->size() == 2u);
|
||||||
CHECK(tbl["fruit"][0]["physical"]["color"] == "red"sv);
|
CHECK(tbl["fruit"][0]["physical"]["color"] == "red"sv);
|
||||||
CHECK(tbl["fruit"][0]["physical"]["shape"] == "round"sv);
|
CHECK(tbl["fruit"][0]["physical"]["shape"] == "round"sv);
|
||||||
|
|
||||||
@ -381,8 +526,8 @@ color = "gray"
|
|||||||
CHECK(tbl["fruit"][0]["variety"][0]["name"] == "red delicious"sv);
|
CHECK(tbl["fruit"][0]["variety"][0]["name"] == "red delicious"sv);
|
||||||
CHECK(tbl["fruit"][0]["variety"][1]["name"] == "granny smith"sv);
|
CHECK(tbl["fruit"][0]["variety"][1]["name"] == "granny smith"sv);
|
||||||
|
|
||||||
REQUIRE(tbl["fruit"][1].as<table>());
|
REQUIRE(tbl["fruit"][1].as_table());
|
||||||
CHECK(tbl["fruit"][1].as<table>()->size() == 2u);
|
CHECK(tbl["fruit"][1].as_table()->size() == 2u);
|
||||||
CHECK(tbl["fruit"][1]["name"] == "banana"sv);
|
CHECK(tbl["fruit"][1]["name"] == "banana"sv);
|
||||||
|
|
||||||
REQUIRE(tbl["fruit"][1]["variety"].as<array>());
|
REQUIRE(tbl["fruit"][1]["variety"].as<array>());
|
||||||
@ -437,5 +582,4 @@ fruit = []
|
|||||||
[[fruit.physical]]
|
[[fruit.physical]]
|
||||||
color = "green"
|
color = "green"
|
||||||
)"sv);
|
)"sv);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
62
toml.hpp
62
toml.hpp
@ -1,6 +1,6 @@
|
|||||||
//----------------------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// toml++ v2.3.0
|
// toml++ v2.3.1
|
||||||
// https://github.com/marzer/tomlplusplus
|
// https://github.com/marzer/tomlplusplus
|
||||||
// SPDX-License-Identifier: MIT
|
// SPDX-License-Identifier: MIT
|
||||||
//
|
//
|
||||||
@ -108,7 +108,7 @@
|
|||||||
#if defined(_MSC_VER) // msvc compat mode
|
#if defined(_MSC_VER) // msvc compat mode
|
||||||
#ifdef __has_declspec_attribute
|
#ifdef __has_declspec_attribute
|
||||||
#if __has_declspec_attribute(novtable)
|
#if __has_declspec_attribute(novtable)
|
||||||
#define TOML_INTERFACE __declspec(novtable)
|
#define TOML_ABSTRACT_BASE __declspec(novtable)
|
||||||
#endif
|
#endif
|
||||||
#if __has_declspec_attribute(empty_bases)
|
#if __has_declspec_attribute(empty_bases)
|
||||||
#define TOML_EMPTY_BASES __declspec(empty_bases)
|
#define TOML_EMPTY_BASES __declspec(empty_bases)
|
||||||
@ -156,7 +156,7 @@
|
|||||||
#define TOML_NEVER_INLINE __declspec(noinline)
|
#define TOML_NEVER_INLINE __declspec(noinline)
|
||||||
#define TOML_ASSUME(cond) __assume(cond)
|
#define TOML_ASSUME(cond) __assume(cond)
|
||||||
#define TOML_UNREACHABLE __assume(0)
|
#define TOML_UNREACHABLE __assume(0)
|
||||||
#define TOML_INTERFACE __declspec(novtable)
|
#define TOML_ABSTRACT_BASE __declspec(novtable)
|
||||||
#define TOML_EMPTY_BASES __declspec(empty_bases)
|
#define TOML_EMPTY_BASES __declspec(empty_bases)
|
||||||
|
|
||||||
#endif // msvc
|
#endif // msvc
|
||||||
@ -389,8 +389,8 @@ is no longer necessary.
|
|||||||
#define TOML_ATTR(...)
|
#define TOML_ATTR(...)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef TOML_INTERFACE
|
#ifndef TOML_ABSTRACT_BASE
|
||||||
#define TOML_INTERFACE
|
#define TOML_ABSTRACT_BASE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef TOML_EMPTY_BASES
|
#ifndef TOML_EMPTY_BASES
|
||||||
@ -527,7 +527,7 @@ is no longer necessary.
|
|||||||
|
|
||||||
#define TOML_LIB_MAJOR 2
|
#define TOML_LIB_MAJOR 2
|
||||||
#define TOML_LIB_MINOR 3
|
#define TOML_LIB_MINOR 3
|
||||||
#define TOML_LIB_PATCH 0
|
#define TOML_LIB_PATCH 1
|
||||||
|
|
||||||
#define TOML_LANG_MAJOR 1
|
#define TOML_LANG_MAJOR 1
|
||||||
#define TOML_LANG_MINOR 0
|
#define TOML_LANG_MINOR 0
|
||||||
@ -2175,7 +2175,7 @@ TOML_POP_WARNINGS // TOML_DISABLE_SWITCH_WARNINGS
|
|||||||
|
|
||||||
TOML_NAMESPACE_START
|
TOML_NAMESPACE_START
|
||||||
{
|
{
|
||||||
class TOML_INTERFACE TOML_API node
|
class TOML_ABSTRACT_BASE TOML_API node
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
friend class TOML_PARSER_TYPENAME;
|
friend class TOML_PARSER_TYPENAME;
|
||||||
@ -2192,6 +2192,7 @@ TOML_NAMESPACE_START
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
TOML_ALWAYS_INLINE
|
TOML_ALWAYS_INLINE
|
||||||
|
TOML_ATTR(pure)
|
||||||
impl::wrap_node<T>& ref_cast() & noexcept
|
impl::wrap_node<T>& ref_cast() & noexcept
|
||||||
{
|
{
|
||||||
return *reinterpret_cast<impl::wrap_node<T>*>(this);
|
return *reinterpret_cast<impl::wrap_node<T>*>(this);
|
||||||
@ -2200,6 +2201,7 @@ TOML_NAMESPACE_START
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
TOML_ALWAYS_INLINE
|
TOML_ALWAYS_INLINE
|
||||||
|
TOML_ATTR(pure)
|
||||||
impl::wrap_node<T>&& ref_cast() && noexcept
|
impl::wrap_node<T>&& ref_cast() && noexcept
|
||||||
{
|
{
|
||||||
return std::move(*reinterpret_cast<impl::wrap_node<T>*>(this));
|
return std::move(*reinterpret_cast<impl::wrap_node<T>*>(this));
|
||||||
@ -2208,6 +2210,7 @@ TOML_NAMESPACE_START
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
TOML_ALWAYS_INLINE
|
TOML_ALWAYS_INLINE
|
||||||
|
TOML_ATTR(pure)
|
||||||
const impl::wrap_node<T>& ref_cast() const & noexcept
|
const impl::wrap_node<T>& ref_cast() const & noexcept
|
||||||
{
|
{
|
||||||
return *reinterpret_cast<const impl::wrap_node<T>*>(this);
|
return *reinterpret_cast<const impl::wrap_node<T>*>(this);
|
||||||
@ -2220,7 +2223,23 @@ TOML_NAMESPACE_START
|
|||||||
|
|
||||||
virtual ~node() noexcept = default;
|
virtual ~node() noexcept = default;
|
||||||
|
|
||||||
|
#if defined(DOXYGEN) || !TOML_ICC || TOML_ICC_CL
|
||||||
|
|
||||||
[[nodiscard]] virtual node_type type() const noexcept = 0;
|
[[nodiscard]] virtual node_type type() const noexcept = 0;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
[[nodiscard]] virtual node_type type() const noexcept
|
||||||
|
{
|
||||||
|
// Q: "what the fuck?"
|
||||||
|
// A: https://github.com/marzer/tomlplusplus/issues/83
|
||||||
|
// tl,dr: go home ICC, you're drunk.
|
||||||
|
|
||||||
|
return type();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
[[nodiscard]] virtual bool is_table() const noexcept = 0;
|
[[nodiscard]] virtual bool is_table() const noexcept = 0;
|
||||||
[[nodiscard]] virtual bool is_array() const noexcept = 0;
|
[[nodiscard]] virtual bool is_array() const noexcept = 0;
|
||||||
[[nodiscard]] virtual bool is_value() const noexcept = 0;
|
[[nodiscard]] virtual bool is_value() const noexcept = 0;
|
||||||
@ -2236,6 +2255,7 @@ TOML_NAMESPACE_START
|
|||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
|
TOML_ATTR(pure)
|
||||||
bool is() const noexcept
|
bool is() const noexcept
|
||||||
{
|
{
|
||||||
using type = impl::unwrap_node<T>;
|
using type = impl::unwrap_node<T>;
|
||||||
@ -2280,6 +2300,7 @@ TOML_NAMESPACE_START
|
|||||||
|
|
||||||
template <typename ElemType = void>
|
template <typename ElemType = void>
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
|
TOML_ATTR(pure)
|
||||||
bool is_homogeneous() const noexcept
|
bool is_homogeneous() const noexcept
|
||||||
{
|
{
|
||||||
using type = impl::unwrap_node<ElemType>;
|
using type = impl::unwrap_node<ElemType>;
|
||||||
@ -2326,6 +2347,7 @@ TOML_NAMESPACE_START
|
|||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
|
TOML_ATTR(pure)
|
||||||
impl::wrap_node<T>* as() noexcept
|
impl::wrap_node<T>* as() noexcept
|
||||||
{
|
{
|
||||||
using type = impl::unwrap_node<T>;
|
using type = impl::unwrap_node<T>;
|
||||||
@ -2348,6 +2370,7 @@ TOML_NAMESPACE_START
|
|||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
|
TOML_ATTR(pure)
|
||||||
const impl::wrap_node<T>* as() const noexcept
|
const impl::wrap_node<T>* as() const noexcept
|
||||||
{
|
{
|
||||||
using type = impl::unwrap_node<T>;
|
using type = impl::unwrap_node<T>;
|
||||||
@ -2520,6 +2543,7 @@ TOML_NAMESPACE_START
|
|||||||
|
|
||||||
template <typename T, typename N>
|
template <typename T, typename N>
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
|
TOML_ATTR(pure)
|
||||||
static decltype(auto) do_ref(N&& n) noexcept
|
static decltype(auto) do_ref(N&& n) noexcept
|
||||||
{
|
{
|
||||||
using type = impl::unwrap_node<T>;
|
using type = impl::unwrap_node<T>;
|
||||||
@ -2563,6 +2587,7 @@ TOML_NAMESPACE_START
|
|||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
|
TOML_ATTR(pure)
|
||||||
impl::unwrap_node<T>& ref() & noexcept
|
impl::unwrap_node<T>& ref() & noexcept
|
||||||
{
|
{
|
||||||
return do_ref<T>(*this);
|
return do_ref<T>(*this);
|
||||||
@ -2570,6 +2595,7 @@ TOML_NAMESPACE_START
|
|||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
|
TOML_ATTR(pure)
|
||||||
impl::unwrap_node<T>&& ref() && noexcept
|
impl::unwrap_node<T>&& ref() && noexcept
|
||||||
{
|
{
|
||||||
return do_ref<T>(std::move(*this));
|
return do_ref<T>(std::move(*this));
|
||||||
@ -2577,6 +2603,7 @@ TOML_NAMESPACE_START
|
|||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
|
TOML_ATTR(pure)
|
||||||
const impl::unwrap_node<T>& ref() const& noexcept
|
const impl::unwrap_node<T>& ref() const& noexcept
|
||||||
{
|
{
|
||||||
return do_ref<T>(*this);
|
return do_ref<T>(*this);
|
||||||
@ -3430,6 +3457,7 @@ TOML_IMPL_NAMESPACE_START
|
|||||||
|
|
||||||
mutable raw_iterator raw_;
|
mutable raw_iterator raw_;
|
||||||
|
|
||||||
|
TOML_NODISCARD_CTOR
|
||||||
array_iterator(raw_mutable_iterator raw) noexcept
|
array_iterator(raw_mutable_iterator raw) noexcept
|
||||||
: raw_{ raw }
|
: raw_{ raw }
|
||||||
{}
|
{}
|
||||||
@ -3448,8 +3476,12 @@ TOML_IMPL_NAMESPACE_START
|
|||||||
using difference_type = ptrdiff_t;
|
using difference_type = ptrdiff_t;
|
||||||
using iterator_category = typename std::iterator_traits<raw_iterator>::iterator_category;
|
using iterator_category = typename std::iterator_traits<raw_iterator>::iterator_category;
|
||||||
|
|
||||||
|
TOML_NODISCARD_CTOR
|
||||||
array_iterator() noexcept = default;
|
array_iterator() noexcept = default;
|
||||||
|
|
||||||
|
TOML_NODISCARD_CTOR
|
||||||
array_iterator(const array_iterator&) noexcept = default;
|
array_iterator(const array_iterator&) noexcept = default;
|
||||||
|
|
||||||
array_iterator& operator = (const array_iterator&) noexcept = default;
|
array_iterator& operator = (const array_iterator&) noexcept = default;
|
||||||
|
|
||||||
array_iterator& operator++() noexcept // ++pre
|
array_iterator& operator++() noexcept // ++pre
|
||||||
@ -3738,6 +3770,7 @@ TOML_NAMESPACE_START
|
|||||||
[[nodiscard]] bool is_homogeneous(node_type ntype) const noexcept override;
|
[[nodiscard]] bool is_homogeneous(node_type ntype) const noexcept override;
|
||||||
[[nodiscard]] bool is_homogeneous(node_type ntype, node*& first_nonmatch) noexcept override;
|
[[nodiscard]] bool is_homogeneous(node_type ntype, node*& first_nonmatch) noexcept override;
|
||||||
[[nodiscard]] bool is_homogeneous(node_type ntype, const node*& first_nonmatch) const noexcept override;
|
[[nodiscard]] bool is_homogeneous(node_type ntype, const node*& first_nonmatch) const noexcept override;
|
||||||
|
|
||||||
template <typename ElemType = void>
|
template <typename ElemType = void>
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
bool is_homogeneous() const noexcept
|
bool is_homogeneous() const noexcept
|
||||||
@ -4039,6 +4072,7 @@ TOML_IMPL_NAMESPACE_START
|
|||||||
return TOML_LAUNDER(reinterpret_cast<proxy_type*>(&proxy));
|
return TOML_LAUNDER(reinterpret_cast<proxy_type*>(&proxy));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TOML_NODISCARD_CTOR
|
||||||
table_iterator(raw_mutable_iterator raw) noexcept
|
table_iterator(raw_mutable_iterator raw) noexcept
|
||||||
: raw_{ raw }
|
: raw_{ raw }
|
||||||
{}
|
{}
|
||||||
@ -4051,8 +4085,10 @@ TOML_IMPL_NAMESPACE_START
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
TOML_NODISCARD_CTOR
|
||||||
table_iterator() noexcept = default;
|
table_iterator() noexcept = default;
|
||||||
|
|
||||||
|
TOML_NODISCARD_CTOR
|
||||||
table_iterator(const table_iterator& other) noexcept
|
table_iterator(const table_iterator& other) noexcept
|
||||||
: raw_{ other.raw_ }
|
: raw_{ other.raw_ }
|
||||||
{}
|
{}
|
||||||
@ -6929,7 +6965,7 @@ TOML_IMPL_NAMESPACE_START
|
|||||||
#define TOML_ERROR err.emplace
|
#define TOML_ERROR err.emplace
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct TOML_INTERFACE utf8_reader_interface
|
struct TOML_ABSTRACT_BASE utf8_reader_interface
|
||||||
{
|
{
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
virtual const source_path_ptr& source_path() const noexcept = 0;
|
virtual const source_path_ptr& source_path() const noexcept = 0;
|
||||||
@ -11408,6 +11444,9 @@ TOML_IMPL_NAMESPACE_START
|
|||||||
return_if_error();
|
return_if_error();
|
||||||
|
|
||||||
TOML_ASSERT(kvp.key.segments.size() >= 1_sz);
|
TOML_ASSERT(kvp.key.segments.size() >= 1_sz);
|
||||||
|
|
||||||
|
// if it's a dotted kvp we need to spawn the sub-tables if necessary,
|
||||||
|
// and set the target table to the second-to-last one in the chain
|
||||||
if (kvp.key.segments.size() > 1_sz)
|
if (kvp.key.segments.size() > 1_sz)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < kvp.key.segments.size() - 1_sz; i++)
|
for (size_t i = 0; i < kvp.key.segments.size() - 1_sz; i++)
|
||||||
@ -11420,13 +11459,14 @@ TOML_IMPL_NAMESPACE_START
|
|||||||
new toml::table{}
|
new toml::table{}
|
||||||
).first->second.get();
|
).first->second.get();
|
||||||
dotted_key_tables.push_back(&child->ref_cast<table>());
|
dotted_key_tables.push_back(&child->ref_cast<table>());
|
||||||
dotted_key_tables.back()->inline_ = true;
|
|
||||||
child->source_ = kvp.value.get()->source_;
|
child->source_ = kvp.value.get()->source_;
|
||||||
}
|
}
|
||||||
else if (!child->is_table() || !find(dotted_key_tables, &child->ref_cast<table>()))
|
else if (!child->is_table()
|
||||||
|
|| !(find(dotted_key_tables, &child->ref_cast<table>()) || find(implicit_tables, &child->ref_cast<table>())))
|
||||||
set_error("cannot redefine existing "sv, to_sv(child->type()), " as dotted key-value pair"sv);
|
set_error("cannot redefine existing "sv, to_sv(child->type()), " as dotted key-value pair"sv);
|
||||||
else
|
else
|
||||||
child->source_.end = kvp.value.get()->source_.end;
|
child->source_.end = kvp.value.get()->source_.end;
|
||||||
|
|
||||||
return_if_error();
|
return_if_error();
|
||||||
tab = &child->ref_cast<table>();
|
tab = &child->ref_cast<table>();
|
||||||
}
|
}
|
||||||
@ -12021,6 +12061,7 @@ TOML_POP_WARNINGS // TOML_DISABLE_SPAM_WARNINGS
|
|||||||
#undef TOML_ABI_NAMESPACE_BOOL
|
#undef TOML_ABI_NAMESPACE_BOOL
|
||||||
#undef TOML_ABI_NAMESPACE_END
|
#undef TOML_ABI_NAMESPACE_END
|
||||||
#undef TOML_ABI_NAMESPACE_START
|
#undef TOML_ABI_NAMESPACE_START
|
||||||
|
#undef TOML_ABSTRACT_BASE
|
||||||
#undef TOML_ALWAYS_INLINE
|
#undef TOML_ALWAYS_INLINE
|
||||||
#undef TOML_ANON_NAMESPACE
|
#undef TOML_ANON_NAMESPACE
|
||||||
#undef TOML_ANON_NAMESPACE_END
|
#undef TOML_ANON_NAMESPACE_END
|
||||||
@ -12063,7 +12104,6 @@ TOML_POP_WARNINGS // TOML_DISABLE_SPAM_WARNINGS
|
|||||||
#undef TOML_IMPL_NAMESPACE_START
|
#undef TOML_IMPL_NAMESPACE_START
|
||||||
#undef TOML_INT128
|
#undef TOML_INT128
|
||||||
#undef TOML_INTELLISENSE
|
#undef TOML_INTELLISENSE
|
||||||
#undef TOML_INTERFACE
|
|
||||||
#undef TOML_INTERNAL_LINKAGE
|
#undef TOML_INTERNAL_LINKAGE
|
||||||
#undef TOML_INT_CHARCONV
|
#undef TOML_INT_CHARCONV
|
||||||
#undef TOML_LANG_AT_LEAST
|
#undef TOML_LANG_AT_LEAST
|
||||||
|
Loading…
Reference in New Issue
Block a user