[PATCH v1 4/4] libcamera: controls: Simplify ControlValue::{ControlValue, get, set}
Barnabás Pőcze
barnabas.pocze at ideasonboard.com
Wed Apr 2 10:39:08 CEST 2025
Hi
2025. 04. 01. 23:47 keltezéssel, Laurent Pinchart írta:
> Hi Barnabás,
>
> Thank you for the patch.
>
> On Tue, Apr 01, 2025 at 03:19:39PM +0200, Barnabás Pőcze wrote:
>> Whether or not the control has an array type can be determined from the
>> static information in `detail::control_type<T>`, so use that and
>> `if constexpr` to deduplicate the constructor, get, and set functions.
>
> I'd rather not do this, as it would prevent us from supporting arrays of
> strings. Is there anything you're working on that depends on this
> series, or is it standalone cleanups ?
Nothing depends on this change per se, but I have made use of the same uniform
handling of control values in other code. So I would like to achieve something
more uniform. Can we establish how multi-dimensional things are expected to work?
Regards,
Barnabás Pőcze
>
>> Signed-off-by: Barnabás Pőcze <barnabas.pocze at ideasonboard.com>
>> ---
>> include/libcamera/controls.h | 75 ++++++++++--------------------------
>> 1 file changed, 20 insertions(+), 55 deletions(-)
>>
>> diff --git a/include/libcamera/controls.h b/include/libcamera/controls.h
>> index 85c724ec1..22b5e3d96 100644
>> --- a/include/libcamera/controls.h
>> +++ b/include/libcamera/controls.h
>> @@ -136,28 +136,14 @@ public:
>> ControlValue();
>>
>> #ifndef __DOXYGEN__
>> - template<typename T, std::enable_if_t<!details::is_span<T>::value &&
>> - details::control_type<T>::value &&
>> - !std::is_same<std::string, std::remove_cv_t<T>>::value,
>> - std::nullptr_t> = nullptr>
>> - ControlValue(const T &value)
>> - : type_(ControlTypeNone), numElements_(0)
>> - {
>> - set(details::control_type<std::remove_cv_t<T>>::value, false,
>> - &value, 1, sizeof(T));
>> - }
>> -
>> - template<typename T, std::enable_if_t<details::is_span<T>::value ||
>> - std::is_same<std::string, std::remove_cv_t<T>>::value,
>> - std::nullptr_t> = nullptr>
>> + template<typename T, typename = std::void_t<decltype(details::control_type<T>::value)>>
>> #else
>> template<typename T>
>> #endif
>> ControlValue(const T &value)
>> - : type_(ControlTypeNone), numElements_(0)
>> + : type_(ControlTypeNone), isArray_(false), numElements_(0)
>> {
>> - set(details::control_type<std::remove_cv_t<T>>::value, true,
>> - value.data(), value.size(), sizeof(typename T::value_type));
>> + set(value);
>> }
>>
>> ~ControlValue();
>> @@ -180,54 +166,33 @@ public:
>> return !(*this == other);
>> }
>>
>> -#ifndef __DOXYGEN__
>> - template<typename T, std::enable_if_t<!details::is_span<T>::value &&
>> - !std::is_same<std::string, std::remove_cv_t<T>>::value,
>> - std::nullptr_t> = nullptr>
>> - T get() const
>> - {
>> - assert(type_ == details::control_type<std::remove_cv_t<T>>::value);
>> - assert(!isArray_);
>> -
>> - return *reinterpret_cast<const T *>(data().data());
>> - }
>> -
>> - template<typename T, std::enable_if_t<details::is_span<T>::value ||
>> - std::is_same<std::string, std::remove_cv_t<T>>::value,
>> - std::nullptr_t> = nullptr>
>> -#else
>> template<typename T>
>> -#endif
>> T get() const
>> {
>> - assert(type_ == details::control_type<std::remove_cv_t<T>>::value);
>> - assert(isArray_);
>> + using TypeInfo = details::control_type<std::remove_cv_t<T>>;
>>
>> - using V = typename T::value_type;
>> - const V *value = reinterpret_cast<const V *>(data().data());
>> - return T{ value, numElements_ };
>> - }
>> + assert(type_ == TypeInfo::value);
>> + assert(isArray_ == (TypeInfo::size > 0));
>>
>> -#ifndef __DOXYGEN__
>> - template<typename T, std::enable_if_t<!details::is_span<T>::value &&
>> - !std::is_same<std::string, std::remove_cv_t<T>>::value,
>> - std::nullptr_t> = nullptr>
>> - void set(const T &value)
>> - {
>> - set(details::control_type<std::remove_cv_t<T>>::value, false,
>> - reinterpret_cast<const void *>(&value), 1, sizeof(T));
>> + if constexpr (TypeInfo::size > 0)
>> + return T(reinterpret_cast<const typename T::value_type *>(data().data()), numElements_);
>> + else
>> + return *reinterpret_cast<const T *>(data().data());
>> }
>>
>> - template<typename T, std::enable_if_t<details::is_span<T>::value ||
>> - std::is_same<std::string, std::remove_cv_t<T>>::value,
>> - std::nullptr_t> = nullptr>
>> -#else
>> template<typename T>
>> -#endif
>> void set(const T &value)
>> {
>> - set(details::control_type<std::remove_cv_t<T>>::value, true,
>> - value.data(), value.size(), sizeof(typename T::value_type));
>> + using TypeInfo = details::control_type<std::remove_cv_t<T>>;
>> + constexpr auto type = TypeInfo::value;
>> +
>> + if constexpr (TypeInfo::size > 0) {
>> + static_assert(std::is_trivially_copyable_v<typename T::value_type>);
>> + set(type, true, value.data(), value.size(), sizeof(typename T::value_type));
>> + } else {
>> + static_assert(std::is_trivially_copyable_v<T>);
>> + set(type, false, reinterpret_cast<const void *>(&value), 1, sizeof(T));
>> + }
>> }
>>
>> void reserve(ControlType type, bool isArray = false,
>
More information about the libcamera-devel
mailing list