1/*
2 * Copyright © 2018 Google, Inc.
3 *
4 * This is part of HarfBuzz, a text shaping library.
5 *
6 * Permission is hereby granted, without written agreement and without
7 * license or royalty fees, to use, copy, modify, and distribute this
8 * software and its documentation for any purpose, provided that the
9 * above copyright notice and the following two paragraphs appear in
10 * all copies of this software.
11 *
12 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
13 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
14 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
15 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
16 * DAMAGE.
17 *
18 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
19 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
20 * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
21 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
22 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
23 *
24 * Google Author(s): Behdad Esfahbod
25 */
26
27#ifndef HB_ITER_HH
28#define HB_ITER_HH
29
30#include "hb.hh"
31
32
33/* Unified iterator object.
34 *
35 * The goal of this template is to make the same iterator interface
36 * available to all types, and make it very easy and compact to use.
37 * Iterator objects are small, light-weight, objects that can be
38 * copied by value. If the collection / object being iterated on
39 * is writable, then the iterator points to lvalues, otherwise it
40 * returns rvalues.
41 *
42 * The way to declare, initialize, and use iterators, eg.:
43 *
44 * Iter<const int *> s (src);
45 * Iter<int *> t (dst);
46 * for (; s && t; s++, t++)
47 * *s = *t;
48 */
49
50template <typename T>
51struct Iter;
52
53#if 0
54template <typename T>
55struct Iter
56{
57 explicit inline Iter (const T &c);
58};
59#endif
60
61template <typename T>
62struct Iter<T *>
63{
64 /* Type of items. */
65 typedef T Value;
66
67 /* Constructors. */
68 inline Iter (T *array_, int length_) :
69 array (array_), length (MAX (length_, 0)) {}
70 template <unsigned int length_>
71 explicit inline Iter (T (&array_)[length_]) :
72 array (array_), length (length_) {}
73
74 /* Emptiness. */
75 explicit_operator inline operator bool (void) const { return bool (length); }
76
77 /* Current item. */
78 inline T &operator * (void)
79 {
80 if (unlikely (!length)) return CrapOrNull(T);
81 return *array;
82 }
83 inline T &operator -> (void)
84 {
85 return (operator *);
86 }
87
88 /* Next. */
89 inline Iter<T *> & operator ++ (void)
90 {
91 if (unlikely (!length)) return *this;
92 array++;
93 length--;
94 return *this;
95 }
96 /* Might return void, or a copy of pre-increment iterator. */
97 inline void operator ++ (int)
98 {
99 if (unlikely (!length)) return;
100 array++;
101 length--;
102 }
103
104 /* Some iterators might implement len(). */
105 inline unsigned int len (void) const { return length; }
106
107 /* Some iterators might implement fast-forward.
108 * Only implement it if it's constant-time. */
109 inline void operator += (unsigned int n)
110 {
111 n = MIN (n, length);
112 array += n;
113 length -= n;
114 }
115
116 /* Some iterators might implement random-access.
117 * Only implement it if it's constant-time. */
118 inline Iter<T *> & operator [] (unsigned int i)
119 {
120 if (unlikely (i >= length)) return CrapOrNull(T);
121 return array[i];
122 }
123
124 private:
125 T *array;
126 unsigned int length;
127};
128
129/* XXX Remove
130 * Just to test these compile. */
131static inline void
132m (void)
133{
134 const int src[10] = {};
135 int dst[20];
136
137 Iter<const int *> s (src);
138 Iter<const int *> s2 (src, 5);
139 Iter<int *> t (dst);
140
141 s2 = s;
142
143 for (; s && t; ++s, ++t)
144 {
145 *t = *s;
146 }
147}
148
149#endif /* HB_ITER_HH */
150