class Frame<P>
represents an image with pixels of type P
. The algorithm that iterates through its pixels is non-trivial due to several flexibilities in the underlying data buffer format.
template <typename P, bool RM = true> // P is pixel type; RM = is_row_major
class Frame {
// ...
template<typename F>
void iterate(F f) { // iterate in a way that is performant for this buffer
if (stride == (RM ? size.w : size.h)) {
auto n = size.area();
for (index_t k = 0; k < n; k++) {
f(view[k]);
}
}
else {
auto s = static_cast<index_t>(stride)*(RM ? size.h : size.w);
for (index_t k0 = 0; k0 < s; k0 += stride) {
auto m = k0 + (RM ? size.w : size.h);
for (index_t k = k0; k < m; k++) {
f(view[k]);
}
}
}
}
}
I would like to be able to call both iterate(fc) const
and iterate(f)
(with lambda signatures fc(const P&)
and f(P&)
respectively). I could duplicate the entire function body and attach const
to the signature, but is there a better way?