add some traits to check range for range types including proper type inheritance

This commit is contained in:
q66 2015-05-23 20:33:08 +01:00
parent 8908ac0506
commit 7589a93539
2 changed files with 72 additions and 9 deletions

View file

@ -15,9 +15,9 @@
namespace octa { namespace octa {
struct InputRangeTag {}; struct InputRangeTag {};
struct OutputRangeTag {}; struct OutputRangeTag {};
struct ForwardRangeTag {}; struct ForwardRangeTag: InputRangeTag {};
struct BidirectionalRangeTag {}; struct BidirectionalRangeTag: ForwardRangeTag {};
struct RandomAccessRangeTag {}; struct RandomAccessRangeTag: BidirectionalRangeTag {};
struct FiniteRandomAccessRangeTag: RandomAccessRangeTag {}; struct FiniteRandomAccessRangeTag: RandomAccessRangeTag {};
template<typename T> using RangeCategory = typename T::Category; template<typename T> using RangeCategory = typename T::Category;
@ -25,6 +25,69 @@ namespace octa {
template<typename T> using RangeValue = typename T::ValType; template<typename T> using RangeValue = typename T::ValType;
template<typename T> using RangeReference = typename T::RefType; template<typename T> using RangeReference = typename T::RefType;
// is input range
template<typename T, bool = IsConvertible<
RangeCategory<T>, InputRangeTag
>::value> struct IsInputRange: False {};
template<typename T>
struct IsInputRange<T, true>: True {};
// is forward range
template<typename T, bool = IsConvertible<
RangeCategory<T>, ForwardRangeTag
>::value> struct IsForwardRange: False {};
template<typename T>
struct IsForwardRange<T, true>: True {};
// is bidirectional range
template<typename T, bool = IsConvertible<
RangeCategory<T>, BidirectionalRangeTag
>::value> struct IsBidirectionalRange: False {};
template<typename T>
struct IsBidirectionalRange<T, true>: True {};
// is random access range
template<typename T, bool = IsConvertible<
RangeCategory<T>, RandomAccessRangeTag
>::value> struct IsRandomAccessRange: False {};
template<typename T>
struct IsRandomAccessRange<T, true>: True {};
// is finite random access range
template<typename T, bool = IsConvertible<
RangeCategory<T>, FiniteRandomAccessRangeTag
>::value> struct IsFiniteRandomAccessRange: False {};
template<typename T>
struct IsFiniteRandomAccessRange<T, true>: True {};
// is infinite random access range
template<typename T>
struct IsInfiniteRandomAccessRange: IntegralConstant<bool,
(IsRandomAccessRange<T>::value && !IsFiniteRandomAccessRange<T>::value)
> {};
// is output range
template<typename T, bool = IsConvertible<
RangeCategory<T>, OutputRangeTag
>::value> struct IsOutputRange: False {};
template<typename T>
struct IsOutputRange<T, true>: True {};
// range iterator
template<typename T> template<typename T>
struct __OctaRangeIterator { struct __OctaRangeIterator {
__OctaRangeIterator(): p_range() {} __OctaRangeIterator(): p_range() {}

View file

@ -31,9 +31,9 @@ namespace octa {
} }
template<typename R> template<typename R>
void ctor_from_range(R &range, EnableIf<IsSame< void ctor_from_range(R &range, EnableIf<IsFiniteRandomAccessRange<R>
RangeCategory<R>, FiniteRandomAccessRangeTag ::value, bool
>::value, bool> = true) { > = true) {
RangeSize<R> len = range.length(); RangeSize<R> len = range.length();
reserve(len); reserve(len);
p_len = len; p_len = len;
@ -44,9 +44,9 @@ namespace octa {
} }
template<typename R> template<typename R>
void ctor_from_range(R &range, EnableIf<!IsSame< void ctor_from_range(R &range, EnableIf<!IsFiniteRandomAccessRange<R>
RangeCategory<R>, FiniteRandomAccessRangeTag ::value, bool
>::value, bool> = true) { > = true) {
size_t i = 0; size_t i = 0;
for (; !range.empty(); range.pop_first()) { for (; !range.empty(); range.pop_first()) {
reserve(i + 1); reserve(i + 1);