Easily compose operations on ranges of values. The evaluation is delayed, thus the name "lazy".
The boost library and the thrust library include (fancy) iterators which facilitate implicit and/or delayed computations. While these iterators help in fitting even more classes of ranges in standard algorithms, they incur a severe increase in locs. The most important examples are the following:
An iterator which when evaluated returns a number in a range.
This example:
thrust::copy(
thrust::make_counting_iterator(0),
thrust::make_counting_iterator(10),
std::ostream_iterator<int>(std::cout, " "));
Yields this output: 0 1 2 3 4 5 6 7 8 9
An iterator which wraps another iterator and when evaluated yields the result of the application of a unary function on the dereferenced value.
This example:
auto pow = [](int a) { return a * a };
thrust::copy(
thrust::make_transform_iterator(thrust::make_counting_iterator(0), pow),
thrust::make_transform_iterator(thrust::make_counting_iterator(10), pow),
std::ostream_iterator<int>(std::cout, " "));
Yields this output: 0 1 4 9 16 25 36 49 64 81
An iterator which uses a range as indexes in another range and dereferences the latter in the order dictated by the former.
This example:
int values = [] = { 10, 20, 30, 40, 50 };
int reorder[] = { 4, 3, 2, 1, 0 };
thrust::copy(
thrust::make_permutation_iterator(std::begin(values), std::begin(reorder)),
thrust::make_permutation_iterator(std::begin(values), std::end(reorder)),
std::ostream_iterator<int>(std::cout, " "));
Yields this output: 50 40 30 20 10
The introduction of important features in C++11, such as lambdas, auto, decltype, variadic tempaltes, etc., introduces the ability to severely decrease the amount of code required to utilize implicit computations in iterator-based algorithms. This library aims exactly there.
This library facilitates the quick and easy construction of lazily evaluated iterator ranges. To do so it exploits C++11 features. The main use evolves around the use of a special operand, which is overloaded over common operations in order to easily synthesize computations. Some examples follow:
int values[] = { 0, 1, 2, 3, 4 };
int results[5];
thrust::copy(std::begin(values), std::end(values), std::begin(results))
int values[] = { 0, 1, 2, 3, 4 };
int results[5];
using namespace lazy_thrust;
make_lazy(results) = make_lazy(values);
int values[] = { 0, 1, 2, 3, 4 };
int results[5];
thrust::transform(
std::begin(values),
std::end(values),
std::begin(results),
[](int i) { return 2 * i });
int values[] = { 0, 1, 2, 3, 4 };
int results[5];
using namespace lazy_thrust;
make_lazy(results) = transform(make_lazy(values), [](int i) { return 2 * i });
int values1[] = { 0, 1, 2, 3, 4 };
int values2[] = { 0, 1, 2, 3, 4 };
int values3[] = { 0, 1, 2, 3, 4 };
int results[5];
auto iter = thrust::make_zip_iterator(thrust::make_tuple(
std::begin(values1), std::begin(values2), std::begin(values3)));
thrust::transform(
iter, iter + 5,
std::begin(results),
[](const thrust::tuple<int, int, int> &t)
{ return thrust::get<0>(t) + thrust::get<1>(t) + thrust::get<2>(t) });
int values1[] = { 0, 1, 2, 3, 4 };
int values2[] = { 0, 1, 2, 3, 4 };
int values3[] = { 0, 1, 2, 3, 4 };
int results[5];
using namespace lazy_thrust;
make_lazy(results) = transform(join(make_lazy(values1),
make_lazy(values2),
make_lazy(values3)),
// notice how the tuple is expanded into arguments
// instead of a cumbersome thrust::tuple
[](int a, int b, int c) { return a + b + c; })
int values1[] = { 0, 1, 2, 3, 4 };
int values2[] = { 0, 1, 2, 3, 4 };
int values3[] = { 0, 1, 2, 3, 4 };
int results[5];
auto iter = thrust::make_zip_iterator(thrust::make_tuple(
std::begin(values1), std::begin(values2), std::begin(values3)));
thrust::transform(
iter, iter + 5,
std::begin(results),
[](const thrust::tuple<int, int, int> &t)
{ return thrust::get<0>(t) + thrust::get<1>(t) + thrust::get<2>(t) });
int values1[] = { 0, 1, 2, 3, 4 };
int values2[] = { 0, 1, 2, 3, 4 };
int values3[] = { 0, 1, 2, 3, 4 };
int results[5];
using namespace lazy_thrust;
make_lazy(results) = make_lazy(values1) + make_lazy(values2) + make_lazy(values3);