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_FUNCTION_CALL_DETAIL_HPP_
12
#define CHAISCRIPT_FUNCTION_CALL_DETAIL_HPP_
13

14
#include <functional>
15
#include <memory>
16
#include <string>
17
#include <type_traits>
18
#include <vector>
19

20
#include "boxed_cast.hpp"
21
#include "boxed_number.hpp"
22
#include "boxed_value.hpp"
23
#include "type_conversions.hpp"
24
#include "proxy_functions.hpp"
25

26
namespace chaiscript
27
{
28
  namespace dispatch
29
  {
30
    namespace detail
31
    {
32
      /// used internally for unwrapping a function call's types
33
      template<typename Ret, typename ... Param>
34
        struct Build_Function_Caller_Helper
35
        {
36 1
          Build_Function_Caller_Helper(std::vector<Const_Proxy_Function> t_funcs, const Type_Conversions *t_conversions)
37 1
            : m_funcs(std::move(t_funcs)),
38 1
              m_conversions(t_conversions)
39
          {
40
          }
41

42 1
          Ret call(const chaiscript::Function_Params &params, const Type_Conversions_State &t_state)
43
          {
44
            if constexpr (std::is_arithmetic_v<Ret> && !std::is_same_v<std::remove_cv_t<std::remove_reference_t<Ret>>, bool>) {
45 1
              return Boxed_Number(dispatch::dispatch(m_funcs, params, t_state)).get_as<Ret>();
46
            } else if constexpr (std::is_same_v<void, Ret>) {
47 1
              dispatch::dispatch(m_funcs, params, t_state);
48
            } else {
49 1
              return boxed_cast<Ret>(dispatch::dispatch(m_funcs, params, t_state), &t_state);
50
            }
51
          }
52

53
          template<typename ... P>
54 1
          Ret operator()(P&&  ...  param)
55
          {
56 1
            std::array<Boxed_Value, sizeof...(P)> params{box<P>(std::forward<P>(param))...};
57

58 1
            if (m_conversions) {
59 1
              Type_Conversions_State state(*m_conversions, m_conversions->conversion_saves());
60 1
              return call(chaiscript::Function_Params{params}, state);
61
            } else {
62 1
              Type_Conversions conv;
63 1
              Type_Conversions_State state(conv, conv.conversion_saves());
64 1
              return call(chaiscript::Function_Params{params}, state);
65
            }
66

67
          }
68

69

70
          template<typename P, typename Q>
71 1
            static Boxed_Value box(Q &&q) {
72
              if constexpr (std::is_same_v<chaiscript::Boxed_Value, std::decay_t<Q>>) {
73 1
                return std::forward<Q>(q);
74
              } else if constexpr (std::is_reference_v<P>) {
75 1
                return Boxed_Value(std::ref(std::forward<Q>(q)));
76
              } else {
77 1
                return Boxed_Value(std::forward<Q>(q));
78
              }
79
            }
80

81

82
          std::vector<Const_Proxy_Function> m_funcs;
83
          const Type_Conversions *m_conversions;
84
        };
85

86

87

88
      /// \todo what happens if t_conversions is deleted out from under us?!
89
      template<typename Ret, typename ... Params>
90
        std::function<Ret (Params...)> build_function_caller_helper(Ret (Params...), const std::vector<Const_Proxy_Function> &funcs, const Type_Conversions_State *t_conversions)
91
        {
92
          /*
93
          if (funcs.size() == 1)
94
          {
95
            std::shared_ptr<const Proxy_Function_Impl<Ret (Params...)>> pfi = 
96
              std::dynamic_pointer_cast<const Proxy_Function_Impl<Ret (Params...)> >
97
                (funcs[0]);
98

99
            if (pfi)
100
            {
101
              return pfi->internal_function();
102
            } 
103
            // looks like this either wasn't a Proxy_Function_Impl or the types didn't match
104
            // we cannot make any other guesses or assumptions really, so continuing
105
          }
106
*/
107

108
          return std::function<Ret (Params...)>(Build_Function_Caller_Helper<Ret, Params...>(funcs, t_conversions?t_conversions->get():nullptr));
109
        }
110
    }
111
  }
112
}
113

114
#endif
115

Read our documentation on viewing source code .

Loading