Suppose I have some array-based code that is enabled to be used by expression templates. E.g., I have operator[]
for these arrays overloaded and also have overloaded the arithmetic operator +
etc.
Now I would like to let the STL algorithm any_of
run on such arrays. The simple way is to do
ExprArray<double, N> b, c; // init etc.
auto a = b + c; // for (auto i = 0; i < N; ++i) { a[i] = b[i] + c[i]; }
auto res = std::any_of(begin(a), end(a), SomePred{});
Of course, I would like to be able to short-circuit the computation and have a modified (range-based) lib::any_of
that does
// only compute b[i] + c[i] until SomePred is satisified
auto res = lib::any_of(b + c, SomePred{}); // write as explicit loop over b[i] + c[i]
Writing lib::any_of
in terms of operator[]
on its input will do that job, the same as it was done for the overloaded operator+
. However, this would require similar reimplementations of all STL algorithms that I could possibly run on such arrays.
Question: So suppose I want to re-use existing range-based algorithms (Boost.Range, range-v3) by only modifying the ExprArray iterators
. Is it possible to modify the ExprArray
iterator operator*
and operator++
in such a way that this is transparent to range-based algorithms?
// only compute b[i] + c[i] until SomePred is satisified
// needs to eventually dispatch to
// for (auto i = 0; i < N; ++i)
// if (SomePred(b[i] + c[i])) return true;
// return false;
auto res = ranges::any_of(b + c, SomePred{});
So if the algorithm version actually is implemented in terms of iterators, the loop for (auto it = first; it != last; ++it)
needs *it
to be aware of the fact that it needs to compute b[i] + c[i]
, and ++it
has to know that it needs to do ++i
.