forked from OctaForge/libostd
convert the remaining type_traits.hh checking traits to constexpr bools
This commit is contained in:
parent
a6744105dc
commit
818cbe376a
|
@ -736,9 +736,8 @@ namespace detail {
|
|||
template<typename>
|
||||
static Nat test(...);
|
||||
|
||||
static constexpr bool value = IsConvertible<
|
||||
decltype(test<T>(nullptr)), R
|
||||
>::value;
|
||||
static constexpr bool value
|
||||
= IsConvertible<decltype(test<T>(nullptr)), R>;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
|
|
|
@ -56,8 +56,7 @@ public:
|
|||
|
||||
template<typename U>
|
||||
HashRange(const HashRange<U> &v, EnableIf<
|
||||
IsSame<RemoveCv<T>, RemoveCv<U>> &&
|
||||
IsConvertible<U *, T *>::value, bool
|
||||
IsSame<RemoveCv<T>, RemoveCv<U>> && IsConvertible<U *, T *>, bool
|
||||
> = true): p_node((Chain *)v.p_node) {}
|
||||
|
||||
HashRange &operator=(const HashRange &v) {
|
||||
|
@ -95,8 +94,7 @@ public:
|
|||
|
||||
template<typename U>
|
||||
BucketRange(const BucketRange<U> &v, EnableIf<
|
||||
IsSame<RemoveCv<T>, RemoveCv<U>> &&
|
||||
IsConvertible<U *, T *>::value, bool
|
||||
IsSame<RemoveCv<T>, RemoveCv<U>> && IsConvertible<U *, T *>, bool
|
||||
> = true): p_node((Chain *)v.p_node), p_end((Chain *)v.p_end) {}
|
||||
|
||||
BucketRange &operator=(const BucketRange &v) {
|
||||
|
|
|
@ -185,7 +185,7 @@ namespace detail {
|
|||
|
||||
template<typename T, typename ...TT, typename U, typename ...UU>
|
||||
struct TupleConvertibleBase<TupleTypes<T, TT...>, TupleTypes<U, UU...>>:
|
||||
IntegralConstant<bool, IsConvertible<T, U>::value &&
|
||||
IntegralConstant<bool, IsConvertible<T, U> &&
|
||||
TupleConvertibleBase<TupleTypes<TT...>,
|
||||
TupleTypes<UU...>>::value> {};
|
||||
|
||||
|
|
|
@ -86,7 +86,7 @@ namespace detail {
|
|||
KeysetImpl(KeysetImpl &&m, const A &alloc): Base(move(m), alloc) {}
|
||||
|
||||
template<typename R, typename = EnableIf<
|
||||
IsInputRange<R> && IsConvertible<RangeReference<R>, Value>::value
|
||||
IsInputRange<R> && IsConvertible<RangeReference<R>, Value>
|
||||
>> KeysetImpl(R range, Size size = 0, const H &hf = H(),
|
||||
const C &eqf = C(), const A &alloc = A()
|
||||
): Base(size ? size : detail::estimate_hrsize(range),
|
||||
|
@ -126,7 +126,7 @@ namespace detail {
|
|||
}
|
||||
|
||||
template<typename R, typename = EnableIf<
|
||||
IsInputRange<R> && IsConvertible<RangeReference<R>, Value>::value
|
||||
IsInputRange<R> && IsConvertible<RangeReference<R>, Value>
|
||||
>> KeysetImpl &operator=(R range) {
|
||||
Base::assign_range(range);
|
||||
return *this;
|
||||
|
|
|
@ -86,7 +86,7 @@ namespace detail {
|
|||
MapImpl(MapImpl &&m, const A &alloc): Base(move(m), alloc) {}
|
||||
|
||||
template<typename R, typename = EnableIf<
|
||||
IsInputRange<R> && IsConvertible<RangeReference<R>, Value>::value
|
||||
IsInputRange<R> && IsConvertible<RangeReference<R>, Value>
|
||||
>> MapImpl(R range, Size size = 0, const H &hf = H(),
|
||||
const C &eqf = C(), const A &alloc = A()
|
||||
): Base(size ? size : detail::estimate_hrsize(range),
|
||||
|
@ -126,7 +126,7 @@ namespace detail {
|
|||
}
|
||||
|
||||
template<typename R, typename = EnableIf<
|
||||
IsInputRange<R> && IsConvertible<RangeReference<R>, Value>::value
|
||||
IsInputRange<R> && IsConvertible<RangeReference<R>, Value>
|
||||
>> MapImpl &operator=(R range) {
|
||||
Base::assign_range(range);
|
||||
return *this;
|
||||
|
|
|
@ -24,7 +24,7 @@ struct Nothing {
|
|||
constexpr Nothing nothing = Nothing(0);
|
||||
|
||||
namespace detail {
|
||||
template<typename T, bool = IsTriviallyDestructible<T>::value>
|
||||
template<typename T, bool = IsTriviallyDestructible<T>>
|
||||
class MaybeStorage {
|
||||
protected:
|
||||
using Value = T;
|
||||
|
@ -101,7 +101,7 @@ public:
|
|||
"Initialization of Maybe with Nothing is not allowed.");
|
||||
static_assert(IsObject<T>,
|
||||
"Initialization of Maybe with non-object type is not allowed.");
|
||||
static_assert(IsDestructible<T>::value,
|
||||
static_assert(IsDestructible<T>,
|
||||
"Initialization of Maybe with a non-destructible object is not allowed.");
|
||||
|
||||
constexpr Maybe() {}
|
||||
|
@ -219,7 +219,7 @@ public:
|
|||
constexpr Value value_or(U &&v) const & {
|
||||
static_assert(IsCopyConstructible<Value>,
|
||||
"Maybe<T>::value_or: T must be copy constructible");
|
||||
static_assert(IsConvertible<U, Value>::value,
|
||||
static_assert(IsConvertible<U, Value>,
|
||||
"Maybe<T>::value_or: U must be convertible to T");
|
||||
return this->p_engaged ? this->p_value : Value(forward<U>(v));
|
||||
}
|
||||
|
@ -228,7 +228,7 @@ public:
|
|||
Value value_or(U &&v) && {
|
||||
static_assert(IsMoveConstructible<Value>,
|
||||
"Maybe<T>::value_or: T must be copy constructible");
|
||||
static_assert(IsConvertible<U, Value>::value,
|
||||
static_assert(IsConvertible<U, Value>,
|
||||
"Maybe<T>::value_or: U must be convertible to T");
|
||||
return this->p_engaged ? move(this->p_value)
|
||||
: Value(forward<U>(v));
|
||||
|
|
|
@ -262,9 +262,8 @@ public:
|
|||
|
||||
template<typename TT, typename DD>
|
||||
Box(Box<TT, DD> &&u, EnableIf<!IsArray<TT>
|
||||
&& IsConvertible<typename Box<TT, DD>::Pointer, Pointer>::value
|
||||
&& IsConvertible<DD, D>::value
|
||||
&& (!IsReference<D> || IsSame<D, DD>)
|
||||
&& IsConvertible<typename Box<TT, DD>::Pointer, Pointer>
|
||||
&& IsConvertible<DD, D> && (!IsReference<D> || IsSame<D, DD>)
|
||||
> = Nat()): p_stor(u.release(), forward<DD>(u.get_deleter())) {}
|
||||
|
||||
Box &operator=(Box &&u) {
|
||||
|
@ -275,7 +274,7 @@ public:
|
|||
|
||||
template<typename TT, typename DD>
|
||||
EnableIf<!IsArray<TT>
|
||||
&& IsConvertible<typename Box<TT, DD>::Pointer, Pointer>::value
|
||||
&& IsConvertible<typename Box<TT, DD>::Pointer, Pointer>
|
||||
&& IsAssignable<D &, DD &&>,
|
||||
Box &
|
||||
> operator=(Box<TT, DD> &&u) {
|
||||
|
@ -327,7 +326,8 @@ namespace detail {
|
|||
template<typename T, typename U, bool = IsSame<
|
||||
RemoveCv<PointerElement<T>>,
|
||||
RemoveCv<PointerElement<U>>
|
||||
>> struct SameOrLessCvQualifiedBase: IsConvertible<T, U> {};
|
||||
>> struct SameOrLessCvQualifiedBase:
|
||||
IntegralConstant<bool, IsConvertible<T, U>> {};
|
||||
|
||||
template<typename T, typename U>
|
||||
struct SameOrLessCvQualifiedBase<T, U, false>: False {};
|
||||
|
@ -392,8 +392,7 @@ public:
|
|||
Box(Box<TT, DD> &&u, EnableIf<IsArray<TT>
|
||||
&& detail::SameOrLessCvQualified<typename Box<TT, DD>::Pointer,
|
||||
Pointer>::value
|
||||
&& IsConvertible<DD, D>::value
|
||||
&& (!IsReference<D> || IsSame<D, DD>)> = Nat()
|
||||
&& IsConvertible<DD, D> && (!IsReference<D> || IsSame<D, DD>)> = Nat()
|
||||
): p_stor(u.release(), forward<DD>(u.get_deleter())) {}
|
||||
|
||||
Box &operator=(Box &&u) {
|
||||
|
@ -1067,7 +1066,7 @@ namespace detail {
|
|||
|
||||
template<typename T, typename A, bool = HasAllocatorType<T>::value>
|
||||
struct UsesAllocatorBase: IntegralConstant<bool,
|
||||
IsConvertible<A, typename T::Allocator>::value
|
||||
IsConvertible<A, typename T::Allocator>
|
||||
> {};
|
||||
|
||||
template<typename T, typename A>
|
||||
|
|
|
@ -71,9 +71,8 @@ namespace detail {
|
|||
// is input range
|
||||
|
||||
namespace detail {
|
||||
template<typename T, bool = IsConvertible<
|
||||
RangeCategory<T>, InputRangeTag
|
||||
>::value> struct IsInputRangeCore: False {};
|
||||
template<typename T, bool = IsConvertible<RangeCategory<T>, InputRangeTag>>
|
||||
struct IsInputRangeCore: False {};
|
||||
|
||||
template<typename T>
|
||||
struct IsInputRangeCore<T, true>: True {};
|
||||
|
@ -91,9 +90,8 @@ static constexpr bool IsInputRange = detail::IsInputRangeBase<T>::value;
|
|||
// is forward range
|
||||
|
||||
namespace detail {
|
||||
template<typename T, bool = IsConvertible<
|
||||
RangeCategory<T>, ForwardRangeTag
|
||||
>::value> struct IsForwardRangeCore: False {};
|
||||
template<typename T, bool = IsConvertible<RangeCategory<T>, ForwardRangeTag>>
|
||||
struct IsForwardRangeCore: False {};
|
||||
|
||||
template<typename T>
|
||||
struct IsForwardRangeCore<T, true>: True {};
|
||||
|
@ -113,7 +111,7 @@ static constexpr bool IsForwardRange = detail::IsForwardRangeBase<T>::value;
|
|||
namespace detail {
|
||||
template<typename T, bool = IsConvertible<
|
||||
RangeCategory<T>, BidirectionalRangeTag
|
||||
>::value> struct IsBidirectionalRangeCore: False {};
|
||||
>> struct IsBidirectionalRangeCore: False {};
|
||||
|
||||
template<typename T>
|
||||
struct IsBidirectionalRangeCore<T, true>: True {};
|
||||
|
@ -134,7 +132,7 @@ template<typename T> static constexpr bool IsBidirectionalRange
|
|||
namespace detail {
|
||||
template<typename T, bool = IsConvertible<
|
||||
RangeCategory<T>, RandomAccessRangeTag
|
||||
>::value> struct IsRandomAccessRangeCore: False {};
|
||||
>> struct IsRandomAccessRangeCore: False {};
|
||||
|
||||
template<typename T>
|
||||
struct IsRandomAccessRangeCore<T, true>: True {};
|
||||
|
@ -155,7 +153,7 @@ template<typename T> static constexpr bool IsRandomAccessRange
|
|||
namespace detail {
|
||||
template<typename T, bool = IsConvertible<
|
||||
RangeCategory<T>, FiniteRandomAccessRangeTag
|
||||
>::value> struct IsFiniteRandomAccessRangeCore: False {};
|
||||
>> struct IsFiniteRandomAccessRangeCore: False {};
|
||||
|
||||
template<typename T>
|
||||
struct IsFiniteRandomAccessRangeCore<T, true>: True {};
|
||||
|
@ -181,7 +179,7 @@ template<typename T> static constexpr bool IsInfiniteRandomAccessRange
|
|||
namespace detail {
|
||||
template<typename T, bool = IsConvertible<
|
||||
RangeCategory<T>, ContiguousRangeTag
|
||||
>::value> struct IsContiguousRangeCore: False {};
|
||||
>> struct IsContiguousRangeCore: False {};
|
||||
|
||||
template<typename T>
|
||||
struct IsContiguousRangeCore<T, true>: True {};
|
||||
|
@ -210,7 +208,7 @@ namespace detail {
|
|||
|
||||
template<typename T, bool = (IsConvertible<
|
||||
RangeCategory<T>, OutputRangeTag
|
||||
>::value || (IsInputRange<T> &&
|
||||
> || (IsInputRange<T> &&
|
||||
(detail::OutputRangeTest<T, const RangeValue<T> &>::value ||
|
||||
detail::OutputRangeTest<T, RangeValue<T> &&>::value ||
|
||||
detail::OutputRangeTest<T, RangeValue<T> >::value)
|
||||
|
@ -304,9 +302,8 @@ public:
|
|||
RangeHalf() = delete;
|
||||
RangeHalf(const T &range): p_range(range) {}
|
||||
|
||||
template<typename U, typename = EnableIf<
|
||||
IsConvertible<U, T>::value
|
||||
>> RangeHalf(const RangeHalf<U> &half): p_range(half.p_range) {}
|
||||
template<typename U, typename = EnableIf<IsConvertible<U, T>>>
|
||||
RangeHalf(const RangeHalf<U> &half): p_range(half.p_range) {}
|
||||
|
||||
RangeHalf(const RangeHalf &half): p_range(half.p_range) {}
|
||||
RangeHalf(RangeHalf &&half): p_range(move(half.p_range)) {}
|
||||
|
@ -899,16 +896,13 @@ public:
|
|||
|
||||
template<typename U>
|
||||
PointerRange(T *beg, U end, EnableIf<
|
||||
(IsPointer<U> || IsNullPointer<U>) &&
|
||||
IsConvertible<U, T *>::value, Nat
|
||||
(IsPointer<U> || IsNullPointer<U>) && IsConvertible<U, T *>, Nat
|
||||
> = Nat()): p_beg(beg), p_end(end) {}
|
||||
|
||||
PointerRange(T *beg, Size n): p_beg(beg), p_end(beg + n) {}
|
||||
|
||||
template<typename U, typename = EnableIf<
|
||||
IsConvertible<U *, T *>::value
|
||||
>> PointerRange(const PointerRange<U> &v):
|
||||
p_beg(&v[0]), p_end(&v[v.size()]) {}
|
||||
template<typename U, typename = EnableIf<IsConvertible<U *, T *>>>
|
||||
PointerRange(const PointerRange<U> &v): p_beg(&v[0]), p_end(&v[v.size()]) {}
|
||||
|
||||
PointerRange &operator=(const PointerRange &v) {
|
||||
p_beg = v.p_beg;
|
||||
|
@ -1051,8 +1045,7 @@ namespace detail {
|
|||
|
||||
template<typename T, typename U>
|
||||
PointerRange<T> iter(T *a, U b, EnableIf<
|
||||
(IsPointer<U> || IsNullPointer<U>) &&
|
||||
IsConvertible<U, T *>::value, detail::PtrNat
|
||||
(IsPointer<U> || IsNullPointer<U>) && IsConvertible<U, T *>, detail::PtrNat
|
||||
> = detail::PtrNat()) {
|
||||
return PointerRange<T>(a, b);
|
||||
}
|
||||
|
|
|
@ -75,7 +75,7 @@ namespace detail {
|
|||
SetImpl(SetImpl &&m, const A &alloc): Base(move(m), alloc) {}
|
||||
|
||||
template<typename R, typename = EnableIf<
|
||||
IsInputRange<R> && IsConvertible<RangeReference<R>, Value>::value
|
||||
IsInputRange<R> && IsConvertible<RangeReference<R>, Value>
|
||||
>> SetImpl(R range, Size size = 0, const H &hf = H(),
|
||||
const C &eqf = C(), const A &alloc = A()
|
||||
): Base(size ? size : detail::estimate_hrsize(range),
|
||||
|
@ -115,7 +115,7 @@ namespace detail {
|
|||
}
|
||||
|
||||
template<typename R, typename = EnableIf<
|
||||
IsInputRange<R> && IsConvertible<RangeReference<R>, Value>::value
|
||||
IsInputRange<R> && IsConvertible<RangeReference<R>, Value>
|
||||
>> SetImpl &operator=(R range) {
|
||||
Base::assign_range(range);
|
||||
return *this;
|
||||
|
|
|
@ -32,35 +32,30 @@ public:
|
|||
|
||||
template<typename U>
|
||||
CharRangeBase(T *beg, U end, EnableIf<
|
||||
(IsPointer<U> || IsNullPointer<U>) &&
|
||||
IsConvertible<U, T *>::value, Nat
|
||||
(IsPointer<U> || IsNullPointer<U>) && IsConvertible<U, T *>, Nat
|
||||
> = Nat()): p_beg(beg), p_end(end) {}
|
||||
|
||||
CharRangeBase(T *beg, Size n): p_beg(beg), p_end(beg + n) {}
|
||||
|
||||
/* TODO: traits for utf-16/utf-32 string lengths, for now assume char */
|
||||
template<typename U>
|
||||
CharRangeBase(U beg, EnableIf<
|
||||
IsConvertible<U, T *>::value && !IsArray<U>, Nat
|
||||
> = Nat()): p_beg(beg), p_end((T *)beg + (beg ? strlen(beg) : 0)) {}
|
||||
CharRangeBase(U beg, EnableIf<IsConvertible<U, T *> && !IsArray<U>, Nat>
|
||||
= Nat()): p_beg(beg), p_end((T *)beg + (beg ? strlen(beg) : 0)) {}
|
||||
|
||||
CharRangeBase(Nullptr): p_beg(nullptr), p_end(nullptr) {}
|
||||
|
||||
template<typename U, Size N>
|
||||
CharRangeBase(U (&beg)[N], EnableIf<
|
||||
IsConvertible<U *, T *>::value, Nat
|
||||
> = Nat()): p_beg(beg),
|
||||
p_end(beg + N - (beg[N - 1] == '\0')) {}
|
||||
CharRangeBase(U (&beg)[N], EnableIf<IsConvertible<U *, T *>, Nat> = Nat()):
|
||||
p_beg(beg), p_end(beg + N - (beg[N - 1] == '\0')) {}
|
||||
|
||||
template<typename U, typename A>
|
||||
CharRangeBase(const StringBase<U, A> &s, EnableIf<
|
||||
IsConvertible<U *, T *>::value, Nat
|
||||
IsConvertible<U *, T *>, Nat
|
||||
> = Nat()): p_beg(s.data()),
|
||||
p_end(s.data() + s.size()) {}
|
||||
|
||||
template<typename U, typename = EnableIf<
|
||||
IsConvertible<U *, T *>::value
|
||||
>> CharRangeBase(const CharRangeBase<U> &v):
|
||||
template<typename U, typename = EnableIf<IsConvertible<U *, T *>>>
|
||||
CharRangeBase(const CharRangeBase<U> &v):
|
||||
p_beg(&v[0]), p_end(&v[v.size()]) {}
|
||||
|
||||
CharRangeBase &operator=(const CharRangeBase &v) {
|
||||
|
@ -317,16 +312,16 @@ public:
|
|||
|
||||
template<typename U>
|
||||
StringBase(U v, const EnableIf<
|
||||
IsConvertible<U, const Value *>::value && !IsArray<U>, A
|
||||
IsConvertible<U, const Value *> && !IsArray<U>, A
|
||||
> &a = A()): StringBase(ConstRange(v), a) {}
|
||||
|
||||
template<typename U, Size N>
|
||||
StringBase(U (&v)[N], const EnableIf<
|
||||
IsConvertible<U *, const Value *>::value, A
|
||||
IsConvertible<U *, const Value *>, A
|
||||
> &a = A()): StringBase(ConstRange(v), a) {}
|
||||
|
||||
template<typename R, typename = EnableIf<
|
||||
IsInputRange<R> && IsConvertible<RangeReference<R>, Value>::value
|
||||
IsInputRange<R> && IsConvertible<RangeReference<R>, Value>
|
||||
>> StringBase(R range, const A &a = A()): StringBase(a) {
|
||||
ctor_from_range(range);
|
||||
}
|
||||
|
@ -384,21 +379,19 @@ public:
|
|||
}
|
||||
|
||||
template<typename U>
|
||||
EnableIf<
|
||||
IsConvertible<U, const Value *>::value && !IsArray<U>, StringBase &
|
||||
> operator=(U v) {
|
||||
EnableIf<IsConvertible<U, const Value *> && !IsArray<U>, StringBase &>
|
||||
operator=(U v) {
|
||||
return operator=(ConstRange(v));
|
||||
}
|
||||
|
||||
template<typename U, Size N>
|
||||
EnableIf<
|
||||
IsConvertible<U *, const Value *>::value, StringBase &
|
||||
> operator=(U (&v)[N]) {
|
||||
EnableIf<IsConvertible<U *, const Value *>, StringBase &>
|
||||
operator=(U (&v)[N]) {
|
||||
return operator=(ConstRange(v));
|
||||
}
|
||||
|
||||
template<typename R, typename = EnableIf<
|
||||
IsInputRange<R> && IsConvertible<RangeReference<R>, Value>::value
|
||||
IsInputRange<R> && IsConvertible<RangeReference<R>, Value>
|
||||
>> StringBase &operator=(const R &r) {
|
||||
clear();
|
||||
ctor_from_range(r);
|
||||
|
@ -500,9 +493,8 @@ public:
|
|||
}
|
||||
|
||||
template<typename R, typename = EnableIf<
|
||||
IsInputRange<R> &&
|
||||
IsConvertible<RangeReference<R>, Value>::value &&
|
||||
!IsConvertible<R, ConstRange>::value
|
||||
IsInputRange<R> && IsConvertible<RangeReference<R>, Value> &&
|
||||
!IsConvertible<R, ConstRange>
|
||||
>> StringBase &append(R range) {
|
||||
Size nadd = 0;
|
||||
for (; !range.empty(); range.pop_front()) {
|
||||
|
@ -578,8 +570,8 @@ inline namespace literals { inline namespace string_literals {
|
|||
} }
|
||||
|
||||
namespace detail {
|
||||
template<typename T, bool = IsConvertible<T, ConstCharRange>::value,
|
||||
bool = IsConvertible<T, char>::value>
|
||||
template<typename T, bool = IsConvertible<T, ConstCharRange>,
|
||||
bool = IsConvertible<T, char>>
|
||||
struct ConcatPut;
|
||||
|
||||
template<typename T, bool B>
|
||||
|
|
|
@ -582,108 +582,113 @@ namespace detail {
|
|||
: DtibleImpl<T, IsReference<T>> {};
|
||||
|
||||
template<typename T> struct DtibleFalse<T, true>: False {};
|
||||
|
||||
template<typename T>
|
||||
struct IsDestructibleBase: detail::DtibleFalse<T, IsFunction<T>> {};
|
||||
|
||||
template<typename T> struct IsDestructibleBase<T[]>: False {};
|
||||
template< > struct IsDestructibleBase<void>: False {};
|
||||
} /* namespace detail */
|
||||
|
||||
template<typename T>
|
||||
struct IsDestructible: detail::DtibleFalse<T, IsFunction<T>> {};
|
||||
|
||||
template<typename T> struct IsDestructible<T[]>: False {};
|
||||
template< > struct IsDestructible<void>: False {};
|
||||
static constexpr bool IsDestructible = detail::IsDestructibleBase<T>::value;
|
||||
|
||||
/* is trivially constructible */
|
||||
|
||||
namespace detail {
|
||||
template<typename T, typename ...A>
|
||||
struct IsTriviallyConstructible: False {};
|
||||
struct IsTriviallyConstructibleBase: False {};
|
||||
|
||||
template<typename T>
|
||||
struct IsTriviallyConstructible<T>: IntegralConstant<bool,
|
||||
struct IsTriviallyConstructibleBase<T>: IntegralConstant<bool,
|
||||
__has_trivial_constructor(T)
|
||||
> {};
|
||||
|
||||
template<typename T>
|
||||
struct IsTriviallyConstructible<T, T &>: IntegralConstant<bool,
|
||||
struct IsTriviallyConstructibleBase<T, T &>: IntegralConstant<bool,
|
||||
__has_trivial_copy(T)
|
||||
> {};
|
||||
|
||||
template<typename T>
|
||||
struct IsTriviallyConstructible<T, const T &>: IntegralConstant<bool,
|
||||
struct IsTriviallyConstructibleBase<T, const T &>: IntegralConstant<bool,
|
||||
__has_trivial_copy(T)
|
||||
> {};
|
||||
|
||||
template<typename T>
|
||||
struct IsTriviallyConstructible<T, T &&>: IntegralConstant<bool,
|
||||
struct IsTriviallyConstructibleBase<T, T &&>: IntegralConstant<bool,
|
||||
__has_trivial_copy(T)
|
||||
> {};
|
||||
} /* namespace detail */
|
||||
|
||||
template<typename T, typename ...A>
|
||||
static constexpr bool IsTriviallyConstructible
|
||||
= detail::IsTriviallyConstructibleBase<T, A...>::value;
|
||||
|
||||
/* is trivially default constructible */
|
||||
|
||||
template<typename T>
|
||||
struct IsTriviallyDefaultConstructible: IsTriviallyConstructible<T> {};
|
||||
template<typename T> static constexpr bool IsTriviallyDefaultConstructible
|
||||
= IsTriviallyConstructible<T>;
|
||||
|
||||
/* is trivially copy constructible */
|
||||
|
||||
template<typename T>
|
||||
struct IsTriviallyCopyConstructible: IsTriviallyConstructible<T,
|
||||
AddLvalueReference<const T>
|
||||
> {};
|
||||
template<typename T> static constexpr bool IsTriviallyCopyConstructible
|
||||
= IsTriviallyConstructible<T, AddLvalueReference<const T>>;
|
||||
|
||||
/* is trivially move constructible */
|
||||
|
||||
template<typename T>
|
||||
struct IsTriviallyMoveConstructible: IsTriviallyConstructible<T,
|
||||
AddRvalueReference<T>
|
||||
> {};
|
||||
template<typename T> static constexpr bool IsTriviallyMoveConstructible
|
||||
= IsTriviallyConstructible<T, AddRvalueReference<T>>;
|
||||
|
||||
/* is trivially assignable */
|
||||
|
||||
namespace detail {
|
||||
template<typename T, typename ...A>
|
||||
struct IsTriviallyAssignable: False {};
|
||||
struct IsTriviallyAssignableBase: False {};
|
||||
|
||||
template<typename T>
|
||||
struct IsTriviallyAssignable<T>: IntegralConstant<bool,
|
||||
struct IsTriviallyAssignableBase<T>: IntegralConstant<bool,
|
||||
__has_trivial_assign(T)
|
||||
> {};
|
||||
|
||||
template<typename T>
|
||||
struct IsTriviallyAssignable<T, T &>: IntegralConstant<bool,
|
||||
struct IsTriviallyAssignableBase<T, T &>: IntegralConstant<bool,
|
||||
__has_trivial_copy(T)
|
||||
> {};
|
||||
|
||||
template<typename T>
|
||||
struct IsTriviallyAssignable<T, const T &>: IntegralConstant<bool,
|
||||
struct IsTriviallyAssignableBase<T, const T &>: IntegralConstant<bool,
|
||||
__has_trivial_copy(T)
|
||||
> {};
|
||||
|
||||
template<typename T>
|
||||
struct IsTriviallyAssignable<T, T &&>: IntegralConstant<bool,
|
||||
struct IsTriviallyAssignableBase<T, T &&>: IntegralConstant<bool,
|
||||
__has_trivial_copy(T)
|
||||
> {};
|
||||
} /* namespace detail */
|
||||
|
||||
template<typename T, typename ...A>
|
||||
static constexpr bool IsTriviallyAssignable
|
||||
= detail::IsTriviallyAssignableBase<T>::value;
|
||||
|
||||
/* is trivially copy assignable */
|
||||
|
||||
template<typename T>
|
||||
struct IsTriviallyCopyAssignable: IsTriviallyAssignable<T,
|
||||
AddLvalueReference<const T>
|
||||
> {};
|
||||
template<typename T> static constexpr bool IsTriviallyCopyAssignable
|
||||
= IsTriviallyAssignable<T, AddLvalueReference<const T>>;
|
||||
|
||||
/* is trivially move assignable */
|
||||
|
||||
template<typename T>
|
||||
struct IsTriviallyMoveAssignable: IsTriviallyAssignable<T,
|
||||
AddRvalueReference<T>
|
||||
> {};
|
||||
template<typename T> static constexpr bool IsTriviallyMoveAssignable
|
||||
= IsTriviallyAssignable<T, AddRvalueReference<T>>;
|
||||
|
||||
/* is trivially destructible */
|
||||
|
||||
template<typename T>
|
||||
struct IsTriviallyDestructible: IntegralConstant<bool,
|
||||
__has_trivial_destructor(T)
|
||||
> {};
|
||||
static constexpr bool IsTriviallyDestructible = __has_trivial_destructor(T);
|
||||
|
||||
/* is base of */
|
||||
|
||||
template<typename B, typename D>
|
||||
struct IsBaseOf: IntegralConstant<bool, __is_base_of(B, D)> {};
|
||||
static constexpr bool IsBaseOf = __is_base_of(B, D);
|
||||
|
||||
/* is convertible */
|
||||
|
||||
|
@ -708,35 +713,47 @@ namespace detail {
|
|||
};
|
||||
}
|
||||
|
||||
template<typename F, typename T>
|
||||
struct IsConvertible: detail::IsConvertibleBase<F, T>::Type {};
|
||||
template<typename F, typename T> static constexpr bool IsConvertible
|
||||
= detail::IsConvertibleBase<F, T>::Type::value;
|
||||
|
||||
/* extent */
|
||||
|
||||
template<typename T, uint I = 0>
|
||||
struct Extent: IntegralConstant<Size, 0> {};
|
||||
namespace detail {
|
||||
template<typename T, uint I>
|
||||
struct ExtentBase: IntegralConstant<Size, 0> {};
|
||||
|
||||
template<typename T>
|
||||
struct Extent<T[], 0>: IntegralConstant<Size, 0> {};
|
||||
struct ExtentBase<T[], 0>: IntegralConstant<Size, 0> {};
|
||||
|
||||
template<typename T, uint I>
|
||||
struct Extent<T[], I>: IntegralConstant<Size, Extent<T, I - 1>::value> {};
|
||||
struct ExtentBase<T[], I>:
|
||||
IntegralConstant<Size, detail::ExtentBase<T, I - 1>::value> {};
|
||||
|
||||
template<typename T, Size N>
|
||||
struct Extent<T[N], 0>: IntegralConstant<Size, N> {};
|
||||
struct ExtentBase<T[N], 0>: IntegralConstant<Size, N> {};
|
||||
|
||||
template<typename T, Size N, uint I>
|
||||
struct Extent<T[N], I>: IntegralConstant<Size, Extent<T, I - 1>::value> {};
|
||||
struct ExtentBase<T[N], I>:
|
||||
IntegralConstant<Size, detail::ExtentBase<T, I - 1>::value> {};
|
||||
} /* namespace detail */
|
||||
|
||||
template<typename T, uint I = 0>
|
||||
static constexpr Size Extent = detail::ExtentBase<T, I>::value;
|
||||
|
||||
/* rank */
|
||||
|
||||
template<typename T> struct Rank: IntegralConstant<Size, 0> {};
|
||||
namespace detail {
|
||||
template<typename T> struct RankBase: IntegralConstant<Size, 0> {};
|
||||
|
||||
template<typename T> struct RankBase<T[]>:
|
||||
IntegralConstant<Size, detail::RankBase<T>::value + 1> {};
|
||||
|
||||
template<typename T, Size N> struct RankBase<T[N]>:
|
||||
IntegralConstant<Size, detail::RankBase<T>::value + 1> {};
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
struct Rank<T[]>: IntegralConstant<Size, Rank<T>::value + 1> {};
|
||||
|
||||
template<typename T, Size N>
|
||||
struct Rank<T[N]>: IntegralConstant<Size, Rank<T>::value + 1> {};
|
||||
static constexpr Size Rank = detail::RankBase<T>::value;
|
||||
|
||||
/* remove const, volatile, cv */
|
||||
|
||||
|
|
|
@ -151,7 +151,7 @@ public:
|
|||
Vector(ConstRange(v.begin(), v.size()), a) {}
|
||||
|
||||
template<typename R, typename = EnableIf<
|
||||
IsInputRange<R> && IsConvertible<RangeReference<R>, Value>::value
|
||||
IsInputRange<R> && IsConvertible<RangeReference<R>, Value>
|
||||
>> Vector(R range, const A &a = A()): Vector(a) {
|
||||
ctor_from_range(range);
|
||||
}
|
||||
|
@ -218,7 +218,7 @@ public:
|
|||
}
|
||||
|
||||
template<typename R, typename = EnableIf<
|
||||
IsInputRange<R> && IsConvertible<RangeReference<R>, Value>::value
|
||||
IsInputRange<R> && IsConvertible<RangeReference<R>, Value>
|
||||
>> Vector &operator=(R range) {
|
||||
clear();
|
||||
ctor_from_range(range);
|
||||
|
|
Loading…
Reference in a new issue