{"id":26336,"url":"https://patchwork.libcamera.org/api/1.1/patches/26336/?format=json","web_url":"https://patchwork.libcamera.org/patch/26336/","project":{"id":1,"url":"https://patchwork.libcamera.org/api/1.1/projects/1/?format=json","name":"libcamera","link_name":"libcamera","list_id":"libcamera_core","list_email":"libcamera-devel@lists.libcamera.org","web_url":"","scm_url":"","webscm_url":""},"msgid":"<20260325-mali-cru-v6-2-b16b0c49819a@ideasonboard.com>","date":"2026-03-25T14:44:09","name":"[v6,2/7] libcamera: utils: Add overloaded visitor helpers","commit_ref":null,"pull_url":null,"state":"superseded","archived":false,"hash":"65803e23419407a73577be2c0eafbe91a0cc49fd","submitter":{"id":143,"url":"https://patchwork.libcamera.org/api/1.1/people/143/?format=json","name":"Jacopo Mondi","email":"jacopo.mondi@ideasonboard.com"},"delegate":null,"mbox":"https://patchwork.libcamera.org/patch/26336/mbox/","series":[{"id":5848,"url":"https://patchwork.libcamera.org/api/1.1/series/5848/?format=json","web_url":"https://patchwork.libcamera.org/project/libcamera/list/?series=5848","date":"2026-03-25T14:44:07","name":"libcamera: mali-c55: Add support for memory-to-memory","version":6,"mbox":"https://patchwork.libcamera.org/series/5848/mbox/"}],"comments":"https://patchwork.libcamera.org/api/patches/26336/comments/","check":"pending","checks":"https://patchwork.libcamera.org/api/patches/26336/checks/","tags":{},"headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id D9DE7C32DE\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed, 25 Mar 2026 14:44:26 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id EDA6A6274D;\n\tWed, 25 Mar 2026 15:44:22 +0100 (CET)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 5DD046274D\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 25 Mar 2026 15:44:19 +0100 (CET)","from [192.168.1.104] (net-93-65-100-155.cust.vodafonedsl.it\n\t[93.65.100.155])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 5DF011943;\n\tWed, 25 Mar 2026 15:43:01 +0100 (CET)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"c1lJI5tQ\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1774449781;\n\tbh=FegylNAS/ZE8S1oZUyAdmGxPOxc4ElLR/QAsnKcxhNE=;\n\th=From:Date:Subject:References:In-Reply-To:To:Cc:From;\n\tb=c1lJI5tQfvmoapB3LC2CgETRqulLpb2O2rig4M7SI/9/nH5WeZUSwq69kVMo9yXEt\n\tDcPvR0LIlMykC4JCkEQqYEyzNANLSJ1qY4UfiK6ChNEkrFhM2wlKldQ7Io917SLfAW\n\tjlwaNAg+LvP2jtEl8JahihC4XEU8RX8RVuJ2Wiao=","From":"Jacopo Mondi <jacopo.mondi@ideasonboard.com>","Date":"Wed, 25 Mar 2026 15:44:09 +0100","Subject":"[PATCH v6 2/7] libcamera: utils: Add overloaded visitor helpers","MIME-Version":"1.0","Content-Type":"text/plain; charset=\"utf-8\"","Content-Transfer-Encoding":"8bit","Message-Id":"<20260325-mali-cru-v6-2-b16b0c49819a@ideasonboard.com>","References":"<20260325-mali-cru-v6-0-b16b0c49819a@ideasonboard.com>","In-Reply-To":"<20260325-mali-cru-v6-0-b16b0c49819a@ideasonboard.com>","To":"Daniel Scally <dan.scally@ideasonboard.com>, \n\tlibcamera-devel@lists.libcamera.org","Cc":"=?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= <barnabas.pocze@ideasonboard.com>,\n\tJacopo Mondi <jacopo.mondi@ideasonboard.com>","X-Mailer":"b4 0.14.3","X-Developer-Signature":"v=1; a=openpgp-sha256; l=4147;\n\ti=jacopo.mondi@ideasonboard.com; h=from:subject:message-id;\n\tbh=FegylNAS/ZE8S1oZUyAdmGxPOxc4ElLR/QAsnKcxhNE=;\n\tb=kA0DAAoBcjQGjxahVjwByyZiAGnD9MGjgZHy5H2qMyHMYnglPixqilbRwVyt8+W3tWKVmsXDF\n\tokCMwQAAQoAHRYhBLXEPUiAmiCKj1g4wHI0Bo8WoVY8BQJpw/TBAAoJEHI0Bo8WoVY84B0P/j7j\n\tZFXkLrMkFZxfvIL9DzuHjfmSN+ACjnl68A+tr8PYBjYnUNPbwNKs4K+YNzTHL4csNQlRculBG5B\n\tCyk0Zo37cBUMz7VUb1DwLqe2n2TM+TmSksSS0hreyGioz4Elma8zPGnXiRxW+muVh+kdeOf70SU\n\tihnfQ0P6YPeV/fIpw8RvDr6l+fO49aCS+b0Cqu1+37K+ks8+Br4Q1RwLjcp/4ht2Uq+xPg2XRaI\n\tRmIWORs3kc6NSwqNeNTkQpS84wYAdp5zPL72Umm5N5s5GxheDfFE/xs1T9BNKPLwB0EAXSN50Ob\n\tp22i12A5JnPH75CcaXV9W6QAAQNjY11TCqwnE5QMzTcttu5Tciqh1ha8brBuHhviQR8byOBlkLH\n\tsqXBf2uOsTUx2DukF+p1gctkTxy2NhAOlXMKFtCLs7KnmQX22rnGOrAhvgtENW26FXU3SDaQ/fV\n\tnxUxa1UBM7U+dFCMImgzRO3Vy9CX446+pqGgN6L7kZpDttBG3gJ346iZtYOrGcTb7AHT6mnUIpb\n\trFbrwCaQ/my8rXsRupwKlQDZMvlGTUa147GwPizeETO4MCTj1mSxkcLwX+3D6hwO8I682GRN5oZ\n\tJ7K8/uiXi4o3wxYELRlMsnxHNoFlrB+oLC/5H1XcGrngg6yrTccTbWb2qmjJ3BdWGbIda5JltNq\n\tZziZ6","X-Developer-Key":"i=jacopo.mondi@ideasonboard.com; a=openpgp;\n\tfpr=72392EDC88144A65C701EA9BA5826A2587AD026B","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"},"content":"std::visit() allows quite elegant type-matching implementation of the\nvisitor pattern.\n\nThe 'overloaded' type helpers allow to define a hierarchy of overloaded\noperator() implementations which can be used by std::visit().\n\nCurrently only the Virtual pipeline handler uses this type-matching\nimplementation of std::visit. To prepare to add another user in the Mali\nC55 pipeline handler move the 'overloaded' helper type to\nlibcamera::utils for easier re-use.\n\nReviewed-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>\nSigned-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>\n---\n include/libcamera/base/utils.h             |  7 ++++++\n src/libcamera/base/utils.cpp               | 35 ++++++++++++++++++++++++++++++\n src/libcamera/pipeline/virtual/virtual.cpp | 10 ++-------\n 3 files changed, 44 insertions(+), 8 deletions(-)","diff":"diff --git a/include/libcamera/base/utils.h b/include/libcamera/base/utils.h\nindex 7083b7ce9ce9..62c7f89c25a1 100644\n--- a/include/libcamera/base/utils.h\n+++ b/include/libcamera/base/utils.h\n@@ -37,6 +37,13 @@ namespace libcamera {\n \n namespace utils {\n \n+template<class... Ts>\n+struct overloaded : Ts... {\n+\tusing Ts::operator()...;\n+};\n+template<class... Ts>\n+overloaded(Ts...) -> overloaded<Ts...>;\n+\n const char *basename(const char *path);\n \n char *secure_getenv(const char *name);\ndiff --git a/src/libcamera/base/utils.cpp b/src/libcamera/base/utils.cpp\nindex 42a516097be2..836aec87c539 100644\n--- a/src/libcamera/base/utils.cpp\n+++ b/src/libcamera/base/utils.cpp\n@@ -23,6 +23,41 @@ namespace libcamera {\n \n namespace utils {\n \n+/**\n+ * \\struct overloaded\n+ * \\brief Helper type for type-matching std::visit implementations\n+ * \\tparam Ts... Template arguments pack of visitors\n+ *\n+ * Expand the template argument pack \\a Ts... to provide overloaded \\a\n+ * operator() to support type-matching implementations of the visitor design\n+ * pattern using std::visit.\n+ *\n+ * An example is provided by the STL documentation in the form of:\n+ *\n+ * \\code{.cpp}\n+ * template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; };\n+ * template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>;\n+ *\n+ * using var_t = std::variant<int, long, double, std::string>;\n+ * std::vector<var_t> vec = {10, 15l, 1.5, \"hello\"};\n+ *\n+ * for (auto& v: vec) {\n+ * \tstd::visit(overloaded {\n+ * \t\t[](auto arg) { std::cout << arg << ' '; },\n+ * \t\t[](double arg) { std::cout << std::fixed << arg << ' '; },\n+ * \t\t[](const std::string& arg) { std::cout << std::quoted(arg) << ' '; },\n+ * \t}, v);\n+ * \\endcode\n+ *\n+ * Use this helper to implement type-matching visitors using std::visit().\n+ */\n+\n+/**\n+ * \\var <class... Ts> overloaded(Ts...) -> overloaded<Ts...>\n+ * \\brief Deduction guide necessary for C++17 compatibility\n+ * \\tparam Ts... Template arguments pack of visitor functions\n+ */\n+\n /**\n  * \\brief Strip the directory prefix from the path\n  * \\param[in] path The path to process\ndiff --git a/src/libcamera/pipeline/virtual/virtual.cpp b/src/libcamera/pipeline/virtual/virtual.cpp\nindex efd800ebe3d6..e8ef7e524ccf 100644\n--- a/src/libcamera/pipeline/virtual/virtual.cpp\n+++ b/src/libcamera/pipeline/virtual/virtual.cpp\n@@ -23,6 +23,7 @@\n \n #include <libcamera/base/flags.h>\n #include <libcamera/base/log.h>\n+#include <libcamera/base/utils.h>\n \n #include <libcamera/control_ids.h>\n #include <libcamera/controls.h>\n@@ -57,13 +58,6 @@ uint64_t currentTimestamp()\n \n } /* namespace */\n \n-template<class... Ts>\n-struct overloaded : Ts... {\n-\tusing Ts::operator()...;\n-};\n-template<class... Ts>\n-overloaded(Ts...) -> overloaded<Ts...>;\n-\n class VirtualCameraConfiguration : public CameraConfiguration\n {\n public:\n@@ -428,7 +422,7 @@ bool PipelineHandlerVirtual::initFrameGenerator(Camera *camera)\n {\n \tauto data = cameraData(camera);\n \tauto &frame = data->config_.frame;\n-\tstd::visit(overloaded{\n+\tstd::visit(utils::overloaded{\n \t\t\t   [&](TestPattern &testPattern) {\n \t\t\t\t   for (auto &streamConfig : data->streamConfigs_) {\n \t\t\t\t\t   if (testPattern == TestPattern::DiagonalLines)\n","prefixes":["v6","2/7"]}