minor cleanup

This commit is contained in:
Mark Gillard 2021-11-07 22:33:02 +02:00
parent 76e681da4d
commit 9783a94ed4
8 changed files with 224 additions and 264 deletions

View File

@ -632,6 +632,84 @@ TOML_NAMESPACE_START
/// \name Array operations
/// @{
/// \brief Gets a pointer to the element at a specific index.
///
/// \detail \cpp
/// auto arr = toml::array{ 99, "bottles of beer on the wall" };
/// std::cout << "element [0] exists: "sv << !!arr.get(0) << "\n";
/// std::cout << "element [1] exists: "sv << !!arr.get(1) << "\n";
/// std::cout << "element [2] exists: "sv << !!arr.get(2) << "\n";
/// if (toml::node* val = arr.get(0))
/// std::cout << "element [0] is an "sv << val->type() << "\n";
///
/// \ecpp
///
/// \out
/// element [0] exists: true
/// element [1] exists: true
/// element [2] exists: false
/// element [0] is an integer
/// \eout
///
/// \param index The element's index.
///
/// \returns A pointer to the element at the specified index if one existed, or nullptr.
TOML_PURE_INLINE_GETTER
node* get(size_t index) noexcept
{
return index < elems_.size() ? elems_[index].get() : nullptr;
}
/// \brief Gets a pointer to the element at a specific index (const overload).
///
/// \param index The element's index.
///
/// \returns A pointer to the element at the specified index if one existed, or nullptr.
TOML_PURE_INLINE_GETTER
const node* get(size_t index) const noexcept
{
return const_cast<array&>(*this).get(index);
}
/// \brief Gets a pointer to the element at a specific index if it is a particular type.
///
/// \detail \cpp
/// auto arr = toml::array{ 42, "is the meaning of life, apparently."sv };
/// if (toml::value<int64_t>* val = arr.get_as<int64_t>(0))
/// std::cout << "element [0] is an integer with value "sv << *val << "\n";
///
/// \ecpp
///
/// \out
/// element [0] is an integer with value 42
/// \eout
///
/// \tparam ElemType toml::table, toml::array, or a native TOML value type
/// \param index The element's index.
///
/// \returns A pointer to the selected element if it existed and was of the specified type, or nullptr.
template <typename ElemType>
TOML_NODISCARD
impl::wrap_node<ElemType>* get_as(size_t index) noexcept
{
if (auto val = get(index))
return val->template as<ElemType>();
return nullptr;
}
/// \brief Gets a pointer to the element at a specific index if it is a particular type (const overload).
///
/// \tparam ElemType toml::table, toml::array, or a native TOML value type
/// \param index The element's index.
///
/// \returns A pointer to the selected element if it existed and was of the specified type, or nullptr.
template <typename ElemType>
TOML_NODISCARD
const impl::wrap_node<ElemType>* get_as(size_t index) const noexcept
{
return const_cast<array&>(*this).template get_as<ElemType>(index);
}
/// \brief Gets a reference to the element at a specific index.
TOML_NODISCARD
node& operator[](size_t index) noexcept
@ -646,28 +724,18 @@ TOML_NAMESPACE_START
return *elems_[index];
}
#if TOML_COMPILER_EXCEPTIONS
/// \brief Gets a reference to the element at a specific index, throwing `std::out_of_range` if none existed.
///
/// \availability This function is only available if you compile with exceptions enabled.
TOML_NODISCARD
node& at(size_t index)
{
return *elems_.at(index);
}
TOML_API
node& at(size_t index);
/// \brief Gets a reference to the element at a specific index, throwing `std::out_of_range` if none existed.
///
/// \availability This function is only available if you compile with exceptions enabled.
TOML_NODISCARD
const node& at(size_t index) const
{
return *elems_.at(index);
return const_cast<array&>(*this).at(index);
}
#endif // TOML_COMPILER_EXCEPTIONS
/// \brief Returns a reference to the first element in the array.
TOML_NODISCARD
node& front() noexcept
@ -1228,86 +1296,6 @@ TOML_NAMESPACE_START
elems_.pop_back();
}
/// \brief Gets the element at a specific index.
///
/// \detail \cpp
/// auto arr = toml::array{ 99, "bottles of beer on the wall" };
/// std::cout << "element [0] exists: "sv << !!arr.get(0) << "\n";
/// std::cout << "element [1] exists: "sv << !!arr.get(1) << "\n";
/// std::cout << "element [2] exists: "sv << !!arr.get(2) << "\n";
/// if (toml::node* val = arr.get(0))
/// std::cout << "element [0] is an "sv << val->type() << "\n";
///
/// \ecpp
///
/// \out
/// element [0] exists: true
/// element [1] exists: true
/// element [2] exists: false
/// element [0] is an integer
/// \eout
///
/// \param index The element's index.
///
/// \returns A pointer to the element at the specified index if one existed, or nullptr.
TOML_NODISCARD
node* get(size_t index) noexcept
{
return index < elems_.size() ? elems_[index].get() : nullptr;
}
/// \brief Gets the element at a specific index (const overload).
///
/// \param index The element's index.
///
/// \returns A pointer to the element at the specified index if one existed, or nullptr.
TOML_NODISCARD
const node* get(size_t index) const noexcept
{
return index < elems_.size() ? elems_[index].get() : nullptr;
}
/// \brief Gets the element at a specific index if it is a particular type.
///
/// \detail \cpp
/// auto arr = toml::array{ 42, "is the meaning of life, apparently."sv };
/// if (toml::value<int64_t>* val = arr.get_as<int64_t>(0))
/// std::cout << "element [0] is an integer with value "sv << *val << "\n";
///
/// \ecpp
///
/// \out
/// element [0] is an integer with value 42
/// \eout
///
/// \tparam ElemType toml::table, toml::array, or a native TOML value type
/// \param index The element's index.
///
/// \returns A pointer to the selected element if it existed and was of the specified type, or nullptr.
template <typename ElemType>
TOML_NODISCARD
impl::wrap_node<ElemType>* get_as(size_t index) noexcept
{
if (auto val = get(index))
return val->as<ElemType>();
return nullptr;
}
/// \brief Gets the element at a specific index if it is a particular type (const overload).
///
/// \tparam ElemType toml::table, toml::array, or a native TOML value type
/// \param index The element's index.
///
/// \returns A pointer to the selected element if it existed and was of the specified type, or nullptr.
template <typename ElemType>
TOML_NODISCARD
const impl::wrap_node<ElemType>* get_as(size_t index) const noexcept
{
if (auto val = get(index))
return val->as<ElemType>();
return nullptr;
}
/// \brief Flattens this array, recursively hoisting the contents of child arrays up into itself.
///
/// \detail \cpp

