]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: fix constexpr for string_size 15738/head
authorCasey Bodley <cbodley@redhat.com>
Fri, 16 Jun 2017 20:50:12 +0000 (16:50 -0400)
committerCasey Bodley <cbodley@redhat.com>
Fri, 16 Jun 2017 21:03:05 +0000 (17:03 -0400)
string_size<const char*>() is no longer constexpr. added new constexpr
specialization for string_size<char[N]>()

Signed-off-by: Adam C. Emerson <aemerson@redhat.com>
Signed-off-by: Casey Bodley <cbodley@redhat.com>
src/rgw/rgw_string.h
src/test/rgw/test_rgw_string.cc

index 311add42c7744cbcd94235ffca5b8c79c5b34007..747c47ebe27599528970666732dbd52219d1f68e 100644 (file)
@@ -137,15 +137,21 @@ struct string_traits {
 // specializations for char*/const char* use strlen()
 template <>
 struct string_traits<const char*> {
-  static constexpr size_t size(const char* s) { return std::strlen(s); }
+  static size_t size(const char* s) { return std::strlen(s); }
 };
 template <>
 struct string_traits<char*> : string_traits<const char*> {};
-// specializations for char[]/const char[] also use strlen()
+// constexpr specializations for char[]/const char[]
 template <std::size_t N>
-struct string_traits<const char[N]> : string_traits<const char*> {};
+struct string_traits<const char[N]> {
+  static constexpr size_t size_(const char* s, size_t i) {
+    return i < N ? (*(s + i) == '\0' ? i : size_(s, i + 1))
+        : throw std::invalid_argument("Unterminated string constant.");
+  }
+  static constexpr size_t size(const char(&s)[N]) { return size_(s, 0); }
+};
 template <std::size_t N>
-struct string_traits<char[N]> : string_traits<const char*> {};
+struct string_traits<char[N]> : string_traits<const char[N]> {};
 
 // helpers for string_cat_reserve()
 static inline void append_to(std::string& s) {}
index 4b35fbc292614bda83a095526e7c4a848f61d0e8..96dc8a9bf26b4edaefd1aeb16c0b36a204fad2dc 100644 (file)
@@ -32,8 +32,13 @@ TEST(string_size, types)
   ASSERT_EQ(3u, string_size(mno));
   ASSERT_EQ(3u, string_size(pqr));
 
-  constexpr auto compile_time_size = string_size(jkl);
-  ASSERT_EQ(3u, compile_time_size);
+  constexpr auto compile_time_string_view_size = string_size(jkl);
+  ASSERT_EQ(3u, compile_time_string_view_size);
+  constexpr auto compile_time_string_literal_size = string_size(mno);
+  ASSERT_EQ(3u, compile_time_string_literal_size);
+
+  char arr[] = {'a', 'b', 'c'}; // not null-terminated
+  ASSERT_THROW(string_size(arr), std::invalid_argument);
 }
 
 TEST(string_cat_reserve, types)