From 11a0e84ced0f7486d6fbbe68f556b999ea075b30 Mon Sep 17 00:00:00 2001 From: Mark Gillard Date: Thu, 13 Aug 2020 14:02:40 +0300 Subject: [PATCH] added additional node_view constructors also made node conversion operators explicit --- examples/toml_generator.cpp | 15 +++++++-- include/toml++/toml_node.h | 4 +-- include/toml++/toml_node_view.h | 44 +++++++++++++++++++-------- include/toml++/toml_table.hpp | 8 ++--- toml.hpp | 54 +++++++++++++++++++++------------ 5 files changed, 85 insertions(+), 40 deletions(-) diff --git a/examples/toml_generator.cpp b/examples/toml_generator.cpp index 4a0c529..645e1be 100644 --- a/examples/toml_generator.cpp +++ b/examples/toml_generator.cpp @@ -123,6 +123,7 @@ int main(int argc, char** argv) tree.push_back(&root); constexpr size_t max_depth = 10u; int container_min_values = 10; + bool in_arr = false; const auto add = [&](auto&& obj) noexcept -> toml::node& { @@ -143,6 +144,7 @@ int main(int argc, char** argv) { tree.push_back(new_node); container_min_values = rand(1, 4); + in_arr = toml::is_array; } else container_min_values--; @@ -153,14 +155,20 @@ int main(int argc, char** argv) while (node_budget) { - if (rand(100) >= 75) + if (!in_arr && rand(100) >= 75) { if (container_min_values <= 0 && tree.size() < max_depth) add(toml::table{}).ref().is_inline(tree.size() >= max_depth - 2u && rand(100) >= 85); } else { - switch (static_cast((rand() % 8) + 2)) + toml::node_type new_node_type; + if (auto arr = tree.back()->as_array(); arr && !arr->empty()) + new_node_type = arr->front().type(); + else + new_node_type = static_cast((rand() % 8) + 2); + + switch (new_node_type) { case toml::node_type::array: if (container_min_values <= 0 && tree.size() < max_depth) @@ -199,7 +207,10 @@ int main(int argc, char** argv) break; } if (container_min_values <= 0 && tree.size() >= 2u && rand(100) >= 85) + { tree.pop_back(); + in_arr = !tree.empty() && tree.back()->type() == toml::node_type::array; + } } } diff --git a/include/toml++/toml_node.h b/include/toml++/toml_node.h index 130312c..f11fb30 100644 --- a/include/toml++/toml_node.h +++ b/include/toml++/toml_node.h @@ -816,10 +816,10 @@ TOML_NAMESPACE_START } /// \brief Creates a `node_view` pointing to this node. - [[nodiscard]] operator node_view() noexcept; + [[nodiscard]] explicit operator node_view() noexcept; /// \brief Creates a `node_view` pointing to this node (const overload). - [[nodiscard]] operator node_view() const noexcept; + [[nodiscard]] explicit operator node_view() const noexcept; }; } TOML_NAMESPACE_END diff --git a/include/toml++/toml_node_view.h b/include/toml++/toml_node_view.h index 0e6fa09..fd54f68 100644 --- a/include/toml++/toml_node_view.h +++ b/include/toml++/toml_node_view.h @@ -59,21 +59,19 @@ TOML_NAMESPACE_START template class TOML_API TOML_TRIVIAL_ABI node_view { + static_assert( + impl::is_one_of, + "A toml::node_view<> must wrap toml::node or const toml::node." + ); + public: using viewed_type = ViewedType; private: - friend class TOML_NAMESPACE::node; - friend class TOML_NAMESPACE::table; template friend class TOML_NAMESPACE::node_view; mutable viewed_type* node_ = nullptr; - TOML_NODISCARD_CTOR - node_view(viewed_type* node) noexcept - : node_{ node } - {} - template static constexpr bool visit_is_nothrow = noexcept(std::declval()->visit(std::declval())); @@ -84,6 +82,18 @@ TOML_NAMESPACE_START TOML_NODISCARD_CTOR node_view() noexcept = default; + /// \brief Constructs node_view of a specific node. + TOML_NODISCARD_CTOR + explicit node_view(viewed_type* node) noexcept + : node_{ node } + {} + + /// \brief Constructs node_view of a specific node. + TOML_NODISCARD_CTOR + explicit node_view(viewed_type& node) noexcept + : node_{ &node } + {} + ///// \brief Copy constructor. TOML_NODISCARD_CTOR node_view(const node_view&) noexcept = default; @@ -547,8 +557,8 @@ TOML_NAMESPACE_START node_view operator[] (std::string_view key) const noexcept { if (auto tbl = this->as_table()) - return { tbl->get(key) }; - return { nullptr }; + return node_view{ tbl->get(key) }; + return node_view{ nullptr }; } #if TOML_WINDOWS_COMPAT @@ -565,8 +575,8 @@ TOML_NAMESPACE_START node_view operator[] (std::wstring_view key) const noexcept { if (auto tbl = this->as_table()) - return { tbl->get(key) }; - return { nullptr }; + return node_view{ tbl->get(key) }; + return node_view{ nullptr }; } #endif // TOML_WINDOWS_COMPAT @@ -581,13 +591,21 @@ TOML_NAMESPACE_START node_view operator[] (size_t index) const noexcept { if (auto arr = this->as_array()) - return { arr->get(index) }; - return { nullptr }; + return node_view{ arr->get(index) }; + return node_view{ nullptr }; } template friend std::basic_ostream& operator << (std::basic_ostream&, const node_view&); }; + template node_view(const value&) -> node_view; + node_view(const table&) -> node_view; + node_view(const array&) -> node_view; + template node_view(value&) -> node_view; + node_view(table&) -> node_view; + node_view(array&) -> node_view; + template node_view(const T*) -> node_view; + template node_view(T*) -> node_view; /// \brief Prints the viewed node out to a stream. template diff --git a/include/toml++/toml_table.hpp b/include/toml++/toml_table.hpp index aa26e62..71aec11 100644 --- a/include/toml++/toml_table.hpp +++ b/include/toml++/toml_table.hpp @@ -160,12 +160,12 @@ TOML_NAMESPACE_START TOML_EXTERNAL_LINKAGE node_view table::operator[] (std::string_view key) noexcept { - return { this->get(key) }; + return node_view{ this->get(key) }; } TOML_EXTERNAL_LINKAGE node_view table::operator[] (std::string_view key) const noexcept { - return { this->get(key) }; + return node_view{ this->get(key) }; } TOML_EXTERNAL_LINKAGE @@ -232,12 +232,12 @@ TOML_NAMESPACE_START TOML_EXTERNAL_LINKAGE node_view table::operator[] (std::wstring_view key) noexcept { - return { this->get(key) }; + return node_view{ this->get(key) }; } TOML_EXTERNAL_LINKAGE node_view table::operator[] (std::wstring_view key) const noexcept { - return { this->get(key) }; + return node_view{ this->get(key) }; } TOML_EXTERNAL_LINKAGE diff --git a/toml.hpp b/toml.hpp index ff62682..2cc7053 100644 --- a/toml.hpp +++ b/toml.hpp @@ -2475,8 +2475,8 @@ TOML_NAMESPACE_START return do_ref(*this); } - [[nodiscard]] operator node_view() noexcept; - [[nodiscard]] operator node_view() const noexcept; + [[nodiscard]] explicit operator node_view() noexcept; + [[nodiscard]] explicit operator node_view() const noexcept; }; } TOML_NAMESPACE_END @@ -4379,21 +4379,19 @@ TOML_NAMESPACE_START template class TOML_API TOML_TRIVIAL_ABI node_view { + static_assert( + impl::is_one_of, + "A toml::node_view<> must wrap toml::node or const toml::node." + ); + public: using viewed_type = ViewedType; private: - friend class TOML_NAMESPACE::node; - friend class TOML_NAMESPACE::table; template friend class TOML_NAMESPACE::node_view; mutable viewed_type* node_ = nullptr; - TOML_NODISCARD_CTOR - node_view(viewed_type* node) noexcept - : node_{ node } - {} - template static constexpr bool visit_is_nothrow = noexcept(std::declval()->visit(std::declval())); @@ -4403,6 +4401,16 @@ TOML_NAMESPACE_START TOML_NODISCARD_CTOR node_view() noexcept = default; + TOML_NODISCARD_CTOR + explicit node_view(viewed_type* node) noexcept + : node_{ node } + {} + + TOML_NODISCARD_CTOR + explicit node_view(viewed_type& node) noexcept + : node_{ &node } + {} + TOML_NODISCARD_CTOR node_view(const node_view&) noexcept = default; @@ -4655,8 +4663,8 @@ TOML_NAMESPACE_START node_view operator[] (std::string_view key) const noexcept { if (auto tbl = this->as_table()) - return { tbl->get(key) }; - return { nullptr }; + return node_view{ tbl->get(key) }; + return node_view{ nullptr }; } #if TOML_WINDOWS_COMPAT @@ -4665,8 +4673,8 @@ TOML_NAMESPACE_START node_view operator[] (std::wstring_view key) const noexcept { if (auto tbl = this->as_table()) - return { tbl->get(key) }; - return { nullptr }; + return node_view{ tbl->get(key) }; + return node_view{ nullptr }; } #endif // TOML_WINDOWS_COMPAT @@ -4675,13 +4683,21 @@ TOML_NAMESPACE_START node_view operator[] (size_t index) const noexcept { if (auto arr = this->as_array()) - return { arr->get(index) }; - return { nullptr }; + return node_view{ arr->get(index) }; + return node_view{ nullptr }; } template friend std::basic_ostream& operator << (std::basic_ostream&, const node_view&); }; + template node_view(const value&) -> node_view; + node_view(const table&) -> node_view; + node_view(const array&) -> node_view; + template node_view(value&) -> node_view; + node_view(table&) -> node_view; + node_view(array&) -> node_view; + template node_view(const T*) -> node_view; + template node_view(T*) -> node_view; template inline std::basic_ostream& operator << (std::basic_ostream& os, const node_view& nv) @@ -7908,12 +7924,12 @@ TOML_NAMESPACE_START TOML_EXTERNAL_LINKAGE node_view table::operator[] (std::string_view key) noexcept { - return { this->get(key) }; + return node_view{ this->get(key) }; } TOML_EXTERNAL_LINKAGE node_view table::operator[] (std::string_view key) const noexcept { - return { this->get(key) }; + return node_view{ this->get(key) }; } TOML_EXTERNAL_LINKAGE @@ -7980,12 +7996,12 @@ TOML_NAMESPACE_START TOML_EXTERNAL_LINKAGE node_view table::operator[] (std::wstring_view key) noexcept { - return { this->get(key) }; + return node_view{ this->get(key) }; } TOML_EXTERNAL_LINKAGE node_view table::operator[] (std::wstring_view key) const noexcept { - return { this->get(key) }; + return node_view{ this->get(key) }; } TOML_EXTERNAL_LINKAGE