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

bool_constant and index_constant

Summary: [Folly] `bool_constant` (C++17 backport) and `index_constant`.

Reviewed By: aary

Differential Revision: D8440131

fbshipit-source-id: 2bc4fae1e2d1f404d4060c209ee325beebe2a415
parent 9e713840
......@@ -229,8 +229,8 @@ constexpr const std::array<
}};
// Check if ASCII is really ASCII
using IsAscii = std::
integral_constant<bool, 'A' == 65 && 'Z' == 90 && 'a' == 97 && 'z' == 122>;
using IsAscii =
bool_constant<'A' == 65 && 'Z' == 90 && 'a' == 97 && 'z' == 122>;
// The code in this file that uses tolower() really only cares about
// 7-bit ASCII characters, so we can take a nice shortcut here.
......
......@@ -219,11 +219,12 @@ class fbvector {
typedef typename std::conditional<
should_pass_by_value::value, T, T&&>::type MT;
typedef std::integral_constant<bool,
std::is_same<Allocator, std::allocator<T>>::value> usingStdAllocator;
typedef std::integral_constant<bool,
typedef bool_constant<std::is_same<Allocator, std::allocator<T>>::value>
usingStdAllocator;
typedef bool_constant<
usingStdAllocator::value ||
A::propagate_on_container_move_assignment::value> moveIsSwap;
A::propagate_on_container_move_assignment::value>
moveIsSwap;
//===========================================================================
//---------------------------------------------------------------------------
......@@ -637,15 +638,15 @@ class fbvector {
}
// dispatch type trait
typedef std::integral_constant<bool,
folly::IsRelocatable<T>::value && usingStdAllocator::value
> relocate_use_memcpy;
typedef std::integral_constant<bool,
(std::is_nothrow_move_constructible<T>::value
&& usingStdAllocator::value)
|| !std::is_copy_constructible<T>::value
> relocate_use_move;
typedef bool_constant<
folly::IsRelocatable<T>::value && usingStdAllocator::value>
relocate_use_memcpy;
typedef bool_constant<
(std::is_nothrow_move_constructible<T>::value &&
usingStdAllocator::value) ||
!std::is_copy_constructible<T>::value>
relocate_use_move;
// move
void relocate_move(T* dest, T* first, T* last) {
......
......@@ -255,7 +255,7 @@ union Data {
template <typename Fun, typename = Fun*>
using IsSmall = Conjunction<
std::integral_constant<bool, (sizeof(Fun) <= sizeof(Data::tiny))>,
bool_constant<(sizeof(Fun) <= sizeof(Data::tiny))>,
std::is_nothrow_move_constructible<Fun>>;
using SmallTag = std::true_type;
using HeapTag = std::false_type;
......
......@@ -134,6 +134,21 @@
namespace folly {
#if __cpp_lib_bool_constant || _MSC_VER
using std::bool_constant;
#else
// mimic: std::bool_constant, C++17
template <bool B>
using bool_constant = std::integral_constant<bool, B>;
#endif
template <std::size_t I>
using index_constant = std::integral_constant<std::size_t, I>;
/***
* _t
*
......@@ -289,8 +304,7 @@ using void_t = type_t<void, Ts...>;
// Older versions of libstdc++ do not provide std::is_trivially_copyable
#if defined(__clang__) && !defined(_LIBCPP_VERSION)
template <class T>
struct is_trivially_copyable
: std::integral_constant<bool, __is_trivially_copyable(T)> {};
struct is_trivially_copyable : bool_constant<__is_trivially_copyable(T)> {};
#elif defined(__GNUC__) && !defined(__clang__) && __GNUC__ < 5
template <class T>
struct is_trivially_copyable : std::is_trivial<T> {};
......@@ -417,10 +431,8 @@ using IsNothrowSwappable = std::_Is_nothrow_swappable<T>;
template <class T>
struct IsNothrowSwappable
: std::integral_constant<bool,
std::is_nothrow_move_constructible<T>::value &&
noexcept(swap(std::declval<T&>(), std::declval<T&>()))
> {};
: bool_constant<std::is_nothrow_move_constructible<T>::value&& noexcept(
swap(std::declval<T&>(), std::declval<T&>()))> {};
#endif
} // namespace traits_detail_IsNothrowSwappable
......@@ -435,12 +447,12 @@ struct IsRelocatable : std::conditional<
// std::is_trivially_move_constructible<T>::value ||
is_trivially_copyable<T>>::type {};
template <class T> struct IsZeroInitializable
: std::conditional<
traits_detail::has_IsZeroInitializable<T>::value,
traits_detail::has_true_IsZeroInitializable<T>,
std::integral_constant<bool, !std::is_class<T>::value>
>::type {};
template <class T>
struct IsZeroInitializable
: std::conditional<
traits_detail::has_IsZeroInitializable<T>::value,
traits_detail::has_true_IsZeroInitializable<T>,
bool_constant<!std::is_class<T>::value>>::type {};
template <typename...>
struct Conjunction : std::true_type {};
......@@ -459,7 +471,7 @@ struct Disjunction<T, TList...>
: std::conditional<T::value, T, Disjunction<TList...>>::type {};
template <typename T>
struct Negation : std::integral_constant<bool, !T::value> {};
struct Negation : bool_constant<!T::value> {};
template <bool... Bs>
struct Bools {
......@@ -594,10 +606,8 @@ namespace folly {
// STL commonly-used types
template <class T, class U>
struct IsRelocatable< std::pair<T, U> >
: std::integral_constant<bool,
IsRelocatable<T>::value &&
IsRelocatable<U>::value> {};
struct IsRelocatable<std::pair<T, U>>
: bool_constant<IsRelocatable<T>::value && IsRelocatable<U>::value> {};
// Is T one of T1, T2, ..., Tn?
template <typename T, typename... Ts>
......
......@@ -385,12 +385,6 @@ class MoveOnly {
using MoveOnly = moveonly_::MoveOnly;
/**
* A pithy alias for std::integral_constant<bool, B>.
*/
template <bool B>
using Bool = std::integral_constant<bool, B>;
template <typename T>
constexpr auto to_signed(T const& t) -> typename std::make_signed<T>::type {
using S = typename std::make_signed<T>::type;
......
......@@ -142,11 +142,11 @@ using EnableIfAcceptsOneArgument = void_t<decltype(std::declval<Func>()(
template <typename Sequence, typename Func>
using EnableIfAcceptsTwoArguments = void_t<decltype(std::declval<Func>()(
std::declval<typename DeclvalSequence<Sequence>::type>(),
std::integral_constant<std::size_t, 0>{}))>;
index_constant<0>{}))>;
template <typename Sequence, typename Func>
using EnableIfAcceptsThreeArguments = void_t<decltype(std::declval<Func>()(
std::declval<typename DeclvalSequence<Sequence>::type>(),
std::integral_constant<std::size_t, 0>{},
index_constant<0>{},
adl::adl_begin(std::declval<Sequence>())))>;
template <typename Sequence, typename Func>
using EnableIfBreaksRange = std::enable_if_t<std::is_same<
......@@ -159,7 +159,7 @@ template <typename Sequence, typename Func>
using EnableIfBreaksTuple = std::enable_if_t<std::is_same<
typename std::decay<decltype(std::declval<Func>()(
std::declval<typename DeclvalSequence<Sequence>::type>(),
std::integral_constant<std::size_t, 0>{}))>::type,
index_constant<0>{}))>::type,
LoopControl>::value>;
/**
* Enables if the sequence has random access iterators
......@@ -263,7 +263,7 @@ struct ForEachTupleImpl {
static_cast<void>(std::initializer_list<int>{
(func(
Get<Indices, Sequence>::impl(std::forward<Sequence>(seq)),
std::integral_constant<std::size_t, Indices>{}),
index_constant<Indices>{}),
0)...});
}
};
......@@ -282,7 +282,7 @@ struct ForEachTupleImpl<Seq, F, EnableIfBreaksTuple<Seq, F>> {
(((break_or_not == loop_continue)
? (break_or_not = func(
Get<Indices, Sequence>::impl(std::forward<Sequence>(seq)),
std::integral_constant<std::size_t, Indices>{}))
index_constant<Indices>{}))
: (loop_continue)),
0)...});
}
......
......@@ -405,7 +405,7 @@ struct integral_hasher {
template <typename I>
using integral_hasher_avalanches =
std::integral_constant<bool, sizeof(I) >= 8 || sizeof(size_t) == 4>;
bool_constant<sizeof(I) >= 8 || sizeof(size_t) == 4>;
template <typename F>
struct float_hasher {
......
......@@ -212,7 +212,7 @@ void LogStreamVoidify<true>::operator&(std::ostream& stream) {
abort();
}
void logDisabledHelper(std::integral_constant<bool, true>) noexcept {
void logDisabledHelper(std::true_type) noexcept {
// This function can only be reached if we had a disabled fatal log message.
// This should never happen: LogCategory::setLevelLocked() does not allow
// setting the threshold for a category lower than FATAL (in production
......
......@@ -492,8 +492,7 @@ class LogStreamVoidify<true> {
* out how to format it.
*/
// clang-format off
inline void logDisabledHelper(std::integral_constant<bool, false>) noexcept {}
[[noreturn]] void logDisabledHelper(
std::integral_constant<bool, true>) noexcept;
inline void logDisabledHelper(std::false_type) noexcept {}
[[noreturn]] void logDisabledHelper(std::true_type) noexcept;
// clang-format on
} // namespace folly
......@@ -101,17 +101,17 @@
*
* This macro generally should not be used directly by end users.
*/
#define FB_LOG_IMPL(logger, level, type, ...) \
(!(logger).getCategory()->logCheck(level)) \
? ::folly::logDisabledHelper( \
std::integral_constant<bool, ::folly::isLogLevelFatal(level)>{}) \
: ::folly::LogStreamVoidify<::folly::isLogLevelFatal(level)>{} & \
::folly::LogStreamProcessor{(logger).getCategory(), \
(level), \
__FILE__, \
__LINE__, \
(type), \
##__VA_ARGS__} \
#define FB_LOG_IMPL(logger, level, type, ...) \
(!(logger).getCategory()->logCheck(level)) \
? ::folly::logDisabledHelper( \
::folly::bool_constant<::folly::isLogLevelFatal(level)>{}) \
: ::folly::LogStreamVoidify<::folly::isLogLevelFatal(level)>{} & \
::folly::LogStreamProcessor{(logger).getCategory(), \
(level), \
__FILE__, \
__LINE__, \
(type), \
##__VA_ARGS__} \
.stream()
/**
......
......@@ -151,7 +151,7 @@
#define XLOG_IMPL(level, cond, type, ...) \
(!XLOG_IS_ON_IMPL(level) || !(cond)) \
? ::folly::logDisabledHelper( \
std::integral_constant<bool, ::folly::isLogLevelFatal(level)>{}) \
::folly::bool_constant<::folly::isLogLevelFatal(level)>{}) \
: ::folly::LogStreamVoidify< ::folly::isLogLevelFatal(level)>{} & \
::folly::LogStreamProcessor( \
[] { \
......
......@@ -604,10 +604,8 @@ struct Data : DataTracker<(f & IS_RELOCATABLE) != 0>,
namespace folly {
template <Flags f, size_t pad>
struct IsRelocatable<Data<f, pad>>
: std::integral_constant<bool,
(f & IS_RELOCATABLE) != 0
> {};
struct IsRelocatable<Data<f, pad>> : bool_constant<(f & IS_RELOCATABLE) != 0> {
};
} // namespace folly
//-----------------------------------------------------------------------------
......@@ -617,21 +615,17 @@ struct IsRelocatable<Data<f, pad>>
template <typename T>
struct isPropCopy : true_type {};
template <Flags f, size_t pad>
struct isPropCopy<Data<f, pad>> :
std::integral_constant<bool, (f & PROP_COPY) != 0> {};
struct isPropCopy<Data<f, pad>> : bool_constant<(f & PROP_COPY) != 0> {};
template <typename T>
struct isPropMove : true_type {};
template <Flags f, size_t pad>
struct isPropMove<Data<f, pad>> :
std::integral_constant<bool, (f & PROP_MOVE) != 0> {};
struct isPropMove<Data<f, pad>> : bool_constant<(f & PROP_MOVE) != 0> {};
template <typename T>
struct isPropSwap : true_type {};
template <Flags f, size_t pad>
struct isPropSwap<Data<f, pad>> :
std::integral_constant<bool, (f & PROP_SWAP) != 0> {};
struct isPropSwap<Data<f, pad>> : bool_constant<(f & PROP_SWAP) != 0> {};
struct AllocTracker {
static int Constructed;
......@@ -798,36 +792,30 @@ void isSane() {
template <typename T>
struct is_copy_constructibleAndAssignable
: std::integral_constant<bool,
std::is_copy_constructible<T>::value &&
std::is_copy_assignable<T>::value
> {};
: bool_constant<
std::is_copy_constructible<T>::value &&
std::is_copy_assignable<T>::value> {};
template <typename T>
struct is_move_constructibleAndAssignable
: std::integral_constant<bool,
std::is_move_constructible<T>::value &&
std::is_move_assignable<T>::value
> {};
: bool_constant<
std::is_move_constructible<T>::value &&
std::is_move_assignable<T>::value> {};
template <class Vector>
struct customAllocator
: std::integral_constant<bool,
!is_same<
typename Vector::allocator_type,
std::allocator<typename Vector::value_type>
>::value
> {};
: bool_constant<!is_same<
typename Vector::allocator_type,
std::allocator<typename Vector::value_type>>::value> {};
template <typename T>
struct special_move_assignable
: is_move_constructibleAndAssignable<T> {};
template <Flags f, size_t pad>
struct special_move_assignable<Data<f, pad>>
: std::integral_constant<bool,
is_move_constructibleAndAssignable<Data<f, pad>>::value ||
f & PROP_MOVE
> {};
: bool_constant<
is_move_constructibleAndAssignable<Data<f, pad>>::value ||
f & PROP_MOVE> {};
//=============================================================================
//=============================================================================
......@@ -919,7 +907,7 @@ uint64_t ReadTSC() {
BOOST_PP_SEQ_FOR_EACH(GEN_CLOSER, _, BOOST_PP_SEQ_REVERSE(argseq)) \
} \
template <class Vector> void test_ ## name ## 3 () { \
test_ ## name ## 2 <Vector> (std::integral_constant<bool, \
test_ ## name ## 2 <Vector> (bool_constant< \
restriction<typename Vector::value_type>::value && \
is_copy_constructible<typename Vector::value_type>::value \
>()); \
......@@ -935,7 +923,7 @@ uint64_t ReadTSC() {
return true; \
} \
template <class Vector> bool test_I_ ## name ## 3 () { \
return test_I_ ## name ## 2 <Vector> (std::integral_constant<bool, \
return test_I_ ## name ## 2 <Vector> (bool_constant< \
restriction<typename Vector::value_type>::value>()); \
return false; \
} \
......
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