[{"id":3563,"web_url":"https://patchwork.libcamera.org/comment/3563/","msgid":"<20200122150208.GK1124294@oden.dyn.berto.se>","date":"2020-01-22T15:02:08","subject":"Re: [libcamera-devel] [PATCH 1/3] libcamera: utils: Add a new\n\tmake_array() function","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-01-20 19:38:14 +0200, Laurent Pinchart wrote:\n> Add a custom implementation of std::make_array() as defined by the\n> library fundamentals TS v2 ([1]). The function is useful to initialize\n> static arrays without requiring manually specifying the number of\n> elements, which could lead to bugs when the specified size is larger\n> than the number of initializers.\n> \n> This is an experimental feature in the C++ standard, and while available\n> in <experimental/array> in stdlibc++ from g++-6 onwards, it is not\n> provided by libc++.\n> \n> [1] https://en.cppreference.com/w/cpp/experimental/make_array\n> \n> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n\nReviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>\n\n> ---\n>  Documentation/Doxyfile.in     |  1 +\n>  src/libcamera/include/utils.h | 42 +++++++++++++++++++++++++++++++++++\n>  src/libcamera/utils.cpp       | 14 ++++++++++++\n>  3 files changed, 57 insertions(+)\n> \n> diff --git a/Documentation/Doxyfile.in b/Documentation/Doxyfile.in\n> index 8e6fbdbb92b6..6de59d407e7b 100644\n> --- a/Documentation/Doxyfile.in\n> +++ b/Documentation/Doxyfile.in\n> @@ -877,6 +877,7 @@ EXCLUDE_SYMBOLS        = libcamera::BoundMethodArgs \\\n>                           libcamera::BoundMethodPackBase \\\n>                           libcamera::BoundMethodStatic \\\n>                           libcamera::SignalBase \\\n> +                         *::details::* \\\n>                           std::*\n>  \n>  # The EXAMPLE_PATH tag can be used to specify one or more files or directories\n> diff --git a/src/libcamera/include/utils.h b/src/libcamera/include/utils.h\n> index e467eb21c518..6e9b9259456a 100644\n> --- a/src/libcamera/include/utils.h\n> +++ b/src/libcamera/include/utils.h\n> @@ -8,12 +8,15 @@\n>  #define __LIBCAMERA_UTILS_H__\n>  \n>  #include <algorithm>\n> +#include <array>\n>  #include <chrono>\n> +#include <functional>\n>  #include <memory>\n>  #include <ostream>\n>  #include <string>\n>  #include <string.h>\n>  #include <sys/time.h>\n> +#include <type_traits>\n>  \n>  #define ARRAY_SIZE(a)\t(sizeof(a) / sizeof(a[0]))\n>  \n> @@ -108,6 +111,45 @@ inline _hex hex<uint64_t>(uint64_t value, unsigned int width)\n>  \n>  size_t strlcpy(char *dst, const char *src, size_t size);\n>  \n> +namespace details {\n> +\n> +namespace make_array {\n> +\n> +\ttemplate<class B>\n> +\tstruct negation : std::integral_constant<bool, !bool(B::value)> {};\n> +\n> +\ttemplate<class...> struct conjunction : std::true_type {};\n> +\ttemplate<class B1> struct conjunction<B1> : B1 {};\n> +\ttemplate<class B1, class... Bn>\n> +\tstruct conjunction<B1, Bn...>\n> +\t\t: std::conditional_t<bool(B1::value), conjunction<Bn...>, B1> {};\n> +\n> +\ttemplate<class> struct is_ref_wrapper : std::false_type {};\n> +\ttemplate<class T> struct is_ref_wrapper<std::reference_wrapper<T>> : std::true_type {};\n> +\n> +\ttemplate<class D, class...>\n> +\tstruct return_type_helper {\n> +\t\tusing type = D;\n> +\t};\n> +\ttemplate <class... Types>\n> +\tstruct return_type_helper<void, Types...> : std::common_type<Types...> {\n> +\t\tstatic_assert(conjunction<negation<is_ref_wrapper<std::decay_t<Types>>>...>::value,\n> +\t\t\t      \"Types cannot contain reference_wrappers when D is void\");\n> +\t};\n> +\n> +\ttemplate<class D, class... Types>\n> +\tusing return_type = std::array<typename return_type_helper<D, Types...>::type,\n> +\t\t\t\t       sizeof...(Types)>;\n> +} /* namespace make_array */\n> +\n> +} /* namespace details */\n> +\n> +template<class D = void, class... Types>\n> +constexpr details::make_array::return_type<D, Types...> make_array(Types&&... t)\n> +{\n> +\treturn {std::forward<Types>(t)... };\n> +}\n> +\n>  } /* namespace utils */\n>  \n>  } /* namespace libcamera */\n> diff --git a/src/libcamera/utils.cpp b/src/libcamera/utils.cpp\n> index 4beffdab5eb6..b639cfa83d0c 100644\n> --- a/src/libcamera/utils.cpp\n> +++ b/src/libcamera/utils.cpp\n> @@ -199,6 +199,20 @@ size_t strlcpy(char *dst, const char *src, size_t size)\n>  \treturn strlen(src);\n>  }\n>  \n> +/**\n> + * \\fn template<class D, class... Types> libcamera::utils::make_array(Types&&... t)\n> + * \\brief Create a std::array with automatic deduction of element type and count\n> + * \\param[in] t The initialization values for the array elements\n> + *\n> + * This function creates and returns an instance of std::array whose size is\n> + * equal to the number of arguments. If the template argument \\a D is void, the\n> + * array element type is deduced from the elements through\n> + * std::common_types_t<Types...>. Otherwise it is set to D. The elements are\n> + * initialized from the corresponding arguments.\n> + *\n> + * \\return A std::array initialized from the arguments\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":"<niklas.soderlund@ragnatech.se>","Received":["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 CDE71607F3\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 22 Jan 2020 16:02:09 +0100 (CET)","by mail-lf1-x141.google.com with SMTP id b15so5571093lfc.4\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 22 Jan 2020 07:02:09 -0800 (PST)","from localhost (h-93-159.A463.priv.bahnhof.se. [46.59.93.159])\n\tby smtp.gmail.com with ESMTPSA id\n\t138sm21273215lfa.76.2020.01.22.07.02.08\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tWed, 22 Jan 2020 07:02:08 -0800 (PST)"],"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=+0X7eeWdYcUqTQzi1xbeC9odwvX7Y61xP9hLi+L2/Ag=;\n\tb=TssqAxMWQZNbZCRRH0kI+6udspsP4JqnExVX0S0brCHSsxDS86f2CFhY7ChN8376R6\n\tZDi8lxkEjR0jE8KzUjBKm7boDCEAnjWMNQVgeWhmwh2O6Cc7+QUvbwWzdjiMSfJlHBrw\n\tnDFMnk4CroIbjZjRAo9tey/Gtbr20BZ/Gu5C+Iz/50PLLcTOv37yUCYmolYRM16/469r\n\t2aFtgBxk1jXyn/DIMkmhmndRfnwvt3VKJVjAdGZCDMYB/6TDmGJ/rFQ4SurrxctPQzFk\n\tpn4M7kZu9qa5jH5hEvl1m/pZF2jc/VZMMjDOVCwflVSIJsjinp5mQITGjx4CaAUJzRqS\n\thFpg==","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=+0X7eeWdYcUqTQzi1xbeC9odwvX7Y61xP9hLi+L2/Ag=;\n\tb=Q13R1B716I8qqZ/WVCH67jIkKGA1HVKcMUwm6AVyQZQcG9Bp3hy1Lneg8d00LjAXPj\n\tAL4RN9I2AM4A6BXCcTbvnJ1y9DLhy8gNpbmC0fZkD2/+1cGCJt50rolSQYK57P37yOx8\n\tMYr43boflNoO8XrtJ1mRRGTZl92QmuolBtqMAAk3s8/njD2utN3lOVJr//SBwDMANu9E\n\tHQlRjMYa1l8QeSj98zGOoIziYp3PBIhslTwqOe0CuACysHlPjXO4PEF5Uaqu7XsIlFx7\n\t9oUQO9LTZE1kvoJycyxHxod6uQf4D/Y28WH+EOWAO6pbNSJQZkMLplW+Z96v4NR35cwz\n\t3yHA==","X-Gm-Message-State":"APjAAAW4cTLNDNjAyWsznciFf8tGJTU7tYpNszeSVxShTLfuek/JH9j7\n\t/z+gCxv4iwSRF74Q4Yo5lZUrlA==","X-Google-Smtp-Source":"APXvYqx+iBpbJ2Jc9XcPaksmt0Vj9KLwWuZq27S65BEdrps67dsF8xAPFVj4ubRB0FeWBlkA7hfezQ==","X-Received":"by 2002:a05:6512:78:: with SMTP id\n\ti24mr2052520lfo.10.1579705328996; \n\tWed, 22 Jan 2020 07:02:08 -0800 (PST)","Date":"Wed, 22 Jan 2020 16:02:08 +0100","From":"Niklas =?iso-8859-1?q?S=F6derlund?= <niklas.soderlund@ragnatech.se>","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org","Message-ID":"<20200122150208.GK1124294@oden.dyn.berto.se>","References":"<20200120173816.31829-1-laurent.pinchart@ideasonboard.com>\n\t<20200120173816.31829-2-laurent.pinchart@ideasonboard.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=iso-8859-1","Content-Disposition":"inline","Content-Transfer-Encoding":"8bit","In-Reply-To":"<20200120173816.31829-2-laurent.pinchart@ideasonboard.com>","Subject":"Re: [libcamera-devel] [PATCH 1/3] libcamera: utils: Add a new\n\tmake_array() function","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>","X-List-Received-Date":"Wed, 22 Jan 2020 15:02:10 -0000"}}]