
#ifndef PLS_INTERNAL_HELPERS_MEMBER_FUNCTION_H_
#define PLS_INTERNAL_HELPERS_MEMBER_FUNCTION_H_

namespace pls {
namespace internal {
namespace helpers {

template<class C, typename R, typename ...ARGS>
class member_function {
 public:
  using type = member_function<C, R, ARGS...>;

  member_function(C *object, R (C::*function_pointer)(ARGS...)) : object_{object},
                                                                  function_pointer_{function_pointer} {}

  R operator()(ARGS... args) {
    ((*object_).*function_pointer_)(args...);
  }

 private:
  C *object_;
  R (C::*function_pointer_)(ARGS...);
};

template<typename C, typename R, typename ...ARGS>
static constexpr member_function<C, R, ARGS...> bind(C *object, R (C::*function_pointer)(ARGS...)) {
  return {object, function_pointer};
}

}
}
}

#endif //PLS_INTERNAL_HELPERS_MEMBER_FUNCTION_H_
