//# 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. // SPDX-License-Identifier: MIT #pragma once #include "toml_node.h" #include "toml_print_to_stream.h" TOML_PUSH_WARNINGS TOML_DISABLE_FLOAT_WARNINGS TOML_DISABLE_PADDING_WARNINGS namespace toml { template std::basic_ostream& operator << (std::basic_ostream&, const value&); /// \brief A TOML value. /// /// \tparam T The value's data type. Can be one of: /// - toml::string /// - int64_t /// - double /// - bool /// - toml::date /// - toml::time /// - toml::date_time template class TOML_API value final : public node { static_assert( impl::is_value, "Template type parameter must be one of the TOML value types" ); private: friend class TOML_PARSER_TYPENAME; template [[nodiscard]] TOML_ALWAYS_INLINE static auto as_value([[maybe_unused]] V* ptr) noexcept { if constexpr (std::is_same_v) return ptr; else return nullptr; } T val_; public: /// \brief The value's underlying data type. using value_type = T; /// \brief A type alias for 'value arguments'. /// \details This differs according to the value's type argument: /// - ints, floats, booleans: `value_type` /// - strings: `string_view` /// - everything else: `const value_type&` using value_arg = std::conditional_t< std::is_same_v, string_view, std::conditional_t, T, const T&> >; /// \brief Constructs a toml value. /// /// \tparam U Constructor argument types. /// \param args Arguments to forward to the internal value's constructor. template TOML_NODISCARD_CTOR explicit value(U&&... args) noexcept(std::is_nothrow_constructible_v) : val_{ std::forward(args)... } {} /// \brief Move constructor. TOML_NODISCARD_CTOR value(value&& other) noexcept : node{ std::move(other) }, val_{ std::move(other.val_) } {} /// \brief Move-assignment operator. value& operator= (value&& rhs) noexcept { node::operator=(std::move(rhs)); val_ = std::move(rhs.val_); return *this; } value(const value&) = delete; value& operator= (const value&) = delete; /// \brief Returns the value's node type identifier. /// /// \returns One of: /// - node_type::string /// - node_type::integer /// - node_type::floating_point /// - node_type::boolean /// - node_type::date /// - node_type::time /// - node_type::date_time [[nodiscard]] node_type type() const noexcept override { return impl::node_type_of; } /// \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; } [[nodiscard]] bool is_integer() const noexcept override { return std::is_same_v; } [[nodiscard]] bool is_floating_point() const noexcept override { return std::is_same_v; } [[nodiscard]] bool is_number() const noexcept override { return impl::is_one_of; } [[nodiscard]] bool is_boolean() const noexcept override { return std::is_same_v; } [[nodiscard]] bool is_date() const noexcept override { return std::is_same_v; } [[nodiscard]] bool is_time() const noexcept override { return std::is_same_v; } [[nodiscard]] bool is_date_time() const noexcept override { return std::is_same_v; } /// \brief Returns a pointer to the value if the data type is a string. [[nodiscard]] value* as_string() noexcept override { return as_value(this); } /// \brief Returns a pointer to the value if the data type is an integer. [[nodiscard]] value* as_integer() noexcept override { return as_value(this); } /// \brief Returns a pointer to the value if the data type is a floating-point. [[nodiscard]] value* as_floating_point() noexcept override { return as_value(this); } /// \brief Returns a pointer to the value if the data type is boolean. [[nodiscard]] value* as_boolean() noexcept override { return as_value(this); } /// \brief Returns a pointer to the value if the data type is a date. [[nodiscard]] value* as_date() noexcept override { return as_value(this); } /// \brief Returns a pointer to the value if the data type is a time. [[nodiscard]] value