[{"id":14433,"web_url":"https://patchwork.libcamera.org/comment/14433/","msgid":"<X/KtjRurtexrbiFj@pendragon.ideasonboard.com>","date":"2021-01-04T05:54:21","subject":"Re: [libcamera-devel] [PATCH] libcamera: revert C++17 specific code\n\tfor public API","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi Jean-Michel,\n\nThank you for the patch.\n\nOn Thu, Dec 31, 2020 at 04:47:10PM +0100, Jean-Michel Hautbois wrote:\n> Some applications may not be compliant with C++17 (Chromium, as an\n> example). Keep the C++17 features for libcamera internals, and C++14\n> compliance for public API.\n\nThis is (unfortunately :-)) a good point. I was expecting Chromium to\nuse a more recent C++ version, I'm a bit surprised. There seem to be two\nseparate questions here:\n\n- Could we build the libcamera support in Chromium with C++17\n  (specifying the C++ version explicitly in the BUILD.gn file in the\n  corresponding subdirectory, overriding the default C++14 version) ?\n\n- As a more general question, can we expect C++17 support in the not too\n  distant future in code that will use libcamera, or is that an\n  unreasonable expectation and should we stick to c++14 in the public\n  API ?\n\nIf the answer to the first question is no, then we won't have a choice\nfor the second question.\n\nWe could stick to C++14 in the public API as it should not block us (at\nleast for now), this revert isn't that bad. I'm however concerned that\nC++17 features may creep in unnoticed in the API, as we can't test\nbuilding libcamera with C++14, given that the internals depend on C++17.\n\n> This reverts commits 8e42c2feb7ff7c350ffbbf97dd963dfd54e21faa and\n> 6cbdc2859963e17bc897a4022f1d68170477d888.\n\nReverts are usually submitted separately, to make is easier to track\nchanges.\n\n> Signed-off-by: Jean-Michel Hautbois <jeanmichel.hautbois@ideasonboard.com>\n> ---\n>  include/libcamera/bound_method.h |  2 +-\n>  include/libcamera/controls.h     | 24 +++++------\n>  include/libcamera/object.h       |  2 +-\n>  include/libcamera/signal.h       |  4 +-\n>  include/libcamera/span.h         | 70 +++++++++++++++-----------------\n>  5 files changed, 48 insertions(+), 54 deletions(-)\n> \n> diff --git a/include/libcamera/bound_method.h b/include/libcamera/bound_method.h\n> index feac51da..95a95653 100644\n> --- a/include/libcamera/bound_method.h\n> +++ b/include/libcamera/bound_method.h\n> @@ -63,7 +63,7 @@ public:\n>  \t}\n>  \tvirtual ~BoundMethodBase() = default;\n>  \n> -\ttemplate<typename T, typename std::enable_if_t<!std::is_same_v<Object, T>> * = nullptr>\n> +\ttemplate<typename T, typename std::enable_if_t<!std::is_same<Object, T>::value> * = nullptr>\n>  \tbool match(T *obj) { return obj == obj_; }\n>  \tbool match(Object *object) { return object == object_; }\n>  \n> diff --git a/include/libcamera/controls.h b/include/libcamera/controls.h\n> index 3634dc43..3b7f3347 100644\n> --- a/include/libcamera/controls.h\n> +++ b/include/libcamera/controls.h\n> @@ -96,9 +96,9 @@ public:\n>  \tControlValue();\n>  \n>  #ifndef __DOXYGEN__\n> -\ttemplate<typename T, typename std::enable_if_t<!details::is_span_v<T> &&\n> +\ttemplate<typename T, typename std::enable_if_t<!details::is_span<T>::value &&\n>  \t\t\t\t\t\t       details::control_type<T>::value &&\n> -\t\t\t\t\t\t       !std::is_same_v<std::string, std::remove_cv_t<T>>,\n> +\t\t\t\t\t\t       !std::is_same<std::string, std::remove_cv_t<T>>::value,\n>  \t\t\t\t\t\t       std::nullptr_t> = nullptr>\n>  \tControlValue(const T &value)\n>  \t\t: type_(ControlTypeNone), numElements_(0)\n> @@ -107,8 +107,8 @@ public:\n>  \t\t    &value, 1, sizeof(T));\n>  \t}\n>  \n> -\ttemplate<typename T, typename std::enable_if_t<details::is_span_v<T> ||\n> -\t\t\t\t\t\t       std::is_same_v<std::string, std::remove_cv_t<T>>,\n> +\ttemplate<typename T, typename std::enable_if_t<details::is_span<T>::value ||\n> +\t\t\t\t\t\t       std::is_same<std::string, std::remove_cv_t<T>>::value,\n>  \t\t\t\t\t\t       std::nullptr_t> = nullptr>\n>  #else\n>  \ttemplate<typename T>\n> @@ -141,8 +141,8 @@ public:\n>  \t}\n>  \n>  #ifndef __DOXYGEN__\n> -\ttemplate<typename T, typename std::enable_if_t<!details::is_span_v<T> &&\n> -\t\t\t\t\t\t       !std::is_same_v<std::string, std::remove_cv_t<T>>,\n> +\ttemplate<typename T, typename std::enable_if_t<!details::is_span<T>::value &&\n> +\t\t\t\t\t\t       !std::is_same<std::string, std::remove_cv_t<T>>::value,\n>  \t\t\t\t\t\t       std::nullptr_t> = nullptr>\n>  \tT get() const\n>  \t{\n> @@ -152,8 +152,8 @@ public:\n>  \t\treturn *reinterpret_cast<const T *>(data().data());\n>  \t}\n>  \n> -\ttemplate<typename T, typename std::enable_if_t<details::is_span_v<T> ||\n> -\t\t\t\t\t\t       std::is_same_v<std::string, std::remove_cv_t<T>>,\n> +\ttemplate<typename T, typename std::enable_if_t<details::is_span<T>::value ||\n> +\t\t\t\t\t\t       std::is_same<std::string, std::remove_cv_t<T>>::value,\n>  \t\t\t\t\t\t       std::nullptr_t> = nullptr>\n>  #else\n>  \ttemplate<typename T>\n> @@ -169,8 +169,8 @@ public:\n>  \t}\n>  \n>  #ifndef __DOXYGEN__\n> -\ttemplate<typename T, typename std::enable_if_t<!details::is_span_v<T> &&\n> -\t\t\t\t\t\t       !std::is_same_v<std::string, std::remove_cv_t<T>>,\n> +\ttemplate<typename T, typename std::enable_if_t<!details::is_span<T>::value &&\n> +\t\t\t\t\t\t       !std::is_same<std::string, std::remove_cv_t<T>>::value,\n>  \t\t\t\t\t\t       std::nullptr_t> = nullptr>\n>  \tvoid set(const T &value)\n>  \t{\n> @@ -178,8 +178,8 @@ public:\n>  \t\t    reinterpret_cast<const void *>(&value), 1, sizeof(T));\n>  \t}\n>  \n> -\ttemplate<typename T, typename std::enable_if_t<details::is_span_v<T> ||\n> -\t\t\t\t\t\t       std::is_same_v<std::string, std::remove_cv_t<T>>,\n> +\ttemplate<typename T, typename std::enable_if_t<details::is_span<T>::value ||\n> +\t\t\t\t\t\t       std::is_same<std::string, std::remove_cv_t<T>>::value,\n>  \t\t\t\t\t\t       std::nullptr_t> = nullptr>\n>  #else\n>  \ttemplate<typename T>\n> diff --git a/include/libcamera/object.h b/include/libcamera/object.h\n> index 423208db..a1882f05 100644\n> --- a/include/libcamera/object.h\n> +++ b/include/libcamera/object.h\n> @@ -32,7 +32,7 @@ public:\n>  \tvoid postMessage(std::unique_ptr<Message> msg);\n>  \n>  \ttemplate<typename T, typename R, typename... FuncArgs, typename... Args,\n> -\t\t typename std::enable_if_t<std::is_base_of_v<Object, T>> * = nullptr>\n> +\t\t typename std::enable_if_t<std::is_base_of<Object, T>::value> * = nullptr>\n>  \tR invokeMethod(R (T::*func)(FuncArgs...), ConnectionType type,\n>  \t\t       Args... args)\n>  \t{\n> diff --git a/include/libcamera/signal.h b/include/libcamera/signal.h\n> index 46d917d5..5bcd7a77 100644\n> --- a/include/libcamera/signal.h\n> +++ b/include/libcamera/signal.h\n> @@ -44,7 +44,7 @@ public:\n>  \t}\n>  \n>  #ifndef __DOXYGEN__\n> -\ttemplate<typename T, typename R, typename std::enable_if_t<std::is_base_of_v<Object, T>> * = nullptr>\n> +\ttemplate<typename T, typename R, typename std::enable_if_t<std::is_base_of<Object, T>::value> * = nullptr>\n>  \tvoid connect(T *obj, R (T::*func)(Args...),\n>  \t\t     ConnectionType type = ConnectionTypeAuto)\n>  \t{\n> @@ -52,7 +52,7 @@ public:\n>  \t\tSignalBase::connect(new BoundMethodMember<T, void, Args...>(obj, object, func, type));\n>  \t}\n>  \n> -\ttemplate<typename T, typename R, typename std::enable_if_t<!std::is_base_of_v<Object, T>> * = nullptr>\n> +\ttemplate<typename T, typename R, typename std::enable_if_t<!std::is_base_of<Object, T>::value> * = nullptr>\n>  #else\n>  \ttemplate<typename T, typename R>\n>  #endif\n> diff --git a/include/libcamera/span.h b/include/libcamera/span.h\n> index e7ffef12..91e9f974 100644\n> --- a/include/libcamera/span.h\n> +++ b/include/libcamera/span.h\n> @@ -31,9 +31,6 @@ template<typename U, std::size_t N>\n>  struct is_array<std::array<U, N>> : public std::true_type {\n>  };\n>  \n> -template<typename T>\n> -inline constexpr bool is_array_v = is_array<T>::value;\n> -\n>  template<typename U>\n>  struct is_span : public std::false_type {\n>  };\n> @@ -42,9 +39,6 @@ template<typename U, std::size_t Extent>\n>  struct is_span<Span<U, Extent>> : public std::true_type {\n>  };\n>  \n> -template<typename T>\n> -inline constexpr bool is_span_v = is_span<T>::value;\n> -\n>  } /* namespace details */\n>  \n>  namespace utils {\n> @@ -131,8 +125,8 @@ public:\n>  \n>  \ttemplate<std::size_t N>\n>  \tconstexpr Span(element_type (&arr)[N],\n> -\t\t       std::enable_if_t<std::is_convertible_v<std::remove_pointer_t<decltype(utils::data(arr))> (*)[],\n> -\t\t\t\t\t\t\t      element_type (*)[]> &&\n> +\t\t       std::enable_if_t<std::is_convertible<std::remove_pointer_t<decltype(utils::data(arr))> (*)[],\n> +\t\t\t\t\t\t\t    element_type (*)[]>::value &&\n>  \t\t\t\t\tN == Extent,\n>  \t\t\t\t\tstd::nullptr_t> = nullptr) noexcept\n>  \t\t: data_(arr)\n> @@ -141,8 +135,8 @@ public:\n>  \n>  \ttemplate<std::size_t N>\n>  \tconstexpr Span(std::array<value_type, N> &arr,\n> -\t\t       std::enable_if_t<std::is_convertible_v<std::remove_pointer_t<decltype(utils::data(arr))> (*)[],\n> -\t\t\t\t\t\t\t      element_type (*)[]> &&\n> +\t\t       std::enable_if_t<std::is_convertible<std::remove_pointer_t<decltype(utils::data(arr))> (*)[],\n> +\t\t\t\t\t\t\t    element_type (*)[]>::value &&\n>  \t\t\t\t\tN == Extent,\n>  \t\t\t\t\tstd::nullptr_t> = nullptr) noexcept\n>  \t\t: data_(arr.data())\n> @@ -151,8 +145,8 @@ public:\n>  \n>  \ttemplate<std::size_t N>\n>  \tconstexpr Span(const std::array<value_type, N> &arr,\n> -\t\t       std::enable_if_t<std::is_convertible_v<std::remove_pointer_t<decltype(utils::data(arr))> (*)[],\n> -\t\t\t\t\t\t\t      element_type (*)[]> &&\n> +\t\t       std::enable_if_t<std::is_convertible<std::remove_pointer_t<decltype(utils::data(arr))> (*)[],\n> +\t\t\t\t\t\t\t    element_type (*)[]>::value &&\n>  \t\t\t\t\tN == Extent,\n>  \t\t\t\t\tstd::nullptr_t> = nullptr) noexcept\n>  \t\t: data_(arr.data())\n> @@ -161,11 +155,11 @@ public:\n>  \n>  \ttemplate<class Container>\n>  \texplicit constexpr Span(Container &cont,\n> -\t\t\t\tstd::enable_if_t<!details::is_span_v<Container> &&\n> -\t\t\t\t\t\t !details::is_array_v<Container> &&\n> -\t\t\t\t\t\t !std::is_array_v<Container> &&\n> -\t\t\t\t\t\t std::is_convertible_v<std::remove_pointer_t<decltype(utils::data(cont))> (*)[],\n> -\t\t\t\t\t\t\t\t       element_type (*)[]>,\n> +\t\t\t\tstd::enable_if_t<!details::is_span<Container>::value &&\n> +\t\t\t\t\t\t !details::is_array<Container>::value &&\n> +\t\t\t\t\t\t !std::is_array<Container>::value &&\n> +\t\t\t\t\t\t std::is_convertible<std::remove_pointer_t<decltype(utils::data(cont))> (*)[],\n> +\t\t\t\t\t\t\t\t     element_type (*)[]>::value,\n>  \t\t\t\t\t\t std::nullptr_t> = nullptr)\n>  \t\t: data_(utils::data(cont))\n>  \t{\n> @@ -173,11 +167,11 @@ public:\n>  \n>  \ttemplate<class Container>\n>  \texplicit constexpr Span(const Container &cont,\n> -\t\t\t\tstd::enable_if_t<!details::is_span_v<Container> &&\n> -\t\t\t\t\t\t !details::is_array_v<Container> &&\n> -\t\t\t\t\t\t !std::is_array_v<Container> &&\n> -\t\t\t\t\t\t std::is_convertible_v<std::remove_pointer_t<decltype(utils::data(cont))> (*)[],\n> -\t\t\t\t\t\t\t\t       element_type (*)[]>,\n> +\t\t\t\tstd::enable_if_t<!details::is_span<Container>::value &&\n> +\t\t\t\t\t\t !details::is_array<Container>::value &&\n> +\t\t\t\t\t\t !std::is_array<Container>::value &&\n> +\t\t\t\t\t\t std::is_convertible<std::remove_pointer_t<decltype(utils::data(cont))> (*)[],\n> +\t\t\t\t\t\t\t\t     element_type (*)[]>::value,\n>  \t\t\t\t\t\t std::nullptr_t> = nullptr)\n>  \t\t: data_(utils::data(cont))\n>  \t{\n> @@ -186,7 +180,7 @@ public:\n>  \n>  \ttemplate<class U, std::size_t N>\n>  \texplicit constexpr Span(const Span<U, N> &s,\n> -\t\t\t\tstd::enable_if_t<std::is_convertible_v<U (*)[], element_type (*)[]> &&\n> +\t\t\t\tstd::enable_if_t<std::is_convertible<U (*)[], element_type (*)[]>::value &&\n>  \t\t\t\t\t\t N == Extent,\n>  \t\t\t\t\t\t std::nullptr_t> = nullptr) noexcept\n>  \t\t: data_(s.data())\n> @@ -299,8 +293,8 @@ public:\n>  \n>  \ttemplate<std::size_t N>\n>  \tconstexpr Span(element_type (&arr)[N],\n> -\t\t       std::enable_if_t<std::is_convertible_v<std::remove_pointer_t<decltype(utils::data(arr))> (*)[],\n> -\t\t\t\t\t\t\t      element_type (*)[]>,\n> +\t\t       std::enable_if_t<std::is_convertible<std::remove_pointer_t<decltype(utils::data(arr))> (*)[],\n> +\t\t\t\t\t\t\t    element_type (*)[]>::value,\n>  \t\t\t\t\tstd::nullptr_t> = nullptr) noexcept\n>  \t\t: data_(arr), size_(N)\n>  \t{\n> @@ -308,8 +302,8 @@ public:\n>  \n>  \ttemplate<std::size_t N>\n>  \tconstexpr Span(std::array<value_type, N> &arr,\n> -\t\t       std::enable_if_t<std::is_convertible_v<std::remove_pointer_t<decltype(utils::data(arr))> (*)[],\n> -\t\t\t\t\t\t\t      element_type (*)[]>,\n> +\t\t       std::enable_if_t<std::is_convertible<std::remove_pointer_t<decltype(utils::data(arr))> (*)[],\n> +\t\t\t\t\t\t\t    element_type (*)[]>::value,\n>  \t\t\t\t\tstd::nullptr_t> = nullptr) noexcept\n>  \t\t: data_(utils::data(arr)), size_(N)\n>  \t{\n> @@ -323,11 +317,11 @@ public:\n>  \n>  \ttemplate<class Container>\n>  \tconstexpr Span(Container &cont,\n> -\t\t       std::enable_if_t<!details::is_span_v<Container> &&\n> -\t\t\t\t\t!details::is_array_v<Container> &&\n> -\t\t\t\t\t!std::is_array_v<Container> &&\n> -\t\t\t\t\tstd::is_convertible_v<std::remove_pointer_t<decltype(utils::data(cont))> (*)[],\n> -\t\t\t\t\t\t\t      element_type (*)[]>,\n> +\t\t       std::enable_if_t<!details::is_span<Container>::value &&\n> +\t\t\t\t\t!details::is_array<Container>::value &&\n> +\t\t\t\t\t!std::is_array<Container>::value &&\n> +\t\t\t\t\tstd::is_convertible<std::remove_pointer_t<decltype(utils::data(cont))> (*)[],\n> +\t\t\t\t\t\t\t    element_type (*)[]>::value,\n>  \t\t\t\t\tstd::nullptr_t> = nullptr)\n>  \t\t: data_(utils::data(cont)), size_(utils::size(cont))\n>  \t{\n> @@ -335,11 +329,11 @@ public:\n>  \n>  \ttemplate<class Container>\n>  \tconstexpr Span(const Container &cont,\n> -\t\t       std::enable_if_t<!details::is_span_v<Container> &&\n> -\t\t\t\t\t!details::is_array_v<Container> &&\n> -\t\t\t\t\t!std::is_array_v<Container> &&\n> -\t\t\t\t\tstd::is_convertible_v<std::remove_pointer_t<decltype(utils::data(cont))> (*)[],\n> -\t\t\t\t\t\t\t      element_type (*)[]>,\n> +\t\t       std::enable_if_t<!details::is_span<Container>::value &&\n> +\t\t\t\t\t!details::is_array<Container>::value &&\n> +\t\t\t\t\t!std::is_array<Container>::value &&\n> +\t\t\t\t\tstd::is_convertible<std::remove_pointer_t<decltype(utils::data(cont))> (*)[],\n> +\t\t\t\t\t\t\t    element_type (*)[]>::value,\n>  \t\t\t\t\tstd::nullptr_t> = nullptr)\n>  \t\t: data_(utils::data(cont)), size_(utils::size(cont))\n>  \t{\n> @@ -347,7 +341,7 @@ public:\n>  \n>  \ttemplate<class U, std::size_t N>\n>  \tconstexpr Span(const Span<U, N> &s,\n> -\t\t       std::enable_if_t<std::is_convertible_v<U (*)[], element_type (*)[]>,\n> +\t\t       std::enable_if_t<std::is_convertible<U (*)[], element_type (*)[]>::value,\n>  \t\t\t\t\tstd::nullptr_t> = nullptr) noexcept\n>  \t\t: data_(s.data()), size_(s.size())\n>  \t{","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 89035C0F1A\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon,  4 Jan 2021 05:54:36 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id DA14E62000;\n\tMon,  4 Jan 2021 06:54:35 +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 F35A960318\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon,  4 Jan 2021 06:54:33 +0100 (CET)","from pendragon.ideasonboard.com (62-78-145-57.bb.dnainternet.fi\n\t[62.78.145.57])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 2604E2E0;\n\tMon,  4 Jan 2021 06:54:33 +0100 (CET)"],"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=\"BFttwGvr\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1609739673;\n\tbh=/5F/9tACPgo7IZrF+JDUAWc4wx/XYiW8dAVaa64Qld8=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=BFttwGvrmU/cRXFOo+NNHTfxzjh6NyZ1CWQyHiwoxw0f/KFSGR2HZlDzxDCbJkF/I\n\tvKB/8d0AI0dWZPoGx/KozQFJ9a7jsZs7ldoBnat26GCnt7WN9ashxsdyNV2nbuDxcx\n\t67r1KbBWqs+JJn0iDC5OgiAhf4LIMoA/oaV2U78c=","Date":"Mon, 4 Jan 2021 07:54:21 +0200","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Jean-Michel Hautbois <jeanmichel.hautbois@ideasonboard.com>","Message-ID":"<X/KtjRurtexrbiFj@pendragon.ideasonboard.com>","References":"<20201231154711.207852-1-jeanmichel.hautbois@ideasonboard.com>","MIME-Version":"1.0","Content-Disposition":"inline","In-Reply-To":"<20201231154711.207852-1-jeanmichel.hautbois@ideasonboard.com>","Subject":"Re: [libcamera-devel] [PATCH] libcamera: revert C++17 specific code\n\tfor public API","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":14451,"web_url":"https://patchwork.libcamera.org/comment/14451/","msgid":"<CAFixSa3QTZtZr9Yq_qd1vNzCb+9YZYqao8V-gS-uP4zpMYeE+Q@mail.gmail.com>","date":"2021-01-06T09:28:38","subject":"Re: [libcamera-devel] [PATCH] libcamera: revert C++17 specific code\n\tfor public API","submitter":{"id":8,"url":"https://patchwork.libcamera.org/api/people/8/","name":"Shik Chen","email":"shik@google.com"},"content":"Hi all,\n\nOn Mon, Jan 4, 2021 at 1:54 PM Laurent Pinchart\n<laurent.pinchart@ideasonboard.com> wrote:\n>\n> Hi Jean-Michel,\n>\n> Thank you for the patch.\n>\n> On Thu, Dec 31, 2020 at 04:47:10PM +0100, Jean-Michel Hautbois wrote:\n> > Some applications may not be compliant with C++17 (Chromium, as an\n> > example). Keep the C++17 features for libcamera internals, and C++14\n> > compliance for public API.\n>\n> This is (unfortunately :-)) a good point. I was expecting Chromium to\n> use a more recent C++ version, I'm a bit surprised. There seem to be two\n> separate questions here:\n>\n> - Could we build the libcamera support in Chromium with C++17\n>   (specifying the C++ version explicitly in the BUILD.gn file in the\n>   corresponding subdirectory, overriding the default C++14 version) ?\n>\n> - As a more general question, can we expect C++17 support in the not too\n>   distant future in code that will use libcamera, or is that an\n>   unreasonable expectation and should we stick to c++14 in the public\n>   API ?\n\nSome information for Chromium specifically:\n\nAccording to https://chromium-cpp.appspot.com/:\n> C++17: Not yet supported in Chromium, unlikely before mid-2021\n\nQuote from the tracking bug https://crbug.com/752720#c147:\n> the NaCl toolchain's lack of C++17 support is the sole significant blocker.\n\nThe EOL of NaCl toolchain was punted to June 2022 (it was June 2021):\nhttps://blog.chromium.org/2020/08/changes-to-chrome-app-support-timeline.html\n\n>\n>\n> If the answer to the first question is no, then we won't have a choice\n> for the second question.\n>\n> We could stick to C++14 in the public API as it should not block us (at\n> least for now), this revert isn't that bad. I'm however concerned that\n> C++17 features may creep in unnoticed in the API, as we can't test\n> building libcamera with C++14, given that the internals depend on C++17.\n>\n> > This reverts commits 8e42c2feb7ff7c350ffbbf97dd963dfd54e21faa and\n> > 6cbdc2859963e17bc897a4022f1d68170477d888.\n>\n> Reverts are usually submitted separately, to make is easier to track\n> changes.\n>\n> > Signed-off-by: Jean-Michel Hautbois <jeanmichel.hautbois@ideasonboard.com>\n> > ---\n> >  include/libcamera/bound_method.h |  2 +-\n> >  include/libcamera/controls.h     | 24 +++++------\n> >  include/libcamera/object.h       |  2 +-\n> >  include/libcamera/signal.h       |  4 +-\n> >  include/libcamera/span.h         | 70 +++++++++++++++-----------------\n> >  5 files changed, 48 insertions(+), 54 deletions(-)\n> >\n> > diff --git a/include/libcamera/bound_method.h b/include/libcamera/bound_method.h\n> > index feac51da..95a95653 100644\n> > --- a/include/libcamera/bound_method.h\n> > +++ b/include/libcamera/bound_method.h\n> > @@ -63,7 +63,7 @@ public:\n> >       }\n> >       virtual ~BoundMethodBase() = default;\n> >\n> > -     template<typename T, typename std::enable_if_t<!std::is_same_v<Object, T>> * = nullptr>\n> > +     template<typename T, typename std::enable_if_t<!std::is_same<Object, T>::value> * = nullptr>\n> >       bool match(T *obj) { return obj == obj_; }\n> >       bool match(Object *object) { return object == object_; }\n> >\n> > diff --git a/include/libcamera/controls.h b/include/libcamera/controls.h\n> > index 3634dc43..3b7f3347 100644\n> > --- a/include/libcamera/controls.h\n> > +++ b/include/libcamera/controls.h\n> > @@ -96,9 +96,9 @@ public:\n> >       ControlValue();\n> >\n> >  #ifndef __DOXYGEN__\n> > -     template<typename T, typename std::enable_if_t<!details::is_span_v<T> &&\n> > +     template<typename T, typename std::enable_if_t<!details::is_span<T>::value &&\n> >                                                      details::control_type<T>::value &&\n> > -                                                    !std::is_same_v<std::string, std::remove_cv_t<T>>,\n> > +                                                    !std::is_same<std::string, std::remove_cv_t<T>>::value,\n> >                                                      std::nullptr_t> = nullptr>\n> >       ControlValue(const T &value)\n> >               : type_(ControlTypeNone), numElements_(0)\n> > @@ -107,8 +107,8 @@ public:\n> >                   &value, 1, sizeof(T));\n> >       }\n> >\n> > -     template<typename T, typename std::enable_if_t<details::is_span_v<T> ||\n> > -                                                    std::is_same_v<std::string, std::remove_cv_t<T>>,\n> > +     template<typename T, typename std::enable_if_t<details::is_span<T>::value ||\n> > +                                                    std::is_same<std::string, std::remove_cv_t<T>>::value,\n> >                                                      std::nullptr_t> = nullptr>\n> >  #else\n> >       template<typename T>\n> > @@ -141,8 +141,8 @@ public:\n> >       }\n> >\n> >  #ifndef __DOXYGEN__\n> > -     template<typename T, typename std::enable_if_t<!details::is_span_v<T> &&\n> > -                                                    !std::is_same_v<std::string, std::remove_cv_t<T>>,\n> > +     template<typename T, typename std::enable_if_t<!details::is_span<T>::value &&\n> > +                                                    !std::is_same<std::string, std::remove_cv_t<T>>::value,\n> >                                                      std::nullptr_t> = nullptr>\n> >       T get() const\n> >       {\n> > @@ -152,8 +152,8 @@ public:\n> >               return *reinterpret_cast<const T *>(data().data());\n> >       }\n> >\n> > -     template<typename T, typename std::enable_if_t<details::is_span_v<T> ||\n> > -                                                    std::is_same_v<std::string, std::remove_cv_t<T>>,\n> > +     template<typename T, typename std::enable_if_t<details::is_span<T>::value ||\n> > +                                                    std::is_same<std::string, std::remove_cv_t<T>>::value,\n> >                                                      std::nullptr_t> = nullptr>\n> >  #else\n> >       template<typename T>\n> > @@ -169,8 +169,8 @@ public:\n> >       }\n> >\n> >  #ifndef __DOXYGEN__\n> > -     template<typename T, typename std::enable_if_t<!details::is_span_v<T> &&\n> > -                                                    !std::is_same_v<std::string, std::remove_cv_t<T>>,\n> > +     template<typename T, typename std::enable_if_t<!details::is_span<T>::value &&\n> > +                                                    !std::is_same<std::string, std::remove_cv_t<T>>::value,\n> >                                                      std::nullptr_t> = nullptr>\n> >       void set(const T &value)\n> >       {\n> > @@ -178,8 +178,8 @@ public:\n> >                   reinterpret_cast<const void *>(&value), 1, sizeof(T));\n> >       }\n> >\n> > -     template<typename T, typename std::enable_if_t<details::is_span_v<T> ||\n> > -                                                    std::is_same_v<std::string, std::remove_cv_t<T>>,\n> > +     template<typename T, typename std::enable_if_t<details::is_span<T>::value ||\n> > +                                                    std::is_same<std::string, std::remove_cv_t<T>>::value,\n> >                                                      std::nullptr_t> = nullptr>\n> >  #else\n> >       template<typename T>\n> > diff --git a/include/libcamera/object.h b/include/libcamera/object.h\n> > index 423208db..a1882f05 100644\n> > --- a/include/libcamera/object.h\n> > +++ b/include/libcamera/object.h\n> > @@ -32,7 +32,7 @@ public:\n> >       void postMessage(std::unique_ptr<Message> msg);\n> >\n> >       template<typename T, typename R, typename... FuncArgs, typename... Args,\n> > -              typename std::enable_if_t<std::is_base_of_v<Object, T>> * = nullptr>\n> > +              typename std::enable_if_t<std::is_base_of<Object, T>::value> * = nullptr>\n> >       R invokeMethod(R (T::*func)(FuncArgs...), ConnectionType type,\n> >                      Args... args)\n> >       {\n> > diff --git a/include/libcamera/signal.h b/include/libcamera/signal.h\n> > index 46d917d5..5bcd7a77 100644\n> > --- a/include/libcamera/signal.h\n> > +++ b/include/libcamera/signal.h\n> > @@ -44,7 +44,7 @@ public:\n> >       }\n> >\n> >  #ifndef __DOXYGEN__\n> > -     template<typename T, typename R, typename std::enable_if_t<std::is_base_of_v<Object, T>> * = nullptr>\n> > +     template<typename T, typename R, typename std::enable_if_t<std::is_base_of<Object, T>::value> * = nullptr>\n> >       void connect(T *obj, R (T::*func)(Args...),\n> >                    ConnectionType type = ConnectionTypeAuto)\n> >       {\n> > @@ -52,7 +52,7 @@ public:\n> >               SignalBase::connect(new BoundMethodMember<T, void, Args...>(obj, object, func, type));\n> >       }\n> >\n> > -     template<typename T, typename R, typename std::enable_if_t<!std::is_base_of_v<Object, T>> * = nullptr>\n> > +     template<typename T, typename R, typename std::enable_if_t<!std::is_base_of<Object, T>::value> * = nullptr>\n> >  #else\n> >       template<typename T, typename R>\n> >  #endif\n> > diff --git a/include/libcamera/span.h b/include/libcamera/span.h\n> > index e7ffef12..91e9f974 100644\n> > --- a/include/libcamera/span.h\n> > +++ b/include/libcamera/span.h\n> > @@ -31,9 +31,6 @@ template<typename U, std::size_t N>\n> >  struct is_array<std::array<U, N>> : public std::true_type {\n> >  };\n> >\n> > -template<typename T>\n> > -inline constexpr bool is_array_v = is_array<T>::value;\n> > -\n> >  template<typename U>\n> >  struct is_span : public std::false_type {\n> >  };\n> > @@ -42,9 +39,6 @@ template<typename U, std::size_t Extent>\n> >  struct is_span<Span<U, Extent>> : public std::true_type {\n> >  };\n> >\n> > -template<typename T>\n> > -inline constexpr bool is_span_v = is_span<T>::value;\n> > -\n> >  } /* namespace details */\n> >\n> >  namespace utils {\n> > @@ -131,8 +125,8 @@ public:\n> >\n> >       template<std::size_t N>\n> >       constexpr Span(element_type (&arr)[N],\n> > -                    std::enable_if_t<std::is_convertible_v<std::remove_pointer_t<decltype(utils::data(arr))> (*)[],\n> > -                                                           element_type (*)[]> &&\n> > +                    std::enable_if_t<std::is_convertible<std::remove_pointer_t<decltype(utils::data(arr))> (*)[],\n> > +                                                         element_type (*)[]>::value &&\n> >                                       N == Extent,\n> >                                       std::nullptr_t> = nullptr) noexcept\n> >               : data_(arr)\n> > @@ -141,8 +135,8 @@ public:\n> >\n> >       template<std::size_t N>\n> >       constexpr Span(std::array<value_type, N> &arr,\n> > -                    std::enable_if_t<std::is_convertible_v<std::remove_pointer_t<decltype(utils::data(arr))> (*)[],\n> > -                                                           element_type (*)[]> &&\n> > +                    std::enable_if_t<std::is_convertible<std::remove_pointer_t<decltype(utils::data(arr))> (*)[],\n> > +                                                         element_type (*)[]>::value &&\n> >                                       N == Extent,\n> >                                       std::nullptr_t> = nullptr) noexcept\n> >               : data_(arr.data())\n> > @@ -151,8 +145,8 @@ public:\n> >\n> >       template<std::size_t N>\n> >       constexpr Span(const std::array<value_type, N> &arr,\n> > -                    std::enable_if_t<std::is_convertible_v<std::remove_pointer_t<decltype(utils::data(arr))> (*)[],\n> > -                                                           element_type (*)[]> &&\n> > +                    std::enable_if_t<std::is_convertible<std::remove_pointer_t<decltype(utils::data(arr))> (*)[],\n> > +                                                         element_type (*)[]>::value &&\n> >                                       N == Extent,\n> >                                       std::nullptr_t> = nullptr) noexcept\n> >               : data_(arr.data())\n> > @@ -161,11 +155,11 @@ public:\n> >\n> >       template<class Container>\n> >       explicit constexpr Span(Container &cont,\n> > -                             std::enable_if_t<!details::is_span_v<Container> &&\n> > -                                              !details::is_array_v<Container> &&\n> > -                                              !std::is_array_v<Container> &&\n> > -                                              std::is_convertible_v<std::remove_pointer_t<decltype(utils::data(cont))> (*)[],\n> > -                                                                    element_type (*)[]>,\n> > +                             std::enable_if_t<!details::is_span<Container>::value &&\n> > +                                              !details::is_array<Container>::value &&\n> > +                                              !std::is_array<Container>::value &&\n> > +                                              std::is_convertible<std::remove_pointer_t<decltype(utils::data(cont))> (*)[],\n> > +                                                                  element_type (*)[]>::value,\n> >                                                std::nullptr_t> = nullptr)\n> >               : data_(utils::data(cont))\n> >       {\n> > @@ -173,11 +167,11 @@ public:\n> >\n> >       template<class Container>\n> >       explicit constexpr Span(const Container &cont,\n> > -                             std::enable_if_t<!details::is_span_v<Container> &&\n> > -                                              !details::is_array_v<Container> &&\n> > -                                              !std::is_array_v<Container> &&\n> > -                                              std::is_convertible_v<std::remove_pointer_t<decltype(utils::data(cont))> (*)[],\n> > -                                                                    element_type (*)[]>,\n> > +                             std::enable_if_t<!details::is_span<Container>::value &&\n> > +                                              !details::is_array<Container>::value &&\n> > +                                              !std::is_array<Container>::value &&\n> > +                                              std::is_convertible<std::remove_pointer_t<decltype(utils::data(cont))> (*)[],\n> > +                                                                  element_type (*)[]>::value,\n> >                                                std::nullptr_t> = nullptr)\n> >               : data_(utils::data(cont))\n> >       {\n> > @@ -186,7 +180,7 @@ public:\n> >\n> >       template<class U, std::size_t N>\n> >       explicit constexpr Span(const Span<U, N> &s,\n> > -                             std::enable_if_t<std::is_convertible_v<U (*)[], element_type (*)[]> &&\n> > +                             std::enable_if_t<std::is_convertible<U (*)[], element_type (*)[]>::value &&\n> >                                                N == Extent,\n> >                                                std::nullptr_t> = nullptr) noexcept\n> >               : data_(s.data())\n> > @@ -299,8 +293,8 @@ public:\n> >\n> >       template<std::size_t N>\n> >       constexpr Span(element_type (&arr)[N],\n> > -                    std::enable_if_t<std::is_convertible_v<std::remove_pointer_t<decltype(utils::data(arr))> (*)[],\n> > -                                                           element_type (*)[]>,\n> > +                    std::enable_if_t<std::is_convertible<std::remove_pointer_t<decltype(utils::data(arr))> (*)[],\n> > +                                                         element_type (*)[]>::value,\n> >                                       std::nullptr_t> = nullptr) noexcept\n> >               : data_(arr), size_(N)\n> >       {\n> > @@ -308,8 +302,8 @@ public:\n> >\n> >       template<std::size_t N>\n> >       constexpr Span(std::array<value_type, N> &arr,\n> > -                    std::enable_if_t<std::is_convertible_v<std::remove_pointer_t<decltype(utils::data(arr))> (*)[],\n> > -                                                           element_type (*)[]>,\n> > +                    std::enable_if_t<std::is_convertible<std::remove_pointer_t<decltype(utils::data(arr))> (*)[],\n> > +                                                         element_type (*)[]>::value,\n> >                                       std::nullptr_t> = nullptr) noexcept\n> >               : data_(utils::data(arr)), size_(N)\n> >       {\n> > @@ -323,11 +317,11 @@ public:\n> >\n> >       template<class Container>\n> >       constexpr Span(Container &cont,\n> > -                    std::enable_if_t<!details::is_span_v<Container> &&\n> > -                                     !details::is_array_v<Container> &&\n> > -                                     !std::is_array_v<Container> &&\n> > -                                     std::is_convertible_v<std::remove_pointer_t<decltype(utils::data(cont))> (*)[],\n> > -                                                           element_type (*)[]>,\n> > +                    std::enable_if_t<!details::is_span<Container>::value &&\n> > +                                     !details::is_array<Container>::value &&\n> > +                                     !std::is_array<Container>::value &&\n> > +                                     std::is_convertible<std::remove_pointer_t<decltype(utils::data(cont))> (*)[],\n> > +                                                         element_type (*)[]>::value,\n> >                                       std::nullptr_t> = nullptr)\n> >               : data_(utils::data(cont)), size_(utils::size(cont))\n> >       {\n> > @@ -335,11 +329,11 @@ public:\n> >\n> >       template<class Container>\n> >       constexpr Span(const Container &cont,\n> > -                    std::enable_if_t<!details::is_span_v<Container> &&\n> > -                                     !details::is_array_v<Container> &&\n> > -                                     !std::is_array_v<Container> &&\n> > -                                     std::is_convertible_v<std::remove_pointer_t<decltype(utils::data(cont))> (*)[],\n> > -                                                           element_type (*)[]>,\n> > +                    std::enable_if_t<!details::is_span<Container>::value &&\n> > +                                     !details::is_array<Container>::value &&\n> > +                                     !std::is_array<Container>::value &&\n> > +                                     std::is_convertible<std::remove_pointer_t<decltype(utils::data(cont))> (*)[],\n> > +                                                         element_type (*)[]>::value,\n> >                                       std::nullptr_t> = nullptr)\n> >               : data_(utils::data(cont)), size_(utils::size(cont))\n> >       {\n> > @@ -347,7 +341,7 @@ public:\n> >\n> >       template<class U, std::size_t N>\n> >       constexpr Span(const Span<U, N> &s,\n> > -                    std::enable_if_t<std::is_convertible_v<U (*)[], element_type (*)[]>,\n> > +                    std::enable_if_t<std::is_convertible<U (*)[], element_type (*)[]>::value,\n> >                                       std::nullptr_t> = nullptr) noexcept\n> >               : data_(s.data()), size_(s.size())\n> >       {\n>\n> --\n> Regards,\n>\n> Laurent Pinchart\n> _______________________________________________\n> libcamera-devel mailing list\n> libcamera-devel@lists.libcamera.org\n> https://lists.libcamera.org/listinfo/libcamera-devel\n\n- shik","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 B7D2BC0F1C\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed,  6 Jan 2021 09:29:08 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 163E76278D;\n\tWed,  6 Jan 2021 10:29:08 +0100 (CET)","from mail-qt1-x829.google.com (mail-qt1-x829.google.com\n\t[IPv6:2607:f8b0:4864:20::829])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 596A16010B\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed,  6 Jan 2021 10:29:06 +0100 (CET)","by mail-qt1-x829.google.com with SMTP id y15so1668825qtv.5\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 06 Jan 2021 01:29:06 -0800 (PST)"],"Authentication-Results":"lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key;\n\tunprotected) header.d=google.com header.i=@google.com\n\theader.b=\"NCfO1ppX\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com;\n\ts=20161025; \n\th=mime-version:references:in-reply-to:from:date:message-id:subject:to\n\t:cc; bh=KrpbCq6N7Bn5WGNZBwBMana8xkc4eqfhRmlHM4pzTNs=;\n\tb=NCfO1ppXy5nlNDP0kRSkqLV/6zoBwwt9yC7QNRBxZB2AMXeDSD1AZpvU8JPPHz2Fb1\n\tdrJltTlfq2lFZ6BJYPuKL4/ckoffvj82MEk303KYHzkB6UyU42iKCYpmDKm3olTdebaJ\n\t3pX49VPxrlQ/k4Du/QJAita2mm9MrdF2MKyYdqlGIV0ttvsNjwfJoXmp9HcyWlu+GY/W\n\tScHC/Sl+zl3sHUxzDLZnUX3JjSxgouJKG7PCj65yZg97UOuJc6xjBit5TFeQecZcBFPH\n\tUETcS0dOgi3kiLvPDFiBGaPoOe32omTB+T7CKhhRrBesDvpqwjrKgCq+X4iQK56QPZaD\n\tYolw==","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20161025;\n\th=x-gm-message-state:mime-version:references:in-reply-to:from:date\n\t:message-id:subject:to:cc;\n\tbh=KrpbCq6N7Bn5WGNZBwBMana8xkc4eqfhRmlHM4pzTNs=;\n\tb=dRcW4PX4yG8e2R2NirUQzoXJu0kLwdkEb6XiwtjN9t8o3Qzyuw4t2su/OfyPlzYLyn\n\tVc8G3b0rpDSD9rHGZkMovOyb7lUQrLtyLtnGVWTyj5tQV9wDGhhSlR7cLo5PfUjEr5R2\n\tSXyLp1OYTKhTjw6vJEWNB6JBt9dQE8MzLd4C41Ijzw1WczU318iyxbXGLnec8UZn6nC+\n\t1+V3dm/WO96ak+upJpmwclHC36sD0HgKM+wMpSDbNoWGmOlKZrLjzydkorqYhpedenlv\n\t+iY5oV3on6a8/UzzRjg8t4LXVTA2jsPoiv62lxHEt3WjyuUR1Y85f6o3FAZqg70xG/Pg\n\ttQlA==","X-Gm-Message-State":"AOAM5322rVr3C0SQfLWiNJp3Dww9b+V3Wv73GimzfFqHOY/BwqzHWc/R\n\tAxf3DVDnOrmKdbMT2nA3/iLHspAljuyAG1ma9r0Oig==","X-Google-Smtp-Source":"ABdhPJyF6vFux/eamA5jwZWpeIW4FXmkNH3jzq8r1VO0vYdtdDtYhxkeWREV6mvSKo6UvCrBWiOZCoOe62z+dPTeGkY=","X-Received":"by 2002:ac8:7c8e:: with SMTP id\n\ty14mr3099473qtv.161.1609925344549; \n\tWed, 06 Jan 2021 01:29:04 -0800 (PST)","MIME-Version":"1.0","References":"<20201231154711.207852-1-jeanmichel.hautbois@ideasonboard.com>\n\t<X/KtjRurtexrbiFj@pendragon.ideasonboard.com>","In-Reply-To":"<X/KtjRurtexrbiFj@pendragon.ideasonboard.com>","From":"Shik Chen <shik@google.com>","Date":"Wed, 6 Jan 2021 17:28:38 +0800","Message-ID":"<CAFixSa3QTZtZr9Yq_qd1vNzCb+9YZYqao8V-gS-uP4zpMYeE+Q@mail.gmail.com>","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Subject":"Re: [libcamera-devel] [PATCH] libcamera: revert C++17 specific code\n\tfor public API","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":14456,"web_url":"https://patchwork.libcamera.org/comment/14456/","msgid":"<X/WjRWymQG72swzW@pendragon.ideasonboard.com>","date":"2021-01-06T11:47:17","subject":"Re: [libcamera-devel] [PATCH] libcamera: revert C++17 specific code\n\tfor public API","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi Shik,\n\nOn Wed, Jan 06, 2021 at 05:28:38PM +0800, Shik Chen wrote:\n> On Mon, Jan 4, 2021 at 1:54 PM Laurent Pinchart wrote:\n> > On Thu, Dec 31, 2020 at 04:47:10PM +0100, Jean-Michel Hautbois wrote:\n> > > Some applications may not be compliant with C++17 (Chromium, as an\n> > > example). Keep the C++17 features for libcamera internals, and C++14\n> > > compliance for public API.\n> >\n> > This is (unfortunately :-)) a good point. I was expecting Chromium to\n> > use a more recent C++ version, I'm a bit surprised. There seem to be two\n> > separate questions here:\n> >\n> > - Could we build the libcamera support in Chromium with C++17\n> >   (specifying the C++ version explicitly in the BUILD.gn file in the\n> >   corresponding subdirectory, overriding the default C++14 version) ?\n> >\n> > - As a more general question, can we expect C++17 support in the not too\n> >   distant future in code that will use libcamera, or is that an\n> >   unreasonable expectation and should we stick to c++14 in the public\n> >   API ?\n> \n> Some information for Chromium specifically:\n> \n> According to https://chromium-cpp.appspot.com/:\n> > C++17: Not yet supported in Chromium, unlikely before mid-2021\n\nWe found the same information :-)\n\nFor Chromium specifically, I wonder if the libcamera integration code\ncould be compiled with C++-17, with the rest of the code base using\nC++14.\n\n> Quote from the tracking bug https://crbug.com/752720#c147:\n> > the NaCl toolchain's lack of C++17 support is the sole significant blocker.\n> \n> The EOL of NaCl toolchain was punted to June 2022 (it was June 2021):\n> https://blog.chromium.org/2020/08/changes-to-chrome-app-support-timeline.html\n>\n> > If the answer to the first question is no, then we won't have a choice\n> > for the second question.\n> >\n> > We could stick to C++14 in the public API as it should not block us (at\n> > least for now), this revert isn't that bad. I'm however concerned that\n> > C++17 features may creep in unnoticed in the API, as we can't test\n> > building libcamera with C++14, given that the internals depend on C++17.\n> >\n> > > This reverts commits 8e42c2feb7ff7c350ffbbf97dd963dfd54e21faa and\n> > > 6cbdc2859963e17bc897a4022f1d68170477d888.\n> >\n> > Reverts are usually submitted separately, to make is easier to track\n> > changes.\n> >\n> > > Signed-off-by: Jean-Michel Hautbois <jeanmichel.hautbois@ideasonboard.com>\n> > > ---\n> > >  include/libcamera/bound_method.h |  2 +-\n> > >  include/libcamera/controls.h     | 24 +++++------\n> > >  include/libcamera/object.h       |  2 +-\n> > >  include/libcamera/signal.h       |  4 +-\n> > >  include/libcamera/span.h         | 70 +++++++++++++++-----------------\n> > >  5 files changed, 48 insertions(+), 54 deletions(-)\n> > >\n> > > diff --git a/include/libcamera/bound_method.h b/include/libcamera/bound_method.h\n> > > index feac51da..95a95653 100644\n> > > --- a/include/libcamera/bound_method.h\n> > > +++ b/include/libcamera/bound_method.h\n> > > @@ -63,7 +63,7 @@ public:\n> > >       }\n> > >       virtual ~BoundMethodBase() = default;\n> > >\n> > > -     template<typename T, typename std::enable_if_t<!std::is_same_v<Object, T>> * = nullptr>\n> > > +     template<typename T, typename std::enable_if_t<!std::is_same<Object, T>::value> * = nullptr>\n> > >       bool match(T *obj) { return obj == obj_; }\n> > >       bool match(Object *object) { return object == object_; }\n> > >\n> > > diff --git a/include/libcamera/controls.h b/include/libcamera/controls.h\n> > > index 3634dc43..3b7f3347 100644\n> > > --- a/include/libcamera/controls.h\n> > > +++ b/include/libcamera/controls.h\n> > > @@ -96,9 +96,9 @@ public:\n> > >       ControlValue();\n> > >\n> > >  #ifndef __DOXYGEN__\n> > > -     template<typename T, typename std::enable_if_t<!details::is_span_v<T> &&\n> > > +     template<typename T, typename std::enable_if_t<!details::is_span<T>::value &&\n> > >                                                      details::control_type<T>::value &&\n> > > -                                                    !std::is_same_v<std::string, std::remove_cv_t<T>>,\n> > > +                                                    !std::is_same<std::string, std::remove_cv_t<T>>::value,\n> > >                                                      std::nullptr_t> = nullptr>\n> > >       ControlValue(const T &value)\n> > >               : type_(ControlTypeNone), numElements_(0)\n> > > @@ -107,8 +107,8 @@ public:\n> > >                   &value, 1, sizeof(T));\n> > >       }\n> > >\n> > > -     template<typename T, typename std::enable_if_t<details::is_span_v<T> ||\n> > > -                                                    std::is_same_v<std::string, std::remove_cv_t<T>>,\n> > > +     template<typename T, typename std::enable_if_t<details::is_span<T>::value ||\n> > > +                                                    std::is_same<std::string, std::remove_cv_t<T>>::value,\n> > >                                                      std::nullptr_t> = nullptr>\n> > >  #else\n> > >       template<typename T>\n> > > @@ -141,8 +141,8 @@ public:\n> > >       }\n> > >\n> > >  #ifndef __DOXYGEN__\n> > > -     template<typename T, typename std::enable_if_t<!details::is_span_v<T> &&\n> > > -                                                    !std::is_same_v<std::string, std::remove_cv_t<T>>,\n> > > +     template<typename T, typename std::enable_if_t<!details::is_span<T>::value &&\n> > > +                                                    !std::is_same<std::string, std::remove_cv_t<T>>::value,\n> > >                                                      std::nullptr_t> = nullptr>\n> > >       T get() const\n> > >       {\n> > > @@ -152,8 +152,8 @@ public:\n> > >               return *reinterpret_cast<const T *>(data().data());\n> > >       }\n> > >\n> > > -     template<typename T, typename std::enable_if_t<details::is_span_v<T> ||\n> > > -                                                    std::is_same_v<std::string, std::remove_cv_t<T>>,\n> > > +     template<typename T, typename std::enable_if_t<details::is_span<T>::value ||\n> > > +                                                    std::is_same<std::string, std::remove_cv_t<T>>::value,\n> > >                                                      std::nullptr_t> = nullptr>\n> > >  #else\n> > >       template<typename T>\n> > > @@ -169,8 +169,8 @@ public:\n> > >       }\n> > >\n> > >  #ifndef __DOXYGEN__\n> > > -     template<typename T, typename std::enable_if_t<!details::is_span_v<T> &&\n> > > -                                                    !std::is_same_v<std::string, std::remove_cv_t<T>>,\n> > > +     template<typename T, typename std::enable_if_t<!details::is_span<T>::value &&\n> > > +                                                    !std::is_same<std::string, std::remove_cv_t<T>>::value,\n> > >                                                      std::nullptr_t> = nullptr>\n> > >       void set(const T &value)\n> > >       {\n> > > @@ -178,8 +178,8 @@ public:\n> > >                   reinterpret_cast<const void *>(&value), 1, sizeof(T));\n> > >       }\n> > >\n> > > -     template<typename T, typename std::enable_if_t<details::is_span_v<T> ||\n> > > -                                                    std::is_same_v<std::string, std::remove_cv_t<T>>,\n> > > +     template<typename T, typename std::enable_if_t<details::is_span<T>::value ||\n> > > +                                                    std::is_same<std::string, std::remove_cv_t<T>>::value,\n> > >                                                      std::nullptr_t> = nullptr>\n> > >  #else\n> > >       template<typename T>\n> > > diff --git a/include/libcamera/object.h b/include/libcamera/object.h\n> > > index 423208db..a1882f05 100644\n> > > --- a/include/libcamera/object.h\n> > > +++ b/include/libcamera/object.h\n> > > @@ -32,7 +32,7 @@ public:\n> > >       void postMessage(std::unique_ptr<Message> msg);\n> > >\n> > >       template<typename T, typename R, typename... FuncArgs, typename... Args,\n> > > -              typename std::enable_if_t<std::is_base_of_v<Object, T>> * = nullptr>\n> > > +              typename std::enable_if_t<std::is_base_of<Object, T>::value> * = nullptr>\n> > >       R invokeMethod(R (T::*func)(FuncArgs...), ConnectionType type,\n> > >                      Args... args)\n> > >       {\n> > > diff --git a/include/libcamera/signal.h b/include/libcamera/signal.h\n> > > index 46d917d5..5bcd7a77 100644\n> > > --- a/include/libcamera/signal.h\n> > > +++ b/include/libcamera/signal.h\n> > > @@ -44,7 +44,7 @@ public:\n> > >       }\n> > >\n> > >  #ifndef __DOXYGEN__\n> > > -     template<typename T, typename R, typename std::enable_if_t<std::is_base_of_v<Object, T>> * = nullptr>\n> > > +     template<typename T, typename R, typename std::enable_if_t<std::is_base_of<Object, T>::value> * = nullptr>\n> > >       void connect(T *obj, R (T::*func)(Args...),\n> > >                    ConnectionType type = ConnectionTypeAuto)\n> > >       {\n> > > @@ -52,7 +52,7 @@ public:\n> > >               SignalBase::connect(new BoundMethodMember<T, void, Args...>(obj, object, func, type));\n> > >       }\n> > >\n> > > -     template<typename T, typename R, typename std::enable_if_t<!std::is_base_of_v<Object, T>> * = nullptr>\n> > > +     template<typename T, typename R, typename std::enable_if_t<!std::is_base_of<Object, T>::value> * = nullptr>\n> > >  #else\n> > >       template<typename T, typename R>\n> > >  #endif\n> > > diff --git a/include/libcamera/span.h b/include/libcamera/span.h\n> > > index e7ffef12..91e9f974 100644\n> > > --- a/include/libcamera/span.h\n> > > +++ b/include/libcamera/span.h\n> > > @@ -31,9 +31,6 @@ template<typename U, std::size_t N>\n> > >  struct is_array<std::array<U, N>> : public std::true_type {\n> > >  };\n> > >\n> > > -template<typename T>\n> > > -inline constexpr bool is_array_v = is_array<T>::value;\n> > > -\n> > >  template<typename U>\n> > >  struct is_span : public std::false_type {\n> > >  };\n> > > @@ -42,9 +39,6 @@ template<typename U, std::size_t Extent>\n> > >  struct is_span<Span<U, Extent>> : public std::true_type {\n> > >  };\n> > >\n> > > -template<typename T>\n> > > -inline constexpr bool is_span_v = is_span<T>::value;\n> > > -\n> > >  } /* namespace details */\n> > >\n> > >  namespace utils {\n> > > @@ -131,8 +125,8 @@ public:\n> > >\n> > >       template<std::size_t N>\n> > >       constexpr Span(element_type (&arr)[N],\n> > > -                    std::enable_if_t<std::is_convertible_v<std::remove_pointer_t<decltype(utils::data(arr))> (*)[],\n> > > -                                                           element_type (*)[]> &&\n> > > +                    std::enable_if_t<std::is_convertible<std::remove_pointer_t<decltype(utils::data(arr))> (*)[],\n> > > +                                                         element_type (*)[]>::value &&\n> > >                                       N == Extent,\n> > >                                       std::nullptr_t> = nullptr) noexcept\n> > >               : data_(arr)\n> > > @@ -141,8 +135,8 @@ public:\n> > >\n> > >       template<std::size_t N>\n> > >       constexpr Span(std::array<value_type, N> &arr,\n> > > -                    std::enable_if_t<std::is_convertible_v<std::remove_pointer_t<decltype(utils::data(arr))> (*)[],\n> > > -                                                           element_type (*)[]> &&\n> > > +                    std::enable_if_t<std::is_convertible<std::remove_pointer_t<decltype(utils::data(arr))> (*)[],\n> > > +                                                         element_type (*)[]>::value &&\n> > >                                       N == Extent,\n> > >                                       std::nullptr_t> = nullptr) noexcept\n> > >               : data_(arr.data())\n> > > @@ -151,8 +145,8 @@ public:\n> > >\n> > >       template<std::size_t N>\n> > >       constexpr Span(const std::array<value_type, N> &arr,\n> > > -                    std::enable_if_t<std::is_convertible_v<std::remove_pointer_t<decltype(utils::data(arr))> (*)[],\n> > > -                                                           element_type (*)[]> &&\n> > > +                    std::enable_if_t<std::is_convertible<std::remove_pointer_t<decltype(utils::data(arr))> (*)[],\n> > > +                                                         element_type (*)[]>::value &&\n> > >                                       N == Extent,\n> > >                                       std::nullptr_t> = nullptr) noexcept\n> > >               : data_(arr.data())\n> > > @@ -161,11 +155,11 @@ public:\n> > >\n> > >       template<class Container>\n> > >       explicit constexpr Span(Container &cont,\n> > > -                             std::enable_if_t<!details::is_span_v<Container> &&\n> > > -                                              !details::is_array_v<Container> &&\n> > > -                                              !std::is_array_v<Container> &&\n> > > -                                              std::is_convertible_v<std::remove_pointer_t<decltype(utils::data(cont))> (*)[],\n> > > -                                                                    element_type (*)[]>,\n> > > +                             std::enable_if_t<!details::is_span<Container>::value &&\n> > > +                                              !details::is_array<Container>::value &&\n> > > +                                              !std::is_array<Container>::value &&\n> > > +                                              std::is_convertible<std::remove_pointer_t<decltype(utils::data(cont))> (*)[],\n> > > +                                                                  element_type (*)[]>::value,\n> > >                                                std::nullptr_t> = nullptr)\n> > >               : data_(utils::data(cont))\n> > >       {\n> > > @@ -173,11 +167,11 @@ public:\n> > >\n> > >       template<class Container>\n> > >       explicit constexpr Span(const Container &cont,\n> > > -                             std::enable_if_t<!details::is_span_v<Container> &&\n> > > -                                              !details::is_array_v<Container> &&\n> > > -                                              !std::is_array_v<Container> &&\n> > > -                                              std::is_convertible_v<std::remove_pointer_t<decltype(utils::data(cont))> (*)[],\n> > > -                                                                    element_type (*)[]>,\n> > > +                             std::enable_if_t<!details::is_span<Container>::value &&\n> > > +                                              !details::is_array<Container>::value &&\n> > > +                                              !std::is_array<Container>::value &&\n> > > +                                              std::is_convertible<std::remove_pointer_t<decltype(utils::data(cont))> (*)[],\n> > > +                                                                  element_type (*)[]>::value,\n> > >                                                std::nullptr_t> = nullptr)\n> > >               : data_(utils::data(cont))\n> > >       {\n> > > @@ -186,7 +180,7 @@ public:\n> > >\n> > >       template<class U, std::size_t N>\n> > >       explicit constexpr Span(const Span<U, N> &s,\n> > > -                             std::enable_if_t<std::is_convertible_v<U (*)[], element_type (*)[]> &&\n> > > +                             std::enable_if_t<std::is_convertible<U (*)[], element_type (*)[]>::value &&\n> > >                                                N == Extent,\n> > >                                                std::nullptr_t> = nullptr) noexcept\n> > >               : data_(s.data())\n> > > @@ -299,8 +293,8 @@ public:\n> > >\n> > >       template<std::size_t N>\n> > >       constexpr Span(element_type (&arr)[N],\n> > > -                    std::enable_if_t<std::is_convertible_v<std::remove_pointer_t<decltype(utils::data(arr))> (*)[],\n> > > -                                                           element_type (*)[]>,\n> > > +                    std::enable_if_t<std::is_convertible<std::remove_pointer_t<decltype(utils::data(arr))> (*)[],\n> > > +                                                         element_type (*)[]>::value,\n> > >                                       std::nullptr_t> = nullptr) noexcept\n> > >               : data_(arr), size_(N)\n> > >       {\n> > > @@ -308,8 +302,8 @@ public:\n> > >\n> > >       template<std::size_t N>\n> > >       constexpr Span(std::array<value_type, N> &arr,\n> > > -                    std::enable_if_t<std::is_convertible_v<std::remove_pointer_t<decltype(utils::data(arr))> (*)[],\n> > > -                                                           element_type (*)[]>,\n> > > +                    std::enable_if_t<std::is_convertible<std::remove_pointer_t<decltype(utils::data(arr))> (*)[],\n> > > +                                                         element_type (*)[]>::value,\n> > >                                       std::nullptr_t> = nullptr) noexcept\n> > >               : data_(utils::data(arr)), size_(N)\n> > >       {\n> > > @@ -323,11 +317,11 @@ public:\n> > >\n> > >       template<class Container>\n> > >       constexpr Span(Container &cont,\n> > > -                    std::enable_if_t<!details::is_span_v<Container> &&\n> > > -                                     !details::is_array_v<Container> &&\n> > > -                                     !std::is_array_v<Container> &&\n> > > -                                     std::is_convertible_v<std::remove_pointer_t<decltype(utils::data(cont))> (*)[],\n> > > -                                                           element_type (*)[]>,\n> > > +                    std::enable_if_t<!details::is_span<Container>::value &&\n> > > +                                     !details::is_array<Container>::value &&\n> > > +                                     !std::is_array<Container>::value &&\n> > > +                                     std::is_convertible<std::remove_pointer_t<decltype(utils::data(cont))> (*)[],\n> > > +                                                         element_type (*)[]>::value,\n> > >                                       std::nullptr_t> = nullptr)\n> > >               : data_(utils::data(cont)), size_(utils::size(cont))\n> > >       {\n> > > @@ -335,11 +329,11 @@ public:\n> > >\n> > >       template<class Container>\n> > >       constexpr Span(const Container &cont,\n> > > -                    std::enable_if_t<!details::is_span_v<Container> &&\n> > > -                                     !details::is_array_v<Container> &&\n> > > -                                     !std::is_array_v<Container> &&\n> > > -                                     std::is_convertible_v<std::remove_pointer_t<decltype(utils::data(cont))> (*)[],\n> > > -                                                           element_type (*)[]>,\n> > > +                    std::enable_if_t<!details::is_span<Container>::value &&\n> > > +                                     !details::is_array<Container>::value &&\n> > > +                                     !std::is_array<Container>::value &&\n> > > +                                     std::is_convertible<std::remove_pointer_t<decltype(utils::data(cont))> (*)[],\n> > > +                                                         element_type (*)[]>::value,\n> > >                                       std::nullptr_t> = nullptr)\n> > >               : data_(utils::data(cont)), size_(utils::size(cont))\n> > >       {\n> > > @@ -347,7 +341,7 @@ public:\n> > >\n> > >       template<class U, std::size_t N>\n> > >       constexpr Span(const Span<U, N> &s,\n> > > -                    std::enable_if_t<std::is_convertible_v<U (*)[], element_type (*)[]>,\n> > > +                    std::enable_if_t<std::is_convertible<U (*)[], element_type (*)[]>::value,\n> > >                                       std::nullptr_t> = nullptr) noexcept\n> > >               : data_(s.data()), size_(s.size())\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 18FEEC0F1A\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed,  6 Jan 2021 11:47:32 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 4D4BC630BA;\n\tWed,  6 Jan 2021 12:47:31 +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 5BC626010B\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed,  6 Jan 2021 12:47:30 +0100 (CET)","from pendragon.ideasonboard.com (62-78-145-57.bb.dnainternet.fi\n\t[62.78.145.57])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id B9CCB335;\n\tWed,  6 Jan 2021 12:47:29 +0100 (CET)"],"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=\"NMrfRTNx\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1609933649;\n\tbh=HpFBlgxAqfmAeSkxvU1ZX9I7ThbcwmXmmrXBxSu+3Kc=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=NMrfRTNxAkGu8MhHIIp1uOljrYfSXkuQh29aw9R7jKV7vd2X4rqYJxxERYv8U481A\n\tKSdWhLcjuDBKyv40cTyiNzK2OInasRwUtQJn2NE3O0NXvWC5WvrJrIZwE3mFsMV5eR\n\t/orpgTD6MgzWDl2r6Q/+nM1v+sOwBXt6KxL7unRE=","Date":"Wed, 6 Jan 2021 13:47:17 +0200","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Shik Chen <shik@google.com>","Message-ID":"<X/WjRWymQG72swzW@pendragon.ideasonboard.com>","References":"<20201231154711.207852-1-jeanmichel.hautbois@ideasonboard.com>\n\t<X/KtjRurtexrbiFj@pendragon.ideasonboard.com>\n\t<CAFixSa3QTZtZr9Yq_qd1vNzCb+9YZYqao8V-gS-uP4zpMYeE+Q@mail.gmail.com>","MIME-Version":"1.0","Content-Disposition":"inline","In-Reply-To":"<CAFixSa3QTZtZr9Yq_qd1vNzCb+9YZYqao8V-gS-uP4zpMYeE+Q@mail.gmail.com>","Subject":"Re: [libcamera-devel] [PATCH] libcamera: revert C++17 specific code\n\tfor public API","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>"}}]