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

master
Daniel Kolesa 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 {
struct InputRangeTag {};
struct OutputRangeTag {};
struct ForwardRangeTag {};
struct BidirectionalRangeTag {};
struct RandomAccessRangeTag {};
struct ForwardRangeTag: InputRangeTag {};
struct BidirectionalRangeTag: ForwardRangeTag {};
struct RandomAccessRangeTag: BidirectionalRangeTag {};
struct FiniteRandomAccessRangeTag: RandomAccessRangeTag {};
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 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>
struct __OctaRangeIterator {
__OctaRangeIterator(): p_range() {}

View File

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