diff options
author | Laurent Pinchart <laurent.pinchart@ideasonboard.com> | 2021-08-27 02:50:29 +0300 |
---|---|---|
committer | Laurent Pinchart <laurent.pinchart@ideasonboard.com> | 2021-09-02 01:16:45 +0300 |
commit | c4e2b00d51f150632b203f81866604168d2ac1ff (patch) | |
tree | 69afd2d77a1c08748c8ebf949d897131b428c292 | |
parent | d1315600b8d406291215efc2be722dd93a38e481 (diff) |
libcamera: base: bound_method: Remove BoundMethodArgs specialization
The BoundMethodArgs specialization for the void return type is only
needed to avoid accessing the ret_ member variable that is lacking from
the corresponding BoundMethodPack specialization. As the member variable
is only accessed in the invokePack() function, instead of specializing
the whole class we can use SFINAE to select between two different
implementations of the function.
SFINAE can only depend on the function template parameters, not the
parameters of the class template in which the function is defined:
"Only the failures in the types and expressions in the immediate context
of the function type or its template parameter types are SFINAE errors."
We thus can't use the type R in an std::enable_if expression for the
invokePack() function. To work around this, we have to add a type T to
the function template definition, which defaults to R, and use T with
std::enable_if.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
-rw-r--r-- | include/libcamera/base/bound_method.h | 34 |
1 files changed, 8 insertions, 26 deletions
diff --git a/include/libcamera/base/bound_method.h b/include/libcamera/base/bound_method.h index 9c212f1e..76ce8017 100644 --- a/include/libcamera/base/bound_method.h +++ b/include/libcamera/base/bound_method.h @@ -98,35 +98,17 @@ public: using PackType = BoundMethodPack<R, Args...>; private: - template<std::size_t... I> - void invokePack(BoundMethodPackBase *pack, std::index_sequence<I...>) + template<std::size_t... I, typename T = R> + std::enable_if_t<!std::is_void<T>::value, void> + invokePack(BoundMethodPackBase *pack, std::index_sequence<I...>) { PackType *args = static_cast<PackType *>(pack); args->ret_ = invoke(std::get<I>(args->args_)...); } -public: - BoundMethodArgs(void *obj, Object *object, ConnectionType type) - : BoundMethodBase(obj, object, type) {} - - void invokePack(BoundMethodPackBase *pack) override - { - invokePack(pack, std::make_index_sequence<sizeof...(Args)>{}); - } - - virtual R activate(Args... args, bool deleteMethod = false) = 0; - virtual R invoke(Args... args) = 0; -}; - -template<typename... Args> -class BoundMethodArgs<void, Args...> : public BoundMethodBase -{ -public: - using PackType = BoundMethodPack<void, Args...>; - -private: - template<std::size_t... I> - void invokePack(BoundMethodPackBase *pack, std::index_sequence<I...>) + template<std::size_t... I, typename T = R> + std::enable_if_t<std::is_void<T>::value, void> + invokePack(BoundMethodPackBase *pack, std::index_sequence<I...>) { /* args is effectively unused when the sequence I is empty. */ PackType *args [[gnu::unused]] = static_cast<PackType *>(pack); @@ -142,8 +124,8 @@ public: invokePack(pack, std::make_index_sequence<sizeof...(Args)>{}); } - virtual void activate(Args... args, bool deleteMethod = false) = 0; - virtual void invoke(Args... args) = 0; + virtual R activate(Args... args, bool deleteMethod = false) = 0; + virtual R invoke(Args... args) = 0; }; template<typename T, typename R, typename... Args> |