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>
|
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>
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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> {};
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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));
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
template<typename T, typename ...A>
|
||||||
|
struct IsTriviallyConstructibleBase: False {};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct IsTriviallyConstructibleBase<T>: IntegralConstant<bool,
|
||||||
|
__has_trivial_constructor(T)
|
||||||
|
> {};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct IsTriviallyConstructibleBase<T, T &>: IntegralConstant<bool,
|
||||||
|
__has_trivial_copy(T)
|
||||||
|
> {};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct IsTriviallyConstructibleBase<T, const T &>: IntegralConstant<bool,
|
||||||
|
__has_trivial_copy(T)
|
||||||
|
> {};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct IsTriviallyConstructibleBase<T, T &&>: IntegralConstant<bool,
|
||||||
|
__has_trivial_copy(T)
|
||||||
|
> {};
|
||||||
|
} /* namespace detail */
|
||||||
|
|
||||||
template<typename T, typename ...A>
|
template<typename T, typename ...A>
|
||||||
struct IsTriviallyConstructible: False {};
|
static constexpr bool IsTriviallyConstructible
|
||||||
|
= detail::IsTriviallyConstructibleBase<T, A...>::value;
|
||||||
template<typename T>
|
|
||||||
struct IsTriviallyConstructible<T>: IntegralConstant<bool,
|
|
||||||
__has_trivial_constructor(T)
|
|
||||||
> {};
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct IsTriviallyConstructible<T, T &>: IntegralConstant<bool,
|
|
||||||
__has_trivial_copy(T)
|
|
||||||
> {};
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct IsTriviallyConstructible<T, const T &>: IntegralConstant<bool,
|
|
||||||
__has_trivial_copy(T)
|
|
||||||
> {};
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct IsTriviallyConstructible<T, T &&>: IntegralConstant<bool,
|
|
||||||
__has_trivial_copy(T)
|
|
||||||
> {};
|
|
||||||
|
|
||||||
/* 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 */
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
template<typename T, typename ...A>
|
||||||
|
struct IsTriviallyAssignableBase: False {};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct IsTriviallyAssignableBase<T>: IntegralConstant<bool,
|
||||||
|
__has_trivial_assign(T)
|
||||||
|
> {};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct IsTriviallyAssignableBase<T, T &>: IntegralConstant<bool,
|
||||||
|
__has_trivial_copy(T)
|
||||||
|
> {};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct IsTriviallyAssignableBase<T, const T &>: IntegralConstant<bool,
|
||||||
|
__has_trivial_copy(T)
|
||||||
|
> {};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct IsTriviallyAssignableBase<T, T &&>: IntegralConstant<bool,
|
||||||
|
__has_trivial_copy(T)
|
||||||
|
> {};
|
||||||
|
} /* namespace detail */
|
||||||
|
|
||||||
template<typename T, typename ...A>
|
template<typename T, typename ...A>
|
||||||
struct IsTriviallyAssignable: False {};
|
static constexpr bool IsTriviallyAssignable
|
||||||
|
= detail::IsTriviallyAssignableBase<T>::value;
|
||||||
template<typename T>
|
|
||||||
struct IsTriviallyAssignable<T>: IntegralConstant<bool,
|
|
||||||
__has_trivial_assign(T)
|
|
||||||
> {};
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct IsTriviallyAssignable<T, T &>: IntegralConstant<bool,
|
|
||||||
__has_trivial_copy(T)
|
|
||||||
> {};
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct IsTriviallyAssignable<T, const T &>: IntegralConstant<bool,
|
|
||||||
__has_trivial_copy(T)
|
|
||||||
> {};
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct IsTriviallyAssignable<T, T &&>: IntegralConstant<bool,
|
|
||||||
__has_trivial_copy(T)
|
|
||||||
> {};
|
|
||||||
|
|
||||||
/* 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 */
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in a new issue