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 | |
50 | template <typename T> |
51 | struct Iter; |
52 | |
53 | #if 0 |
54 | template <typename T> |
55 | struct Iter |
56 | { |
57 | explicit inline Iter (const T &c); |
58 | }; |
59 | #endif |
60 | |
61 | template <typename T> |
62 | struct 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. */ |
131 | static inline void |
132 | m (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 | |