/* * Copyright © 2018 Google, Inc. * * This is part of HarfBuzz, a text shaping library. * * Permission is hereby granted, without written agreement and without * license or royalty fees, to use, copy, modify, and distribute this * software and its documentation for any purpose, provided that the * above copyright notice and the following two paragraphs appear in * all copies of this software. * * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH * DAMAGE. * * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. * * Google Author(s): Behdad Esfahbod */ #ifndef HB_ITER_HH #define HB_ITER_HH #include "hb.hh" /* Unified iterator object. * * 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. * Iterator objects are small, light-weight, objects that can be * copied by value. If the collection / object being iterated on * is writable, then the iterator points to lvalues, otherwise it * returns rvalues. * * The way to declare, initialize, and use iterators, eg.: * * Iter s (src); * Iter t (dst); * for (; s && t; s++, t++) * *s = *t; */ template struct Iter; #if 0 template struct Iter { explicit inline Iter (const T &c); }; #endif template struct Iter { /* Type of items. */ typedef T Value; /* Constructors. */ inline Iter (T *array_, int length_) : array (array_), length (MAX (length_, 0)) {} template explicit inline Iter (T (&array_)[length_]) : array (array_), length (length_) {} /* Emptiness. */ explicit_operator inline operator bool (void) const { return bool (length); } /* Current item. */ inline T &operator * (void) { if (unlikely (!length)) return CrapOrNull(T); return *array; } inline T &operator -> (void) { return (operator *); } /* Next. */ inline Iter & operator ++ (void) { if (unlikely (!length)) return *this; array++; length--; return *this; } /* Might return void, or a copy of pre-increment iterator. */ inline void operator ++ (int) { if (unlikely (!length)) return; array++; length--; } /* Some iterators might implement len(). */ inline unsigned int len (void) const { return length; } /* Some iterators might implement fast-forward. * Only implement it if it's constant-time. */ inline void operator += (unsigned int n) { n = MIN (n, length); array += n; length -= n; } /* Some iterators might implement random-access. * Only implement it if it's constant-time. */ inline Iter & operator [] (unsigned int i) { if (unlikely (i >= length)) return CrapOrNull(T); return array[i]; } private: T *array; unsigned int length; }; /* XXX Remove * Just to test these compile. */ static inline void m (void) { const int src[10] = {}; int dst[20]; Iter s (src); Iter s2 (src, 5); Iter t (dst); s2 = s; for (; s && t; ++s, ++t) { *t = *s; } } #endif /* HB_ITER_HH */