mirror of
https://github.com/marzer/tomlplusplus.git
synced 2024-09-15 15:13:21 +00:00
moved is_homogenous to toml::node
also: - added is_homogenous overload for identifying failure-causing element (to assist with implementing #45) - added table::is_homogenous - added value::is_homogenous (just for generic code's sake)
This commit is contained in:
parent
b024ee6dc2
commit
f6450f6ff9
@ -123,6 +123,11 @@
|
||||
#undef TOML_SA_NEWLINE
|
||||
#undef TOML_SA_NODE_TYPE_LIST
|
||||
#undef TOML_SA_UNWRAPPED_NODE_TYPE_LIST
|
||||
#undef TOML_SA_VALUE_EXACT_FUNC_MESSAGE
|
||||
#undef TOML_SA_VALUE_FUNC_MESSAGE
|
||||
#undef TOML_SA_VALUE_MESSAGE_CONST_CHAR8
|
||||
#undef TOML_SA_VALUE_MESSAGE_U8STRING_VIEW
|
||||
#undef TOML_SA_VALUE_MESSAGE_WSTRING
|
||||
#undef TOML_SIMPLE_STATIC_ASSERT_MESSAGES
|
||||
#undef TOML_TRIVIAL_ABI
|
||||
#undef TOML_UINT128
|
||||
|
@ -403,69 +403,17 @@ TOML_NAMESPACE_START
|
||||
}
|
||||
|
||||
|
||||
/// \brief Always returns node_type::array for array nodes.
|
||||
[[nodiscard]] node_type type() const noexcept override;
|
||||
/// \brief Always returns `false` for array nodes.
|
||||
[[nodiscard]] bool is_table() const noexcept override;
|
||||
/// \brief Always returns `true` for array nodes.
|
||||
[[nodiscard]] bool is_array() const noexcept override;
|
||||
/// \brief Always returns `false` for array nodes.
|
||||
[[nodiscard]] bool is_value() const noexcept override;
|
||||
[[nodiscard]] array* as_array() noexcept override;
|
||||
[[nodiscard]] const array* as_array() const noexcept override;
|
||||
[[nodiscard]] bool is_array_of_tables() const noexcept override;
|
||||
|
||||
/// \brief Checks if the array contains elements of only one type.
|
||||
///
|
||||
/// \detail \cpp
|
||||
/// auto arr = toml::array{ 1, 2, 3 };
|
||||
/// std::cout << "homogenous: "sv << arr.is_homogeneous(toml::node_type::none) << "\n";
|
||||
/// std::cout << "all floats: "sv << arr.is_homogeneous(toml::node_type::floating_point) << "\n";
|
||||
/// std::cout << "all arrays: "sv << arr.is_homogeneous(toml::node_type::array) << "\n";
|
||||
/// std::cout << "all ints: "sv << arr.is_homogeneous(toml::node_type::integer) << "\n";
|
||||
///
|
||||
/// \ecpp
|
||||
///
|
||||
/// \out
|
||||
/// homogeneous: true
|
||||
/// all floats: false
|
||||
/// all arrays: false
|
||||
/// all ints: true
|
||||
/// \eout
|
||||
///
|
||||
/// \param type A TOML node type. <br>
|
||||
/// <strong><em>toml::node_type::none: </em></strong> "is every node the same type?" <br>
|
||||
/// <strong><em>Anything else:</em></strong> "is every node one of these?"
|
||||
///
|
||||
/// \returns True if the array was homogeneous.
|
||||
///
|
||||
/// \remarks Always returns `false` for empty arrays.
|
||||
[[nodiscard]] bool is_homogeneous(node_type type) const noexcept;
|
||||
|
||||
/// \brief Checks if the array contains elements of only one type.
|
||||
///
|
||||
/// \detail \cpp
|
||||
/// auto arr = toml::array{ 1, 2, 3 };
|
||||
/// std::cout << "homogenous: "sv << arr.is_homogeneous() << "\n";
|
||||
/// std::cout << "all doubles: "sv << arr.is_homogeneous<double>() << "\n";
|
||||
/// std::cout << "all arrays: "sv << arr.is_homogeneous<toml::array>() << "\n";
|
||||
/// std::cout << "all integers: "sv << arr.is_homogeneous<int64_t>() << "\n";
|
||||
///
|
||||
/// \ecpp
|
||||
///
|
||||
/// \out
|
||||
/// homogeneous: true
|
||||
/// all doubles: false
|
||||
/// all arrays: false
|
||||
/// all integers: true
|
||||
/// \eout
|
||||
///
|
||||
/// \tparam ElemType A TOML node or value type. <br>
|
||||
/// <strong><em>Left as `void`:</em></strong> "is every node the same type?" <br>
|
||||
/// <strong><em>Explicitly specified:</em></strong> "is every node a T?"
|
||||
///
|
||||
/// \returns True if the array was homogeneous.
|
||||
///
|
||||
/// \remarks Always returns `false` for empty arrays.
|
||||
[[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, const node*& first_nonmatch) const noexcept override;
|
||||
template <typename ElemType = void>
|
||||
[[nodiscard]]
|
||||
bool is_homogeneous() const noexcept
|
||||
@ -477,16 +425,9 @@ TOML_NAMESPACE_START
|
||||
"The template type argument of array::is_homogeneous() must be void or one of:"
|
||||
TOML_SA_UNWRAPPED_NODE_TYPE_LIST
|
||||
);
|
||||
|
||||
if constexpr (std::is_void_v<type>)
|
||||
return is_homogeneous(node_type::none);
|
||||
else
|
||||
return is_homogeneous(impl::node_type_of<type>);
|
||||
return is_homogeneous(impl::node_type_of<type>);
|
||||
}
|
||||
|
||||
/// \brief Returns true if this array contains only tables.
|
||||
[[nodiscard]] bool is_array_of_tables() const noexcept override;
|
||||
|
||||
/// \brief Gets a reference to the element at a specific index.
|
||||
[[nodiscard]] node& operator[] (size_t index) noexcept;
|
||||
/// \brief Gets a reference to the element at a specific index.
|
||||
|
@ -113,6 +113,59 @@ TOML_NAMESPACE_START
|
||||
|
||||
#undef TOML_MEMBER_ATTR
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
bool array::is_homogeneous(node_type ntype) const noexcept
|
||||
{
|
||||
if (elements.empty())
|
||||
return false;
|
||||
|
||||
if (ntype == node_type::none)
|
||||
ntype = elements[0]->type();
|
||||
|
||||
for (const auto& val : elements)
|
||||
if (val->type() != ntype)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
namespace impl
|
||||
{
|
||||
template <typename T, typename U>
|
||||
TOML_INTERNAL_LINKAGE
|
||||
bool array_is_homogeneous(T& elements, node_type ntype, U& first_nonmatch) noexcept
|
||||
{
|
||||
if (elements.empty())
|
||||
{
|
||||
first_nonmatch = {};
|
||||
return false;
|
||||
}
|
||||
if (ntype == node_type::none)
|
||||
ntype = elements[0]->type();
|
||||
for (const auto& val : elements)
|
||||
{
|
||||
if (val->type() != ntype)
|
||||
{
|
||||
first_nonmatch = val.get();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
bool array::is_homogeneous(node_type ntype, toml::node*& first_nonmatch) noexcept
|
||||
{
|
||||
return impl::array_is_homogeneous(elements, ntype, first_nonmatch);
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
bool array::is_homogeneous(node_type ntype, const toml::node*& first_nonmatch) const noexcept
|
||||
{
|
||||
return impl::array_is_homogeneous(elements, ntype, first_nonmatch);
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
void array::truncate(size_t new_size)
|
||||
{
|
||||
@ -263,22 +316,6 @@ TOML_NAMESPACE_START
|
||||
return *this;
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
bool array::is_homogeneous(node_type type) const noexcept
|
||||
{
|
||||
if (elements.empty())
|
||||
return false;
|
||||
|
||||
if (type == node_type::none)
|
||||
type = elements[0]->type();
|
||||
|
||||
for (const auto& val : elements)
|
||||
if (val->type() != type)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
bool array::is_array_of_tables() const noexcept
|
||||
{
|
||||
|
@ -549,6 +549,7 @@ TOML_IMPL_NAMESPACE_START
|
||||
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<T>>>::value;
|
||||
|
||||
@ -611,7 +612,7 @@ TOML_IMPL_NAMESPACE_START
|
||||
[[nodiscard]]
|
||||
TOML_ATTR(const)
|
||||
TOML_ALWAYS_INLINE
|
||||
constexpr std::underlying_type_t<T> unbox_enum(T val) noexcept
|
||||
constexpr std::underlying_type_t<T> unwrap_enum(T val) noexcept
|
||||
{
|
||||
return static_cast<std::underlying_type_t<T>>(val);
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ TOML_NAMESPACE_START
|
||||
TOML_ATTR(flatten)
|
||||
constexpr format_flags operator & (format_flags lhs, format_flags rhs) noexcept
|
||||
{
|
||||
return static_cast<format_flags>(impl::unbox_enum(lhs) & impl::unbox_enum(rhs));
|
||||
return static_cast<format_flags>(impl::unwrap_enum(lhs) & impl::unwrap_enum(rhs));
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
@ -43,7 +43,7 @@ TOML_NAMESPACE_START
|
||||
TOML_ATTR(flatten)
|
||||
constexpr format_flags operator | (format_flags lhs, format_flags rhs) noexcept
|
||||
{
|
||||
return static_cast<format_flags>( impl::unbox_enum(lhs) | impl::unbox_enum(rhs) );
|
||||
return static_cast<format_flags>( impl::unwrap_enum(lhs) | impl::unwrap_enum(rhs) );
|
||||
}
|
||||
}
|
||||
TOML_NAMESPACE_END
|
||||
|
@ -195,6 +195,104 @@ TOML_NAMESPACE_START
|
||||
[[nodiscard]] virtual const toml::value<time>* as_time() const noexcept;
|
||||
[[nodiscard]] virtual const toml::value<date_time>* as_date_time() const noexcept;
|
||||
|
||||
/// \brief Checks if a node contains values/elements of only one type.
|
||||
///
|
||||
/// \detail \cpp
|
||||
/// auto cfg = toml::parse("arr = [ 1, 2, 3, 4.0 ]");
|
||||
/// toml::array& arr = *cfg["arr"].as_array();
|
||||
///
|
||||
/// toml::node* nonmatch{};
|
||||
/// if (arr.is_homogeneous(toml::node_type::integer, nonmatch))
|
||||
/// std::cout << "array was homogeneous"sv << "\n";
|
||||
/// else
|
||||
/// std::cout << "array was not homogeneous!\n"
|
||||
/// << "first non-match was a "sv << nonmatch->type() << " at " << nonmatch->source() << "\n";
|
||||
/// \ecpp
|
||||
///
|
||||
/// \out
|
||||
/// array was not homogeneous!
|
||||
/// first non-match was a floating-point at line 1, column 18
|
||||
/// \eout
|
||||
///
|
||||
/// \param ntype A TOML node type. <br>
|
||||
/// <strong><em>toml::node_type::none: </em></strong> "is every element the same type?" <br>
|
||||
/// <strong><em>Anything else:</em></strong> "is every element one of these?"
|
||||
/// \param first_nonmatch Reference to a pointer in which the address of the first non-matching element
|
||||
/// will be stored if the return value is false.
|
||||
///
|
||||
/// \returns True if the node was homogeneous.
|
||||
///
|
||||
/// \remarks Always returns `false` for empty tables and arrays.
|
||||
[[nodiscard]] virtual bool is_homogeneous(node_type ntype, node*& first_nonmatch) noexcept = 0;
|
||||
|
||||
/// \brief Checks if a node contains values/elements of only one type (const overload).
|
||||
[[nodiscard]] virtual bool is_homogeneous(node_type ntype, const node*& first_nonmatch) const noexcept = 0;
|
||||
|
||||
/// \brief Checks if the node contains values/elements of only one type.
|
||||
///
|
||||
/// \detail \cpp
|
||||
/// auto arr = toml::array{ 1, 2, 3 };
|
||||
/// std::cout << "homogenous: "sv << arr.is_homogeneous(toml::node_type::none) << "\n";
|
||||
/// std::cout << "all floats: "sv << arr.is_homogeneous(toml::node_type::floating_point) << "\n";
|
||||
/// std::cout << "all arrays: "sv << arr.is_homogeneous(toml::node_type::array) << "\n";
|
||||
/// std::cout << "all ints: "sv << arr.is_homogeneous(toml::node_type::integer) << "\n";
|
||||
///
|
||||
/// \ecpp
|
||||
///
|
||||
/// \out
|
||||
/// homogeneous: true
|
||||
/// all floats: false
|
||||
/// all arrays: false
|
||||
/// all ints: true
|
||||
/// \eout
|
||||
///
|
||||
/// \param ntype A TOML node type. <br>
|
||||
/// <strong><em>toml::node_type::none: </em></strong> "is every element the same type?" <br>
|
||||
/// <strong><em>Anything else:</em></strong> "is every element one of these?"
|
||||
///
|
||||
/// \returns True if the node was homogeneous.
|
||||
///
|
||||
/// \remarks Always returns `false` for empty tables and arrays.
|
||||
[[nodiscard]] virtual bool is_homogeneous(node_type ntype) const noexcept = 0;
|
||||
|
||||
/// \brief Checks if the node contains values/elements of only one type.
|
||||
///
|
||||
/// \detail \cpp
|
||||
/// auto arr = toml::array{ 1, 2, 3 };
|
||||
/// std::cout << "homogenous: "sv << arr.is_homogeneous() << "\n";
|
||||
/// std::cout << "all doubles: "sv << arr.is_homogeneous<double>() << "\n";
|
||||
/// std::cout << "all arrays: "sv << arr.is_homogeneous<toml::array>() << "\n";
|
||||
/// std::cout << "all integers: "sv << arr.is_homogeneous<int64_t>() << "\n";
|
||||
///
|
||||
/// \ecpp
|
||||
///
|
||||
/// \out
|
||||
/// homogeneous: true
|
||||
/// all floats: false
|
||||
/// all arrays: false
|
||||
/// all ints: true
|
||||
/// \eout
|
||||
///
|
||||
/// \tparam ElemType A TOML node or value type. <br>
|
||||
/// <strong><em>Left as `void`:</em></strong> "is every element the same type?" <br>
|
||||
/// <strong><em>Explicitly specified:</em></strong> "is every element a T?"
|
||||
///
|
||||
/// \returns True if the node was homogeneous.
|
||||
///
|
||||
/// \remarks Always returns `false` for empty tables and arrays.
|
||||
template <typename ElemType = void>
|
||||
[[nodiscard]]
|
||||
bool is_homogeneous() const noexcept
|
||||
{
|
||||
using type = impl::unwrap_node<ElemType>;
|
||||
static_assert(
|
||||
std::is_void_v<type>
|
||||
|| ((impl::is_native<type> || impl::is_one_of<type, table, array>) && !impl::is_cvref<type>),
|
||||
"The template type argument of node::is_homogeneous() must be void or one of:"
|
||||
TOML_SA_UNWRAPPED_NODE_TYPE_LIST
|
||||
);
|
||||
return is_homogeneous(impl::node_type_of<type>);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@ -377,6 +475,14 @@ TOML_NAMESPACE_START
|
||||
[[nodiscard]]
|
||||
auto value_or(T&& default_value) const noexcept;
|
||||
|
||||
//template <typename T>
|
||||
//[[nodiscard]]
|
||||
//std::vector<T> select_exact() const noexcept;
|
||||
|
||||
//template <typename T>
|
||||
//[[nodiscard]]
|
||||
//std::vector<T> select() const noexcept;
|
||||
|
||||
/// \brief Gets a pointer to the node as a more specific node type.
|
||||
///
|
||||
/// \details \cpp
|
||||
|
@ -179,6 +179,110 @@ TOML_NAMESPACE_START
|
||||
/// \brief Returns a pointer to the viewed node as a toml::value<date_time>, if it is one.
|
||||
[[nodiscard]] auto as_date_time() const noexcept { return as<date_time>(); }
|
||||
|
||||
/// \brief Checks if the viewed node contains values/elements of only one type.
|
||||
///
|
||||
/// \detail \cpp
|
||||
/// auto cfg = toml::parse("arr = [ 1, 2, 3, 4.0 ]");
|
||||
///
|
||||
/// toml::node* nonmatch{};
|
||||
/// if (cfg["arr"].is_homogeneous(toml::node_type::integer, nonmatch))
|
||||
/// std::cout << "array was homogeneous"sv << "\n";
|
||||
/// else
|
||||
/// std::cout << "array was not homogeneous!\n"
|
||||
/// << "first non-match was a "sv << nonmatch->type() << " at " << nonmatch->source() << "\n";
|
||||
/// \ecpp
|
||||
///
|
||||
/// \out
|
||||
/// array was not homogeneous!
|
||||
/// first non-match was a floating-point at line 1, column 18
|
||||
/// \eout
|
||||
///
|
||||
/// \param ntype A TOML node type. <br>
|
||||
/// <strong><em>toml::node_type::none: </em></strong> "is every element the same type?" <br>
|
||||
/// <strong><em>Anything else:</em></strong> "is every element one of these?"
|
||||
/// \param first_nonmatch Reference to a pointer in which the address of the first non-matching element
|
||||
/// will be stored if the return value is false.
|
||||
///
|
||||
/// \returns True if the viewed node was homogeneous.
|
||||
///
|
||||
/// \remarks Always returns `false` if the view does not reference a node, or if the viewed node is
|
||||
/// an empty table or array.
|
||||
[[nodiscard]]
|
||||
bool is_homogeneous(node_type ntype, viewed_type*& first_nonmatch) const noexcept
|
||||
{
|
||||
if (!node_)
|
||||
{
|
||||
first_nonmatch = {};
|
||||
return false;
|
||||
}
|
||||
return node_->is_homogeneous(ntype, first_nonmatch);
|
||||
}
|
||||
|
||||
/// \brief Checks if the viewed node contains values/elements of only one type.
|
||||
///
|
||||
/// \detail \cpp
|
||||
/// auto cfg = toml::parse("arr = [ 1, 2, 3 ]");
|
||||
/// std::cout << "homogenous: "sv << cfg["arr"].is_homogeneous(toml::node_type::none) << "\n";
|
||||
/// std::cout << "all floats: "sv << cfg["arr"].is_homogeneous(toml::node_type::floating_point) << "\n";
|
||||
/// std::cout << "all arrays: "sv << cfg["arr"].is_homogeneous(toml::node_type::array) << "\n";
|
||||
/// std::cout << "all ints: "sv << cfg["arr"].is_homogeneous(toml::node_type::integer) << "\n";
|
||||
///
|
||||
/// \ecpp
|
||||
///
|
||||
/// \out
|
||||
/// homogeneous: true
|
||||
/// all floats: false
|
||||
/// all arrays: false
|
||||
/// all ints: true
|
||||
/// \eout
|
||||
///
|
||||
/// \param ntype A TOML node type. <br>
|
||||
/// <strong><em>toml::node_type::none: </em></strong> "is every element the same type?" <br>
|
||||
/// <strong><em>Anything else:</em></strong> "is every element one of these?"
|
||||
///
|
||||
/// \returns True if the viewed node was homogeneous.
|
||||
///
|
||||
/// \remarks Always returns `false` if the view does not reference a node, or if the viewed node is
|
||||
/// an empty table or array.
|
||||
[[nodiscard]]
|
||||
bool is_homogeneous(node_type ntype) const noexcept
|
||||
{
|
||||
return node_ ? node_->is_homogeneous(ntype) : false;
|
||||
}
|
||||
|
||||
/// \brief Checks if the viewed node contains values/elements of only one type.
|
||||
///
|
||||
/// \detail \cpp
|
||||
/// auto cfg = toml::parse("arr = [ 1, 2, 3 ]");
|
||||
/// std::cout << "homogenous: "sv << cfg["arr"].is_homogeneous() << "\n";
|
||||
/// std::cout << "all doubles: "sv << cfg["arr"].is_homogeneous<double>() << "\n";
|
||||
/// std::cout << "all arrays: "sv << cfg["arr"].is_homogeneous<toml::array>() << "\n";
|
||||
/// std::cout << "all integers: "sv << cfg["arr"].is_homogeneous<int64_t>() << "\n";
|
||||
///
|
||||
/// \ecpp
|
||||
///
|
||||
/// \out
|
||||
/// homogeneous: true
|
||||
/// all floats: false
|
||||
/// all arrays: false
|
||||
/// all ints: true
|
||||
/// \eout
|
||||
///
|
||||
/// \tparam ElemType A TOML node or value type. <br>
|
||||
/// <strong><em>Left as `void`:</em></strong> "is every element the same type?" <br>
|
||||
/// <strong><em>Explicitly specified:</em></strong> "is every element a T?"
|
||||
///
|
||||
/// \returns True if the viewed node was homogeneous.
|
||||
///
|
||||
/// \remarks Always returns `false` if the view does not reference a node, or if the viewed node is
|
||||
/// an empty table or array.
|
||||
template <typename ElemType = void>
|
||||
[[nodiscard]]
|
||||
bool is_homogeneous() const noexcept
|
||||
{
|
||||
return node_ ? node_->template is_homogeneous<impl::unwrap_node<ElemType>>() : false;
|
||||
}
|
||||
|
||||
/// \brief Gets the value contained by the referenced node.
|
||||
///
|
||||
/// \detail This function has 'exact' retrieval semantics; the only return value types allowed are the
|
||||
|
@ -83,7 +83,7 @@ TOML_ANON_NAMESPACE_START
|
||||
{
|
||||
using namespace ::toml::impl;
|
||||
|
||||
return node_type_friendly_names[unbox_enum(val)];
|
||||
return node_type_friendly_names[unwrap_enum(val)];
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
@ -2068,7 +2068,7 @@ TOML_IMPL_NAMESPACE_START
|
||||
// all correct value parses will come out of this list, so doing this as a switch is likely to
|
||||
// be a better friend to the optimizer on the success path (failure path can be slow but that
|
||||
// doesn't matter much).
|
||||
switch (unbox_enum(traits))
|
||||
switch (unwrap_enum(traits))
|
||||
{
|
||||
//=================== binary integers
|
||||
// 0b10
|
||||
|
@ -450,8 +450,6 @@ is no longer necessary.
|
||||
#define TOML_ARM 0
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
//#====================================================================================================================
|
||||
//# EXTENDED INT AND FLOAT TYPES
|
||||
//#====================================================================================================================
|
||||
|
@ -278,17 +278,30 @@ TOML_NAMESPACE_START
|
||||
: table{ arr, N }
|
||||
{}
|
||||
|
||||
/// \brief Always returns `node_type::table` for table nodes.
|
||||
[[nodiscard]] node_type type() const noexcept override;
|
||||
/// \brief Always returns `true` for table nodes.
|
||||
[[nodiscard]] bool is_table() const noexcept override;
|
||||
/// \brief Always returns `false` for table nodes.
|
||||
[[nodiscard]] bool is_array() const noexcept override;
|
||||
/// \brief Always returns `false` for table nodes.
|
||||
[[nodiscard]] bool is_value() const noexcept override;
|
||||
[[nodiscard]] table* as_table() noexcept override;
|
||||
[[nodiscard]] const table* as_table() 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, const node*& first_nonmatch) const noexcept override;
|
||||
template <typename ElemType = void>
|
||||
[[nodiscard]]
|
||||
bool is_homogeneous() const noexcept
|
||||
{
|
||||
using type = impl::unwrap_node<ElemType>;
|
||||
static_assert(
|
||||
std::is_void_v<type>
|
||||
|| ((impl::is_native<type> || impl::is_one_of<type, table, array>) && !impl::is_cvref<type>),
|
||||
"The template type argument of table::is_homogeneous() must be void or one of:"
|
||||
TOML_SA_UNWRAPPED_NODE_TYPE_LIST
|
||||
);
|
||||
return is_homogeneous(impl::node_type_of<type>);
|
||||
}
|
||||
|
||||
/// \brief Returns true if this table is an inline table.
|
||||
///
|
||||
/// \remarks Runtime-constructed tables (i.e. those not created during
|
||||
@ -1083,6 +1096,49 @@ TOML_NAMESPACE_START
|
||||
template <typename Char>
|
||||
friend std::basic_ostream<Char>& operator << (std::basic_ostream<Char>&, const table&);
|
||||
};
|
||||
|
||||
#ifndef DOXYGEN
|
||||
|
||||
|
||||
|
||||
//template <typename T>
|
||||
//inline std::vector<T> node::select_exact() const noexcept
|
||||
//{
|
||||
// using namespace impl;
|
||||
|
||||
// static_assert(
|
||||
// !is_wide_string<T> || TOML_WINDOWS_COMPAT,
|
||||
// "Retrieving values as wide-character strings with node::select_exact() is only "
|
||||
// "supported on Windows with TOML_WINDOWS_COMPAT enabled."
|
||||
// );
|
||||
|
||||
// static_assert(
|
||||
// (is_native<T> || can_represent_native<T>) && !is_cvref<T>,
|
||||
// TOML_SA_VALUE_EXACT_FUNC_MESSAGE("return type of node::select_exact()")
|
||||
// );
|
||||
//}
|
||||
|
||||
//template <typename T>
|
||||
//inline std::vector<T> node::select() const noexcept
|
||||
//{
|
||||
// using namespace impl;
|
||||
|
||||
// static_assert(
|
||||
// !is_wide_string<T> || TOML_WINDOWS_COMPAT,
|
||||
// "Retrieving values as wide-character strings with node::select() is only "
|
||||
// "supported on Windows with TOML_WINDOWS_COMPAT enabled."
|
||||
// );
|
||||
// static_assert(
|
||||
// (is_native<T> || can_represent_native<T> || can_partially_represent_native<T>) && !is_cvref<T>,
|
||||
// TOML_SA_VALUE_FUNC_MESSAGE("return type of node::select()")
|
||||
// );
|
||||
//}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif // !DOXYGEN
|
||||
}
|
||||
TOML_NAMESPACE_END
|
||||
|
||||
|
@ -104,6 +104,63 @@ TOML_NAMESPACE_START
|
||||
|
||||
#undef TOML_MEMBER_ATTR
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
bool table::is_homogeneous(node_type ntype) const noexcept
|
||||
{
|
||||
if (map.empty())
|
||||
return false;
|
||||
|
||||
if (ntype == node_type::none)
|
||||
ntype = map.cbegin()->second->type();
|
||||
|
||||
for (const auto& [k, v] : map)
|
||||
{
|
||||
(void)k;
|
||||
if (v->type() != ntype)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
namespace impl
|
||||
{
|
||||
template <typename T, typename U>
|
||||
TOML_INTERNAL_LINKAGE
|
||||
bool table_is_homogeneous(T& map, node_type ntype, U& first_nonmatch) noexcept
|
||||
{
|
||||
if (map.empty())
|
||||
{
|
||||
first_nonmatch = {};
|
||||
return false;
|
||||
}
|
||||
if (ntype == node_type::none)
|
||||
ntype = map.cbegin()->second->type();
|
||||
for (const auto& [k, v] : map)
|
||||
{
|
||||
(void)k;
|
||||
if (v->type() != ntype)
|
||||
{
|
||||
first_nonmatch = v.get();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
bool table::is_homogeneous(node_type ntype, toml::node*& first_nonmatch) noexcept
|
||||
{
|
||||
return impl::table_is_homogeneous(map, ntype, first_nonmatch);
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
bool table::is_homogeneous(node_type ntype, const toml::node*& first_nonmatch) const noexcept
|
||||
{
|
||||
return impl::table_is_homogeneous(map, ntype, first_nonmatch);
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
node_view<node> table::operator[] (std::string_view key) noexcept
|
||||
{
|
||||
|
@ -7,6 +7,65 @@
|
||||
#include "toml_node.h"
|
||||
#include "toml_print_to_stream.h"
|
||||
|
||||
#ifndef DOXYGEN
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
#define TOML_SA_VALUE_MESSAGE_WSTRING TOML_SA_LIST_SEP "std::wstring"
|
||||
#else
|
||||
#define TOML_SA_VALUE_MESSAGE_WSTRING
|
||||
#endif
|
||||
|
||||
#ifdef __cpp_lib_char8_t
|
||||
#define TOML_SA_VALUE_MESSAGE_U8STRING_VIEW TOML_SA_LIST_SEP "std::u8string_view"
|
||||
#define TOML_SA_VALUE_MESSAGE_CONST_CHAR8 TOML_SA_LIST_SEP "const char8_t*"
|
||||
#else
|
||||
#define TOML_SA_VALUE_MESSAGE_U8STRING_VIEW
|
||||
#define TOML_SA_VALUE_MESSAGE_CONST_CHAR8
|
||||
#endif
|
||||
|
||||
#define TOML_SA_VALUE_EXACT_FUNC_MESSAGE(type_arg) \
|
||||
"The " type_arg " must be one of:" \
|
||||
TOML_SA_LIST_NEW "A native TOML value type" \
|
||||
TOML_SA_NATIVE_VALUE_TYPE_LIST \
|
||||
\
|
||||
TOML_SA_LIST_NXT "A non-view type capable of losslessly representing a native TOML value type" \
|
||||
TOML_SA_LIST_BEG "std::string" \
|
||||
TOML_SA_VALUE_MESSAGE_WSTRING \
|
||||
TOML_SA_LIST_SEP "any signed integer type >= 64 bits" \
|
||||
TOML_SA_LIST_SEP "any floating-point type >= 64 bits" \
|
||||
TOML_SA_LIST_END \
|
||||
\
|
||||
TOML_SA_LIST_NXT "An immutable view type not requiring additional temporary storage" \
|
||||
TOML_SA_LIST_BEG "std::string_view" \
|
||||
TOML_SA_VALUE_MESSAGE_U8STRING_VIEW \
|
||||
TOML_SA_LIST_SEP "const char*" \
|
||||
TOML_SA_VALUE_MESSAGE_CONST_CHAR8 \
|
||||
TOML_SA_LIST_END
|
||||
|
||||
#define TOML_SA_VALUE_FUNC_MESSAGE(type_arg) \
|
||||
"The " type_arg " must be one of:" \
|
||||
TOML_SA_LIST_NEW "A native TOML value type" \
|
||||
TOML_SA_NATIVE_VALUE_TYPE_LIST \
|
||||
\
|
||||
TOML_SA_LIST_NXT "A non-view type capable of losslessly representing a native TOML value type" \
|
||||
TOML_SA_LIST_BEG "std::string" \
|
||||
TOML_SA_VALUE_MESSAGE_WSTRING \
|
||||
TOML_SA_LIST_SEP "any signed integer type >= 64 bits" \
|
||||
TOML_SA_LIST_SEP "any floating-point type >= 64 bits" \
|
||||
TOML_SA_LIST_END \
|
||||
\
|
||||
TOML_SA_LIST_NXT "A non-view type capable of (reasonably) representing a native TOML value type" \
|
||||
TOML_SA_LIST_BEG "any other integer type" \
|
||||
TOML_SA_LIST_SEP "any floating-point type >= 32 bits" \
|
||||
TOML_SA_LIST_END \
|
||||
\
|
||||
TOML_SA_LIST_NXT "An immutable view type not requiring additional temporary storage" \
|
||||
TOML_SA_LIST_BEG "std::string_view" \
|
||||
TOML_SA_VALUE_MESSAGE_U8STRING_VIEW \
|
||||
TOML_SA_LIST_SEP "const char*" \
|
||||
TOML_SA_VALUE_MESSAGE_CONST_CHAR8 \
|
||||
TOML_SA_LIST_END
|
||||
#endif // !DOXYGEN
|
||||
|
||||
TOML_PUSH_WARNINGS
|
||||
TOML_DISABLE_ARITHMETIC_WARNINGS
|
||||
TOML_DISABLE_PADDING_WARNINGS
|
||||
@ -218,11 +277,8 @@ TOML_NAMESPACE_START
|
||||
/// - node_type::date_time
|
||||
[[nodiscard]] node_type type() const noexcept override { return impl::node_type_of<value_type>; }
|
||||
|
||||
/// \brief Always returns `false` for value nodes.
|
||||
[[nodiscard]] bool is_table() const noexcept override { return false; }
|
||||
/// \brief Always returns `false` for value nodes.
|
||||
[[nodiscard]] bool is_array() const noexcept override { return false; }
|
||||
/// \brief Always returns `true` for value nodes.
|
||||
[[nodiscard]] bool is_value() const noexcept override { return true; }
|
||||
|
||||
[[nodiscard]] bool is_string() const noexcept override { return std::is_same_v<value_type, std::string>; }
|
||||
@ -234,36 +290,66 @@ TOML_NAMESPACE_START
|
||||
[[nodiscard]] bool is_time() const noexcept override { return std::is_same_v<value_type, time>; }
|
||||
[[nodiscard]] bool is_date_time() const noexcept override { return std::is_same_v<value_type, date_time>; }
|
||||
|
||||
/// \brief Returns a pointer to the value if the data type is a string.
|
||||
[[nodiscard]] value<std::string>* as_string() noexcept override { return as_value<std::string>(this); }
|
||||
/// \brief Returns a pointer to the value if the data type is an integer.
|
||||
[[nodiscard]] value<int64_t>* as_integer() noexcept override { return as_value<int64_t>(this); }
|
||||
/// \brief Returns a pointer to the value if the data type is a floating-point.
|
||||
[[nodiscard]] value<double>* as_floating_point() noexcept override { return as_value<double>(this); }
|
||||
/// \brief Returns a pointer to the value if the data type is boolean.
|
||||
[[nodiscard]] value<bool>* as_boolean() noexcept override { return as_value<bool>(this); }
|
||||
/// \brief Returns a pointer to the value if the data type is a date.
|
||||
[[nodiscard]] value<date>* as_date() noexcept override { return as_value<date>(this); }
|
||||
/// \brief Returns a pointer to the value if the data type is a time.
|
||||
[[nodiscard]] value<time>* as_time() noexcept override { return as_value<time>(this); }
|
||||
/// \brief Returns a pointer to the value if the data type is date-time.
|
||||
[[nodiscard]] value<date_time>* as_date_time() noexcept override { return as_value<date_time>(this); }
|
||||
|
||||
/// \brief Returns a const pointer to the value if the data type is a string.
|
||||
[[nodiscard]] const value<std::string>* as_string() const noexcept override { return as_value<std::string>(this); }
|
||||
/// \brief Returns a const pointer to the value if the data type is an integer.
|
||||
[[nodiscard]] const value<int64_t>* as_integer() const noexcept override { return as_value<int64_t>(this); }
|
||||
/// \brief Returns a const pointer to the value if the data type is a floating-point.
|
||||
[[nodiscard]] const value<double>* as_floating_point() const noexcept override { return as_value<double>(this); }
|
||||
/// \brief Returns a const pointer to the value if the data type is a boolean.
|
||||
[[nodiscard]] const value<bool>* as_boolean() const noexcept override { return as_value<bool>(this); }
|
||||
/// \brief Returns a const pointer to the value if the data type is a date.
|
||||
[[nodiscard]] const value<date>* as_date() const noexcept override { return as_value<date>(this); }
|
||||
/// \brief Returns a const pointer to the value if the data type is a time.
|
||||
[[nodiscard]] const value<time>* as_time() const noexcept override { return as_value<time>(this); }
|
||||
/// \brief Returns a const pointer to the value if the data type is a date-time.
|
||||
[[nodiscard]] const value<date_time>* as_date_time() const noexcept override { return as_value<date_time>(this); }
|
||||
|
||||
[[nodiscard]]
|
||||
bool is_homogeneous(node_type ntype) const noexcept override
|
||||
{
|
||||
return ntype == node_type::none || ntype == impl::node_type_of<value_type>;
|
||||
}
|
||||
[[nodiscard]]
|
||||
bool is_homogeneous(node_type ntype, toml::node*& first_nonmatch) noexcept override
|
||||
{
|
||||
if (ntype != node_type::none && ntype != impl::node_type_of<value_type>)
|
||||
{
|
||||
first_nonmatch = this;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
[[nodiscard]]
|
||||
bool is_homogeneous(node_type ntype, const toml::node*& first_nonmatch) const noexcept override
|
||||
{
|
||||
if (ntype != node_type::none && ntype != impl::node_type_of<value_type>)
|
||||
{
|
||||
first_nonmatch = this;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
template <typename ElemType = void>
|
||||
[[nodiscard]]
|
||||
bool is_homogeneous() const noexcept
|
||||
{
|
||||
using type = impl::unwrap_node<ElemType>;
|
||||
static_assert(
|
||||
std::is_void_v<type>
|
||||
|| ((impl::is_native<type> || impl::is_one_of<type, table, array>) && !impl::is_cvref<type>),
|
||||
"The template type argument of value::is_homogeneous() must be void or one of:"
|
||||
TOML_SA_UNWRAPPED_NODE_TYPE_LIST
|
||||
);
|
||||
|
||||
using type = impl::unwrap_node<ElemType>;
|
||||
if constexpr (std::is_void_v<type>)
|
||||
return true;
|
||||
else
|
||||
return impl::node_type_of<type> == impl::node_type_of<value_type>;
|
||||
}
|
||||
|
||||
/// \brief Returns a reference to the underlying value.
|
||||
[[nodiscard]] value_type& get() & noexcept { return val_; }
|
||||
/// \brief Returns a reference to the underlying value (rvalue overload).
|
||||
@ -315,8 +401,8 @@ TOML_NAMESPACE_START
|
||||
using namespace impl;
|
||||
static constexpr auto pack = [](auto l, auto r) constexpr noexcept
|
||||
{
|
||||
return (static_cast<uint64_t>(unbox_enum(l)) << 32)
|
||||
| static_cast<uint64_t>(unbox_enum(r));
|
||||
return (static_cast<uint64_t>(unwrap_enum(l)) << 32)
|
||||
| static_cast<uint64_t>(unwrap_enum(r));
|
||||
};
|
||||
|
||||
switch (pack(impl::fpclassify(lhs.val_), impl::fpclassify(rhs)))
|
||||
@ -467,6 +553,9 @@ TOML_NAMESPACE_START
|
||||
value(T) -> value<impl::native_type_of<impl::remove_cvref_t<T>>>;
|
||||
|
||||
#ifndef DOXYGEN
|
||||
TOML_PUSH_WARNINGS
|
||||
TOML_DISABLE_INIT_WARNINGS
|
||||
TOML_DISABLE_SWITCH_WARNINGS
|
||||
|
||||
#if !TOML_HEADER_ONLY
|
||||
extern template class TOML_API value<std::string>;
|
||||
@ -477,10 +566,6 @@ TOML_NAMESPACE_START
|
||||
extern template class TOML_API value<time>;
|
||||
extern template class TOML_API value<date_time>;
|
||||
#endif
|
||||
|
||||
TOML_PUSH_WARNINGS
|
||||
TOML_DISABLE_INIT_WARNINGS
|
||||
TOML_DISABLE_SWITCH_WARNINGS
|
||||
|
||||
template <typename T>
|
||||
[[nodiscard]]
|
||||
@ -543,29 +628,7 @@ TOML_NAMESPACE_START
|
||||
|
||||
static_assert(
|
||||
(is_native<T> || can_represent_native<T>) && !is_cvref<T>,
|
||||
"The return type of node::value_exact() must be one of:"
|
||||
TOML_SA_LIST_NEW "A native TOML value type"
|
||||
TOML_SA_NATIVE_VALUE_TYPE_LIST
|
||||
|
||||
TOML_SA_LIST_NXT "A non-view type capable of losslessly representing a native TOML value type"
|
||||
TOML_SA_LIST_BEG "std::string"
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
TOML_SA_LIST_SEP "std::wstring"
|
||||
#endif
|
||||
TOML_SA_LIST_SEP "any signed integer type >= 64 bits"
|
||||
TOML_SA_LIST_SEP "any floating-point type >= 64 bits"
|
||||
TOML_SA_LIST_END
|
||||
|
||||
TOML_SA_LIST_NXT "An immutable view type not requiring additional temporary storage"
|
||||
TOML_SA_LIST_BEG "std::string_view"
|
||||
#ifdef __cpp_lib_char8_t
|
||||
TOML_SA_LIST_SEP "std::u8string_view"
|
||||
#endif
|
||||
TOML_SA_LIST_SEP "const char*"
|
||||
#ifdef __cpp_lib_char8_t
|
||||
TOML_SA_LIST_SEP "const char8_t*"
|
||||
#endif
|
||||
TOML_SA_LIST_END
|
||||
TOML_SA_VALUE_EXACT_FUNC_MESSAGE("return type of node::value_exact()")
|
||||
);
|
||||
|
||||
// prevent additional compiler error spam when the static_assert fails by gating behind if constexpr
|
||||
@ -590,34 +653,7 @@ TOML_NAMESPACE_START
|
||||
);
|
||||
static_assert(
|
||||
(is_native<T> || can_represent_native<T> || can_partially_represent_native<T>) && !is_cvref<T>,
|
||||
"The return type of node::value() must be one of:"
|
||||
TOML_SA_LIST_NEW "A native TOML value type"
|
||||
TOML_SA_NATIVE_VALUE_TYPE_LIST
|
||||
|
||||
TOML_SA_LIST_NXT "A non-view type capable of losslessly representing a native TOML value type"
|
||||
TOML_SA_LIST_BEG "std::string"
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
TOML_SA_LIST_SEP "std::wstring"
|
||||
#endif
|
||||
TOML_SA_LIST_SEP "any signed integer type >= 64 bits"
|
||||
TOML_SA_LIST_SEP "any floating-point type >= 64 bits"
|
||||
TOML_SA_LIST_END
|
||||
|
||||
TOML_SA_LIST_NXT "A non-view type capable of (reasonably) representing a native TOML value type"
|
||||
TOML_SA_LIST_BEG "any other integer type"
|
||||
TOML_SA_LIST_SEP "any floating-point type >= 32 bits"
|
||||
TOML_SA_LIST_END
|
||||
|
||||
TOML_SA_LIST_NXT "An immutable view type not requiring additional temporary storage"
|
||||
TOML_SA_LIST_BEG "std::string_view"
|
||||
#ifdef __cpp_lib_char8_t
|
||||
TOML_SA_LIST_SEP "std::u8string_view"
|
||||
#endif
|
||||
TOML_SA_LIST_SEP "const char*"
|
||||
#ifdef __cpp_lib_char8_t
|
||||
TOML_SA_LIST_SEP "const char8_t*"
|
||||
#endif
|
||||
TOML_SA_LIST_END
|
||||
TOML_SA_VALUE_FUNC_MESSAGE("return type of node::value()")
|
||||
);
|
||||
|
||||
// when asking for strings, dates, times and date_times there's no 'fuzzy' conversion
|
||||
@ -760,7 +796,7 @@ TOML_NAMESPACE_START
|
||||
|
||||
static_assert(
|
||||
traits::is_native || traits::can_represent_native || traits::can_partially_represent_native,
|
||||
"The default return value type of node::value_or() must be one of:"
|
||||
"The default value type of node::value_or() must be one of:"
|
||||
TOML_SA_LIST_NEW "A native TOML value type"
|
||||
TOML_SA_NATIVE_VALUE_TYPE_LIST
|
||||
|
||||
@ -799,6 +835,11 @@ TOML_NAMESPACE_START
|
||||
// prevent additional compiler error spam when the static_assert fails by gating behind if constexpr
|
||||
if constexpr (traits::is_native || traits::can_represent_native || traits::can_partially_represent_native)
|
||||
{
|
||||
if constexpr (traits::is_native)
|
||||
{
|
||||
if (type() == node_type_of<value_type>)
|
||||
return *ref_cast<typename traits::native_type>();
|
||||
}
|
||||
if (auto val = this->value<value_type>())
|
||||
return *val;
|
||||
if constexpr (std::is_pointer_v<value_type>)
|
||||
@ -858,7 +899,6 @@ TOML_NAMESPACE_START
|
||||
#endif // !TOML_HEADER_ONLY
|
||||
|
||||
TOML_POP_WARNINGS // TOML_DISABLE_INIT_WARNINGS, TOML_DISABLE_SWITCH_WARNINGS
|
||||
|
||||
#endif // !DOXYGEN
|
||||
}
|
||||
TOML_NAMESPACE_END
|
||||
|
@ -12,9 +12,6 @@ TOML_DISABLE_ALL_WARNINGS
|
||||
TOML_POP_WARNINGS
|
||||
#endif
|
||||
|
||||
// TOML_PUSH_WARNINGS
|
||||
// TOML_DISABLE_ARITHMETIC_WARNINGS
|
||||
|
||||
template <typename T>
|
||||
static constexpr T one = static_cast<T>(1);
|
||||
|
||||
@ -28,6 +25,9 @@ TEST_CASE("values - construction")
|
||||
CHECK(equiv == v); \
|
||||
CHECK(*v == equiv); \
|
||||
CHECK(v.get() == equiv); \
|
||||
CHECK(v.is_homogeneous()); \
|
||||
CHECK(v.is_homogeneous<target_type>()); \
|
||||
CHECK(v.is_homogeneous(impl::node_type_of<target_type>)); \
|
||||
} while (false)
|
||||
|
||||
#define CHECK_VALUE_INIT(initializer, target_type) \
|
||||
@ -86,8 +86,6 @@ TEST_CASE("values - construction")
|
||||
#endif
|
||||
}
|
||||
|
||||
// TOML_POP_WARNINGS
|
||||
|
||||
TEST_CASE("values - printing")
|
||||
{
|
||||
static constexpr auto print_value = [](auto&& raw)
|
||||
|
@ -26,27 +26,63 @@ TEST_CASE("parsing - arrays")
|
||||
[](table&& tbl)
|
||||
{
|
||||
REQUIRE(tbl["integers"].as<array>());
|
||||
CHECK(tbl["integers"].is_homogeneous());
|
||||
CHECK(tbl["integers"].is_homogeneous(node_type::integer));
|
||||
CHECK(!tbl["integers"].is_homogeneous(node_type::floating_point));
|
||||
CHECK(tbl["integers"].is_homogeneous<int64_t>());
|
||||
CHECK(!tbl["integers"].is_homogeneous<double>());
|
||||
CHECK(tbl["integers"].as<array>()->is_homogeneous());
|
||||
CHECK(tbl["integers"].as<array>()->is_homogeneous(node_type::integer));
|
||||
CHECK(!tbl["integers"].as<array>()->is_homogeneous(node_type::floating_point));
|
||||
CHECK(tbl["integers"].as<array>()->is_homogeneous<int64_t>());
|
||||
CHECK(!tbl["integers"].as<array>()->is_homogeneous<double>());
|
||||
CHECK(tbl["integers"].as<array>()->size() == 3);
|
||||
CHECK(tbl["integers"][0] == 1);
|
||||
CHECK(tbl["integers"][1] == 2);
|
||||
CHECK(tbl["integers"][2] == 3);
|
||||
|
||||
REQUIRE(tbl["integers2"].as<array>());
|
||||
CHECK(tbl["integers2"].is_homogeneous());
|
||||
CHECK(tbl["integers2"].is_homogeneous(node_type::integer));
|
||||
CHECK(!tbl["integers2"].is_homogeneous(node_type::floating_point));
|
||||
CHECK(tbl["integers2"].is_homogeneous<int64_t>());
|
||||
CHECK(!tbl["integers2"].is_homogeneous<double>());
|
||||
CHECK(tbl["integers2"].as<array>()->is_homogeneous());
|
||||
CHECK(tbl["integers2"].as<array>()->is_homogeneous(node_type::integer));
|
||||
CHECK(!tbl["integers2"].as<array>()->is_homogeneous(node_type::floating_point));
|
||||
CHECK(tbl["integers2"].as<array>()->is_homogeneous<int64_t>());
|
||||
CHECK(!tbl["integers2"].as<array>()->is_homogeneous<double>());
|
||||
CHECK(tbl["integers2"].as<array>()->size() == 3);
|
||||
CHECK(tbl["integers2"][0] == 1);
|
||||
CHECK(tbl["integers2"][1] == 2);
|
||||
CHECK(tbl["integers2"][2] == 3);
|
||||
|
||||
REQUIRE(tbl["integers3"].as<array>());
|
||||
CHECK(tbl["integers3"].is_homogeneous());
|
||||
CHECK(tbl["integers3"].is_homogeneous(node_type::integer));
|
||||
CHECK(!tbl["integers3"].is_homogeneous(node_type::floating_point));
|
||||
CHECK(tbl["integers3"].is_homogeneous<int64_t>());
|
||||
CHECK(!tbl["integers3"].is_homogeneous<double>());
|
||||
CHECK(tbl["integers3"].as<array>()->is_homogeneous());
|
||||
CHECK(tbl["integers3"].as<array>()->is_homogeneous(node_type::integer));
|
||||
CHECK(!tbl["integers3"].as<array>()->is_homogeneous(node_type::floating_point));
|
||||
CHECK(tbl["integers3"].as<array>()->is_homogeneous<int64_t>());
|
||||
CHECK(!tbl["integers3"].as<array>()->is_homogeneous<double>());
|
||||
CHECK(tbl["integers3"].as<array>()->size() == 2);
|
||||
CHECK(tbl["integers3"][0] == 1);
|
||||
CHECK(tbl["integers3"][1] == 2);
|
||||
|
||||
REQUIRE(tbl["colors"].as<array>());
|
||||
CHECK(tbl["colors"].is_homogeneous());
|
||||
CHECK(tbl["colors"].is_homogeneous(node_type::string));
|
||||
CHECK(!tbl["colors"].is_homogeneous(node_type::floating_point));
|
||||
CHECK(tbl["colors"].is_homogeneous<std::string>());
|
||||
CHECK(!tbl["colors"].is_homogeneous<double>());
|
||||
CHECK(tbl["colors"].as<array>()->is_homogeneous());
|
||||
CHECK(tbl["colors"].as<array>()->is_homogeneous(node_type::string));
|
||||
CHECK(!tbl["colors"].as<array>()->is_homogeneous(node_type::floating_point));
|
||||
CHECK(tbl["colors"].as<array>()->is_homogeneous<std::string>());
|
||||
CHECK(!tbl["colors"].as<array>()->is_homogeneous<double>());
|
||||
CHECK(tbl["colors"].as<array>()->size() == 3);
|
||||
CHECK(tbl["colors"][0] == "red"sv);
|
||||
CHECK(tbl["colors"][1] == "yellow"sv);
|
||||
|
@ -5,8 +5,6 @@
|
||||
|
||||
#include "tests.h"
|
||||
|
||||
TOML_DISABLE_ARITHMETIC_WARNINGS
|
||||
|
||||
TEST_CASE("parsing - floats")
|
||||
{
|
||||
parsing_should_succeed(
|
||||
|
@ -18,15 +18,15 @@
|
||||
#include "../include/toml++/toml.h"
|
||||
#endif
|
||||
|
||||
TOML_DISABLE_ARITHMETIC_WARNINGS
|
||||
|
||||
TOML_PUSH_WARNINGS
|
||||
TOML_DISABLE_ALL_WARNINGS
|
||||
|
||||
#include "catch2.h"
|
||||
#include <sstream>
|
||||
namespace toml {}
|
||||
using namespace Catch::literals;
|
||||
using namespace toml;
|
||||
|
||||
TOML_POP_WARNINGS
|
||||
|
||||
#define FILE_LINE_ARGS std::string_view{ __FILE__ }, __LINE__
|
||||
@ -115,9 +115,6 @@ bool parsing_should_fail(
|
||||
uint32_t test_line,
|
||||
std::string_view toml_str);
|
||||
|
||||
TOML_PUSH_WARNINGS
|
||||
TOML_DISABLE_ARITHMETIC_WARNINGS
|
||||
|
||||
template <typename T>
|
||||
inline bool parse_expected_value(
|
||||
std::string_view test_file,
|
||||
@ -198,6 +195,28 @@ inline bool parse_expected_value(
|
||||
REQUIRE(nv.node()->as<value_type>());
|
||||
REQUIRE(nv.node()->type() == impl::node_type_of<T>);
|
||||
|
||||
// check homogeneity
|
||||
REQUIRE(nv.is_homogeneous());
|
||||
REQUIRE(nv.is_homogeneous(node_type::none));
|
||||
REQUIRE(nv.is_homogeneous(impl::node_type_of<T>));
|
||||
REQUIRE(nv.is_homogeneous<value_type>());
|
||||
REQUIRE(nv.node()->is_homogeneous());
|
||||
REQUIRE(nv.node()->is_homogeneous(node_type::none));
|
||||
REQUIRE(nv.node()->is_homogeneous(impl::node_type_of<T>));
|
||||
REQUIRE(nv.node()->is_homogeneous<value_type>());
|
||||
for (auto nt = impl::unwrap_enum(node_type::table); nt <= impl::unwrap_enum(node_type::date_time); nt++)
|
||||
{
|
||||
if (node_type{ nt } == impl::node_type_of<T>)
|
||||
continue;
|
||||
node* first_nonmatch{};
|
||||
REQUIRE(!nv.is_homogeneous(node_type{ nt }));
|
||||
REQUIRE(!nv.is_homogeneous(node_type{ nt }, first_nonmatch));
|
||||
REQUIRE(first_nonmatch == nv.node());
|
||||
REQUIRE(!nv.node()->is_homogeneous(node_type{ nt }));
|
||||
REQUIRE(!nv.node()->is_homogeneous(node_type{ nt }, first_nonmatch));
|
||||
REQUIRE(first_nonmatch == nv.node());
|
||||
}
|
||||
|
||||
// check the raw value
|
||||
REQUIRE(nv.node()->value<value_type>() == expected);
|
||||
REQUIRE(nv.node()->value_or(T{}) == expected);
|
||||
@ -305,5 +324,3 @@ namespace Catch
|
||||
extern template std::string stringify(const node_view<const node>&);
|
||||
}
|
||||
}
|
||||
|
||||
TOML_POP_WARNINGS // TOML_DISABLE_ARITHMETIC_WARNINGS
|
||||
|
@ -97,6 +97,9 @@ TEST_CASE("feedback - github/pull/50")
|
||||
REQUIRE(val->is_number());
|
||||
REQUIRE(val->is_integer());
|
||||
REQUIRE(val->ref<int64_t>() == 10);
|
||||
REQUIRE(val->value<int64_t>() == 10);
|
||||
REQUIRE(val->value_or(0) == 10);
|
||||
REQUIRE(val->value<double>() == 10.0);
|
||||
REQUIRE(val->value_or(0.0) == 10.0);
|
||||
}
|
||||
}
|
||||
|
429
toml.hpp
429
toml.hpp
@ -1066,6 +1066,7 @@ TOML_IMPL_NAMESPACE_START
|
||||
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<T>>>::value;
|
||||
|
||||
@ -1114,7 +1115,7 @@ TOML_IMPL_NAMESPACE_START
|
||||
[[nodiscard]]
|
||||
TOML_ATTR(const)
|
||||
TOML_ALWAYS_INLINE
|
||||
constexpr std::underlying_type_t<T> unbox_enum(T val) noexcept
|
||||
constexpr std::underlying_type_t<T> unwrap_enum(T val) noexcept
|
||||
{
|
||||
return static_cast<std::underlying_type_t<T>>(val);
|
||||
}
|
||||
@ -2180,6 +2181,23 @@ TOML_NAMESPACE_START
|
||||
[[nodiscard]] virtual const toml::value<date>* as_date() const noexcept;
|
||||
[[nodiscard]] virtual const toml::value<time>* as_time() const noexcept;
|
||||
[[nodiscard]] virtual const toml::value<date_time>* as_date_time() const noexcept;
|
||||
[[nodiscard]] virtual bool is_homogeneous(node_type ntype, node*& first_nonmatch) noexcept = 0;
|
||||
[[nodiscard]] virtual bool is_homogeneous(node_type ntype, const node*& first_nonmatch) const noexcept = 0;
|
||||
[[nodiscard]] virtual bool is_homogeneous(node_type ntype) const noexcept = 0;
|
||||
|
||||
template <typename ElemType = void>
|
||||
[[nodiscard]]
|
||||
bool is_homogeneous() const noexcept
|
||||
{
|
||||
using type = impl::unwrap_node<ElemType>;
|
||||
static_assert(
|
||||
std::is_void_v<type>
|
||||
|| ((impl::is_native<type> || impl::is_one_of<type, table, array>) && !impl::is_cvref<type>),
|
||||
"The template type argument of node::is_homogeneous() must be void or one of:"
|
||||
TOML_SA_UNWRAPPED_NODE_TYPE_LIST
|
||||
);
|
||||
return is_homogeneous(impl::node_type_of<type>);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@ -2205,6 +2223,14 @@ TOML_NAMESPACE_START
|
||||
[[nodiscard]]
|
||||
auto value_or(T&& default_value) const noexcept;
|
||||
|
||||
//template <typename T>
|
||||
//[[nodiscard]]
|
||||
//std::vector<T> select_exact() const noexcept;
|
||||
|
||||
//template <typename T>
|
||||
//[[nodiscard]]
|
||||
//std::vector<T> select() const noexcept;
|
||||
|
||||
template <typename T>
|
||||
[[nodiscard]]
|
||||
impl::wrap_node<T>* as() noexcept
|
||||
@ -2474,6 +2500,65 @@ TOML_POP_WARNINGS // TOML_DISABLE_PADDING_WARNINGS, TOML_DISABLE_MISC_WARNINGS
|
||||
//------------------------------------------ ↓ toml_value.h ----------------------------------------------------------
|
||||
#if 1
|
||||
|
||||
#ifndef DOXYGEN
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
#define TOML_SA_VALUE_MESSAGE_WSTRING TOML_SA_LIST_SEP "std::wstring"
|
||||
#else
|
||||
#define TOML_SA_VALUE_MESSAGE_WSTRING
|
||||
#endif
|
||||
|
||||
#ifdef __cpp_lib_char8_t
|
||||
#define TOML_SA_VALUE_MESSAGE_U8STRING_VIEW TOML_SA_LIST_SEP "std::u8string_view"
|
||||
#define TOML_SA_VALUE_MESSAGE_CONST_CHAR8 TOML_SA_LIST_SEP "const char8_t*"
|
||||
#else
|
||||
#define TOML_SA_VALUE_MESSAGE_U8STRING_VIEW
|
||||
#define TOML_SA_VALUE_MESSAGE_CONST_CHAR8
|
||||
#endif
|
||||
|
||||
#define TOML_SA_VALUE_EXACT_FUNC_MESSAGE(type_arg) \
|
||||
"The " type_arg " must be one of:" \
|
||||
TOML_SA_LIST_NEW "A native TOML value type" \
|
||||
TOML_SA_NATIVE_VALUE_TYPE_LIST \
|
||||
\
|
||||
TOML_SA_LIST_NXT "A non-view type capable of losslessly representing a native TOML value type" \
|
||||
TOML_SA_LIST_BEG "std::string" \
|
||||
TOML_SA_VALUE_MESSAGE_WSTRING \
|
||||
TOML_SA_LIST_SEP "any signed integer type >= 64 bits" \
|
||||
TOML_SA_LIST_SEP "any floating-point type >= 64 bits" \
|
||||
TOML_SA_LIST_END \
|
||||
\
|
||||
TOML_SA_LIST_NXT "An immutable view type not requiring additional temporary storage" \
|
||||
TOML_SA_LIST_BEG "std::string_view" \
|
||||
TOML_SA_VALUE_MESSAGE_U8STRING_VIEW \
|
||||
TOML_SA_LIST_SEP "const char*" \
|
||||
TOML_SA_VALUE_MESSAGE_CONST_CHAR8 \
|
||||
TOML_SA_LIST_END
|
||||
|
||||
#define TOML_SA_VALUE_FUNC_MESSAGE(type_arg) \
|
||||
"The " type_arg " must be one of:" \
|
||||
TOML_SA_LIST_NEW "A native TOML value type" \
|
||||
TOML_SA_NATIVE_VALUE_TYPE_LIST \
|
||||
\
|
||||
TOML_SA_LIST_NXT "A non-view type capable of losslessly representing a native TOML value type" \
|
||||
TOML_SA_LIST_BEG "std::string" \
|
||||
TOML_SA_VALUE_MESSAGE_WSTRING \
|
||||
TOML_SA_LIST_SEP "any signed integer type >= 64 bits" \
|
||||
TOML_SA_LIST_SEP "any floating-point type >= 64 bits" \
|
||||
TOML_SA_LIST_END \
|
||||
\
|
||||
TOML_SA_LIST_NXT "A non-view type capable of (reasonably) representing a native TOML value type" \
|
||||
TOML_SA_LIST_BEG "any other integer type" \
|
||||
TOML_SA_LIST_SEP "any floating-point type >= 32 bits" \
|
||||
TOML_SA_LIST_END \
|
||||
\
|
||||
TOML_SA_LIST_NXT "An immutable view type not requiring additional temporary storage" \
|
||||
TOML_SA_LIST_BEG "std::string_view" \
|
||||
TOML_SA_VALUE_MESSAGE_U8STRING_VIEW \
|
||||
TOML_SA_LIST_SEP "const char*" \
|
||||
TOML_SA_VALUE_MESSAGE_CONST_CHAR8 \
|
||||
TOML_SA_LIST_END
|
||||
#endif // !DOXYGEN
|
||||
|
||||
TOML_PUSH_WARNINGS
|
||||
TOML_DISABLE_ARITHMETIC_WARNINGS
|
||||
TOML_DISABLE_PADDING_WARNINGS
|
||||
@ -2674,6 +2759,49 @@ TOML_NAMESPACE_START
|
||||
[[nodiscard]] const value<date>* as_date() const noexcept override { return as_value<date>(this); }
|
||||
[[nodiscard]] const value<time>* as_time() const noexcept override { return as_value<time>(this); }
|
||||
[[nodiscard]] const value<date_time>* as_date_time() const noexcept override { return as_value<date_time>(this); }
|
||||
[[nodiscard]]
|
||||
bool is_homogeneous(node_type ntype) const noexcept override
|
||||
{
|
||||
return ntype == node_type::none || ntype == impl::node_type_of<value_type>;
|
||||
}
|
||||
[[nodiscard]]
|
||||
bool is_homogeneous(node_type ntype, toml::node*& first_nonmatch) noexcept override
|
||||
{
|
||||
if (ntype != node_type::none && ntype != impl::node_type_of<value_type>)
|
||||
{
|
||||
first_nonmatch = this;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
[[nodiscard]]
|
||||
bool is_homogeneous(node_type ntype, const toml::node*& first_nonmatch) const noexcept override
|
||||
{
|
||||
if (ntype != node_type::none && ntype != impl::node_type_of<value_type>)
|
||||
{
|
||||
first_nonmatch = this;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
template <typename ElemType = void>
|
||||
[[nodiscard]]
|
||||
bool is_homogeneous() const noexcept
|
||||
{
|
||||
using type = impl::unwrap_node<ElemType>;
|
||||
static_assert(
|
||||
std::is_void_v<type>
|
||||
|| ((impl::is_native<type> || impl::is_one_of<type, table, array>) && !impl::is_cvref<type>),
|
||||
"The template type argument of value::is_homogeneous() must be void or one of:"
|
||||
TOML_SA_UNWRAPPED_NODE_TYPE_LIST
|
||||
);
|
||||
|
||||
using type = impl::unwrap_node<ElemType>;
|
||||
if constexpr (std::is_void_v<type>)
|
||||
return true;
|
||||
else
|
||||
return impl::node_type_of<type> == impl::node_type_of<value_type>;
|
||||
}
|
||||
|
||||
[[nodiscard]] value_type& get() & noexcept { return val_; }
|
||||
[[nodiscard]] value_type&& get() && noexcept { return std::move(val_); }
|
||||
@ -2713,8 +2841,8 @@ TOML_NAMESPACE_START
|
||||
using namespace impl;
|
||||
static constexpr auto pack = [](auto l, auto r) constexpr noexcept
|
||||
{
|
||||
return (static_cast<uint64_t>(unbox_enum(l)) << 32)
|
||||
| static_cast<uint64_t>(unbox_enum(r));
|
||||
return (static_cast<uint64_t>(unwrap_enum(l)) << 32)
|
||||
| static_cast<uint64_t>(unwrap_enum(r));
|
||||
};
|
||||
|
||||
switch (pack(impl::fpclassify(lhs.val_), impl::fpclassify(rhs)))
|
||||
@ -2815,6 +2943,9 @@ TOML_NAMESPACE_START
|
||||
value(T) -> value<impl::native_type_of<impl::remove_cvref_t<T>>>;
|
||||
|
||||
#ifndef DOXYGEN
|
||||
TOML_PUSH_WARNINGS
|
||||
TOML_DISABLE_INIT_WARNINGS
|
||||
TOML_DISABLE_SWITCH_WARNINGS
|
||||
|
||||
#if !TOML_HEADER_ONLY
|
||||
extern template class TOML_API value<std::string>;
|
||||
@ -2826,10 +2957,6 @@ TOML_NAMESPACE_START
|
||||
extern template class TOML_API value<date_time>;
|
||||
#endif
|
||||
|
||||
TOML_PUSH_WARNINGS
|
||||
TOML_DISABLE_INIT_WARNINGS
|
||||
TOML_DISABLE_SWITCH_WARNINGS
|
||||
|
||||
template <typename T>
|
||||
[[nodiscard]]
|
||||
inline decltype(auto) node::get_value_exact() const noexcept
|
||||
@ -2891,29 +3018,7 @@ TOML_NAMESPACE_START
|
||||
|
||||
static_assert(
|
||||
(is_native<T> || can_represent_native<T>) && !is_cvref<T>,
|
||||
"The return type of node::value_exact() must be one of:"
|
||||
TOML_SA_LIST_NEW "A native TOML value type"
|
||||
TOML_SA_NATIVE_VALUE_TYPE_LIST
|
||||
|
||||
TOML_SA_LIST_NXT "A non-view type capable of losslessly representing a native TOML value type"
|
||||
TOML_SA_LIST_BEG "std::string"
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
TOML_SA_LIST_SEP "std::wstring"
|
||||
#endif
|
||||
TOML_SA_LIST_SEP "any signed integer type >= 64 bits"
|
||||
TOML_SA_LIST_SEP "any floating-point type >= 64 bits"
|
||||
TOML_SA_LIST_END
|
||||
|
||||
TOML_SA_LIST_NXT "An immutable view type not requiring additional temporary storage"
|
||||
TOML_SA_LIST_BEG "std::string_view"
|
||||
#ifdef __cpp_lib_char8_t
|
||||
TOML_SA_LIST_SEP "std::u8string_view"
|
||||
#endif
|
||||
TOML_SA_LIST_SEP "const char*"
|
||||
#ifdef __cpp_lib_char8_t
|
||||
TOML_SA_LIST_SEP "const char8_t*"
|
||||
#endif
|
||||
TOML_SA_LIST_END
|
||||
TOML_SA_VALUE_EXACT_FUNC_MESSAGE("return type of node::value_exact()")
|
||||
);
|
||||
|
||||
// prevent additional compiler error spam when the static_assert fails by gating behind if constexpr
|
||||
@ -2938,34 +3043,7 @@ TOML_NAMESPACE_START
|
||||
);
|
||||
static_assert(
|
||||
(is_native<T> || can_represent_native<T> || can_partially_represent_native<T>) && !is_cvref<T>,
|
||||
"The return type of node::value() must be one of:"
|
||||
TOML_SA_LIST_NEW "A native TOML value type"
|
||||
TOML_SA_NATIVE_VALUE_TYPE_LIST
|
||||
|
||||
TOML_SA_LIST_NXT "A non-view type capable of losslessly representing a native TOML value type"
|
||||
TOML_SA_LIST_BEG "std::string"
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
TOML_SA_LIST_SEP "std::wstring"
|
||||
#endif
|
||||
TOML_SA_LIST_SEP "any signed integer type >= 64 bits"
|
||||
TOML_SA_LIST_SEP "any floating-point type >= 64 bits"
|
||||
TOML_SA_LIST_END
|
||||
|
||||
TOML_SA_LIST_NXT "A non-view type capable of (reasonably) representing a native TOML value type"
|
||||
TOML_SA_LIST_BEG "any other integer type"
|
||||
TOML_SA_LIST_SEP "any floating-point type >= 32 bits"
|
||||
TOML_SA_LIST_END
|
||||
|
||||
TOML_SA_LIST_NXT "An immutable view type not requiring additional temporary storage"
|
||||
TOML_SA_LIST_BEG "std::string_view"
|
||||
#ifdef __cpp_lib_char8_t
|
||||
TOML_SA_LIST_SEP "std::u8string_view"
|
||||
#endif
|
||||
TOML_SA_LIST_SEP "const char*"
|
||||
#ifdef __cpp_lib_char8_t
|
||||
TOML_SA_LIST_SEP "const char8_t*"
|
||||
#endif
|
||||
TOML_SA_LIST_END
|
||||
TOML_SA_VALUE_FUNC_MESSAGE("return type of node::value()")
|
||||
);
|
||||
|
||||
// when asking for strings, dates, times and date_times there's no 'fuzzy' conversion
|
||||
@ -3107,7 +3185,7 @@ TOML_NAMESPACE_START
|
||||
|
||||
static_assert(
|
||||
traits::is_native || traits::can_represent_native || traits::can_partially_represent_native,
|
||||
"The default return value type of node::value_or() must be one of:"
|
||||
"The default value type of node::value_or() must be one of:"
|
||||
TOML_SA_LIST_NEW "A native TOML value type"
|
||||
TOML_SA_NATIVE_VALUE_TYPE_LIST
|
||||
|
||||
@ -3146,6 +3224,11 @@ TOML_NAMESPACE_START
|
||||
// prevent additional compiler error spam when the static_assert fails by gating behind if constexpr
|
||||
if constexpr (traits::is_native || traits::can_represent_native || traits::can_partially_represent_native)
|
||||
{
|
||||
if constexpr (traits::is_native)
|
||||
{
|
||||
if (type() == node_type_of<value_type>)
|
||||
return *ref_cast<typename traits::native_type>();
|
||||
}
|
||||
if (auto val = this->value<value_type>())
|
||||
return *val;
|
||||
if constexpr (std::is_pointer_v<value_type>)
|
||||
@ -3205,7 +3288,6 @@ TOML_NAMESPACE_START
|
||||
#endif // !TOML_HEADER_ONLY
|
||||
|
||||
TOML_POP_WARNINGS // TOML_DISABLE_INIT_WARNINGS, TOML_DISABLE_SWITCH_WARNINGS
|
||||
|
||||
#endif // !DOXYGEN
|
||||
}
|
||||
TOML_NAMESPACE_END
|
||||
@ -3523,8 +3605,10 @@ TOML_NAMESPACE_START
|
||||
[[nodiscard]] bool is_value() const noexcept override;
|
||||
[[nodiscard]] array* as_array() noexcept override;
|
||||
[[nodiscard]] const array* as_array() const noexcept override;
|
||||
[[nodiscard]] bool is_homogeneous(node_type type) const noexcept;
|
||||
|
||||
[[nodiscard]] bool is_array_of_tables() 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, const node*& first_nonmatch) const noexcept override;
|
||||
template <typename ElemType = void>
|
||||
[[nodiscard]]
|
||||
bool is_homogeneous() const noexcept
|
||||
@ -3536,14 +3620,9 @@ TOML_NAMESPACE_START
|
||||
"The template type argument of array::is_homogeneous() must be void or one of:"
|
||||
TOML_SA_UNWRAPPED_NODE_TYPE_LIST
|
||||
);
|
||||
|
||||
if constexpr (std::is_void_v<type>)
|
||||
return is_homogeneous(node_type::none);
|
||||
else
|
||||
return is_homogeneous(impl::node_type_of<type>);
|
||||
return is_homogeneous(impl::node_type_of<type>);
|
||||
}
|
||||
|
||||
[[nodiscard]] bool is_array_of_tables() const noexcept override;
|
||||
[[nodiscard]] node& operator[] (size_t index) noexcept;
|
||||
[[nodiscard]] const node& operator[] (size_t index) const noexcept;
|
||||
[[nodiscard]] node& front() noexcept;
|
||||
@ -4024,6 +4103,23 @@ TOML_NAMESPACE_START
|
||||
[[nodiscard]] bool is_value() const noexcept override;
|
||||
[[nodiscard]] table* as_table() noexcept override;
|
||||
[[nodiscard]] const table* as_table() 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, const node*& first_nonmatch) const noexcept override;
|
||||
template <typename ElemType = void>
|
||||
[[nodiscard]]
|
||||
bool is_homogeneous() const noexcept
|
||||
{
|
||||
using type = impl::unwrap_node<ElemType>;
|
||||
static_assert(
|
||||
std::is_void_v<type>
|
||||
|| ((impl::is_native<type> || impl::is_one_of<type, table, array>) && !impl::is_cvref<type>),
|
||||
"The template type argument of table::is_homogeneous() must be void or one of:"
|
||||
TOML_SA_UNWRAPPED_NODE_TYPE_LIST
|
||||
);
|
||||
return is_homogeneous(impl::node_type_of<type>);
|
||||
}
|
||||
|
||||
[[nodiscard]] bool is_inline() const noexcept;
|
||||
void is_inline(bool val) noexcept;
|
||||
[[nodiscard]] node_view<node> operator[] (std::string_view key) noexcept;
|
||||
@ -4289,6 +4385,43 @@ TOML_NAMESPACE_START
|
||||
template <typename Char>
|
||||
friend std::basic_ostream<Char>& operator << (std::basic_ostream<Char>&, const table&);
|
||||
};
|
||||
|
||||
#ifndef DOXYGEN
|
||||
|
||||
//template <typename T>
|
||||
//inline std::vector<T> node::select_exact() const noexcept
|
||||
//{
|
||||
// using namespace impl;
|
||||
|
||||
// static_assert(
|
||||
// !is_wide_string<T> || TOML_WINDOWS_COMPAT,
|
||||
// "Retrieving values as wide-character strings with node::select_exact() is only "
|
||||
// "supported on Windows with TOML_WINDOWS_COMPAT enabled."
|
||||
// );
|
||||
|
||||
// static_assert(
|
||||
// (is_native<T> || can_represent_native<T>) && !is_cvref<T>,
|
||||
// TOML_SA_VALUE_EXACT_FUNC_MESSAGE("return type of node::select_exact()")
|
||||
// );
|
||||
//}
|
||||
|
||||
//template <typename T>
|
||||
//inline std::vector<T> node::select() const noexcept
|
||||
//{
|
||||
// using namespace impl;
|
||||
|
||||
// static_assert(
|
||||
// !is_wide_string<T> || TOML_WINDOWS_COMPAT,
|
||||
// "Retrieving values as wide-character strings with node::select() is only "
|
||||
// "supported on Windows with TOML_WINDOWS_COMPAT enabled."
|
||||
// );
|
||||
// static_assert(
|
||||
// (is_native<T> || can_represent_native<T> || can_partially_represent_native<T>) && !is_cvref<T>,
|
||||
// TOML_SA_VALUE_FUNC_MESSAGE("return type of node::select()")
|
||||
// );
|
||||
//}
|
||||
|
||||
#endif // !DOXYGEN
|
||||
}
|
||||
TOML_NAMESPACE_END
|
||||
|
||||
@ -4383,6 +4516,29 @@ TOML_NAMESPACE_START
|
||||
[[nodiscard]] auto as_date() const noexcept { return as<date>(); }
|
||||
[[nodiscard]] auto as_time() const noexcept { return as<time>(); }
|
||||
[[nodiscard]] auto as_date_time() const noexcept { return as<date_time>(); }
|
||||
[[nodiscard]]
|
||||
bool is_homogeneous(node_type ntype, viewed_type*& first_nonmatch) const noexcept
|
||||
{
|
||||
if (!node_)
|
||||
{
|
||||
first_nonmatch = {};
|
||||
return false;
|
||||
}
|
||||
return node_->is_homogeneous(ntype, first_nonmatch);
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
bool is_homogeneous(node_type ntype) const noexcept
|
||||
{
|
||||
return node_ ? node_->is_homogeneous(ntype) : false;
|
||||
}
|
||||
|
||||
template <typename ElemType = void>
|
||||
[[nodiscard]]
|
||||
bool is_homogeneous() const noexcept
|
||||
{
|
||||
return node_ ? node_->template is_homogeneous<impl::unwrap_node<ElemType>>() : false;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
[[nodiscard]]
|
||||
@ -5656,7 +5812,7 @@ TOML_NAMESPACE_START
|
||||
TOML_ATTR(flatten)
|
||||
constexpr format_flags operator & (format_flags lhs, format_flags rhs) noexcept
|
||||
{
|
||||
return static_cast<format_flags>(impl::unbox_enum(lhs) & impl::unbox_enum(rhs));
|
||||
return static_cast<format_flags>(impl::unwrap_enum(lhs) & impl::unwrap_enum(rhs));
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
@ -5665,7 +5821,7 @@ TOML_NAMESPACE_START
|
||||
TOML_ATTR(flatten)
|
||||
constexpr format_flags operator | (format_flags lhs, format_flags rhs) noexcept
|
||||
{
|
||||
return static_cast<format_flags>( impl::unbox_enum(lhs) | impl::unbox_enum(rhs) );
|
||||
return static_cast<format_flags>( impl::unwrap_enum(lhs) | impl::unwrap_enum(rhs) );
|
||||
}
|
||||
}
|
||||
TOML_NAMESPACE_END
|
||||
@ -7484,6 +7640,58 @@ TOML_NAMESPACE_START
|
||||
|
||||
#undef TOML_MEMBER_ATTR
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
bool array::is_homogeneous(node_type ntype) const noexcept
|
||||
{
|
||||
if (elements.empty())
|
||||
return false;
|
||||
|
||||
if (ntype == node_type::none)
|
||||
ntype = elements[0]->type();
|
||||
|
||||
for (const auto& val : elements)
|
||||
if (val->type() != ntype)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
namespace impl
|
||||
{
|
||||
template <typename T, typename U>
|
||||
TOML_INTERNAL_LINKAGE
|
||||
bool array_is_homogeneous(T& elements, node_type ntype, U& first_nonmatch) noexcept
|
||||
{
|
||||
if (elements.empty())
|
||||
{
|
||||
first_nonmatch = {};
|
||||
return false;
|
||||
}
|
||||
if (ntype == node_type::none)
|
||||
ntype = elements[0]->type();
|
||||
for (const auto& val : elements)
|
||||
{
|
||||
if (val->type() != ntype)
|
||||
{
|
||||
first_nonmatch = val.get();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
bool array::is_homogeneous(node_type ntype, toml::node*& first_nonmatch) noexcept
|
||||
{
|
||||
return impl::array_is_homogeneous(elements, ntype, first_nonmatch);
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
bool array::is_homogeneous(node_type ntype, const toml::node*& first_nonmatch) const noexcept
|
||||
{
|
||||
return impl::array_is_homogeneous(elements, ntype, first_nonmatch);
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
void array::truncate(size_t new_size)
|
||||
{
|
||||
@ -7634,21 +7842,6 @@ TOML_NAMESPACE_START
|
||||
return *this;
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
bool array::is_homogeneous(node_type type) const noexcept
|
||||
{
|
||||
if (elements.empty())
|
||||
return false;
|
||||
|
||||
if (type == node_type::none)
|
||||
type = elements[0]->type();
|
||||
|
||||
for (const auto& val : elements)
|
||||
if (val->type() != type)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
bool array::is_array_of_tables() const noexcept
|
||||
{
|
||||
@ -7755,6 +7948,63 @@ TOML_NAMESPACE_START
|
||||
|
||||
#undef TOML_MEMBER_ATTR
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
bool table::is_homogeneous(node_type ntype) const noexcept
|
||||
{
|
||||
if (map.empty())
|
||||
return false;
|
||||
|
||||
if (ntype == node_type::none)
|
||||
ntype = map.cbegin()->second->type();
|
||||
|
||||
for (const auto& [k, v] : map)
|
||||
{
|
||||
(void)k;
|
||||
if (v->type() != ntype)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
namespace impl
|
||||
{
|
||||
template <typename T, typename U>
|
||||
TOML_INTERNAL_LINKAGE
|
||||
bool table_is_homogeneous(T& map, node_type ntype, U& first_nonmatch) noexcept
|
||||
{
|
||||
if (map.empty())
|
||||
{
|
||||
first_nonmatch = {};
|
||||
return false;
|
||||
}
|
||||
if (ntype == node_type::none)
|
||||
ntype = map.cbegin()->second->type();
|
||||
for (const auto& [k, v] : map)
|
||||
{
|
||||
(void)k;
|
||||
if (v->type() != ntype)
|
||||
{
|
||||
first_nonmatch = v.get();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
bool table::is_homogeneous(node_type ntype, toml::node*& first_nonmatch) noexcept
|
||||
{
|
||||
return impl::table_is_homogeneous(map, ntype, first_nonmatch);
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
bool table::is_homogeneous(node_type ntype, const toml::node*& first_nonmatch) const noexcept
|
||||
{
|
||||
return impl::table_is_homogeneous(map, ntype, first_nonmatch);
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
node_view<node> table::operator[] (std::string_view key) noexcept
|
||||
{
|
||||
@ -8415,7 +8665,7 @@ TOML_ANON_NAMESPACE_START
|
||||
{
|
||||
using namespace ::toml::impl;
|
||||
|
||||
return node_type_friendly_names[unbox_enum(val)];
|
||||
return node_type_friendly_names[unwrap_enum(val)];
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
@ -10398,7 +10648,7 @@ TOML_IMPL_NAMESPACE_START
|
||||
// all correct value parses will come out of this list, so doing this as a switch is likely to
|
||||
// be a better friend to the optimizer on the success path (failure path can be slow but that
|
||||
// doesn't matter much).
|
||||
switch (unbox_enum(traits))
|
||||
switch (unwrap_enum(traits))
|
||||
{
|
||||
//=================== binary integers
|
||||
// 0b10
|
||||
@ -11585,6 +11835,11 @@ TOML_NAMESPACE_END
|
||||
#undef TOML_SA_NEWLINE
|
||||
#undef TOML_SA_NODE_TYPE_LIST
|
||||
#undef TOML_SA_UNWRAPPED_NODE_TYPE_LIST
|
||||
#undef TOML_SA_VALUE_EXACT_FUNC_MESSAGE
|
||||
#undef TOML_SA_VALUE_FUNC_MESSAGE
|
||||
#undef TOML_SA_VALUE_MESSAGE_CONST_CHAR8
|
||||
#undef TOML_SA_VALUE_MESSAGE_U8STRING_VIEW
|
||||
#undef TOML_SA_VALUE_MESSAGE_WSTRING
|
||||
#undef TOML_SIMPLE_STATIC_ASSERT_MESSAGES
|
||||
#undef TOML_TRIVIAL_ABI
|
||||
#undef TOML_UINT128
|
||||
|
Loading…
Reference in New Issue
Block a user