From a6744105dcf467b5fb04f787b825d97bad93a132 Mon Sep 17 00:00:00 2001 From: q66 Date: Wed, 13 Jan 2016 17:42:37 +0000 Subject: [PATCH] convert range checks to template vars --- ostd/internal/hashtable.hh | 4 +- ostd/keyset.hh | 6 +- ostd/map.hh | 6 +- ostd/range.hh | 154 +++++++++++++++++++++---------------- ostd/set.hh | 6 +- ostd/string.hh | 15 ++-- ostd/vector.hh | 10 +-- 7 files changed, 107 insertions(+), 94 deletions(-) diff --git a/ostd/internal/hashtable.hh b/ostd/internal/hashtable.hh index 57bea35..df6fba8 100644 --- a/ostd/internal/hashtable.hh +++ b/ostd/internal/hashtable.hh @@ -27,14 +27,14 @@ namespace detail { template static inline Size estimate_hrsize(const R &range, - EnableIf::value, bool> = true + EnableIf, bool> = true ) { return range.size(); } template static inline Size estimate_hrsize(const R &, - EnableIf::value, bool> = true + EnableIf, bool> = true ) { /* we have no idea how big the range actually is */ return 16; diff --git a/ostd/keyset.hh b/ostd/keyset.hh index 832c4ab..6e04d9d 100644 --- a/ostd/keyset.hh +++ b/ostd/keyset.hh @@ -86,8 +86,7 @@ namespace detail { KeysetImpl(KeysetImpl &&m, const A &alloc): Base(move(m), alloc) {} template::value && IsConvertible, - Value>::value + IsInputRange && IsConvertible, Value>::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), @@ -127,8 +126,7 @@ namespace detail { } template::value && - IsConvertible, Value>::value + IsInputRange && IsConvertible, Value>::value >> KeysetImpl &operator=(R range) { Base::assign_range(range); return *this; diff --git a/ostd/map.hh b/ostd/map.hh index 1e6453c..f2f4f2b 100644 --- a/ostd/map.hh +++ b/ostd/map.hh @@ -86,8 +86,7 @@ namespace detail { MapImpl(MapImpl &&m, const A &alloc): Base(move(m), alloc) {} template::value && IsConvertible, - Value>::value + IsInputRange && IsConvertible, Value>::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), @@ -127,8 +126,7 @@ namespace detail { } template::value && - IsConvertible, Value>::value + IsInputRange && IsConvertible, Value>::value >> MapImpl &operator=(R range) { Base::assign_range(range); return *this; diff --git a/ostd/range.hh b/ostd/range.hh index 4a0d1ba..f6edbc3 100644 --- a/ostd/range.hh +++ b/ostd/range.hh @@ -73,113 +73,129 @@ namespace detail { namespace detail { template, InputRangeTag - >::value> struct IsInputRangeBase: False {}; + >::value> struct IsInputRangeCore: False {}; template - struct IsInputRangeBase: True {}; + struct IsInputRangeCore: True {}; + + template::value> + struct IsInputRangeBase: False {}; + + template + struct IsInputRangeBase: detail::IsInputRangeCore::Type {}; } -template::value> -struct IsInputRange: False {}; - template -struct IsInputRange: detail::IsInputRangeBase::Type {}; +static constexpr bool IsInputRange = detail::IsInputRangeBase::value; // is forward range namespace detail { template, ForwardRangeTag - >::value> struct IsForwardRangeBase: False {}; + >::value> struct IsForwardRangeCore: False {}; template - struct IsForwardRangeBase: True {}; + struct IsForwardRangeCore: True {}; + + template::value> + struct IsForwardRangeBase: False {}; + + template + struct IsForwardRangeBase: detail::IsForwardRangeCore::Type {}; } -template::value> -struct IsForwardRange: False {}; - template -struct IsForwardRange: detail::IsForwardRangeBase::Type {}; +static constexpr bool IsForwardRange = detail::IsForwardRangeBase::value; // is bidirectional range namespace detail { template, BidirectionalRangeTag - >::value> struct IsBidirectionalRangeBase: False {}; + >::value> struct IsBidirectionalRangeCore: False {}; template - struct IsBidirectionalRangeBase: True {}; + struct IsBidirectionalRangeCore: True {}; + + template::value> + struct IsBidirectionalRangeBase: False {}; + + template + struct IsBidirectionalRangeBase: + detail::IsBidirectionalRangeCore::Type {}; } -template::value> -struct IsBidirectionalRange: False {}; - -template -struct IsBidirectionalRange: - detail::IsBidirectionalRangeBase::Type {}; +template static constexpr bool IsBidirectionalRange + = detail::IsBidirectionalRangeBase::value; // is random access range namespace detail { template, RandomAccessRangeTag - >::value> struct IsRandomAccessRangeBase: False {}; + >::value> struct IsRandomAccessRangeCore: False {}; template - struct IsRandomAccessRangeBase: True {}; + struct IsRandomAccessRangeCore: True {}; + + template::value> + struct IsRandomAccessRangeBase: False {}; + + template + struct IsRandomAccessRangeBase: + detail::IsRandomAccessRangeCore::Type {}; } -template::value> -struct IsRandomAccessRange: False {}; - -template -struct IsRandomAccessRange: - detail::IsRandomAccessRangeBase::Type {}; +template static constexpr bool IsRandomAccessRange + = detail::IsRandomAccessRangeBase::value; // is finite random access range namespace detail { template, FiniteRandomAccessRangeTag - >::value> struct IsFiniteRandomAccessRangeBase: False {}; + >::value> struct IsFiniteRandomAccessRangeCore: False {}; template - struct IsFiniteRandomAccessRangeBase: True {}; + struct IsFiniteRandomAccessRangeCore: True {}; + + template::value> + struct IsFiniteRandomAccessRangeBase: False {}; + + template + struct IsFiniteRandomAccessRangeBase: + detail::IsFiniteRandomAccessRangeCore::Type {}; } -template::value> -struct IsFiniteRandomAccessRange: False {}; - -template -struct IsFiniteRandomAccessRange: - detail::IsFiniteRandomAccessRangeBase::Type {}; +template static constexpr bool IsFiniteRandomAccessRange + = detail::IsFiniteRandomAccessRangeBase::value; // is infinite random access range -template -struct IsInfiniteRandomAccessRange: IntegralConstant::value && !IsFiniteRandomAccessRange::value) -> {}; +template static constexpr bool IsInfiniteRandomAccessRange + = IsRandomAccessRange && !IsFiniteRandomAccessRange; // is contiguous range namespace detail { template, ContiguousRangeTag - >::value> struct IsContiguousRangeBase: False {}; + >::value> struct IsContiguousRangeCore: False {}; template - struct IsContiguousRangeBase: True {}; + struct IsContiguousRangeCore: True {}; + + template::value> + struct IsContiguousRangeBase: False {}; + + template + struct IsContiguousRangeBase: + detail::IsContiguousRangeCore::Type {}; } -template::value> -struct IsContiguousRange: False {}; - -template -struct IsContiguousRange: - detail::IsContiguousRangeBase::Type {}; +template static constexpr bool IsContiguousRange + = detail::IsContiguousRangeBase::value; // is output range @@ -191,18 +207,28 @@ namespace detail { template static int test(...); static constexpr bool value = (sizeof(test(0)) == sizeof(char)); }; + + template, OutputRangeTag + >::value || (IsInputRange && + (detail::OutputRangeTest &>::value || + detail::OutputRangeTest &&>::value || + detail::OutputRangeTest >::value) + ))> struct IsOutputRangeCore: False {}; + + template + struct IsOutputRangeCore: True {}; + + template::value> + struct IsOutputRangeBase: False {}; + + template + struct IsOutputRangeBase: + detail::IsOutputRangeCore::Type {}; } -template, OutputRangeTag ->::value || (IsInputRange::value && - (detail::OutputRangeTest &>::value || - detail::OutputRangeTest &&>::value || - detail::OutputRangeTest >::value) -))> struct IsOutputRange: False {}; - -template -struct IsOutputRange: True {}; +template static constexpr bool IsOutputRange + = detail::IsOutputRangeBase::value; namespace detail { // range iterator @@ -236,7 +262,7 @@ namespace detail { template struct HalfRange; namespace detail { - template::value> + template> struct RangeAdd; template @@ -484,9 +510,8 @@ template::value> - > Size copy(OR &&orange, Size n = -1) { + template>> + Size copy(OR &&orange, Size n = -1) { B r(*((B *)this)); Size on = n; for (; n && !r.empty(); --n) { @@ -995,9 +1020,8 @@ public: return ret; } - template::value - >> Size copy(R &&orange, Size n = -1) { + template>> + Size copy(R &&orange, Size n = -1) { Size c = size(); if (n < c) c = n; return orange.put_n(p_beg, c); diff --git a/ostd/set.hh b/ostd/set.hh index 1bb0f3e..7cc9cc5 100644 --- a/ostd/set.hh +++ b/ostd/set.hh @@ -75,8 +75,7 @@ namespace detail { SetImpl(SetImpl &&m, const A &alloc): Base(move(m), alloc) {} template::value && - IsConvertible, Value>::value + IsInputRange && IsConvertible, Value>::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), @@ -116,8 +115,7 @@ namespace detail { } template::value && - IsConvertible, Value>::value + IsInputRange && IsConvertible, Value>::value >> SetImpl &operator=(R range) { Base::assign_range(range); return *this; diff --git a/ostd/string.hh b/ostd/string.hh index 7d9fefe..7eb12be 100644 --- a/ostd/string.hh +++ b/ostd/string.hh @@ -209,8 +209,7 @@ class StringBase { template void ctor_from_range(R &range, EnableIf< - IsFiniteRandomAccessRange::value && - IsSame>>, bool + IsFiniteRandomAccessRange && IsSame>>, bool > = true) { if (range.empty()) return; RangeSize l = range.size(); @@ -222,8 +221,8 @@ class StringBase { template void ctor_from_range(R &range, EnableIf< - !IsFiniteRandomAccessRange::value || - !IsSame>>, bool + !IsFiniteRandomAccessRange || !IsSame>>, + bool > = true) { if (range.empty()) return; Size i = 0; @@ -327,8 +326,7 @@ public: > &a = A()): StringBase(ConstRange(v), a) {} template::value && - IsConvertible, Value>::value + IsInputRange && IsConvertible, Value>::value >> StringBase(R range, const A &a = A()): StringBase(a) { ctor_from_range(range); } @@ -400,8 +398,7 @@ public: } template::value && - IsConvertible, Value>::value + IsInputRange && IsConvertible, Value>::value >> StringBase &operator=(const R &r) { clear(); ctor_from_range(r); @@ -503,7 +500,7 @@ public: } template::value && + IsInputRange && IsConvertible, Value>::value && !IsConvertible::value >> StringBase &append(R range) { diff --git a/ostd/vector.hh b/ostd/vector.hh index 75abd29..61e7b74 100644 --- a/ostd/vector.hh +++ b/ostd/vector.hh @@ -35,7 +35,7 @@ class Vector { template void ctor_from_range(R &range, EnableIf< - IsFiniteRandomAccessRange::value && IsPod && + IsFiniteRandomAccessRange && IsPod && IsSame>>, bool > = true) { RangeSize l = range.size(); @@ -46,7 +46,7 @@ class Vector { template void ctor_from_range(R &range, EnableIf< - !IsFiniteRandomAccessRange::value || !IsPod || + !IsFiniteRandomAccessRange || !IsPod || !IsSame>>, bool > = true) { Size i = 0; @@ -151,8 +151,7 @@ public: Vector(ConstRange(v.begin(), v.size()), a) {} template::value && - IsConvertible, Value>::value + IsInputRange && IsConvertible, Value>::value >> Vector(R range, const A &a = A()): Vector(a) { ctor_from_range(range); } @@ -219,8 +218,7 @@ public: } template::value && - IsConvertible, Value>::value + IsInputRange && IsConvertible, Value>::value >> Vector &operator=(R range) { clear(); ctor_from_range(range);