[{"id":33559,"web_url":"https://patchwork.libcamera.org/comment/33559/","msgid":"<20250303230445.GG23684@pendragon.ideasonboard.com>","date":"2025-03-03T23:04:45","subject":"Re: [PATCH v1] libcamera: base: bound_method: Forward arguments when\n\tpossible","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 Mon, Mar 03, 2025 at 04:14:38PM +0100, Barnabás Pőcze wrote:\n> Use `std::{forward,move}` to forward the arguments, this enables the\n> use of move constructors, likely leading to less code and better runtime.\n> For example, move constructing a libstdc++ `std::shared_ptr` is noticeably\n> less code than copy constructing one.\n> \n> Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>\n> ---\n>  include/libcamera/base/bound_method.h | 26 ++++++++++++++------------\n>  1 file changed, 14 insertions(+), 12 deletions(-)\n> \n> diff --git a/include/libcamera/base/bound_method.h b/include/libcamera/base/bound_method.h\n> index dd3488eeb..47e0a2475 100644\n> --- a/include/libcamera/base/bound_method.h\n> +++ b/include/libcamera/base/bound_method.h\n> @@ -33,8 +33,9 @@ template<typename R, typename... Args>\n>  class BoundMethodPack : public BoundMethodPackBase\n>  {\n>  public:\n> -\tBoundMethodPack(const Args &... args)\n> -\t\t: args_(args...)\n> +\ttemplate<typename... Ts>\n> +\tBoundMethodPack(Ts &&...args)\n\nWhy is a Ts template parameter needed here, what happens if you use\n\n\tBoundMethodPack(const Args &... args)\n\t\t: args_(std::forward<Args>(args)...)\n\n?\n\nReviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n\n> +\t\t: args_(std::forward<Ts>(args)...)\n>  \t{\n>  \t}\n>  \n> @@ -51,8 +52,9 @@ template<typename... Args>\n>  class BoundMethodPack<void, Args...> : public BoundMethodPackBase\n>  {\n>  public:\n> -\tBoundMethodPack(const Args &... args)\n> -\t\t: args_(args...)\n> +\ttemplate<typename... Ts>\n> +\tBoundMethodPack(Ts &&...args)\n> +\t\t: args_(std::forward<Ts>(args)...)\n>  \t{\n>  \t}\n>  \n> @@ -136,23 +138,23 @@ public:\n>  \n>  \tBoundMethodFunctor(T *obj, Object *object, Func func,\n>  \t\t\t   ConnectionType type = ConnectionTypeAuto)\n> -\t\t: BoundMethodArgs<R, Args...>(obj, object, type), func_(func)\n> +\t\t: BoundMethodArgs<R, Args...>(obj, object, type), func_(std::move(func))\n>  \t{\n>  \t}\n>  \n>  \tR activate(Args... args, bool deleteMethod = false) override\n>  \t{\n>  \t\tif (!this->object_)\n> -\t\t\treturn func_(args...);\n> +\t\t\treturn func_(std::forward<Args>(args)...);\n>  \n> -\t\tauto pack = std::make_shared<PackType>(args...);\n> +\t\tauto pack = std::make_shared<PackType>(std::forward<Args>(args)...);\n>  \t\tbool sync = BoundMethodBase::activatePack(pack, deleteMethod);\n>  \t\treturn sync ? pack->returnValue() : R();\n>  \t}\n>  \n>  \tR invoke(Args... args) override\n>  \t{\n> -\t\treturn func_(args...);\n> +\t\treturn func_(std::forward<Args>(args)...);\n>  \t}\n>  \n>  private:\n> @@ -177,10 +179,10 @@ public:\n>  \t{\n>  \t\tif (!this->object_) {\n>  \t\t\tT *obj = static_cast<T *>(this->obj_);\n> -\t\t\treturn (obj->*func_)(args...);\n> +\t\t\treturn (obj->*func_)(std::forward<Args>(args)...);\n>  \t\t}\n>  \n> -\t\tauto pack = std::make_shared<PackType>(args...);\n> +\t\tauto pack = std::make_shared<PackType>(std::forward<Args>(args)...);\n>  \t\tbool sync = BoundMethodBase::activatePack(pack, deleteMethod);\n>  \t\treturn sync ? pack->returnValue() : R();\n>  \t}\n> @@ -188,7 +190,7 @@ public:\n>  \tR invoke(Args... args) override\n>  \t{\n>  \t\tT *obj = static_cast<T *>(this->obj_);\n> -\t\treturn (obj->*func_)(args...);\n> +\t\treturn (obj->*func_)(std::forward<Args>(args)...);\n>  \t}\n>  \n>  private:\n> @@ -209,7 +211,7 @@ public:\n>  \n>  \tR activate(Args... args, [[maybe_unused]] bool deleteMethod = false) override\n>  \t{\n> -\t\treturn (*func_)(args...);\n> +\t\treturn (*func_)(std::forward<Args>(args)...);\n>  \t}\n>  \n>  \tR invoke(Args...) override","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 1784EC3257\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon,  3 Mar 2025 23:05:11 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 8AE51687EB;\n\tTue,  4 Mar 2025 00:05:09 +0100 (CET)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id B6E0A61846\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue,  4 Mar 2025 00:05:06 +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 C38BA352;\n\tTue,  4 Mar 2025 00:03:34 +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=\"HTl9+3dP\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1741043015;\n\tbh=DWHLlOIpuo0oZqdwhuG7tejVfoqIL3j3Rxroihdg9ik=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=HTl9+3dPwuijODKxM6grFpZxkiq74XnDDWG6ftacJ291zyoo+wSw832PBJ6+A5n+F\n\tr6dGMZnI1qe8bErVnVoSEmfJ7IhvVBaSJj/6NCJv3EjiuYbrDmtNxhxJTCZS0xWxNE\n\t32TERuFpLFYw1QcMA0rcWX3zokbCoju39wnYWUOA=","Date":"Tue, 4 Mar 2025 01:04:45 +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] libcamera: base: bound_method: Forward arguments when\n\tpossible","Message-ID":"<20250303230445.GG23684@pendragon.ideasonboard.com>","References":"<20250303151438.732916-1-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":"<20250303151438.732916-1-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":33570,"web_url":"https://patchwork.libcamera.org/comment/33570/","msgid":"<09f29968-5ea9-4ebc-902f-afda1c139e4d@ideasonboard.com>","date":"2025-03-04T11:01:35","subject":"Re: [PATCH v1] libcamera: base: bound_method: Forward arguments when\n\tpossible","submitter":{"id":216,"url":"https://patchwork.libcamera.org/api/people/216/","name":"Barnabás Pőcze","email":"barnabas.pocze@ideasonboard.com"},"content":"Hi\n\n\n2025. 03. 04. 0:04 keltezéssel, Laurent Pinchart írta:\n> Hi Barnabás,\n> \n> Thank you for the patch.\n> \n> On Mon, Mar 03, 2025 at 04:14:38PM +0100, Barnabás Pőcze wrote:\n>> Use `std::{forward,move}` to forward the arguments, this enables the\n>> use of move constructors, likely leading to less code and better runtime.\n>> For example, move constructing a libstdc++ `std::shared_ptr` is noticeably\n>> less code than copy constructing one.\n>>\n>> Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>\n>> ---\n>>   include/libcamera/base/bound_method.h | 26 ++++++++++++++------------\n>>   1 file changed, 14 insertions(+), 12 deletions(-)\n>>\n>> diff --git a/include/libcamera/base/bound_method.h b/include/libcamera/base/bound_method.h\n>> index dd3488eeb..47e0a2475 100644\n>> --- a/include/libcamera/base/bound_method.h\n>> +++ b/include/libcamera/base/bound_method.h\n>> @@ -33,8 +33,9 @@ template<typename R, typename... Args>\n>>   class BoundMethodPack : public BoundMethodPackBase\n>>   {\n>>   public:\n>> -\tBoundMethodPack(const Args &... args)\n>> -\t\t: args_(args...)\n>> +\ttemplate<typename... Ts>\n>> +\tBoundMethodPack(Ts &&...args)\n> \n> Why is a Ts template parameter needed here, what happens if you use\n> \n> \tBoundMethodPack(const Args &... args)\n> \t\t: args_(std::forward<Args>(args)...)\n> \n> ?\n\nIf `const T&` is used, then the object in the tuple will always be\ncopy constructed even if the constructor receives a temporary that\ncould be moved.\n\nUsing `BoundMethodPack(Args&&...)` would also not work generally because\nthat will only accept rvalue references (except when the given type in `Args`\nis an lvalue reference).\n\nAn alternative would be `BoundMethodPack(Args...)`, but the downside of that\nis that it might force unnecessary object construction.\n\nSo \"forwarding\" references are used to avoid the above issues, and to be able\nto pass the references through unmodified to the tuple constructor.\n\n\nRegards,\nBarnabás Pőcze\n\n\n> \n> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n> \n>> +\t\t: args_(std::forward<Ts>(args)...)\n>>   \t{\n>>   \t}\n>>   \n>> @@ -51,8 +52,9 @@ template<typename... Args>\n>>   class BoundMethodPack<void, Args...> : public BoundMethodPackBase\n>>   {\n>>   public:\n>> -\tBoundMethodPack(const Args &... args)\n>> -\t\t: args_(args...)\n>> +\ttemplate<typename... Ts>\n>> +\tBoundMethodPack(Ts &&...args)\n>> +\t\t: args_(std::forward<Ts>(args)...)\n>>   \t{\n>>   \t}\n>>   \n>> @@ -136,23 +138,23 @@ public:\n>>   \n>>   \tBoundMethodFunctor(T *obj, Object *object, Func func,\n>>   \t\t\t   ConnectionType type = ConnectionTypeAuto)\n>> -\t\t: BoundMethodArgs<R, Args...>(obj, object, type), func_(func)\n>> +\t\t: BoundMethodArgs<R, Args...>(obj, object, type), func_(std::move(func))\n>>   \t{\n>>   \t}\n>>   \n>>   \tR activate(Args... args, bool deleteMethod = false) override\n>>   \t{\n>>   \t\tif (!this->object_)\n>> -\t\t\treturn func_(args...);\n>> +\t\t\treturn func_(std::forward<Args>(args)...);\n>>   \n>> -\t\tauto pack = std::make_shared<PackType>(args...);\n>> +\t\tauto pack = std::make_shared<PackType>(std::forward<Args>(args)...);\n>>   \t\tbool sync = BoundMethodBase::activatePack(pack, deleteMethod);\n>>   \t\treturn sync ? pack->returnValue() : R();\n>>   \t}\n>>   \n>>   \tR invoke(Args... args) override\n>>   \t{\n>> -\t\treturn func_(args...);\n>> +\t\treturn func_(std::forward<Args>(args)...);\n>>   \t}\n>>   \n>>   private:\n>> @@ -177,10 +179,10 @@ public:\n>>   \t{\n>>   \t\tif (!this->object_) {\n>>   \t\t\tT *obj = static_cast<T *>(this->obj_);\n>> -\t\t\treturn (obj->*func_)(args...);\n>> +\t\t\treturn (obj->*func_)(std::forward<Args>(args)...);\n>>   \t\t}\n>>   \n>> -\t\tauto pack = std::make_shared<PackType>(args...);\n>> +\t\tauto pack = std::make_shared<PackType>(std::forward<Args>(args)...);\n>>   \t\tbool sync = BoundMethodBase::activatePack(pack, deleteMethod);\n>>   \t\treturn sync ? pack->returnValue() : R();\n>>   \t}\n>> @@ -188,7 +190,7 @@ public:\n>>   \tR invoke(Args... args) override\n>>   \t{\n>>   \t\tT *obj = static_cast<T *>(this->obj_);\n>> -\t\treturn (obj->*func_)(args...);\n>> +\t\treturn (obj->*func_)(std::forward<Args>(args)...);\n>>   \t}\n>>   \n>>   private:\n>> @@ -209,7 +211,7 @@ public:\n>>   \n>>   \tR activate(Args... args, [[maybe_unused]] bool deleteMethod = false) override\n>>   \t{\n>> -\t\treturn (*func_)(args...);\n>> +\t\treturn (*func_)(std::forward<Args>(args)...);\n>>   \t}\n>>   \n>>   \tR invoke(Args...) override\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 344BAC32DC\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue,  4 Mar 2025 11:01:41 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id D940E68822;\n\tTue,  4 Mar 2025 12:01:40 +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 4690B68755\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue,  4 Mar 2025 12:01:39 +0100 (CET)","from [192.168.33.3] (185.221.143.4.nat.pool.zt.hu [185.221.143.4])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id DB59C11DF; \n\tTue,  4 Mar 2025 12:00:06 +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=\"vHkbdCgw\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1741086007;\n\tbh=3iCbEjqhfmM9nmD/6FEobbIuZOrtDqBxv5opeXkRjjY=;\n\th=Date:Subject:To:Cc:References:From:In-Reply-To:From;\n\tb=vHkbdCgwg1WDMx7sNmB4D3eJvncfw2bN1xP7/fyvxJ+A/rvCwFZzjcU5Ushqi+WqI\n\twJG3lBZtv4jIOgEfoFc7JaPLvd9d8YJxPbdPihZ/CiFutUgIzCRz2oDlInOinb7i9x\n\twlLOeV6/G9UVGRPSNkOuU29tzQ80Nvg8XGT/IL3g=","Message-ID":"<09f29968-5ea9-4ebc-902f-afda1c139e4d@ideasonboard.com>","Date":"Tue, 4 Mar 2025 12:01:35 +0100","MIME-Version":"1.0","User-Agent":"Mozilla Thunderbird","Subject":"Re: [PATCH v1] libcamera: base: bound_method: Forward arguments when\n\tpossible","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org","References":"<20250303151438.732916-1-barnabas.pocze@ideasonboard.com>\n\t<20250303230445.GG23684@pendragon.ideasonboard.com>","From":"=?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= <barnabas.pocze@ideasonboard.com>","Content-Language":"en-US, hu-HU","In-Reply-To":"<20250303230445.GG23684@pendragon.ideasonboard.com>","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":34707,"web_url":"https://patchwork.libcamera.org/comment/34707/","msgid":"<175104399886.3281735.13005065666177189888@ping.linuxembedded.co.uk>","date":"2025-06-27T17:06:38","subject":"Re: [PATCH v1] libcamera: base: bound_method: Forward arguments when\n\tpossible","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 (2025-03-04 11:01:35)\n> Hi\n> \n> \n> 2025. 03. 04. 0:04 keltezéssel, Laurent Pinchart írta:\n> > Hi Barnabás,\n> > \n> > Thank you for the patch.\n> > \n> > On Mon, Mar 03, 2025 at 04:14:38PM +0100, Barnabás Pőcze wrote:\n> >> Use `std::{forward,move}` to forward the arguments, this enables the\n> >> use of move constructors, likely leading to less code and better runtime.\n> >> For example, move constructing a libstdc++ `std::shared_ptr` is noticeably\n> >> less code than copy constructing one.\n> >>\n> >> Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>\n> >> ---\n> >>   include/libcamera/base/bound_method.h | 26 ++++++++++++++------------\n> >>   1 file changed, 14 insertions(+), 12 deletions(-)\n> >>\n> >> diff --git a/include/libcamera/base/bound_method.h b/include/libcamera/base/bound_method.h\n> >> index dd3488eeb..47e0a2475 100644\n> >> --- a/include/libcamera/base/bound_method.h\n> >> +++ b/include/libcamera/base/bound_method.h\n> >> @@ -33,8 +33,9 @@ template<typename R, typename... Args>\n> >>   class BoundMethodPack : public BoundMethodPackBase\n> >>   {\n> >>   public:\n> >> -    BoundMethodPack(const Args &... args)\n> >> -            : args_(args...)\n> >> +    template<typename... Ts>\n> >> +    BoundMethodPack(Ts &&...args)\n> > \n> > Why is a Ts template parameter needed here, what happens if you use\n> > \n> >       BoundMethodPack(const Args &... args)\n> >               : args_(std::forward<Args>(args)...)\n> > \n> > ?\n> \n> If `const T&` is used, then the object in the tuple will always be\n> copy constructed even if the constructor receives a temporary that\n> could be moved.\n> \n> Using `BoundMethodPack(Args&&...)` would also not work generally because\n> that will only accept rvalue references (except when the given type in `Args`\n> is an lvalue reference).\n> \n> An alternative would be `BoundMethodPack(Args...)`, but the downside of that\n> is that it might force unnecessary object construction.\n> \n> So \"forwarding\" references are used to avoid the above issues, and to be able\n> to pass the references through unmodified to the tuple constructor.\n> \n> \n> Regards,\n> Barnabás Pőcze\n> \n> \n> > \n> > Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n\nThis one is still in my inbox, honestly - I don't think I can review it\ncomfortably to put an RB tag ... but as /you/ wrote it and there's an RB\ntag from Laurent - I'm fine seeing this merged if the CI is all passed!\n\nIn case that helps get one more mail out of my inbox..\n\nAcked-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n\n> > \n> >> +            : args_(std::forward<Ts>(args)...)\n> >>      {\n> >>      }\n> >>   \n> >> @@ -51,8 +52,9 @@ template<typename... Args>\n> >>   class BoundMethodPack<void, Args...> : public BoundMethodPackBase\n> >>   {\n> >>   public:\n> >> -    BoundMethodPack(const Args &... args)\n> >> -            : args_(args...)\n> >> +    template<typename... Ts>\n> >> +    BoundMethodPack(Ts &&...args)\n> >> +            : args_(std::forward<Ts>(args)...)\n> >>      {\n> >>      }\n> >>   \n> >> @@ -136,23 +138,23 @@ public:\n> >>   \n> >>      BoundMethodFunctor(T *obj, Object *object, Func func,\n> >>                         ConnectionType type = ConnectionTypeAuto)\n> >> -            : BoundMethodArgs<R, Args...>(obj, object, type), func_(func)\n> >> +            : BoundMethodArgs<R, Args...>(obj, object, type), func_(std::move(func))\n> >>      {\n> >>      }\n> >>   \n> >>      R activate(Args... args, bool deleteMethod = false) override\n> >>      {\n> >>              if (!this->object_)\n> >> -                    return func_(args...);\n> >> +                    return func_(std::forward<Args>(args)...);\n> >>   \n> >> -            auto pack = std::make_shared<PackType>(args...);\n> >> +            auto pack = std::make_shared<PackType>(std::forward<Args>(args)...);\n> >>              bool sync = BoundMethodBase::activatePack(pack, deleteMethod);\n> >>              return sync ? pack->returnValue() : R();\n> >>      }\n> >>   \n> >>      R invoke(Args... args) override\n> >>      {\n> >> -            return func_(args...);\n> >> +            return func_(std::forward<Args>(args)...);\n> >>      }\n> >>   \n> >>   private:\n> >> @@ -177,10 +179,10 @@ public:\n> >>      {\n> >>              if (!this->object_) {\n> >>                      T *obj = static_cast<T *>(this->obj_);\n> >> -                    return (obj->*func_)(args...);\n> >> +                    return (obj->*func_)(std::forward<Args>(args)...);\n> >>              }\n> >>   \n> >> -            auto pack = std::make_shared<PackType>(args...);\n> >> +            auto pack = std::make_shared<PackType>(std::forward<Args>(args)...);\n> >>              bool sync = BoundMethodBase::activatePack(pack, deleteMethod);\n> >>              return sync ? pack->returnValue() : R();\n> >>      }\n> >> @@ -188,7 +190,7 @@ public:\n> >>      R invoke(Args... args) override\n> >>      {\n> >>              T *obj = static_cast<T *>(this->obj_);\n> >> -            return (obj->*func_)(args...);\n> >> +            return (obj->*func_)(std::forward<Args>(args)...);\n> >>      }\n> >>   \n> >>   private:\n> >> @@ -209,7 +211,7 @@ public:\n> >>   \n> >>      R activate(Args... args, [[maybe_unused]] bool deleteMethod = false) override\n> >>      {\n> >> -            return (*func_)(args...);\n> >> +            return (*func_)(std::forward<Args>(args)...);\n> >>      }\n> >>   \n> >>      R invoke(Args...) override\n> > \n>","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id B8828C3237\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri, 27 Jun 2025 17:06:44 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 6340768E04;\n\tFri, 27 Jun 2025 19:06:43 +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 9146768DE5\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 27 Jun 2025 19:06:41 +0200 (CEST)","from pendragon.ideasonboard.com\n\t(cpc89244-aztw30-2-0-cust6594.18-1.cable.virginm.net [86.31.185.195])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id A82DD6AE;\n\tFri, 27 Jun 2025 19:06:21 +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=\"AlBPkDBX\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1751043981;\n\tbh=+RF8aRXKYL91iV8PxIiKGrVmj7PueNmU5YTEEeB86sU=;\n\th=In-Reply-To:References:Subject:From:Cc:To:Date:From;\n\tb=AlBPkDBXoexkLst9hm/OMpG65ipF/f/jyiknsNlDFN4zUXx7oDuKB5wpPi7eZhd0U\n\tDvc+LpLDcxjyEmkL1B2joBftrpFaNj1d0iYcm35VCNL7g2oesCNyHsCfR7Z+hq1Pgk\n\tT+3wOWfJbhKt1ZnMGhSUIOZNUlckhpfHilLN/c/I=","Content-Type":"text/plain; charset=\"utf-8\"","MIME-Version":"1.0","Content-Transfer-Encoding":"quoted-printable","In-Reply-To":"<09f29968-5ea9-4ebc-902f-afda1c139e4d@ideasonboard.com>","References":"<20250303151438.732916-1-barnabas.pocze@ideasonboard.com>\n\t<20250303230445.GG23684@pendragon.ideasonboard.com>\n\t<09f29968-5ea9-4ebc-902f-afda1c139e4d@ideasonboard.com>","Subject":"Re: [PATCH v1] libcamera: base: bound_method: Forward arguments when\n\tpossible","From":"Kieran Bingham <kieran.bingham@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org","To":"=?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= <barnabas.pocze@ideasonboard.com>,\n\tLaurent Pinchart <laurent.pinchart@ideasonboard.com>","Date":"Fri, 27 Jun 2025 18:06:38 +0100","Message-ID":"<175104399886.3281735.13005065666177189888@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>"}}]