Expressions¶

Calling functions on arrays of data is performed lazily using C++ template expressions. This allows better optimization and does not require saving temporary data.

For example, subtracting one univector from another gives expression type, not univector:

univector<int, 5> x{1, 2, 3, 4, 5};
univector<int, 5> y{0, 0, 1, 10, -5};

auto z = x - y; // z is of type expression, not univector.
// This only constructs an expression and does not perform any calculation


But you can always convert expression back to univector to get actual data:

univector<int, 5> x{1, 2, 3, 4, 5};
univector<int, 5> y{0, 0, 1, 10, -5};

univector<int, 5> z = x - y;


Note

when an expression is assigned to a univector variable, expression is evaluated and values are being written to the variable.

Same applies to calling KFR functions on univectors, this doesn't calculate value immediately. Instead, new expression will be created.

univector<float, 5> x{1, 2, 3, 4, 5};
sqrt(x);                                // only constructs an expression
univector<float, 5> values = sqrt(x);   // constructs an expression and writes data to univector


Input expressions can be read from and output expressions can be written to. Class can be an input and output expression at same time. univector is an example of such class.

Data type of an input expressions can be determined by using value_type_of<Expression>. However, not all expressions have their types specified. In such cases value_type_of will return special type generic.

Size (length) of an expression also can be specified or not. counter is an example of generic (untyped) expression without the size.