zstring: Fix conversion for string references
Change-Id: I0c89df2e53dc04f058c409624bb2383bc5952b3c
Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/include/stdplus/zstring.hpp b/include/stdplus/zstring.hpp
index 28a3494..ab1e524 100644
--- a/include/stdplus/zstring.hpp
+++ b/include/stdplus/zstring.hpp
@@ -32,6 +32,17 @@
return str.find('\0') == str.npos;
}
+template <typename T, typename CharT, typename Traits>
+struct same_string : std::false_type
+{
+};
+
+template <typename CharT, typename Traits, typename Allocator>
+struct same_string<std::basic_string<CharT, Traits, Allocator>, CharT, Traits>
+ : std::true_type
+{
+};
+
} // namespace detail
/**
@@ -56,9 +67,7 @@
using const_reference = const value_type&;
using size_type = std::size_t;
- template <typename T, size_type N,
- std::enable_if_t<std::is_same_v<decay_t, std::remove_cvref_t<T>>,
- bool> = true>
+ template <typename T, size_type N>
constexpr basic_zstring(T (&str)[N])
#ifdef NDEBUG
noexcept
@@ -78,12 +87,10 @@
{
}
template <typename T,
- std::enable_if_t<
- std::is_same_v<std::basic_string<decay_t, Traits,
- typename T::allocator_type>,
- std::remove_cvref_t<T>>,
- bool> = true>
- constexpr basic_zstring(T& str)
+ std::enable_if_t<detail::same_string<std::remove_cvref_t<T>,
+ decay_t, Traits>::value,
+ bool> = true>
+ constexpr basic_zstring(T&& str)
#ifdef NDEBUG
noexcept
#endif
diff --git a/include/stdplus/zstring_view.hpp b/include/stdplus/zstring_view.hpp
index c97364c..a88edf8 100644
--- a/include/stdplus/zstring_view.hpp
+++ b/include/stdplus/zstring_view.hpp
@@ -73,10 +73,7 @@
static constexpr size_type npos = string_view_base::npos;
- template <
- typename T, size_type N,
- std::enable_if_t<std::is_same_v<value_type, std::remove_cvref_t<T>>,
- bool> = true>
+ template <typename T, size_type N>
constexpr basic_zstring_view(T (&str)[N])
#ifdef NDEBUG
noexcept
@@ -96,12 +93,9 @@
{
}
template <typename T,
- std::enable_if_t<
- std::is_same_v<std::basic_string<value_type, Traits,
- typename T::allocator_type>,
- std::remove_cvref_t<T>>,
- bool> = true>
- constexpr basic_zstring_view(T& str)
+ std::enable_if_t<detail::same_string<T, CharT, Traits>::value,
+ bool> = true>
+ constexpr basic_zstring_view(const T& str)
#ifdef NDEBUG
noexcept
#endif
diff --git a/test/zstring.cpp b/test/zstring.cpp
index 07ea1f1..70f4c88 100644
--- a/test/zstring.cpp
+++ b/test/zstring.cpp
@@ -32,7 +32,14 @@
EXPECT_EQ("c", zstring(as));
EXPECT_EQ("c", const_zstring(as));
+ auto str2 = "d"s;
+ auto zs = zstring(str2);
+ EXPECT_EQ(str2, zs);
+
std::cerr << const_zstring(as);
+
+ auto from_str = [&](const_zstring cs) { EXPECT_EQ(cs, "ac"); };
+ from_str("ac"s);
}
TEST(Zstring, NoTypeCoercion)
diff --git a/test/zstring_view.cpp b/test/zstring_view.cpp
index 8ed2f63..84b7cb8 100644
--- a/test/zstring_view.cpp
+++ b/test/zstring_view.cpp
@@ -12,6 +12,14 @@
using std::literals::string_view_literals::operator""sv;
using zstring_view_literals::operator""_zsv;
+TEST(ZstringView, IsString)
+{
+ EXPECT_TRUE((
+ detail::same_string<std::string, char, std::char_traits<char>>::value));
+ EXPECT_FALSE((detail::same_string<std::string_view, char,
+ std::char_traits<char>>::value));
+}
+
TEST(ZstringView, Basic)
{
auto s1 = zstring_view("ac");
@@ -48,6 +56,9 @@
std::set<zstring_view> set{s2, s2};
EXPECT_EQ(0, set.count("ac"));
EXPECT_EQ(1, set.count("b"));
+
+ auto from_str = [&](zstring_view cs) { EXPECT_EQ(cs, "ac"); };
+ from_str("ac"s);
}
TEST(ZstringView, ConstructError)