initial proof-of-concept implementation of ranges and range iterator

master
Daniel Kolesa 2015-04-16 00:18:00 +01:00
parent e12b221112
commit c79e5757f9
2 changed files with 161 additions and 0 deletions

96
octa/range.h 100644
View File

@ -0,0 +1,96 @@
/* Ranges for OctaSTD.
*
* This file is part of OctaSTD. See COPYING.md for futher information.
*/
#ifndef OCTA_RANGE_H
#define OCTA_RANGE_H
#include <stddef.h>
#include "octa/types.h"
namespace octa {
template<typename T>
struct RangeTraits {
typedef typename T::type::difference difference;
typedef typename T::type::value value;
typedef typename T::type::pointer pointer;
typedef typename T::type::reference reference;
};
template<typename T>
struct RangeTraits<T *> {
typedef ptrdiff_t difference;
typedef T value;
typedef T *pointer;
typedef T &reference;
};
template<typename T>
struct RangeTraits<const T *> {
typedef ptrdiff_t difference;
typedef T value;
typedef const T *pointer;
typedef const T &reference;
};
template<>
struct RangeTraits<void *> {
typedef ptrdiff_t difference;
typedef uchar value;
typedef void *pointer;
typedef uchar &reference;
};
template<>
struct RangeTraits<const void *> {
typedef ptrdiff_t difference;
typedef uchar value;
typedef const void *pointer;
typedef const uchar &reference;
};
template<typename T>
class RangeIterator {
T p_range;
public:
struct type {
typedef typename RangeTraits<T>::difference difference;
typedef typename RangeTraits<T>::value value;
typedef typename RangeTraits<T>::pointer pointer;
typedef typename RangeTraits<T>::reference reference;
};
RangeIterator(): p_range() {}
RangeIterator(const T &range): p_range(range) {}
template<typename U>
RangeIterator(const RangeIterator<U> &it): p_range(it.range()) {}
T range() const { return p_range; }
RangeIterator &operator++() {
p_range.pop_first();
return *this;
}
typename type::reference operator*() {
return p_range.first();
}
template<typename U>
friend bool operator!=(const RangeIterator &a, const RangeIterator<U> &b) {
return a.range() != b.range();
}
};
template<typename T>
struct Range {
RangeIterator<T> begin() { return RangeIterator<T>((const T &)*this); }
RangeIterator<T> end() { return RangeIterator<T>(); }
};
}
#endif

View File

@ -12,8 +12,69 @@
#include "octa/new.h"
#include "octa/traits.h"
#include "octa/utility.h"
#include "octa/range.h"
namespace octa {
template<typename T>
class VectorRange: public Range<VectorRange<T> > {
T *p_beg, *p_end;
public:
struct type {
typedef ptrdiff_t difference;
typedef T value;
typedef T *pointer;
typedef T &reference;
};
VectorRange(): p_beg(nullptr), p_end(nullptr) {}
VectorRange(const VectorRange &v): p_beg(v.p_beg), p_end(v.p_end) {}
VectorRange(T *beg, T *end): p_beg(beg), p_end(end) {}
/* satisfy InputRange */
bool empty() const { return p_beg == nullptr; }
T &first() { return *p_beg; }
const T &first() const { return *p_beg; }
void pop_first() {
if (p_beg == nullptr) return;
if (++p_beg == p_end) p_beg = p_end = nullptr;
}
template<typename U>
friend bool operator==(const VectorRange &a, const VectorRange<U> &b) {
return a.p_beg == b.p_beg && a.p_end == b.p_end;
}
template<typename U>
friend bool operator!=(const VectorRange &a, const VectorRange<U> &b) {
return a.p_beg != b.p_beg || a.p_end != b.p_end;
}
/* satisfy ForwardRange */
VectorRange save() { return *this; }
/* satisfy BidirectionalRange */
T &last() { return *(p_end - 1); }
const T &last() const { return *(p_end - 1); }
void pop_last() {
if (p_end-- == p_beg) { p_end = nullptr; return; }
if (p_end == p_beg) p_beg = p_end = nullptr;
}
/* satisfy RandomAccessRange */
T &operator[](size_t i) { return p_beg[i]; }
const T &operator[](size_t i) const { return p_beg[i]; }
size_t length() const { return p_end - p_beg; }
};
template<typename T>
class Vector {
T *p_buf;
@ -221,6 +282,10 @@ namespace octa {
for (size_t i = 0; i < n; ++i) p_buf[idx + i] = v[i];
return &p_buf[idx];
}
VectorRange<T> each() {
return VectorRange<T>(p_buf, p_buf + p_len);
}
};
}