diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/libcamera/bound_method.h | 54 |
1 files changed, 33 insertions, 21 deletions
diff --git a/include/libcamera/bound_method.h b/include/libcamera/bound_method.h index b50072ff..a74d2c50 100644 --- a/include/libcamera/bound_method.h +++ b/include/libcamera/bound_method.h @@ -7,6 +7,7 @@ #ifndef __LIBCAMERA_BOUND_METHOD_H__ #define __LIBCAMERA_BOUND_METHOD_H__ +#include <memory> #include <tuple> #include <type_traits> @@ -21,6 +22,24 @@ enum ConnectionType { ConnectionTypeBlocking, }; +class BoundMethodPackBase +{ +public: + virtual ~BoundMethodPackBase() {} +}; + +template<typename... Args> +class BoundMethodPack : public BoundMethodPackBase +{ +public: + BoundMethodPack(const Args &... args) + : args_(args...) + { + } + + std::tuple<typename std::remove_reference<Args>::type...> args_; +}; + class BoundMethodBase { public: @@ -36,7 +55,7 @@ public: Object *object() const { return object_; } - virtual void invokePack(void *pack) = 0; + virtual void invokePack(BoundMethodPackBase *pack) = 0; protected: #ifndef __DOXYGEN__ @@ -58,7 +77,8 @@ protected: }; #endif - void activatePack(void *pack, bool deleteMethod); + void activatePack(std::shared_ptr<BoundMethodPackBase> pack, + bool deleteMethod); void *obj_; Object *object_; @@ -67,18 +87,6 @@ private: ConnectionType connectionType_; }; -template<typename... Args> -class BoundMethodPack -{ -public: - BoundMethodPack(const Args &... args) - : args_(args...) - { - } - - std::tuple<typename std::remove_reference<Args>::type...> args_; -}; - template<typename R, typename... Args> class BoundMethodArgs : public BoundMethodBase { @@ -87,18 +95,18 @@ public: private: template<int... S> - void invokePack(void *pack, BoundMethodBase::sequence<S...>) + void invokePack(BoundMethodPackBase *pack, BoundMethodBase::sequence<S...>) { - PackType *args = static_cast<PackType *>(pack); + /* args is effectively unused when the sequence S is empty. */ + PackType *args [[gnu::unused]] = static_cast<PackType *>(pack); invoke(std::get<S>(args->args_)...); - delete args; } public: BoundMethodArgs(void *obj, Object *object, ConnectionType type) : BoundMethodBase(obj, object, type) {} - void invokePack(void *pack) override + void invokePack(BoundMethodPackBase *pack) override { invokePack(pack, typename BoundMethodBase::generator<sizeof...(Args)>::type()); } @@ -123,10 +131,14 @@ public: void activate(Args... args, bool deleteMethod = false) override { - if (this->object_) - BoundMethodBase::activatePack(new PackType{ args... }, deleteMethod); - else + if (!this->object_) { (static_cast<T *>(this->obj_)->*func_)(args...); + return; + } + + std::shared_ptr<BoundMethodPackBase> pack = + std::make_shared<typename BoundMemberMethod<T, R, Args...>::PackType>(args...); + BoundMethodBase::activatePack(pack, deleteMethod); } void invoke(Args... args) override |