]> git.saurik.com Git - apt.git/commitdiff
provide a constexpr char[] overload for APT::StringView
authorDavid Kalnischkies <david@kalnischkies.de>
Fri, 15 Jan 2016 16:11:19 +0000 (17:11 +0100)
committerDavid Kalnischkies <david@kalnischkies.de>
Fri, 15 Jan 2016 17:19:16 +0000 (18:19 +0100)
The commit also adds a few trivial tests

Git-Dch: Ignore

apt-pkg/contrib/string_view.h
test/libapt/stringview_test.cc [new file with mode: 0644]

index d4ff800286ad7e9f69b18c75db6a4a4aee214b3b..ea38224e888f62b08f4d8b3850fe76fae8105789 100644 (file)
@@ -27,6 +27,10 @@ class StringView {
     const char *data_;
     size_t size_;
 
+    // without this little stunt the "char const *" overload is always preferred
+    // over char[], but if we got a char[] we can deduct the length at compile time
+    #define APT_T_IS_CHARPOINTER template<class T, typename std::enable_if<std::is_pointer<T>{} && !std::is_array<T>{}>::type* = nullptr>
+
 public:
     static constexpr size_t npos = static_cast<size_t>(-1);
     static_assert(APT::StringView::npos == std::string::npos, "npos values are different");
@@ -35,9 +39,10 @@ public:
     constexpr StringView() : data_(""), size_(0) {}
     constexpr StringView(const char *data, size_t size) : data_(data), size_(size) {}
 
-    StringView(const char *data) : data_(data), size_(strlen(data)) {}
-    StringView(std::string const & str): data_(str.data()), size_(str.size()) {}
+    template<size_t N> constexpr StringView(char const (&data)[N]) : StringView(data, N-1) {}
+    APT_T_IS_CHARPOINTER StringView(T data) : data_(data), size_(strlen(data)) {}
 
+    StringView(std::string const & str): data_(str.data()), size_(str.size()) {}
 
     /* Viewers */
     constexpr StringView substr(size_t pos, size_t n = npos) const {
@@ -114,7 +119,8 @@ public:
 
 }
 
-inline bool operator ==(const char *other, APT::StringView that);
-inline bool operator ==(const char *other, APT::StringView that) { return that.operator==(other); }
+template<size_t N> inline bool operator ==(char const (&other)[N], APT::StringView that) { return that.operator==(other); }
+APT_T_IS_CHARPOINTER inline bool operator ==(T other, APT::StringView that) { return that.operator==(other); }
 
+#undef APT_T_IS_CHARPOINTER
 #endif
diff --git a/test/libapt/stringview_test.cc b/test/libapt/stringview_test.cc
new file mode 100644 (file)
index 0000000..bac69ec
--- /dev/null
@@ -0,0 +1,88 @@
+#if !(defined APT_PKG_EXPOSE_STRING_VIEW)
+       #define APT_PKG_EXPOSE_STRING_VIEW
+#endif
+
+#include <config.h>
+#include <apt-pkg/string_view.h>
+#include <string>
+
+#include <type_traits>
+
+#include <gtest/gtest.h>
+
+TEST(StringViewTest,EmptyString)
+{
+   constexpr APT::StringView defString;
+   static_assert( 0 == defString.length(), "def right size");
+
+   APT::StringView strString{std::string{}};
+   EXPECT_EQ(0, strString.length());
+
+   constexpr char const * const charp = "";
+   constexpr APT::StringView charpString{charp, 0};
+   static_assert( 0 == charpString.length(), "charp right size");
+
+   APT::StringView charp2String{charp};
+   EXPECT_EQ(0, strString.length());
+
+   constexpr APT::StringView charaString{""};
+   static_assert( 0 == charaString.length(), "chara right size");
+
+   EXPECT_TRUE(APT::StringView("") == "");
+   EXPECT_FALSE(APT::StringView("") != "");
+}
+
+TEST(StringViewTest,FooString)
+{
+   constexpr APT::StringView defString("foo", 3);
+   static_assert( 3 == defString.length(), "def right size");
+   EXPECT_EQ(defString.to_string(), defString.data());
+
+   APT::StringView strString{std::string{"foo"}};
+   EXPECT_EQ(3, strString.length());
+   EXPECT_EQ(strString.to_string(), strString.data());
+
+   constexpr char const * const charp = "foo";
+   constexpr APT::StringView charpString{charp, 3};
+   static_assert( 3 == charpString.length(), "charp right size");
+   EXPECT_EQ(charpString.to_string(), charpString.data());
+
+   APT::StringView charp2String{charp};
+   EXPECT_EQ(3, charp2String.length());
+   EXPECT_EQ(charp2String.to_string(), charp2String.data());
+
+   constexpr APT::StringView charaString{"foo"};
+   static_assert( 3 == charaString.length(), "chara right size");
+   EXPECT_EQ(charaString.to_string(), charaString.data());
+
+   EXPECT_TRUE(APT::StringView("foo") == "foo");
+   EXPECT_FALSE(APT::StringView("foo") != "foo");
+}
+
+TEST(StringViewTest,SubStr)
+{
+   constexpr APT::StringView defString("Hello World!");
+   EXPECT_EQ(defString.to_string().substr(6), defString.substr(6).to_string());
+   EXPECT_EQ(defString.to_string().substr(0,5), defString.substr(0,5).to_string());
+   EXPECT_EQ(defString.to_string().substr(6,5), defString.substr(6,5).to_string());
+}
+
+TEST(StringViewTest,Find)
+{
+   constexpr APT::StringView defString("Hello World!");
+   EXPECT_EQ(defString.to_string().find('l'), defString.find('l'));
+   EXPECT_EQ(defString.to_string().find('X'), defString.find('X'));
+   EXPECT_EQ(defString.to_string().find('e',3), defString.find('e',3));
+   EXPECT_EQ(defString.to_string().find('l',6), defString.find('l',6));
+   EXPECT_EQ(defString.to_string().find('l',11), defString.find('l',11));
+}
+
+TEST(StringViewTest,RFind)
+{
+   constexpr APT::StringView defString("Hello World!");
+   EXPECT_EQ(defString.to_string().rfind('l'), defString.rfind('l'));
+   EXPECT_EQ(defString.to_string().rfind('X'), defString.rfind('X'));
+   EXPECT_EQ(defString.to_string().rfind('e',3), defString.rfind('e',3));
+   EXPECT_EQ(defString.to_string().rfind('l',6), defString.rfind('l',6));
+   EXPECT_EQ(defString.to_string().rfind('l',11), defString.rfind('l',11));
+}