From cb1bf48aaa1031e5efca4dc7571a8c9a6b996676 Mon Sep 17 00:00:00 2001 From: q66 Date: Fri, 29 May 2015 23:48:05 +0100 Subject: [PATCH] allow range traits to work on halves --- octa/range.h | 55 ++++++++++++++++++++++++++++++---------------------- 1 file changed, 32 insertions(+), 23 deletions(-) diff --git a/octa/range.h b/octa/range.h index d5ca3af..aefd5e1 100644 --- a/octa/range.h +++ b/octa/range.h @@ -20,11 +20,27 @@ namespace octa { struct RandomAccessRangeTag: BidirectionalRangeTag {}; struct FiniteRandomAccessRangeTag: RandomAccessRangeTag {}; - template using RangeCategory = typename T::Category; - template using RangeSize = typename T::SizeType; - template using RangeValue = typename T::ValType; - template using RangeReference = typename T::RefType; - template using RangeDifference = typename T::DiffType; + template struct RangeHalf; + +#define __OCTA_RANGE_TRAIT(Name, TypeName) \ + template \ + struct __OctaRange##Name { \ + typedef typename T::TypeName Type; \ + }; \ + template \ + struct __OctaRange##Name> { \ + typedef typename T::TypeName Type; \ + }; \ + template \ + using Range##Name = typename __OctaRange##Name::Type; + + __OCTA_RANGE_TRAIT(Category, Category) + __OCTA_RANGE_TRAIT(Size, SizeType) + __OCTA_RANGE_TRAIT(Value, ValType) + __OCTA_RANGE_TRAIT(Reference, RefType) + __OCTA_RANGE_TRAIT(Difference, DiffType) + +#undef __OCTA_RANGE_TRAIT // is input range @@ -847,11 +863,8 @@ namespace octa { template struct HalfRange: InputRange, - RangeCategory , - RangeValue , - RangeReference , - RangeSize , - RangeDifference + RangeCategory, RangeValue, RangeReference, RangeSize, + RangeDifference > { private: T p_beg; @@ -894,10 +907,10 @@ namespace octa { return p_end.next(); } - RangeReference first() const { + RangeReference first() const { return p_beg.get(); } - RangeReference last() const { + RangeReference last() const { auto copy = p_end; copy.prev(); return copy.get(); @@ -910,33 +923,29 @@ namespace octa { return p_end == range.p_end; } - RangeDifference - distance_first(const HalfRange &range) const { + RangeDifference distance_first(const HalfRange &range) const { return p_beg.distance(range.p_beg); } - RangeDifference - distance_last(const HalfRange &range) const { + RangeDifference distance_last(const HalfRange &range) const { return p_end.distance(range.p_end); } - RangeSize size() { + RangeSize size() const { return p_end - p_beg; } - HalfRange slice(RangeSize start, - RangeSize end) { + HalfRange slice(RangeSize start, RangeSize end) const { return HalfRange(p_beg + start, p_beg + end); } - RangeReference - operator[](RangeSize idx) { + RangeReference operator[](RangeSize idx) const { return p_beg[idx]; } - void put(const RangeValue &v) { + void put(const RangeValue &v) { p_beg.range().put(v); } - void put(RangeValue &&v) { + void put(RangeValue &&v) { p_beg.range().put(move(v)); } };