View File

@ -14,32 +14,6 @@
#include "array.h"
#include "header_start.h"
TOML_ANON_NAMESPACE_START
{
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_ANON_NAMESPACE_END;
TOML_NAMESPACE_START
{
TOML_EXTERNAL_LINKAGE
@ -125,13 +99,47 @@ TOML_NAMESPACE_START
TOML_EXTERNAL_LINKAGE
bool array::is_homogeneous(node_type ntype, node * &first_nonmatch) noexcept
{
return TOML_ANON_NAMESPACE::array_is_homogeneous(elems_, ntype, first_nonmatch);
if (elems_.empty())
{
first_nonmatch = {};
return false;
}
if (ntype == node_type::none)
ntype = elems_[0]->type();
for (const auto& val : elems_)
{
if (val->type() != ntype)
{
first_nonmatch = val.get();
return false;
}
}
return true;
}
TOML_EXTERNAL_LINKAGE
bool array::is_homogeneous(node_type ntype, const node*& first_nonmatch) const noexcept
{
return TOML_ANON_NAMESPACE::array_is_homogeneous(elems_, ntype, first_nonmatch);
node* fnm = nullptr;
const auto result = const_cast<array&>(*this).is_homogeneous(ntype, fnm);
first_nonmatch = fnm;
return result;
}
TOML_EXTERNAL_LINKAGE
node& array::at(size_t index)
{
#if TOML_COMPILER_EXCEPTIONS
return *elems_.at(index);
#else
auto n = get(index);
TOML_ASSERT(n && "element index not found in array!");
return *n;
#endif
}
TOML_EXTERNAL_LINKAGE

View File

@ -672,8 +672,10 @@ TOML_NAMESPACE_START
///
/// \returns A pointer to the node at the specified key, or nullptr.
TOML_NODISCARD
TOML_API
node* get(std::wstring_view key);
node* get(std::wstring_view key)
{
return get(impl::narrow(key));
}
/// \brief Gets the node at a specific key (const overload).
///
@ -765,18 +767,12 @@ TOML_NAMESPACE_START
#endif // TOML_ENABLE_WINDOWS_COMPAT
#if TOML_COMPILER_EXCEPTIONS
/// \brief Gets a reference to the element at a specific key, throwing `std::out_of_range` if none existed.
///
/// \availability This function is only available if you compile with exceptions enabled.
TOML_NODISCARD
TOML_API
node& at(std::string_view key);
/// \brief Gets a reference to the element at a specific key, throwing `std::out_of_range` if none existed.
///
/// \availability This function is only available if you compile with exceptions enabled.
TOML_NODISCARD
const node& at(std::string_view key) const
{
@ -787,14 +783,16 @@ TOML_NAMESPACE_START
/// \brief Gets a reference to the element at a specific key, throwing `std::out_of_range` if none existed.
///
/// \availability This function is only available if you compile with exceptions and #TOML_ENABLE_WINDOWS_COMPAT enabled.
/// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
TOML_NODISCARD
TOML_API
node& at(std::wstring_view key);
node& at(std::wstring_view key)
{
return at(impl::narrow(key));
}
/// \brief Gets a reference to the element at a specific key, throwing `std::out_of_range` if none existed.
///
/// \availability This function is only available if you compile with exceptions and #TOML_ENABLE_WINDOWS_COMPAT enabled.
/// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
TOML_NODISCARD
const node& at(std::wstring_view key) const
{
@ -802,7 +800,6 @@ TOML_NAMESPACE_START
}
#endif // TOML_ENABLE_WINDOWS_COMPAT
#endif // TOML_COMPILER_EXCEPTIONS
/// @}

View File

@ -141,22 +141,13 @@ TOML_NAMESPACE_START
return nullptr;
}
#if TOML_ENABLE_WINDOWS_COMPAT
TOML_EXTERNAL_LINKAGE
node* table::get(std::wstring_view key)
{
return get(impl::narrow(key));
}
#endif
#if TOML_COMPILER_EXCEPTIONS
TOML_EXTERNAL_LINKAGE
node& table::at(std::string_view key)
{
auto n = get(key);
#if TOML_COMPILER_EXCEPTIONS
if (!n)
{
auto err = "key '"s;
@ -164,20 +155,16 @@ TOML_NAMESPACE_START
err.append("' not found in table"sv);
throw std::out_of_range{ err };
}
#else
TOML_ASSERT(n && "key not found in table!");
#endif
return *n;
}
#if TOML_ENABLE_WINDOWS_COMPAT
TOML_EXTERNAL_LINKAGE
node& table::at(std::wstring_view key)
{
return at(impl::narrow(key));
}
#endif // TOML_ENABLE_WINDOWS_COMPAT
#endif // TOML_COMPILER_EXCEPTIONS
TOML_EXTERNAL_LINKAGE
bool table::equal(const table& lhs, const table& rhs) noexcept
{

View File

@ -15,6 +15,7 @@
TOML_PUSH_WARNINGS;
TOML_DISABLE_SPAM_WARNINGS;
TOML_DISABLE_SWITCH_WARNINGS;
TOML_DISABLE_SUGGEST_ATTR_WARNINGS;
#if TOML_MSVC
#pragma warning(disable : 5031) // #pragma warning(pop): likely mismatch (false-positive)
#elif TOML_CLANG && !TOML_HEADER_ONLY && TOML_IMPLEMENTATION

View File

@ -182,9 +182,7 @@ TEST_CASE("arrays - construction")
CHECK(arr.is_homogeneous());
CHECK(arr.is_homogeneous<int64_t>());
CHECK(!arr.is_homogeneous<double>());
#if TOML_COMPILER_EXCEPTIONS
CHECK(arr.get(0u) == &arr.at(0u));
#endif
const array& carr = arr;
CHECK(carr.size() == 1u);
@ -197,9 +195,7 @@ TEST_CASE("arrays - construction")
CHECK(carr.is_homogeneous());
CHECK(carr.is_homogeneous<int64_t>());
CHECK(!carr.is_homogeneous<double>());
#if TOML_COMPILER_EXCEPTIONS
CHECK(carr.get(0u) == &carr.at(0u));
#endif
}
{
@ -218,10 +214,8 @@ TEST_CASE("arrays - construction")
REQUIRE(arr.get_as<int64_t>(4u));
CHECK(*arr.get_as<int64_t>(4u) == 3);
CHECK(!arr.is_homogeneous());
#if TOML_COMPILER_EXCEPTIONS
CHECK(arr.get(0u) == &arr.at(0u));
CHECK(arr.get(1u) == &arr.at(1u));
#endif
}
#if TOML_ENABLE_WINDOWS_COMPAT

View File

@ -20,9 +20,7 @@ TEST_CASE("tables - moving")
CHECK(tbl["test"].as<table>()->source().begin == source_position{ 1, 8 });
CHECK(tbl["test"].as<table>()->source().end == source_position{ 1, 24 });
CHECK(tbl["test"].node() == tbl.get("test"sv));
#if TOML_COMPILER_EXCEPTIONS
CHECK(tbl["test"].node() == &tbl.at("test"sv));
#endif
// sanity-check initial state of a freshly-parsed table (const)
const table& ctbl = tbl;
@ -31,9 +29,7 @@ TEST_CASE("tables - moving")
CHECK(ctbl["test"].as<table>()->source().begin == source_position{ 1, 8 });
CHECK(ctbl["test"].as<table>()->source().end == source_position{ 1, 24 });
CHECK(ctbl["test"].node() == ctbl.get("test"sv));
#if TOML_COMPILER_EXCEPTIONS
CHECK(ctbl["test"].node() == &ctbl.at("test"sv));
#endif
// sanity check the virtual type checks
CHECK(tbl.type() == node_type::table);

183
toml.hpp
View File

@ -933,6 +933,7 @@ TOML_ENABLE_WARNINGS;
TOML_PUSH_WARNINGS;
TOML_DISABLE_SPAM_WARNINGS;
TOML_DISABLE_SWITCH_WARNINGS;
TOML_DISABLE_SUGGEST_ATTR_WARNINGS;
#if TOML_MSVC
#pragma warning(disable : 5031) // #pragma warning(pop): likely mismatch (false-positive)
#elif TOML_CLANG && !TOML_HEADER_ONLY && TOML_IMPLEMENTATION
@ -5178,6 +5179,34 @@ TOML_NAMESPACE_START
return nullptr;
}
TOML_PURE_INLINE_GETTER
node* get(size_t index) noexcept
{
return index < elems_.size() ? elems_[index].get() : nullptr;
}
TOML_PURE_INLINE_GETTER
const node* get(size_t index) const noexcept
{
return const_cast<array&>(*this).get(index);
}
template <typename ElemType>
TOML_NODISCARD
impl::wrap_node<ElemType>* get_as(size_t index) noexcept
{
if (auto val = get(index))
return val->template as<ElemType>();
return nullptr;
}
template <typename ElemType>
TOML_NODISCARD
const impl::wrap_node<ElemType>* get_as(size_t index) const noexcept
{
return const_cast<array&>(*this).template get_as<ElemType>(index);
}
TOML_NODISCARD
node& operator[](size_t index) noexcept
{
@ -5190,22 +5219,16 @@ TOML_NAMESPACE_START
return *elems_[index];
}
#if TOML_COMPILER_EXCEPTIONS
TOML_NODISCARD
node& at(size_t index)
{
return *elems_.at(index);
}
TOML_API
node& at(size_t index);
TOML_NODISCARD
const node& at(size_t index) const
{
return *elems_.at(index);
return const_cast<array&>(*this).at(index);
}
#endif // TOML_COMPILER_EXCEPTIONS
TOML_NODISCARD
node& front() noexcept
{
@ -5471,36 +5494,6 @@ TOML_NAMESPACE_START
elems_.pop_back();
}
TOML_NODISCARD
node* get(size_t index) noexcept
{
return index < elems_.size() ? elems_[index].get() : nullptr;
}
TOML_NODISCARD
const node* get(size_t index) const noexcept
{
return index < elems_.size() ? elems_[index].get() : nullptr;
}
template <typename ElemType>
TOML_NODISCARD
impl::wrap_node<ElemType>* get_as(size_t index) noexcept
{
if (auto val = get(index))
return val->as<ElemType>();
return nullptr;
}
template <typename ElemType>
TOML_NODISCARD
const impl::wrap_node<ElemType>* get_as(size_t index) const noexcept
{
if (auto val = get(index))
return val->as<ElemType>();
return nullptr;
}
TOML_API
array& flatten() &;
@ -6096,8 +6089,10 @@ TOML_NAMESPACE_START
#if TOML_ENABLE_WINDOWS_COMPAT
TOML_NODISCARD
TOML_API
node* get(std::wstring_view key);
node* get(std::wstring_view key)
{
return get(impl::narrow(key));
}
TOML_NODISCARD
const node* get(std::wstring_view key) const
@ -6140,8 +6135,6 @@ TOML_NAMESPACE_START
#endif // TOML_ENABLE_WINDOWS_COMPAT
#if TOML_COMPILER_EXCEPTIONS
TOML_NODISCARD
TOML_API
node& at(std::string_view key);
@ -6155,8 +6148,10 @@ TOML_NAMESPACE_START
#if TOML_ENABLE_WINDOWS_COMPAT
TOML_NODISCARD
TOML_API
node& at(std::wstring_view key);
node& at(std::wstring_view key)
{
return at(impl::narrow(key));
}
TOML_NODISCARD
const node& at(std::wstring_view key) const
@ -6165,7 +6160,6 @@ TOML_NAMESPACE_START
}
#endif // TOML_ENABLE_WINDOWS_COMPAT
#endif // TOML_COMPILER_EXCEPTIONS
TOML_NODISCARD
iterator begin() noexcept
@ -9218,32 +9212,6 @@ TOML_PUSH_WARNINGS;
#undef max
#endif
TOML_ANON_NAMESPACE_START
{
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_ANON_NAMESPACE_END;
TOML_NAMESPACE_START
{
TOML_EXTERNAL_LINKAGE
@ -9329,13 +9297,47 @@ TOML_NAMESPACE_START
TOML_EXTERNAL_LINKAGE
bool array::is_homogeneous(node_type ntype, node * &first_nonmatch) noexcept
{
return TOML_ANON_NAMESPACE::array_is_homogeneous(elems_, ntype, first_nonmatch);
if (elems_.empty())
{
first_nonmatch = {};
return false;
}
if (ntype == node_type::none)
ntype = elems_[0]->type();
for (const auto& val : elems_)
{
if (val->type() != ntype)
{
first_nonmatch = val.get();
return false;
}
}
return true;
}
TOML_EXTERNAL_LINKAGE
bool array::is_homogeneous(node_type ntype, const node*& first_nonmatch) const noexcept
{
return TOML_ANON_NAMESPACE::array_is_homogeneous(elems_, ntype, first_nonmatch);
node* fnm = nullptr;
const auto result = const_cast<array&>(*this).is_homogeneous(ntype, fnm);
first_nonmatch = fnm;
return result;
}
TOML_EXTERNAL_LINKAGE
node& array::at(size_t index)
{
#if TOML_COMPILER_EXCEPTIONS
return *elems_.at(index);
#else
auto n = get(index);
TOML_ASSERT(n && "element index not found in array!");
return *n;
#endif
}
TOML_EXTERNAL_LINKAGE
@ -9584,22 +9586,13 @@ TOML_NAMESPACE_START
return nullptr;
}
#if TOML_ENABLE_WINDOWS_COMPAT
TOML_EXTERNAL_LINKAGE
node* table::get(std::wstring_view key)
{
return get(impl::narrow(key));
}
#endif
#if TOML_COMPILER_EXCEPTIONS
TOML_EXTERNAL_LINKAGE
node& table::at(std::string_view key)
{
auto n = get(key);
#if TOML_COMPILER_EXCEPTIONS
if (!n)
{
auto err = "key '"s;
@ -9607,20 +9600,16 @@ TOML_NAMESPACE_START
err.append("' not found in table"sv);
throw std::out_of_range{ err };
}
#else
TOML_ASSERT(n && "key not found in table!");
#endif
return *n;
}
#if TOML_ENABLE_WINDOWS_COMPAT
TOML_EXTERNAL_LINKAGE
node& table::at(std::wstring_view key)
{
return at(impl::narrow(key));
}
#endif // TOML_ENABLE_WINDOWS_COMPAT
#endif // TOML_COMPILER_EXCEPTIONS
TOML_EXTERNAL_LINKAGE
bool table::equal(const table& lhs, const table& rhs) noexcept
{