From 4bbca20fc1525bca9d982d0bd092f3bc908184a9 Mon Sep 17 00:00:00 2001 From: Mark Gillard Date: Thu, 5 Mar 2020 13:07:26 +0200 Subject: [PATCH] added `node::ref()` and `node_view::ref()` (resolves #10) also: - simplified `const` handling in `node_view` --- README.md | 2 - include/toml++/toml_node.h | 94 +++++++++++++---- include/toml++/toml_node_view.h | 152 ++++++++++----------------- include/toml++/toml_version.h | 4 +- meson.build | 2 +- tests/main.cpp | 1 + tests/tests.cpp | 29 +++++ tests/tests.h | 7 +- toml.hpp | 181 ++++++++++++++++---------------- 9 files changed, 261 insertions(+), 211 deletions(-) diff --git a/README.md b/README.md index 713cb10d..f063dbe0 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,6 @@ Given a TOML file `configuration.toml` containing the following: ```toml [library] name = "toml++" -version = "0.3.3" authors = ["Mark Gillard "] [dependencies] @@ -35,7 +34,6 @@ auto config = toml::parse_file( "configuration.toml" ); // get key-value pairs std::string_view library_name = config["library"]["name"].value_or(""sv); -std::string_view library_version = config["library"]["version"].value_or(""sv); std::string_view library_author = config["library"]["authors"][0].value_or(""sv); int64_t depends_on_cpp_version = config["dependencies"]["cpp"].value_or(0); diff --git a/include/toml++/toml_node.h b/include/toml++/toml_node.h index 2e82ac1a..d9f26305 100644 --- a/include/toml++/toml_node.h +++ b/include/toml++/toml_node.h @@ -91,7 +91,7 @@ TOML_START using type = impl::unwrapped>; static_assert( impl::is_value_or_node, - "Template type parameter must be one of the basic value types, a toml::table, or a toml::array" + "Template type parameter must be one of the TOML value types, a toml::table, or a toml::array" ); if constexpr (std::is_same_v) return is_table(); @@ -218,7 +218,7 @@ TOML_START using type = impl::unwrapped; static_assert( impl::is_value_or_node, - "Template type parameter must be one of the basic value types, a toml::table, or a toml::array" + "Template type parameter must be one of the TOML value types, a toml::table, or a toml::array" ); if constexpr (std::is_same_v) return as_table(); @@ -240,7 +240,7 @@ TOML_START using type = impl::unwrapped; static_assert( impl::is_value_or_node, - "Template type parameter must be one of the basic value types, a toml::table, or a toml::array" + "Template type parameter must be one of the TOML value types, a toml::table, or a toml::array" ); if constexpr (std::is_same_v) return as_table(); @@ -321,11 +321,12 @@ TOML_START template using nonvoid = std::conditional_t, B, A>; - //# this is done using a static helper to preserve const and ref categories - //# (otherwise I'd have to implement this function thrice) + //# these functions are static helpers to preserve const and ref categories + //# (otherwise I'd have to implement them thrice) //# ((propagation in C++: a modern horror story)) + template - static decltype(auto) do_visit(N&& node, FUNC&& visitor) + static decltype(auto) do_visit(N&& n, FUNC&& visitor) TOML_MAY_THROW_UNLESS(visit_is_nothrow) { static_assert( @@ -333,51 +334,51 @@ TOML_START "Visitors must be invocable for at least one of the toml::node specializations" ); - switch (node.type()) + switch (n.type()) { case node_type::table: if constexpr (can_visit) - return std::forward(visitor)(std::forward(node).template ref_cast()); + return std::forward(visitor)(std::forward(n).template ref_cast
()); break; case node_type::array: if constexpr (can_visit) - return std::forward(visitor)(std::forward(node).template ref_cast()); + return std::forward(visitor)(std::forward(n).template ref_cast()); break; case node_type::string: if constexpr (can_visit) - return std::forward(visitor)(std::forward(node).template ref_cast()); + return std::forward(visitor)(std::forward(n).template ref_cast()); break; case node_type::integer: if constexpr (can_visit) - return std::forward(visitor)(std::forward(node).template ref_cast()); + return std::forward(visitor)(std::forward(n).template ref_cast()); break; case node_type::floating_point: if constexpr (can_visit) - return std::forward(visitor)(std::forward(node).template ref_cast()); + return std::forward(visitor)(std::forward(n).template ref_cast()); break; case node_type::boolean: if constexpr (can_visit) - return std::forward(visitor)(std::forward(node).template ref_cast()); + return std::forward(visitor)(std::forward(n).template ref_cast()); break; case node_type::date: if constexpr (can_visit) - return std::forward(visitor)(std::forward(node).template ref_cast()); + return std::forward(visitor)(std::forward(n).template ref_cast()); break; case node_type::time: if constexpr (can_visit) - return std::forward(visitor)(std::forward(node).template ref_cast
(); } + [[nodiscard]] auto as_table() const noexcept { return as
(); } /// \brief Returns a pointer to the viewed node as a toml::array, if it is one. - [[nodiscard]] auto as_array() noexcept { return as(); } + [[nodiscard]] auto as_array() const noexcept { return as(); } /// \brief Returns a pointer to the viewed node as a toml::value, if it is one. - [[nodiscard]] auto as_string() noexcept { return as(); } + [[nodiscard]] auto as_string() const noexcept { return as(); } /// \brief Returns a pointer to the viewed node as a toml::value, if it is one. - [[nodiscard]] auto as_integer() noexcept { return as(); } + [[nodiscard]] auto as_integer() const noexcept { return as(); } /// \brief Returns a pointer to the viewed node as a toml::value, if it is one. - [[nodiscard]] auto as_floating_point() noexcept { return as(); } + [[nodiscard]] auto as_floating_point() const noexcept { return as(); } /// \brief Returns a pointer to the viewed node as a toml::value, if it is one. - [[nodiscard]] auto as_boolean() noexcept { return as(); } + [[nodiscard]] auto as_boolean() const noexcept { return as(); } /// \brief Returns a pointer to the viewed node as a toml::value, if it is one. - [[nodiscard]] auto as_date() noexcept { return as(); } + [[nodiscard]] auto as_date() const noexcept { return as(); } /// \brief Returns a pointer to the viewed node as a toml::value
(); } - /// \brief Returns a pointer to the viewed node as a toml::array, if it is one (const overload). - [[nodiscard]] const array* as_array() const noexcept { return as(); } - /// \brief Returns a pointer to the viewed node as a toml::value, if it is one (const overload). - [[nodiscard]] const toml::value* as_string() const noexcept { return as(); } - /// \brief Returns a pointer to the viewed node as a toml::value, if it is one (const overload). - [[nodiscard]] const toml::value* as_integer() const noexcept { return as(); } - /// \brief Returns a pointer to the viewed node as a toml::value, if it is one (const overload). - [[nodiscard]] const toml::value* as_floating_point() const noexcept { return as(); } - /// \brief Returns a pointer to the viewed node as a toml::value, if it is one (const overload). - [[nodiscard]] const toml::value* as_boolean() const noexcept { return as(); } - /// \brief Returns a pointer to the viewed node as a toml::value, if it is one (const overload). - [[nodiscard]] const toml::value* as_date() const noexcept { return as(); } - /// \brief Returns a pointer to the viewed node as a toml::value
()), table&>); + static_assert(is_same_v().ref
()), table&&>); + static_assert(is_same_v().ref
()), const table&>); + static_assert(is_same_v().ref()), array&>); + static_assert(is_same_v().ref()), array&&>); + static_assert(is_same_v().ref()), const array&>); + + static_assert(is_same_v>().ref()), double&>); + static_assert(is_same_v>().ref()), const double&>); + static_assert(is_same_v>().ref>()), double&>); + static_assert(is_same_v>().ref>()), const double&>); + static_assert(is_same_v>().ref
()), table&>); + static_assert(is_same_v>().ref
()), const table&>); + static_assert(is_same_v>().ref()), array&>); + static_assert(is_same_v>().ref()), const array&>); + +} +TOML_END diff --git a/tests/tests.h b/tests/tests.h index 29caeda4..8ac6d4b9 100644 --- a/tests/tests.h +++ b/tests/tests.h @@ -7,11 +7,12 @@ #endif #define TOML_OPTIONAL_TYPE tl::optional #endif +#include "catch2.h" +#include +#include //so TOML_ASSERT() maps to assert() #define TOML_UNDEF_MACROS 0 #define TOML_ALL_INLINE 0 #include "../include/toml++/toml.h" -#include "catch2.h" -#include using namespace toml; using namespace Catch::literals; @@ -230,6 +231,8 @@ inline void parse_expected_value(std::string_view value_str, const T& expected) CHECK(nv.as()->get() == expected); CHECK(nv.value() == expected); CHECK(nv.value_or(T{}) == expected); + CHECK(nv.ref() == expected); + CHECK(nv.get()->ref() == expected); // check the table relops CHECK(tbl == table{ { { S("val"sv), expected } } }); diff --git a/toml.hpp b/toml.hpp index f25db0d6..0313ad16 100644 --- a/toml.hpp +++ b/toml.hpp @@ -1,6 +1,6 @@ //---------------------------------------------------------------------------------------------------------------------- // -// toml++ v0.3.3 +// toml++ v0.4.0 // https://github.com/marzer/tomlplusplus // SPDX-License-Identifier: MIT // @@ -308,8 +308,8 @@ #endif #define TOML_LIB_MAJOR 0 -#define TOML_LIB_MINOR 3 -#define TOML_LIB_PATCH 3 +#define TOML_LIB_MINOR 4 +#define TOML_LIB_PATCH 0 #define TOML_LANG_MAJOR 0 #define TOML_LANG_MINOR 5 @@ -1595,7 +1595,7 @@ TOML_START using type = impl::unwrapped>; static_assert( impl::is_value_or_node, - "Template type parameter must be one of the basic value types, a toml::table, or a toml::array" + "Template type parameter must be one of the TOML value types, a toml::table, or a toml::array" ); if constexpr (std::is_same_v) return is_table(); @@ -1641,7 +1641,7 @@ TOML_START using type = impl::unwrapped; static_assert( impl::is_value_or_node, - "Template type parameter must be one of the basic value types, a toml::table, or a toml::array" + "Template type parameter must be one of the TOML value types, a toml::table, or a toml::array" ); if constexpr (std::is_same_v) return as_table(); @@ -1662,7 +1662,7 @@ TOML_START using type = impl::unwrapped; static_assert( impl::is_value_or_node, - "Template type parameter must be one of the basic value types, a toml::table, or a toml::array" + "Template type parameter must be one of the TOML value types, a toml::table, or a toml::array" ); if constexpr (std::is_same_v) return as_table(); @@ -1743,7 +1743,7 @@ TOML_START using nonvoid = std::conditional_t, B, A>; template - static decltype(auto) do_visit(N&& node, FUNC&& visitor) + static decltype(auto) do_visit(N&& n, FUNC&& visitor) TOML_MAY_THROW_UNLESS(visit_is_nothrow) { static_assert( @@ -1751,51 +1751,51 @@ TOML_START "Visitors must be invocable for at least one of the toml::node specializations" ); - switch (node.type()) + switch (n.type()) { case node_type::table: if constexpr (can_visit) - return std::forward(visitor)(std::forward(node).template ref_cast
()); + return std::forward(visitor)(std::forward(n).template ref_cast
()); break; case node_type::array: if constexpr (can_visit) - return std::forward(visitor)(std::forward(node).template ref_cast()); + return std::forward(visitor)(std::forward(n).template ref_cast()); break; case node_type::string: if constexpr (can_visit) - return std::forward(visitor)(std::forward(node).template ref_cast()); + return std::forward(visitor)(std::forward(n).template ref_cast()); break; case node_type::integer: if constexpr (can_visit) - return std::forward(visitor)(std::forward(node).template ref_cast()); + return std::forward(visitor)(std::forward(n).template ref_cast()); break; case node_type::floating_point: if constexpr (can_visit) - return std::forward(visitor)(std::forward(node).template ref_cast()); + return std::forward(visitor)(std::forward(n).template ref_cast()); break; case node_type::boolean: if constexpr (can_visit) - return std::forward(visitor)(std::forward(node).template ref_cast()); + return std::forward(visitor)(std::forward(n).template ref_cast()); break; case node_type::date: if constexpr (can_visit) - return std::forward(visitor)(std::forward(node).template ref_cast()); + return std::forward(visitor)(std::forward(n).template ref_cast()); break; case node_type::time: if constexpr (can_visit) - return std::forward(visitor)(std::forward(node).template ref_cast
(); } - [[nodiscard]] auto as_array() noexcept { return as(); } - [[nodiscard]] auto as_string() noexcept { return as(); } - [[nodiscard]] auto as_integer() noexcept { return as(); } - [[nodiscard]] auto as_floating_point() noexcept { return as(); } - [[nodiscard]] auto as_boolean() noexcept { return as(); } - [[nodiscard]] auto as_date() noexcept { return as(); } - [[nodiscard]] auto as_time() noexcept { return as
(); } - [[nodiscard]] const array* as_array() const noexcept { return as(); } - [[nodiscard]] const toml::value* as_string() const noexcept { return as(); } - [[nodiscard]] const toml::value* as_integer() const noexcept { return as(); } - [[nodiscard]] const toml::value* as_floating_point() const noexcept { return as(); } - [[nodiscard]] const toml::value* as_boolean() const noexcept { return as(); } - [[nodiscard]] const toml::value* as_date() const noexcept { return as(); } - [[nodiscard]] const toml::value
(); } + [[nodiscard]] auto as_array() const noexcept { return as(); } + [[nodiscard]] auto as_string() const noexcept { return as(); } + [[nodiscard]] auto as_integer() const noexcept { return as(); } + [[nodiscard]] auto as_floating_point() const noexcept { return as(); } + [[nodiscard]] auto as_boolean() const noexcept { return as(); } + [[nodiscard]] auto as_date() const noexcept { return as(); } + [[nodiscard]] auto as_time() const noexcept { return as