bind_first.hpp 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. // This file is distributed under the BSD License.
  2. // See "license.txt" for details.
  3. // Copyright 2009-2012, Jonathan Turner ([email protected])
  4. // Copyright 2009-2017, Jason Turner ([email protected])
  5. // http://www.chaiscript.com
  6. // This is an open source non-commercial project. Dear PVS-Studio, please check it.
  7. // PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
  8. #ifndef CHAISCRIPT_BIND_FIRST_HPP_
  9. #define CHAISCRIPT_BIND_FIRST_HPP_
  10. #include <functional>
  11. namespace chaiscript
  12. {
  13. namespace detail
  14. {
  15. template<typename T>
  16. T* get_pointer(T *t)
  17. {
  18. return t;
  19. }
  20. template<typename T>
  21. T* get_pointer(const std::reference_wrapper<T> &t)
  22. {
  23. return &t.get();
  24. }
  25. template<typename O, typename Ret, typename P1, typename ... Param>
  26. auto bind_first(Ret (*f)(P1, Param...), O&& o)
  27. {
  28. return [f, o](Param...param) -> Ret {
  29. return f(std::forward<O>(o), std::forward<Param>(param)...);
  30. };
  31. }
  32. template<typename O, typename Ret, typename Class, typename ... Param>
  33. auto bind_first(Ret (Class::*f)(Param...), O&& o)
  34. {
  35. return [f, o](Param...param) -> Ret {
  36. return (get_pointer(o)->*f)(std::forward<Param>(param)...);
  37. };
  38. }
  39. template<typename O, typename Ret, typename Class, typename ... Param>
  40. auto bind_first(Ret (Class::*f)(Param...) const, O&& o)
  41. {
  42. return [f, o](Param...param) -> Ret {
  43. return (get_pointer(o)->*f)(std::forward<Param>(param)...);
  44. };
  45. }
  46. template<typename O, typename Ret, typename P1, typename ... Param>
  47. auto bind_first(const std::function<Ret (P1, Param...)> &f, O&& o)
  48. {
  49. return [f, o](Param...param) -> Ret {
  50. return f(o, std::forward<Param>(param)...);
  51. };
  52. }
  53. template<typename F, typename O, typename Ret, typename Class, typename P1, typename ... Param>
  54. auto bind_first(const F &fo, O&& o, Ret (Class::*f)(P1, Param...) const)
  55. {
  56. return [fo, o, f](Param ...param) -> Ret {
  57. return (fo.*f)(o, std::forward<Param>(param)...);
  58. };
  59. }
  60. template<typename F, typename O>
  61. auto bind_first(const F &f, O&& o)
  62. {
  63. return bind_first(f, std::forward<O>(o), &F::operator());
  64. }
  65. }
  66. }
  67. #endif