[libcamera-devel] [PATCH 1/3] libcamera: utils: Add a new make_array() function
Niklas Söderlund
niklas.soderlund at ragnatech.se
Wed Jan 22 16:02:08 CET 2020
Hi Laurent,
Thanks for your work.
On 2020-01-20 19:38:14 +0200, Laurent Pinchart wrote:
> Add a custom implementation of std::make_array() as defined by the
> library fundamentals TS v2 ([1]). The function is useful to initialize
> static arrays without requiring manually specifying the number of
> elements, which could lead to bugs when the specified size is larger
> than the number of initializers.
>
> This is an experimental feature in the C++ standard, and while available
> in <experimental/array> in stdlibc++ from g++-6 onwards, it is not
> provided by libc++.
>
> [1] https://en.cppreference.com/w/cpp/experimental/make_array
>
> Signed-off-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund at ragnatech.se>
> ---
> Documentation/Doxyfile.in | 1 +
> src/libcamera/include/utils.h | 42 +++++++++++++++++++++++++++++++++++
> src/libcamera/utils.cpp | 14 ++++++++++++
> 3 files changed, 57 insertions(+)
>
> diff --git a/Documentation/Doxyfile.in b/Documentation/Doxyfile.in
> index 8e6fbdbb92b6..6de59d407e7b 100644
> --- a/Documentation/Doxyfile.in
> +++ b/Documentation/Doxyfile.in
> @@ -877,6 +877,7 @@ EXCLUDE_SYMBOLS = libcamera::BoundMethodArgs \
> libcamera::BoundMethodPackBase \
> libcamera::BoundMethodStatic \
> libcamera::SignalBase \
> + *::details::* \
> std::*
>
> # The EXAMPLE_PATH tag can be used to specify one or more files or directories
> diff --git a/src/libcamera/include/utils.h b/src/libcamera/include/utils.h
> index e467eb21c518..6e9b9259456a 100644
> --- a/src/libcamera/include/utils.h
> +++ b/src/libcamera/include/utils.h
> @@ -8,12 +8,15 @@
> #define __LIBCAMERA_UTILS_H__
>
> #include <algorithm>
> +#include <array>
> #include <chrono>
> +#include <functional>
> #include <memory>
> #include <ostream>
> #include <string>
> #include <string.h>
> #include <sys/time.h>
> +#include <type_traits>
>
> #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
>
> @@ -108,6 +111,45 @@ inline _hex hex<uint64_t>(uint64_t value, unsigned int width)
>
> size_t strlcpy(char *dst, const char *src, size_t size);
>
> +namespace details {
> +
> +namespace make_array {
> +
> + template<class B>
> + struct negation : std::integral_constant<bool, !bool(B::value)> {};
> +
> + template<class...> struct conjunction : std::true_type {};
> + template<class B1> struct conjunction<B1> : B1 {};
> + template<class B1, class... Bn>
> + struct conjunction<B1, Bn...>
> + : std::conditional_t<bool(B1::value), conjunction<Bn...>, B1> {};
> +
> + template<class> struct is_ref_wrapper : std::false_type {};
> + template<class T> struct is_ref_wrapper<std::reference_wrapper<T>> : std::true_type {};
> +
> + template<class D, class...>
> + struct return_type_helper {
> + using type = D;
> + };
> + template <class... Types>
> + struct return_type_helper<void, Types...> : std::common_type<Types...> {
> + static_assert(conjunction<negation<is_ref_wrapper<std::decay_t<Types>>>...>::value,
> + "Types cannot contain reference_wrappers when D is void");
> + };
> +
> + template<class D, class... Types>
> + using return_type = std::array<typename return_type_helper<D, Types...>::type,
> + sizeof...(Types)>;
> +} /* namespace make_array */
> +
> +} /* namespace details */
> +
> +template<class D = void, class... Types>
> +constexpr details::make_array::return_type<D, Types...> make_array(Types&&... t)
> +{
> + return {std::forward<Types>(t)... };
> +}
> +
> } /* namespace utils */
>
> } /* namespace libcamera */
> diff --git a/src/libcamera/utils.cpp b/src/libcamera/utils.cpp
> index 4beffdab5eb6..b639cfa83d0c 100644
> --- a/src/libcamera/utils.cpp
> +++ b/src/libcamera/utils.cpp
> @@ -199,6 +199,20 @@ size_t strlcpy(char *dst, const char *src, size_t size)
> return strlen(src);
> }
>
> +/**
> + * \fn template<class D, class... Types> libcamera::utils::make_array(Types&&... t)
> + * \brief Create a std::array with automatic deduction of element type and count
> + * \param[in] t The initialization values for the array elements
> + *
> + * This function creates and returns an instance of std::array whose size is
> + * equal to the number of arguments. If the template argument \a D is void, the
> + * array element type is deduced from the elements through
> + * std::common_types_t<Types...>. Otherwise it is set to D. The elements are
> + * initialized from the corresponding arguments.
> + *
> + * \return A std::array initialized from the arguments
> + */
> +
> } /* namespace utils */
>
> } /* namespace libcamera */
> --
> Regards,
>
> Laurent Pinchart
>
> _______________________________________________
> libcamera-devel mailing list
> libcamera-devel at lists.libcamera.org
> https://lists.libcamera.org/listinfo/libcamera-devel
--
Regards,
Niklas Söderlund
More information about the libcamera-devel
mailing list