[{"id":29883,"web_url":"https://patchwork.libcamera.org/comment/29883/","msgid":"<ZmqfG8MNeVlr0019@pyrite.rasen.tech>","date":"2024-06-13T07:26:19","subject":"Re: [PATCH 02/11] libcamera: yaml_parser: Delegate YamlObject::get()\n\tto helper structure","submitter":{"id":17,"url":"https://patchwork.libcamera.org/api/people/17/","name":"Paul Elder","email":"paul.elder@ideasonboard.com"},"content":"On Thu, Jun 13, 2024 at 04:39:35AM +0300, Laurent Pinchart wrote:\n> The YamlObject::get() function is a function template that gets fully\n> specialized for various types. This works fine for non-template types,\n> but specializing it for template types (e.g. a std::vector<U>) would\n> require partial template specialization, which C++ allows for classes\n> and variables but not functions.\n> \n> To work around this problem, delegate the implementation to a new\n> YamlObject::Getter structure template, which will support partial\n> specialization.\n> \n> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n\nReviewed-by: Paul Elder <paul.elder@ideasonboard.com>\n\n> ---\n>  include/libcamera/internal/yaml_parser.h | 12 +++-\n>  src/libcamera/yaml_parser.cpp            | 78 +++++++++++++-----------\n>  2 files changed, 55 insertions(+), 35 deletions(-)\n> \n> diff --git a/include/libcamera/internal/yaml_parser.h b/include/libcamera/internal/yaml_parser.h\n> index 81cc0e25ae0f..06a41146ad01 100644\n> --- a/include/libcamera/internal/yaml_parser.h\n> +++ b/include/libcamera/internal/yaml_parser.h\n> @@ -162,7 +162,10 @@ public:\n>  \tstd::size_t size() const;\n>  \n>  \ttemplate<typename T>\n> -\tstd::optional<T> get() const;\n> +\tstd::optional<T> get() const\n> +\t{\n> +\t\treturn Getter<T>{}.get(*this);\n> +\t}\n>  \n>  \ttemplate<typename T, typename U>\n>  \tT get(U &&defaultValue) const\n> @@ -199,6 +202,8 @@ public:\n>  private:\n>  \tLIBCAMERA_DISABLE_COPY_AND_MOVE(YamlObject)\n>  \n> +\ttemplate<typename T>\n> +\tfriend struct Getter;\n>  \tfriend class YamlParserContext;\n>  \n>  \tenum class Type {\n> @@ -207,6 +212,11 @@ private:\n>  \t\tValue,\n>  \t};\n>  \n> +\ttemplate<typename T>\n> +\tstruct Getter {\n> +\t\tstd::optional<T> get(const YamlObject &obj) const;\n> +\t};\n> +\n>  \tType type_;\n>  \n>  \tstd::string value_;\n> diff --git a/src/libcamera/yaml_parser.cpp b/src/libcamera/yaml_parser.cpp\n> index b68a44c15c35..56670ba7a584 100644\n> --- a/src/libcamera/yaml_parser.cpp\n> +++ b/src/libcamera/yaml_parser.cpp\n> @@ -118,14 +118,15 @@ std::size_t YamlObject::size() const\n>  #ifndef __DOXYGEN__\n>  \n>  template<>\n> -std::optional<bool> YamlObject::get() const\n> +std::optional<bool>\n> +YamlObject::Getter<bool>::get(const YamlObject &obj) const\n>  {\n> -\tif (type_ != Type::Value)\n> +\tif (obj.type_ != Type::Value)\n>  \t\treturn std::nullopt;\n>  \n> -\tif (value_ == \"true\")\n> +\tif (obj.value_ == \"true\")\n>  \t\treturn true;\n> -\telse if (value_ == \"false\")\n> +\telse if (obj.value_ == \"false\")\n>  \t\treturn false;\n>  \n>  \treturn std::nullopt;\n> @@ -182,14 +183,15 @@ bool parseUnsignedInteger(const std::string &str, unsigned long max,\n>  } /* namespace */\n>  \n>  template<>\n> -std::optional<int8_t> YamlObject::get() const\n> +std::optional<int8_t>\n> +YamlObject::Getter<int8_t>::get(const YamlObject &obj) const\n>  {\n> -\tif (type_ != Type::Value)\n> +\tif (obj.type_ != Type::Value)\n>  \t\treturn std::nullopt;\n>  \n>  \tlong value;\n>  \n> -\tif (!parseSignedInteger(value_, std::numeric_limits<int8_t>::min(),\n> +\tif (!parseSignedInteger(obj.value_, std::numeric_limits<int8_t>::min(),\n>  \t\t\t\tstd::numeric_limits<int8_t>::max(), &value))\n>  \t\treturn std::nullopt;\n>  \n> @@ -197,14 +199,15 @@ std::optional<int8_t> YamlObject::get() const\n>  }\n>  \n>  template<>\n> -std::optional<uint8_t> YamlObject::get() const\n> +std::optional<uint8_t>\n> +YamlObject::Getter<uint8_t>::get(const YamlObject &obj) const\n>  {\n> -\tif (type_ != Type::Value)\n> +\tif (obj.type_ != Type::Value)\n>  \t\treturn std::nullopt;\n>  \n>  \tunsigned long value;\n>  \n> -\tif (!parseUnsignedInteger(value_, std::numeric_limits<uint8_t>::max(),\n> +\tif (!parseUnsignedInteger(obj.value_, std::numeric_limits<uint8_t>::max(),\n>  \t\t\t\t  &value))\n>  \t\treturn std::nullopt;\n>  \n> @@ -212,14 +215,15 @@ std::optional<uint8_t> YamlObject::get() const\n>  }\n>  \n>  template<>\n> -std::optional<int16_t> YamlObject::get() const\n> +std::optional<int16_t>\n> +YamlObject::Getter<int16_t>::get(const YamlObject &obj) const\n>  {\n> -\tif (type_ != Type::Value)\n> +\tif (obj.type_ != Type::Value)\n>  \t\treturn std::nullopt;\n>  \n>  \tlong value;\n>  \n> -\tif (!parseSignedInteger(value_, std::numeric_limits<int16_t>::min(),\n> +\tif (!parseSignedInteger(obj.value_, std::numeric_limits<int16_t>::min(),\n>  \t\t\t\tstd::numeric_limits<int16_t>::max(), &value))\n>  \t\treturn std::nullopt;\n>  \n> @@ -227,14 +231,15 @@ std::optional<int16_t> YamlObject::get() const\n>  }\n>  \n>  template<>\n> -std::optional<uint16_t> YamlObject::get() const\n> +std::optional<uint16_t>\n> +YamlObject::Getter<uint16_t>::get(const YamlObject &obj) const\n>  {\n> -\tif (type_ != Type::Value)\n> +\tif (obj.type_ != Type::Value)\n>  \t\treturn std::nullopt;\n>  \n>  \tunsigned long value;\n>  \n> -\tif (!parseUnsignedInteger(value_, std::numeric_limits<uint16_t>::max(),\n> +\tif (!parseUnsignedInteger(obj.value_, std::numeric_limits<uint16_t>::max(),\n>  \t\t\t\t  &value))\n>  \t\treturn std::nullopt;\n>  \n> @@ -242,14 +247,15 @@ std::optional<uint16_t> YamlObject::get() const\n>  }\n>  \n>  template<>\n> -std::optional<int32_t> YamlObject::get() const\n> +std::optional<int32_t>\n> +YamlObject::Getter<int32_t>::get(const YamlObject &obj) const\n>  {\n> -\tif (type_ != Type::Value)\n> +\tif (obj.type_ != Type::Value)\n>  \t\treturn std::nullopt;\n>  \n>  \tlong value;\n>  \n> -\tif (!parseSignedInteger(value_, std::numeric_limits<int32_t>::min(),\n> +\tif (!parseSignedInteger(obj.value_, std::numeric_limits<int32_t>::min(),\n>  \t\t\t\tstd::numeric_limits<int32_t>::max(), &value))\n>  \t\treturn std::nullopt;\n>  \n> @@ -257,14 +263,15 @@ std::optional<int32_t> YamlObject::get() const\n>  }\n>  \n>  template<>\n> -std::optional<uint32_t> YamlObject::get() const\n> +std::optional<uint32_t>\n> +YamlObject::Getter<uint32_t>::get(const YamlObject &obj) const\n>  {\n> -\tif (type_ != Type::Value)\n> +\tif (obj.type_ != Type::Value)\n>  \t\treturn std::nullopt;\n>  \n>  \tunsigned long value;\n>  \n> -\tif (!parseUnsignedInteger(value_, std::numeric_limits<uint32_t>::max(),\n> +\tif (!parseUnsignedInteger(obj.value_, std::numeric_limits<uint32_t>::max(),\n>  \t\t\t\t  &value))\n>  \t\treturn std::nullopt;\n>  \n> @@ -272,18 +279,19 @@ std::optional<uint32_t> YamlObject::get() const\n>  }\n>  \n>  template<>\n> -std::optional<double> YamlObject::get() const\n> +std::optional<double>\n> +YamlObject::Getter<double>::get(const YamlObject &obj) const\n>  {\n> -\tif (type_ != Type::Value)\n> +\tif (obj.type_ != Type::Value)\n>  \t\treturn std::nullopt;\n>  \n> -\tif (value_ == \"\")\n> +\tif (obj.value_ == \"\")\n>  \t\treturn std::nullopt;\n>  \n>  \tchar *end;\n>  \n>  \terrno = 0;\n> -\tdouble value = utils::strtod(value_.c_str(), &end);\n> +\tdouble value = utils::strtod(obj.value_.c_str(), &end);\n>  \n>  \tif ('\\0' != *end || errno == ERANGE)\n>  \t\treturn std::nullopt;\n> @@ -292,28 +300,30 @@ std::optional<double> YamlObject::get() const\n>  }\n>  \n>  template<>\n> -std::optional<std::string> YamlObject::get() const\n> +std::optional<std::string>\n> +YamlObject::Getter<std::string>::get(const YamlObject &obj) const\n>  {\n> -\tif (type_ != Type::Value)\n> +\tif (obj.type_ != Type::Value)\n>  \t\treturn std::nullopt;\n>  \n> -\treturn value_;\n> +\treturn obj.value_;\n>  }\n>  \n>  template<>\n> -std::optional<Size> YamlObject::get() const\n> +std::optional<Size>\n> +YamlObject::Getter<Size>::get(const YamlObject &obj) const\n>  {\n> -\tif (type_ != Type::List)\n> +\tif (obj.type_ != Type::List)\n>  \t\treturn std::nullopt;\n>  \n> -\tif (list_.size() != 2)\n> +\tif (obj.list_.size() != 2)\n>  \t\treturn std::nullopt;\n>  \n> -\tauto width = list_[0].value->get<uint32_t>();\n> +\tauto width = obj.list_[0].value->get<uint32_t>();\n>  \tif (!width)\n>  \t\treturn std::nullopt;\n>  \n> -\tauto height = list_[1].value->get<uint32_t>();\n> +\tauto height = obj.list_[1].value->get<uint32_t>();\n>  \tif (!height)\n>  \t\treturn std::nullopt;\n>","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 3B950C3237\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu, 13 Jun 2024 07:26:28 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 18C3C6548D;\n\tThu, 13 Jun 2024 09:26:27 +0200 (CEST)","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 20ACC65458\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 13 Jun 2024 09:26:26 +0200 (CEST)","from pyrite.rasen.tech (h175-177-049-156.catv02.itscom.jp\n\t[175.177.49.156])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id BDF2D4CF;\n\tThu, 13 Jun 2024 09:26:10 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"QJ3BHbBv\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1718263572;\n\tbh=YwRggzJDI5zXxmr+kTBoinDL2ByW2htaAtHPtBNEOFE=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=QJ3BHbBv56qkFKjDGYhjW8Vxoxs75PenxI+GNeYIhXz62p05P8a2mb3YHP9OtxRgs\n\tKDUk8fB8/ZI+pZdIstlB8wDXt+tzsToZ0rlQrUuJuns/LXNApN3v+V82xeq1YhnudN\n\tY7bTV7MX0EteQ1p+J15Kmv18jGh2wZH1bIGvzXHo=","Date":"Thu, 13 Jun 2024 16:26:19 +0900","From":"Paul Elder <paul.elder@ideasonboard.com>","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org,\n\tDavid Plowman <david.plowman@raspberrypi.com>,\n\tNaushir Patuck <naush@raspberrypi.com>","Subject":"Re: [PATCH 02/11] libcamera: yaml_parser: Delegate YamlObject::get()\n\tto helper structure","Message-ID":"<ZmqfG8MNeVlr0019@pyrite.rasen.tech>","References":"<20240613013944.23344-1-laurent.pinchart@ideasonboard.com>\n\t<20240613013944.23344-3-laurent.pinchart@ideasonboard.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=us-ascii","Content-Disposition":"inline","In-Reply-To":"<20240613013944.23344-3-laurent.pinchart@ideasonboard.com>","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>"}},{"id":29920,"web_url":"https://patchwork.libcamera.org/comment/29920/","msgid":"<171827873461.2248009.6385062751997883516@ping.linuxembedded.co.uk>","date":"2024-06-13T11:38:54","subject":"Re: [PATCH 02/11] libcamera: yaml_parser: Delegate YamlObject::get()\n\tto helper structure","submitter":{"id":4,"url":"https://patchwork.libcamera.org/api/people/4/","name":"Kieran Bingham","email":"kieran.bingham@ideasonboard.com"},"content":"Quoting Laurent Pinchart (2024-06-13 02:39:35)\n> The YamlObject::get() function is a function template that gets fully\n> specialized for various types. This works fine for non-template types,\n> but specializing it for template types (e.g. a std::vector<U>) would\n> require partial template specialization, which C++ allows for classes\n> and variables but not functions.\n> \n> To work around this problem, delegate the implementation to a new\n> YamlObject::Getter structure template, which will support partial\n> specialization.\n> \n> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n> ---\n>  include/libcamera/internal/yaml_parser.h | 12 +++-\n>  src/libcamera/yaml_parser.cpp            | 78 +++++++++++++-----------\n>  2 files changed, 55 insertions(+), 35 deletions(-)\n> \n> diff --git a/include/libcamera/internal/yaml_parser.h b/include/libcamera/internal/yaml_parser.h\n> index 81cc0e25ae0f..06a41146ad01 100644\n> --- a/include/libcamera/internal/yaml_parser.h\n> +++ b/include/libcamera/internal/yaml_parser.h\n> @@ -162,7 +162,10 @@ public:\n>         std::size_t size() const;\n>  \n>         template<typename T>\n> -       std::optional<T> get() const;\n> +       std::optional<T> get() const\n> +       {\n> +               return Getter<T>{}.get(*this);\n> +       }\n\nAha, this is the magic I missed on my first pass. I was curious how we\nwere changing all these fucntions to now need an object, and I couldn't\nsee core changes not passing it in - but it comes from here.\n\nOk so that's neat - and means nothing else is impacted during the\ntransition...\n\nIt all falls into place:\n\nReviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n\n>  \n>         template<typename T, typename U>\n>         T get(U &&defaultValue) const\n> @@ -199,6 +202,8 @@ public:\n>  private:\n>         LIBCAMERA_DISABLE_COPY_AND_MOVE(YamlObject)\n>  \n> +       template<typename T>\n> +       friend struct Getter;\n>         friend class YamlParserContext;\n>  \n>         enum class Type {\n> @@ -207,6 +212,11 @@ private:\n>                 Value,\n>         };\n>  \n> +       template<typename T>\n> +       struct Getter {\n> +               std::optional<T> get(const YamlObject &obj) const;\n> +       };\n> +\n>         Type type_;\n>  \n>         std::string value_;\n> diff --git a/src/libcamera/yaml_parser.cpp b/src/libcamera/yaml_parser.cpp\n> index b68a44c15c35..56670ba7a584 100644\n> --- a/src/libcamera/yaml_parser.cpp\n> +++ b/src/libcamera/yaml_parser.cpp\n> @@ -118,14 +118,15 @@ std::size_t YamlObject::size() const\n>  #ifndef __DOXYGEN__\n>  \n>  template<>\n> -std::optional<bool> YamlObject::get() const\n> +std::optional<bool>\n> +YamlObject::Getter<bool>::get(const YamlObject &obj) const\n>  {\n> -       if (type_ != Type::Value)\n> +       if (obj.type_ != Type::Value)\n>                 return std::nullopt;\n>  \n> -       if (value_ == \"true\")\n> +       if (obj.value_ == \"true\")\n>                 return true;\n> -       else if (value_ == \"false\")\n> +       else if (obj.value_ == \"false\")\n>                 return false;\n>  \n>         return std::nullopt;\n> @@ -182,14 +183,15 @@ bool parseUnsignedInteger(const std::string &str, unsigned long max,\n>  } /* namespace */\n>  \n>  template<>\n> -std::optional<int8_t> YamlObject::get() const\n> +std::optional<int8_t>\n> +YamlObject::Getter<int8_t>::get(const YamlObject &obj) const\n>  {\n> -       if (type_ != Type::Value)\n> +       if (obj.type_ != Type::Value)\n>                 return std::nullopt;\n>  \n>         long value;\n>  \n> -       if (!parseSignedInteger(value_, std::numeric_limits<int8_t>::min(),\n> +       if (!parseSignedInteger(obj.value_, std::numeric_limits<int8_t>::min(),\n>                                 std::numeric_limits<int8_t>::max(), &value))\n>                 return std::nullopt;\n>  \n> @@ -197,14 +199,15 @@ std::optional<int8_t> YamlObject::get() const\n>  }\n>  \n>  template<>\n> -std::optional<uint8_t> YamlObject::get() const\n> +std::optional<uint8_t>\n> +YamlObject::Getter<uint8_t>::get(const YamlObject &obj) const\n>  {\n> -       if (type_ != Type::Value)\n> +       if (obj.type_ != Type::Value)\n>                 return std::nullopt;\n>  \n>         unsigned long value;\n>  \n> -       if (!parseUnsignedInteger(value_, std::numeric_limits<uint8_t>::max(),\n> +       if (!parseUnsignedInteger(obj.value_, std::numeric_limits<uint8_t>::max(),\n>                                   &value))\n>                 return std::nullopt;\n>  \n> @@ -212,14 +215,15 @@ std::optional<uint8_t> YamlObject::get() const\n>  }\n>  \n>  template<>\n> -std::optional<int16_t> YamlObject::get() const\n> +std::optional<int16_t>\n> +YamlObject::Getter<int16_t>::get(const YamlObject &obj) const\n>  {\n> -       if (type_ != Type::Value)\n> +       if (obj.type_ != Type::Value)\n>                 return std::nullopt;\n>  \n>         long value;\n>  \n> -       if (!parseSignedInteger(value_, std::numeric_limits<int16_t>::min(),\n> +       if (!parseSignedInteger(obj.value_, std::numeric_limits<int16_t>::min(),\n>                                 std::numeric_limits<int16_t>::max(), &value))\n>                 return std::nullopt;\n>  \n> @@ -227,14 +231,15 @@ std::optional<int16_t> YamlObject::get() const\n>  }\n>  \n>  template<>\n> -std::optional<uint16_t> YamlObject::get() const\n> +std::optional<uint16_t>\n> +YamlObject::Getter<uint16_t>::get(const YamlObject &obj) const\n>  {\n> -       if (type_ != Type::Value)\n> +       if (obj.type_ != Type::Value)\n>                 return std::nullopt;\n>  \n>         unsigned long value;\n>  \n> -       if (!parseUnsignedInteger(value_, std::numeric_limits<uint16_t>::max(),\n> +       if (!parseUnsignedInteger(obj.value_, std::numeric_limits<uint16_t>::max(),\n>                                   &value))\n>                 return std::nullopt;\n>  \n> @@ -242,14 +247,15 @@ std::optional<uint16_t> YamlObject::get() const\n>  }\n>  \n>  template<>\n> -std::optional<int32_t> YamlObject::get() const\n> +std::optional<int32_t>\n> +YamlObject::Getter<int32_t>::get(const YamlObject &obj) const\n>  {\n> -       if (type_ != Type::Value)\n> +       if (obj.type_ != Type::Value)\n>                 return std::nullopt;\n>  \n>         long value;\n>  \n> -       if (!parseSignedInteger(value_, std::numeric_limits<int32_t>::min(),\n> +       if (!parseSignedInteger(obj.value_, std::numeric_limits<int32_t>::min(),\n>                                 std::numeric_limits<int32_t>::max(), &value))\n>                 return std::nullopt;\n>  \n> @@ -257,14 +263,15 @@ std::optional<int32_t> YamlObject::get() const\n>  }\n>  \n>  template<>\n> -std::optional<uint32_t> YamlObject::get() const\n> +std::optional<uint32_t>\n> +YamlObject::Getter<uint32_t>::get(const YamlObject &obj) const\n>  {\n> -       if (type_ != Type::Value)\n> +       if (obj.type_ != Type::Value)\n>                 return std::nullopt;\n>  \n>         unsigned long value;\n>  \n> -       if (!parseUnsignedInteger(value_, std::numeric_limits<uint32_t>::max(),\n> +       if (!parseUnsignedInteger(obj.value_, std::numeric_limits<uint32_t>::max(),\n>                                   &value))\n>                 return std::nullopt;\n>  \n> @@ -272,18 +279,19 @@ std::optional<uint32_t> YamlObject::get() const\n>  }\n>  \n>  template<>\n> -std::optional<double> YamlObject::get() const\n> +std::optional<double>\n> +YamlObject::Getter<double>::get(const YamlObject &obj) const\n>  {\n> -       if (type_ != Type::Value)\n> +       if (obj.type_ != Type::Value)\n>                 return std::nullopt;\n>  \n> -       if (value_ == \"\")\n> +       if (obj.value_ == \"\")\n>                 return std::nullopt;\n>  \n>         char *end;\n>  \n>         errno = 0;\n> -       double value = utils::strtod(value_.c_str(), &end);\n> +       double value = utils::strtod(obj.value_.c_str(), &end);\n>  \n>         if ('\\0' != *end || errno == ERANGE)\n>                 return std::nullopt;\n> @@ -292,28 +300,30 @@ std::optional<double> YamlObject::get() const\n>  }\n>  \n>  template<>\n> -std::optional<std::string> YamlObject::get() const\n> +std::optional<std::string>\n> +YamlObject::Getter<std::string>::get(const YamlObject &obj) const\n>  {\n> -       if (type_ != Type::Value)\n> +       if (obj.type_ != Type::Value)\n>                 return std::nullopt;\n>  \n> -       return value_;\n> +       return obj.value_;\n>  }\n>  \n>  template<>\n> -std::optional<Size> YamlObject::get() const\n> +std::optional<Size>\n> +YamlObject::Getter<Size>::get(const YamlObject &obj) const\n>  {\n> -       if (type_ != Type::List)\n> +       if (obj.type_ != Type::List)\n>                 return std::nullopt;\n>  \n> -       if (list_.size() != 2)\n> +       if (obj.list_.size() != 2)\n>                 return std::nullopt;\n>  \n> -       auto width = list_[0].value->get<uint32_t>();\n> +       auto width = obj.list_[0].value->get<uint32_t>();\n>         if (!width)\n>                 return std::nullopt;\n>  \n> -       auto height = list_[1].value->get<uint32_t>();\n> +       auto height = obj.list_[1].value->get<uint32_t>();\n>         if (!height)\n>                 return std::nullopt;\n>  \n> -- \n> Regards,\n> \n> Laurent Pinchart\n>","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 188BCC3237\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu, 13 Jun 2024 11:39:00 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id B4ABA65497;\n\tThu, 13 Jun 2024 13:38:59 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id C8CA36548E\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 13 Jun 2024 13:38:57 +0200 (CEST)","from pendragon.ideasonboard.com\n\t(cpc89244-aztw30-2-0-cust6594.18-1.cable.virginm.net [86.31.185.195])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id CDF544CF;\n\tThu, 13 Jun 2024 13:38:43 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"GV8y5UQr\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1718278723;\n\tbh=U/WBShIipAHyd85HWf5Xtnzak43LK4PPK/5PfWs0Eqw=;\n\th=In-Reply-To:References:Subject:From:Cc:To:Date:From;\n\tb=GV8y5UQrCY1Lk5DngTobEp/5kGJyj3xwOqjofSb8JzZlwQkI1ZuVsJ2qEl9WJuYZr\n\tXFCdQeijYvK8V7zpgSoFArvv8GsR0UM1HsRNn2Los+dX38waRrimTplmkaWLvMci9O\n\tdrRiHgfvyQH1dMbMhOA+6fvMurAxLrVnp0XHfI7g=","Content-Type":"text/plain; charset=\"utf-8\"","MIME-Version":"1.0","Content-Transfer-Encoding":"quoted-printable","In-Reply-To":"<20240613013944.23344-3-laurent.pinchart@ideasonboard.com>","References":"<20240613013944.23344-1-laurent.pinchart@ideasonboard.com>\n\t<20240613013944.23344-3-laurent.pinchart@ideasonboard.com>","Subject":"Re: [PATCH 02/11] libcamera: yaml_parser: Delegate YamlObject::get()\n\tto helper structure","From":"Kieran Bingham <kieran.bingham@ideasonboard.com>","Cc":"Paul Elder <paul.elder@ideasonboard.com>,\n\tDavid Plowman <david.plowman@raspberrypi.com>,\n\tNaushir Patuck <naush@raspberrypi.com>","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>,\n\tlibcamera-devel@lists.libcamera.org","Date":"Thu, 13 Jun 2024 12:38:54 +0100","Message-ID":"<171827873461.2248009.6385062751997883516@ping.linuxembedded.co.uk>","User-Agent":"alot/0.10","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>"}}]