/* SPDX-License-Identifier: LGPL-2.1-or-later */ /* * Copyright (C) 2019, Google Inc. * * bound_method.h - Method bind and invocation */ #ifndef __LIBCAMERA_BOUND_METHOD_H__ #define __LIBCAMERA_BOUND_METHOD_H__ #include #include namespace libcamera { class Object; class BoundMethodBase { public: BoundMethodBase(void *obj, Object *object) : obj_(obj), object_(object) {} virtual ~BoundMethodBase() {} template::value>::type * = nullptr> bool match(T *obj) { return obj == obj_; } bool match(Object *object) { return object == object_; } Object *object() const { return object_; } void activatePack(void *pack); virtual void invokePack(void *pack) = 0; protected: void *obj_; Object *object_; }; template class BoundMethodArgs : public BoundMethodBase { private: #ifndef __DOXYGEN__ /* * This is a cheap partial implementation of std::integer_sequence<> * from C++14. */ template struct sequence { }; template struct generator : generator { }; template struct generator<0, S...> { typedef sequence type; }; #endif using PackType = std::tuple::type...>; template void invokePack(void *pack, sequence) { PackType *args = static_cast(pack); invoke(std::get(*args)...); delete args; } public: BoundMethodArgs(void *obj, Object *object) : BoundMethodBase(obj, object) {} void invokePack(void *pack) override { invokePack(pack, typename generator::type()); } virtual void activate(Args... args) = 0; virtual void invoke(Args... args) = 0; }; template class BoundMemberMethod : public BoundMethodArgs { public: using PackType = std::tuple::type...>; BoundMemberMethod(T *obj, Object *object, void (T::*func)(Args...)) : BoundMethodArgs(obj, object), func_(func) {} bool match(void (T::*func)(Args...)) const { return func == func_; } void activate(Args... args) { if (this->object_) BoundMethodBase::activatePack(new PackType{ args... }); else (static_cast(this->obj_)->*func_)(args...); } void invoke(Args... args) { (static_cast(this->obj_)->*func_)(args...); } private: void (T::*func_)(Args...); }; template class BoundStaticMethod : public BoundMethodArgs { public: BoundStaticMethod(void (*func)(Args...)) : BoundMethodArgs(nullptr, nullptr), func_(func) {} bool match(void (*func)(Args...)) const { return func == func_; } void activate(Args... args) { (*func_)(args...); } void invoke(Args... args) {} private: void (*func_)(Args...); }; }; /* namespace libcamera */ #endif /* __LIBCAMERA_BOUND_METHOD_H__ */