From 3ff13a243d6bfd0d35e0922c4805aae975fda87a Mon Sep 17 00:00:00 2001 From: Kefu Chai Date: Mon, 31 Oct 2022 14:37:59 +0800 Subject: [PATCH] node/convert: support conversion for std::string_view MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit as the key is not always nul terminated, it'd be handy to use a `std::string_view` when a key is expected. before this change, we would have FTBFS if the key is a `string_view` when looking up a node in a map: ``` /usr/include/yaml-cpp/node/detail/impl.h: In instantiation of ‘bool YAML::detail::node::equals(const T&, YAML::detail::shared_memory_holder) [with T = std::basic_string_view; YAML::detail::shared_memory_holder = std::shared_ptr]’: /usr/include/yaml-cpp/node/detail/impl.h:122:26: required from ‘YAML::detail::node* YAML::detail::node_data::get(const Key&, YAML::detail::shared_memory_holder) const [with Key = std::basic_string_view; YAML::detail::shared_memory_holder = std::shared_ptr]’ /usr/include/yaml-cpp/node/detail/node_ref.h:64:55: required from ‘YAML::detail::node* YAML::detail::node_ref::get(const Key&, YAML::detail::shared_memory_holder) const [with Key = std::basic_string_view; YAML::detail::shared_memory_holder = std::shared_ptr]’ /usr/include/yaml-cpp/node/detail/node.h:125:53: required from ‘YAML::detail::node* YAML::detail::node::get(const Key&, YAML::detail::shared_memory_holder) const [with Key = std::basic_string_view; YAML::detail::shared_memory_holder = std::shared_ptr]’ /usr/include/yaml-cpp/node/impl.h:392:71: required from ‘const YAML::Node YAML::Node::operator[](const Key&) const [with Key = std::basic_string_view]’ ../../src/config/base_config.cc:20:23: required from here /usr/include/yaml-cpp/node/detail/impl.h:93:25: error: incomplete type ‘YAML::convert >’ used in nested name specifier 93 | if (convert::decode(Node(*this, pMemory), lhs)) { | ~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~ ``` after this change, a full specialization for `convert --- include/yaml-cpp/node/convert.h | 18 ++++++++++++++++++ test/node/node_test.cpp | 9 +++++++++ 2 files changed, 27 insertions(+) diff --git a/include/yaml-cpp/node/convert.h b/include/yaml-cpp/node/convert.h index 292c5d3..d0eb450 100644 --- a/include/yaml-cpp/node/convert.h +++ b/include/yaml-cpp/node/convert.h @@ -18,6 +18,10 @@ #include #include +#if __cplusplus >= 201703L +#include +#endif + #include "yaml-cpp/binary.h" #include "yaml-cpp/node/impl.h" #include "yaml-cpp/node/iterator.h" @@ -89,6 +93,20 @@ struct convert { static Node encode(const char* rhs) { return Node(rhs); } }; +#if __cplusplus >= 201703L +template <> +struct convert { + static Node encode(std::string_view rhs) { return Node(std::string(rhs)); } + + static bool decode(const Node& node, std::string_view& rhs) { + if (!node.IsScalar()) + return false; + rhs = node.Scalar(); + return true; + } +}; +#endif + template <> struct convert<_Null> { static Node encode(const _Null& /* rhs */) { return Node(); } diff --git a/test/node/node_test.cpp b/test/node/node_test.cpp index ff3d799..5f41ef2 100644 --- a/test/node/node_test.cpp +++ b/test/node/node_test.cpp @@ -356,6 +356,15 @@ TEST(NodeTest, ConstInteratorOnSequence) { EXPECT_EQ(3, count); } +#if __cplusplus >= 201703L +TEST(NodeTest, StdStringViewAsKey) { + Node node; + std::string_view key = "username"; + node[key] = "monkey"; + EXPECT_EQ("monkey", node[key].as()); +} +#endif + TEST(NodeTest, SimpleSubkeys) { Node node; node["device"]["udid"] = "12345";