From patchwork Thu Jun 13 01:39:35 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 20274 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 19284C3237 for ; Thu, 13 Jun 2024 01:40:12 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id E202F6548E; Thu, 13 Jun 2024 03:40:10 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="hm0R90g1"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id A6F2C6548D for ; Thu, 13 Jun 2024 03:40:07 +0200 (CEST) Received: from pendragon.ideasonboard.com (81-175-209-231.bb.dnainternet.fi [81.175.209.231]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id DB842D77; Thu, 13 Jun 2024 03:39:53 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1718242794; bh=rpXcpQX6Ga5FqCCk4kox9hOvcSZpo6tu6GCqeSqh7nI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=hm0R90g1qgK/MdAguc3ykL2G65RlPBgD+gWu1y3XBNCh+Zos8KLnLMSUSbDOHpZKR S7gcQcarJSUZcnlVAoK21W9CUFB9ns1vqQb/5ANQpMZ0kVK1A5dUfkeIsxafQExuBK +/QAFFOF9BAO5b2NTsNd+jSc5cA6X6h4P7LBcsCc= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Cc: Paul Elder , David Plowman , Naushir Patuck Subject: [PATCH 02/11] libcamera: yaml_parser: Delegate YamlObject::get() to helper structure Date: Thu, 13 Jun 2024 04:39:35 +0300 Message-ID: <20240613013944.23344-3-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.44.2 In-Reply-To: <20240613013944.23344-1-laurent.pinchart@ideasonboard.com> References: <20240613013944.23344-1-laurent.pinchart@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" The YamlObject::get() function is a function template that gets fully specialized for various types. This works fine for non-template types, but specializing it for template types (e.g. a std::vector) would require partial template specialization, which C++ allows for classes and variables but not functions. To work around this problem, delegate the implementation to a new YamlObject::Getter structure template, which will support partial specialization. Signed-off-by: Laurent Pinchart Reviewed-by: Paul Elder Reviewed-by: Kieran Bingham --- include/libcamera/internal/yaml_parser.h | 12 +++- src/libcamera/yaml_parser.cpp | 78 +++++++++++++----------- 2 files changed, 55 insertions(+), 35 deletions(-) diff --git a/include/libcamera/internal/yaml_parser.h b/include/libcamera/internal/yaml_parser.h index 81cc0e25ae0f..06a41146ad01 100644 --- a/include/libcamera/internal/yaml_parser.h +++ b/include/libcamera/internal/yaml_parser.h @@ -162,7 +162,10 @@ public: std::size_t size() const; template - std::optional get() const; + std::optional get() const + { + return Getter{}.get(*this); + } template T get(U &&defaultValue) const @@ -199,6 +202,8 @@ public: private: LIBCAMERA_DISABLE_COPY_AND_MOVE(YamlObject) + template + friend struct Getter; friend class YamlParserContext; enum class Type { @@ -207,6 +212,11 @@ private: Value, }; + template + struct Getter { + std::optional get(const YamlObject &obj) const; + }; + Type type_; std::string value_; diff --git a/src/libcamera/yaml_parser.cpp b/src/libcamera/yaml_parser.cpp index b68a44c15c35..56670ba7a584 100644 --- a/src/libcamera/yaml_parser.cpp +++ b/src/libcamera/yaml_parser.cpp @@ -118,14 +118,15 @@ std::size_t YamlObject::size() const #ifndef __DOXYGEN__ template<> -std::optional YamlObject::get() const +std::optional +YamlObject::Getter::get(const YamlObject &obj) const { - if (type_ != Type::Value) + if (obj.type_ != Type::Value) return std::nullopt; - if (value_ == "true") + if (obj.value_ == "true") return true; - else if (value_ == "false") + else if (obj.value_ == "false") return false; return std::nullopt; @@ -182,14 +183,15 @@ bool parseUnsignedInteger(const std::string &str, unsigned long max, } /* namespace */ template<> -std::optional YamlObject::get() const +std::optional +YamlObject::Getter::get(const YamlObject &obj) const { - if (type_ != Type::Value) + if (obj.type_ != Type::Value) return std::nullopt; long value; - if (!parseSignedInteger(value_, std::numeric_limits::min(), + if (!parseSignedInteger(obj.value_, std::numeric_limits::min(), std::numeric_limits::max(), &value)) return std::nullopt; @@ -197,14 +199,15 @@ std::optional YamlObject::get() const } template<> -std::optional YamlObject::get() const +std::optional +YamlObject::Getter::get(const YamlObject &obj) const { - if (type_ != Type::Value) + if (obj.type_ != Type::Value) return std::nullopt; unsigned long value; - if (!parseUnsignedInteger(value_, std::numeric_limits::max(), + if (!parseUnsignedInteger(obj.value_, std::numeric_limits::max(), &value)) return std::nullopt; @@ -212,14 +215,15 @@ std::optional YamlObject::get() const } template<> -std::optional YamlObject::get() const +std::optional +YamlObject::Getter::get(const YamlObject &obj) const { - if (type_ != Type::Value) + if (obj.type_ != Type::Value) return std::nullopt; long value; - if (!parseSignedInteger(value_, std::numeric_limits::min(), + if (!parseSignedInteger(obj.value_, std::numeric_limits::min(), std::numeric_limits::max(), &value)) return std::nullopt; @@ -227,14 +231,15 @@ std::optional YamlObject::get() const } template<> -std::optional YamlObject::get() const +std::optional +YamlObject::Getter::get(const YamlObject &obj) const { - if (type_ != Type::Value) + if (obj.type_ != Type::Value) return std::nullopt; unsigned long value; - if (!parseUnsignedInteger(value_, std::numeric_limits::max(), + if (!parseUnsignedInteger(obj.value_, std::numeric_limits::max(), &value)) return std::nullopt; @@ -242,14 +247,15 @@ std::optional YamlObject::get() const } template<> -std::optional YamlObject::get() const +std::optional +YamlObject::Getter::get(const YamlObject &obj) const { - if (type_ != Type::Value) + if (obj.type_ != Type::Value) return std::nullopt; long value; - if (!parseSignedInteger(value_, std::numeric_limits::min(), + if (!parseSignedInteger(obj.value_, std::numeric_limits::min(), std::numeric_limits::max(), &value)) return std::nullopt; @@ -257,14 +263,15 @@ std::optional YamlObject::get() const } template<> -std::optional YamlObject::get() const +std::optional +YamlObject::Getter::get(const YamlObject &obj) const { - if (type_ != Type::Value) + if (obj.type_ != Type::Value) return std::nullopt; unsigned long value; - if (!parseUnsignedInteger(value_, std::numeric_limits::max(), + if (!parseUnsignedInteger(obj.value_, std::numeric_limits::max(), &value)) return std::nullopt; @@ -272,18 +279,19 @@ std::optional YamlObject::get() const } template<> -std::optional YamlObject::get() const +std::optional +YamlObject::Getter::get(const YamlObject &obj) const { - if (type_ != Type::Value) + if (obj.type_ != Type::Value) return std::nullopt; - if (value_ == "") + if (obj.value_ == "") return std::nullopt; char *end; errno = 0; - double value = utils::strtod(value_.c_str(), &end); + double value = utils::strtod(obj.value_.c_str(), &end); if ('\0' != *end || errno == ERANGE) return std::nullopt; @@ -292,28 +300,30 @@ std::optional YamlObject::get() const } template<> -std::optional YamlObject::get() const +std::optional +YamlObject::Getter::get(const YamlObject &obj) const { - if (type_ != Type::Value) + if (obj.type_ != Type::Value) return std::nullopt; - return value_; + return obj.value_; } template<> -std::optional YamlObject::get() const +std::optional +YamlObject::Getter::get(const YamlObject &obj) const { - if (type_ != Type::List) + if (obj.type_ != Type::List) return std::nullopt; - if (list_.size() != 2) + if (obj.list_.size() != 2) return std::nullopt; - auto width = list_[0].value->get(); + auto width = obj.list_[0].value->get(); if (!width) return std::nullopt; - auto height = list_[1].value->get(); + auto height = obj.list_[1].value->get(); if (!height) return std::nullopt;