[v2,3/5] libcamera: controls: Implement move ctor/assignment
diff mbox series

Message ID 20250421153556.171192-4-barnabas.pocze@ideasonboard.com
State New
Headers show
Series
  • libcamera: controls: Move constructor/assignment + swap
Related show

Commit Message

Barnabás Pőcze April 21, 2025, 3:35 p.m. UTC
Implement a move constructor and move assignment operator for `ControlValue`.
The `ControlValue` type already has an "empty" state that is used when
creating a default constructed `ControlValue`, so have the moved-from
instance return to that state after move construction/assignment.

This is useful, for example, for `std::vector` as most implementations will
use the copy constructor when reallocating if no nothrow move constructor
is available. Having a nothrow move constructor avoids the extra copies.
It is also useful when using temporaries of `ControlValue` with other
containers such as `std::optional`, and it also makes `ControlInfo`
"cheaply" move constructible/assignable.

Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
---
 include/libcamera/controls.h | 26 ++++++++++++++++++++++++++
 src/libcamera/controls.cpp   | 18 ++++++++++++++++++
 2 files changed, 44 insertions(+)

Patch
diff mbox series

diff --git a/include/libcamera/controls.h b/include/libcamera/controls.h
index 3f3580036..866d667c4 100644
--- a/include/libcamera/controls.h
+++ b/include/libcamera/controls.h
@@ -14,6 +14,7 @@ 
 #include <stdint.h>
 #include <string>
 #include <unordered_map>
+#include <utility>
 #include <vector>
 
 #include <libcamera/base/class.h>
@@ -165,6 +166,31 @@  public:
 	ControlValue(const ControlValue &other);
 	ControlValue &operator=(const ControlValue &other);
 
+	ControlValue(ControlValue &&other) noexcept
+		: type_(other.type_),
+		  isArray_(std::exchange(other.isArray_, false)),
+		  numElements_(std::exchange(other.numElements_, 0)),
+		  storage_(std::exchange(other.storage_, {}))
+	{
+		other.type_ = ControlTypeNone;
+	}
+
+	ControlValue &operator=(ControlValue &&other) noexcept
+	{
+		if (this != &other) {
+			release();
+
+			type_ = other.type_;
+			isArray_ = std::exchange(other.isArray_, false);
+			numElements_ = std::exchange(other.numElements_, 0);
+			storage_ = std::exchange(other.storage_, {});
+
+			other.type_ = ControlTypeNone;
+		}
+
+		return *this;
+	}
+
 	ControlType type() const { return type_; }
 	bool isNone() const { return type_ == ControlTypeNone; }
 	bool isArray() const { return isArray_; }
diff --git a/src/libcamera/controls.cpp b/src/libcamera/controls.cpp
index d384e1ef7..135e87613 100644
--- a/src/libcamera/controls.cpp
+++ b/src/libcamera/controls.cpp
@@ -155,6 +155,24 @@  ControlValue &ControlValue::operator=(const ControlValue &other)
 	return *this;
 }
 
+/**
+ * \fn ControlValue::ControlValue(ControlValue &&other) noexcept
+ * \brief Move constructor for ControlValue
+ * \param[in] other The ControlValue object to move from
+ *
+ * Move constructs a ControlValue instance from \a other.
+ * After this operation \a other will be in the same state
+ * as a default constructed ControlValue instance.
+ */
+
+/**
+ * \fn ControlValue &ControlValue::operator=(ControlValue &&other) noexcept
+ * \brief Move assignment operator for ControlValue
+ * \param[in] other The ControlValue object to move from
+ *
+ * \sa ControlValue::ControlValue(ControlValue &&other)
+ */
+
 /**
  * \fn ControlValue::type()
  * \brief Retrieve the data type of the value