[libcamera-devel] [PATCH v2 0/4] libcamera: Simplify range-based for loop counters
Laurent Pinchart
laurent.pinchart at ideasonboard.com
Sat May 15 06:05:07 CEST 2021
Hello,
This patch series simplifies for loops that iterate over a range and
require a loop counter. v1 was sent as an RFC, and as it was positively
received, v2 graduates to a normal series.
The limitation of the range-based for loop is explained in patch 1/4,
which provides a new utils::enumerate() function to solve the problem.
The API is inspired by the C++23 views::enumerate proposal
(http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2164r1.pdf),
but implemented without the range library as that's a C++20 feature.
Patch 2/4 is an example of how code can be simplified. It also outlines
a limitation of the API. Due to the C++ lifetime rules, we can't safely
pass a temporary to utils::enumerate() as the temporary would be
destroyed once utils::enumerate() returns but before the for loop
completes (actually before it even starts), resulting in use-after-free
errors. The issue is explained in more details in
http://josuttis.com/download/std/D2012R0_fix_rangebasedfor_201029.pdf.
The ensure that such bugs can't be introduced by mistake, the
utils::enumerate() function takes an lvalue reference only. The drawback
is that a loop that iterates over a temporary must now stores that
temporary in a named variable before the loop. On a side note, C++20
would bring us a workaround to declare that variable within the loop
statement. If anyone can think of a clever idea to fix this problem, I'm
all ears. One option may be to store a copy of the iterable in the
adapter when utils::enumerate() is given an rvalue, possibly with move
semantics, but it may still be costly in some cases, I'm not sure how
compilers would optimize that.
Patch 3/4 provides an alternative API that uses an aggregate with named
fields instead of an std::pair with structured binding, with patch 4/4
adapting the example for 2/4 accordingly. There seems to be a preference
for the structured bindings, which means that 3/4 and 4/4 are likely to
be dropped. If they however end up being accepted after changes of mind,
I'll squash them with 1/4 and 2/4 respectively.
Laurent Pinchart (4):
libcamera: utils: Add enumerate view for range-based for loops
v4l2: Replace manual loop counters with utils::enumerate()
libcamera: utils: enumerate: Use named fields for result
v4l2: Adapt to utils::enumerate() usage of named fields
include/libcamera/internal/utils.h | 92 ++++++++++++++++++++++++++++++
src/libcamera/utils.cpp | 30 ++++++++++
src/v4l2/v4l2_compat_manager.cpp | 18 +++---
test/utils.cpp | 59 +++++++++++++++++++
4 files changed, 190 insertions(+), 9 deletions(-)
--
Regards,
Laurent Pinchart
More information about the libcamera-devel
mailing list