From patchwork Wed Sep 24 12:47:08 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 24449 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 959F2C3331 for ; Wed, 24 Sep 2025 12:47:36 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 8E2106B5FE; Wed, 24 Sep 2025 14:47:28 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="GmIc45Y+"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 41DF26B5F3 for ; Wed, 24 Sep 2025 14:47:17 +0200 (CEST) Received: from pb-laptop.local (185.221.140.70.nat.pool.zt.hu [185.221.140.70]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 513431E30; Wed, 24 Sep 2025 14:45:53 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1758717953; bh=PULD/bhzlEF1pA8U1Nm12ABhT2Gudiv9VA4pjEP6cP8=; h=From:To:Subject:Date:In-Reply-To:References:From; b=GmIc45Y+F7EGcYqzwG03YsfbmUNQJNtjjlWd3mfwCvqQY8T69PUykrHr14oeiRsue sBJ2KxyMx3wMWAcQwvbO+97T5/8bmgagDsfJAgSSsnXEtteKWOmdGqD1av36eq4F5j dm2PmCXpKZpolgHaa5UVtJgwcn2OL0yc3mUeZhcI= From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= To: libcamera-devel@lists.libcamera.org, Kieran Bingham Subject: [RFC PATCH v1 3/7] libcamera: controls: Add rvalue `ControlList::merge()` Date: Wed, 24 Sep 2025 14:47:08 +0200 Message-ID: <20250924124713.3361707-4-barnabas.pocze@ideasonboard.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20250924124713.3361707-1-barnabas.pocze@ideasonboard.com> References: <20250924124713.3361707-1-barnabas.pocze@ideasonboard.com> MIME-Version: 1.0 X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Add an overload of `ControlList::merge()` that takes the source `ControlList` object via an rvalue. In contrast to the other overload, this one does not make copies, it uses `std::unordered_map::merge()` to move key-value pairs from one map to the other. Signed-off-by: Barnabás Pőcze --- include/libcamera/controls.h | 1 + src/libcamera/controls.cpp | 42 +++++++++++++++++++++++++++++++++--- 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/include/libcamera/controls.h b/include/libcamera/controls.h index 32fb31f78..5d4a53c46 100644 --- a/include/libcamera/controls.h +++ b/include/libcamera/controls.h @@ -432,6 +432,7 @@ public: void clear() { controls_.clear(); } void merge(const ControlList &source, MergePolicy policy = MergePolicy::KeepExisting); + void merge(ControlList &&source, MergePolicy policy = MergePolicy::KeepExisting); bool contains(unsigned int id) const; diff --git a/src/libcamera/controls.cpp b/src/libcamera/controls.cpp index 1e1b49e6b..54cd3b703 100644 --- a/src/libcamera/controls.cpp +++ b/src/libcamera/controls.cpp @@ -1005,9 +1005,6 @@ ControlList::ControlList(const ControlInfoMap &infoMap, * * Only control lists created from the same ControlIdMap or ControlInfoMap may * be merged. Attempting to do otherwise results in undefined behaviour. - * - * \todo Reimplement or implement an overloaded version which internally uses - * std::unordered_map::merge() and accepts a non-const argument. */ void ControlList::merge(const ControlList &source, MergePolicy policy) { @@ -1035,6 +1032,45 @@ void ControlList::merge(const ControlList &source, MergePolicy policy) } } +/** + * \brief Merge the \a source into the ControlList + * \param[in] source The ControlList to merge into this object + * \param[in] policy Controls if existing elements in *this shall be + * overwritten + * + * Merging two control lists moves elements from the \a source and inserts + * them in *this. If the \a source contains elements whose key is already + * present in *this, then those elements are only overwritten if + * \a policy is MergePolicy::OverwriteExisting. + * + * Only control lists created from the same ControlIdMap or ControlInfoMap may + * be merged. Attempting to do otherwise results in undefined behaviour. + */ +void ControlList::merge(ControlList &&source, MergePolicy policy) +{ + /** + * \todo ASSERT that the current and source ControlList are derived + * from a compatible ControlIdMap, to prevent undefined behaviour due to + * id collisions. + * + * This can not currently be a direct pointer comparison due to the + * duplication of the ControlIdMaps in the isolated IPA use cases. + * Furthermore, manually checking each entry of the id map is identical + * is expensive. + * See https://bugs.libcamera.org/show_bug.cgi?id=31 for further details + */ + + switch (policy) { + case MergePolicy::KeepExisting: + controls_.merge(source.controls_); + break; + case MergePolicy::OverwriteExisting: + source.controls_.merge(controls_); + controls_.swap(source.controls_); + break; + } +} + /** * \brief Check if the list contains a control with the specified \a id * \param[in] id The control numerical ID