Commit 8a00bcc5 authored by Yedidya Feldblum's avatar Yedidya Feldblum Committed by Facebook Github Bot

conditional_t

Summary: [Folly] `conditional_t`, like `std::conditional_t` but where the result can be used in deducible contexts.

Reviewed By: nbronson

Differential Revision: D14477367

fbshipit-source-id: d0a9da7f0e1584a45a0709e80e2b8afb2851214c
parent 4ffe3aae
......@@ -468,6 +468,31 @@ struct IsZeroInitializable
traits_detail::has_true_IsZeroInitializable<T>,
bool_constant<!std::is_class<T>::value>>::type {};
namespace detail {
template <bool>
struct conditional_;
template <>
struct conditional_<false> {
template <typename, typename T>
using apply = T;
};
template <>
struct conditional_<true> {
template <typename T, typename>
using apply = T;
};
} // namespace detail
// conditional_t
//
// Like std::conditional_t but with only two total class template instances,
// rather than as many class template instances as there are uses.
//
// As one effect, the result can be used in deducible contexts, allowing
// deduction of conditional_t<V, T, F> to work when T or F is a template param.
template <bool V, typename T, typename F>
using conditional_t = typename detail::conditional_<V>::template apply<T, F>;
template <typename...>
struct Conjunction : std::true_type {};
template <typename T>
......
......@@ -103,6 +103,29 @@ TEST(Traits, bitAndInit) {
EXPECT_FALSE(IsZeroInitializable<vector<int>>::value);
}
template <bool V>
struct Cond {
template <typename K = std::string>
static auto fun_std(std::conditional_t<V, K, std::string>&& arg) {
return std::is_same<remove_cvref_t<decltype(arg)>, std::string>{};
}
template <typename K = std::string>
static auto fun_folly(folly::conditional_t<V, K, std::string>&& arg) {
return std::is_same<remove_cvref_t<decltype(arg)>, std::string>{};
}
};
TEST(Traits, conditional) {
using folly::conditional_t;
EXPECT_TRUE((std::is_same<conditional_t<false, char, int>, int>::value));
EXPECT_TRUE((std::is_same<conditional_t<true, char, int>, char>::value));
EXPECT_TRUE(Cond<false>::fun_std("hello"));
EXPECT_TRUE(Cond<true>::fun_std("hello"));
EXPECT_TRUE(Cond<false>::fun_folly("hello"));
EXPECT_FALSE(Cond<true>::fun_folly("hello"));
}
TEST(Trait, logicOperators) {
static_assert(Conjunction<true_type>::value, "");
static_assert(!Conjunction<false_type>::value, "");
......
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