tuple_product(3) | tuple_product(3) |
tuple_product - combine elements of tuples using function
#include <cfl/tuple/tuple_product.hpp>
template <typename F, typename... ARGS>
auto tuple_product (F && f, ARGS &&... args);
auto f = [] (int a, int b) { return a * b; };
auto u = tuple (2,3);
auto v = tuple (5,7);
auto r = tuple_product (f, u, v);
r == tuple (tuple (10, 14), tuple (15, 21));
tuple_product (f, 2, v) == tuple (10, 14);
tuple_product (f, 2, 5) == 10;
Roughly, tuple_product
uses a function f
to combine the elements of two
tuples, similar to a cartesian product. As f
may be n-ary and
shape-polymorphic and the arguments multi-dimensional, a more precise
description follows below.
In general, product is an higher-order function of arrays. For a binary
function f
and two arrays A
and B
, the product C
is defined as:
C = product (f, A, B) = {c(i,j)} = {f (a(i), b(j))} (1)
Here {c(i,j)}
represents the elements of the result, and {a(i)}
and {b(j)}
the collection of subarrays of A
and B
for which f (a(i), b(j))
is
applicable. The collection is formed by each of the tuple elements of A,
possibly recursively or not at all (see below). It should not be confused with
the mathematical concept of a subset, which can be formed by arbitrary
combinations of elements of the set.
If the collection of subarrays is not unqiue, i.e. f
accepts arguments of more
than one dimension, there are two variants of product using either the
smallest or the largest collection of subarrays. In other words, either
combine A
and B
in as small or as large chunks as possible. The two variants
are named tuple_product
and tuple_Product
respectively, where the
lower-case m denotes small chunks, and the capital M large chunks. Full
control over when f
should be applied or not, is achieved by augumenting f
with a predicate, see enable_if(3) for details.
The collection of subarrays may consist of A
and B
themselves, meaning a
product may be equivalent to just f (A, B)
. There are also cases where
smallest or largest is ambiguous. Then the first match reducing arguments
from left to right is selected.
tuple_product
accepts functions with arbitrary arity, as long as the number of
supplied arguments match. For a unary function, tuple_map
and tuple_product
coincide, with the difference that tuple_product
does not accept unary void
functions as operator.
A tuple with elements as in the definition of product (1) above.
The mix of underscore and camelCase in tuple_Product
is maybe not very
pleasing to the eye. Also, the names of two functions tuple_product
and
tuple_Product
differing only in a single case may not be entirely safe. But
for brevity, these are the chosen names in CFL.
tuple(3), tuple_map(3), enable_if(3)