ChaiScript / ChaiScript
1
// This file is distributed under the BSD License.
2
// See "license.txt" for details.
3
// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
4
// Copyright 2009-2018, Jason Turner (jason@emptycrate.com)
5
// http://www.chaiscript.com
6

7
// This is an open source non-commercial project. Dear PVS-Studio, please check it.
8
// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
9

10

11
#ifndef CHAISCRIPT_REGISTER_FUNCTION_HPP_
12
#define CHAISCRIPT_REGISTER_FUNCTION_HPP_
13

14
#include <type_traits>
15

16
#include "bind_first.hpp"
17
#include "proxy_functions.hpp"
18
#include "function_signature.hpp"
19

20
namespace chaiscript
21
{
22
  namespace dispatch::detail
23
  {
24
    template<typename Obj, typename Param1, typename ... Rest>
25 1
      Param1 get_first_param(Function_Params<Param1, Rest...>, Obj &&obj)
26
      {
27 1
        return static_cast<Param1>(std::forward<Obj>(obj));
28
      }
29

30
    template<typename Func, bool Is_Noexcept, bool Is_Member, bool Is_MemberObject, bool Is_Object, typename Ret, typename ... Param>
31 1
      auto make_callable_impl(Func &&func, Function_Signature<Ret, Function_Params<Param...>, Is_Noexcept, Is_Member, Is_MemberObject, Is_Object>)
32
      {
33
        if constexpr (Is_MemberObject) {
34
          // we now that the Param pack will have only one element, so we are safe expanding it here
35 1
          return Proxy_Function(chaiscript::make_shared<dispatch::Proxy_Function_Base, dispatch::Attribute_Access<Ret, std::decay_t<Param>...>>(std::forward<Func>(func)));
36
        } else if constexpr (Is_Member) {
37
		  // TODO some kind of bug is preventing forwarding of this noexcept for the lambda
38 1
          auto call = [func = std::forward<Func>(func)](auto && obj, auto && ... param) /* noexcept(Is_Noexcept) */ -> decltype(auto) {
39
            return (( get_first_param(Function_Params<Param...>{}, obj).*func )(std::forward<decltype(param)>(param)...));
40
          };
41
          return Proxy_Function(
42
              chaiscript::make_shared<dispatch::Proxy_Function_Base, 
43 1
              dispatch::Proxy_Function_Callable_Impl<Ret (Param...), decltype(call)>>(std::move(call))
44 1
              );
45
        } else {
46
          return Proxy_Function(
47
              chaiscript::make_shared<dispatch::Proxy_Function_Base, 
48
              dispatch::Proxy_Function_Callable_Impl<Ret (Param...), std::decay_t<Func>>>(std::forward<Func>(func))
49 1
              );
50
        }
51
      }
52

53
    // this version peels off the function object itself from the function signature, when used
54
    // on a callable object
55
    template<typename Func, typename Ret, typename Object, typename ... Param, bool Is_Noexcept>
56 1
      auto make_callable(Func &&func, Function_Signature<Ret, Function_Params<Object, Param...>, Is_Noexcept, false, false, true>)
57
      {
58 1
        return make_callable_impl(std::forward<Func>(func), Function_Signature<Ret, Function_Params<Param...>, Is_Noexcept, false, false, true>{});
59
      } 
60

61
    template<typename Func, typename Ret, typename ... Param, bool Is_Noexcept, bool Is_Member, bool Is_MemberObject>
62 1
      auto make_callable(Func &&func, Function_Signature<Ret, Function_Params<Param...>, Is_Noexcept, Is_Member, Is_MemberObject, false> fs)
63
      {
64 1
        return make_callable_impl(std::forward<Func>(func), fs);
65
      }
66
  }
67

68
  /// \brief Creates a new Proxy_Function object from a free function, member function or data member
69
  /// \param[in] t Function / member to expose
70
  ///
71
  /// \b Example:
72
  /// \code
73
  /// int myfunction(const std::string &);
74
  /// class MyClass
75
  /// {
76
  ///   public:
77
  ///     void memberfunction();
78
  ///     int memberdata;
79
  /// };
80
  /// 
81
  /// chaiscript::ChaiScript chai;
82
  /// chai.add(fun(&myfunction), "myfunction");
83
  /// chai.add(fun(&MyClass::memberfunction), "memberfunction");
84
  /// chai.add(fun(&MyClass::memberdata), "memberdata");
85
  /// \endcode
86
  /// 
87
  /// \sa \ref adding_functions
88
  template<typename T>
89 1
    Proxy_Function fun(T &&t)
90
    {
91 1
      return dispatch::detail::make_callable(std::forward<T>(t), dispatch::detail::function_signature(t));
92
    }
93

94

95
  
96
  /// \brief Creates a new Proxy_Function object from a free function, member function or data member and binds the first parameter of it
97
  /// \param[in] t Function / member to expose
98
  /// \param[in] q Value to bind to first parameter
99
  ///
100
  /// \b Example:
101
  /// \code
102
  /// struct MyClass
103
  /// {
104
  ///   void memberfunction(int);
105
  /// };
106
  /// 
107
  /// MyClass obj;
108
  /// chaiscript::ChaiScript chai;
109
  /// // Add function taking only one argument, an int, and permanently bound to "obj"
110
  /// chai.add(fun(&MyClass::memberfunction, std::ref(obj)), "memberfunction"); 
111
  /// \endcode
112
  /// 
113
  /// \sa \ref adding_functions
114
  template<typename T, typename Q>
115
    Proxy_Function fun(T &&t, const Q &q)
116
    {
117
      return fun(detail::bind_first(std::forward<T>(t), q));
118
    }
119

120

121

122
}
123

124

125
#endif
126

Read our documentation on viewing source code .

Loading