convert the remaining type_traits.hh checking traits to constexpr bools

master
Daniel Kolesa 2016-01-13 18:09:21 +00:00
parent a6744105dc
commit 818cbe376a
12 changed files with 164 additions and 166 deletions

View File

@ -736,9 +736,8 @@ namespace detail {
template<typename> template<typename>
static Nat test(...); static Nat test(...);
static constexpr bool value = IsConvertible< static constexpr bool value
decltype(test<T>(nullptr)), R = IsConvertible<decltype(test<T>(nullptr)), R>;
>::value;
}; };
template<typename T> template<typename T>

View File

@ -56,8 +56,7 @@ public:
template<typename U> template<typename U>
HashRange(const HashRange<U> &v, EnableIf< HashRange(const HashRange<U> &v, EnableIf<
IsSame<RemoveCv<T>, RemoveCv<U>> && IsSame<RemoveCv<T>, RemoveCv<U>> && IsConvertible<U *, T *>, bool
IsConvertible<U *, T *>::value, bool
> = true): p_node((Chain *)v.p_node) {} > = true): p_node((Chain *)v.p_node) {}
HashRange &operator=(const HashRange &v) { HashRange &operator=(const HashRange &v) {
@ -95,8 +94,7 @@ public:
template<typename U> template<typename U>
BucketRange(const BucketRange<U> &v, EnableIf< BucketRange(const BucketRange<U> &v, EnableIf<
IsSame<RemoveCv<T>, RemoveCv<U>> && IsSame<RemoveCv<T>, RemoveCv<U>> && IsConvertible<U *, T *>, bool
IsConvertible<U *, T *>::value, bool
> = true): p_node((Chain *)v.p_node), p_end((Chain *)v.p_end) {} > = true): p_node((Chain *)v.p_node), p_end((Chain *)v.p_end) {}
BucketRange &operator=(const BucketRange &v) { BucketRange &operator=(const BucketRange &v) {

View File

@ -185,7 +185,7 @@ namespace detail {
template<typename T, typename ...TT, typename U, typename ...UU> template<typename T, typename ...TT, typename U, typename ...UU>
struct TupleConvertibleBase<TupleTypes<T, TT...>, TupleTypes<U, UU...>>: struct TupleConvertibleBase<TupleTypes<T, TT...>, TupleTypes<U, UU...>>:
IntegralConstant<bool, IsConvertible<T, U>::value && IntegralConstant<bool, IsConvertible<T, U> &&
TupleConvertibleBase<TupleTypes<TT...>, TupleConvertibleBase<TupleTypes<TT...>,
TupleTypes<UU...>>::value> {}; TupleTypes<UU...>>::value> {};

View File

@ -86,7 +86,7 @@ namespace detail {
KeysetImpl(KeysetImpl &&m, const A &alloc): Base(move(m), alloc) {} KeysetImpl(KeysetImpl &&m, const A &alloc): Base(move(m), alloc) {}
template<typename R, typename = EnableIf< 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(), >> KeysetImpl(R range, Size size = 0, const H &hf = H(),
const C &eqf = C(), const A &alloc = A() const C &eqf = C(), const A &alloc = A()
): Base(size ? size : detail::estimate_hrsize(range), ): Base(size ? size : detail::estimate_hrsize(range),
@ -126,7 +126,7 @@ namespace detail {
} }
template<typename R, typename = EnableIf< template<typename R, typename = EnableIf<
IsInputRange<R> && IsConvertible<RangeReference<R>, Value>::value IsInputRange<R> && IsConvertible<RangeReference<R>, Value>
>> KeysetImpl &operator=(R range) { >> KeysetImpl &operator=(R range) {
Base::assign_range(range); Base::assign_range(range);
return *this; return *this;

View File

@ -86,7 +86,7 @@ namespace detail {
MapImpl(MapImpl &&m, const A &alloc): Base(move(m), alloc) {} MapImpl(MapImpl &&m, const A &alloc): Base(move(m), alloc) {}
template<typename R, typename = EnableIf< 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(), >> MapImpl(R range, Size size = 0, const H &hf = H(),
const C &eqf = C(), const A &alloc = A() const C &eqf = C(), const A &alloc = A()
): Base(size ? size : detail::estimate_hrsize(range), ): Base(size ? size : detail::estimate_hrsize(range),
@ -126,7 +126,7 @@ namespace detail {
} }
template<typename R, typename = EnableIf< template<typename R, typename = EnableIf<
IsInputRange<R> && IsConvertible<RangeReference<R>, Value>::value IsInputRange<R> && IsConvertible<RangeReference<R>, Value>
>> MapImpl &operator=(R range) { >> MapImpl &operator=(R range) {
Base::assign_range(range); Base::assign_range(range);
return *this; return *this;

View File

@ -24,7 +24,7 @@ struct Nothing {
constexpr Nothing nothing = Nothing(0); constexpr Nothing nothing = Nothing(0);
namespace detail { namespace detail {
template<typename T, bool = IsTriviallyDestructible<T>::value> template<typename T, bool = IsTriviallyDestructible<T>>
class MaybeStorage { class MaybeStorage {
protected: protected:
using Value = T; using Value = T;
@ -101,7 +101,7 @@ public:
"Initialization of Maybe with Nothing is not allowed."); "Initialization of Maybe with Nothing is not allowed.");
static_assert(IsObject<T>, static_assert(IsObject<T>,
"Initialization of Maybe with non-object type is not allowed."); "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."); "Initialization of Maybe with a non-destructible object is not allowed.");
constexpr Maybe() {} constexpr Maybe() {}
@ -219,7 +219,7 @@ public:
constexpr Value value_or(U &&v) const & { constexpr Value value_or(U &&v) const & {
static_assert(IsCopyConstructible<Value>, static_assert(IsCopyConstructible<Value>,
"Maybe<T>::value_or: T must be copy constructible"); "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"); "Maybe<T>::value_or: U must be convertible to T");
return this->p_engaged ? this->p_value : Value(forward<U>(v)); return this->p_engaged ? this->p_value : Value(forward<U>(v));
} }
@ -228,7 +228,7 @@ public:
Value value_or(U &&v) && { Value value_or(U &&v) && {
static_assert(IsMoveConstructible<Value>, static_assert(IsMoveConstructible<Value>,
"Maybe<T>::value_or: T must be copy constructible"); "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"); "Maybe<T>::value_or: U must be convertible to T");
return this->p_engaged ? move(this->p_value) return this->p_engaged ? move(this->p_value)
: Value(forward<U>(v)); : Value(forward<U>(v));

View File

@ -262,9 +262,8 @@ public:
template<typename TT, typename DD> template<typename TT, typename DD>
Box(Box<TT, DD> &&u, EnableIf<!IsArray<TT> Box(Box<TT, DD> &&u, EnableIf<!IsArray<TT>
&& IsConvertible<typename Box<TT, DD>::Pointer, Pointer>::value && IsConvertible<typename Box<TT, DD>::Pointer, Pointer>
&& IsConvertible<DD, D>::value && IsConvertible<DD, D> && (!IsReference<D> || IsSame<D, DD>)
&& (!IsReference<D> || IsSame<D, DD>)
> = Nat()): p_stor(u.release(), forward<DD>(u.get_deleter())) {} > = Nat()): p_stor(u.release(), forward<DD>(u.get_deleter())) {}
Box &operator=(Box &&u) { Box &operator=(Box &&u) {
@ -275,7 +274,7 @@ public:
template<typename TT, typename DD> template<typename TT, typename DD>
EnableIf<!IsArray<TT> EnableIf<!IsArray<TT>
&& IsConvertible<typename Box<TT, DD>::Pointer, Pointer>::value && IsConvertible<typename Box<TT, DD>::Pointer, Pointer>
&& IsAssignable<D &, DD &&>, && IsAssignable<D &, DD &&>,
Box & Box &
> operator=(Box<TT, DD> &&u) { > operator=(Box<TT, DD> &&u) {
@ -327,7 +326,8 @@ namespace detail {
template<typename T, typename U, bool = IsSame< template<typename T, typename U, bool = IsSame<
RemoveCv<PointerElement<T>>, RemoveCv<PointerElement<T>>,
RemoveCv<PointerElement<U>> RemoveCv<PointerElement<U>>
>> struct SameOrLessCvQualifiedBase: IsConvertible<T, U> {}; >> struct SameOrLessCvQualifiedBase:
IntegralConstant<bool, IsConvertible<T, U>> {};
template<typename T, typename U> template<typename T, typename U>
struct SameOrLessCvQualifiedBase<T, U, false>: False {}; struct SameOrLessCvQualifiedBase<T, U, false>: False {};
@ -392,8 +392,7 @@ public:
Box(Box<TT, DD> &&u, EnableIf<IsArray<TT> Box(Box<TT, DD> &&u, EnableIf<IsArray<TT>
&& detail::SameOrLessCvQualified<typename Box<TT, DD>::Pointer, && detail::SameOrLessCvQualified<typename Box<TT, DD>::Pointer,
Pointer>::value Pointer>::value
&& IsConvertible<DD, D>::value && IsConvertible<DD, D> && (!IsReference<D> || IsSame<D, DD>)> = Nat()
&& (!IsReference<D> || IsSame<D, DD>)> = Nat()
): p_stor(u.release(), forward<DD>(u.get_deleter())) {} ): p_stor(u.release(), forward<DD>(u.get_deleter())) {}
Box &operator=(Box &&u) { Box &operator=(Box &&u) {
@ -1067,7 +1066,7 @@ namespace detail {
template<typename T, typename A, bool = HasAllocatorType<T>::value> template<typename T, typename A, bool = HasAllocatorType<T>::value>
struct UsesAllocatorBase: IntegralConstant<bool, struct UsesAllocatorBase: IntegralConstant<bool,
IsConvertible<A, typename T::Allocator>::value IsConvertible<A, typename T::Allocator>
> {}; > {};
template<typename T, typename A> template<typename T, typename A>

View File

@ -71,9 +71,8 @@ namespace detail {
// is input range // is input range
namespace detail { namespace detail {
template<typename T, bool = IsConvertible< template<typename T, bool = IsConvertible<RangeCategory<T>, InputRangeTag>>
RangeCategory<T>, InputRangeTag struct IsInputRangeCore: False {};
>::value> struct IsInputRangeCore: False {};
template<typename T> template<typename T>
struct IsInputRangeCore<T, true>: True {}; struct IsInputRangeCore<T, true>: True {};
@ -91,9 +90,8 @@ static constexpr bool IsInputRange = detail::IsInputRangeBase<T>::value;
// is forward range // is forward range
namespace detail { namespace detail {
template<typename T, bool = IsConvertible< template<typename T, bool = IsConvertible<RangeCategory<T>, ForwardRangeTag>>
RangeCategory<T>, ForwardRangeTag struct IsForwardRangeCore: False {};
>::value> struct IsForwardRangeCore: False {};
template<typename T> template<typename T>
struct IsForwardRangeCore<T, true>: True {}; struct IsForwardRangeCore<T, true>: True {};
@ -113,7 +111,7 @@ static constexpr bool IsForwardRange = detail::IsForwardRangeBase<T>::value;
namespace detail { namespace detail {
template<typename T, bool = IsConvertible< template<typename T, bool = IsConvertible<
RangeCategory<T>, BidirectionalRangeTag RangeCategory<T>, BidirectionalRangeTag
>::value> struct IsBidirectionalRangeCore: False {}; >> struct IsBidirectionalRangeCore: False {};
template<typename T> template<typename T>
struct IsBidirectionalRangeCore<T, true>: True {}; struct IsBidirectionalRangeCore<T, true>: True {};
@ -134,7 +132,7 @@ template<typename T> static constexpr bool IsBidirectionalRange
namespace detail { namespace detail {
template<typename T, bool = IsConvertible< template<typename T, bool = IsConvertible<
RangeCategory<T>, RandomAccessRangeTag RangeCategory<T>, RandomAccessRangeTag
>::value> struct IsRandomAccessRangeCore: False {}; >> struct IsRandomAccessRangeCore: False {};
template<typename T> template<typename T>
struct IsRandomAccessRangeCore<T, true>: True {}; struct IsRandomAccessRangeCore<T, true>: True {};
@ -155,7 +153,7 @@ template<typename T> static constexpr bool IsRandomAccessRange
namespace detail { namespace detail {
template<typename T, bool = IsConvertible< template<typename T, bool = IsConvertible<
RangeCategory<T>, FiniteRandomAccessRangeTag RangeCategory<T>, FiniteRandomAccessRangeTag
>::value> struct IsFiniteRandomAccessRangeCore: False {}; >> struct IsFiniteRandomAccessRangeCore: False {};
template<typename T> template<typename T>
struct IsFiniteRandomAccessRangeCore<T, true>: True {}; struct IsFiniteRandomAccessRangeCore<T, true>: True {};
@ -181,7 +179,7 @@ template<typename T> static constexpr bool IsInfiniteRandomAccessRange
namespace detail { namespace detail {
template<typename T, bool = IsConvertible< template<typename T, bool = IsConvertible<
RangeCategory<T>, ContiguousRangeTag RangeCategory<T>, ContiguousRangeTag
>::value> struct IsContiguousRangeCore: False {}; >> struct IsContiguousRangeCore: False {};
template<typename T> template<typename T>
struct IsContiguousRangeCore<T, true>: True {}; struct IsContiguousRangeCore<T, true>: True {};
@ -210,7 +208,7 @@ namespace detail {
template<typename T, bool = (IsConvertible< template<typename T, bool = (IsConvertible<
RangeCategory<T>, OutputRangeTag RangeCategory<T>, OutputRangeTag
>::value || (IsInputRange<T> && > || (IsInputRange<T> &&
(detail::OutputRangeTest<T, const RangeValue<T> &>::value || (detail::OutputRangeTest<T, const RangeValue<T> &>::value ||
detail::OutputRangeTest<T, RangeValue<T> &&>::value || detail::OutputRangeTest<T, RangeValue<T> &&>::value ||
detail::OutputRangeTest<T, RangeValue<T> >::value) detail::OutputRangeTest<T, RangeValue<T> >::value)
@ -304,9 +302,8 @@ public:
RangeHalf() = delete; RangeHalf() = delete;
RangeHalf(const T &range): p_range(range) {} RangeHalf(const T &range): p_range(range) {}
template<typename U, typename = EnableIf< template<typename U, typename = EnableIf<IsConvertible<U, T>>>
IsConvertible<U, T>::value RangeHalf(const RangeHalf<U> &half): p_range(half.p_range) {}
>> RangeHalf(const RangeHalf<U> &half): p_range(half.p_range) {}
RangeHalf(const RangeHalf &half): p_range(half.p_range) {} RangeHalf(const RangeHalf &half): p_range(half.p_range) {}
RangeHalf(RangeHalf &&half): p_range(move(half.p_range)) {} RangeHalf(RangeHalf &&half): p_range(move(half.p_range)) {}
@ -899,16 +896,13 @@ public:
template<typename U> template<typename U>
PointerRange(T *beg, U end, EnableIf< PointerRange(T *beg, U end, EnableIf<
(IsPointer<U> || IsNullPointer<U>) && (IsPointer<U> || IsNullPointer<U>) && IsConvertible<U, T *>, Nat
IsConvertible<U, T *>::value, Nat
> = Nat()): p_beg(beg), p_end(end) {} > = Nat()): p_beg(beg), p_end(end) {}
PointerRange(T *beg, Size n): p_beg(beg), p_end(beg + n) {} PointerRange(T *beg, Size n): p_beg(beg), p_end(beg + n) {}
template<typename U, typename = EnableIf< template<typename U, typename = EnableIf<IsConvertible<U *, T *>>>
IsConvertible<U *, T *>::value PointerRange(const PointerRange<U> &v): p_beg(&v[0]), p_end(&v[v.size()]) {}
>> PointerRange(const PointerRange<U> &v):
p_beg(&v[0]), p_end(&v[v.size()]) {}
PointerRange &operator=(const PointerRange &v) { PointerRange &operator=(const PointerRange &v) {
p_beg = v.p_beg; p_beg = v.p_beg;
@ -1051,8 +1045,7 @@ namespace detail {
template<typename T, typename U> template<typename T, typename U>
PointerRange<T> iter(T *a, U b, EnableIf< PointerRange<T> iter(T *a, U b, EnableIf<
(IsPointer<U> || IsNullPointer<U>) && (IsPointer<U> || IsNullPointer<U>) && IsConvertible<U, T *>, detail::PtrNat
IsConvertible<U, T *>::value, detail::PtrNat
> = detail::PtrNat()) { > = detail::PtrNat()) {
return PointerRange<T>(a, b); return PointerRange<T>(a, b);
} }

View File

@ -75,7 +75,7 @@ namespace detail {
SetImpl(SetImpl &&m, const A &alloc): Base(move(m), alloc) {} SetImpl(SetImpl &&m, const A &alloc): Base(move(m), alloc) {}
template<typename R, typename = EnableIf< 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(), >> SetImpl(R range, Size size = 0, const H &hf = H(),
const C &eqf = C(), const A &alloc = A() const C &eqf = C(), const A &alloc = A()
): Base(size ? size : detail::estimate_hrsize(range), ): Base(size ? size : detail::estimate_hrsize(range),
@ -115,7 +115,7 @@ namespace detail {
} }
template<typename R, typename = EnableIf< template<typename R, typename = EnableIf<
IsInputRange<R> && IsConvertible<RangeReference<R>, Value>::value IsInputRange<R> && IsConvertible<RangeReference<R>, Value>
>> SetImpl &operator=(R range) { >> SetImpl &operator=(R range) {
Base::assign_range(range); Base::assign_range(range);
return *this; return *this;

View File

@ -32,35 +32,30 @@ public:
template<typename U> template<typename U>
CharRangeBase(T *beg, U end, EnableIf< CharRangeBase(T *beg, U end, EnableIf<
(IsPointer<U> || IsNullPointer<U>) && (IsPointer<U> || IsNullPointer<U>) && IsConvertible<U, T *>, Nat
IsConvertible<U, T *>::value, Nat
> = Nat()): p_beg(beg), p_end(end) {} > = Nat()): p_beg(beg), p_end(end) {}
CharRangeBase(T *beg, Size n): p_beg(beg), p_end(beg + n) {} 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 */ /* TODO: traits for utf-16/utf-32 string lengths, for now assume char */
template<typename U> template<typename U>
CharRangeBase(U beg, EnableIf< CharRangeBase(U beg, EnableIf<IsConvertible<U, T *> && !IsArray<U>, Nat>
IsConvertible<U, T *>::value && !IsArray<U>, Nat = Nat()): p_beg(beg), p_end((T *)beg + (beg ? strlen(beg) : 0)) {}
> = Nat()): p_beg(beg), p_end((T *)beg + (beg ? strlen(beg) : 0)) {}
CharRangeBase(Nullptr): p_beg(nullptr), p_end(nullptr) {} CharRangeBase(Nullptr): p_beg(nullptr), p_end(nullptr) {}
template<typename U, Size N> template<typename U, Size N>
CharRangeBase(U (&beg)[N], EnableIf< CharRangeBase(U (&beg)[N], EnableIf<IsConvertible<U *, T *>, Nat> = Nat()):
IsConvertible<U *, T *>::value, Nat p_beg(beg), p_end(beg + N - (beg[N - 1] == '\0')) {}
> = Nat()): p_beg(beg),
p_end(beg + N - (beg[N - 1] == '\0')) {}
template<typename U, typename A> template<typename U, typename A>
CharRangeBase(const StringBase<U, A> &s, EnableIf< CharRangeBase(const StringBase<U, A> &s, EnableIf<
IsConvertible<U *, T *>::value, Nat IsConvertible<U *, T *>, Nat
> = Nat()): p_beg(s.data()), > = Nat()): p_beg(s.data()),
p_end(s.data() + s.size()) {} p_end(s.data() + s.size()) {}
template<typename U, typename = EnableIf< template<typename U, typename = EnableIf<IsConvertible<U *, T *>>>
IsConvertible<U *, T *>::value CharRangeBase(const CharRangeBase<U> &v):
>> CharRangeBase(const CharRangeBase<U> &v):
p_beg(&v[0]), p_end(&v[v.size()]) {} p_beg(&v[0]), p_end(&v[v.size()]) {}
CharRangeBase &operator=(const CharRangeBase &v) { CharRangeBase &operator=(const CharRangeBase &v) {
@ -317,16 +312,16 @@ public:
template<typename U> template<typename U>
StringBase(U v, const EnableIf< 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) {} > &a = A()): StringBase(ConstRange(v), a) {}
template<typename U, Size N> template<typename U, Size N>
StringBase(U (&v)[N], const EnableIf< StringBase(U (&v)[N], const EnableIf<
IsConvertible<U *, const Value *>::value, A IsConvertible<U *, const Value *>, A
> &a = A()): StringBase(ConstRange(v), a) {} > &a = A()): StringBase(ConstRange(v), a) {}
template<typename R, typename = EnableIf< 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) { >> StringBase(R range, const A &a = A()): StringBase(a) {
ctor_from_range(range); ctor_from_range(range);
} }
@ -384,21 +379,19 @@ public:
} }
template<typename U> template<typename U>
EnableIf< EnableIf<IsConvertible<U, const Value *> && !IsArray<U>, StringBase &>
IsConvertible<U, const Value *>::value && !IsArray<U>, StringBase & operator=(U v) {
> operator=(U v) {
return operator=(ConstRange(v)); return operator=(ConstRange(v));
} }
template<typename U, Size N> template<typename U, Size N>
EnableIf< EnableIf<IsConvertible<U *, const Value *>, StringBase &>
IsConvertible<U *, const Value *>::value, StringBase & operator=(U (&v)[N]) {
> operator=(U (&v)[N]) {
return operator=(ConstRange(v)); return operator=(ConstRange(v));
} }
template<typename R, typename = EnableIf< template<typename R, typename = EnableIf<
IsInputRange<R> && IsConvertible<RangeReference<R>, Value>::value IsInputRange<R> && IsConvertible<RangeReference<R>, Value>
>> StringBase &operator=(const R &r) { >> StringBase &operator=(const R &r) {
clear(); clear();
ctor_from_range(r); ctor_from_range(r);
@ -500,9 +493,8 @@ public:
} }
template<typename R, typename = EnableIf< template<typename R, typename = EnableIf<
IsInputRange<R> && IsInputRange<R> && IsConvertible<RangeReference<R>, Value> &&
IsConvertible<RangeReference<R>, Value>::value && !IsConvertible<R, ConstRange>
!IsConvertible<R, ConstRange>::value
>> StringBase &append(R range) { >> StringBase &append(R range) {
Size nadd = 0; Size nadd = 0;
for (; !range.empty(); range.pop_front()) { for (; !range.empty(); range.pop_front()) {
@ -578,8 +570,8 @@ inline namespace literals { inline namespace string_literals {
} } } }
namespace detail { namespace detail {
template<typename T, bool = IsConvertible<T, ConstCharRange>::value, template<typename T, bool = IsConvertible<T, ConstCharRange>,
bool = IsConvertible<T, char>::value> bool = IsConvertible<T, char>>
struct ConcatPut; struct ConcatPut;
template<typename T, bool B> template<typename T, bool B>

View File

@ -582,108 +582,113 @@ namespace detail {
: DtibleImpl<T, IsReference<T>> {}; : DtibleImpl<T, IsReference<T>> {};
template<typename T> struct DtibleFalse<T, true>: False {}; 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 */ } /* namespace detail */
template<typename T> template<typename T>
struct IsDestructible: detail::DtibleFalse<T, IsFunction<T>> {}; static constexpr bool IsDestructible = detail::IsDestructibleBase<T>::value;
template<typename T> struct IsDestructible<T[]>: False {};
template< > struct IsDestructible<void>: False {};
/* is trivially constructible */ /* is trivially constructible */
template<typename T, typename ...A> namespace detail {
struct IsTriviallyConstructible: False {}; template<typename T, typename ...A>
struct IsTriviallyConstructibleBase: False {};
template<typename T> template<typename T>
struct IsTriviallyConstructible<T>: IntegralConstant<bool, struct IsTriviallyConstructibleBase<T>: IntegralConstant<bool,
__has_trivial_constructor(T) __has_trivial_constructor(T)
> {}; > {};
template<typename T> template<typename T>
struct IsTriviallyConstructible<T, T &>: IntegralConstant<bool, struct IsTriviallyConstructibleBase<T, T &>: IntegralConstant<bool,
__has_trivial_copy(T) __has_trivial_copy(T)
> {}; > {};
template<typename T> template<typename T>
struct IsTriviallyConstructible<T, const T &>: IntegralConstant<bool, struct IsTriviallyConstructibleBase<T, const T &>: IntegralConstant<bool,
__has_trivial_copy(T) __has_trivial_copy(T)
> {}; > {};
template<typename T> template<typename T>
struct IsTriviallyConstructible<T, T &&>: IntegralConstant<bool, struct IsTriviallyConstructibleBase<T, T &&>: IntegralConstant<bool,
__has_trivial_copy(T) __has_trivial_copy(T)
> {}; > {};
} /* namespace detail */
template<typename T, typename ...A>
static constexpr bool IsTriviallyConstructible
= detail::IsTriviallyConstructibleBase<T, A...>::value;
/* is trivially default constructible */ /* is trivially default constructible */
template<typename T> template<typename T> static constexpr bool IsTriviallyDefaultConstructible
struct IsTriviallyDefaultConstructible: IsTriviallyConstructible<T> {}; = IsTriviallyConstructible<T>;
/* is trivially copy constructible */ /* is trivially copy constructible */
template<typename T> template<typename T> static constexpr bool IsTriviallyCopyConstructible
struct IsTriviallyCopyConstructible: IsTriviallyConstructible<T, = IsTriviallyConstructible<T, AddLvalueReference<const T>>;
AddLvalueReference<const T>
> {};
/* is trivially move constructible */ /* is trivially move constructible */
template<typename T> template<typename T> static constexpr bool IsTriviallyMoveConstructible
struct IsTriviallyMoveConstructible: IsTriviallyConstructible<T, = IsTriviallyConstructible<T, AddRvalueReference<T>>;
AddRvalueReference<T>
> {};
/* is trivially assignable */ /* is trivially assignable */
template<typename T, typename ...A> namespace detail {
struct IsTriviallyAssignable: False {}; template<typename T, typename ...A>
struct IsTriviallyAssignableBase: False {};
template<typename T> template<typename T>
struct IsTriviallyAssignable<T>: IntegralConstant<bool, struct IsTriviallyAssignableBase<T>: IntegralConstant<bool,
__has_trivial_assign(T) __has_trivial_assign(T)
> {}; > {};
template<typename T> template<typename T>
struct IsTriviallyAssignable<T, T &>: IntegralConstant<bool, struct IsTriviallyAssignableBase<T, T &>: IntegralConstant<bool,
__has_trivial_copy(T) __has_trivial_copy(T)
> {}; > {};
template<typename T> template<typename T>
struct IsTriviallyAssignable<T, const T &>: IntegralConstant<bool, struct IsTriviallyAssignableBase<T, const T &>: IntegralConstant<bool,
__has_trivial_copy(T) __has_trivial_copy(T)
> {}; > {};
template<typename T> template<typename T>
struct IsTriviallyAssignable<T, T &&>: IntegralConstant<bool, struct IsTriviallyAssignableBase<T, T &&>: IntegralConstant<bool,
__has_trivial_copy(T) __has_trivial_copy(T)
> {}; > {};
} /* namespace detail */
template<typename T, typename ...A>
static constexpr bool IsTriviallyAssignable
= detail::IsTriviallyAssignableBase<T>::value;
/* is trivially copy assignable */ /* is trivially copy assignable */
template<typename T> template<typename T> static constexpr bool IsTriviallyCopyAssignable
struct IsTriviallyCopyAssignable: IsTriviallyAssignable<T, = IsTriviallyAssignable<T, AddLvalueReference<const T>>;
AddLvalueReference<const T>
> {};
/* is trivially move assignable */ /* is trivially move assignable */
template<typename T> template<typename T> static constexpr bool IsTriviallyMoveAssignable
struct IsTriviallyMoveAssignable: IsTriviallyAssignable<T, = IsTriviallyAssignable<T, AddRvalueReference<T>>;
AddRvalueReference<T>
> {};
/* is trivially destructible */ /* is trivially destructible */
template<typename T> template<typename T>
struct IsTriviallyDestructible: IntegralConstant<bool, static constexpr bool IsTriviallyDestructible = __has_trivial_destructor(T);
__has_trivial_destructor(T)
> {};
/* is base of */ /* is base of */
template<typename B, typename D> 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 */ /* is convertible */
@ -708,35 +713,47 @@ namespace detail {
}; };
} }
template<typename F, typename T> template<typename F, typename T> static constexpr bool IsConvertible
struct IsConvertible: detail::IsConvertibleBase<F, T>::Type {}; = detail::IsConvertibleBase<F, T>::Type::value;
/* extent */ /* extent */
namespace detail {
template<typename T, uint I>
struct ExtentBase: IntegralConstant<Size, 0> {};
template<typename T>
struct ExtentBase<T[], 0>: IntegralConstant<Size, 0> {};
template<typename T, uint I>
struct ExtentBase<T[], I>:
IntegralConstant<Size, detail::ExtentBase<T, I - 1>::value> {};
template<typename T, Size N>
struct ExtentBase<T[N], 0>: IntegralConstant<Size, N> {};
template<typename T, Size N, uint I>
struct ExtentBase<T[N], I>:
IntegralConstant<Size, detail::ExtentBase<T, I - 1>::value> {};
} /* namespace detail */
template<typename T, uint I = 0> template<typename T, uint I = 0>
struct Extent: IntegralConstant<Size, 0> {}; static constexpr Size Extent = detail::ExtentBase<T, I>::value;
template<typename T>
struct Extent<T[], 0>: IntegralConstant<Size, 0> {};
template<typename T, uint I>
struct Extent<T[], I>: IntegralConstant<Size, Extent<T, I - 1>::value> {};
template<typename T, Size N>
struct Extent<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> {};
/* rank */ /* 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> template<typename T>
struct Rank<T[]>: IntegralConstant<Size, Rank<T>::value + 1> {}; static constexpr Size Rank = detail::RankBase<T>::value;
template<typename T, Size N>
struct Rank<T[N]>: IntegralConstant<Size, Rank<T>::value + 1> {};
/* remove const, volatile, cv */ /* remove const, volatile, cv */

View File

@ -151,7 +151,7 @@ public:
Vector(ConstRange(v.begin(), v.size()), a) {} Vector(ConstRange(v.begin(), v.size()), a) {}
template<typename R, typename = EnableIf< 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) { >> Vector(R range, const A &a = A()): Vector(a) {
ctor_from_range(range); ctor_from_range(range);
} }
@ -218,7 +218,7 @@ public:
} }
template<typename R, typename = EnableIf< template<typename R, typename = EnableIf<
IsInputRange<R> && IsConvertible<RangeReference<R>, Value>::value IsInputRange<R> && IsConvertible<RangeReference<R>, Value>
>> Vector &operator=(R range) { >> Vector &operator=(R range) {
clear(); clear();
ctor_from_range(range); ctor_from_range(range);