typedef detail::IEEEFloat IEEEFloat;
typedef detail::DoubleAPFloat DoubleAPFloat;
- static_assert(std::is_standard_layout_v<IEEEFloat>);
+ static_assert(std::is_standard_layout<IEEEFloat>::value);
union Storage {
const fltSemantics *semantics;
} U;
template <typename T> static bool usesLayout(const fltSemantics &Semantics) {
- static_assert(std::is_same_v<T, IEEEFloat> ||
- std::is_same_v<T, DoubleAPFloat>);
- if (std::is_same_v<T, DoubleAPFloat>) {
+ static_assert(std::is_same<T, IEEEFloat>::value ||
+ std::is_same<T, DoubleAPFloat>::value);
+ if (std::is_same<T, DoubleAPFloat>::value) {
return &Semantics == &PPCDoubleDouble();
}
return &Semantics != &PPCDoubleDouble();
APFloat(const fltSemantics &Semantics, StringRef S);
APFloat(const fltSemantics &Semantics, integerPart I) : U(Semantics, I) {}
template <typename T,
- typename = std::enable_if_t<std::is_floating_point_v<T>>>
+ typename = std::enable_if_t<std::is_floating_point<T>::value>>
APFloat(const fltSemantics &Semantics, T V) = delete;
// TODO: Remove this constructor. This isn't faster than the first one.
APFloat(const fltSemantics &Semantics, uninitializedTag)
// instead.
template <typename T,
std::enable_if_t<
- std::conjunction_v<
+ std::conjunction<
std::negation<std::is_same<std::decay_t<T>, Any>>,
// We also disable this overload when an `Any` object can be
// converted to the parameter type because in that case,
// adopting it to work-around usage of `Any` with types that
// need to be implicitly convertible from an `Any`.
std::negation<std::is_convertible<Any, std::decay_t<T>>>,
- std::is_copy_constructible<std::decay_t<T>>>,
+ std::is_copy_constructible<std::decay_t<T>>>::value,
int> = 0>
Any(T &&Value) {
Storage =
/// ensure that only ArrayRefs of pointers can be converted.
template <typename U>
ArrayRef(const ArrayRef<U *> &A,
- std::enable_if_t<std::is_convertible_v<U *const *, T const *>> * =
- nullptr)
+ std::enable_if_t<std::is_convertible<U *const *, T const *>::value>
+ * = nullptr)
: Data(A.data()), Length(A.size()) {}
/// Construct an ArrayRef<const T*> from a SmallVector<T*>. This is
template <typename U, typename DummyT>
/*implicit*/ ArrayRef(
const SmallVectorTemplateCommon<U *, DummyT> &Vec,
- std::enable_if_t<std::is_convertible_v<U *const *, T const *>> * =
+ std::enable_if_t<std::is_convertible<U *const *, T const *>::value> * =
nullptr)
: Data(Vec.data()), Length(Vec.size()) {}
/// to ensure that only vectors of pointers can be converted.
template <typename U, typename A>
ArrayRef(const std::vector<U *, A> &Vec,
- std::enable_if_t<std::is_convertible_v<U *const *, T const *>> * =
- nullptr)
+ std::enable_if_t<std::is_convertible<U *const *, T const *>::value>
+ * = nullptr)
: Data(Vec.data()), Length(Vec.size()) {}
/// @}
/// The declaration here is extra complicated so that "arrayRef = {}"
/// continues to select the move assignment operator.
template <typename U>
- std::enable_if_t<std::is_same_v<U, T>, ArrayRef<T>> &
+ std::enable_if_t<std::is_same<U, T>::value, ArrayRef<T>> &
operator=(U &&Temporary) = delete;
/// Disallow accidental assignment from a temporary.
/// The declaration here is extra complicated so that "arrayRef = {}"
/// continues to select the move assignment operator.
template <typename U>
- std::enable_if_t<std::is_same_v<U, T>, ArrayRef<T>> &
+ std::enable_if_t<std::is_same<U, T>::value, ArrayRef<T>> &
operator=(std::initializer_list<U>) = delete;
/// @}
/// type so it can be packed and unpacked into a `bits` sized integer,
/// `Compressor` is specialized on signed-ness so no runtime cost is incurred.
/// The `pack` method also checks that the passed in `UserValue` is valid.
-template <typename T, unsigned Bits, bool = std::is_unsigned_v<T>>
+template <typename T, unsigned Bits, bool = std::is_unsigned<T>::value>
struct Compressor {
- static_assert(std::is_unsigned_v<T>, "T must be unsigned");
+ static_assert(std::is_unsigned<T>::value, "T must be unsigned");
using BP = BitPatterns<T, Bits>;
static T pack(T UserValue, T UserMaxValue) {
};
template <typename T, unsigned Bits> struct Compressor<T, Bits, false> {
- static_assert(std::is_signed_v<T>, "T must be signed");
+ static_assert(std::is_signed<T>::value, "T must be signed");
using BP = BitPatterns<T, Bits>;
static T pack(T UserValue, T UserMaxValue) {
/// Impl is where Bifield description and Storage are put together to interact
/// with values.
template <typename Bitfield, typename StorageType> struct Impl {
- static_assert(std::is_unsigned_v<StorageType>, "Storage must be unsigned");
+ static_assert(std::is_unsigned<StorageType>::value,
+ "Storage must be unsigned");
using IntegerType = typename Bitfield::IntegerType;
using C = Compressor<IntegerType, Bitfield::Bits>;
using BP = BitPatterns<StorageType, Bitfield::Bits>;
/// consistent semantics, this excludes typed enums and `bool` that are replaced
/// with their unsigned counterparts. The correct type is restored in the public
/// API.
-template <typename T, bool = std::is_enum_v<T>> struct ResolveUnderlyingType {
+template <typename T, bool = std::is_enum<T>::value>
+struct ResolveUnderlyingType {
using type = std::underlying_type_t<T>;
};
template <typename T> struct ResolveUnderlyingType<T, false> {
/// \tparam Size The size of the field.
/// \tparam MaxValue For enums the maximum enum allowed.
template <typename T, unsigned Offset, unsigned Size,
- T MaxValue = std::is_enum_v<T>
+ T MaxValue = std::is_enum<T>::value
? T(0) // coupled with static_assert below
: std::numeric_limits<T>::max()>
struct Element {
static_assert(Bits > 0, "Bits must be non zero");
static constexpr size_t TypeBits = sizeof(IntegerType) * CHAR_BIT;
static_assert(Bits <= TypeBits, "Bits may not be greater than T size");
- static_assert(!std::is_enum_v<T> || MaxValue != T(0),
+ static_assert(!std::is_enum<T>::value || MaxValue != T(0),
"Enum Bitfields must provide a MaxValue");
- static_assert(!std::is_enum_v<T> || std::is_unsigned_v<IntegerType>,
+ static_assert(!std::is_enum<T>::value ||
+ std::is_unsigned<IntegerType>::value,
"Enum must be unsigned");
- static_assert(std::is_integral_v<IntegerType> &&
+ static_assert(std::is_integral<IntegerType>::value &&
std::numeric_limits<IntegerType>::is_integer,
"IntegerType must be an integer type");
///
/// \tparam IndexT - The type of the index into the bitvector.
template <typename IndexT> class CoalescingBitVector {
- static_assert(std::is_unsigned_v<IndexT>,
+ static_assert(std::is_unsigned<IndexT>::value,
"Index must be an unsigned integer.");
using ThisT = CoalescingBitVector<IndexT>;
}
static const KeyT getEmptyKey() {
- static_assert(std::is_base_of_v<DenseMapBase, DerivedT>,
+ static_assert(std::is_base_of<DenseMapBase, DerivedT>::value,
"Must pass the derived type to this template!");
return KeyInfoT::getEmptyKey();
}
};
template <typename T>
-struct FoldingSetTrait<T, std::enable_if_t<std::is_enum_v<T>>> {
+struct FoldingSetTrait<T, std::enable_if_t<std::is_enum<T>::value>> {
static void Profile(const T &X, FoldingSetNodeID &ID) {
ID.AddInteger(static_cast<std::underlying_type_t<T>>(X));
}
template <typename T>
using EnableIfTrivial =
std::enable_if_t<llvm::is_trivially_move_constructible<T>::value &&
- std::is_trivially_destructible_v<T>>;
+ std::is_trivially_destructible<T>::value>;
template <typename CallableT, typename ThisT>
using EnableUnlessSameType =
- std::enable_if_t<!std::is_same_v<remove_cvref_t<CallableT>, ThisT>>;
+ std::enable_if_t<!std::is_same<remove_cvref_t<CallableT>, ThisT>::value>;
template <typename CallableT, typename Ret, typename... Params>
-using EnableIfCallable = std::enable_if_t<std::disjunction_v<
+using EnableIfCallable = std::enable_if_t<std::disjunction<
std::is_void<Ret>,
std::is_same<decltype(std::declval<CallableT>()(std::declval<Params>()...)),
Ret>,
std::is_same<const decltype(std::declval<CallableT>()(
std::declval<Params>()...)),
Ret>,
- std::is_convertible<
- decltype(std::declval<CallableT>()(std::declval<Params>()...)), Ret>>>;
+ std::is_convertible<decltype(std::declval<CallableT>()(
+ std::declval<Params>()...)),
+ Ret>>::value>;
template <typename ReturnT, typename... ParamTs> class UniqueFunctionBase {
protected:
// It doesn't have to be exact though, and in one way it is more strict
// because we want to still be able to observe either moves *or* copies.
template <typename T> struct AdjustedParamTBase {
- static_assert(!std::is_reference_v<T>,
+ static_assert(!std::is_reference<T>::value,
"references should be handled by template specialization");
using type = std::conditional_t<
llvm::is_trivially_copy_constructible<T>::value &&
// for equality. For all the platforms we care about, this holds for integers
// and pointers, but there are platforms where it doesn't and we would like to
// support user-defined types which happen to satisfy this property.
-template <typename T>
-struct is_hashable_data
- : std::integral_constant<bool, ((is_integral_or_enum<T>::value ||
- std::is_pointer_v<T>)&&64 %
- sizeof(T) ==
- 0)> {};
+template <typename T> struct is_hashable_data
+ : std::integral_constant<bool, ((is_integral_or_enum<T>::value ||
+ std::is_pointer<T>::value) &&
+ 64 % sizeof(T) == 0)> {};
// Special case std::pair to detect when both types are viable and when there
// is no alignment-derived padding in the pair. This is a bit of a lie because
IntrusiveRefCntPtr(IntrusiveRefCntPtr &&S) : Obj(S.Obj) { S.Obj = nullptr; }
template <class X,
- std::enable_if_t<std::is_convertible_v<X *, T *>, bool> = true>
+ std::enable_if_t<std::is_convertible<X *, T *>::value, bool> = true>
IntrusiveRefCntPtr(IntrusiveRefCntPtr<X> S) : Obj(S.get()) {
S.Obj = nullptr;
}
template <class X,
- std::enable_if_t<std::is_convertible_v<X *, T *>, bool> = true>
+ std::enable_if_t<std::is_convertible<X *, T *>::value, bool> = true>
IntrusiveRefCntPtr(std::unique_ptr<X> S) : Obj(S.release()) {
retain();
}
// Asserts that allow us to let the compiler implement the destructor and
// copy/move constructors
- static_assert(std::is_trivially_destructible_v<Ptr>, "");
- static_assert(std::is_trivially_copy_constructible_v<Ptr>, "");
- static_assert(std::is_trivially_move_constructible_v<Ptr>, "");
+ static_assert(std::is_trivially_destructible<Ptr>::value, "");
+ static_assert(std::is_trivially_copy_constructible<Ptr>::value, "");
+ static_assert(std::is_trivially_move_constructible<Ptr>::value, "");
explicit constexpr PunnedPointer(intptr_t i = 0) { *this = i; }
/// Insert a sequence of new elements into the PriorityWorklist.
template <typename SequenceT>
- std::enable_if_t<!std::is_convertible_v<SequenceT, T>>
+ std::enable_if_t<!std::is_convertible<SequenceT, T>::value>
insert(SequenceT &&Input) {
if (std::begin(Input) == std::end(Input))
// Nothing to do for an empty input sequence.
/// * To access the number of arguments: Traits::num_args
/// * To access the type of an argument: Traits::arg_t<Index>
/// * To access the type of the result: Traits::result_t
-template <typename T, bool isClass = std::is_class_v<T>>
+template <typename T, bool isClass = std::is_class<T>::value>
struct function_traits : public function_traits<decltype(&T::operator())> {};
/// Overload for class function types.
/// Helper which adds two underlying types of enumeration type.
/// Implicit conversion to a common type is accepted.
template <typename EnumTy1, typename EnumTy2,
- typename UT1 = std::enable_if_t<std::is_enum_v<EnumTy1>,
+ typename UT1 = std::enable_if_t<std::is_enum<EnumTy1>::value,
std::underlying_type_t<EnumTy1>>,
- typename UT2 = std::enable_if_t<std::is_enum_v<EnumTy2>,
+ typename UT2 = std::enable_if_t<std::is_enum<EnumTy2>::value,
std::underlying_type_t<EnumTy2>>>
constexpr auto addEnumValues(EnumTy1 LHS, EnumTy2 RHS) {
return static_cast<UT1>(LHS) + static_cast<UT2>(RHS);
/// of \p IterT does not derive from bidirectional_iterator_tag, and to
/// bidirectional_iterator_tag otherwise.
template <typename IterT> struct fwd_or_bidi_tag {
- using type = typename fwd_or_bidi_tag_impl<std::is_base_of_v<
+ using type = typename fwd_or_bidi_tag_impl<std::is_base_of<
std::bidirectional_iterator_tag,
- typename std::iterator_traits<IterT>::iterator_category>>::type;
+ typename std::iterator_traits<IterT>::iterator_category>::value>::type;
};
} // namespace detail
}
/// Allow conversion to any type accepting an iterator_range.
- template <typename RangeT,
- typename = std::enable_if_t<
- std::is_constructible_v<RangeT, iterator_range<iterator>>>>
+ template <typename RangeT, typename = std::enable_if_t<std::is_constructible<
+ RangeT, iterator_range<iterator>>::value>>
operator RangeT() const {
return RangeT(iterator_range<iterator>(*this));
}
/// always be a reference, to avoid returning a reference to a temporary.
template <typename EltTy, typename FirstTy> class first_or_second_type {
public:
- using type = std::conditional_t<std::is_reference_v<EltTy>, FirstTy,
+ using type = std::conditional_t<std::is_reference<EltTy>::value, FirstTy,
std::remove_reference_t<FirstTy>>;
};
} // end namespace detail
/// Get the size of a range. This is a wrapper function around std::distance
/// which is only enabled when the operation is O(1).
template <typename R>
-auto size(
- R &&Range,
- std::enable_if_t<
- std::is_base_of_v<std::random_access_iterator_tag,
- typename std::iterator_traits<
- decltype(Range.begin())>::iterator_category>,
- void> * = nullptr) {
+auto size(R &&Range,
+ std::enable_if_t<
+ std::is_base_of<std::random_access_iterator_tag,
+ typename std::iterator_traits<decltype(
+ Range.begin())>::iterator_category>::value,
+ void> * = nullptr) {
return std::distance(Range.begin(), Range.end());
}
/// [&](StringRef name) { os << name; },
/// [&] { os << ", "; });
/// \endcode
-template <
- typename ForwardIterator, typename UnaryFunctor, typename NullaryFunctor,
- typename =
- std::enable_if_t<!std::is_constructible_v<StringRef, UnaryFunctor> &&
- !std::is_constructible_v<StringRef, NullaryFunctor>>>
+template <typename ForwardIterator, typename UnaryFunctor,
+ typename NullaryFunctor,
+ typename = std::enable_if_t<
+ !std::is_constructible<StringRef, UnaryFunctor>::value &&
+ !std::is_constructible<StringRef, NullaryFunctor>::value>>
inline void interleave(ForwardIterator begin, ForwardIterator end,
UnaryFunctor each_fn, NullaryFunctor between_fn) {
if (begin == end)
template <typename Container, typename UnaryFunctor, typename NullaryFunctor,
typename = std::enable_if_t<
- !std::is_constructible_v<StringRef, UnaryFunctor> &&
- !std::is_constructible_v<StringRef, NullaryFunctor>>>
+ !std::is_constructible<StringRef, UnaryFunctor>::value &&
+ !std::is_constructible<StringRef, NullaryFunctor>::value>>
inline void interleave(const Container &c, UnaryFunctor each_fn,
NullaryFunctor between_fn) {
interleave(c.begin(), c.end(), each_fn, between_fn);
IterTy &&Begin, IterTy &&End, unsigned N,
Pred &&ShouldBeCounted =
[](const decltype(*std::declval<IterTy>()) &) { return true; },
- std::enable_if_t<!std::is_base_of_v<
- std::random_access_iterator_tag,
+ std::enable_if_t<
+ !std::is_base_of<std::random_access_iterator_tag,
typename std::iterator_traits<std::remove_reference_t<
- decltype(Begin)>>::iterator_category>,
- void> * = nullptr) {
+ decltype(Begin)>>::iterator_category>::value,
+ void> * = nullptr) {
for (; N; ++Begin) {
if (Begin == End)
return false; // Too few.
IterTy &&Begin, IterTy &&End, unsigned N,
Pred &&ShouldBeCounted =
[](const decltype(*std::declval<IterTy>()) &) { return true; },
- std::enable_if_t<!std::is_base_of_v<
- std::random_access_iterator_tag,
+ std::enable_if_t<
+ !std::is_base_of<std::random_access_iterator_tag,
typename std::iterator_traits<std::remove_reference_t<
- decltype(Begin)>>::iterator_category>,
- void> * = nullptr) {
+ decltype(Begin)>>::iterator_category>::value,
+ void> * = nullptr) {
for (; N; ++Begin) {
if (Begin == End)
return false; // Too few.
function_ref(
Callable &&callable,
// This is not the copy-constructor.
- std::enable_if_t<!std::is_same_v<remove_cvref_t<Callable>, function_ref>>
- * = nullptr,
+ std::enable_if_t<!std::is_same<remove_cvref_t<Callable>,
+ function_ref>::value> * = nullptr,
// Functor must be callable and return a suitable type.
- std::enable_if_t<std::is_void_v<Ret> ||
- std::is_convertible_v<decltype(std::declval<Callable>()(
- std::declval<Params>()...)),
- Ret>> * = nullptr)
+ std::enable_if_t<std::is_void<Ret>::value ||
+ std::is_convertible<decltype(std::declval<Callable>()(
+ std::declval<Params>()...)),
+ Ret>::value> * = nullptr)
: callback(callback_fn<std::remove_reference_t<Callable>>),
callable(reinterpret_cast<intptr_t>(&callable)) {}
struct CheckedInt {
// Integral constructor, asserts if Value cannot be represented as intmax_t.
template <typename Integral,
- std::enable_if_t<std::is_integral_v<Integral>, bool> = 0>
+ std::enable_if_t<std::is_integral<Integral>::value, bool> = 0>
static CheckedInt from(Integral FromValue) {
if (!canTypeFitValue<intmax_t>(FromValue))
assertOutOfBounds();
}
// Enum constructor, asserts if Value cannot be represented as intmax_t.
- template <typename Enum, std::enable_if_t<std::is_enum_v<Enum>, bool> = 0>
+ template <typename Enum,
+ std::enable_if_t<std::is_enum<Enum>::value, bool> = 0>
static CheckedInt from(Enum FromValue) {
using type = std::underlying_type_t<Enum>;
return from<type>(static_cast<type>(FromValue));
// Convert to integral, asserts if Value cannot be represented as Integral.
template <typename Integral,
- std::enable_if_t<std::is_integral_v<Integral>, bool> = 0>
+ std::enable_if_t<std::is_integral<Integral>::value, bool> = 0>
Integral to() const {
if (!canTypeFitValue<Integral>(Value))
assertOutOfBounds();
// Convert to enum, asserts if Value cannot be represented as Enum's
// underlying type.
- template <typename Enum, std::enable_if_t<std::is_enum_v<Enum>, bool> = 0>
+ template <typename Enum,
+ std::enable_if_t<std::is_enum<Enum>::value, bool> = 0>
Enum to() const {
using type = std::underlying_type_t<Enum>;
return Enum(to<type>());
auto rend() const { return const_reverse_iterator(BeginValue - 1); }
private:
- static_assert(std::is_integral_v<T> || std::is_enum_v<T>,
+ static_assert(std::is_integral<T>::value || std::is_enum<T>::value,
"T must be an integral or enum type");
- static_assert(std::is_same_v<T, std::remove_cv_t<T>>,
+ static_assert(std::is_same<T, std::remove_cv_t<T>>::value,
"T must not be const nor volatile");
iterator BeginValue;
/// Note: Begin and End values have to be within [INTMAX_MIN, INTMAX_MAX] for
/// forward iteration (resp. [INTMAX_MIN + 1, INTMAX_MAX] for reverse
/// iteration).
-template <typename T, typename = std::enable_if_t<std::is_integral_v<T> &&
- !std::is_enum_v<T>>>
+template <typename T, typename = std::enable_if_t<std::is_integral<T>::value &&
+ !std::is_enum<T>::value>>
auto seq(T Begin, T End) {
return iota_range<T>(Begin, End, false);
}
/// Note: Begin and End values have to be within [INTMAX_MIN, INTMAX_MAX - 1]
/// for forward iteration (resp. [INTMAX_MIN + 1, INTMAX_MAX - 1] for reverse
/// iteration).
-template <typename T, typename = std::enable_if_t<std::is_integral_v<T> &&
- !std::is_enum_v<T>>>
+template <typename T, typename = std::enable_if_t<std::is_integral<T>::value &&
+ !std::is_enum<T>::value>>
auto seq_inclusive(T Begin, T End) {
return iota_range<T>(Begin, End, true);
}
/// Note: Begin and End values have to be within [INTMAX_MIN, INTMAX_MAX] for
/// forward iteration (resp. [INTMAX_MIN + 1, INTMAX_MAX] for reverse
/// iteration).
-template <typename EnumT, typename = std::enable_if_t<std::is_enum_v<EnumT>>>
+template <typename EnumT,
+ typename = std::enable_if_t<std::is_enum<EnumT>::value>>
auto enum_seq(EnumT Begin, EnumT End) {
static_assert(enum_iteration_traits<EnumT>::is_iterable,
"Enum type is not marked as iterable.");
/// Note: Begin and End values have to be within [INTMAX_MIN, INTMAX_MAX] for
/// forward iteration (resp. [INTMAX_MIN + 1, INTMAX_MAX] for reverse
/// iteration).
-template <typename EnumT, typename = std::enable_if_t<std::is_enum_v<EnumT>>>
+template <typename EnumT,
+ typename = std::enable_if_t<std::is_enum<EnumT>::value>>
auto enum_seq(EnumT Begin, EnumT End, force_iteration_on_noniterable_enum_t) {
return iota_range<EnumT>(Begin, End, false);
}
/// Note: Begin and End values have to be within [INTMAX_MIN, INTMAX_MAX - 1]
/// for forward iteration (resp. [INTMAX_MIN + 1, INTMAX_MAX - 1] for reverse
/// iteration).
-template <typename EnumT, typename = std::enable_if_t<std::is_enum_v<EnumT>>>
+template <typename EnumT,
+ typename = std::enable_if_t<std::is_enum<EnumT>::value>>
auto enum_seq_inclusive(EnumT Begin, EnumT End) {
static_assert(enum_iteration_traits<EnumT>::is_iterable,
"Enum type is not marked as iterable.");
/// Note: Begin and End values have to be within [INTMAX_MIN, INTMAX_MAX - 1]
/// for forward iteration (resp. [INTMAX_MIN + 1, INTMAX_MAX - 1] for reverse
/// iteration).
-template <typename EnumT, typename = std::enable_if_t<std::is_enum_v<EnumT>>>
+template <typename EnumT,
+ typename = std::enable_if_t<std::is_enum<EnumT>::value>>
auto enum_seq_inclusive(EnumT Begin, EnumT End,
force_iteration_on_noniterable_enum_t) {
return iota_range<EnumT>(Begin, End, true);
template <typename IteratorT> class iterator_range;
template <class Iterator>
-using EnableIfConvertibleToInputIterator =
- std::enable_if_t<std::is_convertible_v<
- typename std::iterator_traits<Iterator>::iterator_category,
- std::input_iterator_tag>>;
+using EnableIfConvertibleToInputIterator = std::enable_if_t<std::is_convertible<
+ typename std::iterator_traits<Iterator>::iterator_category,
+ std::input_iterator_tag>::value>;
/// This is all the stuff common to all SmallVectors.
///
this->assertSafeToReferenceAfterResize(From, 0);
this->assertSafeToReferenceAfterResize(To - 1, 0);
}
- template <class ItTy,
- std::enable_if_t<!std::is_same_v<std::remove_const_t<ItTy>, T *>,
- bool> = false>
+ template <
+ class ItTy,
+ std::enable_if_t<!std::is_same<std::remove_const_t<ItTy>, T *>::value,
+ bool> = false>
void assertSafeToReferenceAfterClear(ItTy, ItTy) {}
/// Check whether any part of the range will be invalidated by growing.
this->assertSafeToAdd(From, To - From);
this->assertSafeToAdd(To - 1, To - From);
}
- template <class ItTy,
- std::enable_if_t<!std::is_same_v<std::remove_const_t<ItTy>, T *>,
- bool> = false>
+ template <
+ class ItTy,
+ std::enable_if_t<!std::is_same<std::remove_const_t<ItTy>, T *>::value,
+ bool> = false>
void assertSafeToAddRange(ItTy, ItTy) {}
/// Reserve enough space to add one element, and return the updated element
/// trivially assignable.
template <typename T, bool = (is_trivially_copy_constructible<T>::value) &&
(is_trivially_move_constructible<T>::value) &&
- std::is_trivially_destructible_v<T>>
+ std::is_trivially_destructible<T>::value>
class SmallVectorTemplateBase : public SmallVectorTemplateCommon<T> {
friend class SmallVectorTemplateCommon<T>;
template <typename T1, typename T2>
static void uninitialized_copy(
T1 *I, T1 *E, T2 *Dest,
- std::enable_if_t<std::is_same_v<std::remove_const_t<T1>, T2>> * =
+ std::enable_if_t<std::is_same<std::remove_const_t<T1>, T2>::value> * =
nullptr) {
// Use memcpy for PODs iterated by pointers (which includes SmallVector
// iterators): std::uninitialized_copy optimizes to memmove, but we can
}
template <typename U,
- typename = std::enable_if_t<std::is_convertible_v<U, T>>>
+ typename = std::enable_if_t<std::is_convertible<U, T>::value>>
explicit SmallVector(ArrayRef<U> A) : SmallVectorImpl<T>(N) {
this->append(A.begin(), A.end());
}
/// The declaration here is extra complicated so that `stringRef = {}`
/// and `stringRef = "abc"` continue to select the move assignment operator.
template <typename T>
- std::enable_if_t<std::is_same_v<T, std::string>, StringRef> &
+ std::enable_if_t<std::is_same<T, std::string>::value, StringRef> &
operator=(T &&Str) = delete;
/// @}
}
// Implicit conversion to ArrayRef<U> if EltTy* implicitly converts to U*.
- template <typename U, std::enable_if_t<
- std::is_convertible_v<ArrayRef<EltTy>, ArrayRef<U>>,
- bool> = false>
+ template <
+ typename U,
+ std::enable_if_t<std::is_convertible<ArrayRef<EltTy>, ArrayRef<U>>::value,
+ bool> = false>
operator ArrayRef<U>() const {
return operator ArrayRef<EltTy>();
}
// This implementation of bit_cast is different from the C++20 one in two ways:
// - It isn't constexpr because that requires compiler support.
// - It requires trivially-constructible To, to avoid UB in the implementation.
-template <typename To, typename From,
- typename = std::enable_if_t<sizeof(To) == sizeof(From)>,
- typename = std::enable_if_t<std::is_trivially_constructible_v<To>>,
- typename = std::enable_if_t<std::is_trivially_copyable_v<To>>,
- typename = std::enable_if_t<std::is_trivially_copyable_v<From>>>
+template <
+ typename To, typename From,
+ typename = std::enable_if_t<sizeof(To) == sizeof(From)>,
+ typename = std::enable_if_t<std::is_trivially_constructible<To>::value>,
+ typename = std::enable_if_t<std::is_trivially_copyable<To>::value>,
+ typename = std::enable_if_t<std::is_trivially_copyable<From>::value>>
[[nodiscard]] inline To bit_cast(const From &from) noexcept {
#if __has_builtin(__builtin_bit_cast)
return __builtin_bit_cast(To, from);
protected:
enum {
- IsRandomAccess =
- std::is_base_of_v<std::random_access_iterator_tag, IteratorCategoryT>,
- IsBidirectional =
- std::is_base_of_v<std::bidirectional_iterator_tag, IteratorCategoryT>,
+ IsRandomAccess = std::is_base_of<std::random_access_iterator_tag,
+ IteratorCategoryT>::value,
+ IsBidirectional = std::is_base_of<std::bidirectional_iterator_tag,
+ IteratorCategoryT>::value,
};
/// A proxy object for computing a reference via indirecting a copy of an
typename DifferenceTypeT =
typename std::iterator_traits<WrappedIteratorT>::difference_type,
typename PointerT = std::conditional_t<
- std::is_same_v<
- T, typename std::iterator_traits<WrappedIteratorT>::value_type>,
+ std::is_same<T, typename std::iterator_traits<
+ WrappedIteratorT>::value_type>::value,
typename std::iterator_traits<WrappedIteratorT>::pointer, T *>,
typename ReferenceT = std::conditional_t<
- std::is_same_v<
- T, typename std::iterator_traits<WrappedIteratorT>::value_type>,
+ std::is_same<T, typename std::iterator_traits<
+ WrappedIteratorT>::value_type>::value,
typename std::iterator_traits<WrappedIteratorT>::reference, T &>>
class iterator_adaptor_base
: public iterator_facade_base<DerivedT, IteratorCategoryT, T,