Commit c99481f5 authored by Yedidya Feldblum's avatar Yedidya Feldblum Committed by Facebook GitHub Bot

Revise is_constexpr_default_constructible_v and is_constexpr_default_constructible

Summary: [Folly] Revise `is_constexpr_default_constructible_v` as a variable and as eager, and `is_constexpr_default_constructible` as a type and as deferred.

Reviewed By: Mizuchi

Differential Revision: D23371343

fbshipit-source-id: 192b5df78053c89acadab285b6dfb9ab52b14528
parent e1180516
...@@ -71,42 +71,29 @@ struct is_instantiation_of : bool_constant<is_instantiation_of_v<C, T...>> {}; ...@@ -71,42 +71,29 @@ struct is_instantiation_of : bool_constant<is_instantiation_of_v<C, T...>> {};
namespace detail { namespace detail {
template <bool, typename T> struct is_constexpr_default_constructible_ {
struct is_constexpr_default_constructible_; template <typename T, int = (void(T()), 0)>
template <typename T> static std::true_type sfinae(T*);
struct is_constexpr_default_constructible_<false, T> { static std::false_type sfinae(void*);
using type = std::false_type; template <typename T>
}; static constexpr bool apply =
template <typename T> decltype(sfinae(static_cast<T*>(nullptr)))::value;
struct is_constexpr_default_constructible_<true, T> {
static constexpr int take(T) {
return 0;
}
template <int = take(T{})>
static std::true_type sfinae(int);
static std::false_type sfinae(...);
using type = decltype(sfinae(0));
}; };
} // namespace detail } // namespace detail
// is_constexpr_default_constructible
// is_constexpr_default_constructible_v // is_constexpr_default_constructible_v
// is_constexpr_default_constructible
// //
// A type trait, with associated variable template, which determines whether // A trait variable and type which determines whether the type parameter is
// its type parameter is constexpr default-constructible, that is, default- // constexpr default-constructible, that is, default-constructible in a
// constructible in a constexpr context. // constexpr context.
//
// Instantiations of is_constexpr_default_constructible unambiguously inherit
// std::integral_constant<bool, V> for some bool V.
template <typename T>
struct is_constexpr_default_constructible
: detail::is_constexpr_default_constructible_<
std::is_default_constructible<T>::value,
T>::type {};
template <typename T> template <typename T>
FOLLY_INLINE_VARIABLE constexpr bool is_constexpr_default_constructible_v = FOLLY_INLINE_VARIABLE constexpr bool is_constexpr_default_constructible_v =
is_constexpr_default_constructible<T>::value; detail::is_constexpr_default_constructible_::apply<T>;
template <typename T>
struct is_constexpr_default_constructible
: bool_constant<is_constexpr_default_constructible_v<T>> {};
/*** /***
* _t * _t
......
...@@ -426,33 +426,36 @@ TEST(Traits, is_instantiation_of) { ...@@ -426,33 +426,36 @@ TEST(Traits, is_instantiation_of) {
} }
TEST(Traits, is_constexpr_default_constructible) { TEST(Traits, is_constexpr_default_constructible) {
constexpr auto const broken = kGnuc == 7 && !kIsClang;
EXPECT_TRUE(is_constexpr_default_constructible_v<int>); EXPECT_TRUE(is_constexpr_default_constructible_v<int>);
EXPECT_TRUE(is_constexpr_default_constructible<int>{});
struct Empty {}; struct Empty {};
EXPECT_TRUE(is_constexpr_default_constructible_v<Empty>); EXPECT_TRUE(is_constexpr_default_constructible_v<Empty>);
EXPECT_TRUE(is_constexpr_default_constructible<Empty>{});
struct NonTrivialDtor { struct NonTrivialDtor {
~NonTrivialDtor() {} ~NonTrivialDtor() {}
}; };
EXPECT_FALSE(is_constexpr_default_constructible_v<NonTrivialDtor> && !broken); EXPECT_FALSE(is_constexpr_default_constructible_v<NonTrivialDtor>);
EXPECT_FALSE(is_constexpr_default_constructible<NonTrivialDtor>{});
struct ConstexprCtor { struct ConstexprCtor {
int x, y; int x, y;
constexpr ConstexprCtor() noexcept : x(7), y(11) {} constexpr ConstexprCtor() noexcept : x(7), y(11) {}
}; };
EXPECT_TRUE(is_constexpr_default_constructible_v<ConstexprCtor>); EXPECT_TRUE(is_constexpr_default_constructible_v<ConstexprCtor>);
EXPECT_TRUE(is_constexpr_default_constructible<ConstexprCtor>{});
struct NonConstexprCtor { struct NonConstexprCtor {
int x, y; int x, y;
NonConstexprCtor() noexcept : x(7), y(11) {} NonConstexprCtor() noexcept : x(7), y(11) {}
}; };
EXPECT_FALSE( EXPECT_FALSE(is_constexpr_default_constructible_v<NonConstexprCtor>);
is_constexpr_default_constructible_v<NonConstexprCtor> && !broken); EXPECT_FALSE(is_constexpr_default_constructible<NonConstexprCtor>{});
struct NoDefaultCtor { struct NoDefaultCtor {
constexpr NoDefaultCtor(int, int) noexcept {} constexpr NoDefaultCtor(int, int) noexcept {}
}; };
EXPECT_FALSE(is_constexpr_default_constructible_v<NoDefaultCtor>); EXPECT_FALSE(is_constexpr_default_constructible_v<NoDefaultCtor>);
EXPECT_FALSE(is_constexpr_default_constructible<NoDefaultCtor>{});
} }
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