/* * Copyright (C) 2015 Intel Corporation. All rights reserved. * * This file is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This file is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #pragma once #include #define FUNCTOR_TYPEDEF(name, rettype, ...) \ typedef Functor name #define FUNCTOR_DECLARE(name, rettype, ...) \ Functor name #define FUNCTOR_BIND(obj, func, rettype, ...) \ Functor::bind::type, func>(obj) #define FUNCTOR_BIND_MEMBER(func, rettype, ...) \ Functor::bind::type, func>(this) template class Functor { public: constexpr Functor(void *obj, RetType (*method)(void *obj, Args...)) : _obj(obj) , _method(method) { } // Allow to construct an empty Functor constexpr Functor(decltype(nullptr)) : Functor(nullptr, nullptr) { } constexpr Functor() : Functor(nullptr, nullptr) { } // Call the method on the obj this Functor is bound to RetType operator()(Args... args) const { return _method(_obj, args...); } // Compare if the two Functors are calling the same method in the same // object inline bool operator==(const Functor& rhs) { return _obj == rhs._obj && _method == rhs._method; } // Allow to check if there's a method set in the Functor explicit operator bool() const { return _method != nullptr; } template static constexpr Functor bind(T *obj) { return { obj, method_wrapper }; } private: void *_obj; RetType (*_method)(void *obj, Args...); template static RetType method_wrapper(void *obj, Args... args) { T *t = static_cast(obj); return (t->*method)(args...); } };