[{"id":14356,"web_url":"https://patchwork.libcamera.org/comment/14356/","msgid":"<X+huXZxqK5XvoeBE@wyvern>","date":"2020-12-27T11:22:05","subject":"Re: [libcamera-devel] [PATCH] libcamera: utils: Add reverse adapter\n\tfor range-based loop","submitter":{"id":5,"url":"https://patchwork.libcamera.org/api/people/5/","name":"Niklas Söderlund","email":"niklas.soderlund@ragnatech.se"},"content":"Hi Laurent,\n\nI like template magic :-)\n\nOn 2020-12-27 12:03:31 +0200, Laurent Pinchart wrote:\n> Add a utils::reverse() function that creates an adapter wrapping in\n> iterable, such that range-based iteration over the adapter iterates over\n> the iterable in reverse order.\n> \n> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n> ---\n>  include/libcamera/internal/utils.h | 27 +++++++++++++++++++++++++++\n>  src/libcamera/utils.cpp            |  8 ++++++++\n>  2 files changed, 35 insertions(+)\n> \n> This will be used in an upcoming patch series, I'm already sending it\n> out to get the idea reviewed.\n\nLooking forward do see what you have in store ;-)\n\nReviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>\n\n> \n> diff --git a/include/libcamera/internal/utils.h b/include/libcamera/internal/utils.h\n> index f08134afb5ba..d0146b71727d 100644\n> --- a/include/libcamera/internal/utils.h\n> +++ b/include/libcamera/internal/utils.h\n> @@ -203,6 +203,33 @@ constexpr unsigned int alignUp(unsigned int value, unsigned int alignment)\n>  \treturn (value + alignment - 1) / alignment * alignment;\n>  }\n>  \n> +namespace details {\n> +\n> +template<typename T>\n> +struct reverse_adapter {\n> +\tT &iterable;\n> +};\n> +\n> +template<typename T>\n> +auto begin(reverse_adapter<T> r)\n> +{\n> +\treturn std::rbegin(r.iterable);\n> +}\n> +\n> +template<typename T>\n> +auto end(reverse_adapter<T> r)\n> +{\n> +\treturn std::rend(r.iterable);\n> +}\n> +\n> +} /* namespace details */\n> +\n> +template<typename T>\n> +details::reverse_adapter<T> reverse(T &&iterable)\n> +{\n> +\treturn { iterable };\n> +}\n> +\n>  } /* namespace utils */\n>  \n>  } /* namespace libcamera */\n> diff --git a/src/libcamera/utils.cpp b/src/libcamera/utils.cpp\n> index e90375ae115c..c4098a74e0ab 100644\n> --- a/src/libcamera/utils.cpp\n> +++ b/src/libcamera/utils.cpp\n> @@ -464,6 +464,14 @@ std::string libcameraSourcePath()\n>   * \\return The value rounded up to the nearest multiple of \\a alignment\n>   */\n>  \n> +/**\n> + * \\fn reverse(T &&iterable)\n> + * \\brief Wrap an iterable to reverse iteration in a range-based loop\n> + * \\param[in] iterable The iterable\n> + * \\return A value of unspecified type that, when used in a range-based for\n> + * loop, will cause the loop to iterate over the \\a iterable in reverse order\n> + */\n> +\n>  } /* namespace utils */\n>  \n>  } /* namespace libcamera */\n> -- \n> Regards,\n> \n> Laurent Pinchart\n> \n> _______________________________________________\n> libcamera-devel mailing list\n> libcamera-devel@lists.libcamera.org\n> https://lists.libcamera.org/listinfo/libcamera-devel","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 4E001C0F1A\n\tfor <parsemail@patchwork.libcamera.org>;\n\tSun, 27 Dec 2020 11:22:10 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 9B81562005;\n\tSun, 27 Dec 2020 12:22:09 +0100 (CET)","from mail-lf1-x141.google.com (mail-lf1-x141.google.com\n\t[IPv6:2a00:1450:4864:20::141])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 0C353615B1\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tSun, 27 Dec 2020 12:22:08 +0100 (CET)","by mail-lf1-x141.google.com with SMTP id h205so18114739lfd.5\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tSun, 27 Dec 2020 03:22:07 -0800 (PST)","from localhost ([185.224.57.161]) by smtp.gmail.com with ESMTPSA id\n\tp5sm4977415lfj.295.2020.12.27.03.22.06\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tSun, 27 Dec 2020 03:22:06 -0800 (PST)"],"Authentication-Results":"lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key;\n\tunprotected) header.d=ragnatech-se.20150623.gappssmtp.com\n\theader.i=@ragnatech-se.20150623.gappssmtp.com\n\theader.b=\"etxW2VlG\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=ragnatech-se.20150623.gappssmtp.com; s=20150623;\n\th=date:from:to:cc:subject:message-id:references:mime-version\n\t:content-disposition:content-transfer-encoding:in-reply-to;\n\tbh=M95jPpQ630xVl/mXvfoloFfGUzzEQHulmCGYl5mPWEo=;\n\tb=etxW2VlGnhrJscfTS8AY/QwzYpa2IStX5WYORkKmaDjW/FGGmxcAqpRl7clODG0Qbn\n\tydzGdNOMeJ0gD3gFV9vJ5FHBevzM8xXN9gzwgYR+EzAY3l4tH2vE+oflaUyuOzcehlYd\n\t4V7HlQ+uz7QW2wc1eg2o1mcmczzCEqhIiQybreQ1HqTBBZq1GsADrsR3PeAIE5LZ4HHF\n\tr+10NTErVB0t7CxEFEVyGXTzg3cfr/qUXx0zPQuQaCo21apx7MKl0kHs37Rpy54GoFgr\n\tWyY4giIXF++PtpmyVVdlBoGRp/qcxqNUdVbWPKaBz7obkwBMxqLOVZjtvdr6JU7NDrl1\n\tljlQ==","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20161025;\n\th=x-gm-message-state:date:from:to:cc:subject:message-id:references\n\t:mime-version:content-disposition:content-transfer-encoding\n\t:in-reply-to;\n\tbh=M95jPpQ630xVl/mXvfoloFfGUzzEQHulmCGYl5mPWEo=;\n\tb=QOR0R97F9Q9SzDbAYneQCcIwYrbsWWsA6SAWMHFrk65NhtgxghUScMOO5BKmbt4Ly4\n\t7W4McosrdxO2SijfyefJhBBrHSD7iQmBBxeLZRNY0Sby0gNRchXtLeoONtvSRP+wTATv\n\tBWIYEC7vnfjP8Yjt6PewfBL4SonvLpBJ/vXLfLg77MkOHVV/GtQOCBCC6JaPnL3dcYua\n\t69xkaez5Ai2P1S6VRLjsCGXYRt3Dl7Jin5yz75MToNxs8Thzj/+hWn/JWmiZVkay6uL6\n\t19DVTA6BB5jDLXEnBN3Hj7c4nT8T3r4dI3iCJ0YpFcRoS1+CA9lIkVxlh0XyL8x0jkB7\n\tZxZQ==","X-Gm-Message-State":"AOAM531OBY0Yq7Rb0NXGLDtTktkybtuoTPP6WYDAGVBYxsRgwDtwg4/3\n\tBf68fZtxteCQ0CUilJAdrBJ4mBTuUgmRKQ==","X-Google-Smtp-Source":"ABdhPJwZnsKY8R3nuAUyJSgONE/DocJ5GJWgwpiS0Z2t4za6nJAzyfv0Z6agLZNyP7BJ3Tr0JnSi7Q==","X-Received":"by 2002:a05:6512:1053:: with SMTP id\n\tc19mr16421897lfb.298.1609068127428; \n\tSun, 27 Dec 2020 03:22:07 -0800 (PST)","Date":"Sun, 27 Dec 2020 12:22:05 +0100","From":"Niklas =?iso-8859-1?q?S=F6derlund?= <niklas.soderlund@ragnatech.se>","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Message-ID":"<X+huXZxqK5XvoeBE@wyvern>","References":"<20201227100331.1347-1-laurent.pinchart@ideasonboard.com>","MIME-Version":"1.0","Content-Disposition":"inline","In-Reply-To":"<20201227100331.1347-1-laurent.pinchart@ideasonboard.com>","Subject":"Re: [libcamera-devel] [PATCH] libcamera: utils: Add reverse adapter\n\tfor range-based loop","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>","Cc":"libcamera-devel@lists.libcamera.org","Content-Type":"text/plain; charset=\"iso-8859-1\"","Content-Transfer-Encoding":"quoted-printable","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":14373,"web_url":"https://patchwork.libcamera.org/comment/14373/","msgid":"<20201228093037.ewgqsyxiwofiefdy@uno.localdomain>","date":"2020-12-28T09:30:37","subject":"Re: [libcamera-devel] [PATCH] libcamera: utils: Add reverse adapter\n\tfor range-based loop","submitter":{"id":3,"url":"https://patchwork.libcamera.org/api/people/3/","name":"Jacopo Mondi","email":"jacopo@jmondi.org"},"content":"Hi Laurent,\n\nOn Sun, Dec 27, 2020 at 12:03:31PM +0200, Laurent Pinchart wrote:\n> Add a utils::reverse() function that creates an adapter wrapping in\n> iterable, such that range-based iteration over the adapter iterates over\n> the iterable in reverse order.\n>\n> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n> ---\n>  include/libcamera/internal/utils.h | 27 +++++++++++++++++++++++++++\n>  src/libcamera/utils.cpp            |  8 ++++++++\n>  2 files changed, 35 insertions(+)\n>\n> This will be used in an upcoming patch series, I'm already sending it\n> out to get the idea reviewed.\n>\n> diff --git a/include/libcamera/internal/utils.h b/include/libcamera/internal/utils.h\n> index f08134afb5ba..d0146b71727d 100644\n> --- a/include/libcamera/internal/utils.h\n> +++ b/include/libcamera/internal/utils.h\n> @@ -203,6 +203,33 @@ constexpr unsigned int alignUp(unsigned int value, unsigned int alignment)\n>  \treturn (value + alignment - 1) / alignment * alignment;\n>  }\n>\n> +namespace details {\n> +\n> +template<typename T>\n> +struct reverse_adapter {\n> +\tT &iterable;\n> +};\n> +\n> +template<typename T>\n> +auto begin(reverse_adapter<T> r)\n> +{\n> +\treturn std::rbegin(r.iterable);\n> +}\n> +\n> +template<typename T>\n> +auto end(reverse_adapter<T> r)\n> +{\n> +\treturn std::rend(r.iterable);\n> +}\n> +\n> +} /* namespace details */\n> +\n> +template<typename T>\n> +details::reverse_adapter<T> reverse(T &&iterable)\n> +{\n> +\treturn { iterable };\n> +}\n> +\n\nClever!!\n\nI thought we could get away with reverse_iterator, but mixin it\nrange-based loops is cumbersome. This feels very natural on the\ncontrary\n\nReviewed-by: Jacopo Mondi <jacopo@jmondi.org>\n\nThanks\n   j\n\n>  } /* namespace utils */\n>\n>  } /* namespace libcamera */\n> diff --git a/src/libcamera/utils.cpp b/src/libcamera/utils.cpp\n> index e90375ae115c..c4098a74e0ab 100644\n> --- a/src/libcamera/utils.cpp\n> +++ b/src/libcamera/utils.cpp\n> @@ -464,6 +464,14 @@ std::string libcameraSourcePath()\n>   * \\return The value rounded up to the nearest multiple of \\a alignment\n>   */\n>\n> +/**\n> + * \\fn reverse(T &&iterable)\n> + * \\brief Wrap an iterable to reverse iteration in a range-based loop\n> + * \\param[in] iterable The iterable\n> + * \\return A value of unspecified type that, when used in a range-based for\n> + * loop, will cause the loop to iterate over the \\a iterable in reverse order\n> + */\n> +\n>  } /* namespace utils */\n>\n>  } /* namespace libcamera */\n> --\n> Regards,\n>\n> Laurent Pinchart\n>\n> _______________________________________________\n> libcamera-devel mailing list\n> libcamera-devel@lists.libcamera.org\n> https://lists.libcamera.org/listinfo/libcamera-devel","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 BA4C3C0F1B\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 28 Dec 2020 09:30:26 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id DFDC46159A;\n\tMon, 28 Dec 2020 10:30:25 +0100 (CET)","from relay3-d.mail.gandi.net (relay3-d.mail.gandi.net\n\t[217.70.183.195])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 72A1C6031E\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 28 Dec 2020 10:30:24 +0100 (CET)","from uno.localdomain (2-224-242-101.ip172.fastwebnet.it\n\t[2.224.242.101]) (Authenticated sender: jacopo@jmondi.org)\n\tby relay3-d.mail.gandi.net (Postfix) with ESMTPSA id D6E5A6000F;\n\tMon, 28 Dec 2020 09:30:23 +0000 (UTC)"],"X-Originating-IP":"2.224.242.101","Date":"Mon, 28 Dec 2020 10:30:37 +0100","From":"Jacopo Mondi <jacopo@jmondi.org>","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Message-ID":"<20201228093037.ewgqsyxiwofiefdy@uno.localdomain>","References":"<20201227100331.1347-1-laurent.pinchart@ideasonboard.com>","MIME-Version":"1.0","Content-Disposition":"inline","In-Reply-To":"<20201227100331.1347-1-laurent.pinchart@ideasonboard.com>","Subject":"Re: [libcamera-devel] [PATCH] libcamera: utils: Add reverse adapter\n\tfor range-based loop","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>","Cc":"libcamera-devel@lists.libcamera.org","Content-Type":"text/plain; charset=\"us-ascii\"","Content-Transfer-Encoding":"7bit","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]