diff --git a/ostd/functional.hh b/ostd/functional.hh index b376f25..567d43d 100644 --- a/ostd/functional.hh +++ b/ostd/functional.hh @@ -736,9 +736,8 @@ namespace detail { template static Nat test(...); - static constexpr bool value = IsConvertible< - decltype(test(nullptr)), R - >::value; + static constexpr bool value + = IsConvertible(nullptr)), R>; }; template diff --git a/ostd/internal/hashtable.hh b/ostd/internal/hashtable.hh index df6fba8..a7caa26 100644 --- a/ostd/internal/hashtable.hh +++ b/ostd/internal/hashtable.hh @@ -56,8 +56,7 @@ public: template HashRange(const HashRange &v, EnableIf< - IsSame, RemoveCv> && - IsConvertible::value, bool + IsSame, RemoveCv> && IsConvertible, bool > = true): p_node((Chain *)v.p_node) {} HashRange &operator=(const HashRange &v) { @@ -95,8 +94,7 @@ public: template BucketRange(const BucketRange &v, EnableIf< - IsSame, RemoveCv> && - IsConvertible::value, bool + IsSame, RemoveCv> && IsConvertible, bool > = true): p_node((Chain *)v.p_node), p_end((Chain *)v.p_end) {} BucketRange &operator=(const BucketRange &v) { diff --git a/ostd/internal/tuple.hh b/ostd/internal/tuple.hh index d77b59c..47196e3 100644 --- a/ostd/internal/tuple.hh +++ b/ostd/internal/tuple.hh @@ -185,7 +185,7 @@ namespace detail { template struct TupleConvertibleBase, TupleTypes>: - IntegralConstant::value && + IntegralConstant && TupleConvertibleBase, TupleTypes>::value> {}; diff --git a/ostd/keyset.hh b/ostd/keyset.hh index 6e04d9d..cef4b62 100644 --- a/ostd/keyset.hh +++ b/ostd/keyset.hh @@ -86,7 +86,7 @@ namespace detail { KeysetImpl(KeysetImpl &&m, const A &alloc): Base(move(m), alloc) {} template && IsConvertible, Value>::value + IsInputRange && IsConvertible, 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 && IsConvertible, Value>::value + IsInputRange && IsConvertible, Value> >> KeysetImpl &operator=(R range) { Base::assign_range(range); return *this; diff --git a/ostd/map.hh b/ostd/map.hh index f2f4f2b..e9a760e 100644 --- a/ostd/map.hh +++ b/ostd/map.hh @@ -86,7 +86,7 @@ namespace detail { MapImpl(MapImpl &&m, const A &alloc): Base(move(m), alloc) {} template && IsConvertible, Value>::value + IsInputRange && IsConvertible, 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 && IsConvertible, Value>::value + IsInputRange && IsConvertible, Value> >> MapImpl &operator=(R range) { Base::assign_range(range); return *this; diff --git a/ostd/maybe.hh b/ostd/maybe.hh index 7451134..c8056a4 100644 --- a/ostd/maybe.hh +++ b/ostd/maybe.hh @@ -24,7 +24,7 @@ struct Nothing { constexpr Nothing nothing = Nothing(0); namespace detail { - template::value> + template> class MaybeStorage { protected: using Value = T; @@ -101,7 +101,7 @@ public: "Initialization of Maybe with Nothing is not allowed."); static_assert(IsObject, "Initialization of Maybe with non-object type is not allowed."); - static_assert(IsDestructible::value, + static_assert(IsDestructible, "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, "Maybe::value_or: T must be copy constructible"); - static_assert(IsConvertible::value, + static_assert(IsConvertible, "Maybe::value_or: U must be convertible to T"); return this->p_engaged ? this->p_value : Value(forward(v)); } @@ -228,7 +228,7 @@ public: Value value_or(U &&v) && { static_assert(IsMoveConstructible, "Maybe::value_or: T must be copy constructible"); - static_assert(IsConvertible::value, + static_assert(IsConvertible, "Maybe::value_or: U must be convertible to T"); return this->p_engaged ? move(this->p_value) : Value(forward(v)); diff --git a/ostd/memory.hh b/ostd/memory.hh index 46c2000..be1d52d 100644 --- a/ostd/memory.hh +++ b/ostd/memory.hh @@ -262,9 +262,8 @@ public: template Box(Box &&u, EnableIf - && IsConvertible::Pointer, Pointer>::value - && IsConvertible::value - && (!IsReference || IsSame) + && IsConvertible::Pointer, Pointer> + && IsConvertible && (!IsReference || IsSame) > = Nat()): p_stor(u.release(), forward
(u.get_deleter())) {} Box &operator=(Box &&u) { @@ -275,7 +274,7 @@ public: template EnableIf - && IsConvertible::Pointer, Pointer>::value + && IsConvertible::Pointer, Pointer> && IsAssignable, Box & > operator=(Box &&u) { @@ -327,7 +326,8 @@ namespace detail { template>, RemoveCv> - >> struct SameOrLessCvQualifiedBase: IsConvertible {}; + >> struct SameOrLessCvQualifiedBase: + IntegralConstant> {}; template struct SameOrLessCvQualifiedBase: False {}; @@ -392,8 +392,7 @@ public: Box(Box &&u, EnableIf && detail::SameOrLessCvQualified::Pointer, Pointer>::value - && IsConvertible::value - && (!IsReference || IsSame)> = Nat() + && IsConvertible && (!IsReference || IsSame)> = Nat() ): p_stor(u.release(), forward
(u.get_deleter())) {} Box &operator=(Box &&u) { @@ -1067,7 +1066,7 @@ namespace detail { template::value> struct UsesAllocatorBase: IntegralConstant::value + IsConvertible > {}; template diff --git a/ostd/range.hh b/ostd/range.hh index f6edbc3..ee14859 100644 --- a/ostd/range.hh +++ b/ostd/range.hh @@ -71,9 +71,8 @@ namespace detail { // is input range namespace detail { - template, InputRangeTag - >::value> struct IsInputRangeCore: False {}; + template, InputRangeTag>> + struct IsInputRangeCore: False {}; template struct IsInputRangeCore: True {}; @@ -91,9 +90,8 @@ static constexpr bool IsInputRange = detail::IsInputRangeBase::value; // is forward range namespace detail { - template, ForwardRangeTag - >::value> struct IsForwardRangeCore: False {}; + template, ForwardRangeTag>> + struct IsForwardRangeCore: False {}; template struct IsForwardRangeCore: True {}; @@ -113,7 +111,7 @@ static constexpr bool IsForwardRange = detail::IsForwardRangeBase::value; namespace detail { template, BidirectionalRangeTag - >::value> struct IsBidirectionalRangeCore: False {}; + >> struct IsBidirectionalRangeCore: False {}; template struct IsBidirectionalRangeCore: True {}; @@ -134,7 +132,7 @@ template static constexpr bool IsBidirectionalRange namespace detail { template, RandomAccessRangeTag - >::value> struct IsRandomAccessRangeCore: False {}; + >> struct IsRandomAccessRangeCore: False {}; template struct IsRandomAccessRangeCore: True {}; @@ -155,7 +153,7 @@ template static constexpr bool IsRandomAccessRange namespace detail { template, FiniteRandomAccessRangeTag - >::value> struct IsFiniteRandomAccessRangeCore: False {}; + >> struct IsFiniteRandomAccessRangeCore: False {}; template struct IsFiniteRandomAccessRangeCore: True {}; @@ -181,7 +179,7 @@ template static constexpr bool IsInfiniteRandomAccessRange namespace detail { template, ContiguousRangeTag - >::value> struct IsContiguousRangeCore: False {}; + >> struct IsContiguousRangeCore: False {}; template struct IsContiguousRangeCore: True {}; @@ -210,7 +208,7 @@ namespace detail { template, OutputRangeTag - >::value || (IsInputRange && + > || (IsInputRange && (detail::OutputRangeTest &>::value || detail::OutputRangeTest &&>::value || detail::OutputRangeTest >::value) @@ -304,9 +302,8 @@ public: RangeHalf() = delete; RangeHalf(const T &range): p_range(range) {} - template::value - >> RangeHalf(const RangeHalf &half): p_range(half.p_range) {} + template>> + 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)) {} @@ -899,16 +896,13 @@ public: template PointerRange(T *beg, U end, EnableIf< - (IsPointer || IsNullPointer) && - IsConvertible::value, Nat + (IsPointer || IsNullPointer) && IsConvertible, Nat > = Nat()): p_beg(beg), p_end(end) {} PointerRange(T *beg, Size n): p_beg(beg), p_end(beg + n) {} - template::value - >> PointerRange(const PointerRange &v): - p_beg(&v[0]), p_end(&v[v.size()]) {} + template>> + PointerRange(const PointerRange &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 PointerRange iter(T *a, U b, EnableIf< - (IsPointer || IsNullPointer) && - IsConvertible::value, detail::PtrNat + (IsPointer || IsNullPointer) && IsConvertible, detail::PtrNat > = detail::PtrNat()) { return PointerRange(a, b); } diff --git a/ostd/set.hh b/ostd/set.hh index 7cc9cc5..72874e9 100644 --- a/ostd/set.hh +++ b/ostd/set.hh @@ -75,7 +75,7 @@ namespace detail { SetImpl(SetImpl &&m, const A &alloc): Base(move(m), alloc) {} template && IsConvertible, Value>::value + IsInputRange && IsConvertible, 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 && IsConvertible, Value>::value + IsInputRange && IsConvertible, Value> >> SetImpl &operator=(R range) { Base::assign_range(range); return *this; diff --git a/ostd/string.hh b/ostd/string.hh index 7eb12be..b1f5fd5 100644 --- a/ostd/string.hh +++ b/ostd/string.hh @@ -32,35 +32,30 @@ public: template CharRangeBase(T *beg, U end, EnableIf< - (IsPointer || IsNullPointer) && - IsConvertible::value, Nat + (IsPointer || IsNullPointer) && IsConvertible, 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 - CharRangeBase(U beg, EnableIf< - IsConvertible::value && !IsArray, Nat - > = Nat()): p_beg(beg), p_end((T *)beg + (beg ? strlen(beg) : 0)) {} + CharRangeBase(U beg, EnableIf && !IsArray, Nat> + = Nat()): p_beg(beg), p_end((T *)beg + (beg ? strlen(beg) : 0)) {} CharRangeBase(Nullptr): p_beg(nullptr), p_end(nullptr) {} template - CharRangeBase(U (&beg)[N], EnableIf< - IsConvertible::value, Nat - > = Nat()): p_beg(beg), - p_end(beg + N - (beg[N - 1] == '\0')) {} + CharRangeBase(U (&beg)[N], EnableIf, Nat> = Nat()): + p_beg(beg), p_end(beg + N - (beg[N - 1] == '\0')) {} template CharRangeBase(const StringBase &s, EnableIf< - IsConvertible::value, Nat + IsConvertible, Nat > = Nat()): p_beg(s.data()), p_end(s.data() + s.size()) {} - template::value - >> CharRangeBase(const CharRangeBase &v): + template>> + CharRangeBase(const CharRangeBase &v): p_beg(&v[0]), p_end(&v[v.size()]) {} CharRangeBase &operator=(const CharRangeBase &v) { @@ -317,16 +312,16 @@ public: template StringBase(U v, const EnableIf< - IsConvertible::value && !IsArray, A + IsConvertible && !IsArray, A > &a = A()): StringBase(ConstRange(v), a) {} template StringBase(U (&v)[N], const EnableIf< - IsConvertible::value, A + IsConvertible, A > &a = A()): StringBase(ConstRange(v), a) {} template && IsConvertible, Value>::value + IsInputRange && IsConvertible, Value> >> StringBase(R range, const A &a = A()): StringBase(a) { ctor_from_range(range); } @@ -384,21 +379,19 @@ public: } template - EnableIf< - IsConvertible::value && !IsArray, StringBase & - > operator=(U v) { + EnableIf && !IsArray, StringBase &> + operator=(U v) { return operator=(ConstRange(v)); } template - EnableIf< - IsConvertible::value, StringBase & - > operator=(U (&v)[N]) { + EnableIf, StringBase &> + operator=(U (&v)[N]) { return operator=(ConstRange(v)); } template && IsConvertible, Value>::value + IsInputRange && IsConvertible, Value> >> StringBase &operator=(const R &r) { clear(); ctor_from_range(r); @@ -500,9 +493,8 @@ public: } template && - IsConvertible, Value>::value && - !IsConvertible::value + IsInputRange && IsConvertible, Value> && + !IsConvertible >> 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::value, - bool = IsConvertible::value> + template, + bool = IsConvertible> struct ConcatPut; template diff --git a/ostd/type_traits.hh b/ostd/type_traits.hh index 07771a7..484519c 100644 --- a/ostd/type_traits.hh +++ b/ostd/type_traits.hh @@ -582,108 +582,113 @@ namespace detail { : DtibleImpl> {}; template struct DtibleFalse: False {}; + + template + struct IsDestructibleBase: detail::DtibleFalse> {}; + + template struct IsDestructibleBase: False {}; + template< > struct IsDestructibleBase: False {}; } /* namespace detail */ template -struct IsDestructible: detail::DtibleFalse> {}; - -template struct IsDestructible: False {}; -template< > struct IsDestructible: False {}; +static constexpr bool IsDestructible = detail::IsDestructibleBase::value; /* is trivially constructible */ +namespace detail { + template + struct IsTriviallyConstructibleBase: False {}; + + template + struct IsTriviallyConstructibleBase: IntegralConstant {}; + + template + struct IsTriviallyConstructibleBase: IntegralConstant {}; + + template + struct IsTriviallyConstructibleBase: IntegralConstant {}; + + template + struct IsTriviallyConstructibleBase: IntegralConstant {}; +} /* namespace detail */ + template -struct IsTriviallyConstructible: False {}; - -template -struct IsTriviallyConstructible: IntegralConstant {}; - -template -struct IsTriviallyConstructible: IntegralConstant {}; - -template -struct IsTriviallyConstructible: IntegralConstant {}; - -template -struct IsTriviallyConstructible: IntegralConstant {}; +static constexpr bool IsTriviallyConstructible + = detail::IsTriviallyConstructibleBase::value; /* is trivially default constructible */ -template -struct IsTriviallyDefaultConstructible: IsTriviallyConstructible {}; +template static constexpr bool IsTriviallyDefaultConstructible + = IsTriviallyConstructible; /* is trivially copy constructible */ -template -struct IsTriviallyCopyConstructible: IsTriviallyConstructible -> {}; +template static constexpr bool IsTriviallyCopyConstructible + = IsTriviallyConstructible>; /* is trivially move constructible */ -template -struct IsTriviallyMoveConstructible: IsTriviallyConstructible -> {}; +template static constexpr bool IsTriviallyMoveConstructible + = IsTriviallyConstructible>; /* is trivially assignable */ +namespace detail { + template + struct IsTriviallyAssignableBase: False {}; + + template + struct IsTriviallyAssignableBase: IntegralConstant {}; + + template + struct IsTriviallyAssignableBase: IntegralConstant {}; + + template + struct IsTriviallyAssignableBase: IntegralConstant {}; + + template + struct IsTriviallyAssignableBase: IntegralConstant {}; +} /* namespace detail */ + template -struct IsTriviallyAssignable: False {}; - -template -struct IsTriviallyAssignable: IntegralConstant {}; - -template -struct IsTriviallyAssignable: IntegralConstant {}; - -template -struct IsTriviallyAssignable: IntegralConstant {}; - -template -struct IsTriviallyAssignable: IntegralConstant {}; +static constexpr bool IsTriviallyAssignable + = detail::IsTriviallyAssignableBase::value; /* is trivially copy assignable */ -template -struct IsTriviallyCopyAssignable: IsTriviallyAssignable -> {}; +template static constexpr bool IsTriviallyCopyAssignable + = IsTriviallyAssignable>; /* is trivially move assignable */ -template -struct IsTriviallyMoveAssignable: IsTriviallyAssignable -> {}; +template static constexpr bool IsTriviallyMoveAssignable + = IsTriviallyAssignable>; /* is trivially destructible */ template -struct IsTriviallyDestructible: IntegralConstant {}; +static constexpr bool IsTriviallyDestructible = __has_trivial_destructor(T); /* is base of */ template -struct IsBaseOf: IntegralConstant {}; +static constexpr bool IsBaseOf = __is_base_of(B, D); /* is convertible */ @@ -708,35 +713,47 @@ namespace detail { }; } -template -struct IsConvertible: detail::IsConvertibleBase::Type {}; +template static constexpr bool IsConvertible + = detail::IsConvertibleBase::Type::value; /* extent */ +namespace detail { + template + struct ExtentBase: IntegralConstant {}; + + template + struct ExtentBase: IntegralConstant {}; + + template + struct ExtentBase: + IntegralConstant::value> {}; + + template + struct ExtentBase: IntegralConstant {}; + + template + struct ExtentBase: + IntegralConstant::value> {}; +} /* namespace detail */ + template -struct Extent: IntegralConstant {}; - -template -struct Extent: IntegralConstant {}; - -template -struct Extent: IntegralConstant::value> {}; - -template -struct Extent: IntegralConstant {}; - -template -struct Extent: IntegralConstant::value> {}; +static constexpr Size Extent = detail::ExtentBase::value; /* rank */ -template struct Rank: IntegralConstant {}; +namespace detail { + template struct RankBase: IntegralConstant {}; + + template struct RankBase: + IntegralConstant::value + 1> {}; + + template struct RankBase: + IntegralConstant::value + 1> {}; +} template -struct Rank: IntegralConstant::value + 1> {}; - -template -struct Rank: IntegralConstant::value + 1> {}; +static constexpr Size Rank = detail::RankBase::value; /* remove const, volatile, cv */ diff --git a/ostd/vector.hh b/ostd/vector.hh index 61e7b74..edf30da 100644 --- a/ostd/vector.hh +++ b/ostd/vector.hh @@ -151,7 +151,7 @@ public: Vector(ConstRange(v.begin(), v.size()), a) {} template && IsConvertible, Value>::value + IsInputRange && IsConvertible, Value> >> Vector(R range, const A &a = A()): Vector(a) { ctor_from_range(range); } @@ -218,7 +218,7 @@ public: } template && IsConvertible, Value>::value + IsInputRange && IsConvertible, Value> >> Vector &operator=(R range) { clear(); ctor_from_range(range);