[{"id":38867,"web_url":"https://patchwork.libcamera.org/comment/38867/","msgid":"<177858418710.540047.6704551640464828764@ping.linuxembedded.co.uk>","date":"2026-05-12T11:09:47","subject":"Re: [PATCH v3 1/2] libcamera: libipa: Add right-shift operators to\n\tVector","submitter":{"id":4,"url":"https://patchwork.libcamera.org/api/people/4/","name":"Kieran Bingham","email":"kieran.bingham@ideasonboard.com"},"content":"Quoting Javier Tia (2026-05-11 21:23:28)\n> Add operator>> and operator>>= for right-shifting all elements by a\n> scalar shift amount. Both operate element-wise: operator>> returns a\n> new Vector with each element shifted, operator>>= shifts in place and\n> returns a reference to *this.\n> \n> The motivating use case is SwStatsCpu::finishFrame(), which right-shifts\n> three individual components of the RGB sum by the same sumShift_ value.\n> With these operators that becomes a single sum_ >>= sumShift_ expression.\n> \n> The private apply() helpers for non-mutating and mutating scalar\n> operations are templated on the scalar type so the existing operators\n> keep working with T while shift can pass an unsigned int. A\n> static_assert in each shift operator restricts them to integer element\n> types since right-shift is undefined on floating-point Vectors.\n> \n> Suggested-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>\n> Suggested-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n> Signed-off-by: Javier Tia <floss@jetm.me>\n> Reviewed-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>\n> ---\n>  include/libcamera/internal/vector.h | 22 ++++++++++++++++++----\n>  src/libcamera/vector.cpp            | 14 ++++++++++++++\n>  test/vector.cpp                     |  5 +++++\n>  3 files changed, 37 insertions(+), 4 deletions(-)\n> \n> diff --git a/include/libcamera/internal/vector.h b/include/libcamera/internal/vector.h\n> index ed7490e1..e3ea723d 100644\n> --- a/include/libcamera/internal/vector.h\n> +++ b/include/libcamera/internal/vector.h\n> @@ -111,6 +111,13 @@ public:\n>                 return apply(*this, scalar, std::divides<>{});\n>         }\n>  \n> +       constexpr Vector operator>>(unsigned int shift) const\n> +       {\n> +               static_assert(std::is_integral_v<T>,\n> +                             \"Vector::operator>> requires an integer element type\");\n> +               return apply(*this, shift, [](T a, unsigned int b) { return a >> b; });\n> +       }\n> +\n>         Vector &operator+=(const Vector &other)\n>         {\n>                 return apply(other, [](T a, T b) { return a + b; });\n> @@ -151,6 +158,13 @@ public:\n>                 return apply(scalar, [](T a, T b) { return a / b; });\n>         }\n>  \n> +       Vector &operator>>=(unsigned int shift)\n> +       {\n> +               static_assert(std::is_integral_v<T>,\n> +                             \"Vector::operator>>= requires an integer element type\");\n> +               return apply(shift, [](T a, unsigned int b) { return a >> b; });\n> +       }\n> +\n>         constexpr Vector min(const Vector &other) const\n>         {\n>                 return apply(*this, other, [](T a, T b) { return std::min(a, b); });\n> @@ -260,8 +274,8 @@ private:\n>                 return result;\n>         }\n>  \n> -       template<class BinaryOp>\n> -       static constexpr Vector apply(const Vector &lhs, T rhs, BinaryOp op)\n> +       template<class U, class BinaryOp>\n> +       static constexpr Vector apply(const Vector &lhs, U rhs, BinaryOp op)\n\nI haven't understood why this needs to change, and does class U get used\nimplicitly ? I don't see anything changing the template parameters\nelsewhere in this patch except...\n\n>         {\n>                 Vector result;\n>                 std::transform(lhs.data_.begin(), lhs.data_.end(),\n> @@ -281,8 +295,8 @@ private:\n>                 return *this;\n>         }\n>  \n> -       template<class BinaryOp>\n> -       Vector &apply(T scalar, BinaryOp op)\n> +       template<class U, class BinaryOp>\n> +       Vector &apply(U scalar, BinaryOp op)\n\nhere ... which I also can't understand how this is used ?\n\nI removed these two hunks and the code still compiled and ran the tests.\n\nWhat am I missing ? Does U mean unsigned version of T perhaps? or\nsomething else implicit?\n\n\n\n>         {\n>                 std::for_each(data_.begin(), data_.end(),\n>                               [&op, scalar](T &v) { v = op(v, scalar); });\n> diff --git a/src/libcamera/vector.cpp b/src/libcamera/vector.cpp\n> index 86b9f9bb..94fbf61e 100644\n> --- a/src/libcamera/vector.cpp\n> +++ b/src/libcamera/vector.cpp\n> @@ -126,6 +126,13 @@ LOG_DEFINE_CATEGORY(Vector)\n>   * \\return The element-wise division of this vector by \\a scalar\n>   */\n>  \n> +/**\n> + * \\fn Vector::operator>>(unsigned int shift) const\n> + * \\brief Right-shift each element of this vector by \\a shift bits\n> + * \\param[in] shift The shift amount\n> + * \\return A new vector with each element right-shifted by \\a shift\n> + */\n> +\n>  /**\n>   * \\fn Vector::operator+=(Vector const &other)\n>   * \\brief Add \\a other element-wise to this vector\n> @@ -182,6 +189,13 @@ LOG_DEFINE_CATEGORY(Vector)\n>   * \\return This vector\n>   */\n>  \n> +/**\n> + * \\fn Vector::operator>>=(unsigned int shift)\n> + * \\brief Right-shift each element of this vector by \\a shift bits in place\n> + * \\param[in] shift The shift amount\n> + * \\return This vector\n> + */\n> +\n>  /**\n>   * \\fn Vector::min(const Vector &other) const\n>   * \\brief Calculate the minimum of this vector and \\a other element-wise\n> diff --git a/test/vector.cpp b/test/vector.cpp\n> index 4fae960d..4ff908e8 100644\n> --- a/test/vector.cpp\n> +++ b/test/vector.cpp\n> @@ -93,6 +93,11 @@ protected:\n>                 v2 /= 4.0;\n>                 ASSERT_EQ(v2, (Vector<double, 3>{{ 1.0, 4.0, 8.0 }}));\n>  \n> +               Vector<int, 3> vi{{ 8, 16, 32 }};\n> +               ASSERT_EQ(vi >> 2, (Vector<int, 3>{{ 2, 4, 8 }}));\n> +               vi >>= 1;\n> +               ASSERT_EQ(vi, (Vector<int, 3>{{ 4, 8, 16 }}));\n> +\n\nThis upsets the checkstyle script / clang format - but I think we should\nignore it - as it's matching the style used for the tests above, and if\nwe fix checkstyle it should be applied to the whole file, not just this\npatch hunk.\n\n\n>                 return TestPass;\n>         }\n>  };\n> \n> -- \n> 2.54.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 123C3BDB1C\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue, 12 May 2026 11:09:53 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id EF8A763025;\n\tTue, 12 May 2026 13:09:51 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 9F5566271A\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 12 May 2026 13:09:50 +0200 (CEST)","from monstersaurus.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 93A7F838;\n\tTue, 12 May 2026 13:09:42 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"BzaFXQLy\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1778584182;\n\tbh=636ErXCNRtjq/bZJP7HJeVMC1BJjzCtNOvaBJl+Z/sQ=;\n\th=In-Reply-To:References:Subject:From:Cc:To:Date:From;\n\tb=BzaFXQLyGlEczKDN7SxnjaGa3gBYa366l0/v3q8zSyZkU5RU5+nLV0UxbMV11xEjJ\n\taNvMmUTj9pyQnl6305DeKTPPqbsxWiHXyqRU/2bgrLtxqYp/L9JFbyPAgVRLZbZEU1\n\tgwAIRDE3evrwK9TKBP3SGbZcrOPaQEbEj7meF//w=","Content-Type":"text/plain; charset=\"utf-8\"","MIME-Version":"1.0","Content-Transfer-Encoding":"quoted-printable","In-Reply-To":"<20260511-libipa-vector-rshift-v3-1-a275f6e87ec4@jetm.me>","References":"<20260511-libipa-vector-rshift-v3-0-a275f6e87ec4@jetm.me>\n\t<20260511-libipa-vector-rshift-v3-1-a275f6e87ec4@jetm.me>","Subject":"Re: [PATCH v3 1/2] libcamera: libipa: Add right-shift operators to\n\tVector","From":"Kieran Bingham <kieran.bingham@ideasonboard.com>","Cc":"=?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= <barnabas.pocze@ideasonboard.com>,\n\tLaurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Javier Tia <floss@jetm.me>, libcamera-devel@lists.libcamera.org","Date":"Tue, 12 May 2026 12:09:47 +0100","Message-ID":"<177858418710.540047.6704551640464828764@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":38868,"web_url":"https://patchwork.libcamera.org/comment/38868/","msgid":"<b94457f1-9de5-41ed-a976-2086f7dbb6d2@ideasonboard.com>","date":"2026-05-12T11:59:12","subject":"Re: [PATCH v3 1/2] libcamera: libipa: Add right-shift operators to\n\tVector","submitter":{"id":216,"url":"https://patchwork.libcamera.org/api/people/216/","name":"Barnabás Pőcze","email":"barnabas.pocze@ideasonboard.com"},"content":"2026. 05. 12. 13:09 keltezéssel, Kieran Bingham írta:\n> Quoting Javier Tia (2026-05-11 21:23:28)\n>> Add operator>> and operator>>= for right-shifting all elements by a\n>> scalar shift amount. Both operate element-wise: operator>> returns a\n>> new Vector with each element shifted, operator>>= shifts in place and\n>> returns a reference to *this.\n>>\n>> The motivating use case is SwStatsCpu::finishFrame(), which right-shifts\n>> three individual components of the RGB sum by the same sumShift_ value.\n>> With these operators that becomes a single sum_ >>= sumShift_ expression.\n>>\n>> The private apply() helpers for non-mutating and mutating scalar\n>> operations are templated on the scalar type so the existing operators\n>> keep working with T while shift can pass an unsigned int. A\n>> static_assert in each shift operator restricts them to integer element\n>> types since right-shift is undefined on floating-point Vectors.\n>>\n>> Suggested-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>\n>> Suggested-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n>> Signed-off-by: Javier Tia <floss@jetm.me>\n>> Reviewed-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>\n>> ---\n>>   include/libcamera/internal/vector.h | 22 ++++++++++++++++++----\n>>   src/libcamera/vector.cpp            | 14 ++++++++++++++\n>>   test/vector.cpp                     |  5 +++++\n>>   3 files changed, 37 insertions(+), 4 deletions(-)\n>>\n>> diff --git a/include/libcamera/internal/vector.h b/include/libcamera/internal/vector.h\n>> index ed7490e1..e3ea723d 100644\n>> --- a/include/libcamera/internal/vector.h\n>> +++ b/include/libcamera/internal/vector.h\n>> @@ -111,6 +111,13 @@ public:\n>>                  return apply(*this, scalar, std::divides<>{});\n>>          }\n>>\n>> +       constexpr Vector operator>>(unsigned int shift) const\n>> +       {\n>> +               static_assert(std::is_integral_v<T>,\n>> +                             \"Vector::operator>> requires an integer element type\");\n>> +               return apply(*this, shift, [](T a, unsigned int b) { return a >> b; });\n>> +       }\n>> +\n>>          Vector &operator+=(const Vector &other)\n>>          {\n>>                  return apply(other, [](T a, T b) { return a + b; });\n>> @@ -151,6 +158,13 @@ public:\n>>                  return apply(scalar, [](T a, T b) { return a / b; });\n>>          }\n>>\n>> +       Vector &operator>>=(unsigned int shift)\n>> +       {\n>> +               static_assert(std::is_integral_v<T>,\n>> +                             \"Vector::operator>>= requires an integer element type\");\n>> +               return apply(shift, [](T a, unsigned int b) { return a >> b; });\n>> +       }\n>> +\n>>          constexpr Vector min(const Vector &other) const\n>>          {\n>>                  return apply(*this, other, [](T a, T b) { return std::min(a, b); });\n>> @@ -260,8 +274,8 @@ private:\n>>                  return result;\n>>          }\n>>\n>> -       template<class BinaryOp>\n>> -       static constexpr Vector apply(const Vector &lhs, T rhs, BinaryOp op)\n>> +       template<class U, class BinaryOp>\n>> +       static constexpr Vector apply(const Vector &lhs, U rhs, BinaryOp op)\n> \n> I haven't understood why this needs to change, and does class U get used\n> implicitly ? I don't see anything changing the template parameters\n> elsewhere in this patch except...\n\nIt's so that the `unsigned int shift` parameter is not converted to `T`\nin the `apply()` call (i.e. `U=unsigned int` is deduced). Since the range\nof `shift` is limited, I'm not sure it makes a lot of practical difference,\nbut I think it's better to make it possible to preserve the type.\n\n\n> \n>>          {\n>>                  Vector result;\n>>                  std::transform(lhs.data_.begin(), lhs.data_.end(),\n>> @@ -281,8 +295,8 @@ private:\n>>                  return *this;\n>>          }\n>>\n>> -       template<class BinaryOp>\n>> -       Vector &apply(T scalar, BinaryOp op)\n>> +       template<class U, class BinaryOp>\n>> +       Vector &apply(U scalar, BinaryOp op)\n> \n> here ... which I also can't understand how this is used ?\n> \n> I removed these two hunks and the code still compiled and ran the tests.\n> \n> What am I missing ? Does U mean unsigned version of T perhaps? or\n> something else implicit?\n> \n> \n> \n>>          {\n>>                  std::for_each(data_.begin(), data_.end(),\n>>                                [&op, scalar](T &v) { v = op(v, scalar); });\n>> diff --git a/src/libcamera/vector.cpp b/src/libcamera/vector.cpp\n>> index 86b9f9bb..94fbf61e 100644\n>> --- a/src/libcamera/vector.cpp\n>> +++ b/src/libcamera/vector.cpp\n>> @@ -126,6 +126,13 @@ LOG_DEFINE_CATEGORY(Vector)\n>>    * \\return The element-wise division of this vector by \\a scalar\n>>    */\n>>\n>> +/**\n>> + * \\fn Vector::operator>>(unsigned int shift) const\n>> + * \\brief Right-shift each element of this vector by \\a shift bits\n>> + * \\param[in] shift The shift amount\n>> + * \\return A new vector with each element right-shifted by \\a shift\n>> + */\n>> +\n>>   /**\n>>    * \\fn Vector::operator+=(Vector const &other)\n>>    * \\brief Add \\a other element-wise to this vector\n>> @@ -182,6 +189,13 @@ LOG_DEFINE_CATEGORY(Vector)\n>>    * \\return This vector\n>>    */\n>>\n>> +/**\n>> + * \\fn Vector::operator>>=(unsigned int shift)\n>> + * \\brief Right-shift each element of this vector by \\a shift bits in place\n>> + * \\param[in] shift The shift amount\n>> + * \\return This vector\n>> + */\n>> +\n>>   /**\n>>    * \\fn Vector::min(const Vector &other) const\n>>    * \\brief Calculate the minimum of this vector and \\a other element-wise\n>> diff --git a/test/vector.cpp b/test/vector.cpp\n>> index 4fae960d..4ff908e8 100644\n>> --- a/test/vector.cpp\n>> +++ b/test/vector.cpp\n>> @@ -93,6 +93,11 @@ protected:\n>>                  v2 /= 4.0;\n>>                  ASSERT_EQ(v2, (Vector<double, 3>{{ 1.0, 4.0, 8.0 }}));\n>>\n>> +               Vector<int, 3> vi{{ 8, 16, 32 }};\n>> +               ASSERT_EQ(vi >> 2, (Vector<int, 3>{{ 2, 4, 8 }}));\n>> +               vi >>= 1;\n>> +               ASSERT_EQ(vi, (Vector<int, 3>{{ 4, 8, 16 }}));\n>> +\n> \n> This upsets the checkstyle script / clang format - but I think we should\n> ignore it - as it's matching the style used for the tests above, and if\n> we fix checkstyle it should be applied to the whole file, not just this\n> patch hunk.\n> \n> \n>>                  return TestPass;\n>>          }\n>>   };\n>>\n>> --\n>> 2.54.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 69E3DBDCBD\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue, 12 May 2026 11:59:19 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 8187C6301E;\n\tTue, 12 May 2026 13:59:18 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 24C636271A\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 12 May 2026 13:59:17 +0200 (CEST)","from [192.168.33.39] (185.182.215.166.nat.pool.zt.hu\n\t[185.182.215.166])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id E73CE838;\n\tTue, 12 May 2026 13:59:08 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"gT/P7KxE\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1778587149;\n\tbh=sH9UL6KOZgljm6AHsYhDEYAFyzOpD+5zS6AG/3UxHQo=;\n\th=Date:Subject:To:Cc:References:From:In-Reply-To:From;\n\tb=gT/P7KxEPC43yfuRSoSMhD3rXy50XSpHiReTNX5ujZ0DbIiify9g+w6tbEVVdZevr\n\t0HNdvzHEcORTZ8rzdFPHgb6YHOUttDp20niScVFew3bqRaz1LmWaOkqWb8Enq9Gk80\n\t8Z8j5txMTCurmyKDj2KKbSQrTcbTzTE9FrAMTW2Y=","Message-ID":"<b94457f1-9de5-41ed-a976-2086f7dbb6d2@ideasonboard.com>","Date":"Tue, 12 May 2026 13:59:12 +0200","MIME-Version":"1.0","User-Agent":"Mozilla Thunderbird","Subject":"Re: [PATCH v3 1/2] libcamera: libipa: Add right-shift operators to\n\tVector","To":"Kieran Bingham <kieran.bingham@ideasonboard.com>,\n\tJavier Tia <floss@jetm.me>, libcamera-devel@lists.libcamera.org","Cc":"=?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= <barnabas.pocze@ideasonboard.com>,\n\tLaurent Pinchart <laurent.pinchart@ideasonboard.com>","References":"<20260511-libipa-vector-rshift-v3-0-a275f6e87ec4@jetm.me>\n\t<20260511-libipa-vector-rshift-v3-1-a275f6e87ec4@jetm.me>\n\t<9MB3c8PW0ekpTNvGS0Dy2mtgKr0C_rYnnc-E0an9wuxL5Ke7JCLh1HYEtxGHBwj8szE3IlFvuvm_EyaU18JMjw==@protonmail.internalid>\n\t<177858418710.540047.6704551640464828764@ping.linuxembedded.co.uk>","From":"=?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= <barnabas.pocze@ideasonboard.com>","Content-Language":"en-US, hu-HU","In-Reply-To":"<177858418710.540047.6704551640464828764@ping.linuxembedded.co.uk>","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":38873,"web_url":"https://patchwork.libcamera.org/comment/38873/","msgid":"<177859041536.3192894.11982416958863042506@ping.linuxembedded.co.uk>","date":"2026-05-12T12:53:35","subject":"Re: [PATCH v3 1/2] libcamera: libipa: Add right-shift operators to\n\tVector","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-05-12 12:59:12)\n> 2026. 05. 12. 13:09 keltezéssel, Kieran Bingham írta:\n> > Quoting Javier Tia (2026-05-11 21:23:28)\n> >> Add operator>> and operator>>= for right-shifting all elements by a\n> >> scalar shift amount. Both operate element-wise: operator>> returns a\n> >> new Vector with each element shifted, operator>>= shifts in place and\n> >> returns a reference to *this.\n> >>\n> >> The motivating use case is SwStatsCpu::finishFrame(), which right-shifts\n> >> three individual components of the RGB sum by the same sumShift_ value.\n> >> With these operators that becomes a single sum_ >>= sumShift_ expression.\n> >>\n> >> The private apply() helpers for non-mutating and mutating scalar\n> >> operations are templated on the scalar type so the existing operators\n> >> keep working with T while shift can pass an unsigned int. A\n> >> static_assert in each shift operator restricts them to integer element\n> >> types since right-shift is undefined on floating-point Vectors.\n> >>\n> >> Suggested-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>\n> >> Suggested-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n> >> Signed-off-by: Javier Tia <floss@jetm.me>\n> >> Reviewed-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>\n> >> ---\n> >>   include/libcamera/internal/vector.h | 22 ++++++++++++++++++----\n> >>   src/libcamera/vector.cpp            | 14 ++++++++++++++\n> >>   test/vector.cpp                     |  5 +++++\n> >>   3 files changed, 37 insertions(+), 4 deletions(-)\n> >>\n> >> diff --git a/include/libcamera/internal/vector.h b/include/libcamera/internal/vector.h\n> >> index ed7490e1..e3ea723d 100644\n> >> --- a/include/libcamera/internal/vector.h\n> >> +++ b/include/libcamera/internal/vector.h\n> >> @@ -111,6 +111,13 @@ public:\n> >>                  return apply(*this, scalar, std::divides<>{});\n> >>          }\n> >>\n> >> +       constexpr Vector operator>>(unsigned int shift) const\n> >> +       {\n> >> +               static_assert(std::is_integral_v<T>,\n> >> +                             \"Vector::operator>> requires an integer element type\");\n> >> +               return apply(*this, shift, [](T a, unsigned int b) { return a >> b; });\n> >> +       }\n> >> +\n> >>          Vector &operator+=(const Vector &other)\n> >>          {\n> >>                  return apply(other, [](T a, T b) { return a + b; });\n> >> @@ -151,6 +158,13 @@ public:\n> >>                  return apply(scalar, [](T a, T b) { return a / b; });\n> >>          }\n> >>\n> >> +       Vector &operator>>=(unsigned int shift)\n> >> +       {\n> >> +               static_assert(std::is_integral_v<T>,\n> >> +                             \"Vector::operator>>= requires an integer element type\");\n> >> +               return apply(shift, [](T a, unsigned int b) { return a >> b; });\n> >> +       }\n> >> +\n> >>          constexpr Vector min(const Vector &other) const\n> >>          {\n> >>                  return apply(*this, other, [](T a, T b) { return std::min(a, b); });\n> >> @@ -260,8 +274,8 @@ private:\n> >>                  return result;\n> >>          }\n> >>\n> >> -       template<class BinaryOp>\n> >> -       static constexpr Vector apply(const Vector &lhs, T rhs, BinaryOp op)\n> >> +       template<class U, class BinaryOp>\n> >> +       static constexpr Vector apply(const Vector &lhs, U rhs, BinaryOp op)\n> > \n> > I haven't understood why this needs to change, and does class U get used\n> > implicitly ? I don't see anything changing the template parameters\n> > elsewhere in this patch except...\n> \n> It's so that the `unsigned int shift` parameter is not converted to `T`\n> in the `apply()` call (i.e. `U=unsigned int` is deduced). Since the range\n> of `shift` is limited, I'm not sure it makes a lot of practical difference,\n> but I think it's better to make it possible to preserve the type.\n\n\nThanks. Templates are hard, but I'm happy with the rest of this, and\nit's passing the tests so:\n\nReviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>","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 7351ABDB1C\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue, 12 May 2026 12:53:41 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 71C2463025;\n\tTue, 12 May 2026 14:53:40 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 7833C6271A\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 12 May 2026 14:53:38 +0200 (CEST)","from monstersaurus.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 60E8C56D;\n\tTue, 12 May 2026 14:53:30 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"sRozafeb\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1778590410;\n\tbh=oT1p2cUEySxGXa/4cylmpmUuxt2dF/HPm1uB4lyoDyM=;\n\th=In-Reply-To:References:Subject:From:Cc:To:Date:From;\n\tb=sRozafebH1W2FETelkGGxWiEXEUgsz03XlwvEoWvecdfHB2O4AlqGpZe1c6ge7Fhd\n\tEcziW1CZa+4fzLFVlX4jItF4cMov80NjBhonLcFTVcHjMGFb2W8zc6pxdEhheGohZ9\n\t3mb78/reeUP63XC/bsLMhyfcZzircuOR1RFWzRNE=","Content-Type":"text/plain; charset=\"utf-8\"","MIME-Version":"1.0","Content-Transfer-Encoding":"quoted-printable","In-Reply-To":"<b94457f1-9de5-41ed-a976-2086f7dbb6d2@ideasonboard.com>","References":"<20260511-libipa-vector-rshift-v3-0-a275f6e87ec4@jetm.me>\n\t<20260511-libipa-vector-rshift-v3-1-a275f6e87ec4@jetm.me>\n\t<9MB3c8PW0ekpTNvGS0Dy2mtgKr0C_rYnnc-E0an9wuxL5Ke7JCLh1HYEtxGHBwj8szE3IlFvuvm_EyaU18JMjw==@protonmail.internalid>\n\t<177858418710.540047.6704551640464828764@ping.linuxembedded.co.uk>\n\t<b94457f1-9de5-41ed-a976-2086f7dbb6d2@ideasonboard.com>","Subject":"Re: [PATCH v3 1/2] libcamera: libipa: Add right-shift operators to\n\tVector","From":"Kieran Bingham <kieran.bingham@ideasonboard.com>","Cc":"=?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= <barnabas.pocze@ideasonboard.com>,\n\tLaurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"=?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= <barnabas.pocze@ideasonboard.com>,\n\tJavier Tia <floss@jetm.me>, libcamera-devel@lists.libcamera.org","Date":"Tue, 12 May 2026 13:53:35 +0100","Message-ID":"<177859041536.3192894.11982416958863042506@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>"}}]