[{"id":5406,"web_url":"https://patchwork.libcamera.org/comment/5406/","msgid":"<20200625074721.vvkpisdmulnxddvy@uno.localdomain>","date":"2020-06-25T07:47:21","subject":"Re: [libcamera-devel] [PATCH] libcamera: utils: Add map_keys()\n\tfunction","submitter":{"id":3,"url":"https://patchwork.libcamera.org/api/people/3/","name":"Jacopo Mondi","email":"jacopo@jmondi.org"},"content":"Hi Laurent,\n   I still wonder why we don't have this in STL...\n\nOn Thu, Jun 25, 2020 at 04:23:35AM +0300, Laurent Pinchart wrote:\n> Add a map_keys() function to the utils namespace to extract keys from a\n> map.\n>\n> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n> ---\n>  include/libcamera/internal/utils.h | 10 ++++++++++\n>  src/libcamera/utils.cpp            |  7 +++++++\n>  test/utils.cpp                     | 21 +++++++++++++++++++++\n>  3 files changed, 38 insertions(+)\n>\n> diff --git a/include/libcamera/internal/utils.h b/include/libcamera/internal/utils.h\n> index 0953423ee8d0..4fe4843922a9 100644\n> --- a/include/libcamera/internal/utils.h\n> +++ b/include/libcamera/internal/utils.h\n> @@ -11,6 +11,7 @@\n>  #include <chrono>\n>  #include <memory>\n>  #include <ostream>\n> +#include <set>\n>  #include <sstream>\n>  #include <string>\n>  #include <string.h>\n> @@ -36,6 +37,15 @@ const char *basename(const char *path);\n>  char *secure_getenv(const char *name);\n>  std::string dirname(const std::string &path);\n>\n> +template<typename T>\n> +std::set<typename T::key_type> map_keys(const T &map)\n\nKeys are unique and sorted in maps, can't we return a vector ? Is this\nmeant to support multimaps too ? If that's not desired, can we use\nstd::map<class Key, T> as the template parameter ?\n\n(To be honest, calling this on a multimap opens one question: do we\nwant the -unique- keys, or all the keys ? The number of keys, if\nunique, would be less than the number of actual entries in the map...\nThis makes me feel we want this for maps only)\n\n\n> +{\n> +\tstd::set<typename T::key_type> keys;\n> +\tstd::transform(map.begin(), map.end(), std::inserter(keys, keys.end()),\n> +\t\t       [](const auto &value) { return value.first; });\n> +\treturn keys;\n> +}\n> +\n>  template<class InputIt1, class InputIt2>\n>  unsigned int set_overlap(InputIt1 first1, InputIt1 last1,\n>  \t\t\t InputIt2 first2, InputIt2 last2)\n> diff --git a/src/libcamera/utils.cpp b/src/libcamera/utils.cpp\n> index d55338fe681a..1eb8970a5bbc 100644\n> --- a/src/libcamera/utils.cpp\n> +++ b/src/libcamera/utils.cpp\n> @@ -127,6 +127,13 @@ std::string dirname(const std::string &path)\n>  \treturn path.substr(0, pos + 1);\n>  }\n>\n> +/**\n> + * \\fn std::set<typename T::key_type> map_keys(const T &map)\n> + * \\brief Retrieve the keys of a std::map<>\n> + * \\param[in] map The map whose keys to retrieve\n> + * \\return A std::set<> containing the keys of \\a map\n> + */\n> +\n>  /**\n>   * \\fn libcamera::utils::set_overlap(InputIt1 first1, InputIt1 last1,\n>   *\t\t\t\t     InputIt2 first2, InputIt2 last2)\n> diff --git a/test/utils.cpp b/test/utils.cpp\n> index 66b91f1203e1..a9d072030f1c 100644\n> --- a/test/utils.cpp\n> +++ b/test/utils.cpp\n> @@ -6,6 +6,8 @@\n>   */\n>\n>  #include <iostream>\n> +#include <map>\n> +#include <set>\n>  #include <sstream>\n>  #include <string>\n>  #include <vector>\n> @@ -144,6 +146,25 @@ protected:\n>  \t\tif (TestPass != testDirname())\n>  \t\t\treturn TestFail;\n>\n> +\n> +\t\t/* utils::map_keys() test. */\n> +\t\tconst std::map<std::string, unsigned int> map{\n> +\t\t\t{ \"zero\", 0 },\n> +\t\t\t{ \"one\", 1 },\n> +\t\t\t{ \"two\", 2 },\n> +\t\t};\n> +\t\tconst std::set<std::string> expectedKeys{\n> +\t\t\t\"zero\",\n> +\t\t\t\"one\",\n> +\t\t\t\"two\",\n> +\t\t};\n\nHow are keys sorted here ?\n\n> +\n> +\t\tconst std::set<std::string> keys = utils::map_keys(map);\n> +\t\tif (keys != expectedKeys) {\n\nThis matches the sorting order of expectedKeys by chance ? I see\nstd::set::operator== assuming lhs and rhs to be sorted equally\n\n> +\t\t\tcerr << \"utils::map_keys() test failed\" << endl;\n> +\t\t\treturn TestFail;\n> +\t\t}\n> +\n>  \t\treturn TestPass;\n>  \t}\n>  };\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 6BEB6C0100\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu, 25 Jun 2020 07:43:56 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id CE49A609A9;\n\tThu, 25 Jun 2020 09:43:55 +0200 (CEST)","from relay9-d.mail.gandi.net (relay9-d.mail.gandi.net\n\t[217.70.183.199])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id DE705603BE\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 25 Jun 2020 09:43:54 +0200 (CEST)","from uno.localdomain (93-34-118-233.ip49.fastwebnet.it\n\t[93.34.118.233]) (Authenticated sender: jacopo@jmondi.org)\n\tby relay9-d.mail.gandi.net (Postfix) with ESMTPSA id 64194FF818;\n\tThu, 25 Jun 2020 07:43:54 +0000 (UTC)"],"X-Originating-IP":"93.34.118.233","Date":"Thu, 25 Jun 2020 09:47:21 +0200","From":"Jacopo Mondi <jacopo@jmondi.org>","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Message-ID":"<20200625074721.vvkpisdmulnxddvy@uno.localdomain>","References":"<20200625012335.7717-1-laurent.pinchart@ideasonboard.com>","MIME-Version":"1.0","Content-Disposition":"inline","In-Reply-To":"<20200625012335.7717-1-laurent.pinchart@ideasonboard.com>","Subject":"Re: [libcamera-devel] [PATCH] libcamera: utils: Add map_keys()\n\tfunction","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>"}},{"id":5411,"web_url":"https://patchwork.libcamera.org/comment/5411/","msgid":"<a6a56e4c-8b6c-1860-f9a1-99e3531d7673@uajain.com>","date":"2020-06-25T08:12:12","subject":"Re: [libcamera-devel] [PATCH] libcamera: utils: Add map_keys()\n\tfunction","submitter":{"id":1,"url":"https://patchwork.libcamera.org/api/people/1/","name":"Umang Jain","email":"email@uajain.com"},"content":"Hi Laurent,\n\nI have a query below.\n\nOn 6/25/20 6:53 AM, Laurent Pinchart wrote:\n> Add a map_keys() function to the utils namespace to extract keys from a\n> map.\n>\n> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n> ---\n>   include/libcamera/internal/utils.h | 10 ++++++++++\n>   src/libcamera/utils.cpp            |  7 +++++++\n>   test/utils.cpp                     | 21 +++++++++++++++++++++\n>   3 files changed, 38 insertions(+)\n>\n> diff --git a/include/libcamera/internal/utils.h b/include/libcamera/internal/utils.h\n> index 0953423ee8d0..4fe4843922a9 100644\n> --- a/include/libcamera/internal/utils.h\n> +++ b/include/libcamera/internal/utils.h\n> @@ -11,6 +11,7 @@\n>   #include <chrono>\n>   #include <memory>\n>   #include <ostream>\n> +#include <set>\n>   #include <sstream>\n>   #include <string>\n>   #include <string.h>\n> @@ -36,6 +37,15 @@ const char *basename(const char *path);\n>   char *secure_getenv(const char *name);\n>   std::string dirname(const std::string &path);\n>   \n> +template<typename T>\n> +std::set<typename T::key_type> map_keys(const T &map)\n> +{\n> +\tstd::set<typename T::key_type> keys;\n> +\tstd::transform(map.begin(), map.end(), std::inserter(keys, keys.end()),\nI am not able to wrap my head around keys.end() as the beginning \nposition for the\ninsertor? keys.end() points to `past-the-end`element which should not be \nde-referenced,\nas claimed in the online docs. Can you explain why we cannot use:\n\nstd::inserter(keys, keys.begin()) ?\n\n> +\t\t       [](const auto &value) { return value.first; });\n> +\treturn keys;\n> +}\n> +\n>   template<class InputIt1, class InputIt2>\n>   unsigned int set_overlap(InputIt1 first1, InputIt1 last1,\n>   \t\t\t InputIt2 first2, InputIt2 last2)\n> diff --git a/src/libcamera/utils.cpp b/src/libcamera/utils.cpp\n> index d55338fe681a..1eb8970a5bbc 100644\n> --- a/src/libcamera/utils.cpp\n> +++ b/src/libcamera/utils.cpp\n> @@ -127,6 +127,13 @@ std::string dirname(const std::string &path)\n>   \treturn path.substr(0, pos + 1);\n>   }\n>   \n> +/**\n> + * \\fn std::set<typename T::key_type> map_keys(const T &map)\n> + * \\brief Retrieve the keys of a std::map<>\n> + * \\param[in] map The map whose keys to retrieve\n> + * \\return A std::set<> containing the keys of \\a map\n> + */\n> +\n>   /**\n>    * \\fn libcamera::utils::set_overlap(InputIt1 first1, InputIt1 last1,\n>    *\t\t\t\t     InputIt2 first2, InputIt2 last2)\n> diff --git a/test/utils.cpp b/test/utils.cpp\n> index 66b91f1203e1..a9d072030f1c 100644\n> --- a/test/utils.cpp\n> +++ b/test/utils.cpp\n> @@ -6,6 +6,8 @@\n>    */\n>   \n>   #include <iostream>\n> +#include <map>\n> +#include <set>\n>   #include <sstream>\n>   #include <string>\n>   #include <vector>\n> @@ -144,6 +146,25 @@ protected:\n>   \t\tif (TestPass != testDirname())\n>   \t\t\treturn TestFail;\n>   \n> +\n> +\t\t/* utils::map_keys() test. */\n> +\t\tconst std::map<std::string, unsigned int> map{\n> +\t\t\t{ \"zero\", 0 },\n> +\t\t\t{ \"one\", 1 },\n> +\t\t\t{ \"two\", 2 },\n> +\t\t};\n> +\t\tconst std::set<std::string> expectedKeys{\n> +\t\t\t\"zero\",\n> +\t\t\t\"one\",\n> +\t\t\t\"two\",\n> +\t\t};\n> +\n> +\t\tconst std::set<std::string> keys = utils::map_keys(map);\n> +\t\tif (keys != expectedKeys) {\n> +\t\t\tcerr << \"utils::map_keys() test failed\" << endl;\n> +\t\t\treturn TestFail;\n> +\t\t}\n> +\n>   \t\treturn TestPass;\n>   \t}\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 98E04C0100\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu, 25 Jun 2020 08:12:15 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 0CEC4609A9;\n\tThu, 25 Jun 2020 10:12:15 +0200 (CEST)","from o1.f.az.sendgrid.net (o1.f.az.sendgrid.net [208.117.55.132])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id DF4B1603BE\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 25 Jun 2020 10:12:13 +0200 (CEST)","by filterdrecv-p3mdw1-6dd9dd6d45-86x7g with SMTP id\n\tfilterdrecv-p3mdw1-6dd9dd6d45-86x7g-19-5EF45C5C-24\n\t2020-06-25 08:12:12.488877615 +0000 UTC m=+569381.855938524","from mail.uajain.com (unknown)\n\tby ismtpd0005p1hnd1.sendgrid.net (SG) with ESMTP\n\tid TrYJ3j4LTwS2XAf6SAqbAg Thu, 25 Jun 2020 08:12:12.011 +0000 (UTC)"],"Authentication-Results":"lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key;\n\tunprotected) header.d=uajain.com header.i=@uajain.com\n\theader.b=\"oZVZF6Kg\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=uajain.com;\n\th=subject:references:from:mime-version:in-reply-to:to:content-type:\n\tcontent-transfer-encoding;\n\ts=s1; bh=gNyXieJjNsijSxOm+9loY8hs4EdIVgQq33MDirdZMpw=;\n\tb=oZVZF6KgtHuwlwmeBEoZL1n/dPqqwXY3RsazZ3pJ8BUu4CXcGDjLOE3/ITig/xLG1A3p\n\tM4hQtH7kLwwbv3HuVkpzZRxObrk2ev0ccQAl9wJQYwVTzlYwaN3x2XSWM7qTxsHmwRNZ9k\n\tJV2zVA2wFonzQ3ghbfb+1eiDEeQNmW14w=","References":"<20200625012335.7717-1-laurent.pinchart@ideasonboard.com>","From":"Umang Jain <email@uajain.com>","Message-ID":"<a6a56e4c-8b6c-1860-f9a1-99e3531d7673@uajain.com>","Date":"Thu, 25 Jun 2020 08:12:12 +0000 (UTC)","Mime-Version":"1.0","In-Reply-To":"<20200625012335.7717-1-laurent.pinchart@ideasonboard.com>","X-SG-EID":"1Q40EQ7YGir8a9gjSIAdTjhngY657NMk9ckeo4dbHZDiOpywc/L3L9rFqlwE4KPcYFho/XlHW4zrk5y9XrA/WiyIEodGJAe7l8s4Iniz98cqW1/w9LUWCmLWL/1MQ4+CEiyZ+tWOGPFcOz91ifNSCTMESgePO44l+21DFt6e1YY367cBVDgYnozuuUH1NZ1Xj3UYZ4Ve68RMwpN19/8iicQ7lQC+/elLJiD3woCrTdz2Ol2XzLLozTPyyO5rAmUWchAJ6+VhE22cTnOkZVOTJg==","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>,\n\tlibcamera-devel@lists.libcamera.org","Content-Language":"en-US","Subject":"Re: [libcamera-devel] [PATCH] libcamera: utils: Add map_keys()\n\tfunction","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>","Content-Transfer-Encoding":"7bit","Content-Type":"text/plain; charset=\"us-ascii\"; Format=\"flowed\"","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":10854,"web_url":"https://patchwork.libcamera.org/comment/10854/","msgid":"<20200625100938.GC10256@oden.dyn.berto.se>","date":"2020-06-25T10:09:38","subject":"Re: [libcamera-devel] [PATCH] libcamera: utils: Add map_keys()\n\tfunction","submitter":{"id":5,"url":"https://patchwork.libcamera.org/api/people/5/","name":"Niklas Söderlund","email":"niklas.soderlund@ragnatech.se"},"content":"Hi Laurent,\n\nThanks for your work.\n\nOn 2020-06-25 04:23:35 +0300, Laurent Pinchart wrote:\n> Add a map_keys() function to the utils namespace to extract keys from a\n> map.\n> \n> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n\nReviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>\n\n> ---\n>  include/libcamera/internal/utils.h | 10 ++++++++++\n>  src/libcamera/utils.cpp            |  7 +++++++\n>  test/utils.cpp                     | 21 +++++++++++++++++++++\n>  3 files changed, 38 insertions(+)\n> \n> diff --git a/include/libcamera/internal/utils.h b/include/libcamera/internal/utils.h\n> index 0953423ee8d0..4fe4843922a9 100644\n> --- a/include/libcamera/internal/utils.h\n> +++ b/include/libcamera/internal/utils.h\n> @@ -11,6 +11,7 @@\n>  #include <chrono>\n>  #include <memory>\n>  #include <ostream>\n> +#include <set>\n>  #include <sstream>\n>  #include <string>\n>  #include <string.h>\n> @@ -36,6 +37,15 @@ const char *basename(const char *path);\n>  char *secure_getenv(const char *name);\n>  std::string dirname(const std::string &path);\n>  \n> +template<typename T>\n> +std::set<typename T::key_type> map_keys(const T &map)\n> +{\n> +\tstd::set<typename T::key_type> keys;\n> +\tstd::transform(map.begin(), map.end(), std::inserter(keys, keys.end()),\n> +\t\t       [](const auto &value) { return value.first; });\n> +\treturn keys;\n> +}\n> +\n>  template<class InputIt1, class InputIt2>\n>  unsigned int set_overlap(InputIt1 first1, InputIt1 last1,\n>  \t\t\t InputIt2 first2, InputIt2 last2)\n> diff --git a/src/libcamera/utils.cpp b/src/libcamera/utils.cpp\n> index d55338fe681a..1eb8970a5bbc 100644\n> --- a/src/libcamera/utils.cpp\n> +++ b/src/libcamera/utils.cpp\n> @@ -127,6 +127,13 @@ std::string dirname(const std::string &path)\n>  \treturn path.substr(0, pos + 1);\n>  }\n>  \n> +/**\n> + * \\fn std::set<typename T::key_type> map_keys(const T &map)\n> + * \\brief Retrieve the keys of a std::map<>\n> + * \\param[in] map The map whose keys to retrieve\n> + * \\return A std::set<> containing the keys of \\a map\n> + */\n> +\n>  /**\n>   * \\fn libcamera::utils::set_overlap(InputIt1 first1, InputIt1 last1,\n>   *\t\t\t\t     InputIt2 first2, InputIt2 last2)\n> diff --git a/test/utils.cpp b/test/utils.cpp\n> index 66b91f1203e1..a9d072030f1c 100644\n> --- a/test/utils.cpp\n> +++ b/test/utils.cpp\n> @@ -6,6 +6,8 @@\n>   */\n>  \n>  #include <iostream>\n> +#include <map>\n> +#include <set>\n>  #include <sstream>\n>  #include <string>\n>  #include <vector>\n> @@ -144,6 +146,25 @@ protected:\n>  \t\tif (TestPass != testDirname())\n>  \t\t\treturn TestFail;\n>  \n> +\n> +\t\t/* utils::map_keys() test. */\n> +\t\tconst std::map<std::string, unsigned int> map{\n> +\t\t\t{ \"zero\", 0 },\n> +\t\t\t{ \"one\", 1 },\n> +\t\t\t{ \"two\", 2 },\n> +\t\t};\n> +\t\tconst std::set<std::string> expectedKeys{\n> +\t\t\t\"zero\",\n> +\t\t\t\"one\",\n> +\t\t\t\"two\",\n> +\t\t};\n> +\n> +\t\tconst std::set<std::string> keys = utils::map_keys(map);\n> +\t\tif (keys != expectedKeys) {\n> +\t\t\tcerr << \"utils::map_keys() test failed\" << endl;\n> +\t\t\treturn TestFail;\n> +\t\t}\n> +\n>  \t\treturn TestPass;\n>  \t}\n>  };\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 5EA6FC0109\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu, 25 Jun 2020 10:09:44 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id C3FD6609C2;\n\tThu, 25 Jun 2020 12:09:43 +0200 (CEST)","from mail-lj1-x232.google.com (mail-lj1-x232.google.com\n\t[IPv6:2a00:1450:4864:20::232])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 3DAAF609A5\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 25 Jun 2020 12:09:42 +0200 (CEST)","by mail-lj1-x232.google.com with SMTP id s1so5878303ljo.0\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 25 Jun 2020 03:09:42 -0700 (PDT)","from localhost (h-209-203.A463.priv.bahnhof.se. [155.4.209.203])\n\tby smtp.gmail.com with ESMTPSA id\n\tu6sm4717080ljk.109.2020.06.25.03.09.39\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tThu, 25 Jun 2020 03:09:39 -0700 (PDT)"],"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=\"tBQnYWmY\"; 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=1NlsVy/a3HtXeJbqs7Qp092s3CaqXNr2p8dc1/M/3UQ=;\n\tb=tBQnYWmYmT0SksaIJyPcLItSjv2M+UTTnnLezTji5+OT4p0qXx/7HpgHPtgrJSRrBO\n\tAmy8/Y7EW7RRyBLZm+TitjDPvyv/p5JFcEf4k/j8BtDc/yKpQrnsQzMPUBS9mnnOhuLB\n\t47KQL/mxfSzjHz6WhWkIlx6CNKNcFfCqqGl6Lo1f47sr7HruyjFBmdUqp2N/G51AhKTH\n\t/GI2Z6xZMMNYrp/ftFScrQlWZKTdddtLvvhlgaxuqJ8D4tdEWLjQPjU/1CiJw6Pf2AW7\n\tIYc4LOsqvhu9wR6C5Du7/9iDjHhvO1zyOsY5wSIZrnQXb9HcJUzAMlpsXDgSZSC/UPH9\n\t1e8Q==","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=1NlsVy/a3HtXeJbqs7Qp092s3CaqXNr2p8dc1/M/3UQ=;\n\tb=sDsUKkBIHIz5rkeyQnr2po+ZKmNGw6aYySvQ1oph5QLNZaQHm5BjBHiD/7jyIYyH5x\n\tdT2+f6nKlZtrA3/TfGnQE2uB9m/oD+M6CJUEI2c0+5g/znSafjnh2WZxMv6jmZ+3XMSI\n\tx38dbTESlVuKP6hIwwFOXSrA95ljGN5minZMKUS3YhwbFe0mny6B/eC65Wr1lNUF52WT\n\t9xUXFQhnN1KCJowA2w2RdmIF/ejY867qpxPsFfQbkRpgfuTavzgmH8WkMd73gXi2kwf5\n\tiOSvsy3wCaQgrNN115rXx93C8x5ItY4WkqdDpu5K9+6bLJ0b2FAQL1RlI7PM51EEPl/x\n\tKDPA==","X-Gm-Message-State":"AOAM530JeGXhv/TquOIYxnE6C7hx2YzZn4COMrHbtsGQJAvFIH5jEJOC\n\tV0dQxD46UYPhzXX1IvmpZWZcwduqfqQ=","X-Google-Smtp-Source":"ABdhPJx3vGqBE4K68/j11XOnoAjewxuL0qmloPf1blzY/rIMLFigygewiS5Tn2qnAwrJt9uYkFAL/A==","X-Received":"by 2002:a2e:5c44:: with SMTP id q65mr755809ljb.156.1593079780262;\n\tThu, 25 Jun 2020 03:09:40 -0700 (PDT)","Date":"Thu, 25 Jun 2020 12:09:38 +0200","From":"Niklas =?iso-8859-1?q?S=F6derlund?= <niklas.soderlund@ragnatech.se>","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Message-ID":"<20200625100938.GC10256@oden.dyn.berto.se>","References":"<20200625012335.7717-1-laurent.pinchart@ideasonboard.com>","MIME-Version":"1.0","Content-Disposition":"inline","In-Reply-To":"<20200625012335.7717-1-laurent.pinchart@ideasonboard.com>","Subject":"Re: [libcamera-devel] [PATCH] libcamera: utils: Add map_keys()\n\tfunction","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":10859,"web_url":"https://patchwork.libcamera.org/comment/10859/","msgid":"<20200625141734.GK5865@pendragon.ideasonboard.com>","date":"2020-06-25T14:17:34","subject":"Re: [libcamera-devel] [PATCH] libcamera: utils: Add map_keys()\n\tfunction","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi Jacopo,\n\nOn Thu, Jun 25, 2020 at 09:47:21AM +0200, Jacopo Mondi wrote:\n> Hi Laurent,\n>    I still wonder why we don't have this in STL...\n\nIf you ever find an answer, I'll be interested to know :-)\n\n> On Thu, Jun 25, 2020 at 04:23:35AM +0300, Laurent Pinchart wrote:\n> > Add a map_keys() function to the utils namespace to extract keys from a\n> > map.\n> >\n> > Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n> > ---\n> >  include/libcamera/internal/utils.h | 10 ++++++++++\n> >  src/libcamera/utils.cpp            |  7 +++++++\n> >  test/utils.cpp                     | 21 +++++++++++++++++++++\n> >  3 files changed, 38 insertions(+)\n> >\n> > diff --git a/include/libcamera/internal/utils.h b/include/libcamera/internal/utils.h\n> > index 0953423ee8d0..4fe4843922a9 100644\n> > --- a/include/libcamera/internal/utils.h\n> > +++ b/include/libcamera/internal/utils.h\n> > @@ -11,6 +11,7 @@\n> >  #include <chrono>\n> >  #include <memory>\n> >  #include <ostream>\n> > +#include <set>\n> >  #include <sstream>\n> >  #include <string>\n> >  #include <string.h>\n> > @@ -36,6 +37,15 @@ const char *basename(const char *path);\n> >  char *secure_getenv(const char *name);\n> >  std::string dirname(const std::string &path);\n> >\n> > +template<typename T>\n> > +std::set<typename T::key_type> map_keys(const T &map)\n> \n> Keys are unique and sorted in maps, can't we return a vector ? Is this\n> meant to support multimaps too ? If that's not desired, can we use\n> std::map<class Key, T> as the template parameter ?\n> \n> (To be honest, calling this on a multimap opens one question: do we\n> want the -unique- keys, or all the keys ? The number of keys, if\n> unique, would be less than the number of actual entries in the map...\n> This makes me feel we want this for maps only)\n\nI'd rather make this specific to std::map for now. Returning a vector\nwould make sense, and I think that's what I'd prefer. Maybe this is why\nSTL doesn't have a std::map::keys() method, they couldn't decide what\ncontainer it should return ;-)\n\n> > +{\n> > +\tstd::set<typename T::key_type> keys;\n> > +\tstd::transform(map.begin(), map.end(), std::inserter(keys, keys.end()),\n> > +\t\t       [](const auto &value) { return value.first; });\n> > +\treturn keys;\n> > +}\n> > +\n> >  template<class InputIt1, class InputIt2>\n> >  unsigned int set_overlap(InputIt1 first1, InputIt1 last1,\n> >  \t\t\t InputIt2 first2, InputIt2 last2)\n> > diff --git a/src/libcamera/utils.cpp b/src/libcamera/utils.cpp\n> > index d55338fe681a..1eb8970a5bbc 100644\n> > --- a/src/libcamera/utils.cpp\n> > +++ b/src/libcamera/utils.cpp\n> > @@ -127,6 +127,13 @@ std::string dirname(const std::string &path)\n> >  \treturn path.substr(0, pos + 1);\n> >  }\n> >\n> > +/**\n> > + * \\fn std::set<typename T::key_type> map_keys(const T &map)\n> > + * \\brief Retrieve the keys of a std::map<>\n> > + * \\param[in] map The map whose keys to retrieve\n> > + * \\return A std::set<> containing the keys of \\a map\n> > + */\n> > +\n> >  /**\n> >   * \\fn libcamera::utils::set_overlap(InputIt1 first1, InputIt1 last1,\n> >   *\t\t\t\t     InputIt2 first2, InputIt2 last2)\n> > diff --git a/test/utils.cpp b/test/utils.cpp\n> > index 66b91f1203e1..a9d072030f1c 100644\n> > --- a/test/utils.cpp\n> > +++ b/test/utils.cpp\n> > @@ -6,6 +6,8 @@\n> >   */\n> >\n> >  #include <iostream>\n> > +#include <map>\n> > +#include <set>\n> >  #include <sstream>\n> >  #include <string>\n> >  #include <vector>\n> > @@ -144,6 +146,25 @@ protected:\n> >  \t\tif (TestPass != testDirname())\n> >  \t\t\treturn TestFail;\n> >\n> > +\n> > +\t\t/* utils::map_keys() test. */\n> > +\t\tconst std::map<std::string, unsigned int> map{\n> > +\t\t\t{ \"zero\", 0 },\n> > +\t\t\t{ \"one\", 1 },\n> > +\t\t\t{ \"two\", 2 },\n> > +\t\t};\n> > +\t\tconst std::set<std::string> expectedKeys{\n> > +\t\t\t\"zero\",\n> > +\t\t\t\"one\",\n> > +\t\t\t\"two\",\n> > +\t\t};\n> \n> How are keys sorted here ?\n\nstd::map<> and std::set<> are sorted automatically. I think the test\nshould actually use a different order in the initializer list of\nexpectedKeys, just to show it gets sorted.\n\n> > +\n> > +\t\tconst std::set<std::string> keys = utils::map_keys(map);\n> > +\t\tif (keys != expectedKeys) {\n> \n> This matches the sorting order of expectedKeys by chance ? I see\n> std::set::operator== assuming lhs and rhs to be sorted equally\n> \n> > +\t\t\tcerr << \"utils::map_keys() test failed\" << endl;\n> > +\t\t\treturn TestFail;\n> > +\t\t}\n> > +\n> >  \t\treturn TestPass;\n> >  \t}\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 37488C0100\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu, 25 Jun 2020 14:17:39 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id AC096609C3;\n\tThu, 25 Jun 2020 16:17:38 +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 BC67E609C2\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 25 Jun 2020 16:17:36 +0200 (CEST)","from pendragon.ideasonboard.com (81-175-216-236.bb.dnainternet.fi\n\t[81.175.216.236])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id E4CDA72E;\n\tThu, 25 Jun 2020 16:17:35 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"MKN4rxfg\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1593094656;\n\tbh=WstgCEwMyXkn49Tts+v387/BKDeTSZ8HMzHBy9Ep1lQ=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=MKN4rxfgAz8izKmQ7wJ3GubmvILvYrG5942ilHhhhBjl/+dLGaxcTWUmHRylj65Gc\n\tas4InuHznblLAYDNNgBgw6pqeaR7eM1UxaEmXPc1EMYxLgMmf3mo1/E2Bgv2uEqewS\n\tq8wRNdk1JOhHzHBrzo1mQp2m4yl/dgeKLWM3RZx8=","Date":"Thu, 25 Jun 2020 17:17:34 +0300","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Jacopo Mondi <jacopo@jmondi.org>","Message-ID":"<20200625141734.GK5865@pendragon.ideasonboard.com>","References":"<20200625012335.7717-1-laurent.pinchart@ideasonboard.com>\n\t<20200625074721.vvkpisdmulnxddvy@uno.localdomain>","MIME-Version":"1.0","Content-Disposition":"inline","In-Reply-To":"<20200625074721.vvkpisdmulnxddvy@uno.localdomain>","Subject":"Re: [libcamera-devel] [PATCH] libcamera: utils: Add map_keys()\n\tfunction","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>"}},{"id":10860,"web_url":"https://patchwork.libcamera.org/comment/10860/","msgid":"<20200625142801.GL5865@pendragon.ideasonboard.com>","date":"2020-06-25T14:28:01","subject":"Re: [libcamera-devel] [PATCH] libcamera: utils: Add map_keys()\n\tfunction","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi Umang,\n\nOn Thu, Jun 25, 2020 at 08:12:12AM +0000, Umang Jain wrote:\n> On 6/25/20 6:53 AM, Laurent Pinchart wrote:\n> > Add a map_keys() function to the utils namespace to extract keys from a\n> > map.\n> >\n> > Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n> > ---\n> >   include/libcamera/internal/utils.h | 10 ++++++++++\n> >   src/libcamera/utils.cpp            |  7 +++++++\n> >   test/utils.cpp                     | 21 +++++++++++++++++++++\n> >   3 files changed, 38 insertions(+)\n> >\n> > diff --git a/include/libcamera/internal/utils.h b/include/libcamera/internal/utils.h\n> > index 0953423ee8d0..4fe4843922a9 100644\n> > --- a/include/libcamera/internal/utils.h\n> > +++ b/include/libcamera/internal/utils.h\n> > @@ -11,6 +11,7 @@\n> >   #include <chrono>\n> >   #include <memory>\n> >   #include <ostream>\n> > +#include <set>\n> >   #include <sstream>\n> >   #include <string>\n> >   #include <string.h>\n> > @@ -36,6 +37,15 @@ const char *basename(const char *path);\n> >   char *secure_getenv(const char *name);\n> >   std::string dirname(const std::string &path);\n> >   \n> > +template<typename T>\n> > +std::set<typename T::key_type> map_keys(const T &map)\n> > +{\n> > +\tstd::set<typename T::key_type> keys;\n> > +\tstd::transform(map.begin(), map.end(), std::inserter(keys, keys.end()),\n>\n> I am not able to wrap my head around keys.end() as the beginning\n> position for the insertor? keys.end() points to `past-the-end`element\n> which should not be de-referenced, as claimed in the online docs. Can\n> you explain why we cannot use:\n> \n> std::inserter(keys, keys.begin()) ?\n\nstd::inserter() is a helper that return a std::insert_iterator. An\nstd::insert_iterator is an iterator that invokes the insert() function of\nthe container it is related to in its operator=(). Calling\n\n\titer = value;\n\non an std::insert_iterator results in\n\n\titer = container->insert(iter, value);\n\t++iter;\n\nwhile calling operator++() directly on the iterator is a no-op.\n\nThe insert() function of STL containers takes an iterator as a parameter\nto specify the insertion position. The insertion happens just prior to\niterator. For std::list and std::vector that's guaranteed, while for\nstd::map and std::set that's just a hint: maps and sets are sorted by\nkey, so the insertion position depends on the key. Still, passing the\ncorrect hint to insert() for map and set can help with performances.\n\nUsing keys.end() will thus result in the new element being inserted just\nbefore the end of the container. As they map is sorted by key, the\nstd::transform call will insert the keys in the set in increasing order.\nend() is thus the correct hint in that case. begin() would work too, but\nwould result in worse performances, as the insert() function would\nrealize that the hint is not correct, and will look up the correct\nposition. See https://en.cppreference.com/w/cpp/container/map/insert\nthat states\n\nComplexity\n\n[...]\n\n4-6) Amortized constant if the insertion happens in the position just\nbefore the hint, logarithmic in the size of the container otherwise.\n\n> > +\t\t       [](const auto &value) { return value.first; });\n> > +\treturn keys;\n> > +}\n> > +\n> >   template<class InputIt1, class InputIt2>\n> >   unsigned int set_overlap(InputIt1 first1, InputIt1 last1,\n> >   \t\t\t InputIt2 first2, InputIt2 last2)\n> > diff --git a/src/libcamera/utils.cpp b/src/libcamera/utils.cpp\n> > index d55338fe681a..1eb8970a5bbc 100644\n> > --- a/src/libcamera/utils.cpp\n> > +++ b/src/libcamera/utils.cpp\n> > @@ -127,6 +127,13 @@ std::string dirname(const std::string &path)\n> >   \treturn path.substr(0, pos + 1);\n> >   }\n> >   \n> > +/**\n> > + * \\fn std::set<typename T::key_type> map_keys(const T &map)\n> > + * \\brief Retrieve the keys of a std::map<>\n> > + * \\param[in] map The map whose keys to retrieve\n> > + * \\return A std::set<> containing the keys of \\a map\n> > + */\n> > +\n> >   /**\n> >    * \\fn libcamera::utils::set_overlap(InputIt1 first1, InputIt1 last1,\n> >    *\t\t\t\t     InputIt2 first2, InputIt2 last2)\n> > diff --git a/test/utils.cpp b/test/utils.cpp\n> > index 66b91f1203e1..a9d072030f1c 100644\n> > --- a/test/utils.cpp\n> > +++ b/test/utils.cpp\n> > @@ -6,6 +6,8 @@\n> >    */\n> >   \n> >   #include <iostream>\n> > +#include <map>\n> > +#include <set>\n> >   #include <sstream>\n> >   #include <string>\n> >   #include <vector>\n> > @@ -144,6 +146,25 @@ protected:\n> >   \t\tif (TestPass != testDirname())\n> >   \t\t\treturn TestFail;\n> >   \n> > +\n> > +\t\t/* utils::map_keys() test. */\n> > +\t\tconst std::map<std::string, unsigned int> map{\n> > +\t\t\t{ \"zero\", 0 },\n> > +\t\t\t{ \"one\", 1 },\n> > +\t\t\t{ \"two\", 2 },\n> > +\t\t};\n> > +\t\tconst std::set<std::string> expectedKeys{\n> > +\t\t\t\"zero\",\n> > +\t\t\t\"one\",\n> > +\t\t\t\"two\",\n> > +\t\t};\n> > +\n> > +\t\tconst std::set<std::string> keys = utils::map_keys(map);\n> > +\t\tif (keys != expectedKeys) {\n> > +\t\t\tcerr << \"utils::map_keys() test failed\" << endl;\n> > +\t\t\treturn TestFail;\n> > +\t\t}\n> > +\n> >   \t\treturn TestPass;\n> >   \t}\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 4CB05C0109\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu, 25 Jun 2020 14:28:04 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id C5865609C5;\n\tThu, 25 Jun 2020 16:28:03 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 154E4609C2\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 25 Jun 2020 16:28:03 +0200 (CEST)","from pendragon.ideasonboard.com (81-175-216-236.bb.dnainternet.fi\n\t[81.175.216.236])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 8057E72E;\n\tThu, 25 Jun 2020 16:28:02 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"GRR5HYoS\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1593095282;\n\tbh=vLLZiEeZA5t1G5n7I3V3x5YcCf2B5iIWbfw9fJrAxz4=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=GRR5HYoSVDcNrO1GpiZloU9f6GekanIzHTdnFs9EpbXuqwvWRE8NAi2Qrz588HQJR\n\tSDq5LpL+daOAFzdlvnRhKZ0OJ6FH88tiP4o1sLJT876bm9wsbC7SgenAwiH0vGOtmL\n\tq3//TwMsET/WP/8IH0JZrtooi/1660d5zlcCV46E=","Date":"Thu, 25 Jun 2020 17:28:01 +0300","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Umang Jain <email@uajain.com>","Message-ID":"<20200625142801.GL5865@pendragon.ideasonboard.com>","References":"<20200625012335.7717-1-laurent.pinchart@ideasonboard.com>\n\t<a6a56e4c-8b6c-1860-f9a1-99e3531d7673@uajain.com>","MIME-Version":"1.0","Content-Disposition":"inline","In-Reply-To":"<a6a56e4c-8b6c-1860-f9a1-99e3531d7673@uajain.com>","Subject":"Re: [libcamera-devel] [PATCH] libcamera: utils: Add map_keys()\n\tfunction","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>"}},{"id":10880,"web_url":"https://patchwork.libcamera.org/comment/10880/","msgid":"<f42618a0-f3ba-0eb7-ee50-1d9eaf37c952@uajain.com>","date":"2020-06-26T06:14:08","subject":"Re: [libcamera-devel] [PATCH] libcamera: utils: Add map_keys()\n\tfunction","submitter":{"id":1,"url":"https://patchwork.libcamera.org/api/people/1/","name":"Umang Jain","email":"email@uajain.com"},"content":"Hi Laurent,\n\nOn 6/25/20 7:58 PM, Laurent Pinchart wrote:\n> Hi Umang,\n>\n> On Thu, Jun 25, 2020 at 08:12:12AM +0000, Umang Jain wrote:\n>> On 6/25/20 6:53 AM, Laurent Pinchart wrote:\n>>> Add a map_keys() function to the utils namespace to extract keys from a\n>>> map.\n>>>\n>>> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n>>> ---\n>>>    include/libcamera/internal/utils.h | 10 ++++++++++\n>>>    src/libcamera/utils.cpp            |  7 +++++++\n>>>    test/utils.cpp                     | 21 +++++++++++++++++++++\n>>>    3 files changed, 38 insertions(+)\n>>>\n>>> diff --git a/include/libcamera/internal/utils.h b/include/libcamera/internal/utils.h\n>>> index 0953423ee8d0..4fe4843922a9 100644\n>>> --- a/include/libcamera/internal/utils.h\n>>> +++ b/include/libcamera/internal/utils.h\n>>> @@ -11,6 +11,7 @@\n>>>    #include <chrono>\n>>>    #include <memory>\n>>>    #include <ostream>\n>>> +#include <set>\n>>>    #include <sstream>\n>>>    #include <string>\n>>>    #include <string.h>\n>>> @@ -36,6 +37,15 @@ const char *basename(const char *path);\n>>>    char *secure_getenv(const char *name);\n>>>    std::string dirname(const std::string &path);\n>>>    \n>>> +template<typename T>\n>>> +std::set<typename T::key_type> map_keys(const T &map)\n>>> +{\n>>> +\tstd::set<typename T::key_type> keys;\n>>> +\tstd::transform(map.begin(), map.end(), std::inserter(keys, keys.end()),\n>> I am not able to wrap my head around keys.end() as the beginning\n>> position for the insertor? keys.end() points to `past-the-end`element\n>> which should not be de-referenced, as claimed in the online docs. Can\n>> you explain why we cannot use:\n>>\n>> std::inserter(keys, keys.begin()) ?\n> std::inserter() is a helper that return a std::insert_iterator. An\n> std::insert_iterator is an iterator that invokes the insert() function of\n> the container it is related to in its operator=(). Calling\n>\n> \titer = value;\n>\n> on an std::insert_iterator results in\n>\n> \titer = container->insert(iter, value);\n> \t++iter;\n>\n> while calling operator++() directly on the iterator is a no-op.\n>\n> The insert() function of STL containers takes an iterator as a parameter\n> to specify the insertion position. The insertion happens just prior to\n> iterator. For std::list and std::vector that's guaranteed, while for\n> std::map and std::set that's just a hint: maps and sets are sorted by\n> key, so the insertion position depends on the key. Still, passing the\n> correct hint to insert() for map and set can help with performances.\nAh Ok. The insertion happening 'just prior to iterator' was the key point\nI was missing here. Plus got clear from your explanation about the \nperformance\nbit of what's happening. Thanks!\n>\n> Using keys.end() will thus result in the new element being inserted just\n> before the end of the container. As they map is sorted by key, the\n> std::transform call will insert the keys in the set in increasing order.\n> end() is thus the correct hint in that case. begin() would work too, but\n> would result in worse performances, as the insert() function would\n> realize that the hint is not correct, and will look up the correct\n> position. See https://en.cppreference.com/w/cpp/container/map/insert\n> that states\n>\n> Complexity\n>\n> [...]\n>\n> 4-6) Amortized constant if the insertion happens in the position just\n> before the hint, logarithmic in the size of the container otherwise.\n>\n>>> +\t\t       [](const auto &value) { return value.first; });\n>>> +\treturn keys;\n>>> +}\n>>> +\n>>>    template<class InputIt1, class InputIt2>\n>>>    unsigned int set_overlap(InputIt1 first1, InputIt1 last1,\n>>>    \t\t\t InputIt2 first2, InputIt2 last2)\n>>> diff --git a/src/libcamera/utils.cpp b/src/libcamera/utils.cpp\n>>> index d55338fe681a..1eb8970a5bbc 100644\n>>> --- a/src/libcamera/utils.cpp\n>>> +++ b/src/libcamera/utils.cpp\n>>> @@ -127,6 +127,13 @@ std::string dirname(const std::string &path)\n>>>    \treturn path.substr(0, pos + 1);\n>>>    }\n>>>    \n>>> +/**\n>>> + * \\fn std::set<typename T::key_type> map_keys(const T &map)\n>>> + * \\brief Retrieve the keys of a std::map<>\n>>> + * \\param[in] map The map whose keys to retrieve\n>>> + * \\return A std::set<> containing the keys of \\a map\n>>> + */\n>>> +\n>>>    /**\n>>>     * \\fn libcamera::utils::set_overlap(InputIt1 first1, InputIt1 last1,\n>>>     *\t\t\t\t     InputIt2 first2, InputIt2 last2)\n>>> diff --git a/test/utils.cpp b/test/utils.cpp\n>>> index 66b91f1203e1..a9d072030f1c 100644\n>>> --- a/test/utils.cpp\n>>> +++ b/test/utils.cpp\n>>> @@ -6,6 +6,8 @@\n>>>     */\n>>>    \n>>>    #include <iostream>\n>>> +#include <map>\n>>> +#include <set>\n>>>    #include <sstream>\n>>>    #include <string>\n>>>    #include <vector>\n>>> @@ -144,6 +146,25 @@ protected:\n>>>    \t\tif (TestPass != testDirname())\n>>>    \t\t\treturn TestFail;\n>>>    \n>>> +\n>>> +\t\t/* utils::map_keys() test. */\n>>> +\t\tconst std::map<std::string, unsigned int> map{\n>>> +\t\t\t{ \"zero\", 0 },\n>>> +\t\t\t{ \"one\", 1 },\n>>> +\t\t\t{ \"two\", 2 },\n>>> +\t\t};\n>>> +\t\tconst std::set<std::string> expectedKeys{\n>>> +\t\t\t\"zero\",\n>>> +\t\t\t\"one\",\n>>> +\t\t\t\"two\",\n>>> +\t\t};\n>>> +\n>>> +\t\tconst std::set<std::string> keys = utils::map_keys(map);\n>>> +\t\tif (keys != expectedKeys) {\n>>> +\t\t\tcerr << \"utils::map_keys() test failed\" << endl;\n>>> +\t\t\treturn TestFail;\n>>> +\t\t}\n>>> +\n>>>    \t\treturn TestPass;\n>>>    \t}\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 3672CC2E65\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri, 26 Jun 2020 06:14:13 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 8D1F6609C6;\n\tFri, 26 Jun 2020 08:14:12 +0200 (CEST)","from o1.f.az.sendgrid.net (o1.f.az.sendgrid.net [208.117.55.132])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 2883B603B4\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 26 Jun 2020 08:14:09 +0200 (CEST)","by filterdrecv-p3las1-7754f7d4cc-h4ckv with SMTP id\n\tfilterdrecv-p3las1-7754f7d4cc-h4ckv-20-5EF5922F-65\n\t2020-06-26 06:14:08.092071858 +0000 UTC m=+43231.736363303","from mail.uajain.com (unknown)\n\tby ismtpd0002p1hnd1.sendgrid.net (SG) with ESMTP\n\tid P2WV8O4cTbmXrJtrC0_JlQ Fri, 26 Jun 2020 06:14:07.652 +0000 (UTC)"],"Authentication-Results":"lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key;\n\tunprotected) header.d=uajain.com header.i=@uajain.com\n\theader.b=\"s32P4oSm\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=uajain.com;\n\th=subject:references:from:mime-version:in-reply-to:to:cc:content-type:\n\tcontent-transfer-encoding;\n\ts=s1; bh=gyswQwAtR9K5p7wxmoxOaY3ELwVKnlu/qtz6m3J3wZU=;\n\tb=s32P4oSmmvhBulH55/F/D2ZIgxOsx1VdBA7qNIeMPcGV2XAR/NnZVTibrBPAbuSBopPw\n\tQJu6MSRjNHCzBdQ1VWQsA+nDt38B7qf2JDgSTxPBgLd3rv8KyDqHGgPxvUbwXg/kmIyOEc\n\tIuKubf/tB5zJFP/eUdLIt+kBkSn0gu2+E=","References":"<20200625012335.7717-1-laurent.pinchart@ideasonboard.com>\n\t<a6a56e4c-8b6c-1860-f9a1-99e3531d7673@uajain.com>\n\t<20200625142801.GL5865@pendragon.ideasonboard.com>","From":"Umang Jain <email@uajain.com>","Message-ID":"<f42618a0-f3ba-0eb7-ee50-1d9eaf37c952@uajain.com>","Date":"Fri, 26 Jun 2020 06:14:08 +0000 (UTC)","Mime-Version":"1.0","In-Reply-To":"<20200625142801.GL5865@pendragon.ideasonboard.com>","X-SG-EID":"1Q40EQ7YGir8a9gjSIAdTjhngY657NMk9ckeo4dbHZDiOpywc/L3L9rFqlwE4KPcYDswUgqLHty1lirORaEntYkZJgIdeCHX0Dy+CNCg8F1cGh9pJvtEBQKwon9CUrBAe/JAbvbfan2fhe5qMl5EdDzfWBKa/VZaX5bruzhYGKp/V7UTEZoBtCadaSBZQIdCo71eRNnHib1iXrB/EDTv8i1H68HeenrunMtwsI+NfraNpKjtr1c1yLk4reEtnSBkBQa09ISaJuV/AyumXh6AOw==","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Content-Language":"en-US","Subject":"Re: [libcamera-devel] [PATCH] libcamera: utils: Add map_keys()\n\tfunction","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-Transfer-Encoding":"7bit","Content-Type":"text/plain; charset=\"us-ascii\"; Format=\"flowed\"","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]