diff --git a/docs/mkdocs/docs/api/basic_node/get_value.md b/docs/mkdocs/docs/api/basic_node/get_value.md index c210a52e..c9d88f0d 100644 --- a/docs/mkdocs/docs/api/basic_node/get_value.md +++ b/docs/mkdocs/docs/api/basic_node/get_value.md @@ -20,7 +20,8 @@ This function converts a [fkyaml::basic_node](./index.md) to either ConverterType::from_node(*this, ret); return ret; ``` - This library implements conversions from a node to a number of STL container types and scalar types. (see the notes down below) + This library implements conversions from a node to a number of STL container types and scalar types. (see the notes down below) + Note that ValueType cannot be either a reference, pointer or C-style array type except `std::nullptr_t`. 2. a [fkyaml::basic_node](./index.md) object The function is equivalent to executing ```cpp diff --git a/docs/mkdocs/docs/api/basic_node/get_value_ref.md b/docs/mkdocs/docs/api/basic_node/get_value_ref.md index 67701fb4..9a8142e1 100644 --- a/docs/mkdocs/docs/api/basic_node/get_value_ref.md +++ b/docs/mkdocs/docs/api/basic_node/get_value_ref.md @@ -23,8 +23,7 @@ This API makes no copies. ***ReferenceType*** : reference type to the target YAML node value. - This must be a reference to [`sequence_type`](sequence_type.md), [`mapping_type`](mapping_type.md), [`boolean_type`](boolean_type.md), [`integer_type`](integer_type.md), [`float_number_type`](float_number_type.md) or [`string_type`](string_type.md). - The above restriction is enforced by a static assertion. + This must be a (const) reference type to [`sequence_type`](sequence_type.md), [`mapping_type`](mapping_type.md), [`boolean_type`](boolean_type.md), [`integer_type`](integer_type.md), [`float_number_type`](float_number_type.md) or [`string_type`](string_type.md). ## **Return Value** diff --git a/include/fkYAML/node.hpp b/include/fkYAML/node.hpp index bbdeca3a..10b9d5ee 100644 --- a/include/fkYAML/node.hpp +++ b/include/fkYAML/node.hpp @@ -1305,15 +1305,22 @@ class basic_node { /// @brief Get the node value object converted into a given type. /// @note This function requires T objects to be default constructible. - /// @tparam T A compatible value type which might be cv-qualified or a reference type. - /// @tparam ValueType A compatible value type, without cv-qualifiers and reference by default. + /// @tparam T A compatible value type which might be cv-qualified. + /// @tparam ValueType A compatible value type with cv-qualifiers removed by default. /// @return A compatible native data value converted from the basic_node object. /// @sa https://fktn-k.github.io/fkYAML/api/basic_node/get_value/ template < - typename T, typename ValueType = detail::remove_cvref_t, + typename T, typename ValueType = detail::remove_cv_t, detail::enable_if_t::value, int> = 0> T get_value() const noexcept( noexcept(std::declval().template get_value_impl(std::declval()))) { + // emit a compile error if T is either a reference, pointer or C-style array type. + static_assert( + !std::is_reference::value, + "get_value() cannot be called with reference types. you might want to call get_value_ref()."); + static_assert(!std::is_pointer::value, "get_value() cannot be called with pointer types."); + static_assert(!std::is_array::value, "get_value() cannot be called with C-style array types."); + auto ret = ValueType(); if (has_anchor_name()) { auto itr = mp_meta->anchor_table.equal_range(m_prop.anchor).first; diff --git a/single_include/fkYAML/node.hpp b/single_include/fkYAML/node.hpp index fd422e7a..195fb28a 100644 --- a/single_include/fkYAML/node.hpp +++ b/single_include/fkYAML/node.hpp @@ -12972,15 +12972,22 @@ class basic_node { /// @brief Get the node value object converted into a given type. /// @note This function requires T objects to be default constructible. - /// @tparam T A compatible value type which might be cv-qualified or a reference type. - /// @tparam ValueType A compatible value type, without cv-qualifiers and reference by default. + /// @tparam T A compatible value type which might be cv-qualified. + /// @tparam ValueType A compatible value type with cv-qualifiers removed by default. /// @return A compatible native data value converted from the basic_node object. /// @sa https://fktn-k.github.io/fkYAML/api/basic_node/get_value/ template < - typename T, typename ValueType = detail::remove_cvref_t, + typename T, typename ValueType = detail::remove_cv_t, detail::enable_if_t::value, int> = 0> T get_value() const noexcept( noexcept(std::declval().template get_value_impl(std::declval()))) { + // emit a compile error if T is either a reference, pointer or C-style array type. + static_assert( + !std::is_reference::value, + "get_value() cannot be called with reference types. you might want to call get_value_ref()."); + static_assert(!std::is_pointer::value, "get_value() cannot be called with pointer types."); + static_assert(!std::is_array::value, "get_value() cannot be called with C-style array types."); + auto ret = ValueType(); if (has_anchor_name()) { auto itr = mp_meta->anchor_table.equal_range(m_prop.anchor).first; diff --git a/test/unit_test/test_node_class.cpp b/test/unit_test/test_node_class.cpp index 7874c47f..27799b37 100644 --- a/test/unit_test/test_node_class.cpp +++ b/test/unit_test/test_node_class.cpp @@ -2373,6 +2373,9 @@ struct string_wrap { std::string str; }; +template +using get_fn_t = decltype(std::declval().template get()); + TEST_CASE("Node_GetValue") { SECTION("sequence") { @@ -2966,6 +2969,12 @@ TEST_CASE("Node_GetValue") { REQUIRE_FALSE(opt_bool.has_value()); } #endif + + SECTION("unsupported types") { + STATIC_REQUIRE_FALSE(fkyaml::detail::is_detected::value); + STATIC_REQUIRE_FALSE(fkyaml::detail::is_detected::value); + STATIC_REQUIRE_FALSE(fkyaml::detail::is_detected::value); + } } //