[libcamera-devel,v2,3/4] libcamera: utils: enumerate: Use named fields for result
diff mbox series

Message ID 20210515040511.23294-4-laurent.pinchart@ideasonboard.com
State Rejected
Delegated to: Laurent Pinchart
Headers show
Series
  • libcamera: Simplify range-based for loop counters
Related show

Commit Message

Laurent Pinchart May 15, 2021, 4:05 a.m. UTC
Returning a pair of { index, value } from container enumeration is
error-prone, as the index and value can easily be swapped. Use a
structure with named index and value fields instead.

This will be squashed with "libcamera: utils: Add enumerate view for
range-based for loops" if accepted.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 include/libcamera/internal/utils.h | 16 +++++++++++-----
 src/libcamera/utils.cpp            | 13 +++++++------
 test/utils.cpp                     | 24 ++++++++++++------------
 3 files changed, 30 insertions(+), 23 deletions(-)

Patch
diff mbox series

diff --git a/include/libcamera/internal/utils.h b/include/libcamera/internal/utils.h
index 83dada7cc16c..5ea82e68a7a2 100644
--- a/include/libcamera/internal/utils.h
+++ b/include/libcamera/internal/utils.h
@@ -16,7 +16,6 @@ 
 #include <string>
 #include <string.h>
 #include <sys/time.h>
-#include <utility>
 #include <vector>
 
 #ifndef __DOXYGEN__
@@ -237,12 +236,19 @@  namespace details {
 template<typename Base>
 class enumerate_iterator
 {
-private:
-	using base_reference = typename std::iterator_traits<Base>::reference;
-
 public:
 	using difference_type = typename std::iterator_traits<Base>::difference_type;
-	using value_type = std::pair<const difference_type, base_reference>;
+
+private:
+	using base_reference = typename std::iterator_traits<Base>::reference;
+
+	struct result {
+		const difference_type index;
+		base_reference value;
+	};
+
+public:
+	using value_type = result;
 	using pointer = value_type *;
 	using reference = value_type &;
 	using iterator_category = std::input_iterator_tag;
diff --git a/src/libcamera/utils.cpp b/src/libcamera/utils.cpp
index ff9a5832b10e..b4b4180c1337 100644
--- a/src/libcamera/utils.cpp
+++ b/src/libcamera/utils.cpp
@@ -481,20 +481,21 @@  std::string libcameraSourcePath()
  * in their ability to replace for loops that require access to a loop counter.
  * The enumerate() function solves this problem by wrapping the \a iterable in
  * an adapter that, when used as a range-expression, will provide iterators
- * whose value_type is a pair of index and value reference.
+ * whose value_type exposes both the element's value and its index.
  *
  * The iterable must support std::begin() and std::end(). This includes all
  * containers provided by the standard C++ library, as well as C-style arrays.
  *
- * A typical usage pattern would use structured binding to store the index and
- * value in two separate variables:
+ * The iterator's value_type is a structure that aggregates the index and value
+ * reference in two named members. The index is always const, and the value
+ * reference is conditionally const depending on the iterable. A typical usage
+ * pattern would be:
  *
  * \code{.cpp}
  * std::vector<int> values = ...;
  *
- * for (auto [index, value] : utils::enumerate(values)) {
- * 	...
- * }
+ * for (const auto v : utils::enumerate(values))
+ * 	std::cout << "- index " << v.index << ", value " << v.value << std::endl;
  * \endcode
  *
  * \return A value of unspecified type that, when used in a range-based for
diff --git a/test/utils.cpp b/test/utils.cpp
index 7e24c71e4775..06ce5301a74e 100644
--- a/test/utils.cpp
+++ b/test/utils.cpp
@@ -79,16 +79,16 @@  protected:
 		std::vector<int> integers{ 1, 2, 3, 4, 5 };
 		int i = 0;
 
-		for (auto [index, value] : utils::enumerate(integers)) {
-			if (index != i || value != i + 1) {
+		for (const auto v : utils::enumerate(integers)) {
+			if (v.index != i || v.value != i + 1) {
 				cerr << "utils::enumerate(<vector>) test failed: i=" << i
-				     << ", index=" << index << ", value=" << value
-				     << std::endl;
+				     << ", index=" << v.index << ", value=" << v.value
+				     << endl;
 				return TestFail;
 			}
 
 			/* Verify that we can modify the value. */
-			--value;
+			--v.value;
 			++i;
 		}
 
@@ -100,10 +100,10 @@  protected:
 		Span<const int> span{ integers };
 		i = 0;
 
-		for (auto [index, value] : utils::enumerate(span)) {
-			if (index != i || value != i) {
+		for (const auto v : utils::enumerate(span)) {
+			if (v.index != i || v.value != i) {
 				cerr << "utils::enumerate(<span>) test failed: i=" << i
-				     << ", index=" << index << ", value=" << value
+				     << ", index=" << v.index << ", value=" << v.value
 				     << std::endl;
 				return TestFail;
 			}
@@ -114,11 +114,11 @@  protected:
 		const int array[] = { 0, 2, 4, 6, 8 };
 		i = 0;
 
-		for (auto [index, value] : utils::enumerate(array)) {
-			if (index != i || value != i * 2) {
+		for (const auto v : utils::enumerate(array)) {
+			if (v.index != i || v.value != i * 2) {
 				cerr << "utils::enumerate(<array>) test failed: i=" << i
-				     << ", index=" << index << ", value=" << value
-				     << std::endl;
+				     << ", index=" << v.index << ", value=" << v.value
+				     << endl;
 				return TestFail;
 			}