make folly/Bits.h clang-compatible
authorPhilip Pronin <philipp@fb.com>
Thu, 1 Aug 2013 08:42:27 +0000 (01:42 -0700)
committerSara Golemon <sgolemon@fb.com>
Wed, 28 Aug 2013 21:30:11 +0000 (14:30 -0700)
Summary: In clang (as of 3.2) intrinsics aren't `constexpr`.

Test Plan:
fbconfig folly/test:bits_test && fbmake opt -j32
fbconfig --clang folly/test:bits_test && fbmake opt -j32

Reviewed By: lucian@fb.com

FB internal diff: D910310

folly/Bits.h
folly/test/BitsTest.cpp

index 2b5225243ea74c2db0c54793879487a700ff7a52..6b2fef765466d82273d968b23dd9308b2b21ad30 100644 (file)
 #error GCC required
 #endif
 
+#ifndef __clang__
+#define FOLLY_INTRINSIC_CONSTEXPR constexpr
+#else
+// Unlike GCC, in Clang (as of 3.2) intrinsics aren't constexpr.
+#define FOLLY_INTRINSIC_CONSTEXPR const
+#endif
+
 #ifndef FOLLY_NO_CONFIG
 #include "folly/folly-config.h"
 #endif
@@ -86,7 +93,7 @@ namespace folly {
 // Generate overloads for findFirstSet as wrappers around
 // appropriate ffs, ffsl, ffsll gcc builtins
 template <class T>
-inline constexpr
+inline FOLLY_INTRINSIC_CONSTEXPR
 typename std::enable_if<
   (std::is_integral<T>::value &&
    std::is_unsigned<T>::value &&
@@ -97,7 +104,7 @@ typename std::enable_if<
 }
 
 template <class T>
-inline constexpr
+inline FOLLY_INTRINSIC_CONSTEXPR
 typename std::enable_if<
   (std::is_integral<T>::value &&
    std::is_unsigned<T>::value &&
@@ -109,7 +116,7 @@ typename std::enable_if<
 }
 
 template <class T>
-inline constexpr
+inline FOLLY_INTRINSIC_CONSTEXPR
 typename std::enable_if<
   (std::is_integral<T>::value &&
    std::is_unsigned<T>::value &&
@@ -121,7 +128,7 @@ typename std::enable_if<
 }
 
 template <class T>
-inline constexpr
+inline FOLLY_INTRINSIC_CONSTEXPR
 typename std::enable_if<
   (std::is_integral<T>::value && std::is_signed<T>::value),
   unsigned int>::type
@@ -135,7 +142,7 @@ typename std::enable_if<
 // findLastSet: return the 1-based index of the highest bit set
 // for x > 0, findLastSet(x) == 1 + floor(log2(x))
 template <class T>
-inline constexpr
+inline FOLLY_INTRINSIC_CONSTEXPR
 typename std::enable_if<
   (std::is_integral<T>::value &&
    std::is_unsigned<T>::value &&
@@ -146,7 +153,7 @@ typename std::enable_if<
 }
 
 template <class T>
-inline constexpr
+inline FOLLY_INTRINSIC_CONSTEXPR
 typename std::enable_if<
   (std::is_integral<T>::value &&
    std::is_unsigned<T>::value &&
@@ -158,7 +165,7 @@ typename std::enable_if<
 }
 
 template <class T>
-inline constexpr
+inline FOLLY_INTRINSIC_CONSTEXPR
 typename std::enable_if<
   (std::is_integral<T>::value &&
    std::is_unsigned<T>::value &&
@@ -170,7 +177,7 @@ typename std::enable_if<
 }
 
 template <class T>
-inline constexpr
+inline FOLLY_INTRINSIC_CONSTEXPR
 typename std::enable_if<
   (std::is_integral<T>::value &&
    std::is_signed<T>::value),
@@ -180,7 +187,7 @@ typename std::enable_if<
 }
 
 template <class T>
-inline constexpr
+inline FOLLY_INTRINSIC_CONSTEXPR
 typename std::enable_if<
   std::is_integral<T>::value && std::is_unsigned<T>::value,
   T>::type
index 2490161b507f84491128749354c97446402d7ad7..d617caa60b592b5c5b8f112b9ed4a145e5a96523 100644 (file)
 using namespace folly;
 
 // Test constexpr-ness.
+#ifndef __clang__
 static_assert(findFirstSet(2u) == 2, "findFirstSet");
 static_assert(findLastSet(2u) == 2, "findLastSet");
 static_assert(nextPowTwo(2u) == 2, "nextPowTwo");
 static_assert(isPowTwo(2u), "isPowTwo");
+#endif  // __clang__
 
 namespace {