functor.h 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. /*
  2. * Copyright (C) 2015 Intel Corporation. All rights reserved.
  3. *
  4. * This file is free software: you can redistribute it and/or modify it
  5. * under the terms of the GNU General Public License as published by the
  6. * Free Software Foundation, either version 3 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This file is distributed in the hope that it will be useful, but
  10. * WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  12. * See the GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License along
  15. * with this program. If not, see <http://www.gnu.org/licenses/>.
  16. */
  17. #pragma once
  18. #include <type_traits>
  19. #define FUNCTOR_TYPEDEF(name, rettype, ...) \
  20. typedef Functor<rettype, ## __VA_ARGS__> name
  21. #define FUNCTOR_DECLARE(name, rettype, ...) \
  22. Functor<rettype, ## __VA_ARGS__> name
  23. #define FUNCTOR_BIND(obj, func, rettype, ...) \
  24. Functor<rettype, ## __VA_ARGS__>::bind<std::remove_reference<decltype(*obj)>::type, func>(obj)
  25. #define FUNCTOR_BIND_MEMBER(func, rettype, ...) \
  26. Functor<rettype, ## __VA_ARGS__>::bind<std::remove_reference<decltype(*this)>::type, func>(this)
  27. template <class RetType, class... Args>
  28. class Functor
  29. {
  30. public:
  31. constexpr Functor(void *obj, RetType (*method)(void *obj, Args...))
  32. : _obj(obj)
  33. , _method(method)
  34. {
  35. }
  36. // Allow to construct an empty Functor
  37. constexpr Functor(decltype(nullptr))
  38. : Functor(nullptr, nullptr) { }
  39. constexpr Functor()
  40. : Functor(nullptr, nullptr) { }
  41. // Call the method on the obj this Functor is bound to
  42. RetType operator()(Args... args) const
  43. {
  44. return _method(_obj, args...);
  45. }
  46. // Compare if the two Functors are calling the same method in the same
  47. // object
  48. inline bool operator==(const Functor<RetType, Args...>& rhs)
  49. {
  50. return _obj == rhs._obj && _method == rhs._method;
  51. }
  52. inline bool operator!=(const Functor<RetType, Args...>& rhs)
  53. {
  54. return _obj != rhs._obj || _method != rhs._method;
  55. }
  56. // Allow to check if there's a method set in the Functor
  57. explicit operator bool() const
  58. {
  59. return _method != nullptr;
  60. }
  61. template<class T, RetType (T::*method)(Args...)>
  62. static constexpr Functor bind(T *obj)
  63. {
  64. return { obj, method_wrapper<T, method> };
  65. }
  66. private:
  67. void *_obj;
  68. RetType (*_method)(void *obj, Args...);
  69. template<class T, RetType (T::*method)(Args...)>
  70. static RetType method_wrapper(void *obj, Args... args)
  71. {
  72. T *t = static_cast<T*>(obj);
  73. return (t->*method)(args...);
  74. }
  75. };