forked from OctaForge/libostd
add some traits to check range for range types including proper type inheritance
This commit is contained in:
parent
8908ac0506
commit
7589a93539
69
octa/range.h
69
octa/range.h
|
@ -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() {}
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue