2 * Copyright © 2018 Google, Inc.
4 * This is part of HarfBuzz, a text shaping library.
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.
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
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.
24 * Google Author(s): Behdad Esfahbod
30 #include "hb-array.hh"
32 #include "hb-ot-layout-common.hh"
36 struct array_iter_t
: hb_iter_with_fallback_t
<array_iter_t
<T
>, T
&>
38 array_iter_t (hb_array_t
<T
> arr_
) : arr (arr_
) {}
40 typedef T
& __item_t__
;
41 static constexpr bool is_random_access_iterator
= true;
42 T
& __item_at__ (unsigned i
) const { return arr
[i
]; }
43 void __forward__ (unsigned n
) { arr
+= n
; }
44 void __rewind__ (unsigned n
) { arr
-= n
; }
45 unsigned __len__ () const { return arr
.length
; }
46 bool operator != (const array_iter_t
& o
) { return arr
!= o
.arr
; }
55 some_array_t (hb_array_t
<T
> arr_
) : arr (arr_
) {}
57 typedef array_iter_t
<T
> iter_t
;
58 array_iter_t
<T
> iter () { return array_iter_t
<T
> (arr
); }
59 operator array_iter_t
<T
> () { return iter (); }
60 operator hb_iter_t
<array_iter_t
<T
>> () { return iter (); }
67 template <typename Iter
,
68 hb_requires (hb_is_iterator (Iter
))>
70 test_iterator_non_default_constructable (Iter it
)
72 /* Iterate over a copy of it. */
73 for (auto c
= it
.iter (); c
; c
++)
77 for (auto c
= +it
; c
; c
++)
80 /* Range-based for over a copy. */
88 assert (*it
== it
[0]);
90 static_assert (true || it
.is_random_access_iterator
, "");
91 static_assert (true || it
.is_sorted_iterator
, "");
94 template <typename Iter
,
95 hb_requires (hb_is_iterator (Iter
))>
97 test_iterator (Iter it
)
99 Iter default_constructed
;
100 assert (!default_constructed
);
102 test_iterator_non_default_constructable (it
);
105 template <typename Iterable
,
106 hb_requires (hb_is_iterable (Iterable
))>
108 test_iterable (const Iterable
&lst
= Null (Iterable
))
113 // Test that can take iterator from.
114 test_iterator (lst
.iter ());
117 template <typename It
>
118 static void check_sequential (It it
)
126 static void test_concat ()
128 hb_vector_t
<int> a
= {1, 2, 3};
129 hb_vector_t
<int> b
= {4, 5};
131 hb_vector_t
<int> c
= {};
132 hb_vector_t
<int> d
= {1, 2, 3, 4, 5};
134 auto it1
= hb_concat (a
, b
);
135 assert (it1
.len () == 5);
136 assert (it1
.is_random_access_iterator
);
137 auto it2
= hb_concat (c
, d
);
138 assert (it2
.len () == 5);
139 auto it3
= hb_concat (d
, c
);
140 assert (it3
.len () == 5);
141 for (int i
= 0; i
< 5; i
++) {
142 assert(it1
[i
] == i
+ 1);
143 assert(it2
[i
] == i
+ 1);
144 assert(it3
[i
] == i
+ 1);
147 check_sequential (it1
);
148 check_sequential (it2
);
149 check_sequential (it3
);
158 assert (it4
.len () == 3);
163 assert (it4
.len () == 1);
167 assert (it4
.len () == 0);
173 hb_set_t s_a
= {1, 2, 3};
174 hb_set_t s_b
= {4, 5};
175 auto it6
= hb_concat (s_a
, s_b
);
176 assert (!it6
.is_random_access_iterator
);
177 check_sequential (it6
);
178 assert (it6
.len () == 5);
186 assert (it6
.len () == 2);
190 main (int argc
, char **argv
)
192 const int src
[10] = {};
196 array_iter_t
<const int> s (src
); /* Implicit conversion from static array. */
197 array_iter_t
<const int> s2 (v
); /* Implicit conversion from vector. */
198 array_iter_t
<int> t (dst
);
200 static_assert (array_iter_t
<int>::is_random_access_iterator
, "");
202 some_array_t
<const int> a (src
);
211 hb_copy (a
.iter (), t
);
217 hb_sorted_array_t
<int> sa
;
218 (void) static_cast<hb_iter_t
<hb_sorted_array_t
<int>, hb_sorted_array_t
<int>::item_t
>&> (sa
);
219 (void) static_cast<hb_iter_t
<hb_sorted_array_t
<int>, hb_sorted_array_t
<int>::__item_t__
>&> (sa
);
220 (void) static_cast<hb_iter_t
<hb_sorted_array_t
<int>, int&>&>(sa
);
221 (void) static_cast<hb_iter_t
<hb_sorted_array_t
<int>>&>(sa
);
222 (void) static_cast<hb_iter_t
<hb_array_t
<int>, int&>&> (sa
);
225 test_iterable
<hb_array_t
<int>> ();
226 test_iterable
<hb_sorted_array_t
<const int>> ();
227 test_iterable
<hb_vector_t
<float>> ();
228 test_iterable
<hb_set_t
> ();
229 test_iterable
<OT::Coverage
> ();
231 test_iterator (hb_zip (st
, v
));
232 test_iterator_non_default_constructable (hb_enumerate (st
));
233 test_iterator_non_default_constructable (hb_enumerate (st
, -5));
234 test_iterator_non_default_constructable (hb_enumerate (hb_iter (st
)));
235 test_iterator_non_default_constructable (hb_enumerate (hb_iter (st
) + 1));
236 test_iterator_non_default_constructable (hb_iter (st
) | hb_filter ());
237 test_iterator_non_default_constructable (hb_iter (st
) | hb_map (hb_lidentity
));
239 assert (true == hb_all (st
));
240 assert (false == hb_all (st
, 42u));
241 assert (true == hb_any (st
));
242 assert (false == hb_any (st
, 14u));
243 assert (true == hb_any (st
, 14u, [] (unsigned _
) { return _
- 1u; }));
244 assert (true == hb_any (st
, [] (unsigned _
) { return _
== 15u; }));
245 assert (true == hb_any (st
, 15u));
246 assert (false == hb_none (st
));
247 assert (false == hb_none (st
, 15u));
248 assert (true == hb_none (st
, 17u));
250 hb_array_t
<hb_vector_t
<int>> pa
;
264 | hb_filter (hb_bool
)
265 | hb_filter (hb_bool
, hb_identity
)
270 | hb_sink (hb_array (dst
))
278 | hb_map ([] (int i
) { return 1; })
279 | hb_reduce ([=] (int acc
, int value
) { return acc
; }, 2)
282 using map_pair_t
= hb_item_type
<hb_map_t
>;
284 | hb_map ([] (map_pair_t p
) { return p
.first
* p
.second
; })
288 using map_key_t
= decltype (*m
.keys());
289 + hb_iter (m
.keys ())
290 | hb_filter ([] (map_key_t k
) { return k
< 42; })
295 using map_value_t
= decltype (*m
.values());
296 + hb_iter (m
.values ())
297 | hb_filter ([] (map_value_t k
) { return k
< 42; })
301 unsigned int temp1
= 10;
302 unsigned int temp2
= 0;
305 | hb_map ([&] (int i
) -> hb_set_t
*
307 hb_set_t
*set
= hb_set_create ();
308 for (unsigned int i
= 0; i
< temp1
; ++i
)
313 | hb_reduce ([&] (hb_map_t
*acc
, hb_set_t
*value
) -> hb_map_t
*
315 hb_map_set (acc
, temp2
++, hb_set_get_population (value
));
316 /* This is not a memory managed language, take care! */
317 hb_set_destroy (value
);
321 /* The result should be something like 0->10, 1->11, ..., 9->19 */
322 assert (hb_map_get (result
, 9) == 19);
324 unsigned int temp3
= 0;
326 | hb_map([&] (int i
) { return ++temp3
; })
327 | hb_reduce([&] (float acc
, int value
) { return acc
+ value
; }, 0)
329 hb_map_destroy (result
);
342 assert ((&vl
) + 1 == *++hb_iota (&vl
, hb_inc
));
346 hb_repeat (vl
) | hb_chop (3);
347 assert (hb_len (hb_range (10) | hb_take (3)) == 3);
348 assert (hb_range (9).len () == 9);
349 assert (hb_range (2, 9).len () == 7);
350 assert (hb_range (2, 9, 3).len () == 3);
351 assert (hb_range (2, 8, 3).len () == 2);
352 assert (hb_range (2, 7, 3).len () == 2);
353 assert (hb_range (-2, -9, -3).len () == 3);
354 assert (hb_range (-2, -8, -3).len () == 2);
355 assert (hb_range (-2, -7, -3).len () == 2);