103 typename HeadC::Iterator it;
105 using T = std::decay_t<typename HeadC::Item_Type>;
110 =
decltype(std::tuple_cat(std::declval<std::tuple<T>>(),
147 std::tuple<T> curr(it.get_curr());
157 std::tuple<T> curr(it.get_curr_ne());
192 using T = std::decay_t<typename C::Item_Type>;
214 return std::tuple<T>(C::Iterator::get_curr());
223 return std::tuple<T>(C::Iterator::get_curr_ne());
229 l.
append(C::Iterator::get_curr());
246template <
class...
Cs>
259template <
class...
Cs>
263 for (
size_t i = 0; i < pos; ++i)
269template <
class...
Cs>
276template <
class...
Cs>
288template <
class...
Cs>
292 for (; it.has_curr(); it.next_ne())
295 return it.completed();
325template <
class Op,
class...
Cs>
328 for (
auto it =
zip_it(
cs...); it.has_curr(); it.next_ne())
329 if (
not std::forward<Op>(op)(it.get_curr()))
342template <
class Op,
class...
Cs>
346 for (; it.has_curr(); it.next_ne())
347 if (
not std::forward<Op>(op)(it.get_curr()))
349 return it.completed();
381template <
class Op,
class...
Cs>
384 for (
auto it =
zip_it(
cs...); it.has_curr(); it.next_ne())
385 std::forward<Op>(op)(it.get_curr());
395template <
class Op,
class...
Cs>
399 for (; it.has_curr(); it.next_ne())
400 std::forward<Op>(op)(it.get_curr());
415template <
class Op,
class...
Cs>
419 for (; it.has_curr(); it.next_ne())
420 if (
not std::forward<Op>(op)(it.get_curr()))
423 return it.completed();
436template <
class Op,
class...
Cs>
439 for (
auto it =
zip_it(
cs...); it.has_curr(); it.next_ne())
440 if (
not std::forward<Op>(op)(it.get_curr()))
450template <
class Op,
class...
Cs>
453 return zip_all(std::forward<Op>(op),
cs...);
460template <
class Op,
class...
Cs>
475template <
class Op,
class...
Cs>
478 for (
auto it =
zip_it(
cs...); it.has_curr(); it.next_ne())
479 if (std::forward<Op>(op)(it.get_curr()))
489template <
class Op,
class...
Cs>
504template <
class Op,
class...
Cs>
517template <
class Op,
class...
Cs>
521 for (
auto it =
zip_it(
cs...); it.has_curr(); it.next_ne())
522 if (std::forward<Op>(op)(it.get_curr()))
533template <
class...
Cs>
537 for (
auto it =
zip_it(
cs...); it.has_curr(); it.next_ne())
550template <
class Op,
class...
Cs>
556 for (
auto it =
zip_it(
cs...); it.has_curr(); it.next_ne())
557 if (
auto t = it.get_curr(); std::forward<Op>(op)(t))
558 return std::make_pair(t,
true);
560 return std::make_pair(
ZipType{},
false);
571template <
class Op,
class...
Cs>
580 for (
auto it =
zip_it(
cs...); it.has_curr(); it.next_ne())
581 if (
auto t = it.get_curr(); std::forward<Op>(op)(t))
587 return std::make_pair(result, found);
598template <
class...
Cs>
605 for (
auto it =
zip_it(
cs...); it.has_curr(); it.next_ne(), ++i)
607 return std::make_pair(it.get_curr(),
true);
609 return std::make_pair(
ZipType{},
false);
619template <
class...
Cs>
656template <
typename T,
class Op,
class...
Cs>
661 for (
auto it =
zip_it(
cs...); it.has_curr(); it.next_ne())
675template <
typename T,
class Prop,
class Op,
class...
Cs>
680 for (
auto it =
zip_it(
cs...); it.has_curr(); it.next_ne())
681 if (
auto t = it.get_curr();
prop(t))
715template <
typename T,
class Op,
class...
Cs>
720 for (
auto it =
zip_it(
cs...); it.has_curr(); it.next_ne())
721 acu = op(
acu, it.get_curr());
735template <
typename T,
class Op,
class...
Cs>
741 for (; it.has_curr(); it.next_ne())
742 acu = op(
acu, it.get_curr());
758template <
typename T,
class Op,
class...
Cs>
764 for (; it.has_curr(); it.next_ne())
765 ret.append(op(it.get_curr()));
782template <
typename T,
class Prop,
class Op,
class...
Cs>
788 for (; it.has_curr(); it.next_ne())
789 if (
auto t = it.get_curr();
prop(t))
807template <
class Op,
class...
Cs>
812 using ResultType = std::decay_t<decltype(std::forward<Op>(op)(std::declval<ZipType>()))>;
815 for (
auto it =
zip_it(
cs...); it.has_curr(); it.next_ne())
816 ret.
append(std::forward<Op>(op)(it.get_curr()));
828template <
class Op,
class...
Cs>
833 using ResultType = std::decay_t<decltype(std::forward<Op>(op)(std::declval<ZipType>()))>;
837 for (; it.has_curr(); it.next_ne())
838 ret.append(std::forward<Op>(op)(it.get_curr()));
868template <
class Op,
class...
Cs>
875 for (
auto it =
zip_it(
cs...); it.has_curr(); it.next_ne())
876 if (
auto t = it.get_curr(); op(t))
909template <
class Op,
class...
Cs>
917 for (; it.has_curr(); it.next_ne())
918 if (
auto t = it.get_curr(); op(t))
929namespace zip_detail {
935template <
class Cmp,
class Tuple,
size_t...
Is>
939 return (...
and cmp(std::get<Is>(t), std::get<Is + 1>(t)));
963template <
class Cmp,
class...
Cs>
967 constexpr size_t N =
sizeof...(Cs);
968 static_assert(
N >= 2,
"zip_cmp requires at least 2 containers");
970 for (
auto it =
get_zip_it(
cs...); it.has_curr(); it.next_ne())
971 if (
auto t = it.get_curr();
986template <
class Op,
class...
Cs>
991 for (
auto it =
zip_it(
cs...); it.has_curr(); it.next_ne(), ++i)
992 if (
auto t = it.get_curr(); op(t))
1033template <
class Op,
class...
Cs>
1040 size_t n1 = 0, n2 = 0;
1041 for (
auto it =
zip_it(
cs...); it.has_curr(); it.next_ne())
1042 if (
auto t = it.get_curr(); op(t))
1053 return std::make_tuple(
ret1, n1,
ret2, n2);
1084template <
class...
Cs>
1088 using T =
decltype(it.get_curr());
1090 for (; it.has_curr(); it.next_ne())
1103template <
class...
Cs>
1107 using T =
decltype(it.get_curr());
1109 for (; it.has_curr(); it.next_ne())
1148 typename HeadC::Iterator it;
1150 using T = std::decay_t<typename HeadC::Item_Type>;
1179 std::tuple<T> curr(it.get_curr());
1192 std::tuple<T> curr(it.get_curr_ne());
1216 C::Iterator::next();
1226 C::Iterator::next_ne();
1230 using T = std::decay_t<typename C::Item_Type>;
1241 return std::tuple<T, size_t>(C::Iterator::get_curr(), i);
1250 return std::tuple<T, size_t>(C::Iterator::get_curr_ne(), i);
1266template <
class...
Cs>
1280template <
class C,
class...
Cs>
1286 for (
size_t i = 0; i < pos; ++i)
1293template <
class...
Cs>
1300template <
class...
Cs>
1314template <
class...
Cs>
1318 using T =
decltype(it.get_curr());
1320 for (; it.has_curr(); it.next_ne())
1333template <
class...
Cs>
1337 using T =
decltype(it.get_curr());
1339 for (; it.has_curr(); it.next_ne())
1347template <
typename...
Ts,
size_t...
is>
1350 std::tuple<DynList<Ts>...>
ret;
1351 for (
auto it =
l.
get_it(); it.has_curr(); it.next_ne())
1352 std::initializer_list<int>{(std::get<is>(
ret).append(std::get<is>(it.get_curr())), 0)...};
1363template <
class...
Ts>
1386template <
class C,
typename...
Lists>
1390 using T =
typename C::Item_Type;
1405template <
class C,
typename...
Lists>
1409 using T =
typename C::Item_Type;
1412 for (; it.has_curr(); it.next_ne())
1413 ret.append(it.get_curr_list());
1423namespace std_zip_detail {
1428template <
typename...
Its>
1431 return (...
and (
its.first !=
its.second));
1437template <
typename...
Its>
1447template <
typename...
Its>
1450 return std::make_tuple(*
its.first...);
1458template <
typename C1,
typename C2>
1462 using T =
typename C1::value_type;
1463 using U =
typename C2::value_type;
1464 std::vector<std::pair<T, U>> result;
1465 auto it1 =
c1.begin();
1466 auto it2 =
c2.begin();
1467 for (; it1 !=
c1.end()
and it2 !=
c2.end(); ++it1, ++it2)
1468 result.emplace_back(*it1, *it2);
1486template <
typename...
Cs>
1490 static_assert(
sizeof...(Cs) >= 2,
"tzip_std requires at least 2 containers");
1492 using TupleType = std::tuple<
typename Cs::value_type...>;
1493 std::vector<TupleType>
ret;
1496 auto iters = std::make_tuple(std::make_pair(
cs.begin(),
cs.end())...);
1521template <
typename...
Cs>
1538template <
class Op,
class...
Cs>
1543 using ResultType = std::decay_t<decltype(std::forward<Op>(op)(std::declval<ZipType>()))>;
1545 std::vector<ResultType>
ret;
1546 for (
auto it =
zip_it(
cs...); it.has_curr(); it.next_ne())
1547 ret.push_back(std::forward<Op>(op)(it.get_curr()));
1560template <
class Op,
class...
Cs>
1565 using ResultType = std::decay_t<decltype(std::forward<Op>(op)(std::declval<ZipType>()))>;
1567 std::vector<ResultType>
ret;
1569 for (; it.has_curr(); it.next_ne())
1570 ret.push_back(std::forward<Op>(op)(it.get_curr()));
1584template <
class Op,
class...
Cs>
1588 for (
auto it =
zip_it(
cs...); it.has_curr(); it.next_ne(), ++idx)
1589 std::forward<Op>(op)(idx, it.get_curr());
1599template <
class Op,
class...
Cs>
1604 for (; it.has_curr(); it.next_ne(), ++idx)
1605 std::forward<Op>(op)(idx, it.get_curr());
1617template <
class...
Cs>
1636template <
class...
Cs>
1645 for (
size_t i = 0; i < n
and it.has_curr(); ++i)
1649 for (; it.has_curr(); it.next_ne())
1650 ret.append(it.get_curr());
1661template <
class Pred,
class...
Cs>
1667 for (
auto it =
zip_it(
cs...); it.has_curr(); it.next_ne())
1669 auto t = it.get_curr();
1670 if (
not std::forward<Pred>(
pred)(t))
1684template <
class Pred,
class...
Cs>
1693 for (; it.has_curr()
and std::forward<Pred>(
pred)(it.get_curr()); it.next_ne())
1697 for (; it.has_curr(); it.next_ne())
1698 ret.append(it.get_curr());
1709namespace zip_index_detail {
1714template <
class Op,
class Tuple,
size_t...
Is>
1717 (std::forward<Op>(op)(std::get<Is>(std::forward<Tuple>(t))), ...);
1725template <
class Op,
class Tuple,
size_t...
Is>
1728 return std::make_tuple(std::forward<Op>(op)(std::get<Is>(std::forward<Tuple>(t)))...);
1739 return (...
and std::forward<Pred>(
pred)(std::get<Is>(t)));
1750 return (...
or std::forward<Pred>(
pred)(std::get<Is>(t)));
1783template <
class Op,
class Tuple>
1786 constexpr auto N = std::tuple_size_v<std::decay_t<Tuple>>;
1788 std::forward<Tuple>(t),
1789 std::make_index_sequence<N>{});
1822template <
class Op,
class Tuple>
1826 constexpr auto N = std::tuple_size_v<std::decay_t<Tuple>>;
1828 std::forward<Tuple>(t),
1829 std::make_index_sequence<N>{});
1853template <
class Pred,
class Tuple>
1857 constexpr auto N = std::tuple_size_v<std::decay_t<Tuple>>;
1860 std::make_index_sequence<N>{});
1883template <
class Pred,
class Tuple>
1887 constexpr auto N = std::tuple_size_v<std::decay_t<Tuple>>;
1890 std::make_index_sequence<N>{});
1913template <
class Pred,
class Tuple>
#define ah_length_error_if(C)
Throws std::length_error if condition holds.
Functional programming utilities for Aleph-w containers.
Dynamic singly linked list with functional programming support.
T & append(const T &item)
bool completed() const noexcept
Return true if the underlying iterator has reached the end.
std::tuple< T, size_t > get_curr_ne() const noexcept
Return the current tuple (value, index) (no-throw variant).
std::tuple< T, size_t > get_curr() const
Return the current tuple (value, index) (bounds-checked).
EnumZipIterator(const C &c)
Construct an enumerating iterator over a single container.
void next()
Advance the iterator and increment the associated index (bounds-checked).
void next_ne() noexcept
Advance the iterator and increment the associated index (no-throw variant).
std::decay_t< typename C::Item_Type > T
std::tuple< T > get_curr_ne() const noexcept
Return the current tuple (no-throw variant).
std::tuple< T > Tuple_Type
The tuple type returned by get_curr() and get_curr_ne()
std::decay_t< typename C::Item_Type > T
bool completed() const noexcept
Return true if the underlying iterator has reached the end.
DynList< T > get_curr_list() const
std::tuple< T > get_curr() const
Return the current tuple (bounds-checked).
ZipIterator(const C &c)
Construct a zip iterator over a single container.
T Item_Type
Type of elements from the container.
Iterator that traverses multiple containers with enumeration index.
auto get_it() const
Return a properly initialized iterator positioned at the first item on the container.
Iterator that traverses multiple Aleph containers in lockstep.
int cmp(const __gmp_expr< T, U > &expr1, const __gmp_expr< V, W > &expr2)
Singly linked list implementations with head-tail access.
Freq_Node * pred
Predecessor node in level-order traversal.
bool all_valid(const Its &...its)
Check if all iterators are valid (not at end).
void advance_all(Its &...its)
Advance all iterators.
auto deref_all(const Its &...its)
Dereference all iterators and make a tuple.
bool compare_adjacent(Cmp &cmp, const Tuple &t, std::index_sequence< Is... >)
Compare all adjacent pairs in a tuple using the given comparator.
bool any_of_tuple_impl(Pred &&pred, const Tuple &t, std::index_sequence< Is... >)
Check if any element satisfies a predicate.
auto transform_tuple_impl(Op &&op, Tuple &&t, std::index_sequence< Is... >)
Transform each element in a tuple.
void for_each_in_tuple_impl(Op &&op, Tuple &&t, std::index_sequence< Is... >)
Apply a function to each element in a tuple.
bool all_of_tuple_impl(Pred &&pred, const Tuple &t, std::index_sequence< Is... >)
Check if all elements satisfy a predicate.
Main namespace for Aleph-w library functions.
and
Check uniqueness with explicit hash + equality functors.
ZipIterator< Cs... > zip_it(const Cs &...cs)
Alias for get_zip_it.
void zip_for_each_eq(Op &&op, const Cs &...cs)
Apply op to every zipped tuple; throw if containers differ in length.
EnumZipIterator< Cs... > get_enum_zip_it(const Cs &...cs)
Create an EnumZipIterator over the given containers.
bool zip_traverse_eq(Op &&op, const Cs &...cs)
Traverse zipped containers while op returns true; verify equal lengths.
void zip_for_each_indexed_eq(Op &&op, const Cs &...cs)
Apply op to each zipped tuple with index; throw if lengths differ.
auto zip_drop_while(Pred &&pred, const Cs &...cs)
Skip tuples while predicate pred returns true, then return the rest.
auto t_enum_zip_eq(const Cs &...cs)
Materialize enumerated zipped tuples; throw if containers differ in length.
DynList< T > zip_maps_if_eq(Prop prop, Op op, const Cs &...cs)
Map op over zipped tuples that satisfy prop; throw if lengths differ.
void zip_for_each(Op &&op, const Cs &...cs)
Apply op to every zipped tuple.
T Item_Type
Type of elements from the first container.
bool completed() const noexcept
Return true if all underlying iterators are finished.
EnumZipIterator< Cs... > enum_zip_it_pos(size_t pos, const Cs &...cs)
Alias for get_enum_zip_it_pos.
ZipIterator< Cs... > zip_it_pos(size_t pos, const Cs &...cs)
Alias for get_zip_it_pos.
bool zip_forall_short(Op &&op, const Cs &...cs)
Alias for zip_all_short.
auto std_zip(const C1 &c1, const C2 &c2)
Build a vector of pairs from two STL containers.
bool all_of_tuple(Pred &&pred, const Tuple &t)
Return true if all tuple elements satisfy pred.
auto transform_tuple(Op &&op, Tuple &&t)
Transform each element of a tuple, returning a new tuple.
auto zip_transform_eq(Op &&op, const Cs &...cs)
Transform zipped tuples; throw if containers differ in length.
static auto t_unzip_impl(const DynList< std::tuple< Ts... > > &l, std::index_sequence< is... >)
ZipIterator< Cs... > get_zip_it_pos(size_t pos, const Cs &...cs)
Create a ZipIterator positioned at index pos.
bool equal_length(const Cs &...cs)
Return true if all containers have the same length.
T zip_foldl(const T &init, Op op, const Cs &...cs)
Left fold (reduce) over zipped tuples.
bool zip_all_short(Op &&op, const Cs &...cs)
Return true if op returns true for all tuples (without length check).
void for_each_in_tuple(Op &&op, Tuple &&t)
Apply op to each element of a tuple.
auto std_zip_n(const Cs &...cs)
Build a vector of tuples from 2 or more STL containers (variadic).
ZipIterator< Cs... > get_zip_it(const Cs &...cs)
Create a ZipIterator over the given containers.
void next_ne() noexcept
Advance all underlying iterators (no-throw variant).
size_t zip_length(const Cs &...cs)
Count all tuples (minimum length of containers).
auto zip_filter(Op op, const Cs &...cs)
Filter zipped tuples by predicate op.
T zip_foldl_eq(const T &init, Op op, const Cs &...cs)
Left fold over zipped tuples; throw if containers differ in length.
auto t_zip(const Cs &...cs)
Materialize zipped tuples into a DynList.
decltype(std::tuple_cat(std::declval< std::tuple< T > >(), std::declval< typename ZipIterator< TailC... >::Tuple_Type >())) Tuple_Type
The tuple type returned by get_curr() and get_curr_ne()
bool zip_any(Op &&op, const Cs &...cs)
Alias for zip_exists.
Divide_Conquer_DP_Result< Cost > divide_and_conquer_partition_dp(const size_t groups, const size_t n, Transition_Cost_Fn transition_cost, const Cost inf=dp_optimization_detail::default_inf< Cost >())
Optimize partition DP using divide-and-conquer optimization.
std::decay_t< typename HeadC::Item_Type > T
auto zip_lists(const C &c, const Lists &...lists)
Take several container of same type and some length and builds a list of lists.
bool zip_forall(Op &&op, const Cs &...cs)
Alias for zip_all.
bool any_of_tuple(Pred &&pred, const Tuple &t)
Return true if any tuple element satisfies pred.
size_t zip_count(Op &&op, const Cs &...cs)
Count tuples that satisfy predicate op.
bool zip_traverse(Op &&op, const Cs &...cs)
Traverse zipped containers while op returns true.
auto get_curr() const
Return the current tuple (bounds-checked).
auto zip_find_first(Op &&op, const Cs &...cs)
Return the first tuple that satisfies predicate op.
bool zip_all(Op &&op, const Cs &...cs)
Return true if op returns true for all tuples and containers have equal length.
auto t_zip_eq(const Cs &...cs)
Materialize zipped tuples; throw if containers differ in length.
bool none_of_tuple(Pred &&pred, const Tuple &t)
Return true if no tuple element satisfies pred.
bool zip_none(Op &&op, const Cs &...cs)
Return true if op returns false for all tuples.
bool has_curr() const noexcept
Return true if all underlying iterators are positioned on a valid item.
auto tzip_std(const Cs &...cs)
Build a vector of tuples from 2 or more STL containers (variadic).
auto t_enum_zip(const Cs &...cs)
Materialize enumerated zipped tuples into a DynList.
auto zip_first(const Cs &...cs)
Return the first tuple from zipped containers.
EnumZipIterator< Cs... > enum_zip_it(const Cs &...cs)
Alias for get_enum_zip_it.
auto zip_find_last(Op &&op, const Cs &...cs)
Return the last tuple that satisfies predicate op.
auto t_unzip(const DynList< std::tuple< Ts... > > &tuples)
Unzip a list of tuples into a tuple of lists.
auto zip_map(Op &&op, const Cs &...cs)
Map op over zipped tuples with auto-deduced return type.
auto zip_partition(Op op, const Cs &...cs)
Partition zipped tuples by predicate op.
size_t zip_find_index(Op op, const Cs &...cs)
Find the first index where op returns true.
auto zip_take_while(Pred &&pred, const Cs &...cs)
Take tuples while predicate pred returns true.
void zip_for_each_indexed(Op &&op, const Cs &...cs)
Apply op to each zipped tuple along with its index.
bool zip_exists(Op &&op, const Cs &...cs)
Return true if op returns true for at least one tuple.
EnumZipIterator< C, Cs... > get_enum_zip_it_pos(size_t pos, const C &c, const Cs &...cs)
Create an EnumZipIterator positioned at index pos.
auto zip_drop(const size_t n, const Cs &...cs)
Skip n tuples and return the rest.
DynList< T > get_curr_list() const
Returns current elements as a DynList (requires homogeneous Item_Type)
DynList< T > zip_maps_eq(Op op, const Cs &...cs)
Map op over zipped tuples; throw if containers differ in length.
DynList< T > zip_maps(Op op, const Cs &...cs)
Map op over zipped tuples, returning a list of results.
auto get_curr_ne() const noexcept
Return the current tuple (no-throw variant).
auto zip_filter_eq(Op op, const Cs &...cs)
Filter zipped tuples by predicate op; throw if containers differ in length.
void next()
Advance all underlying iterators (bounds-checked).
auto zip_nth(size_t n, const Cs &...cs)
Return the n-th tuple from zipped containers.
auto zip_lists_eq(const C &c, const Lists &...lists)
Like zip_lists but throws if containers differ in length.
bool zip_cmp(Cmp cmp, const Cs &...cs)
Return true if cmp(t) is true for each built tuple t.
auto zip_map_eq(Op &&op, const Cs &...cs)
Map op over zipped tuples with auto-deduced return type; throw if lengths differ.
auto zip_transform(Op &&op, const Cs &...cs)
Transform zipped tuples using op and return results in a vector.
DynList< T > zip_maps_if(Prop prop, Op op, const Cs &...cs)
Map op over zipped tuples that satisfy prop.
static std::atomic< bool > init
auto zip_take(size_t n, const Cs &...cs)
Take at most n tuples from the zipped containers.
Itor::difference_type count(const Itor &beg, const Itor &end, const T &value)
Count elements equal to a value.
Dynamic ordered set implemented with a Skip List.