Commit ccb56f3c authored by Phil Willoughby's avatar Phil Willoughby Committed by Facebook Github Bot

C++11 support for Replaceable

Summary: Also add tests for the `is_replaceable` trait.

Reviewed By: yfeldblum

Differential Revision: D5526317

fbshipit-source-id: 92559d55fbb8d115856ef9e8f86b42e327f74e56
parent b669462b
...@@ -28,29 +28,12 @@ ...@@ -28,29 +28,12 @@
#include <type_traits> #include <type_traits>
#include <utility> #include <utility>
#include <folly/Portability.h>
#include <folly/Range.h> #include <folly/Range.h>
#include <folly/Utility.h> #include <folly/Utility.h>
#include <folly/portability/BitsFunctexcept.h> #include <folly/portability/BitsFunctexcept.h>
#include <folly/portability/Constexpr.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 { namespace folly {
template <class Char, std::size_t N> template <class Char, std::size_t N>
......
...@@ -407,3 +407,21 @@ constexpr auto kIsWindows = false; ...@@ -407,3 +407,21 @@ constexpr auto kIsWindows = false;
constexpr auto kMscVer = 0; constexpr auto kMscVer = 0;
#endif #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
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include <utility> #include <utility>
#include <folly/Launder.h> #include <folly/Launder.h>
#include <folly/Portability.h>
#include <folly/Traits.h> #include <folly/Traits.h>
#include <folly/Utility.h> #include <folly/Utility.h>
...@@ -450,7 +451,7 @@ class alignas(T) Replaceable ...@@ -450,7 +451,7 @@ class alignas(T) Replaceable
template < template <
class... Args, class... Args,
std::enable_if_t<std::is_constructible<T, Args&&...>::value, int> = 0> 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 // clang-format off
noexcept(std::is_nothrow_constructible<T, Args&&...>::value) noexcept(std::is_nothrow_constructible<T, Args&&...>::value)
// clang-format on // clang-format on
...@@ -464,7 +465,7 @@ class alignas(T) Replaceable ...@@ -464,7 +465,7 @@ class alignas(T) Replaceable
std::enable_if_t< std::enable_if_t<
std::is_constructible<T, std::initializer_list<U>, Args&&...>::value, std::is_constructible<T, std::initializer_list<U>, Args&&...>::value,
int> = 0> int> = 0>
constexpr explicit Replaceable( FOLLY_CPP14_CONSTEXPR explicit Replaceable(
in_place_t, in_place_t,
std::initializer_list<U> il, std::initializer_list<U> il,
Args&&... args) Args&&... args)
...@@ -486,7 +487,7 @@ class alignas(T) Replaceable ...@@ -486,7 +487,7 @@ class alignas(T) Replaceable
!std::is_same<Replaceable<T>, std::decay_t<U>>::value && !std::is_same<Replaceable<T>, std::decay_t<U>>::value &&
std::is_convertible<U&&, T>::value, std::is_convertible<U&&, T>::value,
int> = 0> int> = 0>
constexpr /* implicit */ Replaceable(U&& other) FOLLY_CPP14_CONSTEXPR /* implicit */ Replaceable(U&& other)
// clang-format off // clang-format off
noexcept(std::is_nothrow_constructible<T, U&&>::value) noexcept(std::is_nothrow_constructible<T, U&&>::value)
// clang-format on // clang-format on
...@@ -502,7 +503,7 @@ class alignas(T) Replaceable ...@@ -502,7 +503,7 @@ class alignas(T) Replaceable
!std::is_same<Replaceable<T>, std::decay_t<U>>::value && !std::is_same<Replaceable<T>, std::decay_t<U>>::value &&
!std::is_convertible<U&&, T>::value, !std::is_convertible<U&&, T>::value,
int> = 0> int> = 0>
explicit constexpr Replaceable(U&& other) FOLLY_CPP14_CONSTEXPR explicit Replaceable(U&& other)
// clang-format off // clang-format off
noexcept(std::is_nothrow_constructible<T, U&&>::value) noexcept(std::is_nothrow_constructible<T, U&&>::value)
// clang-format on // clang-format on
...@@ -622,7 +623,7 @@ class alignas(T) Replaceable ...@@ -622,7 +623,7 @@ class alignas(T) Replaceable
return launder(reinterpret_cast<T const*>(storage_)); return launder(reinterpret_cast<T const*>(storage_));
} }
constexpr T* operator->() { FOLLY_CPP14_CONSTEXPR T* operator->() {
return launder(reinterpret_cast<T*>(storage_)); return launder(reinterpret_cast<T*>(storage_));
} }
...@@ -630,11 +631,11 @@ class alignas(T) Replaceable ...@@ -630,11 +631,11 @@ class alignas(T) Replaceable
return *launder(reinterpret_cast<T const*>(storage_)); return *launder(reinterpret_cast<T const*>(storage_));
} }
constexpr T& operator*() & { FOLLY_CPP14_CONSTEXPR T& operator*() & {
return *launder(reinterpret_cast<T*>(storage_)); return *launder(reinterpret_cast<T*>(storage_));
} }
constexpr T&& operator*() && { FOLLY_CPP14_CONSTEXPR T&& operator*() && {
return std::move(*launder(reinterpret_cast<T*>(storage_))); return std::move(*launder(reinterpret_cast<T*>(storage_)));
} }
......
...@@ -170,6 +170,10 @@ TYPED_TEST(ReplaceableStaticAttributeTest, nothrow_copy_assignable) { ...@@ -170,6 +170,10 @@ TYPED_TEST(ReplaceableStaticAttributeTest, nothrow_copy_assignable) {
std::is_nothrow_copy_constructible<TypeParam>::value, std::is_nothrow_copy_constructible<TypeParam>::value,
std::is_nothrow_copy_assignable<Replaceable<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) { TYPED_TEST(ReplaceableStaticAttributePairTest, copy_construct) {
using T = typename TypeParam::first_type; using T = typename TypeParam::first_type;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment