[{"id":37688,"web_url":"https://patchwork.libcamera.org/comment/37688/","msgid":"<176856240652.3486172.11573500719935235502@ping.linuxembedded.co.uk>","date":"2026-01-16T11:20:06","subject":"Re: [PATCH v1 3/3] libcamera: base: utils: Fix names of `operator<<`\n\tfor `Duration`","submitter":{"id":4,"url":"https://patchwork.libcamera.org/api/people/4/","name":"Kieran Bingham","email":"kieran.bingham@ideasonboard.com"},"content":"Quoting Barnabás Pőcze (2026-01-15 11:16:30)\n> In order for ADL to find the function, it must be in the namespace of any of\n> its arguments. Previously, however, that was not the case, and it has only\n> really worked by accident and could be easily made to fail by introducing\n> other `operator<<` overloads.\n> \n> For example, a user of this function in `libcamera::ipa` would no longer\n> compile after introducing an `operator<<` into the `libcamera::ipa`\n> namespace as that would essentially hide this overload, and without ADL\n> it would not be found.\n\nI see - this was where all my pain was trying to add operator<< to\nQuantized! Thank you for digging through it!\n\n> So move the function into the `utils` namespace.\n> \n\nLooks very reasonable to me:\n\nReviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n\n> Fixes: 5055ca747c4c (\"libcamera: utils: Add helper class for std::chrono::duration\")\n> Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>\n> ---\n>  include/libcamera/base/utils.h | 6 +++---\n>  src/libcamera/base/utils.cpp   | 6 +++---\n>  2 files changed, 6 insertions(+), 6 deletions(-)\n> \n> diff --git a/include/libcamera/base/utils.h b/include/libcamera/base/utils.h\n> index 6ce1ace43..fc4f5079c 100644\n> --- a/include/libcamera/base/utils.h\n> +++ b/include/libcamera/base/utils.h\n> @@ -423,10 +423,10 @@ scope_exit(EF) -> scope_exit<EF>;\n>  \n>  #endif /* __DOXYGEN__ */\n>  \n> -} /* namespace utils */\n> -\n>  #ifndef __DOXYGEN__\n> -std::ostream &operator<<(std::ostream &os, const utils::Duration &d);\n> +std::ostream &operator<<(std::ostream &os, const Duration &d);\n>  #endif\n>  \n> +} /* namespace utils */\n> +\n>  } /* namespace libcamera */\n> diff --git a/src/libcamera/base/utils.cpp b/src/libcamera/base/utils.cpp\n> index 2c3f2b7e6..42a516097 100644\n> --- a/src/libcamera/base/utils.cpp\n> +++ b/src/libcamera/base/utils.cpp\n> @@ -655,10 +655,8 @@ void ScopeExitActions::release()\n>         actions_.clear();\n>  }\n>  \n> -} /* namespace utils */\n> -\n>  #ifndef __DOXYGEN__\n> -std::ostream &operator<<(std::ostream &os, const utils::Duration &d)\n> +std::ostream &operator<<(std::ostream &os, const Duration &d)\n>  {\n>         std::ostringstream s;\n>  \n> @@ -671,4 +669,6 @@ std::ostream &operator<<(std::ostream &os, const utils::Duration &d)\n>  }\n>  #endif\n>  \n> +} /* namespace utils */\n> +\n>  } /* namespace libcamera */\n> -- \n> 2.52.0\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 CCCB8BDCBF\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri, 16 Jan 2026 11:20:11 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 9BA3161FBC;\n\tFri, 16 Jan 2026 12:20:10 +0100 (CET)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id E6258615B2\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 16 Jan 2026 12:20:09 +0100 (CET)","from pendragon.ideasonboard.com\n\t(cpc89244-aztw30-2-0-cust6594.18-1.cable.virginm.net [86.31.185.195])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 8DB4A3D7;\n\tFri, 16 Jan 2026 12:19:41 +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=\"dLufnO1K\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1768562381;\n\tbh=MGPsk9PQKuMZKGEq2HlJ3XOn2lBoaO63e28wJ+yAf3s=;\n\th=In-Reply-To:References:Subject:From:To:Date:From;\n\tb=dLufnO1KIrP0AmJL037m8nGNzHBYU6nahy6u/5yttC8iHviB4KpkPAgRHEKFng4a8\n\tcEXjQHqcMWGYNQPiio046xsBULKG6TY0YNwWlIZpQ4lQJlhjoL5TE7R3xJ87J2nwBq\n\tmAmG0RxOtn4UFZjtqglk/8FFRZi418ELwUtIggtg=","Content-Type":"text/plain; charset=\"utf-8\"","MIME-Version":"1.0","Content-Transfer-Encoding":"quoted-printable","In-Reply-To":"<20260115111630.1892890-3-barnabas.pocze@ideasonboard.com>","References":"<20260115111630.1892890-1-barnabas.pocze@ideasonboard.com>\n\t<20260115111630.1892890-3-barnabas.pocze@ideasonboard.com>","Subject":"Re: [PATCH v1 3/3] libcamera: base: utils: Fix names of `operator<<`\n\tfor `Duration`","From":"Kieran Bingham <kieran.bingham@ideasonboard.com>","To":"=?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= <barnabas.pocze@ideasonboard.com>,\n\tlibcamera-devel@lists.libcamera.org","Date":"Fri, 16 Jan 2026 11:20:06 +0000","Message-ID":"<176856240652.3486172.11573500719935235502@ping.linuxembedded.co.uk>","User-Agent":"alot/0.9.1","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":37821,"web_url":"https://patchwork.libcamera.org/comment/37821/","msgid":"<176901622537.1693075.3691633373448343174@ping.linuxembedded.co.uk>","date":"2026-01-21T17:23:45","subject":"Re: [PATCH v1 3/3] libcamera: base: utils: Fix names of `operator<<`\n\tfor `Duration`","submitter":{"id":4,"url":"https://patchwork.libcamera.org/api/people/4/","name":"Kieran Bingham","email":"kieran.bingham@ideasonboard.com"},"content":"Quoting Barnabás Pőcze (2026-01-15 11:16:30)\n> In order for ADL to find the function, it must be in the namespace of any of\n> its arguments. Previously, however, that was not the case, and it has only\n> really worked by accident and could be easily made to fail by introducing\n> other `operator<<` overloads.\n> \n> For example, a user of this function in `libcamera::ipa` would no longer\n> compile after introducing an `operator<<` into the `libcamera::ipa`\n> namespace as that would essentially hide this overload, and without ADL\n> it would not be found.\n> \n> So move the function into the `utils` namespace.\n> \n> Fixes: 5055ca747c4c (\"libcamera: utils: Add helper class for std::chrono::duration\")\n> Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>\n> ---\n\nSo with these three patches I can successfully apply the following to my\nQuantized series:\n\ndiff --git a/src/ipa/libipa/quantized.cpp b/src/ipa/libipa/quantized.cpp\nindex 06143a97ab3e..67b79ca7b865 100644\n--- a/src/ipa/libipa/quantized.cpp\n+++ b/src/ipa/libipa/quantized.cpp\n@@ -123,7 +123,7 @@ namespace ipa {\n  */\n\n /**\n- * \\fn std::ostream &Quantized::operator<<(std::ostream &out, const Quantized<Traits> &q)\n+ * \\fn std::ostream &operator<<(std::ostream &out, const Quantized<Traits> &q)\n  * \\brief Insert a text representation of a Quantized into an output stream\n  * \\param[in] out The output stream\n  * \\param[in] q The Quantized\ndiff --git a/src/ipa/libipa/quantized.h b/src/ipa/libipa/quantized.h\nindex 0b2f7148c821..b3ae3520b5d8 100644\n--- a/src/ipa/libipa/quantized.h\n+++ b/src/ipa/libipa/quantized.h\n@@ -56,20 +56,21 @@ struct Quantized {\n \t\treturn !(*this == other);\n \t}\n\n-\tfriend std::ostream &operator<<(std::ostream &out,\n-\t\t\t\t\tconst Quantized<Traits> &q)\n-\t{\n-\t\tout << \"[\" << utils::hex(q.quantized())\n-\t\t    << \":\" << q.value() << \"]\";\n-\n-\t\treturn out;\n-\t}\n-\n private:\n \tQuantizedType quantized_;\n \tfloat value_;\n };\n\n+template<typename Traits>\n+std::ostream &operator<<(std::ostream &out,\n+\t\t\t const Quantized<Traits> &q)\n+{\n+\tout << \"[\" << utils::hex(q.quantized())\n+\t    << \":\" << q.value() << \"]\";\n+\n+\treturn out;\n+}\n+\n } /* namespace ipa */\n\n } /* namespace libcamera */\n\n\nand put the operator<< back outside of the Quantized class (though still\ntemplated in the header).\n\nAs this series isn't merged yet - I'll keep this out of the v6 posting,\nbut could be moved on top or included in this series depending on what\nwins the race.\n\n--\nKieran","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 A2A04C3220\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed, 21 Jan 2026 17:23:52 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id EEF8B61FC4;\n\tWed, 21 Jan 2026 18:23:51 +0100 (CET)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 3C86E61F9F\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 21 Jan 2026 18:23:51 +0100 (CET)","from pendragon.ideasonboard.com\n\t(cpc89244-aztw30-2-0-cust6594.18-1.cable.virginm.net [86.31.185.195])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id B8393741;\n\tWed, 21 Jan 2026 18:23: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=\"KDDDvz5f\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1769016196;\n\tbh=5RLVzAjRu+8rtD2VJhDCN5BtCGkg0NPiD/SFbO7ocfA=;\n\th=In-Reply-To:References:Subject:From:To:Date:From;\n\tb=KDDDvz5fS8wnrNypExX06I5o/HqunF0Kgwpag/m8hrXjbY+4KolIWjDc376+EBIrp\n\tEJwZwWDmpXlNkAza2NldAeJsvrqv9FcEyGqr3AwRQk7+4wSZfKutouNjWo3yKlMZmB\n\tIlTZyQwfaJDPz+sJPuKsE7jXfrr0sUq71nXJdVkA=","Content-Type":"text/plain; charset=\"utf-8\"","MIME-Version":"1.0","Content-Transfer-Encoding":"quoted-printable","In-Reply-To":"<20260115111630.1892890-3-barnabas.pocze@ideasonboard.com>","References":"<20260115111630.1892890-1-barnabas.pocze@ideasonboard.com>\n\t<20260115111630.1892890-3-barnabas.pocze@ideasonboard.com>","Subject":"Re: [PATCH v1 3/3] libcamera: base: utils: Fix names of `operator<<`\n\tfor `Duration`","From":"Kieran Bingham <kieran.bingham@ideasonboard.com>","To":"=?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= <barnabas.pocze@ideasonboard.com>,\n\tlibcamera-devel@lists.libcamera.org","Date":"Wed, 21 Jan 2026 17:23:45 +0000","Message-ID":"<176901622537.1693075.3691633373448343174@ping.linuxembedded.co.uk>","User-Agent":"alot/0.9.1","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":37832,"web_url":"https://patchwork.libcamera.org/comment/37832/","msgid":"<20260122012203.GK21091@killaraus>","date":"2026-01-22T01:22:03","subject":"Re: [PATCH v1 3/3] libcamera: base: utils: Fix names of `operator<<`\n\tfor `Duration`","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, Jan 15, 2026 at 12:16:30PM +0100, Barnabás Pőcze wrote:\n> In order for ADL to find the function, it must be in the namespace of any of\n> its arguments. Previously, however, that was not the case, and it has only\n> really worked by accident and could be easily made to fail by introducing\n> other `operator<<` overloads.\n> \n> For example, a user of this function in `libcamera::ipa` would no longer\n> compile after introducing an `operator<<` into the `libcamera::ipa`\n> namespace as that would essentially hide this overload, and without ADL\n> it would not be found.\n> \n> So move the function into the `utils` namespace.\n\nI understand we can't mix, but Would defining all our operator<<() in\nthe libcamera namespace work too ? If so, is the approach in this patch\npreferred ?\n\n> Fixes: 5055ca747c4c (\"libcamera: utils: Add helper class for std::chrono::duration\")\n> Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>\n\nReviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n\n> ---\n>  include/libcamera/base/utils.h | 6 +++---\n>  src/libcamera/base/utils.cpp   | 6 +++---\n>  2 files changed, 6 insertions(+), 6 deletions(-)\n> \n> diff --git a/include/libcamera/base/utils.h b/include/libcamera/base/utils.h\n> index 6ce1ace43..fc4f5079c 100644\n> --- a/include/libcamera/base/utils.h\n> +++ b/include/libcamera/base/utils.h\n> @@ -423,10 +423,10 @@ scope_exit(EF) -> scope_exit<EF>;\n>  \n>  #endif /* __DOXYGEN__ */\n>  \n> -} /* namespace utils */\n> -\n>  #ifndef __DOXYGEN__\n> -std::ostream &operator<<(std::ostream &os, const utils::Duration &d);\n> +std::ostream &operator<<(std::ostream &os, const Duration &d);\n>  #endif\n>  \n> +} /* namespace utils */\n> +\n>  } /* namespace libcamera */\n> diff --git a/src/libcamera/base/utils.cpp b/src/libcamera/base/utils.cpp\n> index 2c3f2b7e6..42a516097 100644\n> --- a/src/libcamera/base/utils.cpp\n> +++ b/src/libcamera/base/utils.cpp\n> @@ -655,10 +655,8 @@ void ScopeExitActions::release()\n>  \tactions_.clear();\n>  }\n>  \n> -} /* namespace utils */\n> -\n>  #ifndef __DOXYGEN__\n> -std::ostream &operator<<(std::ostream &os, const utils::Duration &d)\n> +std::ostream &operator<<(std::ostream &os, const Duration &d)\n>  {\n>  \tstd::ostringstream s;\n>  \n> @@ -671,4 +669,6 @@ std::ostream &operator<<(std::ostream &os, const utils::Duration &d)\n>  }\n>  #endif\n>  \n> +} /* namespace utils */\n> +\n>  } /* namespace libcamera */","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 5A289BDCBF\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu, 22 Jan 2026 01:22:07 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 3DC5161FC4;\n\tThu, 22 Jan 2026 02:22:06 +0100 (CET)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id F13C461A35\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 22 Jan 2026 02:22:04 +0100 (CET)","from pendragon.ideasonboard.com\n\t(2001-14ba-703d-e500--ff4.rev.dnainternet.fi\n\t[IPv6:2001:14ba:703d:e500::ff4])\n\tby perceval.ideasonboard.com (Postfix) with UTF8SMTPSA id 721C2162B; \n\tThu, 22 Jan 2026 02:21:32 +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=\"SRk2f/wP\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1769044892;\n\tbh=2v6kuD2/pEG7/5yS1v+ILN9+jSdYCdW6E0962UPlxhg=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=SRk2f/wPDDHBhbVOwOHjq8X9I1U5YDtVCiW3sLdfRQrKsR5LACKQZqPi4dsTJbYN5\n\tH+Ta9xxsXUrGvSBLiY3PCQ86RLPdaGeC5oIC1+O9/4g0asqJy5/VvTPkCM290WAaeN\n\tN9f2+UTwBeBBIYdeZ7IQtVPyD8eTNyqaCeH2rvxo=","Date":"Thu, 22 Jan 2026 03:22:03 +0200","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"=?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= <barnabas.pocze@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org","Subject":"Re: [PATCH v1 3/3] libcamera: base: utils: Fix names of `operator<<`\n\tfor `Duration`","Message-ID":"<20260122012203.GK21091@killaraus>","References":"<20260115111630.1892890-1-barnabas.pocze@ideasonboard.com>\n\t<20260115111630.1892890-3-barnabas.pocze@ideasonboard.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","Content-Transfer-Encoding":"8bit","In-Reply-To":"<20260115111630.1892890-3-barnabas.pocze@ideasonboard.com>","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":37942,"web_url":"https://patchwork.libcamera.org/comment/37942/","msgid":"<ccc78339-e0be-4d87-a7cc-03db181e5b5f@ideasonboard.com>","date":"2026-01-26T12:04:36","subject":"Re: [PATCH v1 3/3] libcamera: base: utils: Fix names of `operator<<`\n\tfor `Duration`","submitter":{"id":216,"url":"https://patchwork.libcamera.org/api/people/216/","name":"Barnabás Pőcze","email":"barnabas.pocze@ideasonboard.com"},"content":"2026. 01. 22. 2:22 keltezéssel, Laurent Pinchart írta:\n> Hi Barnabás,\n> \n> Thank you for the patch.\n> \n> On Thu, Jan 15, 2026 at 12:16:30PM +0100, Barnabás Pőcze wrote:\n>> In order for ADL to find the function, it must be in the namespace of any of\n>> its arguments. Previously, however, that was not the case, and it has only\n>> really worked by accident and could be easily made to fail by introducing\n>> other `operator<<` overloads.\n>>\n>> For example, a user of this function in `libcamera::ipa` would no longer\n>> compile after introducing an `operator<<` into the `libcamera::ipa`\n>> namespace as that would essentially hide this overload, and without ADL\n>> it would not be found.\n>>\n>> So move the function into the `utils` namespace.\n> \n> I understand we can't mix, but Would defining all our operator<<() in\n> the libcamera namespace work too ? If so, is the approach in this patch\n> preferred ?\n\nI think it would also solve it. But I can't really see a strong enough reason\nto deviate from the practice of using ADL for non-member `operator<<()`.\n\nSo my preference is very much to rely on ADL and define these operators in\nthe ADL-appropriate namespace.\n\n\n> \n>> Fixes: 5055ca747c4c (\"libcamera: utils: Add helper class for std::chrono::duration\")\n>> Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>\n> \n> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n> \n>> ---\n>>   include/libcamera/base/utils.h | 6 +++---\n>>   src/libcamera/base/utils.cpp   | 6 +++---\n>>   2 files changed, 6 insertions(+), 6 deletions(-)\n>>\n>> diff --git a/include/libcamera/base/utils.h b/include/libcamera/base/utils.h\n>> index 6ce1ace43..fc4f5079c 100644\n>> --- a/include/libcamera/base/utils.h\n>> +++ b/include/libcamera/base/utils.h\n>> @@ -423,10 +423,10 @@ scope_exit(EF) -> scope_exit<EF>;\n>>   \n>>   #endif /* __DOXYGEN__ */\n>>   \n>> -} /* namespace utils */\n>> -\n>>   #ifndef __DOXYGEN__\n>> -std::ostream &operator<<(std::ostream &os, const utils::Duration &d);\n>> +std::ostream &operator<<(std::ostream &os, const Duration &d);\n>>   #endif\n>>   \n>> +} /* namespace utils */\n>> +\n>>   } /* namespace libcamera */\n>> diff --git a/src/libcamera/base/utils.cpp b/src/libcamera/base/utils.cpp\n>> index 2c3f2b7e6..42a516097 100644\n>> --- a/src/libcamera/base/utils.cpp\n>> +++ b/src/libcamera/base/utils.cpp\n>> @@ -655,10 +655,8 @@ void ScopeExitActions::release()\n>>   \tactions_.clear();\n>>   }\n>>   \n>> -} /* namespace utils */\n>> -\n>>   #ifndef __DOXYGEN__\n>> -std::ostream &operator<<(std::ostream &os, const utils::Duration &d)\n>> +std::ostream &operator<<(std::ostream &os, const Duration &d)\n>>   {\n>>   \tstd::ostringstream s;\n>>   \n>> @@ -671,4 +669,6 @@ std::ostream &operator<<(std::ostream &os, const utils::Duration &d)\n>>   }\n>>   #endif\n>>   \n>> +} /* namespace utils */\n>> +\n>>   } /* namespace libcamera */\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 66238C3200\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 26 Jan 2026 12:04:43 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 2E28661FCB;\n\tMon, 26 Jan 2026 13:04:42 +0100 (CET)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 6C78461A35\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 26 Jan 2026 13:04:40 +0100 (CET)","from [192.168.33.36] (185.221.142.123.nat.pool.zt.hu\n\t[185.221.142.123])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id CF160557;\n\tMon, 26 Jan 2026 13:04:04 +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=\"ITgPZ0jp\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1769429044;\n\tbh=EP3MTO8++SnD5Tk2d9e1kXT6YwMHolEDQOl9KtJAbWU=;\n\th=Date:Subject:To:Cc:References:From:In-Reply-To:From;\n\tb=ITgPZ0jpuiOqM+Pkjpu4avvXdwYxymLF8vsNK0FqxNoXAsMIOQml5r43kdv7ALs5F\n\tjpIaM/o29ZsRTQxAJ/RBIzrkI12FCiuXIb6+HT8py/dU0PmxVxjkcFFLx4AwKtAkNU\n\t6Z5Bx3NJYxdrfJhbnjESid8HpTdxLwLXwOuFkSCI=","Message-ID":"<ccc78339-e0be-4d87-a7cc-03db181e5b5f@ideasonboard.com>","Date":"Mon, 26 Jan 2026 13:04:36 +0100","MIME-Version":"1.0","User-Agent":"Mozilla Thunderbird","Subject":"Re: [PATCH v1 3/3] libcamera: base: utils: Fix names of `operator<<`\n\tfor `Duration`","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org","References":"<20260115111630.1892890-1-barnabas.pocze@ideasonboard.com>\n\t<20260115111630.1892890-3-barnabas.pocze@ideasonboard.com>\n\t<20260122012203.GK21091@killaraus>","From":"=?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= <barnabas.pocze@ideasonboard.com>","Content-Language":"en-US, hu-HU","In-Reply-To":"<20260122012203.GK21091@killaraus>","Content-Type":"text/plain; charset=UTF-8; format=flowed","Content-Transfer-Encoding":"8bit","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":37943,"web_url":"https://patchwork.libcamera.org/comment/37943/","msgid":"<20260126120946.GD593812@killaraus>","date":"2026-01-26T12:09:46","subject":"Re: [PATCH v1 3/3] libcamera: base: utils: Fix names of `operator<<`\n\tfor `Duration`","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"On Mon, Jan 26, 2026 at 01:04:36PM +0100, Barnabás Pőcze wrote:\n> 2026. 01. 22. 2:22 keltezéssel, Laurent Pinchart írta:\n> > On Thu, Jan 15, 2026 at 12:16:30PM +0100, Barnabás Pőcze wrote:\n> >> In order for ADL to find the function, it must be in the namespace of any of\n> >> its arguments. Previously, however, that was not the case, and it has only\n> >> really worked by accident and could be easily made to fail by introducing\n> >> other `operator<<` overloads.\n> >>\n> >> For example, a user of this function in `libcamera::ipa` would no longer\n> >> compile after introducing an `operator<<` into the `libcamera::ipa`\n> >> namespace as that would essentially hide this overload, and without ADL\n> >> it would not be found.\n> >>\n> >> So move the function into the `utils` namespace.\n> > \n> > I understand we can't mix, but Would defining all our operator<<() in\n> > the libcamera namespace work too ? If so, is the approach in this patch\n> > preferred ?\n> \n> I think it would also solve it. But I can't really see a strong enough reason\n> to deviate from the practice of using ADL for non-member `operator<<()`.\n> \n> So my preference is very much to rely on ADL and define these operators in\n> the ADL-appropriate namespace.\n\nWorks for me.\n\n> >> Fixes: 5055ca747c4c (\"libcamera: utils: Add helper class for std::chrono::duration\")\n> >> Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>\n> > \n> > Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n> > \n> >> ---\n> >>   include/libcamera/base/utils.h | 6 +++---\n> >>   src/libcamera/base/utils.cpp   | 6 +++---\n> >>   2 files changed, 6 insertions(+), 6 deletions(-)\n> >>\n> >> diff --git a/include/libcamera/base/utils.h b/include/libcamera/base/utils.h\n> >> index 6ce1ace43..fc4f5079c 100644\n> >> --- a/include/libcamera/base/utils.h\n> >> +++ b/include/libcamera/base/utils.h\n> >> @@ -423,10 +423,10 @@ scope_exit(EF) -> scope_exit<EF>;\n> >>   \n> >>   #endif /* __DOXYGEN__ */\n> >>   \n> >> -} /* namespace utils */\n> >> -\n> >>   #ifndef __DOXYGEN__\n> >> -std::ostream &operator<<(std::ostream &os, const utils::Duration &d);\n> >> +std::ostream &operator<<(std::ostream &os, const Duration &d);\n> >>   #endif\n> >>   \n> >> +} /* namespace utils */\n> >> +\n> >>   } /* namespace libcamera */\n> >> diff --git a/src/libcamera/base/utils.cpp b/src/libcamera/base/utils.cpp\n> >> index 2c3f2b7e6..42a516097 100644\n> >> --- a/src/libcamera/base/utils.cpp\n> >> +++ b/src/libcamera/base/utils.cpp\n> >> @@ -655,10 +655,8 @@ void ScopeExitActions::release()\n> >>   \tactions_.clear();\n> >>   }\n> >>   \n> >> -} /* namespace utils */\n> >> -\n> >>   #ifndef __DOXYGEN__\n> >> -std::ostream &operator<<(std::ostream &os, const utils::Duration &d)\n> >> +std::ostream &operator<<(std::ostream &os, const Duration &d)\n> >>   {\n> >>   \tstd::ostringstream s;\n> >>   \n> >> @@ -671,4 +669,6 @@ std::ostream &operator<<(std::ostream &os, const utils::Duration &d)\n> >>   }\n> >>   #endif\n> >>   \n> >> +} /* namespace utils */\n> >> +\n> >>   } /* namespace libcamera */","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 C9A4AC3220\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 26 Jan 2026 12:09:50 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id F002D61FC5;\n\tMon, 26 Jan 2026 13:09:49 +0100 (CET)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id A73F461A35\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 26 Jan 2026 13:09:48 +0100 (CET)","from pendragon.ideasonboard.com\n\t(2001-14ba-703d-e500--2a1.rev.dnainternet.fi\n\t[IPv6:2001:14ba:703d:e500::2a1])\n\tby perceval.ideasonboard.com (Postfix) with UTF8SMTPSA id 0215D557;\n\tMon, 26 Jan 2026 13:09:12 +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=\"r1cdXBLw\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1769429353;\n\tbh=pUS16BJXUdFFdy4OBeA8fphWKlkG5LdlJ9UcgsLLuyI=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=r1cdXBLwNuNtTKuiSgn5zQFKuOQhiw5LnRkM0dS9SIyTCl7z4M9b/PkTTUsmV3Da3\n\t6KXqmQO8u+Fg9hy7TBDX3i/yL+OOR96nAibYmWZ0qh2egMPEPL89F9blb4hbBu3OoG\n\ty+imPEfQhsPYcaunRQfqlMlCnZ7wtrOu9xWJMSJM=","Date":"Mon, 26 Jan 2026 14:09:46 +0200","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"=?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= <barnabas.pocze@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org","Subject":"Re: [PATCH v1 3/3] libcamera: base: utils: Fix names of `operator<<`\n\tfor `Duration`","Message-ID":"<20260126120946.GD593812@killaraus>","References":"<20260115111630.1892890-1-barnabas.pocze@ideasonboard.com>\n\t<20260115111630.1892890-3-barnabas.pocze@ideasonboard.com>\n\t<20260122012203.GK21091@killaraus>\n\t<ccc78339-e0be-4d87-a7cc-03db181e5b5f@ideasonboard.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","Content-Transfer-Encoding":"8bit","In-Reply-To":"<ccc78339-e0be-4d87-a7cc-03db181e5b5f@ideasonboard.com>","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]