[iter] Sketch new iterator design

This commit is contained in:
Behdad Esfahbod 2018-12-21 00:54:55 -05:00
parent f6d5f1e91c
commit 314d8698d0
2 changed files with 60 additions and 92 deletions

View File

@ -34,113 +34,65 @@
* *
* The goal of this template is to make the same iterator interface * The goal of this template is to make the same iterator interface
* available to all types, and make it very easy and compact to use. * available to all types, and make it very easy and compact to use.
* Iterator objects are small, light-weight, objects that can be * hb_iter_tator objects are small, light-weight, objects that can be
* copied by value. If the collection / object being iterated on * copied by value. If the collection / object being iterated on
* is writable, then the iterator points to lvalues, otherwise it * is writable, then the iterator returns lvalues, otherwise it
* returns rvalues. * returns rvalues.
*
* The way to declare, initialize, and use iterators, eg.:
*
* Iter<const int *> s (src);
* Iter<int *> t (dst);
* for (; s && t; s++, t++)
* *s = *t;
*/ */
template <typename T> /* Base class for all iterators. */
struct Iter; template <typename Iter>
struct hb_iter_t
#if 0
template <typename T>
struct Iter
{ {
Iter (const T &c); typedef Iter type_t;
}; typedef typename Iter::__type__ item_type_t;
#endif
template <typename T> /* https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern */
struct Iter<T *> const type_t* thiz () const { return static_cast<const type_t *> (this); }
{ type_t* thiz () { return static_cast< type_t *> (this); }
/* Type of items. */
typedef T Value;
/* Constructors. */ /* Operators. */
Iter (T *array_, int length_) : operator type_t () { return iter(); }
array (array_), length (MAX (length_, 0)) {} explicit_operator bool () const { return more (); }
template <unsigned int length_> item_type_t& operator * () { return item (); }
Iter (T (&array_)[length_]) : item_type_t& operator [] (unsigned i) { return item (i); }
array (array_), length (length_) {} type_t& operator += (unsigned count) { forward (count); return thiz(); }
type_t& operator ++ () { next (); return thiz(); }
type_t operator + (unsigned count) { type_t c (*thiz()); c += count; return c; }
type_t operator ++ (int) { type_t c (*thiz()); ++*this; return c; }
/* Emptiness. */ /* Methods. */
explicit_operator bool () const { return length; } type_t iter () const { return *thiz(); }
item_type_t item () const { return thiz()->__item__ (); }
item_type_t item (unsigned i) const { return thiz()->__item__ (i); }
bool more () const { return thiz()->__more__ (); }
void next () { thiz()->next (); }
void forward (unsigned n) { thiz()->__forward__ (n); }
unsigned len () const { return thiz()->__len__ (); }
/* Current item. */ /*
T &operator * () * Subclasses overrides:
{ */
if (unlikely (!length)) return CrapOrNull(T);
return *array;
}
T &operator -> () { return (operator *); }
/* Next. */ /* Item type. */
Iter<T *> & operator ++ () //typedef ... __type__;
{
if (unlikely (!length)) return *this;
array++;
length--;
return *this;
}
/* Might return void, or a copy of pre-increment iterator. */
void operator ++ (int)
{
if (unlikely (!length)) return;
array++;
length--;
}
/* Some iterators might implement len(). */ /* Access: Implement __item__(), or __item__(n) if random-access. */
unsigned int len () const { return length; } item_type_t __item__ () const { return thiz()->item (0); }
item_type_t __item__ (unsigned i) const { return *(thiz() + i); }
/* Some iterators might implement fast-forward. /* Termination: Implement __more__() or __end__(). */
* Only implement it if it's constant-time. */ bool __more__ () const { return item () != thiz()->__end__ (); }
void operator += (unsigned int n) const item_type_t& __end__ () const { return type_t::__sentinel__; }
{
n = MIN (n, length);
array += n;
length -= n;
}
/* Some iterators might implement random-access. /* Advancing: Implement __next__(), or __forward__() if random-access. */
* Only implement it if it's constant-time. */ void __next__ () { thiz()->forward (1); }
Iter<T *> & operator [] (unsigned int i) void __forward__ (unsigned n) { while (n--) next (); }
{
if (unlikely (i >= length)) return CrapOrNull(T);
return array[i];
}
private: /* Population: Implement __len__() if known. */
T *array; unsigned __len__ () const
unsigned int length; { type_t c (*thiz()); unsigned l = 0; while (c) { c++; l++; }; return l; }
}; };
/* XXX Remove
* Just to test these compile. */
static inline void
m ()
{
const int src[10] = {};
int dst[20];
Iter<const int *> s (src);
Iter<const int *> s2 (src, 5);
Iter<int *> t (dst);
s2 = s;
for (; s && t; ++s, ++t)
{
*t = *s;
}
}
#endif /* HB_ITER_HH */ #endif /* HB_ITER_HH */

View File

@ -29,5 +29,21 @@
int int
main (int argc, char **argv) main (int argc, char **argv)
{ {
const int src[10] = {};
int dst[20];
#if 0
hb_iter_t<const int *> s (src);
hb_iter_t<const int *> s2 (src, 5);
hb_iter_t<int *> t (dst);
s2 = s;
for (; s && t; ++s, ++t)
{
*t = *s;
}
#endif
return 0; return 0;
} }