| 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)