[{"id":24181,"web_url":"https://patchwork.libcamera.org/comment/24181/","msgid":"<CAEmqJPopfyn+rLWdqVuVA7LcBbEmHXEfLgnHHxps8nMw9g6jOA@mail.gmail.com>","date":"2022-07-27T09:34:50","subject":"Re: [libcamera-devel] [PATCH v7 01/14] libcamera: yaml_parser:\n\tReplace ok flag to get() with std::optional","submitter":{"id":34,"url":"https://patchwork.libcamera.org/api/people/34/","name":"Naushir Patuck","email":"naush@raspberrypi.com"},"content":"Hi Laurent,\n\nThank you for your patch.\n\nOn Wed, 27 Jul 2022 at 03:38, Laurent Pinchart <\nlaurent.pinchart@ideasonboard.com> wrote:\n\n> The YamlObject::get() function takes a default value and an optional\n> bool ok flag to handle parsing errors. This ad-hoc mechanism complicates\n> error handling in callers.\n>\n> A better API is possible by dropping the default value and ok flag and\n> returning an std::optional. Not only does it simplify the calls, it also\n> lets callers handle errors through the standard std::optional class\n> instead of the current ad-hoc mechanism.\n>\n> Provide a convenience get() wrapper around std::optional::value_or() to\n> further simplify callers that don't need any specific error handling.\n>\n\ns/convenience/convenient/ ?\n\n\n> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n>\n\nThis is much cleaner for error handling!\n\nReviewed-by: Naushir Patuck <naush@raspberrypi.com>\n\n\n> ---\n>  include/libcamera/internal/yaml_parser.h |   9 +-\n>  src/libcamera/yaml_parser.cpp            | 138 +++++++++--------------\n>  test/yaml-parser.cpp                     |  71 ++++++------\n>  3 files changed, 96 insertions(+), 122 deletions(-)\n>\n> diff --git a/include/libcamera/internal/yaml_parser.h\n> b/include/libcamera/internal/yaml_parser.h\n> index 064cf44381d7..61f2223223a7 100644\n> --- a/include/libcamera/internal/yaml_parser.h\n> +++ b/include/libcamera/internal/yaml_parser.h\n> @@ -9,6 +9,7 @@\n>\n>  #include <iterator>\n>  #include <map>\n> +#include <optional>\n>  #include <string>\n>  #include <vector>\n>\n> @@ -165,7 +166,13 @@ public:\n>  #else\n>         template<typename T>\n>  #endif\n> -       T get(const T &defaultValue, bool *ok = nullptr) const;\n> +       std::optional<T> get() const;\n> +\n> +       template<typename T>\n> +       T get(const T &defaultValue) const\n> +       {\n> +               return get<T>().value_or(defaultValue);\n> +       }\n>\n>         DictAdapter asDict() const { return DictAdapter{ dictionary_ }; }\n>         ListAdapter asList() const { return ListAdapter{ list_ }; }\n> diff --git a/src/libcamera/yaml_parser.cpp b/src/libcamera/yaml_parser.cpp\n> index 5c45e44e49c3..4299f5abd38a 100644\n> --- a/src/libcamera/yaml_parser.cpp\n> +++ b/src/libcamera/yaml_parser.cpp\n> @@ -31,12 +31,6 @@ namespace {\n>  /* Empty static YamlObject as a safe result for invalid operations */\n>  static const YamlObject empty;\n>\n> -void setOk(bool *ok, bool result)\n> -{\n> -       if (ok)\n> -               *ok = result;\n> -}\n> -\n>  } /* namespace */\n>\n>  /**\n> @@ -100,54 +94,52 @@ std::size_t YamlObject::size() const\n>  }\n>\n>  /**\n> - * \\fn template<typename T> YamlObject::get<T>(\n> - *     const T &defaultValue, bool *ok) const\n> + * \\fn template<typename T> YamlObject::get<T>() const\n> + * \\brief Parse the YamlObject as a \\a T value\n> + *\n> + * This function parses the value of the YamlObject as a \\a T object, and\n> + * returns the value. If parsing fails (usually because the YamlObject\n> doesn't\n> + * store a \\a T value), std::nullopt is returned.\n> + *\n> + * \\return The YamlObject value, or std::nullopt if parsing failed\n> + */\n> +\n> +/**\n> + * \\fn template<typename T> YamlObject::get<T>(const T &defaultValue)\n> const\n>   * \\brief Parse the YamlObject as a \\a T value\n>   * \\param[in] defaultValue The default value when failing to parse\n> - * \\param[out] ok The result of whether the parse succeeded\n>   *\n>   * This function parses the value of the YamlObject as a \\a T object, and\n>   * returns the value. If parsing fails (usually because the YamlObject\n> doesn't\n> - * store a \\a T value), the \\a defaultValue is returned, and \\a ok is set\n> to\n> - * false. Otherwise, the YamlObject value is returned, and \\a ok is set\n> to true.\n> + * store a \\a T value), the \\a defaultValue is returned.\n>   *\n> - * The \\a ok pointer is optional and can be a nullptr if the caller\n> doesn't\n> - * need to know if parsing succeeded.\n> - *\n> - * \\return Value as a bool type\n> + * \\return The YamlObject value, or \\a defaultValue if parsing failed\n>   */\n>\n>  #ifndef __DOXYGEN__\n>\n>  template<>\n> -bool YamlObject::get(const bool &defaultValue, bool *ok) const\n> +std::optional<bool> YamlObject::get() const\n>  {\n> -       setOk(ok, false);\n> -\n>         if (type_ != Type::Value)\n> -               return defaultValue;\n> +               return {};\n>\n> -       if (value_ == \"true\") {\n> -               setOk(ok, true);\n> +       if (value_ == \"true\")\n>                 return true;\n> -       } else if (value_ == \"false\") {\n> -               setOk(ok, true);\n> +       else if (value_ == \"false\")\n>                 return false;\n> -       }\n>\n> -       return defaultValue;\n> +       return {};\n>  }\n>\n>  template<>\n> -int16_t YamlObject::get(const int16_t &defaultValue, bool *ok) const\n> +std::optional<int16_t> YamlObject::get() const\n>  {\n> -       setOk(ok, false);\n> -\n>         if (type_ != Type::Value)\n> -               return defaultValue;\n> +               return {};\n>\n>         if (value_ == \"\")\n> -               return defaultValue;\n> +               return {};\n>\n>         char *end;\n>\n> @@ -157,22 +149,19 @@ int16_t YamlObject::get(const int16_t &defaultValue,\n> bool *ok) const\n>         if ('\\0' != *end || errno == ERANGE ||\n>             value < std::numeric_limits<int16_t>::min() ||\n>             value > std::numeric_limits<int16_t>::max())\n> -               return defaultValue;\n> +               return {};\n>\n> -       setOk(ok, true);\n>         return value;\n>  }\n>\n>  template<>\n> -uint16_t YamlObject::get(const uint16_t &defaultValue, bool *ok) const\n> +std::optional<uint16_t> YamlObject::get() const\n>  {\n> -       setOk(ok, false);\n> -\n>         if (type_ != Type::Value)\n> -               return defaultValue;\n> +               return {};\n>\n>         if (value_ == \"\")\n> -               return defaultValue;\n> +               return {};\n>\n>         /*\n>          * libyaml parses all scalar values as strings. When a string has\n> @@ -183,7 +172,7 @@ uint16_t YamlObject::get(const uint16_t &defaultValue,\n> bool *ok) const\n>          */\n>         std::size_t found = value_.find_first_not_of(\" \\t\");\n>         if (found != std::string::npos && value_[found] == '-')\n> -               return defaultValue;\n> +               return {};\n>\n>         char *end;\n>\n> @@ -193,22 +182,19 @@ uint16_t YamlObject::get(const uint16_t\n> &defaultValue, bool *ok) const\n>         if ('\\0' != *end || errno == ERANGE ||\n>             value < std::numeric_limits<uint16_t>::min() ||\n>             value > std::numeric_limits<uint16_t>::max())\n> -               return defaultValue;\n> +               return {};\n>\n> -       setOk(ok, true);\n>         return value;\n>  }\n>\n>  template<>\n> -int32_t YamlObject::get(const int32_t &defaultValue, bool *ok) const\n> +std::optional<int32_t> YamlObject::get() const\n>  {\n> -       setOk(ok, false);\n> -\n>         if (type_ != Type::Value)\n> -               return defaultValue;\n> +               return {};\n>\n>         if (value_ == \"\")\n> -               return defaultValue;\n> +               return {};\n>\n>         char *end;\n>\n> @@ -218,22 +204,19 @@ int32_t YamlObject::get(const int32_t &defaultValue,\n> bool *ok) const\n>         if ('\\0' != *end || errno == ERANGE ||\n>             value < std::numeric_limits<int32_t>::min() ||\n>             value > std::numeric_limits<int32_t>::max())\n> -               return defaultValue;\n> +               return {};\n>\n> -       setOk(ok, true);\n>         return value;\n>  }\n>\n>  template<>\n> -uint32_t YamlObject::get(const uint32_t &defaultValue, bool *ok) const\n> +std::optional<uint32_t> YamlObject::get() const\n>  {\n> -       setOk(ok, false);\n> -\n>         if (type_ != Type::Value)\n> -               return defaultValue;\n> +               return {};\n>\n>         if (value_ == \"\")\n> -               return defaultValue;\n> +               return {};\n>\n>         /*\n>          * libyaml parses all scalar values as strings. When a string has\n> @@ -244,7 +227,7 @@ uint32_t YamlObject::get(const uint32_t &defaultValue,\n> bool *ok) const\n>          */\n>         std::size_t found = value_.find_first_not_of(\" \\t\");\n>         if (found != std::string::npos && value_[found] == '-')\n> -               return defaultValue;\n> +               return {};\n>\n>         char *end;\n>\n> @@ -254,22 +237,19 @@ uint32_t YamlObject::get(const uint32_t\n> &defaultValue, bool *ok) const\n>         if ('\\0' != *end || errno == ERANGE ||\n>             value < std::numeric_limits<uint32_t>::min() ||\n>             value > std::numeric_limits<uint32_t>::max())\n> -               return defaultValue;\n> +               return {};\n>\n> -       setOk(ok, true);\n>         return value;\n>  }\n>\n>  template<>\n> -double YamlObject::get(const double &defaultValue, bool *ok) const\n> +std::optional<double> YamlObject::get() const\n>  {\n> -       setOk(ok, false);\n> -\n>         if (type_ != Type::Value)\n> -               return defaultValue;\n> +               return {};\n>\n>         if (value_ == \"\")\n> -               return defaultValue;\n> +               return {};\n>\n>         char *end;\n>\n> @@ -277,50 +257,38 @@ double YamlObject::get(const double &defaultValue,\n> bool *ok) const\n>         double value = std::strtod(value_.c_str(), &end);\n>\n>         if ('\\0' != *end || errno == ERANGE)\n> -               return defaultValue;\n> +               return {};\n>\n> -       setOk(ok, true);\n>         return value;\n>  }\n>\n>  template<>\n> -std::string YamlObject::get(const std::string &defaultValue, bool *ok)\n> const\n> +std::optional<std::string> YamlObject::get() const\n>  {\n> -       setOk(ok, false);\n> -\n>         if (type_ != Type::Value)\n> -               return defaultValue;\n> +               return {};\n>\n> -       setOk(ok, true);\n>         return value_;\n>  }\n>\n>  template<>\n> -Size YamlObject::get(const Size &defaultValue, bool *ok) const\n> +std::optional<Size> YamlObject::get() const\n>  {\n> -       setOk(ok, false);\n> -\n>         if (type_ != Type::List)\n> -               return defaultValue;\n> +               return {};\n>\n>         if (list_.size() != 2)\n> -               return defaultValue;\n> +               return {};\n>\n> -       /*\n> -        * Add a local variable to validate each dimension in case\n> -        * that ok == nullptr.\n> -        */\n> -       bool valid;\n> -       uint32_t width = list_[0]->get<uint32_t>(0, &valid);\n> -       if (!valid)\n> -               return defaultValue;\n> +       auto width = list_[0]->get<uint32_t>();\n> +       if (!width)\n> +               return {};\n>\n> -       uint32_t height = list_[1]->get<uint32_t>(0, &valid);\n> -       if (!valid)\n> -               return defaultValue;\n> +       auto height = list_[1]->get<uint32_t>();\n> +       if (!height)\n> +               return {};\n>\n> -       setOk(ok, true);\n> -       return Size(width, height);\n> +       return Size(*width, *height);\n>  }\n>\n>  #endif /* __DOXYGEN__ */\n> diff --git a/test/yaml-parser.cpp b/test/yaml-parser.cpp\n> index 38f848232fa6..ebb654f2ef9c 100644\n> --- a/test/yaml-parser.cpp\n> +++ b/test/yaml-parser.cpp\n> @@ -148,7 +148,6 @@ protected:\n>                 }\n>\n>                 /* Test string object */\n> -               bool ok;\n>                 auto &strObj = (*root)[\"string\"];\n>\n>                 if (strObj.isDictionary()) {\n> @@ -161,27 +160,27 @@ protected:\n>                         return TestFail;\n>                 }\n>\n> -               if (strObj.get<string>(\"\", &ok) != \"libcamera\" || !ok) {\n> +               if (strObj.get<string>().value_or(\"\") != \"libcamera\") {\n>                         cerr << \"String object parse as wrong content\" <<\n> std::endl;\n>                         return TestFail;\n>                 }\n>\n> -               if (strObj.get<int32_t>(-1, &ok) != -1 || ok) {\n> +               if (strObj.get<int32_t>()) {\n>                         cerr << \"String object parse as integer\" <<\n> std::endl;\n>                         return TestFail;\n>                 }\n>\n> -               if (strObj.get<uint32_t>(1, &ok) != 1 || ok) {\n> +               if (strObj.get<uint32_t>()) {\n>                         cerr << \"String object parse as unsigned integer\"\n> << std::endl;\n>                         return TestFail;\n>                 }\n>\n> -               if (strObj.get<double>(1.0, &ok) != 1.0 || ok) {\n> +               if (strObj.get<double>()) {\n>                         cerr << \"String object parse as double\" <<\n> std::endl;\n>                         return TestFail;\n>                 }\n>\n> -               if (strObj.get<Size>(Size(0, 0), &ok) != Size(0, 0) || ok)\n> {\n> +               if (strObj.get<Size>()) {\n>                         cerr << \"String object parse as Size\" << std::endl;\n>                         return TestFail;\n>                 }\n> @@ -199,27 +198,27 @@ protected:\n>                         return TestFail;\n>                 }\n>\n> -               if (int32Obj.get<int32_t>(-100, &ok) != -100 || !ok) {\n> +               if (int32Obj.get<int32_t>().value_or(0) != -100) {\n>                         cerr << \"Integer object parse as wrong value\" <<\n> std::endl;\n>                         return TestFail;\n>                 }\n>\n> -               if (int32Obj.get<string>(\"\", &ok) != \"-100\" || !ok) {\n> +               if (int32Obj.get<string>().value_or(\"\") != \"-100\") {\n>                         cerr << \"Integer object fail to parse as string\"\n> << std::endl;\n>                         return TestFail;\n>                 }\n>\n> -               if (int32Obj.get<double>(1.0, &ok) != -100.0 || !ok) {\n> +               if (int32Obj.get<double>().value_or(0.0) != -100.0) {\n>                         cerr << \"Integer object fail to parse as double\"\n> << std::endl;\n>                         return TestFail;\n>                 }\n>\n> -               if (int32Obj.get<uint32_t>(1, &ok) != 1 || ok) {\n> +               if (int32Obj.get<uint32_t>()) {\n>                         cerr << \"Negative integer object parse as unsigned\n> integer\" << std::endl;\n>                         return TestFail;\n>                 }\n>\n> -               if (int32Obj.get<Size>(Size(0, 0), &ok) != Size(0, 0) ||\n> ok) {\n> +               if (int32Obj.get<Size>()) {\n>                         cerr << \"Integer object parse as Size\" <<\n> std::endl;\n>                         return TestFail;\n>                 }\n> @@ -237,27 +236,27 @@ protected:\n>                         return TestFail;\n>                 }\n>\n> -               if (uint32Obj.get<int32_t>(-1, &ok) != 100 || !ok) {\n> +               if (uint32Obj.get<int32_t>().value_or(0) != 100) {\n>                         cerr << \"Unsigned integer object fail to parse as\n> integer\" << std::endl;\n>                         return TestFail;\n>                 }\n>\n> -               if (uint32Obj.get<string>(\"\", &ok) != \"100\" || !ok) {\n> +               if (uint32Obj.get<string>().value_or(\"\") != \"100\") {\n>                         cerr << \"Unsigned integer object fail to parse as\n> string\" << std::endl;\n>                         return TestFail;\n>                 }\n>\n> -               if (uint32Obj.get<double>(1.0, &ok) != 100.0 || !ok) {\n> +               if (uint32Obj.get<double>().value_or(0.0) != 100.0) {\n>                         cerr << \"Unsigned integer object fail to parse as\n> double\" << std::endl;\n>                         return TestFail;\n>                 }\n>\n> -               if (uint32Obj.get<uint32_t>(100, &ok) != 100 || !ok) {\n> +               if (uint32Obj.get<uint32_t>().value_or(0) != 100) {\n>                         cerr << \"Unsigned integer object parsed as wrong\n> value\" << std::endl;\n>                         return TestFail;\n>                 }\n>\n> -               if (uint32Obj.get<Size>(Size(0, 0), &ok) != Size(0, 0) ||\n> ok) {\n> +               if (uint32Obj.get<Size>()) {\n>                         cerr << \"Unsigned integer object parsed as Size\"\n> << std::endl;\n>                         return TestFail;\n>                 }\n> @@ -275,27 +274,27 @@ protected:\n>                         return TestFail;\n>                 }\n>\n> -               if (doubleObj.get<string>(\"\", &ok) != \"3.14159\" || !ok) {\n> +               if (doubleObj.get<string>().value_or(\"\") != \"3.14159\") {\n>                         cerr << \"Double object fail to parse as string\" <<\n> std::endl;\n>                         return TestFail;\n>                 }\n>\n> -               if (doubleObj.get<double>(1.0, &ok) != 3.14159 || !ok) {\n> +               if (doubleObj.get<double>().value_or(0.0) != 3.14159) {\n>                         cerr << \"Double object parse as wrong value\" <<\n> std::endl;\n>                         return TestFail;\n>                 }\n>\n> -               if (doubleObj.get<int32_t>(-1, &ok) != -1 || ok) {\n> +               if (doubleObj.get<int32_t>()) {\n>                         cerr << \"Double object parse as integer\" <<\n> std::endl;\n>                         return TestFail;\n>                 }\n>\n> -               if (doubleObj.get<uint32_t>(1, &ok) != 1 || ok) {\n> +               if (doubleObj.get<uint32_t>()) {\n>                         cerr << \"Double object parse as unsigned integer\"\n> << std::endl;\n>                         return TestFail;\n>                 }\n>\n> -               if (doubleObj.get<Size>(Size(0, 0), &ok) != Size(0, 0) ||\n> ok) {\n> +               if (doubleObj.get<Size>()) {\n>                         cerr << \"Double object parse as Size\" << std::endl;\n>                         return TestFail;\n>                 }\n> @@ -313,27 +312,27 @@ protected:\n>                         return TestFail;\n>                 }\n>\n> -               if (sizeObj.get<string>(\"\", &ok) != \"\" || ok) {\n> +               if (sizeObj.get<string>()) {\n>                         cerr << \"Size object parse as string\" << std::endl;\n>                         return TestFail;\n>                 }\n>\n> -               if (sizeObj.get<double>(1.0, &ok) != 1.0 || ok) {\n> +               if (sizeObj.get<double>()) {\n>                         cerr << \"Size object parse as double\" << std::endl;\n>                         return TestFail;\n>                 }\n>\n> -               if (sizeObj.get<int32_t>(-1, &ok) != -1 || ok) {\n> +               if (sizeObj.get<int32_t>()) {\n>                         cerr << \"Size object parse as integer\" <<\n> std::endl;\n>                         return TestFail;\n>                 }\n>\n> -               if (sizeObj.get<uint32_t>(1, &ok) != 1 || ok) {\n> +               if (sizeObj.get<uint32_t>()) {\n>                         cerr << \"Size object parse as unsigned integer\" <<\n> std::endl;\n>                         return TestFail;\n>                 }\n>\n> -               if (sizeObj.get<Size>(Size(0, 0), &ok) != Size(1920, 1080)\n> || !ok) {\n> +               if (sizeObj.get<Size>().value_or(Size(0, 0)) != Size(1920,\n> 1080)) {\n>                         cerr << \"Size object parse as wrong value\" <<\n> std::endl;\n>                         return TestFail;\n>                 }\n> @@ -351,27 +350,27 @@ protected:\n>                         return TestFail;\n>                 }\n>\n> -               if (listObj.get<string>(\"\", &ok) != \"\" || ok) {\n> +               if (listObj.get<string>()) {\n>                         cerr << \"List object parse as string\" << std::endl;\n>                         return TestFail;\n>                 }\n>\n> -               if (listObj.get<double>(1.0, &ok) != 1.0 || ok) {\n> +               if (listObj.get<double>()) {\n>                         cerr << \"List object parse as double\" << std::endl;\n>                         return TestFail;\n>                 }\n>\n> -               if (listObj.get<int32_t>(-1, &ok) != -1 || ok) {\n> +               if (listObj.get<int32_t>()) {\n>                         cerr << \"List object parse as integer\" <<\n> std::endl;\n>                         return TestFail;\n>                 }\n>\n> -               if (listObj.get<uint32_t>(1, &ok) != 1 || ok) {\n> +               if (listObj.get<uint32_t>()) {\n>                         cerr << \"List object parse as unsigne integer\" <<\n> std::endl;\n>                         return TestFail;\n>                 }\n>\n> -               if (listObj.get<Size>(Size(0, 0), &ok) != Size(0, 0) ||\n> ok) {\n> +               if (listObj.get<Size>()) {\n>                         cerr << \"String list object parse as Size\" <<\n> std::endl;\n>                         return TestFail;\n>                 }\n> @@ -424,27 +423,27 @@ protected:\n>                         return TestFail;\n>                 }\n>\n> -               if (dictObj.get<string>(\"\", &ok) != \"\" || ok) {\n> +               if (dictObj.get<string>()) {\n>                         cerr << \"Dictionary object parse as string\" <<\n> std::endl;\n>                         return TestFail;\n>                 }\n>\n> -               if (dictObj.get<double>(1.0, &ok) != 1.0 || ok) {\n> +               if (dictObj.get<double>()) {\n>                         cerr << \"Dictionary object parse as double\" <<\n> std::endl;\n>                         return TestFail;\n>                 }\n>\n> -               if (dictObj.get<int32_t>(-1, &ok) != -1 || ok) {\n> +               if (dictObj.get<int32_t>()) {\n>                         cerr << \"Dictionary object parse as integer\" <<\n> std::endl;\n>                         return TestFail;\n>                 }\n>\n> -               if (dictObj.get<uint32_t>(1, &ok) != 1 || ok) {\n> +               if (dictObj.get<uint32_t>()) {\n>                         cerr << \"Dictionary object parse as unsigned\n> integer\" << std::endl;\n>                         return TestFail;\n>                 }\n>\n> -               if (dictObj.get<Size>(Size(0, 0), &ok) != Size(0, 0) ||\n> ok) {\n> +               if (dictObj.get<Size>()) {\n>                         cerr << \"Dictionary object parse as Size\" <<\n> std::endl;\n>                         return TestFail;\n>                 }\n> --\n> Regards,\n>\n> Laurent Pinchart\n>\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 3CBF6C3275\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed, 27 Jul 2022 09:35:11 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id A587563311;\n\tWed, 27 Jul 2022 11:35:10 +0200 (CEST)","from mail-lj1-x22f.google.com (mail-lj1-x22f.google.com\n\t[IPv6:2a00:1450:4864:20::22f])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 2416A603EC\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 27 Jul 2022 11:35:07 +0200 (CEST)","by mail-lj1-x22f.google.com with SMTP id u20so11383701ljk.0\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 27 Jul 2022 02:35:07 -0700 (PDT)"],"DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1658914510;\n\tbh=E0wGTiY4HK3019Qj2QqYdbnrOOpZK3lQXczYRbJBn+0=;\n\th=References:In-Reply-To:Date:To:Subject:List-Id:List-Unsubscribe:\n\tList-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc:\n\tFrom;\n\tb=pkSWWjDXfEUih6bJXpXyyldsaikufZalsLaojXbiSWVh8YJzkW/b21OO6tTdvBj5/\n\tsmnCtsuLgiqs2qFCN9wvgzfc5MGSvECRbynWJNcUyxCjS0kKn3Z8Kr072Ne24S+z+7\n\tWP25IVCLXG4LTnlH9um+U8z68IyBrq6j+rzGQvO+rXQEZu8lqnaN8CXw/IzKdMlvEg\n\tr0lfHevmHf831QuAIXp1rbgloeAibDZfppV6IpC+26H2oqUZpO7LkDS9hAkRKLpnuj\n\tBxCO6Cg7alx1U6e/20DUhpGjmCJHl3g55gKCsZbqgF4hwvsrf0A2SrJyfgDSQSBo+Y\n\t4IeK2O/F7FhSA==","v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=raspberrypi.com; s=google;\n\th=mime-version:references:in-reply-to:from:date:message-id:subject:to\n\t:cc; bh=M1jFgcAFimplrL67KAul4W48c2jAuZnbH2ZHzcrYTUE=;\n\tb=Fwmt6HjRGkuOa8xZyX+4NhQrk39p/k8M4RcVKiR2p6TU/C/MeepI44N/sGdtikdGeK\n\t2W3bQ9onrKU4z0+QCEKo15pXOpSf2BrXTEmwyMM+BfHPUi9h8W0YlBYFXEasUcTh0wRF\n\t4LWK+ylFb60k6u1kf35kAAO1CNR0ApI0Q8uJi9n5mgPsdfG1k2eMDAMNR6v+VUukhVWl\n\tzHASmqWmx2G3ewwasNAmKCi6l8nZHwyOJE3OViMlUnhnzboVVJ/tCKC5BoVlEpbn5SyY\n\t4eLNis+J6YrAVwJjbpsipuzZf2iquNTWArf5fkcDLd8sOcWcIB+Uh9fyT4PyOmuv3Jdt\n\tmu8w=="],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (2048-bit key; \n\tunprotected) header.d=raspberrypi.com\n\theader.i=@raspberrypi.com\n\theader.b=\"Fwmt6HjR\"; dkim-atps=neutral","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20210112;\n\th=x-gm-message-state:mime-version:references:in-reply-to:from:date\n\t:message-id:subject:to:cc;\n\tbh=M1jFgcAFimplrL67KAul4W48c2jAuZnbH2ZHzcrYTUE=;\n\tb=wuNyY9mv/1IZc352cUU4kqTYQLkpof37K1E4sBYDw2OprPgn6grGFZlVTlyKoMlS6f\n\tJkb1MgCZdy1zdNun/tFb3QNhQS3vEKEETzPXI7/HD5N33xf/g6X9XPDbw95IEdeVODav\n\tV6UbkQ0l5UtesuM3aKL8W9ysFLYD8TzNynb0gssJ8gZjBva1hcy+2YGVUBOsgm2BUEeX\n\tmrVZDzGqUkQBHr4hCAKEsxyt6bENqGUVZgIDDv2iK5ArAOI3kb2YG3SGcrDkIctTEuWL\n\tjseRt+LopmDyVTmmK8Pw83ysNtxEb/vhwvikx5hkfbINnd4FJYp1sLs8JeJvb9wbz4dK\n\tKSQw==","X-Gm-Message-State":"AJIora+mSOpuPr0GKgpDuj60LcAnLvGc98Mu4qZNqPyudE8oBdnppXMD\n\t4NT0lBDf2z12WzyCUpERK687i3050lOy8i6+AgtYZg==","X-Google-Smtp-Source":"AGRyM1tuVRQVVIWCLpdVbWlzFgS7CjAtXKpDOL8Lf5DF+QdxLFFX65YM6/Tb0Ew7u65urpdyp22bVYkFn5IQ6rlSnaM=","X-Received":"by 2002:a2e:9d95:0:b0:25d:f6ea:4447 with SMTP id\n\tc21-20020a2e9d95000000b0025df6ea4447mr7199527ljj.279.1658914506407;\n\tWed, 27 Jul 2022 02:35:06 -0700 (PDT)","MIME-Version":"1.0","References":"<20220727023816.30008-1-laurent.pinchart@ideasonboard.com>\n\t<20220727023816.30008-2-laurent.pinchart@ideasonboard.com>","In-Reply-To":"<20220727023816.30008-2-laurent.pinchart@ideasonboard.com>","Date":"Wed, 27 Jul 2022 10:34:50 +0100","Message-ID":"<CAEmqJPopfyn+rLWdqVuVA7LcBbEmHXEfLgnHHxps8nMw9g6jOA@mail.gmail.com>","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Content-Type":"multipart/alternative; boundary=\"000000000000de170705e4c621d5\"","Subject":"Re: [libcamera-devel] [PATCH v7 01/14] libcamera: yaml_parser:\n\tReplace ok flag to get() with std::optional","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>","From":"Naushir Patuck via libcamera-devel\n\t<libcamera-devel@lists.libcamera.org>","Reply-To":"Naushir Patuck <naush@raspberrypi.com>","Cc":"libcamera devel <libcamera-devel@lists.libcamera.org>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]