C++11 support for Replaceable
authorPhil Willoughby <philwill@fb.com>
Tue, 1 Aug 2017 19:20:30 +0000 (12:20 -0700)
committerFacebook Github Bot <facebook-github-bot@users.noreply.github.com>
Tue, 1 Aug 2017 19:29:30 +0000 (12:29 -0700)
Summary: Also add tests for the `is_replaceable` trait.

Reviewed By: yfeldblum

Differential Revision: D5526317

fbshipit-source-id: 92559d55fbb8d115856ef9e8f86b42e327f74e56

folly/FixedString.h
folly/Portability.h
folly/Replaceable.h
folly/test/ReplaceableTest.cpp

index bf0d52e32a0b10a44841113ebc3f1eb77582ea63..c6925bbf6e2bbcfe25fc391e6e558a0416e8d515 100644 (file)
 #include <type_traits>
 #include <utility>
 
+#include <folly/Portability.h>
 #include <folly/Range.h>
 #include <folly/Utility.h>
 #include <folly/portability/BitsFunctexcept.h>
 #include <folly/portability/Constexpr.h>
 
-// Define FOLLY_USE_CPP14_CONSTEXPR to be true if the compiler's C++14
-// constexpr support is "good enough".
-#ifndef FOLLY_USE_CPP14_CONSTEXPR
-#if defined(__clang__)
-#define FOLLY_USE_CPP14_CONSTEXPR __cplusplus >= 201300L
-#elif defined(__GNUC__)
-#define FOLLY_USE_CPP14_CONSTEXPR __cplusplus >= 201304L
-#else
-#define FOLLY_USE_CPP14_CONSTEXPR 0 // MSVC?
-#endif
-#endif
-
-#if FOLLY_USE_CPP14_CONSTEXPR
-#define FOLLY_CPP14_CONSTEXPR constexpr
-#else
-#define FOLLY_CPP14_CONSTEXPR inline
-#endif
-
 namespace folly {
 
 template <class Char, std::size_t N>
index 0f549868bdd0bb0ea4445bce692fbf8c56bbe669..cf2c8d32749897faab4c5409bef86ef8f468a11a 100644 (file)
@@ -407,3 +407,21 @@ constexpr auto kIsWindows = false;
 constexpr auto kMscVer = 0;
 #endif
 }
+
+// Define FOLLY_USE_CPP14_CONSTEXPR to be true if the compiler's C++14
+// constexpr support is "good enough".
+#ifndef FOLLY_USE_CPP14_CONSTEXPR
+#if defined(__clang__)
+#define FOLLY_USE_CPP14_CONSTEXPR __cplusplus >= 201300L
+#elif defined(__GNUC__)
+#define FOLLY_USE_CPP14_CONSTEXPR __cplusplus >= 201304L
+#else
+#define FOLLY_USE_CPP14_CONSTEXPR 0 // MSVC?
+#endif
+#endif
+
+#if FOLLY_USE_CPP14_CONSTEXPR
+#define FOLLY_CPP14_CONSTEXPR constexpr
+#else
+#define FOLLY_CPP14_CONSTEXPR inline
+#endif
index 011b1f8b9582261a0c8586a6173c90209130f3a8..b786f8e8b15a207abf3a19888c6ef70389df2ad5 100644 (file)
@@ -22,6 +22,7 @@
 #include <utility>
 
 #include <folly/Launder.h>
+#include <folly/Portability.h>
 #include <folly/Traits.h>
 #include <folly/Utility.h>
 
@@ -450,7 +451,7 @@ class alignas(T) Replaceable
   template <
       class... Args,
       std::enable_if_t<std::is_constructible<T, Args&&...>::value, int> = 0>
-  constexpr explicit Replaceable(in_place_t, Args&&... args)
+  FOLLY_CPP14_CONSTEXPR explicit Replaceable(in_place_t, Args&&... args)
       // clang-format off
       noexcept(std::is_nothrow_constructible<T, Args&&...>::value)
       // clang-format on
@@ -464,7 +465,7 @@ class alignas(T) Replaceable
       std::enable_if_t<
           std::is_constructible<T, std::initializer_list<U>, Args&&...>::value,
           int> = 0>
-  constexpr explicit Replaceable(
+  FOLLY_CPP14_CONSTEXPR explicit Replaceable(
       in_place_t,
       std::initializer_list<U> il,
       Args&&... args)
@@ -486,7 +487,7 @@ class alignas(T) Replaceable
               !std::is_same<Replaceable<T>, std::decay_t<U>>::value &&
               std::is_convertible<U&&, T>::value,
           int> = 0>
-  constexpr /* implicit */ Replaceable(U&& other)
+  FOLLY_CPP14_CONSTEXPR /* implicit */ Replaceable(U&& other)
       // clang-format off
       noexcept(std::is_nothrow_constructible<T, U&&>::value)
       // clang-format on
@@ -502,7 +503,7 @@ class alignas(T) Replaceable
               !std::is_same<Replaceable<T>, std::decay_t<U>>::value &&
               !std::is_convertible<U&&, T>::value,
           int> = 0>
-  explicit constexpr Replaceable(U&& other)
+  FOLLY_CPP14_CONSTEXPR explicit Replaceable(U&& other)
       // clang-format off
       noexcept(std::is_nothrow_constructible<T, U&&>::value)
       // clang-format on
@@ -622,7 +623,7 @@ class alignas(T) Replaceable
     return launder(reinterpret_cast<T const*>(storage_));
   }
 
-  constexpr T* operator->() {
+  FOLLY_CPP14_CONSTEXPR T* operator->() {
     return launder(reinterpret_cast<T*>(storage_));
   }
 
@@ -630,11 +631,11 @@ class alignas(T) Replaceable
     return *launder(reinterpret_cast<T const*>(storage_));
   }
 
-  constexpr T& operator*() & {
+  FOLLY_CPP14_CONSTEXPR T& operator*() & {
     return *launder(reinterpret_cast<T*>(storage_));
   }
 
-  constexpr T&& operator*() && {
+  FOLLY_CPP14_CONSTEXPR T&& operator*() && {
     return std::move(*launder(reinterpret_cast<T*>(storage_)));
   }
 
index 9e29ddaa68df8fbbbf77ef236716b807d67d9238..5bc6b62273430e80534d869a31e65637e3f5332f 100644 (file)
@@ -170,6 +170,10 @@ TYPED_TEST(ReplaceableStaticAttributeTest, nothrow_copy_assignable) {
           std::is_nothrow_copy_constructible<TypeParam>::value,
       std::is_nothrow_copy_assignable<Replaceable<TypeParam>>::value);
 }
+TYPED_TEST(ReplaceableStaticAttributeTest, replaceable) {
+  EXPECT_FALSE(is_replaceable<TypeParam>::value);
+  EXPECT_TRUE(is_replaceable<Replaceable<TypeParam>>::value);
+}
 
 TYPED_TEST(ReplaceableStaticAttributePairTest, copy_construct) {
   using T = typename TypeParam::first_type;