[iter] add hb_concat (a, b).

Iterates over a, and then over b.
pull/3312/head
Garret Rieger 3 years ago committed by Behdad Esfahbod
parent 95329081c2
commit ca22741110
  1. 73
      src/hb-iter.hh
  2. 33
      src/test-iter.cc

@ -581,6 +581,79 @@ struct
}
HB_FUNCOBJ (hb_zip);
/* hb_concat() */
template <typename A, typename B>
struct hb_concat_iter_t :
hb_iter_t<hb_concat_iter_t<A, B>, typename A::item_t>
{
hb_concat_iter_t () {}
hb_concat_iter_t (A& a, B& b) : a (a), b (b) {}
hb_concat_iter_t (const A& a, const B& b) : a (a), b (b) {}
typedef typename A::item_t __item_t__;
static constexpr bool is_random_access_iterator =
A::is_random_access_iterator &&
B::is_random_access_iterator;
static constexpr bool is_sorted_iterator = false;
__item_t__ __item__ () const
{
if (!a)
return *b;
return *a;
}
__item_t__ __item_at__ (unsigned i) const
{
if (i < a.len())
return a[i];
return b[i - a.len()];
}
bool __more__ () const { return bool (a) || bool (b); }
unsigned __len__ () const { return a.len () + b.len (); }
void __next__ ()
{
if (a)
++a;
else
++b;
}
void __forward__ (unsigned n)
{
if (n > a.len ()) {
a.__forward__ (a.len ());
n -= a.len ();
}
b.__forward (n);
}
hb_concat_iter_t __end__ () const { return hb_concat_iter_t (a.end (), b.end ()); }
bool operator != (const hb_concat_iter_t& o) const
{
return a != o.a
|| b != o.b;
}
private:
A a;
B b;
};
struct
{ HB_PARTIALIZE(2);
template <typename A, typename B,
hb_requires (hb_is_iterable (A) && hb_is_iterable (B))>
hb_concat_iter_t<hb_iter_type<A>, hb_iter_type<B>>
operator () (A&& a, B&& b) const
{ return hb_concat_iter_t<hb_iter_type<A>, hb_iter_type<B>> (hb_iter (a), hb_iter (b)); }
}
HB_FUNCOBJ (hb_concat);
/* hb_apply() */
template <typename Appl>

@ -114,6 +114,37 @@ test_iterable (const Iterable &lst = Null (Iterable))
test_iterator (lst.iter ());
}
template <typename It>
static void check_sequential (It it)
{
int i = 1;
for (int v : +it) {
assert (v == i++);
}
}
static void test_concat ()
{
hb_vector_t<int> a = {1, 2, 3};
hb_vector_t<int> b = {4, 5};
hb_vector_t<int> c = {};
hb_vector_t<int> d = {1, 2, 3, 4, 5};
auto it1 = hb_concat (a, b);
auto it2 = hb_concat (c, d);
auto it3 = hb_concat (d, c);
for (int i = 0; i < 5; i++) {
assert(it1[i] == i + 1);
assert(it2[i] == i + 1);
assert(it3[i] == i + 1);
}
check_sequential (it1);
check_sequential (it2);
check_sequential (it3);
}
int
main (int argc, char **argv)
{
@ -282,5 +313,7 @@ main (int argc, char **argv)
assert (hb_range (-2, -8, -3).len () == 2);
assert (hb_range (-2, -7, -3).len () == 2);
test_concat ();
return 0;
}

Loading…
Cancel
Save