[{"id":32562,"web_url":"https://patchwork.libcamera.org/comment/32562/","msgid":"<20241206010932.GL21014@pendragon.ideasonboard.com>","date":"2024-12-06T01:09:32","subject":"Re: [PATCH v1 2/3] treewide: Use `YamlObject::find()`","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi Barnabás,\n\nThank you for the patch.\n\nOn Thu, Dec 05, 2024 at 04:34:19PM +0000, Barnabás Pőcze wrote:\n> Replace some uses of `contains()` + `operator[]` with `find()`.\n> Using `find()` avoids the double lookup, as well as does away with\n> the need for specifying the key twice.\n> \n> Signed-off-by: Barnabás Pőcze <pobrn@protonmail.com>\n> ---\n>  src/android/camera_hal_config.cpp          | 19 ++++----\n>  src/ipa/ipu3/ipu3.cpp                      |  5 +-\n>  src/ipa/rkisp1/algorithms/dpcc.cpp         | 56 +++++++++++-----------\n>  src/ipa/rkisp1/rkisp1.cpp                  |  5 +-\n>  src/ipa/rpi/controller/controller.cpp      |  5 +-\n>  src/ipa/rpi/controller/rpi/af.cpp          | 32 ++++++-------\n>  src/ipa/rpi/controller/rpi/agc.cpp         |  8 ++--\n>  src/ipa/rpi/controller/rpi/agc_channel.cpp |  4 +-\n>  src/ipa/rpi/controller/rpi/alsc.cpp        | 10 ++--\n>  src/ipa/rpi/controller/rpi/awb.cpp         | 12 ++---\n>  src/ipa/rpi/controller/rpi/ccm.cpp         |  4 +-\n>  src/ipa/rpi/controller/rpi/geq.cpp         |  4 +-\n>  src/ipa/rpi/controller/rpi/hdr.cpp         | 27 ++++++-----\n>  src/ipa/simple/soft_simple.cpp             |  5 +-\n>  14 files changed, 99 insertions(+), 97 deletions(-)\n> \n> diff --git a/src/android/camera_hal_config.cpp b/src/android/camera_hal_config.cpp\n> index 7ef451ef..6fde953d 100644\n> --- a/src/android/camera_hal_config.cpp\n> +++ b/src/android/camera_hal_config.cpp\n> @@ -73,15 +73,14 @@ int CameraHalConfig::Private::parseConfigFile(File &file,\n>  \t\treturn -EINVAL;\n>  \n>  \t/* Parse property \"cameras\" */\n> -\tif (!root->contains(\"cameras\"))\n> +\tauto *yamlObjectCameras = root->find(\"cameras\");\n\nI generally dislike overusing auto as it makes the code less explicit,\nand therefore less readable. There are valid use cases, for instance\nspelling out std::map<std::string, std::vector<std::pair<...>>>::iterator\nwould be inconvenient. Usage of auto in structured bindings is also\nuseful. In this specifif case, however, writing\n\n\tconst YamlObject *yamlObjectCameras = root->find(\"cameras\");\n\nisn't much longer, and I think it improves readability.\n\nSame below.\n\n> +\tif (!yamlObjectCameras)\n>  \t\treturn -EINVAL;\n>  \n> -\tconst YamlObject &yamlObjectCameras = (*root)[\"cameras\"];\n> -\n> -\tif (!yamlObjectCameras.isDictionary())\n> +\tif (!yamlObjectCameras->isDictionary())\n>  \t\treturn -EINVAL;\n>  \n> -\tfor (const auto &[cameraId, configData] : yamlObjectCameras.asDict()) {\n> +\tfor (const auto &[cameraId, configData] : yamlObjectCameras->asDict()) {\n>  \t\tif (parseCameraConfigData(cameraId, configData))\n>  \t\t\treturn -EINVAL;\n>  \t}\n> @@ -112,10 +111,11 @@ int CameraHalConfig::Private::parseCameraConfigData(const std::string &cameraId,\n>  int CameraHalConfig::Private::parseLocation(const YamlObject &cameraObject,\n>  \t\t\t\t\t    CameraConfigData &cameraConfigData)\n>  {\n> -\tif (!cameraObject.contains(\"location\"))\n> +\tauto *loc = cameraObject.find(\"location\");\n> +\tif (!loc)\n>  \t\treturn -EINVAL;\n>  \n> -\tstd::string location = cameraObject[\"location\"].get<std::string>(\"\");\n> +\tstd::string location = loc->get<std::string>(\"\");\n>  \n>  \tif (location == \"front\")\n>  \t\tcameraConfigData.facing = CAMERA_FACING_FRONT;\n> @@ -130,10 +130,11 @@ int CameraHalConfig::Private::parseLocation(const YamlObject &cameraObject,\n>  int CameraHalConfig::Private::parseRotation(const YamlObject &cameraObject,\n>  \t\t\t\t\t    CameraConfigData &cameraConfigData)\n>  {\n> -\tif (!cameraObject.contains(\"rotation\"))\n> +\tauto *rot = cameraObject.find(\"rotation\");\n> +\tif (!rot)\n>  \t\treturn -EINVAL;\n>  \n> -\tint32_t rotation = cameraObject[\"rotation\"].get<int32_t>(-1);\n> +\tint32_t rotation = rot->get<int32_t>(-1);\n>  \n>  \tif (rotation < 0 || rotation >= 360) {\n>  \t\tLOG(HALConfig, Error)\n> diff --git a/src/ipa/ipu3/ipu3.cpp b/src/ipa/ipu3/ipu3.cpp\n> index 44c98cbf..88b1bb81 100644\n> --- a/src/ipa/ipu3/ipu3.cpp\n> +++ b/src/ipa/ipu3/ipu3.cpp\n> @@ -335,13 +335,14 @@ int IPAIPU3::init(const IPASettings &settings,\n>  \t\treturn -EINVAL;\n>  \t}\n>  \n> -\tif (!data->contains(\"algorithms\")) {\n> +\tauto *algos = data->find(\"algorithms\");\n> +\tif (!algos) {\n>  \t\tLOG(IPAIPU3, Error)\n>  \t\t\t<< \"Tuning file doesn't contain any algorithm\";\n>  \t\treturn -EINVAL;\n>  \t}\n>  \n> -\tint ret = createAlgorithms(context_, (*data)[\"algorithms\"]);\n> +\tint ret = createAlgorithms(context_, *algos);\n>  \tif (ret)\n>  \t\treturn ret;\n>  \n> diff --git a/src/ipa/rkisp1/algorithms/dpcc.cpp b/src/ipa/rkisp1/algorithms/dpcc.cpp\n> index 78946281..8946c1a7 100644\n> --- a/src/ipa/rkisp1/algorithms/dpcc.cpp\n> +++ b/src/ipa/rkisp1/algorithms/dpcc.cpp\n> @@ -80,39 +80,39 @@ int DefectPixelClusterCorrection::init([[maybe_unused]] IPAContext &context,\n>  \t\t/* PG Method */\n>  \t\tconst YamlObject &pgObject = set[\"pg-factor\"];\n>  \n> -\t\tif (pgObject.contains(\"green\")) {\n> +\t\tif (auto *green = pgObject.find(\"green\")) {\n>  \t\t\tmethod.method |=\n>  \t\t\t\tRKISP1_CIF_ISP_DPCC_METHODS_SET_PG_GREEN_ENABLE;\n>  \n> -\t\t\tvalue = pgObject[\"green\"].get<uint16_t>(0);\n> +\t\t\tvalue = green->get<uint16_t>(0);\n>  \t\t\tmethod.pg_fac |= RKISP1_CIF_ISP_DPCC_PG_FAC_G(value);\n>  \t\t}\n>  \n> -\t\tif (pgObject.contains(\"red-blue\")) {\n> +\t\tif (auto *redBlue = pgObject.find(\"red-blue\")) {\n>  \t\t\tmethod.method |=\n>  \t\t\t\tRKISP1_CIF_ISP_DPCC_METHODS_SET_PG_RED_BLUE_ENABLE;\n>  \n> -\t\t\tvalue = pgObject[\"red-blue\"].get<uint16_t>(0);\n> +\t\t\tvalue = redBlue->get<uint16_t>(0);\n>  \t\t\tmethod.pg_fac |= RKISP1_CIF_ISP_DPCC_PG_FAC_RB(value);\n>  \t\t}\n>  \n>  \t\t/* RO Method */\n>  \t\tconst YamlObject &roObject = set[\"ro-limits\"];\n>  \n> -\t\tif (roObject.contains(\"green\")) {\n> +\t\tif (auto *green = roObject.find(\"green\")) {\n>  \t\t\tmethod.method |=\n>  \t\t\t\tRKISP1_CIF_ISP_DPCC_METHODS_SET_RO_GREEN_ENABLE;\n>  \n> -\t\t\tvalue = roObject[\"green\"].get<uint16_t>(0);\n> +\t\t\tvalue = green->get<uint16_t>(0);\n>  \t\t\tconfig_.ro_limits |=\n>  \t\t\t\tRKISP1_CIF_ISP_DPCC_RO_LIMITS_n_G(i, value);\n>  \t\t}\n>  \n> -\t\tif (roObject.contains(\"red-blue\")) {\n> +\t\tif (auto *redBlue = roObject.find(\"red-blue\")) {\n>  \t\t\tmethod.method |=\n>  \t\t\t\tRKISP1_CIF_ISP_DPCC_METHODS_SET_RO_RED_BLUE_ENABLE;\n>  \n> -\t\t\tvalue = roObject[\"red-blue\"].get<uint16_t>(0);\n> +\t\t\tvalue = redBlue->get<uint16_t>(0);\n>  \t\t\tconfig_.ro_limits |=\n>  \t\t\t\tRKISP1_CIF_ISP_DPCC_RO_LIMITS_n_RB(i, value);\n>  \t\t}\n> @@ -121,39 +121,39 @@ int DefectPixelClusterCorrection::init([[maybe_unused]] IPAContext &context,\n>  \t\tconst YamlObject &rgObject = set[\"rg-factor\"];\n>  \t\tmethod.rg_fac = 0;\n>  \n> -\t\tif (rgObject.contains(\"green\")) {\n> +\t\tif (auto *green = rgObject.find(\"green\")) {\n>  \t\t\tmethod.method |=\n>  \t\t\t\tRKISP1_CIF_ISP_DPCC_METHODS_SET_RG_GREEN_ENABLE;\n>  \n> -\t\t\tvalue = rgObject[\"green\"].get<uint16_t>(0);\n> +\t\t\tvalue = green->get<uint16_t>(0);\n>  \t\t\tmethod.rg_fac |= RKISP1_CIF_ISP_DPCC_RG_FAC_G(value);\n>  \t\t}\n>  \n> -\t\tif (rgObject.contains(\"red-blue\")) {\n> +\t\tif (auto *redBlue = rgObject.find(\"red-blue\")) {\n>  \t\t\tmethod.method |=\n>  \t\t\t\tRKISP1_CIF_ISP_DPCC_METHODS_SET_RG_RED_BLUE_ENABLE;\n>  \n> -\t\t\tvalue = rgObject[\"red-blue\"].get<uint16_t>(0);\n> +\t\t\tvalue = redBlue->get<uint16_t>(0);\n>  \t\t\tmethod.rg_fac |= RKISP1_CIF_ISP_DPCC_RG_FAC_RB(value);\n>  \t\t}\n>  \n>  \t\t/* RND Method */\n>  \t\tconst YamlObject &rndOffsetsObject = set[\"rnd-offsets\"];\n>  \n> -\t\tif (rndOffsetsObject.contains(\"green\")) {\n> +\t\tif (auto *green = rndOffsetsObject.find(\"green\")) {\n>  \t\t\tmethod.method |=\n>  \t\t\t\tRKISP1_CIF_ISP_DPCC_METHODS_SET_RND_GREEN_ENABLE;\n>  \n> -\t\t\tvalue = rndOffsetsObject[\"green\"].get<uint16_t>(0);\n> +\t\t\tvalue = green->get<uint16_t>(0);\n>  \t\t\tconfig_.rnd_offs |=\n>  \t\t\t\tRKISP1_CIF_ISP_DPCC_RND_OFFS_n_G(i, value);\n>  \t\t}\n>  \n> -\t\tif (rndOffsetsObject.contains(\"red-blue\")) {\n> +\t\tif (auto *redBlue = rndOffsetsObject.find(\"red-blue\")) {\n>  \t\t\tmethod.method |=\n>  \t\t\t\tRKISP1_CIF_ISP_DPCC_METHODS_SET_RND_RED_BLUE_ENABLE;\n>  \n> -\t\t\tvalue = rndOffsetsObject[\"red-blue\"].get<uint16_t>(0);\n> +\t\t\tvalue = redBlue->get<uint16_t>(0);\n>  \t\t\tconfig_.rnd_offs |=\n>  \t\t\t\tRKISP1_CIF_ISP_DPCC_RND_OFFS_n_RB(i, value);\n>  \t\t}\n> @@ -161,20 +161,20 @@ int DefectPixelClusterCorrection::init([[maybe_unused]] IPAContext &context,\n>  \t\tconst YamlObject &rndThresholdObject = set[\"rnd-threshold\"];\n>  \t\tmethod.rnd_thresh = 0;\n>  \n> -\t\tif (rndThresholdObject.contains(\"green\")) {\n> +\t\tif (auto *green = rndThresholdObject.find(\"green\")) {\n>  \t\t\tmethod.method |=\n>  \t\t\t\tRKISP1_CIF_ISP_DPCC_METHODS_SET_RND_GREEN_ENABLE;\n>  \n> -\t\t\tvalue = rndThresholdObject[\"green\"].get<uint16_t>(0);\n> +\t\t\tvalue = green->get<uint16_t>(0);\n>  \t\t\tmethod.rnd_thresh |=\n>  \t\t\t\tRKISP1_CIF_ISP_DPCC_RND_THRESH_G(value);\n>  \t\t}\n>  \n> -\t\tif (rndThresholdObject.contains(\"red-blue\")) {\n> +\t\tif (auto *redBlue = rndThresholdObject.find(\"red-blue\")) {\n>  \t\t\tmethod.method |=\n>  \t\t\t\tRKISP1_CIF_ISP_DPCC_METHODS_SET_RND_RED_BLUE_ENABLE;\n>  \n> -\t\t\tvalue = rndThresholdObject[\"red-blue\"].get<uint16_t>(0);\n> +\t\t\tvalue = redBlue->get<uint16_t>(0);\n>  \t\t\tmethod.rnd_thresh |=\n>  \t\t\t\tRKISP1_CIF_ISP_DPCC_RND_THRESH_RB(value);\n>  \t\t}\n> @@ -183,20 +183,20 @@ int DefectPixelClusterCorrection::init([[maybe_unused]] IPAContext &context,\n>  \t\tconst YamlObject &lcThresholdObject = set[\"line-threshold\"];\n>  \t\tmethod.line_thresh = 0;\n>  \n> -\t\tif (lcThresholdObject.contains(\"green\")) {\n> +\t\tif (auto *green = lcThresholdObject.find(\"green\")) {\n>  \t\t\tmethod.method |=\n>  \t\t\t\tRKISP1_CIF_ISP_DPCC_METHODS_SET_LC_GREEN_ENABLE;\n>  \n> -\t\t\tvalue = lcThresholdObject[\"green\"].get<uint16_t>(0);\n> +\t\t\tvalue = green->get<uint16_t>(0);\n>  \t\t\tmethod.line_thresh |=\n>  \t\t\t\tRKISP1_CIF_ISP_DPCC_LINE_THRESH_G(value);\n>  \t\t}\n>  \n> -\t\tif (lcThresholdObject.contains(\"red-blue\")) {\n> +\t\tif (auto *redBlue = lcThresholdObject.find(\"red-blue\")) {\n>  \t\t\tmethod.method |=\n>  \t\t\t\tRKISP1_CIF_ISP_DPCC_METHODS_SET_LC_RED_BLUE_ENABLE;\n>  \n> -\t\t\tvalue = lcThresholdObject[\"red-blue\"].get<uint16_t>(0);\n> +\t\t\tvalue = redBlue->get<uint16_t>(0);\n>  \t\t\tmethod.line_thresh |=\n>  \t\t\t\tRKISP1_CIF_ISP_DPCC_LINE_THRESH_RB(value);\n>  \t\t}\n> @@ -204,20 +204,20 @@ int DefectPixelClusterCorrection::init([[maybe_unused]] IPAContext &context,\n>  \t\tconst YamlObject &lcTMadFactorObject = set[\"line-mad-factor\"];\n>  \t\tmethod.line_mad_fac = 0;\n>  \n> -\t\tif (lcTMadFactorObject.contains(\"green\")) {\n> +\t\tif (auto *green = lcTMadFactorObject.find(\"green\")) {\n>  \t\t\tmethod.method |=\n>  \t\t\t\tRKISP1_CIF_ISP_DPCC_METHODS_SET_LC_GREEN_ENABLE;\n>  \n> -\t\t\tvalue = lcTMadFactorObject[\"green\"].get<uint16_t>(0);\n> +\t\t\tvalue = green->get<uint16_t>(0);\n>  \t\t\tmethod.line_mad_fac |=\n>  \t\t\t\tRKISP1_CIF_ISP_DPCC_LINE_MAD_FAC_G(value);\n>  \t\t}\n>  \n> -\t\tif (lcTMadFactorObject.contains(\"red-blue\")) {\n> +\t\tif (auto *redBlue = lcTMadFactorObject.find(\"red-blue\")) {\n>  \t\t\tmethod.method |=\n>  \t\t\t\tRKISP1_CIF_ISP_DPCC_METHODS_SET_LC_RED_BLUE_ENABLE;\n>  \n> -\t\t\tvalue = lcTMadFactorObject[\"red-blue\"].get<uint16_t>(0);\n> +\t\t\tvalue = redBlue->get<uint16_t>(0);\n>  \t\t\tmethod.line_mad_fac |=\n>  \t\t\t\tRKISP1_CIF_ISP_DPCC_LINE_MAD_FAC_RB(value);\n>  \t\t}\n> diff --git a/src/ipa/rkisp1/rkisp1.cpp b/src/ipa/rkisp1/rkisp1.cpp\n> index 2ffdd99b..202b53b7 100644\n> --- a/src/ipa/rkisp1/rkisp1.cpp\n> +++ b/src/ipa/rkisp1/rkisp1.cpp\n> @@ -193,13 +193,14 @@ int IPARkISP1::init(const IPASettings &settings, unsigned int hwRevision,\n>  \t\treturn -EINVAL;\n>  \t}\n>  \n> -\tif (!data->contains(\"algorithms\")) {\n> +\tauto *algos = data->find(\"algorithms\");\n> +\tif (!algos) {\n>  \t\tLOG(IPARkISP1, Error)\n>  \t\t\t<< \"Tuning file doesn't contain any algorithm\";\n>  \t\treturn -EINVAL;\n>  \t}\n>  \n> -\tint ret = createAlgorithms(context_, (*data)[\"algorithms\"]);\n> +\tint ret = createAlgorithms(context_, *algos);\n>  \tif (ret)\n>  \t\treturn ret;\n>  \n> diff --git a/src/ipa/rpi/controller/controller.cpp b/src/ipa/rpi/controller/controller.cpp\n> index e0131018..fbf31f23 100644\n> --- a/src/ipa/rpi/controller/controller.cpp\n> +++ b/src/ipa/rpi/controller/controller.cpp\n> @@ -109,14 +109,15 @@ int Controller::read(char const *filename)\n>  \t\t\t\treturn ret;\n>  \t\t}\n>  \t} else if (version < 3.0) {\n> -\t\tif (!root->contains(\"algorithms\")) {\n> +\t\tauto *algos = root->find(\"algorithms\");\n> +\t\tif (!algos) {\n>  \t\t\tLOG(RPiController, Error)\n>  \t\t\t\t<< \"Tuning file \" << filename\n>  \t\t\t\t<< \" does not have an \\\"algorithms\\\" list!\";\n>  \t\t\treturn -EINVAL;\n>  \t\t}\n>  \n> -\t\tfor (auto const &rootAlgo : (*root)[\"algorithms\"].asList())\n> +\t\tfor (auto const &rootAlgo : algos->asList())\n>  \t\t\tfor (auto const &[key, value] : rootAlgo.asDict()) {\n>  \t\t\t\tint ret = createAlgorithm(key, value);\n>  \t\t\t\tif (ret)\n> diff --git a/src/ipa/rpi/controller/rpi/af.cpp b/src/ipa/rpi/controller/rpi/af.cpp\n> index 2157eb94..c29bbaeb 100644\n> --- a/src/ipa/rpi/controller/rpi/af.cpp\n> +++ b/src/ipa/rpi/controller/rpi/af.cpp\n> @@ -97,39 +97,35 @@ void Af::SpeedDependentParams::read(const libcamera::YamlObject &params)\n>  \n>  int Af::CfgParams::read(const libcamera::YamlObject &params)\n>  {\n> -\tif (params.contains(\"ranges\")) {\n> -\t\tauto &rr = params[\"ranges\"];\n> -\n> -\t\tif (rr.contains(\"normal\"))\n> -\t\t\tranges[AfRangeNormal].read(rr[\"normal\"]);\n> +\tif (auto *rs = params.find(\"ranges\")) {\n\nI would have kept the same variable name (rr) but that doesn't matter\nmuch.\n\n> +\t\tif (auto *normal = rs->find(\"normal\"))\n> +\t\t\tranges[AfRangeNormal].read(*normal);\n>  \t\telse\n>  \t\t\tLOG(RPiAf, Warning) << \"Missing range \\\"normal\\\"\";\n>  \n>  \t\tranges[AfRangeMacro] = ranges[AfRangeNormal];\n> -\t\tif (rr.contains(\"macro\"))\n> -\t\t\tranges[AfRangeMacro].read(rr[\"macro\"]);\n> +\t\tif (auto *macro = rs->find(\"macro\"))\n> +\t\t\tranges[AfRangeMacro].read(*macro);\n>  \n>  \t\tranges[AfRangeFull].focusMin = std::min(ranges[AfRangeNormal].focusMin,\n>  \t\t\t\t\t\t\tranges[AfRangeMacro].focusMin);\n>  \t\tranges[AfRangeFull].focusMax = std::max(ranges[AfRangeNormal].focusMax,\n>  \t\t\t\t\t\t\tranges[AfRangeMacro].focusMax);\n>  \t\tranges[AfRangeFull].focusDefault = ranges[AfRangeNormal].focusDefault;\n> -\t\tif (rr.contains(\"full\"))\n> -\t\t\tranges[AfRangeFull].read(rr[\"full\"]);\n> +\t\tif (auto *full = rs->find(\"full\"))\n> +\t\t\tranges[AfRangeFull].read(*full);\n>  \t} else\n>  \t\tLOG(RPiAf, Warning) << \"No ranges defined\";\n>  \n> -\tif (params.contains(\"speeds\")) {\n> -\t\tauto &ss = params[\"speeds\"];\n> -\n> -\t\tif (ss.contains(\"normal\"))\n> -\t\t\tspeeds[AfSpeedNormal].read(ss[\"normal\"]);\n> +\tif (auto *ss = params.find(\"speeds\")) {\n> +\t\tif (auto *normal = ss->find(\"normal\"))\n> +\t\t\tspeeds[AfSpeedNormal].read(*normal);\n>  \t\telse\n>  \t\t\tLOG(RPiAf, Warning) << \"Missing speed \\\"normal\\\"\";\n>  \n>  \t\tspeeds[AfSpeedFast] = speeds[AfSpeedNormal];\n> -\t\tif (ss.contains(\"fast\"))\n> -\t\t\tspeeds[AfSpeedFast].read(ss[\"fast\"]);\n> +\t\tif (auto *fast = ss->find(\"fast\"))\n> +\t\t\tspeeds[AfSpeedFast].read(*fast);\n>  \t} else\n>  \t\tLOG(RPiAf, Warning) << \"No speeds defined\";\n>  \n> @@ -138,8 +134,8 @@ int Af::CfgParams::read(const libcamera::YamlObject &params)\n>  \treadNumber<uint32_t>(confClip, params, \"conf_clip\");\n>  \treadNumber<uint32_t>(skipFrames, params, \"skip_frames\");\n>  \n> -\tif (params.contains(\"map\"))\n> -\t\tmap = params[\"map\"].get<ipa::Pwl>(ipa::Pwl{});\n> +\tif (auto *m = params.find(\"map\"))\n> +\t\tmap = m->get<ipa::Pwl>(ipa::Pwl{});\n>  \telse\n>  \t\tLOG(RPiAf, Warning) << \"No map defined\";\n>  \n> diff --git a/src/ipa/rpi/controller/rpi/agc.cpp b/src/ipa/rpi/controller/rpi/agc.cpp\n> index c48fdf15..5d924ebf 100644\n> --- a/src/ipa/rpi/controller/rpi/agc.cpp\n> +++ b/src/ipa/rpi/controller/rpi/agc.cpp\n> @@ -37,18 +37,18 @@ int Agc::read(const libcamera::YamlObject &params)\n>  \t * When there is only a single channel we can read the old style syntax.\n>  \t * Otherwise we expect a \"channels\" keyword followed by a list of configurations.\n>  \t */\n> -\tif (!params.contains(\"channels\")) {\n> +\tauto *channels = params.find(\"channels\");\n> +\tif (!channels) {\n>  \t\tLOG(RPiAgc, Debug) << \"Single channel only\";\n>  \t\tchannelTotalExposures_.resize(1, 0s);\n>  \t\tchannelData_.emplace_back();\n>  \t\treturn channelData_.back().channel.read(params, getHardwareConfig());\n>  \t}\n>  \n> -\tconst auto &channels = params[\"channels\"].asList();\n> -\tfor (auto ch = channels.begin(); ch != channels.end(); ch++) {\n> +\tfor (const auto &ch : channels->asList()) {\n>  \t\tLOG(RPiAgc, Debug) << \"Read AGC channel\";\n>  \t\tchannelData_.emplace_back();\n> -\t\tint ret = channelData_.back().channel.read(*ch, getHardwareConfig());\n> +\t\tint ret = channelData_.back().channel.read(ch, getHardwareConfig());\n>  \t\tif (ret)\n>  \t\t\treturn ret;\n>  \t}\n> diff --git a/src/ipa/rpi/controller/rpi/agc_channel.cpp b/src/ipa/rpi/controller/rpi/agc_channel.cpp\n> index 79c45973..50b9efd2 100644\n> --- a/src/ipa/rpi/controller/rpi/agc_channel.cpp\n> +++ b/src/ipa/rpi/controller/rpi/agc_channel.cpp\n> @@ -235,8 +235,8 @@ int AgcConfig::read(const libcamera::YamlObject &params)\n>  \tif (ret)\n>  \t\treturn ret;\n>  \n> -\tif (params.contains(\"channel_constraints\")) {\n> -\t\tret = readChannelConstraints(channelConstraints, params[\"channel_constraints\"]);\n> +\tif (auto *cc = params.find(\"channel_constraints\")) {\n> +\t\tret = readChannelConstraints(channelConstraints, *cc);\n>  \t\tif (ret)\n>  \t\t\treturn ret;\n>  \t}\n> diff --git a/src/ipa/rpi/controller/rpi/alsc.cpp b/src/ipa/rpi/controller/rpi/alsc.cpp\n> index 21edb819..5a1a702b 100644\n> --- a/src/ipa/rpi/controller/rpi/alsc.cpp\n> +++ b/src/ipa/rpi/controller/rpi/alsc.cpp\n> @@ -104,9 +104,9 @@ static int readCalibrations(std::vector<AlscCalibration> &calibrations,\n>  \t\t\t    const libcamera::YamlObject &params,\n>  \t\t\t    std::string const &name, const Size &size)\n>  {\n> -\tif (params.contains(name)) {\n> +\tif (auto *param = params.find(name)) {\n>  \t\tdouble lastCt = 0;\n> -\t\tfor (const auto &p : params[name].asList()) {\n> +\t\tfor (const auto &p : param->asList()) {\n>  \t\t\tauto value = p[\"ct\"].get<double>();\n>  \t\t\tif (!value)\n>  \t\t\t\treturn -EINVAL;\n> @@ -163,10 +163,10 @@ int Alsc::read(const libcamera::YamlObject &params)\n>  \tconfig_.luminanceLut.resize(config_.tableSize, 1.0);\n>  \tint ret = 0;\n>  \n> -\tif (params.contains(\"corner_strength\"))\n> +\tif (params.find(\"corner_strength\"))\n>  \t\tret = generateLut(config_.luminanceLut, params);\n> -\telse if (params.contains(\"luminance_lut\"))\n> -\t\tret = readLut(config_.luminanceLut, params[\"luminance_lut\"]);\n> +\telse if (auto *ll = params.find(\"luminance_lut\"))\n> +\t\tret = readLut(config_.luminanceLut, *ll);\n>  \telse\n>  \t\tLOG(RPiAlsc, Warning)\n>  \t\t\t<< \"no luminance table - assume unity everywhere\";\n> diff --git a/src/ipa/rpi/controller/rpi/awb.cpp b/src/ipa/rpi/controller/rpi/awb.cpp\n> index c277a176..2e6e295c 100644\n> --- a/src/ipa/rpi/controller/rpi/awb.cpp\n> +++ b/src/ipa/rpi/controller/rpi/awb.cpp\n> @@ -102,8 +102,8 @@ int AwbConfig::read(const libcamera::YamlObject &params)\n>  \tconvergenceFrames = params[\"convergence_frames\"].get<unsigned int>(3);\n>  \tspeed = params[\"speed\"].get<double>(0.05);\n>  \n> -\tif (params.contains(\"ct_curve\")) {\n> -\t\tret = readCtCurve(ctR, ctB, params[\"ct_curve\"]);\n> +\tif (auto *ct_curve = params.find(\"ct_curve\")) {\n> +\t\tret = readCtCurve(ctR, ctB, *ct_curve);\n>  \t\tif (ret)\n>  \t\t\treturn ret;\n>  \t\t/* We will want the inverse functions of these too. */\n> @@ -111,8 +111,8 @@ int AwbConfig::read(const libcamera::YamlObject &params)\n>  \t\tctBInverse = ctB.inverse().first;\n>  \t}\n>  \n> -\tif (params.contains(\"priors\")) {\n> -\t\tfor (const auto &p : params[\"priors\"].asList()) {\n> +\tif (auto *ps = params.find(\"priors\")) {\n> +\t\tfor (const auto &p : ps->asList()) {\n>  \t\t\tAwbPrior prior;\n>  \t\t\tret = prior.read(p);\n>  \t\t\tif (ret)\n> @@ -128,8 +128,8 @@ int AwbConfig::read(const libcamera::YamlObject &params)\n>  \t\t\treturn -EINVAL;\n>  \t\t}\n>  \t}\n> -\tif (params.contains(\"modes\")) {\n> -\t\tfor (const auto &[key, value] : params[\"modes\"].asDict()) {\n> +\tif (auto *ms = params.find(\"modes\")) {\n> +\t\tfor (const auto &[key, value] : ms->asDict()) {\n>  \t\t\tret = modes[key].read(value);\n>  \t\t\tif (ret)\n>  \t\t\t\treturn ret;\n> diff --git a/src/ipa/rpi/controller/rpi/ccm.cpp b/src/ipa/rpi/controller/rpi/ccm.cpp\n> index 8607f152..5616e5f4 100644\n> --- a/src/ipa/rpi/controller/rpi/ccm.cpp\n> +++ b/src/ipa/rpi/controller/rpi/ccm.cpp\n> @@ -41,8 +41,8 @@ char const *Ccm::name() const\n>  \n>  int Ccm::read(const libcamera::YamlObject &params)\n>  {\n> -\tif (params.contains(\"saturation\")) {\n> -\t\tconfig_.saturation = params[\"saturation\"].get<ipa::Pwl>(ipa::Pwl{});\n> +\tif (auto *s = params.find(\"saturation\")) {\n> +\t\tconfig_.saturation = s->get<ipa::Pwl>(ipa::Pwl{});\n>  \t\tif (config_.saturation.empty())\n>  \t\t\treturn -EINVAL;\n>  \t}\n> diff --git a/src/ipa/rpi/controller/rpi/geq.cpp b/src/ipa/rpi/controller/rpi/geq.cpp\n> index 40e7191b..6935f726 100644\n> --- a/src/ipa/rpi/controller/rpi/geq.cpp\n> +++ b/src/ipa/rpi/controller/rpi/geq.cpp\n> @@ -43,8 +43,8 @@ int Geq::read(const libcamera::YamlObject &params)\n>  \t\treturn -EINVAL;\n>  \t}\n>  \n> -\tif (params.contains(\"strength\")) {\n> -\t\tconfig_.strength = params[\"strength\"].get<ipa::Pwl>(ipa::Pwl{});\n> +\tif (auto *strength = params.find(\"strength\")) {\n> +\t\tconfig_.strength = strength->get<ipa::Pwl>(ipa::Pwl{});\n>  \t\tif (config_.strength.empty())\n>  \t\t\treturn -EINVAL;\n>  \t}\n> diff --git a/src/ipa/rpi/controller/rpi/hdr.cpp b/src/ipa/rpi/controller/rpi/hdr.cpp\n> index f3da8291..20b1ff4b 100644\n> --- a/src/ipa/rpi/controller/rpi/hdr.cpp\n> +++ b/src/ipa/rpi/controller/rpi/hdr.cpp\n> @@ -27,9 +27,10 @@ void HdrConfig::read(const libcamera::YamlObject &params, const std::string &mod\n>  {\n>  \tname = modeName;\n>  \n> -\tif (!params.contains(\"cadence\"))\n> +\tauto *c = params.find(\"cadence\");\n> +\tif (!c)\n>  \t\tLOG(RPiHdr, Fatal) << \"No cadence for HDR mode \" << name;\n> -\tcadence = params[\"cadence\"].getList<unsigned int>().value();\n> +\tcadence = c->getList<unsigned int>().value();\n>  \tif (cadence.empty())\n>  \t\tLOG(RPiHdr, Fatal) << \"Empty cadence in HDR mode \" << name;\n>  \n> @@ -41,10 +42,10 @@ void HdrConfig::read(const libcamera::YamlObject &params, const std::string &mod\n>  \t\tchannelMap[v.get<unsigned int>().value()] = k;\n>  \n>  \t/* Lens shading related parameters. */\n> -\tif (params.contains(\"spatial_gain_curve\")) {\n> -\t\tspatialGainCurve = params[\"spatial_gain_curve\"].get<ipa::Pwl>(ipa::Pwl{});\n> -\t} else if (params.contains(\"spatial_gain\")) {\n> -\t\tdouble spatialGain = params[\"spatial_gain\"].get<double>(2.0);\n> +\tif (auto *sgc = params.find(\"spatial_gain_curve\")) {\n> +\t\tspatialGainCurve = sgc->get<ipa::Pwl>(ipa::Pwl{});\n> +\t} else if (auto *sg = params.find(\"spatial_gain\")) {\n> +\t\tdouble spatialGain = sg->get<double>(2.0);\n>  \t\tspatialGainCurve.append(0.0, spatialGain);\n>  \t\tspatialGainCurve.append(0.01, spatialGain);\n>  \t\tspatialGainCurve.append(0.06, 1.0); /* maybe make this programmable? */\n> @@ -68,24 +69,24 @@ void HdrConfig::read(const libcamera::YamlObject &params, const std::string &mod\n>  \tif (tonemapEnable)\n>  \t\ttonemap = params[\"tonemap\"].get<ipa::Pwl>(ipa::Pwl{});\n>  \tspeed = params[\"speed\"].get<double>(1.0);\n> -\tif (params.contains(\"hi_quantile_targets\")) {\n> -\t\thiQuantileTargets = params[\"hi_quantile_targets\"].getList<double>().value();\n> +\tif (auto *hqt = params.find(\"hi_quantile_targets\")) {\n> +\t\thiQuantileTargets = hqt->getList<double>().value();\n>  \t\tif (hiQuantileTargets.empty() || hiQuantileTargets.size() % 2)\n>  \t\t\tLOG(RPiHdr, Fatal) << \"hi_quantile_targets much be even and non-empty\";\n>  \t} else\n>  \t\thiQuantileTargets = { 0.95, 0.65, 0.5, 0.28, 0.3, 0.25 };\n>  \thiQuantileMaxGain = params[\"hi_quantile_max_gain\"].get<double>(1.6);\n> -\tif (params.contains(\"quantile_targets\")) {\n> -\t\tquantileTargets = params[\"quantile_targets\"].getList<double>().value();\n> +\tif (auto *qt = params.find(\"quantile_targets\")) {\n> +\t\tquantileTargets = qt->getList<double>().value();\n>  \t\tif (quantileTargets.empty() || quantileTargets.size() % 2)\n>  \t\t\tLOG(RPiHdr, Fatal) << \"quantile_targets much be even and non-empty\";\n>  \t} else\n>  \t\tquantileTargets = { 0.2, 0.03, 1.0, 0.15 };\n>  \tpowerMin = params[\"power_min\"].get<double>(0.65);\n>  \tpowerMax = params[\"power_max\"].get<double>(1.0);\n> -\tif (params.contains(\"contrast_adjustments\")) {\n> -\t\tcontrastAdjustments = params[\"contrast_adjustments\"].getList<double>().value();\n> -\t} else\n> +\tif (auto *ca = params.find(\"contrast_adjustments\"))\n> +\t\tcontrastAdjustments = ca->getList<double>().value();\n> +\telse\n>  \t\tcontrastAdjustments = { 0.5, 0.75 };\n>  \n>  \t/* Read any stitch parameters. */\n> diff --git a/src/ipa/simple/soft_simple.cpp b/src/ipa/simple/soft_simple.cpp\n> index e1b6d3af..ca3fe487 100644\n> --- a/src/ipa/simple/soft_simple.cpp\n> +++ b/src/ipa/simple/soft_simple.cpp\n> @@ -114,12 +114,13 @@ int IPASoftSimple::init(const IPASettings &settings,\n>  \tunsigned int version = (*data)[\"version\"].get<uint32_t>(0);\n>  \tLOG(IPASoft, Debug) << \"Tuning file version \" << version;\n>  \n> -\tif (!data->contains(\"algorithms\")) {\n> +\tauto *algos = data->find(\"algorithms\");\n> +\tif (!algos) {\n>  \t\tLOG(IPASoft, Error) << \"Tuning file doesn't contain algorithms\";\n>  \t\treturn -EINVAL;\n>  \t}\n>  \n> -\tint ret = createAlgorithms(context_, (*data)[\"algorithms\"]);\n> +\tint ret = createAlgorithms(context_, *algos);\n>  \tif (ret)\n>  \t\treturn ret;\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 D618ABF415\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri,  6 Dec 2024 01:09:47 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 2E7F166121;\n\tFri,  6 Dec 2024 02:09:47 +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 7D8C2660C8\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri,  6 Dec 2024 02:09:45 +0100 (CET)","from pendragon.ideasonboard.com (81-175-209-231.bb.dnainternet.fi\n\t[81.175.209.231])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 1F15C641;\n\tFri,  6 Dec 2024 02:09:16 +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=\"oRKxoIaa\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1733447356;\n\tbh=IaN+oVRp4OLD2dMkeJC6VhZH6h6PV23fUjp6YMoPRaU=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=oRKxoIaaUd0BHqLp8VUfpepOu9/gcvsHkfzuYePHrgFZMUWX67rQn+uPXVkxIawD5\n\tMFoHH42Sv4eYto9pc/CAtycgOlXLEfPDu9Nupsp/RIqgdNFwxKVaSuXNnfP9a1PAEr\n\tbA7zWXWcay5syf1cEso6662A4tKQd+HhGnDn3ecc=","Date":"Fri, 6 Dec 2024 03:09:32 +0200","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"=?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= <pobrn@protonmail.com>","Cc":"libcamera-devel@lists.libcamera.org","Subject":"Re: [PATCH v1 2/3] treewide: Use `YamlObject::find()`","Message-ID":"<20241206010932.GL21014@pendragon.ideasonboard.com>","References":"<20241205163411.1160094-1-pobrn@protonmail.com>\n\t<20241205163411.1160094-2-pobrn@protonmail.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","Content-Transfer-Encoding":"8bit","In-Reply-To":"<20241205163411.1160094-2-pobrn@protonmail.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":32640,"web_url":"https://patchwork.libcamera.org/comment/32640/","msgid":"<Ef3UXUsEIxddqbie9PI1tW0qmU2ik-QuS7dUq4de81TptTe_dBh8pUGRtykZVEloMA-i0O8wHZ81pLfQNrgJ7_r3MFNJryV3Zz1uLqaTv64=@protonmail.com>","date":"2024-12-09T17:56:57","subject":"Re: [PATCH v1 2/3] treewide: Use `YamlObject::find()`","submitter":{"id":133,"url":"https://patchwork.libcamera.org/api/people/133/","name":"Pőcze Barnabás","email":"pobrn@protonmail.com"},"content":"Hi\n\n\n2024. december 6., péntek 2:09 keltezéssel, Laurent Pinchart <laurent.pinchart@ideasonboard.com> írta:\n\n> Hi Barnabás,\n> \n> Thank you for the patch.\n> \n> On Thu, Dec 05, 2024 at 04:34:19PM +0000, Barnabás Pőcze wrote:\n> > Replace some uses of `contains()` + `operator[]` with `find()`.\n> > Using `find()` avoids the double lookup, as well as does away with\n> > the need for specifying the key twice.\n> >\n> > Signed-off-by: Barnabás Pőcze <pobrn@protonmail.com>\n> > ---\n> >  src/android/camera_hal_config.cpp          | 19 ++++----\n> >  src/ipa/ipu3/ipu3.cpp                      |  5 +-\n> >  src/ipa/rkisp1/algorithms/dpcc.cpp         | 56 +++++++++++-----------\n> >  src/ipa/rkisp1/rkisp1.cpp                  |  5 +-\n> >  src/ipa/rpi/controller/controller.cpp      |  5 +-\n> >  src/ipa/rpi/controller/rpi/af.cpp          | 32 ++++++-------\n> >  src/ipa/rpi/controller/rpi/agc.cpp         |  8 ++--\n> >  src/ipa/rpi/controller/rpi/agc_channel.cpp |  4 +-\n> >  src/ipa/rpi/controller/rpi/alsc.cpp        | 10 ++--\n> >  src/ipa/rpi/controller/rpi/awb.cpp         | 12 ++---\n> >  src/ipa/rpi/controller/rpi/ccm.cpp         |  4 +-\n> >  src/ipa/rpi/controller/rpi/geq.cpp         |  4 +-\n> >  src/ipa/rpi/controller/rpi/hdr.cpp         | 27 ++++++-----\n> >  src/ipa/simple/soft_simple.cpp             |  5 +-\n> >  14 files changed, 99 insertions(+), 97 deletions(-)\n> >\n> > diff --git a/src/android/camera_hal_config.cpp b/src/android/camera_hal_config.cpp\n> > index 7ef451ef..6fde953d 100644\n> > --- a/src/android/camera_hal_config.cpp\n> > +++ b/src/android/camera_hal_config.cpp\n> > @@ -73,15 +73,14 @@ int CameraHalConfig::Private::parseConfigFile(File &file,\n> >  \t\treturn -EINVAL;\n> >\n> >  \t/* Parse property \"cameras\" */\n> > -\tif (!root->contains(\"cameras\"))\n> > +\tauto *yamlObjectCameras = root->find(\"cameras\");\n> \n> I generally dislike overusing auto as it makes the code less explicit,\n> and therefore less readable. There are valid use cases, for instance\n> spelling out std::map<std::string, std::vector<std::pair<...>>>::iterator\n> would be inconvenient. Usage of auto in structured bindings is also\n> useful. In this specifif case, however, writing\n> \n> \tconst YamlObject *yamlObjectCameras = root->find(\"cameras\");\n> \n> isn't much longer, and I think it improves readability.\n> \n> Same below.\n\nSo you would specify the explicit type everywhere this change touches?\nEven in the controlling expression of `if` statements?\n\n\nRegards,\nBarnabás Pőcze\n\n> \n> > +\tif (!yamlObjectCameras)\n> >  \t\treturn -EINVAL;\n> >\n> > -\tconst YamlObject &yamlObjectCameras = (*root)[\"cameras\"];\n> > -\n> > -\tif (!yamlObjectCameras.isDictionary())\n> > +\tif (!yamlObjectCameras->isDictionary())\n> >  \t\treturn -EINVAL;\n> >\n> > -\tfor (const auto &[cameraId, configData] : yamlObjectCameras.asDict()) {\n> > +\tfor (const auto &[cameraId, configData] : yamlObjectCameras->asDict()) {\n> >  \t\tif (parseCameraConfigData(cameraId, configData))\n> >  \t\t\treturn -EINVAL;\n> >  \t}\n> > @@ -112,10 +111,11 @@ int CameraHalConfig::Private::parseCameraConfigData(const std::string &cameraId,\n> >  int CameraHalConfig::Private::parseLocation(const YamlObject &cameraObject,\n> >  \t\t\t\t\t    CameraConfigData &cameraConfigData)\n> >  {\n> > -\tif (!cameraObject.contains(\"location\"))\n> > +\tauto *loc = cameraObject.find(\"location\");\n> > +\tif (!loc)\n> >  \t\treturn -EINVAL;\n> >\n> > -\tstd::string location = cameraObject[\"location\"].get<std::string>(\"\");\n> > +\tstd::string location = loc->get<std::string>(\"\");\n> >\n> >  \tif (location == \"front\")\n> >  \t\tcameraConfigData.facing = CAMERA_FACING_FRONT;\n> > @@ -130,10 +130,11 @@ int CameraHalConfig::Private::parseLocation(const YamlObject &cameraObject,\n> >  int CameraHalConfig::Private::parseRotation(const YamlObject &cameraObject,\n> >  \t\t\t\t\t    CameraConfigData &cameraConfigData)\n> >  {\n> > -\tif (!cameraObject.contains(\"rotation\"))\n> > +\tauto *rot = cameraObject.find(\"rotation\");\n> > +\tif (!rot)\n> >  \t\treturn -EINVAL;\n> >\n> > -\tint32_t rotation = cameraObject[\"rotation\"].get<int32_t>(-1);\n> > +\tint32_t rotation = rot->get<int32_t>(-1);\n> >\n> >  \tif (rotation < 0 || rotation >= 360) {\n> >  \t\tLOG(HALConfig, Error)\n> > diff --git a/src/ipa/ipu3/ipu3.cpp b/src/ipa/ipu3/ipu3.cpp\n> > index 44c98cbf..88b1bb81 100644\n> > --- a/src/ipa/ipu3/ipu3.cpp\n> > +++ b/src/ipa/ipu3/ipu3.cpp\n> > @@ -335,13 +335,14 @@ int IPAIPU3::init(const IPASettings &settings,\n> >  \t\treturn -EINVAL;\n> >  \t}\n> >\n> > -\tif (!data->contains(\"algorithms\")) {\n> > +\tauto *algos = data->find(\"algorithms\");\n> > +\tif (!algos) {\n> >  \t\tLOG(IPAIPU3, Error)\n> >  \t\t\t<< \"Tuning file doesn't contain any algorithm\";\n> >  \t\treturn -EINVAL;\n> >  \t}\n> >\n> > -\tint ret = createAlgorithms(context_, (*data)[\"algorithms\"]);\n> > +\tint ret = createAlgorithms(context_, *algos);\n> >  \tif (ret)\n> >  \t\treturn ret;\n> >\n> > diff --git a/src/ipa/rkisp1/algorithms/dpcc.cpp b/src/ipa/rkisp1/algorithms/dpcc.cpp\n> > index 78946281..8946c1a7 100644\n> > --- a/src/ipa/rkisp1/algorithms/dpcc.cpp\n> > +++ b/src/ipa/rkisp1/algorithms/dpcc.cpp\n> > @@ -80,39 +80,39 @@ int DefectPixelClusterCorrection::init([[maybe_unused]] IPAContext &context,\n> >  \t\t/* PG Method */\n> >  \t\tconst YamlObject &pgObject = set[\"pg-factor\"];\n> >\n> > -\t\tif (pgObject.contains(\"green\")) {\n> > +\t\tif (auto *green = pgObject.find(\"green\")) {\n> >  \t\t\tmethod.method |=\n> >  \t\t\t\tRKISP1_CIF_ISP_DPCC_METHODS_SET_PG_GREEN_ENABLE;\n> >\n> > -\t\t\tvalue = pgObject[\"green\"].get<uint16_t>(0);\n> > +\t\t\tvalue = green->get<uint16_t>(0);\n> >  \t\t\tmethod.pg_fac |= RKISP1_CIF_ISP_DPCC_PG_FAC_G(value);\n> >  \t\t}\n> >\n> > -\t\tif (pgObject.contains(\"red-blue\")) {\n> > +\t\tif (auto *redBlue = pgObject.find(\"red-blue\")) {\n> >  \t\t\tmethod.method |=\n> >  \t\t\t\tRKISP1_CIF_ISP_DPCC_METHODS_SET_PG_RED_BLUE_ENABLE;\n> >\n> > -\t\t\tvalue = pgObject[\"red-blue\"].get<uint16_t>(0);\n> > +\t\t\tvalue = redBlue->get<uint16_t>(0);\n> >  \t\t\tmethod.pg_fac |= RKISP1_CIF_ISP_DPCC_PG_FAC_RB(value);\n> >  \t\t}\n> >\n> >  \t\t/* RO Method */\n> >  \t\tconst YamlObject &roObject = set[\"ro-limits\"];\n> >\n> > -\t\tif (roObject.contains(\"green\")) {\n> > +\t\tif (auto *green = roObject.find(\"green\")) {\n> >  \t\t\tmethod.method |=\n> >  \t\t\t\tRKISP1_CIF_ISP_DPCC_METHODS_SET_RO_GREEN_ENABLE;\n> >\n> > -\t\t\tvalue = roObject[\"green\"].get<uint16_t>(0);\n> > +\t\t\tvalue = green->get<uint16_t>(0);\n> >  \t\t\tconfig_.ro_limits |=\n> >  \t\t\t\tRKISP1_CIF_ISP_DPCC_RO_LIMITS_n_G(i, value);\n> >  \t\t}\n> >\n> > -\t\tif (roObject.contains(\"red-blue\")) {\n> > +\t\tif (auto *redBlue = roObject.find(\"red-blue\")) {\n> >  \t\t\tmethod.method |=\n> >  \t\t\t\tRKISP1_CIF_ISP_DPCC_METHODS_SET_RO_RED_BLUE_ENABLE;\n> >\n> > -\t\t\tvalue = roObject[\"red-blue\"].get<uint16_t>(0);\n> > +\t\t\tvalue = redBlue->get<uint16_t>(0);\n> >  \t\t\tconfig_.ro_limits |=\n> >  \t\t\t\tRKISP1_CIF_ISP_DPCC_RO_LIMITS_n_RB(i, value);\n> >  \t\t}\n> > @@ -121,39 +121,39 @@ int DefectPixelClusterCorrection::init([[maybe_unused]] IPAContext &context,\n> >  \t\tconst YamlObject &rgObject = set[\"rg-factor\"];\n> >  \t\tmethod.rg_fac = 0;\n> >\n> > -\t\tif (rgObject.contains(\"green\")) {\n> > +\t\tif (auto *green = rgObject.find(\"green\")) {\n> >  \t\t\tmethod.method |=\n> >  \t\t\t\tRKISP1_CIF_ISP_DPCC_METHODS_SET_RG_GREEN_ENABLE;\n> >\n> > -\t\t\tvalue = rgObject[\"green\"].get<uint16_t>(0);\n> > +\t\t\tvalue = green->get<uint16_t>(0);\n> >  \t\t\tmethod.rg_fac |= RKISP1_CIF_ISP_DPCC_RG_FAC_G(value);\n> >  \t\t}\n> >\n> > -\t\tif (rgObject.contains(\"red-blue\")) {\n> > +\t\tif (auto *redBlue = rgObject.find(\"red-blue\")) {\n> >  \t\t\tmethod.method |=\n> >  \t\t\t\tRKISP1_CIF_ISP_DPCC_METHODS_SET_RG_RED_BLUE_ENABLE;\n> >\n> > -\t\t\tvalue = rgObject[\"red-blue\"].get<uint16_t>(0);\n> > +\t\t\tvalue = redBlue->get<uint16_t>(0);\n> >  \t\t\tmethod.rg_fac |= RKISP1_CIF_ISP_DPCC_RG_FAC_RB(value);\n> >  \t\t}\n> >\n> >  \t\t/* RND Method */\n> >  \t\tconst YamlObject &rndOffsetsObject = set[\"rnd-offsets\"];\n> >\n> > -\t\tif (rndOffsetsObject.contains(\"green\")) {\n> > +\t\tif (auto *green = rndOffsetsObject.find(\"green\")) {\n> >  \t\t\tmethod.method |=\n> >  \t\t\t\tRKISP1_CIF_ISP_DPCC_METHODS_SET_RND_GREEN_ENABLE;\n> >\n> > -\t\t\tvalue = rndOffsetsObject[\"green\"].get<uint16_t>(0);\n> > +\t\t\tvalue = green->get<uint16_t>(0);\n> >  \t\t\tconfig_.rnd_offs |=\n> >  \t\t\t\tRKISP1_CIF_ISP_DPCC_RND_OFFS_n_G(i, value);\n> >  \t\t}\n> >\n> > -\t\tif (rndOffsetsObject.contains(\"red-blue\")) {\n> > +\t\tif (auto *redBlue = rndOffsetsObject.find(\"red-blue\")) {\n> >  \t\t\tmethod.method |=\n> >  \t\t\t\tRKISP1_CIF_ISP_DPCC_METHODS_SET_RND_RED_BLUE_ENABLE;\n> >\n> > -\t\t\tvalue = rndOffsetsObject[\"red-blue\"].get<uint16_t>(0);\n> > +\t\t\tvalue = redBlue->get<uint16_t>(0);\n> >  \t\t\tconfig_.rnd_offs |=\n> >  \t\t\t\tRKISP1_CIF_ISP_DPCC_RND_OFFS_n_RB(i, value);\n> >  \t\t}\n> > @@ -161,20 +161,20 @@ int DefectPixelClusterCorrection::init([[maybe_unused]] IPAContext &context,\n> >  \t\tconst YamlObject &rndThresholdObject = set[\"rnd-threshold\"];\n> >  \t\tmethod.rnd_thresh = 0;\n> >\n> > -\t\tif (rndThresholdObject.contains(\"green\")) {\n> > +\t\tif (auto *green = rndThresholdObject.find(\"green\")) {\n> >  \t\t\tmethod.method |=\n> >  \t\t\t\tRKISP1_CIF_ISP_DPCC_METHODS_SET_RND_GREEN_ENABLE;\n> >\n> > -\t\t\tvalue = rndThresholdObject[\"green\"].get<uint16_t>(0);\n> > +\t\t\tvalue = green->get<uint16_t>(0);\n> >  \t\t\tmethod.rnd_thresh |=\n> >  \t\t\t\tRKISP1_CIF_ISP_DPCC_RND_THRESH_G(value);\n> >  \t\t}\n> >\n> > -\t\tif (rndThresholdObject.contains(\"red-blue\")) {\n> > +\t\tif (auto *redBlue = rndThresholdObject.find(\"red-blue\")) {\n> >  \t\t\tmethod.method |=\n> >  \t\t\t\tRKISP1_CIF_ISP_DPCC_METHODS_SET_RND_RED_BLUE_ENABLE;\n> >\n> > -\t\t\tvalue = rndThresholdObject[\"red-blue\"].get<uint16_t>(0);\n> > +\t\t\tvalue = redBlue->get<uint16_t>(0);\n> >  \t\t\tmethod.rnd_thresh |=\n> >  \t\t\t\tRKISP1_CIF_ISP_DPCC_RND_THRESH_RB(value);\n> >  \t\t}\n> > @@ -183,20 +183,20 @@ int DefectPixelClusterCorrection::init([[maybe_unused]] IPAContext &context,\n> >  \t\tconst YamlObject &lcThresholdObject = set[\"line-threshold\"];\n> >  \t\tmethod.line_thresh = 0;\n> >\n> > -\t\tif (lcThresholdObject.contains(\"green\")) {\n> > +\t\tif (auto *green = lcThresholdObject.find(\"green\")) {\n> >  \t\t\tmethod.method |=\n> >  \t\t\t\tRKISP1_CIF_ISP_DPCC_METHODS_SET_LC_GREEN_ENABLE;\n> >\n> > -\t\t\tvalue = lcThresholdObject[\"green\"].get<uint16_t>(0);\n> > +\t\t\tvalue = green->get<uint16_t>(0);\n> >  \t\t\tmethod.line_thresh |=\n> >  \t\t\t\tRKISP1_CIF_ISP_DPCC_LINE_THRESH_G(value);\n> >  \t\t}\n> >\n> > -\t\tif (lcThresholdObject.contains(\"red-blue\")) {\n> > +\t\tif (auto *redBlue = lcThresholdObject.find(\"red-blue\")) {\n> >  \t\t\tmethod.method |=\n> >  \t\t\t\tRKISP1_CIF_ISP_DPCC_METHODS_SET_LC_RED_BLUE_ENABLE;\n> >\n> > -\t\t\tvalue = lcThresholdObject[\"red-blue\"].get<uint16_t>(0);\n> > +\t\t\tvalue = redBlue->get<uint16_t>(0);\n> >  \t\t\tmethod.line_thresh |=\n> >  \t\t\t\tRKISP1_CIF_ISP_DPCC_LINE_THRESH_RB(value);\n> >  \t\t}\n> > @@ -204,20 +204,20 @@ int DefectPixelClusterCorrection::init([[maybe_unused]] IPAContext &context,\n> >  \t\tconst YamlObject &lcTMadFactorObject = set[\"line-mad-factor\"];\n> >  \t\tmethod.line_mad_fac = 0;\n> >\n> > -\t\tif (lcTMadFactorObject.contains(\"green\")) {\n> > +\t\tif (auto *green = lcTMadFactorObject.find(\"green\")) {\n> >  \t\t\tmethod.method |=\n> >  \t\t\t\tRKISP1_CIF_ISP_DPCC_METHODS_SET_LC_GREEN_ENABLE;\n> >\n> > -\t\t\tvalue = lcTMadFactorObject[\"green\"].get<uint16_t>(0);\n> > +\t\t\tvalue = green->get<uint16_t>(0);\n> >  \t\t\tmethod.line_mad_fac |=\n> >  \t\t\t\tRKISP1_CIF_ISP_DPCC_LINE_MAD_FAC_G(value);\n> >  \t\t}\n> >\n> > -\t\tif (lcTMadFactorObject.contains(\"red-blue\")) {\n> > +\t\tif (auto *redBlue = lcTMadFactorObject.find(\"red-blue\")) {\n> >  \t\t\tmethod.method |=\n> >  \t\t\t\tRKISP1_CIF_ISP_DPCC_METHODS_SET_LC_RED_BLUE_ENABLE;\n> >\n> > -\t\t\tvalue = lcTMadFactorObject[\"red-blue\"].get<uint16_t>(0);\n> > +\t\t\tvalue = redBlue->get<uint16_t>(0);\n> >  \t\t\tmethod.line_mad_fac |=\n> >  \t\t\t\tRKISP1_CIF_ISP_DPCC_LINE_MAD_FAC_RB(value);\n> >  \t\t}\n> > diff --git a/src/ipa/rkisp1/rkisp1.cpp b/src/ipa/rkisp1/rkisp1.cpp\n> > index 2ffdd99b..202b53b7 100644\n> > --- a/src/ipa/rkisp1/rkisp1.cpp\n> > +++ b/src/ipa/rkisp1/rkisp1.cpp\n> > @@ -193,13 +193,14 @@ int IPARkISP1::init(const IPASettings &settings, unsigned int hwRevision,\n> >  \t\treturn -EINVAL;\n> >  \t}\n> >\n> > -\tif (!data->contains(\"algorithms\")) {\n> > +\tauto *algos = data->find(\"algorithms\");\n> > +\tif (!algos) {\n> >  \t\tLOG(IPARkISP1, Error)\n> >  \t\t\t<< \"Tuning file doesn't contain any algorithm\";\n> >  \t\treturn -EINVAL;\n> >  \t}\n> >\n> > -\tint ret = createAlgorithms(context_, (*data)[\"algorithms\"]);\n> > +\tint ret = createAlgorithms(context_, *algos);\n> >  \tif (ret)\n> >  \t\treturn ret;\n> >\n> > diff --git a/src/ipa/rpi/controller/controller.cpp b/src/ipa/rpi/controller/controller.cpp\n> > index e0131018..fbf31f23 100644\n> > --- a/src/ipa/rpi/controller/controller.cpp\n> > +++ b/src/ipa/rpi/controller/controller.cpp\n> > @@ -109,14 +109,15 @@ int Controller::read(char const *filename)\n> >  \t\t\t\treturn ret;\n> >  \t\t}\n> >  \t} else if (version < 3.0) {\n> > -\t\tif (!root->contains(\"algorithms\")) {\n> > +\t\tauto *algos = root->find(\"algorithms\");\n> > +\t\tif (!algos) {\n> >  \t\t\tLOG(RPiController, Error)\n> >  \t\t\t\t<< \"Tuning file \" << filename\n> >  \t\t\t\t<< \" does not have an \\\"algorithms\\\" list!\";\n> >  \t\t\treturn -EINVAL;\n> >  \t\t}\n> >\n> > -\t\tfor (auto const &rootAlgo : (*root)[\"algorithms\"].asList())\n> > +\t\tfor (auto const &rootAlgo : algos->asList())\n> >  \t\t\tfor (auto const &[key, value] : rootAlgo.asDict()) {\n> >  \t\t\t\tint ret = createAlgorithm(key, value);\n> >  \t\t\t\tif (ret)\n> > diff --git a/src/ipa/rpi/controller/rpi/af.cpp b/src/ipa/rpi/controller/rpi/af.cpp\n> > index 2157eb94..c29bbaeb 100644\n> > --- a/src/ipa/rpi/controller/rpi/af.cpp\n> > +++ b/src/ipa/rpi/controller/rpi/af.cpp\n> > @@ -97,39 +97,35 @@ void Af::SpeedDependentParams::read(const libcamera::YamlObject &params)\n> >\n> >  int Af::CfgParams::read(const libcamera::YamlObject &params)\n> >  {\n> > -\tif (params.contains(\"ranges\")) {\n> > -\t\tauto &rr = params[\"ranges\"];\n> > -\n> > -\t\tif (rr.contains(\"normal\"))\n> > -\t\t\tranges[AfRangeNormal].read(rr[\"normal\"]);\n> > +\tif (auto *rs = params.find(\"ranges\")) {\n> \n> I would have kept the same variable name (rr) but that doesn't matter\n> much.\n> \n> > +\t\tif (auto *normal = rs->find(\"normal\"))\n> > +\t\t\tranges[AfRangeNormal].read(*normal);\n> >  \t\telse\n> >  \t\t\tLOG(RPiAf, Warning) << \"Missing range \\\"normal\\\"\";\n> >\n> >  \t\tranges[AfRangeMacro] = ranges[AfRangeNormal];\n> > -\t\tif (rr.contains(\"macro\"))\n> > -\t\t\tranges[AfRangeMacro].read(rr[\"macro\"]);\n> > +\t\tif (auto *macro = rs->find(\"macro\"))\n> > +\t\t\tranges[AfRangeMacro].read(*macro);\n> >\n> >  \t\tranges[AfRangeFull].focusMin = std::min(ranges[AfRangeNormal].focusMin,\n> >  \t\t\t\t\t\t\tranges[AfRangeMacro].focusMin);\n> >  \t\tranges[AfRangeFull].focusMax = std::max(ranges[AfRangeNormal].focusMax,\n> >  \t\t\t\t\t\t\tranges[AfRangeMacro].focusMax);\n> >  \t\tranges[AfRangeFull].focusDefault = ranges[AfRangeNormal].focusDefault;\n> > -\t\tif (rr.contains(\"full\"))\n> > -\t\t\tranges[AfRangeFull].read(rr[\"full\"]);\n> > +\t\tif (auto *full = rs->find(\"full\"))\n> > +\t\t\tranges[AfRangeFull].read(*full);\n> >  \t} else\n> >  \t\tLOG(RPiAf, Warning) << \"No ranges defined\";\n> >\n> > -\tif (params.contains(\"speeds\")) {\n> > -\t\tauto &ss = params[\"speeds\"];\n> > -\n> > -\t\tif (ss.contains(\"normal\"))\n> > -\t\t\tspeeds[AfSpeedNormal].read(ss[\"normal\"]);\n> > +\tif (auto *ss = params.find(\"speeds\")) {\n> > +\t\tif (auto *normal = ss->find(\"normal\"))\n> > +\t\t\tspeeds[AfSpeedNormal].read(*normal);\n> >  \t\telse\n> >  \t\t\tLOG(RPiAf, Warning) << \"Missing speed \\\"normal\\\"\";\n> >\n> >  \t\tspeeds[AfSpeedFast] = speeds[AfSpeedNormal];\n> > -\t\tif (ss.contains(\"fast\"))\n> > -\t\t\tspeeds[AfSpeedFast].read(ss[\"fast\"]);\n> > +\t\tif (auto *fast = ss->find(\"fast\"))\n> > +\t\t\tspeeds[AfSpeedFast].read(*fast);\n> >  \t} else\n> >  \t\tLOG(RPiAf, Warning) << \"No speeds defined\";\n> >\n> > @@ -138,8 +134,8 @@ int Af::CfgParams::read(const libcamera::YamlObject &params)\n> >  \treadNumber<uint32_t>(confClip, params, \"conf_clip\");\n> >  \treadNumber<uint32_t>(skipFrames, params, \"skip_frames\");\n> >\n> > -\tif (params.contains(\"map\"))\n> > -\t\tmap = params[\"map\"].get<ipa::Pwl>(ipa::Pwl{});\n> > +\tif (auto *m = params.find(\"map\"))\n> > +\t\tmap = m->get<ipa::Pwl>(ipa::Pwl{});\n> >  \telse\n> >  \t\tLOG(RPiAf, Warning) << \"No map defined\";\n> >\n> > diff --git a/src/ipa/rpi/controller/rpi/agc.cpp b/src/ipa/rpi/controller/rpi/agc.cpp\n> > index c48fdf15..5d924ebf 100644\n> > --- a/src/ipa/rpi/controller/rpi/agc.cpp\n> > +++ b/src/ipa/rpi/controller/rpi/agc.cpp\n> > @@ -37,18 +37,18 @@ int Agc::read(const libcamera::YamlObject &params)\n> >  \t * When there is only a single channel we can read the old style syntax.\n> >  \t * Otherwise we expect a \"channels\" keyword followed by a list of configurations.\n> >  \t */\n> > -\tif (!params.contains(\"channels\")) {\n> > +\tauto *channels = params.find(\"channels\");\n> > +\tif (!channels) {\n> >  \t\tLOG(RPiAgc, Debug) << \"Single channel only\";\n> >  \t\tchannelTotalExposures_.resize(1, 0s);\n> >  \t\tchannelData_.emplace_back();\n> >  \t\treturn channelData_.back().channel.read(params, getHardwareConfig());\n> >  \t}\n> >\n> > -\tconst auto &channels = params[\"channels\"].asList();\n> > -\tfor (auto ch = channels.begin(); ch != channels.end(); ch++) {\n> > +\tfor (const auto &ch : channels->asList()) {\n> >  \t\tLOG(RPiAgc, Debug) << \"Read AGC channel\";\n> >  \t\tchannelData_.emplace_back();\n> > -\t\tint ret = channelData_.back().channel.read(*ch, getHardwareConfig());\n> > +\t\tint ret = channelData_.back().channel.read(ch, getHardwareConfig());\n> >  \t\tif (ret)\n> >  \t\t\treturn ret;\n> >  \t}\n> > diff --git a/src/ipa/rpi/controller/rpi/agc_channel.cpp b/src/ipa/rpi/controller/rpi/agc_channel.cpp\n> > index 79c45973..50b9efd2 100644\n> > --- a/src/ipa/rpi/controller/rpi/agc_channel.cpp\n> > +++ b/src/ipa/rpi/controller/rpi/agc_channel.cpp\n> > @@ -235,8 +235,8 @@ int AgcConfig::read(const libcamera::YamlObject &params)\n> >  \tif (ret)\n> >  \t\treturn ret;\n> >\n> > -\tif (params.contains(\"channel_constraints\")) {\n> > -\t\tret = readChannelConstraints(channelConstraints, params[\"channel_constraints\"]);\n> > +\tif (auto *cc = params.find(\"channel_constraints\")) {\n> > +\t\tret = readChannelConstraints(channelConstraints, *cc);\n> >  \t\tif (ret)\n> >  \t\t\treturn ret;\n> >  \t}\n> > diff --git a/src/ipa/rpi/controller/rpi/alsc.cpp b/src/ipa/rpi/controller/rpi/alsc.cpp\n> > index 21edb819..5a1a702b 100644\n> > --- a/src/ipa/rpi/controller/rpi/alsc.cpp\n> > +++ b/src/ipa/rpi/controller/rpi/alsc.cpp\n> > @@ -104,9 +104,9 @@ static int readCalibrations(std::vector<AlscCalibration> &calibrations,\n> >  \t\t\t    const libcamera::YamlObject &params,\n> >  \t\t\t    std::string const &name, const Size &size)\n> >  {\n> > -\tif (params.contains(name)) {\n> > +\tif (auto *param = params.find(name)) {\n> >  \t\tdouble lastCt = 0;\n> > -\t\tfor (const auto &p : params[name].asList()) {\n> > +\t\tfor (const auto &p : param->asList()) {\n> >  \t\t\tauto value = p[\"ct\"].get<double>();\n> >  \t\t\tif (!value)\n> >  \t\t\t\treturn -EINVAL;\n> > @@ -163,10 +163,10 @@ int Alsc::read(const libcamera::YamlObject &params)\n> >  \tconfig_.luminanceLut.resize(config_.tableSize, 1.0);\n> >  \tint ret = 0;\n> >\n> > -\tif (params.contains(\"corner_strength\"))\n> > +\tif (params.find(\"corner_strength\"))\n> >  \t\tret = generateLut(config_.luminanceLut, params);\n> > -\telse if (params.contains(\"luminance_lut\"))\n> > -\t\tret = readLut(config_.luminanceLut, params[\"luminance_lut\"]);\n> > +\telse if (auto *ll = params.find(\"luminance_lut\"))\n> > +\t\tret = readLut(config_.luminanceLut, *ll);\n> >  \telse\n> >  \t\tLOG(RPiAlsc, Warning)\n> >  \t\t\t<< \"no luminance table - assume unity everywhere\";\n> > diff --git a/src/ipa/rpi/controller/rpi/awb.cpp b/src/ipa/rpi/controller/rpi/awb.cpp\n> > index c277a176..2e6e295c 100644\n> > --- a/src/ipa/rpi/controller/rpi/awb.cpp\n> > +++ b/src/ipa/rpi/controller/rpi/awb.cpp\n> > @@ -102,8 +102,8 @@ int AwbConfig::read(const libcamera::YamlObject &params)\n> >  \tconvergenceFrames = params[\"convergence_frames\"].get<unsigned int>(3);\n> >  \tspeed = params[\"speed\"].get<double>(0.05);\n> >\n> > -\tif (params.contains(\"ct_curve\")) {\n> > -\t\tret = readCtCurve(ctR, ctB, params[\"ct_curve\"]);\n> > +\tif (auto *ct_curve = params.find(\"ct_curve\")) {\n> > +\t\tret = readCtCurve(ctR, ctB, *ct_curve);\n> >  \t\tif (ret)\n> >  \t\t\treturn ret;\n> >  \t\t/* We will want the inverse functions of these too. */\n> > @@ -111,8 +111,8 @@ int AwbConfig::read(const libcamera::YamlObject &params)\n> >  \t\tctBInverse = ctB.inverse().first;\n> >  \t}\n> >\n> > -\tif (params.contains(\"priors\")) {\n> > -\t\tfor (const auto &p : params[\"priors\"].asList()) {\n> > +\tif (auto *ps = params.find(\"priors\")) {\n> > +\t\tfor (const auto &p : ps->asList()) {\n> >  \t\t\tAwbPrior prior;\n> >  \t\t\tret = prior.read(p);\n> >  \t\t\tif (ret)\n> > @@ -128,8 +128,8 @@ int AwbConfig::read(const libcamera::YamlObject &params)\n> >  \t\t\treturn -EINVAL;\n> >  \t\t}\n> >  \t}\n> > -\tif (params.contains(\"modes\")) {\n> > -\t\tfor (const auto &[key, value] : params[\"modes\"].asDict()) {\n> > +\tif (auto *ms = params.find(\"modes\")) {\n> > +\t\tfor (const auto &[key, value] : ms->asDict()) {\n> >  \t\t\tret = modes[key].read(value);\n> >  \t\t\tif (ret)\n> >  \t\t\t\treturn ret;\n> > diff --git a/src/ipa/rpi/controller/rpi/ccm.cpp b/src/ipa/rpi/controller/rpi/ccm.cpp\n> > index 8607f152..5616e5f4 100644\n> > --- a/src/ipa/rpi/controller/rpi/ccm.cpp\n> > +++ b/src/ipa/rpi/controller/rpi/ccm.cpp\n> > @@ -41,8 +41,8 @@ char const *Ccm::name() const\n> >\n> >  int Ccm::read(const libcamera::YamlObject &params)\n> >  {\n> > -\tif (params.contains(\"saturation\")) {\n> > -\t\tconfig_.saturation = params[\"saturation\"].get<ipa::Pwl>(ipa::Pwl{});\n> > +\tif (auto *s = params.find(\"saturation\")) {\n> > +\t\tconfig_.saturation = s->get<ipa::Pwl>(ipa::Pwl{});\n> >  \t\tif (config_.saturation.empty())\n> >  \t\t\treturn -EINVAL;\n> >  \t}\n> > diff --git a/src/ipa/rpi/controller/rpi/geq.cpp b/src/ipa/rpi/controller/rpi/geq.cpp\n> > index 40e7191b..6935f726 100644\n> > --- a/src/ipa/rpi/controller/rpi/geq.cpp\n> > +++ b/src/ipa/rpi/controller/rpi/geq.cpp\n> > @@ -43,8 +43,8 @@ int Geq::read(const libcamera::YamlObject &params)\n> >  \t\treturn -EINVAL;\n> >  \t}\n> >\n> > -\tif (params.contains(\"strength\")) {\n> > -\t\tconfig_.strength = params[\"strength\"].get<ipa::Pwl>(ipa::Pwl{});\n> > +\tif (auto *strength = params.find(\"strength\")) {\n> > +\t\tconfig_.strength = strength->get<ipa::Pwl>(ipa::Pwl{});\n> >  \t\tif (config_.strength.empty())\n> >  \t\t\treturn -EINVAL;\n> >  \t}\n> > diff --git a/src/ipa/rpi/controller/rpi/hdr.cpp b/src/ipa/rpi/controller/rpi/hdr.cpp\n> > index f3da8291..20b1ff4b 100644\n> > --- a/src/ipa/rpi/controller/rpi/hdr.cpp\n> > +++ b/src/ipa/rpi/controller/rpi/hdr.cpp\n> > @@ -27,9 +27,10 @@ void HdrConfig::read(const libcamera::YamlObject &params, const std::string &mod\n> >  {\n> >  \tname = modeName;\n> >\n> > -\tif (!params.contains(\"cadence\"))\n> > +\tauto *c = params.find(\"cadence\");\n> > +\tif (!c)\n> >  \t\tLOG(RPiHdr, Fatal) << \"No cadence for HDR mode \" << name;\n> > -\tcadence = params[\"cadence\"].getList<unsigned int>().value();\n> > +\tcadence = c->getList<unsigned int>().value();\n> >  \tif (cadence.empty())\n> >  \t\tLOG(RPiHdr, Fatal) << \"Empty cadence in HDR mode \" << name;\n> >\n> > @@ -41,10 +42,10 @@ void HdrConfig::read(const libcamera::YamlObject &params, const std::string &mod\n> >  \t\tchannelMap[v.get<unsigned int>().value()] = k;\n> >\n> >  \t/* Lens shading related parameters. */\n> > -\tif (params.contains(\"spatial_gain_curve\")) {\n> > -\t\tspatialGainCurve = params[\"spatial_gain_curve\"].get<ipa::Pwl>(ipa::Pwl{});\n> > -\t} else if (params.contains(\"spatial_gain\")) {\n> > -\t\tdouble spatialGain = params[\"spatial_gain\"].get<double>(2.0);\n> > +\tif (auto *sgc = params.find(\"spatial_gain_curve\")) {\n> > +\t\tspatialGainCurve = sgc->get<ipa::Pwl>(ipa::Pwl{});\n> > +\t} else if (auto *sg = params.find(\"spatial_gain\")) {\n> > +\t\tdouble spatialGain = sg->get<double>(2.0);\n> >  \t\tspatialGainCurve.append(0.0, spatialGain);\n> >  \t\tspatialGainCurve.append(0.01, spatialGain);\n> >  \t\tspatialGainCurve.append(0.06, 1.0); /* maybe make this programmable? */\n> > @@ -68,24 +69,24 @@ void HdrConfig::read(const libcamera::YamlObject &params, const std::string &mod\n> >  \tif (tonemapEnable)\n> >  \t\ttonemap = params[\"tonemap\"].get<ipa::Pwl>(ipa::Pwl{});\n> >  \tspeed = params[\"speed\"].get<double>(1.0);\n> > -\tif (params.contains(\"hi_quantile_targets\")) {\n> > -\t\thiQuantileTargets = params[\"hi_quantile_targets\"].getList<double>().value();\n> > +\tif (auto *hqt = params.find(\"hi_quantile_targets\")) {\n> > +\t\thiQuantileTargets = hqt->getList<double>().value();\n> >  \t\tif (hiQuantileTargets.empty() || hiQuantileTargets.size() % 2)\n> >  \t\t\tLOG(RPiHdr, Fatal) << \"hi_quantile_targets much be even and non-empty\";\n> >  \t} else\n> >  \t\thiQuantileTargets = { 0.95, 0.65, 0.5, 0.28, 0.3, 0.25 };\n> >  \thiQuantileMaxGain = params[\"hi_quantile_max_gain\"].get<double>(1.6);\n> > -\tif (params.contains(\"quantile_targets\")) {\n> > -\t\tquantileTargets = params[\"quantile_targets\"].getList<double>().value();\n> > +\tif (auto *qt = params.find(\"quantile_targets\")) {\n> > +\t\tquantileTargets = qt->getList<double>().value();\n> >  \t\tif (quantileTargets.empty() || quantileTargets.size() % 2)\n> >  \t\t\tLOG(RPiHdr, Fatal) << \"quantile_targets much be even and non-empty\";\n> >  \t} else\n> >  \t\tquantileTargets = { 0.2, 0.03, 1.0, 0.15 };\n> >  \tpowerMin = params[\"power_min\"].get<double>(0.65);\n> >  \tpowerMax = params[\"power_max\"].get<double>(1.0);\n> > -\tif (params.contains(\"contrast_adjustments\")) {\n> > -\t\tcontrastAdjustments = params[\"contrast_adjustments\"].getList<double>().value();\n> > -\t} else\n> > +\tif (auto *ca = params.find(\"contrast_adjustments\"))\n> > +\t\tcontrastAdjustments = ca->getList<double>().value();\n> > +\telse\n> >  \t\tcontrastAdjustments = { 0.5, 0.75 };\n> >\n> >  \t/* Read any stitch parameters. */\n> > diff --git a/src/ipa/simple/soft_simple.cpp b/src/ipa/simple/soft_simple.cpp\n> > index e1b6d3af..ca3fe487 100644\n> > --- a/src/ipa/simple/soft_simple.cpp\n> > +++ b/src/ipa/simple/soft_simple.cpp\n> > @@ -114,12 +114,13 @@ int IPASoftSimple::init(const IPASettings &settings,\n> >  \tunsigned int version = (*data)[\"version\"].get<uint32_t>(0);\n> >  \tLOG(IPASoft, Debug) << \"Tuning file version \" << version;\n> >\n> > -\tif (!data->contains(\"algorithms\")) {\n> > +\tauto *algos = data->find(\"algorithms\");\n> > +\tif (!algos) {\n> >  \t\tLOG(IPASoft, Error) << \"Tuning file doesn't contain algorithms\";\n> >  \t\treturn -EINVAL;\n> >  \t}\n> >\n> > -\tint ret = createAlgorithms(context_, (*data)[\"algorithms\"]);\n> > +\tint ret = createAlgorithms(context_, *algos);\n> >  \tif (ret)\n> >  \t\treturn ret;\n> >\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 72C04BE080\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon,  9 Dec 2024 17:57:06 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 8A33967E73;\n\tMon,  9 Dec 2024 18:57:05 +0100 (CET)","from mail-4316.protonmail.ch (mail-4316.protonmail.ch\n\t[185.70.43.16])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id CB9D166132\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon,  9 Dec 2024 18:57:03 +0100 (CET)"],"Authentication-Results":"lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key;\n\tunprotected) header.d=protonmail.com header.i=@protonmail.com\n\theader.b=\"ju8UmJSo\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=protonmail.com;\n\ts=protonmail3; t=1733767022; x=1734026222;\n\tbh=RlUuPkOcTonkH5EIMXXlcCCb+JYfOmaAaq8uJuNbORs=;\n\th=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References:\n\tFeedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID:\n\tMessage-ID:BIMI-Selector:List-Unsubscribe:List-Unsubscribe-Post;\n\tb=ju8UmJSo+MqZqtI23jNqfwjUMJUQUEtBtWD2u52gP6kWxw9V3oUjKqu0nPhe78vLL\n\tc6kAsh4Y+eaGgc5ZJVZAEaWfqaS8tbam9ljaR2rnCOIB1CxeJmQmiSsaeIFl1MjJcY\n\tBMKaSWVcNUWWT1VA/k2CmcT+wZW7TKkZTvA45QVv/V3ozMnDASxAV5tYFvL6Mtb6SP\n\tF9AsZ4MUVcTDDy1Lm2dAfVJtphwOvPFU3Pp9aMH1+iYQNyva3f7kQevEPOzgOxo/cw\n\t8LtNg5yFgZFgi3yI62RjB0iw3dY47UO4hKRneGZrIqCW9Ayk06UAPcZCGOG1Z4vFu9\n\tX062bUxeim6yw==","Date":"Mon, 09 Dec 2024 17:56:57 +0000","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","From":"=?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= <pobrn@protonmail.com>","Cc":"libcamera-devel@lists.libcamera.org","Subject":"Re: [PATCH v1 2/3] treewide: Use `YamlObject::find()`","Message-ID":"<Ef3UXUsEIxddqbie9PI1tW0qmU2ik-QuS7dUq4de81TptTe_dBh8pUGRtykZVEloMA-i0O8wHZ81pLfQNrgJ7_r3MFNJryV3Zz1uLqaTv64=@protonmail.com>","In-Reply-To":"<20241206010932.GL21014@pendragon.ideasonboard.com>","References":"<20241205163411.1160094-1-pobrn@protonmail.com>\n\t<20241205163411.1160094-2-pobrn@protonmail.com>\n\t<20241206010932.GL21014@pendragon.ideasonboard.com>","Feedback-ID":"20568564:user:proton","X-Pm-Message-ID":"8c41cf425c93122005fb67376ceb509ecf96a154","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Transfer-Encoding":"quoted-printable","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":32642,"web_url":"https://patchwork.libcamera.org/comment/32642/","msgid":"<20241209212124.GA26531@pendragon.ideasonboard.com>","date":"2024-12-09T21:21:24","subject":"Re: [PATCH v1 2/3] treewide: Use `YamlObject::find()`","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"On Mon, Dec 09, 2024 at 05:56:57PM +0000, Barnabás Pőcze wrote:\n> 2024. december 6., péntek 2:09 keltezéssel, Laurent Pinchart írta:\n> > On Thu, Dec 05, 2024 at 04:34:19PM +0000, Barnabás Pőcze wrote:\n> > > Replace some uses of `contains()` + `operator[]` with `find()`.\n> > > Using `find()` avoids the double lookup, as well as does away with\n> > > the need for specifying the key twice.\n> > >\n> > > Signed-off-by: Barnabás Pőcze <pobrn@protonmail.com>\n> > > ---\n> > >  src/android/camera_hal_config.cpp          | 19 ++++----\n> > >  src/ipa/ipu3/ipu3.cpp                      |  5 +-\n> > >  src/ipa/rkisp1/algorithms/dpcc.cpp         | 56 +++++++++++-----------\n> > >  src/ipa/rkisp1/rkisp1.cpp                  |  5 +-\n> > >  src/ipa/rpi/controller/controller.cpp      |  5 +-\n> > >  src/ipa/rpi/controller/rpi/af.cpp          | 32 ++++++-------\n> > >  src/ipa/rpi/controller/rpi/agc.cpp         |  8 ++--\n> > >  src/ipa/rpi/controller/rpi/agc_channel.cpp |  4 +-\n> > >  src/ipa/rpi/controller/rpi/alsc.cpp        | 10 ++--\n> > >  src/ipa/rpi/controller/rpi/awb.cpp         | 12 ++---\n> > >  src/ipa/rpi/controller/rpi/ccm.cpp         |  4 +-\n> > >  src/ipa/rpi/controller/rpi/geq.cpp         |  4 +-\n> > >  src/ipa/rpi/controller/rpi/hdr.cpp         | 27 ++++++-----\n> > >  src/ipa/simple/soft_simple.cpp             |  5 +-\n> > >  14 files changed, 99 insertions(+), 97 deletions(-)\n> > >\n> > > diff --git a/src/android/camera_hal_config.cpp b/src/android/camera_hal_config.cpp\n> > > index 7ef451ef..6fde953d 100644\n> > > --- a/src/android/camera_hal_config.cpp\n> > > +++ b/src/android/camera_hal_config.cpp\n> > > @@ -73,15 +73,14 @@ int CameraHalConfig::Private::parseConfigFile(File &file,\n> > >  \t\treturn -EINVAL;\n> > >\n> > >  \t/* Parse property \"cameras\" */\n> > > -\tif (!root->contains(\"cameras\"))\n> > > +\tauto *yamlObjectCameras = root->find(\"cameras\");\n> > \n> > I generally dislike overusing auto as it makes the code less explicit,\n> > and therefore less readable. There are valid use cases, for instance\n> > spelling out std::map<std::string, std::vector<std::pair<...>>>::iterator\n> > would be inconvenient. Usage of auto in structured bindings is also\n> > useful. In this specifif case, however, writing\n> > \n> > \tconst YamlObject *yamlObjectCameras = root->find(\"cameras\");\n> > \n> > isn't much longer, and I think it improves readability.\n> > \n> > Same below.\n> \n> So you would specify the explicit type everywhere this change touches?\n> Even in the controlling expression of `if` statements?\n\nNot necessarily everywhere. For me it's a matter of readability. If find\nthat usage of auto hinders readability, as it's often unclear when\nreading the code what type a variable takes. For long types, especially\nwith nested qualifiers, writing out the full type would be less readable\nthan 'auto'. Especially in contexts where the type of the variable is\nevident, using 'auto' is fine.\n\nAs readability is a subjective concept, I don't think we can set a clear\nrule. I won't nitpick too much and I'll let you decide where to draw the\nline. Ideally I'd like some sort of consistency through the code base\nthough.\n\n> > > +\tif (!yamlObjectCameras)\n> > >  \t\treturn -EINVAL;\n> > >\n> > > -\tconst YamlObject &yamlObjectCameras = (*root)[\"cameras\"];\n> > > -\n> > > -\tif (!yamlObjectCameras.isDictionary())\n> > > +\tif (!yamlObjectCameras->isDictionary())\n> > >  \t\treturn -EINVAL;\n> > >\n> > > -\tfor (const auto &[cameraId, configData] : yamlObjectCameras.asDict()) {\n> > > +\tfor (const auto &[cameraId, configData] : yamlObjectCameras->asDict()) {\n> > >  \t\tif (parseCameraConfigData(cameraId, configData))\n> > >  \t\t\treturn -EINVAL;\n> > >  \t}\n> > > @@ -112,10 +111,11 @@ int CameraHalConfig::Private::parseCameraConfigData(const std::string &cameraId,\n> > >  int CameraHalConfig::Private::parseLocation(const YamlObject &cameraObject,\n> > >  \t\t\t\t\t    CameraConfigData &cameraConfigData)\n> > >  {\n> > > -\tif (!cameraObject.contains(\"location\"))\n> > > +\tauto *loc = cameraObject.find(\"location\");\n> > > +\tif (!loc)\n> > >  \t\treturn -EINVAL;\n> > >\n> > > -\tstd::string location = cameraObject[\"location\"].get<std::string>(\"\");\n> > > +\tstd::string location = loc->get<std::string>(\"\");\n> > >\n> > >  \tif (location == \"front\")\n> > >  \t\tcameraConfigData.facing = CAMERA_FACING_FRONT;\n> > > @@ -130,10 +130,11 @@ int CameraHalConfig::Private::parseLocation(const YamlObject &cameraObject,\n> > >  int CameraHalConfig::Private::parseRotation(const YamlObject &cameraObject,\n> > >  \t\t\t\t\t    CameraConfigData &cameraConfigData)\n> > >  {\n> > > -\tif (!cameraObject.contains(\"rotation\"))\n> > > +\tauto *rot = cameraObject.find(\"rotation\");\n> > > +\tif (!rot)\n> > >  \t\treturn -EINVAL;\n> > >\n> > > -\tint32_t rotation = cameraObject[\"rotation\"].get<int32_t>(-1);\n> > > +\tint32_t rotation = rot->get<int32_t>(-1);\n> > >\n> > >  \tif (rotation < 0 || rotation >= 360) {\n> > >  \t\tLOG(HALConfig, Error)\n> > > diff --git a/src/ipa/ipu3/ipu3.cpp b/src/ipa/ipu3/ipu3.cpp\n> > > index 44c98cbf..88b1bb81 100644\n> > > --- a/src/ipa/ipu3/ipu3.cpp\n> > > +++ b/src/ipa/ipu3/ipu3.cpp\n> > > @@ -335,13 +335,14 @@ int IPAIPU3::init(const IPASettings &settings,\n> > >  \t\treturn -EINVAL;\n> > >  \t}\n> > >\n> > > -\tif (!data->contains(\"algorithms\")) {\n> > > +\tauto *algos = data->find(\"algorithms\");\n> > > +\tif (!algos) {\n> > >  \t\tLOG(IPAIPU3, Error)\n> > >  \t\t\t<< \"Tuning file doesn't contain any algorithm\";\n> > >  \t\treturn -EINVAL;\n> > >  \t}\n> > >\n> > > -\tint ret = createAlgorithms(context_, (*data)[\"algorithms\"]);\n> > > +\tint ret = createAlgorithms(context_, *algos);\n> > >  \tif (ret)\n> > >  \t\treturn ret;\n> > >\n> > > diff --git a/src/ipa/rkisp1/algorithms/dpcc.cpp b/src/ipa/rkisp1/algorithms/dpcc.cpp\n> > > index 78946281..8946c1a7 100644\n> > > --- a/src/ipa/rkisp1/algorithms/dpcc.cpp\n> > > +++ b/src/ipa/rkisp1/algorithms/dpcc.cpp\n> > > @@ -80,39 +80,39 @@ int DefectPixelClusterCorrection::init([[maybe_unused]] IPAContext &context,\n> > >  \t\t/* PG Method */\n> > >  \t\tconst YamlObject &pgObject = set[\"pg-factor\"];\n> > >\n> > > -\t\tif (pgObject.contains(\"green\")) {\n> > > +\t\tif (auto *green = pgObject.find(\"green\")) {\n> > >  \t\t\tmethod.method |=\n> > >  \t\t\t\tRKISP1_CIF_ISP_DPCC_METHODS_SET_PG_GREEN_ENABLE;\n> > >\n> > > -\t\t\tvalue = pgObject[\"green\"].get<uint16_t>(0);\n> > > +\t\t\tvalue = green->get<uint16_t>(0);\n> > >  \t\t\tmethod.pg_fac |= RKISP1_CIF_ISP_DPCC_PG_FAC_G(value);\n> > >  \t\t}\n> > >\n> > > -\t\tif (pgObject.contains(\"red-blue\")) {\n> > > +\t\tif (auto *redBlue = pgObject.find(\"red-blue\")) {\n> > >  \t\t\tmethod.method |=\n> > >  \t\t\t\tRKISP1_CIF_ISP_DPCC_METHODS_SET_PG_RED_BLUE_ENABLE;\n> > >\n> > > -\t\t\tvalue = pgObject[\"red-blue\"].get<uint16_t>(0);\n> > > +\t\t\tvalue = redBlue->get<uint16_t>(0);\n> > >  \t\t\tmethod.pg_fac |= RKISP1_CIF_ISP_DPCC_PG_FAC_RB(value);\n> > >  \t\t}\n> > >\n> > >  \t\t/* RO Method */\n> > >  \t\tconst YamlObject &roObject = set[\"ro-limits\"];\n> > >\n> > > -\t\tif (roObject.contains(\"green\")) {\n> > > +\t\tif (auto *green = roObject.find(\"green\")) {\n> > >  \t\t\tmethod.method |=\n> > >  \t\t\t\tRKISP1_CIF_ISP_DPCC_METHODS_SET_RO_GREEN_ENABLE;\n> > >\n> > > -\t\t\tvalue = roObject[\"green\"].get<uint16_t>(0);\n> > > +\t\t\tvalue = green->get<uint16_t>(0);\n> > >  \t\t\tconfig_.ro_limits |=\n> > >  \t\t\t\tRKISP1_CIF_ISP_DPCC_RO_LIMITS_n_G(i, value);\n> > >  \t\t}\n> > >\n> > > -\t\tif (roObject.contains(\"red-blue\")) {\n> > > +\t\tif (auto *redBlue = roObject.find(\"red-blue\")) {\n> > >  \t\t\tmethod.method |=\n> > >  \t\t\t\tRKISP1_CIF_ISP_DPCC_METHODS_SET_RO_RED_BLUE_ENABLE;\n> > >\n> > > -\t\t\tvalue = roObject[\"red-blue\"].get<uint16_t>(0);\n> > > +\t\t\tvalue = redBlue->get<uint16_t>(0);\n> > >  \t\t\tconfig_.ro_limits |=\n> > >  \t\t\t\tRKISP1_CIF_ISP_DPCC_RO_LIMITS_n_RB(i, value);\n> > >  \t\t}\n> > > @@ -121,39 +121,39 @@ int DefectPixelClusterCorrection::init([[maybe_unused]] IPAContext &context,\n> > >  \t\tconst YamlObject &rgObject = set[\"rg-factor\"];\n> > >  \t\tmethod.rg_fac = 0;\n> > >\n> > > -\t\tif (rgObject.contains(\"green\")) {\n> > > +\t\tif (auto *green = rgObject.find(\"green\")) {\n> > >  \t\t\tmethod.method |=\n> > >  \t\t\t\tRKISP1_CIF_ISP_DPCC_METHODS_SET_RG_GREEN_ENABLE;\n> > >\n> > > -\t\t\tvalue = rgObject[\"green\"].get<uint16_t>(0);\n> > > +\t\t\tvalue = green->get<uint16_t>(0);\n> > >  \t\t\tmethod.rg_fac |= RKISP1_CIF_ISP_DPCC_RG_FAC_G(value);\n> > >  \t\t}\n> > >\n> > > -\t\tif (rgObject.contains(\"red-blue\")) {\n> > > +\t\tif (auto *redBlue = rgObject.find(\"red-blue\")) {\n> > >  \t\t\tmethod.method |=\n> > >  \t\t\t\tRKISP1_CIF_ISP_DPCC_METHODS_SET_RG_RED_BLUE_ENABLE;\n> > >\n> > > -\t\t\tvalue = rgObject[\"red-blue\"].get<uint16_t>(0);\n> > > +\t\t\tvalue = redBlue->get<uint16_t>(0);\n> > >  \t\t\tmethod.rg_fac |= RKISP1_CIF_ISP_DPCC_RG_FAC_RB(value);\n> > >  \t\t}\n> > >\n> > >  \t\t/* RND Method */\n> > >  \t\tconst YamlObject &rndOffsetsObject = set[\"rnd-offsets\"];\n> > >\n> > > -\t\tif (rndOffsetsObject.contains(\"green\")) {\n> > > +\t\tif (auto *green = rndOffsetsObject.find(\"green\")) {\n> > >  \t\t\tmethod.method |=\n> > >  \t\t\t\tRKISP1_CIF_ISP_DPCC_METHODS_SET_RND_GREEN_ENABLE;\n> > >\n> > > -\t\t\tvalue = rndOffsetsObject[\"green\"].get<uint16_t>(0);\n> > > +\t\t\tvalue = green->get<uint16_t>(0);\n> > >  \t\t\tconfig_.rnd_offs |=\n> > >  \t\t\t\tRKISP1_CIF_ISP_DPCC_RND_OFFS_n_G(i, value);\n> > >  \t\t}\n> > >\n> > > -\t\tif (rndOffsetsObject.contains(\"red-blue\")) {\n> > > +\t\tif (auto *redBlue = rndOffsetsObject.find(\"red-blue\")) {\n> > >  \t\t\tmethod.method |=\n> > >  \t\t\t\tRKISP1_CIF_ISP_DPCC_METHODS_SET_RND_RED_BLUE_ENABLE;\n> > >\n> > > -\t\t\tvalue = rndOffsetsObject[\"red-blue\"].get<uint16_t>(0);\n> > > +\t\t\tvalue = redBlue->get<uint16_t>(0);\n> > >  \t\t\tconfig_.rnd_offs |=\n> > >  \t\t\t\tRKISP1_CIF_ISP_DPCC_RND_OFFS_n_RB(i, value);\n> > >  \t\t}\n> > > @@ -161,20 +161,20 @@ int DefectPixelClusterCorrection::init([[maybe_unused]] IPAContext &context,\n> > >  \t\tconst YamlObject &rndThresholdObject = set[\"rnd-threshold\"];\n> > >  \t\tmethod.rnd_thresh = 0;\n> > >\n> > > -\t\tif (rndThresholdObject.contains(\"green\")) {\n> > > +\t\tif (auto *green = rndThresholdObject.find(\"green\")) {\n> > >  \t\t\tmethod.method |=\n> > >  \t\t\t\tRKISP1_CIF_ISP_DPCC_METHODS_SET_RND_GREEN_ENABLE;\n> > >\n> > > -\t\t\tvalue = rndThresholdObject[\"green\"].get<uint16_t>(0);\n> > > +\t\t\tvalue = green->get<uint16_t>(0);\n> > >  \t\t\tmethod.rnd_thresh |=\n> > >  \t\t\t\tRKISP1_CIF_ISP_DPCC_RND_THRESH_G(value);\n> > >  \t\t}\n> > >\n> > > -\t\tif (rndThresholdObject.contains(\"red-blue\")) {\n> > > +\t\tif (auto *redBlue = rndThresholdObject.find(\"red-blue\")) {\n> > >  \t\t\tmethod.method |=\n> > >  \t\t\t\tRKISP1_CIF_ISP_DPCC_METHODS_SET_RND_RED_BLUE_ENABLE;\n> > >\n> > > -\t\t\tvalue = rndThresholdObject[\"red-blue\"].get<uint16_t>(0);\n> > > +\t\t\tvalue = redBlue->get<uint16_t>(0);\n> > >  \t\t\tmethod.rnd_thresh |=\n> > >  \t\t\t\tRKISP1_CIF_ISP_DPCC_RND_THRESH_RB(value);\n> > >  \t\t}\n> > > @@ -183,20 +183,20 @@ int DefectPixelClusterCorrection::init([[maybe_unused]] IPAContext &context,\n> > >  \t\tconst YamlObject &lcThresholdObject = set[\"line-threshold\"];\n> > >  \t\tmethod.line_thresh = 0;\n> > >\n> > > -\t\tif (lcThresholdObject.contains(\"green\")) {\n> > > +\t\tif (auto *green = lcThresholdObject.find(\"green\")) {\n> > >  \t\t\tmethod.method |=\n> > >  \t\t\t\tRKISP1_CIF_ISP_DPCC_METHODS_SET_LC_GREEN_ENABLE;\n> > >\n> > > -\t\t\tvalue = lcThresholdObject[\"green\"].get<uint16_t>(0);\n> > > +\t\t\tvalue = green->get<uint16_t>(0);\n> > >  \t\t\tmethod.line_thresh |=\n> > >  \t\t\t\tRKISP1_CIF_ISP_DPCC_LINE_THRESH_G(value);\n> > >  \t\t}\n> > >\n> > > -\t\tif (lcThresholdObject.contains(\"red-blue\")) {\n> > > +\t\tif (auto *redBlue = lcThresholdObject.find(\"red-blue\")) {\n> > >  \t\t\tmethod.method |=\n> > >  \t\t\t\tRKISP1_CIF_ISP_DPCC_METHODS_SET_LC_RED_BLUE_ENABLE;\n> > >\n> > > -\t\t\tvalue = lcThresholdObject[\"red-blue\"].get<uint16_t>(0);\n> > > +\t\t\tvalue = redBlue->get<uint16_t>(0);\n> > >  \t\t\tmethod.line_thresh |=\n> > >  \t\t\t\tRKISP1_CIF_ISP_DPCC_LINE_THRESH_RB(value);\n> > >  \t\t}\n> > > @@ -204,20 +204,20 @@ int DefectPixelClusterCorrection::init([[maybe_unused]] IPAContext &context,\n> > >  \t\tconst YamlObject &lcTMadFactorObject = set[\"line-mad-factor\"];\n> > >  \t\tmethod.line_mad_fac = 0;\n> > >\n> > > -\t\tif (lcTMadFactorObject.contains(\"green\")) {\n> > > +\t\tif (auto *green = lcTMadFactorObject.find(\"green\")) {\n> > >  \t\t\tmethod.method |=\n> > >  \t\t\t\tRKISP1_CIF_ISP_DPCC_METHODS_SET_LC_GREEN_ENABLE;\n> > >\n> > > -\t\t\tvalue = lcTMadFactorObject[\"green\"].get<uint16_t>(0);\n> > > +\t\t\tvalue = green->get<uint16_t>(0);\n> > >  \t\t\tmethod.line_mad_fac |=\n> > >  \t\t\t\tRKISP1_CIF_ISP_DPCC_LINE_MAD_FAC_G(value);\n> > >  \t\t}\n> > >\n> > > -\t\tif (lcTMadFactorObject.contains(\"red-blue\")) {\n> > > +\t\tif (auto *redBlue = lcTMadFactorObject.find(\"red-blue\")) {\n> > >  \t\t\tmethod.method |=\n> > >  \t\t\t\tRKISP1_CIF_ISP_DPCC_METHODS_SET_LC_RED_BLUE_ENABLE;\n> > >\n> > > -\t\t\tvalue = lcTMadFactorObject[\"red-blue\"].get<uint16_t>(0);\n> > > +\t\t\tvalue = redBlue->get<uint16_t>(0);\n> > >  \t\t\tmethod.line_mad_fac |=\n> > >  \t\t\t\tRKISP1_CIF_ISP_DPCC_LINE_MAD_FAC_RB(value);\n> > >  \t\t}\n> > > diff --git a/src/ipa/rkisp1/rkisp1.cpp b/src/ipa/rkisp1/rkisp1.cpp\n> > > index 2ffdd99b..202b53b7 100644\n> > > --- a/src/ipa/rkisp1/rkisp1.cpp\n> > > +++ b/src/ipa/rkisp1/rkisp1.cpp\n> > > @@ -193,13 +193,14 @@ int IPARkISP1::init(const IPASettings &settings, unsigned int hwRevision,\n> > >  \t\treturn -EINVAL;\n> > >  \t}\n> > >\n> > > -\tif (!data->contains(\"algorithms\")) {\n> > > +\tauto *algos = data->find(\"algorithms\");\n> > > +\tif (!algos) {\n> > >  \t\tLOG(IPARkISP1, Error)\n> > >  \t\t\t<< \"Tuning file doesn't contain any algorithm\";\n> > >  \t\treturn -EINVAL;\n> > >  \t}\n> > >\n> > > -\tint ret = createAlgorithms(context_, (*data)[\"algorithms\"]);\n> > > +\tint ret = createAlgorithms(context_, *algos);\n> > >  \tif (ret)\n> > >  \t\treturn ret;\n> > >\n> > > diff --git a/src/ipa/rpi/controller/controller.cpp b/src/ipa/rpi/controller/controller.cpp\n> > > index e0131018..fbf31f23 100644\n> > > --- a/src/ipa/rpi/controller/controller.cpp\n> > > +++ b/src/ipa/rpi/controller/controller.cpp\n> > > @@ -109,14 +109,15 @@ int Controller::read(char const *filename)\n> > >  \t\t\t\treturn ret;\n> > >  \t\t}\n> > >  \t} else if (version < 3.0) {\n> > > -\t\tif (!root->contains(\"algorithms\")) {\n> > > +\t\tauto *algos = root->find(\"algorithms\");\n> > > +\t\tif (!algos) {\n> > >  \t\t\tLOG(RPiController, Error)\n> > >  \t\t\t\t<< \"Tuning file \" << filename\n> > >  \t\t\t\t<< \" does not have an \\\"algorithms\\\" list!\";\n> > >  \t\t\treturn -EINVAL;\n> > >  \t\t}\n> > >\n> > > -\t\tfor (auto const &rootAlgo : (*root)[\"algorithms\"].asList())\n> > > +\t\tfor (auto const &rootAlgo : algos->asList())\n> > >  \t\t\tfor (auto const &[key, value] : rootAlgo.asDict()) {\n> > >  \t\t\t\tint ret = createAlgorithm(key, value);\n> > >  \t\t\t\tif (ret)\n> > > diff --git a/src/ipa/rpi/controller/rpi/af.cpp b/src/ipa/rpi/controller/rpi/af.cpp\n> > > index 2157eb94..c29bbaeb 100644\n> > > --- a/src/ipa/rpi/controller/rpi/af.cpp\n> > > +++ b/src/ipa/rpi/controller/rpi/af.cpp\n> > > @@ -97,39 +97,35 @@ void Af::SpeedDependentParams::read(const libcamera::YamlObject &params)\n> > >\n> > >  int Af::CfgParams::read(const libcamera::YamlObject &params)\n> > >  {\n> > > -\tif (params.contains(\"ranges\")) {\n> > > -\t\tauto &rr = params[\"ranges\"];\n> > > -\n> > > -\t\tif (rr.contains(\"normal\"))\n> > > -\t\t\tranges[AfRangeNormal].read(rr[\"normal\"]);\n> > > +\tif (auto *rs = params.find(\"ranges\")) {\n> > \n> > I would have kept the same variable name (rr) but that doesn't matter\n> > much.\n> > \n> > > +\t\tif (auto *normal = rs->find(\"normal\"))\n> > > +\t\t\tranges[AfRangeNormal].read(*normal);\n> > >  \t\telse\n> > >  \t\t\tLOG(RPiAf, Warning) << \"Missing range \\\"normal\\\"\";\n> > >\n> > >  \t\tranges[AfRangeMacro] = ranges[AfRangeNormal];\n> > > -\t\tif (rr.contains(\"macro\"))\n> > > -\t\t\tranges[AfRangeMacro].read(rr[\"macro\"]);\n> > > +\t\tif (auto *macro = rs->find(\"macro\"))\n> > > +\t\t\tranges[AfRangeMacro].read(*macro);\n> > >\n> > >  \t\tranges[AfRangeFull].focusMin = std::min(ranges[AfRangeNormal].focusMin,\n> > >  \t\t\t\t\t\t\tranges[AfRangeMacro].focusMin);\n> > >  \t\tranges[AfRangeFull].focusMax = std::max(ranges[AfRangeNormal].focusMax,\n> > >  \t\t\t\t\t\t\tranges[AfRangeMacro].focusMax);\n> > >  \t\tranges[AfRangeFull].focusDefault = ranges[AfRangeNormal].focusDefault;\n> > > -\t\tif (rr.contains(\"full\"))\n> > > -\t\t\tranges[AfRangeFull].read(rr[\"full\"]);\n> > > +\t\tif (auto *full = rs->find(\"full\"))\n> > > +\t\t\tranges[AfRangeFull].read(*full);\n> > >  \t} else\n> > >  \t\tLOG(RPiAf, Warning) << \"No ranges defined\";\n> > >\n> > > -\tif (params.contains(\"speeds\")) {\n> > > -\t\tauto &ss = params[\"speeds\"];\n> > > -\n> > > -\t\tif (ss.contains(\"normal\"))\n> > > -\t\t\tspeeds[AfSpeedNormal].read(ss[\"normal\"]);\n> > > +\tif (auto *ss = params.find(\"speeds\")) {\n> > > +\t\tif (auto *normal = ss->find(\"normal\"))\n> > > +\t\t\tspeeds[AfSpeedNormal].read(*normal);\n> > >  \t\telse\n> > >  \t\t\tLOG(RPiAf, Warning) << \"Missing speed \\\"normal\\\"\";\n> > >\n> > >  \t\tspeeds[AfSpeedFast] = speeds[AfSpeedNormal];\n> > > -\t\tif (ss.contains(\"fast\"))\n> > > -\t\t\tspeeds[AfSpeedFast].read(ss[\"fast\"]);\n> > > +\t\tif (auto *fast = ss->find(\"fast\"))\n> > > +\t\t\tspeeds[AfSpeedFast].read(*fast);\n> > >  \t} else\n> > >  \t\tLOG(RPiAf, Warning) << \"No speeds defined\";\n> > >\n> > > @@ -138,8 +134,8 @@ int Af::CfgParams::read(const libcamera::YamlObject &params)\n> > >  \treadNumber<uint32_t>(confClip, params, \"conf_clip\");\n> > >  \treadNumber<uint32_t>(skipFrames, params, \"skip_frames\");\n> > >\n> > > -\tif (params.contains(\"map\"))\n> > > -\t\tmap = params[\"map\"].get<ipa::Pwl>(ipa::Pwl{});\n> > > +\tif (auto *m = params.find(\"map\"))\n> > > +\t\tmap = m->get<ipa::Pwl>(ipa::Pwl{});\n> > >  \telse\n> > >  \t\tLOG(RPiAf, Warning) << \"No map defined\";\n> > >\n> > > diff --git a/src/ipa/rpi/controller/rpi/agc.cpp b/src/ipa/rpi/controller/rpi/agc.cpp\n> > > index c48fdf15..5d924ebf 100644\n> > > --- a/src/ipa/rpi/controller/rpi/agc.cpp\n> > > +++ b/src/ipa/rpi/controller/rpi/agc.cpp\n> > > @@ -37,18 +37,18 @@ int Agc::read(const libcamera::YamlObject &params)\n> > >  \t * When there is only a single channel we can read the old style syntax.\n> > >  \t * Otherwise we expect a \"channels\" keyword followed by a list of configurations.\n> > >  \t */\n> > > -\tif (!params.contains(\"channels\")) {\n> > > +\tauto *channels = params.find(\"channels\");\n> > > +\tif (!channels) {\n> > >  \t\tLOG(RPiAgc, Debug) << \"Single channel only\";\n> > >  \t\tchannelTotalExposures_.resize(1, 0s);\n> > >  \t\tchannelData_.emplace_back();\n> > >  \t\treturn channelData_.back().channel.read(params, getHardwareConfig());\n> > >  \t}\n> > >\n> > > -\tconst auto &channels = params[\"channels\"].asList();\n> > > -\tfor (auto ch = channels.begin(); ch != channels.end(); ch++) {\n> > > +\tfor (const auto &ch : channels->asList()) {\n> > >  \t\tLOG(RPiAgc, Debug) << \"Read AGC channel\";\n> > >  \t\tchannelData_.emplace_back();\n> > > -\t\tint ret = channelData_.back().channel.read(*ch, getHardwareConfig());\n> > > +\t\tint ret = channelData_.back().channel.read(ch, getHardwareConfig());\n> > >  \t\tif (ret)\n> > >  \t\t\treturn ret;\n> > >  \t}\n> > > diff --git a/src/ipa/rpi/controller/rpi/agc_channel.cpp b/src/ipa/rpi/controller/rpi/agc_channel.cpp\n> > > index 79c45973..50b9efd2 100644\n> > > --- a/src/ipa/rpi/controller/rpi/agc_channel.cpp\n> > > +++ b/src/ipa/rpi/controller/rpi/agc_channel.cpp\n> > > @@ -235,8 +235,8 @@ int AgcConfig::read(const libcamera::YamlObject &params)\n> > >  \tif (ret)\n> > >  \t\treturn ret;\n> > >\n> > > -\tif (params.contains(\"channel_constraints\")) {\n> > > -\t\tret = readChannelConstraints(channelConstraints, params[\"channel_constraints\"]);\n> > > +\tif (auto *cc = params.find(\"channel_constraints\")) {\n> > > +\t\tret = readChannelConstraints(channelConstraints, *cc);\n> > >  \t\tif (ret)\n> > >  \t\t\treturn ret;\n> > >  \t}\n> > > diff --git a/src/ipa/rpi/controller/rpi/alsc.cpp b/src/ipa/rpi/controller/rpi/alsc.cpp\n> > > index 21edb819..5a1a702b 100644\n> > > --- a/src/ipa/rpi/controller/rpi/alsc.cpp\n> > > +++ b/src/ipa/rpi/controller/rpi/alsc.cpp\n> > > @@ -104,9 +104,9 @@ static int readCalibrations(std::vector<AlscCalibration> &calibrations,\n> > >  \t\t\t    const libcamera::YamlObject &params,\n> > >  \t\t\t    std::string const &name, const Size &size)\n> > >  {\n> > > -\tif (params.contains(name)) {\n> > > +\tif (auto *param = params.find(name)) {\n> > >  \t\tdouble lastCt = 0;\n> > > -\t\tfor (const auto &p : params[name].asList()) {\n> > > +\t\tfor (const auto &p : param->asList()) {\n> > >  \t\t\tauto value = p[\"ct\"].get<double>();\n> > >  \t\t\tif (!value)\n> > >  \t\t\t\treturn -EINVAL;\n> > > @@ -163,10 +163,10 @@ int Alsc::read(const libcamera::YamlObject &params)\n> > >  \tconfig_.luminanceLut.resize(config_.tableSize, 1.0);\n> > >  \tint ret = 0;\n> > >\n> > > -\tif (params.contains(\"corner_strength\"))\n> > > +\tif (params.find(\"corner_strength\"))\n> > >  \t\tret = generateLut(config_.luminanceLut, params);\n> > > -\telse if (params.contains(\"luminance_lut\"))\n> > > -\t\tret = readLut(config_.luminanceLut, params[\"luminance_lut\"]);\n> > > +\telse if (auto *ll = params.find(\"luminance_lut\"))\n> > > +\t\tret = readLut(config_.luminanceLut, *ll);\n> > >  \telse\n> > >  \t\tLOG(RPiAlsc, Warning)\n> > >  \t\t\t<< \"no luminance table - assume unity everywhere\";\n> > > diff --git a/src/ipa/rpi/controller/rpi/awb.cpp b/src/ipa/rpi/controller/rpi/awb.cpp\n> > > index c277a176..2e6e295c 100644\n> > > --- a/src/ipa/rpi/controller/rpi/awb.cpp\n> > > +++ b/src/ipa/rpi/controller/rpi/awb.cpp\n> > > @@ -102,8 +102,8 @@ int AwbConfig::read(const libcamera::YamlObject &params)\n> > >  \tconvergenceFrames = params[\"convergence_frames\"].get<unsigned int>(3);\n> > >  \tspeed = params[\"speed\"].get<double>(0.05);\n> > >\n> > > -\tif (params.contains(\"ct_curve\")) {\n> > > -\t\tret = readCtCurve(ctR, ctB, params[\"ct_curve\"]);\n> > > +\tif (auto *ct_curve = params.find(\"ct_curve\")) {\n> > > +\t\tret = readCtCurve(ctR, ctB, *ct_curve);\n> > >  \t\tif (ret)\n> > >  \t\t\treturn ret;\n> > >  \t\t/* We will want the inverse functions of these too. */\n> > > @@ -111,8 +111,8 @@ int AwbConfig::read(const libcamera::YamlObject &params)\n> > >  \t\tctBInverse = ctB.inverse().first;\n> > >  \t}\n> > >\n> > > -\tif (params.contains(\"priors\")) {\n> > > -\t\tfor (const auto &p : params[\"priors\"].asList()) {\n> > > +\tif (auto *ps = params.find(\"priors\")) {\n> > > +\t\tfor (const auto &p : ps->asList()) {\n> > >  \t\t\tAwbPrior prior;\n> > >  \t\t\tret = prior.read(p);\n> > >  \t\t\tif (ret)\n> > > @@ -128,8 +128,8 @@ int AwbConfig::read(const libcamera::YamlObject &params)\n> > >  \t\t\treturn -EINVAL;\n> > >  \t\t}\n> > >  \t}\n> > > -\tif (params.contains(\"modes\")) {\n> > > -\t\tfor (const auto &[key, value] : params[\"modes\"].asDict()) {\n> > > +\tif (auto *ms = params.find(\"modes\")) {\n> > > +\t\tfor (const auto &[key, value] : ms->asDict()) {\n> > >  \t\t\tret = modes[key].read(value);\n> > >  \t\t\tif (ret)\n> > >  \t\t\t\treturn ret;\n> > > diff --git a/src/ipa/rpi/controller/rpi/ccm.cpp b/src/ipa/rpi/controller/rpi/ccm.cpp\n> > > index 8607f152..5616e5f4 100644\n> > > --- a/src/ipa/rpi/controller/rpi/ccm.cpp\n> > > +++ b/src/ipa/rpi/controller/rpi/ccm.cpp\n> > > @@ -41,8 +41,8 @@ char const *Ccm::name() const\n> > >\n> > >  int Ccm::read(const libcamera::YamlObject &params)\n> > >  {\n> > > -\tif (params.contains(\"saturation\")) {\n> > > -\t\tconfig_.saturation = params[\"saturation\"].get<ipa::Pwl>(ipa::Pwl{});\n> > > +\tif (auto *s = params.find(\"saturation\")) {\n> > > +\t\tconfig_.saturation = s->get<ipa::Pwl>(ipa::Pwl{});\n> > >  \t\tif (config_.saturation.empty())\n> > >  \t\t\treturn -EINVAL;\n> > >  \t}\n> > > diff --git a/src/ipa/rpi/controller/rpi/geq.cpp b/src/ipa/rpi/controller/rpi/geq.cpp\n> > > index 40e7191b..6935f726 100644\n> > > --- a/src/ipa/rpi/controller/rpi/geq.cpp\n> > > +++ b/src/ipa/rpi/controller/rpi/geq.cpp\n> > > @@ -43,8 +43,8 @@ int Geq::read(const libcamera::YamlObject &params)\n> > >  \t\treturn -EINVAL;\n> > >  \t}\n> > >\n> > > -\tif (params.contains(\"strength\")) {\n> > > -\t\tconfig_.strength = params[\"strength\"].get<ipa::Pwl>(ipa::Pwl{});\n> > > +\tif (auto *strength = params.find(\"strength\")) {\n> > > +\t\tconfig_.strength = strength->get<ipa::Pwl>(ipa::Pwl{});\n> > >  \t\tif (config_.strength.empty())\n> > >  \t\t\treturn -EINVAL;\n> > >  \t}\n> > > diff --git a/src/ipa/rpi/controller/rpi/hdr.cpp b/src/ipa/rpi/controller/rpi/hdr.cpp\n> > > index f3da8291..20b1ff4b 100644\n> > > --- a/src/ipa/rpi/controller/rpi/hdr.cpp\n> > > +++ b/src/ipa/rpi/controller/rpi/hdr.cpp\n> > > @@ -27,9 +27,10 @@ void HdrConfig::read(const libcamera::YamlObject &params, const std::string &mod\n> > >  {\n> > >  \tname = modeName;\n> > >\n> > > -\tif (!params.contains(\"cadence\"))\n> > > +\tauto *c = params.find(\"cadence\");\n> > > +\tif (!c)\n> > >  \t\tLOG(RPiHdr, Fatal) << \"No cadence for HDR mode \" << name;\n> > > -\tcadence = params[\"cadence\"].getList<unsigned int>().value();\n> > > +\tcadence = c->getList<unsigned int>().value();\n> > >  \tif (cadence.empty())\n> > >  \t\tLOG(RPiHdr, Fatal) << \"Empty cadence in HDR mode \" << name;\n> > >\n> > > @@ -41,10 +42,10 @@ void HdrConfig::read(const libcamera::YamlObject &params, const std::string &mod\n> > >  \t\tchannelMap[v.get<unsigned int>().value()] = k;\n> > >\n> > >  \t/* Lens shading related parameters. */\n> > > -\tif (params.contains(\"spatial_gain_curve\")) {\n> > > -\t\tspatialGainCurve = params[\"spatial_gain_curve\"].get<ipa::Pwl>(ipa::Pwl{});\n> > > -\t} else if (params.contains(\"spatial_gain\")) {\n> > > -\t\tdouble spatialGain = params[\"spatial_gain\"].get<double>(2.0);\n> > > +\tif (auto *sgc = params.find(\"spatial_gain_curve\")) {\n> > > +\t\tspatialGainCurve = sgc->get<ipa::Pwl>(ipa::Pwl{});\n> > > +\t} else if (auto *sg = params.find(\"spatial_gain\")) {\n> > > +\t\tdouble spatialGain = sg->get<double>(2.0);\n> > >  \t\tspatialGainCurve.append(0.0, spatialGain);\n> > >  \t\tspatialGainCurve.append(0.01, spatialGain);\n> > >  \t\tspatialGainCurve.append(0.06, 1.0); /* maybe make this programmable? */\n> > > @@ -68,24 +69,24 @@ void HdrConfig::read(const libcamera::YamlObject &params, const std::string &mod\n> > >  \tif (tonemapEnable)\n> > >  \t\ttonemap = params[\"tonemap\"].get<ipa::Pwl>(ipa::Pwl{});\n> > >  \tspeed = params[\"speed\"].get<double>(1.0);\n> > > -\tif (params.contains(\"hi_quantile_targets\")) {\n> > > -\t\thiQuantileTargets = params[\"hi_quantile_targets\"].getList<double>().value();\n> > > +\tif (auto *hqt = params.find(\"hi_quantile_targets\")) {\n> > > +\t\thiQuantileTargets = hqt->getList<double>().value();\n> > >  \t\tif (hiQuantileTargets.empty() || hiQuantileTargets.size() % 2)\n> > >  \t\t\tLOG(RPiHdr, Fatal) << \"hi_quantile_targets much be even and non-empty\";\n> > >  \t} else\n> > >  \t\thiQuantileTargets = { 0.95, 0.65, 0.5, 0.28, 0.3, 0.25 };\n> > >  \thiQuantileMaxGain = params[\"hi_quantile_max_gain\"].get<double>(1.6);\n> > > -\tif (params.contains(\"quantile_targets\")) {\n> > > -\t\tquantileTargets = params[\"quantile_targets\"].getList<double>().value();\n> > > +\tif (auto *qt = params.find(\"quantile_targets\")) {\n> > > +\t\tquantileTargets = qt->getList<double>().value();\n> > >  \t\tif (quantileTargets.empty() || quantileTargets.size() % 2)\n> > >  \t\t\tLOG(RPiHdr, Fatal) << \"quantile_targets much be even and non-empty\";\n> > >  \t} else\n> > >  \t\tquantileTargets = { 0.2, 0.03, 1.0, 0.15 };\n> > >  \tpowerMin = params[\"power_min\"].get<double>(0.65);\n> > >  \tpowerMax = params[\"power_max\"].get<double>(1.0);\n> > > -\tif (params.contains(\"contrast_adjustments\")) {\n> > > -\t\tcontrastAdjustments = params[\"contrast_adjustments\"].getList<double>().value();\n> > > -\t} else\n> > > +\tif (auto *ca = params.find(\"contrast_adjustments\"))\n> > > +\t\tcontrastAdjustments = ca->getList<double>().value();\n> > > +\telse\n> > >  \t\tcontrastAdjustments = { 0.5, 0.75 };\n> > >\n> > >  \t/* Read any stitch parameters. */\n> > > diff --git a/src/ipa/simple/soft_simple.cpp b/src/ipa/simple/soft_simple.cpp\n> > > index e1b6d3af..ca3fe487 100644\n> > > --- a/src/ipa/simple/soft_simple.cpp\n> > > +++ b/src/ipa/simple/soft_simple.cpp\n> > > @@ -114,12 +114,13 @@ int IPASoftSimple::init(const IPASettings &settings,\n> > >  \tunsigned int version = (*data)[\"version\"].get<uint32_t>(0);\n> > >  \tLOG(IPASoft, Debug) << \"Tuning file version \" << version;\n> > >\n> > > -\tif (!data->contains(\"algorithms\")) {\n> > > +\tauto *algos = data->find(\"algorithms\");\n> > > +\tif (!algos) {\n> > >  \t\tLOG(IPASoft, Error) << \"Tuning file doesn't contain algorithms\";\n> > >  \t\treturn -EINVAL;\n> > >  \t}\n> > >\n> > > -\tint ret = createAlgorithms(context_, (*data)[\"algorithms\"]);\n> > > +\tint ret = createAlgorithms(context_, *algos);\n> > >  \tif (ret)\n> > >  \t\treturn ret;\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 551E5C32CE\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon,  9 Dec 2024 21:21:42 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 6C35467E73;\n\tMon,  9 Dec 2024 22:21:41 +0100 (CET)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 9C46F66132\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon,  9 Dec 2024 22:21:39 +0100 (CET)","from pendragon.ideasonboard.com (81-175-209-231.bb.dnainternet.fi\n\t[81.175.209.231])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 82F3D502;\n\tMon,  9 Dec 2024 22:21:07 +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=\"p7Cks3jj\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1733779267;\n\tbh=t2JyOKA1t4Eu9BNJiKteQZO5t8V4mwAwgosh7CTcHl0=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=p7Cks3jjuwHPpbvSWT48EW3rtJpW8xGomAcrbptmvUtvS2vn1WDUghuBcRAs7OjPW\n\teafxalVLTR4logL69ECwsQg2qPOhPu3R/Sn/SoQuFHJ639zXc0RZ3/FPHY1/oxJl6C\n\twdpdFjuVeRTWbKl5H2CamAzD8IsmfVgiYGdhab5A=","Date":"Mon, 9 Dec 2024 23:21:24 +0200","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"=?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= <pobrn@protonmail.com>","Cc":"libcamera-devel@lists.libcamera.org","Subject":"Re: [PATCH v1 2/3] treewide: Use `YamlObject::find()`","Message-ID":"<20241209212124.GA26531@pendragon.ideasonboard.com>","References":"<20241205163411.1160094-1-pobrn@protonmail.com>\n\t<20241205163411.1160094-2-pobrn@protonmail.com>\n\t<20241206010932.GL21014@pendragon.ideasonboard.com>\n\t<Ef3UXUsEIxddqbie9PI1tW0qmU2ik-QuS7dUq4de81TptTe_dBh8pUGRtykZVEloMA-i0O8wHZ81pLfQNrgJ7_r3MFNJryV3Zz1uLqaTv64=@protonmail.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","Content-Transfer-Encoding":"8bit","In-Reply-To":"<Ef3UXUsEIxddqbie9PI1tW0qmU2ik-QuS7dUq4de81TptTe_dBh8pUGRtykZVEloMA-i0O8wHZ81pLfQNrgJ7_r3MFNJryV3Zz1uLqaTv64=@protonmail.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>"}}]