From a1e1503e1ac774c7c273b5f9e5853f157cd647c1 Mon Sep 17 00:00:00 2001 From: Lucas De Marchi Date: Sun, 24 May 2015 16:07:04 -0300 Subject: [PATCH] AP_HAL: Add Functor implementation This is a Functor implementation that should cover the use cases we have for FastDelegate. In contrary to the latter, it can be constructed at compile time so the compiler can safely put it in a read-only section which covers the cases in which we are not using it. --- libraries/AP_HAL/utility/functor.h | 93 ++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 libraries/AP_HAL/utility/functor.h diff --git a/libraries/AP_HAL/utility/functor.h b/libraries/AP_HAL/utility/functor.h new file mode 100644 index 0000000000..9e3535ee0e --- /dev/null +++ b/libraries/AP_HAL/utility/functor.h @@ -0,0 +1,93 @@ +/// -*- tab-width: 4; Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*- +/* + * 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 +#ifndef __FUNCTOR_H__ +#define __FUNCTOR_H__ + +#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...); + } +}; + +template< class T > struct remove_reference {typedef T type;}; +template< class T > struct remove_reference {typedef T type;}; +template< class T > struct remove_reference {typedef T type;}; + +#endif