summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>2021-08-27 02:50:29 +0300
committerLaurent Pinchart <laurent.pinchart@ideasonboard.com>2021-09-02 01:16:45 +0300
commitc4e2b00d51f150632b203f81866604168d2ac1ff (patch)
tree69afd2d77a1c08748c8ebf949d897131b428c292
parentd1315600b8d406291215efc2be722dd93a38e481 (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.h34
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>