//# This file is a part of toml++ and is subject to the the terms of the MIT license. //# Copyright (c) Mark Gillard //# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text. // SPDX-License-Identifier: MIT #pragma once #include "forward_declarations.h" #include "header_start.h" /// \cond TOML_IMPL_NAMESPACE_START { template TOML_NODISCARD TOML_ATTR(returns_nonnull) auto* make_node_impl_specialized(T && val, [[maybe_unused]] value_flags flags) { using unwrapped_type = unwrap_node>; static_assert(!std::is_same_v); static_assert(!is_node_view); // arrays + tables - invoke copy/move ctor if constexpr (is_one_of) { return new unwrapped_type(static_cast(val)); } // values else { using native_type = native_type_of; using value_type = value; value_type* out; // copy/move ctor if constexpr (std::is_same_v, value_type>) { out = new value_type{ static_cast(val) }; } // creating from raw value else { static_assert(!is_wide_string || TOML_ENABLE_WINDOWS_COMPAT, "Instantiating values from wide-character strings is only " "supported on Windows with TOML_ENABLE_WINDOWS_COMPAT enabled."); if constexpr (!is_losslessly_convertible_to_native) { if constexpr (std::is_same_v) static_assert(dependent_false, "Integral value initializers must be losslessly convertible to int64_t"); else if constexpr (std::is_same_v) static_assert(dependent_false, "Floating-point value initializers must be losslessly convertible to double"); else static_assert( dependent_false, "Value initializers must be losslessly convertible to one of the TOML value types"); } if constexpr (is_wide_string) { #if TOML_ENABLE_WINDOWS_COMPAT out = new value_type{ narrow(static_cast(val)) }; #else static_assert(dependent_false, "Evaluated unreachable branch!"); #endif } else out = new value_type{ static_cast(val) }; } if (flags != preserve_source_value_flags) out->flags(flags); return out; } } template TOML_NODISCARD auto* make_node_impl(T && val, value_flags flags = preserve_source_value_flags) { using unwrapped_type = unwrap_node>; if constexpr (std::is_same_v || is_node_view) { if constexpr (is_node_view) { if (!val) return static_cast(nullptr); } return static_cast(val).visit( [flags](auto&& concrete) { return static_cast( make_node_impl_specialized(static_cast(concrete), flags)); }); } else return make_node_impl_specialized(static_cast(val), flags); } template TOML_NODISCARD auto* make_node_impl(inserter && val, value_flags flags = preserve_source_value_flags) { return make_node_impl(static_cast(val.value), flags); } template || is_node_view || is_value || can_partially_represent_native)> struct inserted_type_of_ { using type = std::remove_pointer_t()))>; }; template struct inserted_type_of_, false> { using type = typename inserted_type_of_::type; }; template struct inserted_type_of_ { using type = void; }; template TOML_NODISCARD node_ptr make_node(T && val, value_flags flags = preserve_source_value_flags) { return node_ptr{ make_node_impl(static_cast(val), flags) }; } } TOML_IMPL_NAMESPACE_END; /// \endcond TOML_NAMESPACE_START { /// \brief Metafunction for determining which node type would be constructed /// if an object of this type was inserted into a toml::table or toml::array. /// /// \detail \cpp /// static_assert(std::is_same_v, toml::value); /// static_assert(std::is_same_v, toml::value); /// static_assert(std::is_same_v, toml::value); /// static_assert(std::is_same_v, toml::value); /// \ecpp /// /// \note This will return toml::node for nodes and node_views, even though a more specific node subclass /// would actually be inserted. There is no way around this in a compile-time metafunction. template using inserted_type_of = POXY_IMPLEMENTATION_DETAIL(typename impl::inserted_type_of_>::type); } TOML_NAMESPACE_END; #include "header_end.h"