Clang support for constexpr StringPiece constructor
authorGiuseppe Ottaviano <ott@fb.com>
Thu, 22 Oct 2015 19:11:59 +0000 (12:11 -0700)
committerfacebook-github-bot-1 <folly-bot@fb.com>
Thu, 22 Oct 2015 20:20:21 +0000 (13:20 -0700)
Summary: Clang's `strlen` is not `constexpr`, but `__builtin_strlen` is, so we can have an unconditional `constexpr` `StringPiece` constructor.

Reviewed By: luciang, yfeldblum

Differential Revision: D2561782

fb-gh-sync-id: 51e76a0d50355cc5ead1148ba2389b640a6888de

folly/Portability.h
folly/Range.h
folly/test/RangeTest.cpp

index c059a3cb34d2831883f21f472c0f1f1c52401836..594ab9aa6a73a267cf14e4832b9e456ba951245a 100644 (file)
@@ -17,6 +17,8 @@
 #ifndef FOLLY_PORTABILITY_H_
 #define FOLLY_PORTABILITY_H_
 
+#include <string.h>
+
 #include <cstddef>
 
 #ifndef FOLLY_NO_CONFIG
@@ -375,6 +377,13 @@ inline void asm_pause() {
 #endif
 }
 
+constexpr size_t constexpr_strlen(const char* s) {
+#if defined(__clang__)
+  return __builtin_strlen(s);
+#else
+  return strlen(s);
+#endif
 }
 
+} // namespace folly
 #endif // FOLLY_PORTABILITY_H_
index b074b0e8f2bdcddcda06ee30c125cade99df94d1..8e51760728a6e56817e98bf23d435fe483322672 100644 (file)
@@ -200,15 +200,10 @@ public:
   constexpr Range(Iter start, size_t size)
       : b_(start), e_(start + size) { }
 
-#if FOLLY_HAVE_CONSTEXPR_STRLEN
   template <class T = Iter, typename detail::IsCharPointer<T>::type = 0>
   constexpr /* implicit */ Range(Iter str)
-      : b_(str), e_(str + strlen(str)) {}
-#else
-  template <class T = Iter, typename detail::IsCharPointer<T>::type = 0>
-  /* implicit */ Range(Iter str)
-      : b_(str), e_(str + strlen(str)) {}
-#endif
+      : b_(str), e_(str + constexpr_strlen(str)) {}
+
   template <class T = Iter, typename detail::IsCharPointer<T>::const_type = 0>
   /* implicit */ Range(const std::string& str)
       : b_(str.data()), e_(b_ + str.size()) {}
index 3038bff484573db04273f80ca758beef62ff9431..f9ffda970cda2588e5dd411fca9f50f45ed60980 100644 (file)
@@ -290,7 +290,6 @@ TEST(StringPiece, InvalidRange) {
   EXPECT_THROW(a.subpiece(6), std::out_of_range);
 }
 
-#if FOLLY_HAVE_CONSTEXPR_STRLEN
 constexpr char helloArray[] = "hello";
 
 TEST(StringPiece, Constexpr) {
@@ -300,7 +299,6 @@ TEST(StringPiece, Constexpr) {
   constexpr StringPiece hello2(helloArray);
   EXPECT_EQ("hello", hello2);
 }
-#endif
 
 TEST(StringPiece, Prefix) {
   StringPiece a("hello");