//# This file is a part of toml++ and is subject to the the terms of the MIT license. //# Copyright (c) 2019-2020 Mark Gillard //# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text. #pragma once #include "toml_table.h" #include "toml_array.h" #include "toml_value.h" TOML_START { template inline std::basic_ostream& operator << (std::basic_ostream&, const node_view&) TOML_MAY_THROW; /// \brief A view of a node. /// /// \detail A node_view is like a std::optional with lots of toml-specific stuff built-in. /// It _may_ represent a node, and allows you to do many of the same operations that you'd do /// on nodes directly, as well as easily traversing the node tree by creating /// subviews (via node_view::operator[]). \cpp /// /// auto tbl = toml::parse(R"( /// /// title = "my hardware store" /// /// [[products]] /// name = "Hammer" /// sku = 738594937 /// keywords = [ "hammer", "construction", "build" ] /// /// [[products]] /// name = "Nail" /// sku = 284758393 /// color = "gray" /// /// )"sv); /// /// std::cout << tbl["title"] << std::endl; /// std::cout << tbl["products"][0]["name"] << std::endl; /// std::cout << tbl["products"][0]["keywords"] << std::endl; /// std::cout << tbl["products"][0]["keywords"][2] << std::endl; /// /// tbl["products"][0]["keywords"].as_array()->push_back("heavy"); /// std::cout << tbl["products"][0]["keywords"] << std::endl; /// std::cout << "has product[2]: "sv << !!tbl["products"][2] << std::endl; /// std::cout << "product[2]: "sv << tbl["products"][2] << std::endl; /// \ecpp /// /// \out /// "my hardware store" /// "Hammer" /// [ "hammer", "construction", "build" ] /// "build" /// [ "hammer", "construction", "build", "heavy" ] /// has product[2]: false /// product[2]: /// \eout template class TOML_API node_view final { public: using viewed_type = T; private: friend class toml::table; template friend class toml::node_view; mutable viewed_type* node_; TOML_NODISCARD_CTOR node_view(viewed_type* node) noexcept : node_{ node } {} template static constexpr bool visit_is_nothrow = noexcept(std::declval()->visit(std::declval())); public: /// \brief Returns true if the view references a node. [[nodiscard]] explicit operator bool() const noexcept { return node_ != nullptr; } /// \brief Returns the node that's being referenced by the view. [[nodiscard]] viewed_type* get() const noexcept { return node_; } /// \brief Returns the type identifier for the viewed node. [[nodiscard]] node_type type() const noexcept { return node_ ? node_->type() : node_type::none; } /// \brief Returns true if the viewed node is a toml::table. [[nodiscard]] bool is_table() const noexcept { return node_ && node_->is_table(); } /// \brief Returns true if the viewed node is a toml::array. [[nodiscard]] bool is_array() const noexcept { return node_ && node_->is_array(); } /// \brief Returns true if the viewed node is a toml::value<>. [[nodiscard]] bool is_value() const noexcept { return node_ && node_->is_value(); } /// \brief Returns true if the viewed node is a toml::value. [[nodiscard]] bool is_string() const noexcept { return node_ && node_->is_string(); } /// \brief Returns true if the viewed node is a toml::value. [[nodiscard]] bool is_integer() const noexcept { return node_ && node_->is_integer(); } /// \brief Returns true if the viewed node is a toml::value. [[nodiscard]] bool is_floating_point() const noexcept { return node_ && node_->is_floating_point(); } /// \brief Returns true if the viewed node is a toml::value or toml::value. [[nodiscard]] bool is_number() const noexcept { return node_ && node_->is_number(); } /// \brief Returns true if the viewed node is a toml::value. [[nodiscard]] bool is_boolean() const noexcept { return node_ && node_->is_boolean(); } /// \brief Returns true if the viewed node is a toml::value. [[nodiscard]] bool is_date() const noexcept { return node_ && node_->is_date(); } /// \brief Returns true if the viewed node is a toml::value