v8toolkit  0.0.1
Utility library for embedding V8 Javascript engine in a c++ program
call_callable.h
Go to the documentation of this file.
1 
2 #pragma once
3 
4 #include <tuple>
5 
6 
7 #include <v8.h>
8 
9 #include "v8helpers.h"
10 #include "casts.hpp"
11 #include "parameter_builder.h"
12 #include "stdfunctionreplacement.h"
13 
14 
15 namespace v8toolkit {
16 
17 
18 
19 
20 template<class Function, class... T>
21 struct CallCallable;
22 
23 
24 /**
25  * Call a function where the first argument is specified differently for "fake methods" - functions
26  * that aren't proper member instance functions but act like it by taking a pointer to "this" as their first
27  * explicit parameter
28  */
29 template<class ReturnType, class InitialArg, class... Args>
30 struct CallCallable<func::function<ReturnType(InitialArg, Args...)>, InitialArg> {
31 using NonConstReturnType = std::remove_const_t<ReturnType>;
32 
33 template<class DefaultArgsTuple = std::tuple<>, std::size_t... ArgIndexes>
34 void operator()(func::function<ReturnType(InitialArg, Args...)> & function,
35  const v8::FunctionCallbackInfo<v8::Value> & info,
36  InitialArg initial_arg,
37  std::index_sequence<ArgIndexes...>,
38  DefaultArgsTuple const & default_args_tuple = DefaultArgsTuple()) {
39 
40  int i = 0;
41 
42  constexpr int user_parameter_count = sizeof...(Args);
43  constexpr int default_arg_count = std::tuple_size<DefaultArgsTuple>::value;
44 
45  // while this is negative, no default argument is available
46  constexpr int default_parameter_position = default_arg_count - user_parameter_count - 1;
47 
48  std::vector<std::unique_ptr<StuffBase>> stuff;
49  info.GetReturnValue().
50  Set(v8toolkit::CastToJS<ReturnType>()(info.GetIsolate(),
51  run_function(function, info, std::forward<InitialArg>(initial_arg),
52  std::forward<Args>(
54  Args>().template operator()<ArgIndexes - default_arg_count>(info, i, stuff, default_args_tuple))...)));
55 }
56 };
57 
58 
59 template<class InitialArg, class... Args>
60 struct CallCallable<func::function<void(InitialArg, Args...)>, InitialArg> {
61 
62 template<int default_arg_position, class DefaultArgsTuple = std::tuple<>, std::size_t... ArgIndexes>
63 void operator()(func::function<void(InitialArg, Args...)> & function,
64  const v8::FunctionCallbackInfo<v8::Value> & info,
65  InitialArg initial_arg,
66  std::index_sequence<ArgIndexes...>,
67  DefaultArgsTuple const & default_args_tuple = DefaultArgsTuple()) {
68 
69  int i = 0;
70  constexpr auto default_arg_count = std::tuple_size<DefaultArgsTuple>::value;
71 
72  std::vector<std::unique_ptr<StuffBase>> stuff;
73  run_function(function, info, std::forward<InitialArg>(initial_arg),
74  std::forward<Args>(ParameterBuilder<Args>().template operator()<ArgIndexes - default_arg_count - 1>(info, i, stuff,
75  default_args_tuple))...);
76 
77 }
78 };
79 
80 
81 /**
82  * CallCallable for a normal function which has a non-void return type
83  */
84 template<class ReturnType, class... Args>
85 struct CallCallable<func::function<ReturnType(Args...)>> {
86 using NonConstReturnType = std::remove_const_t<ReturnType>;
87 
88 template<class... Ts, class DefaultArgsTuple = std::tuple<>, std::size_t... ArgIndexes>
89 void operator()(func::function<ReturnType(Args...)> & function,
90  const v8::FunctionCallbackInfo<v8::Value> & info,
91  std::index_sequence<ArgIndexes...>,
92  DefaultArgsTuple && default_args_tuple = DefaultArgsTuple(),
93  bool return_most_derived = false) {
94 
95  int i = 0;
96 
97  constexpr int user_parameter_count = sizeof...(Args);
98  constexpr int default_arg_count = std::tuple_size<std::remove_reference_t<DefaultArgsTuple>>::value;
99 
100  // while this is negative, no default argument is available
101 
102  // if there are 3 parameters, 1 default parameter (3-1=2), calls to ParameterBuilder will have positions:
103  // 0 - 2 = -2 (no default available)
104  // 1 - 2 = -1 (no default available)
105  // 2 - 2 = 0 (lookup at std::get<0>(default_args_tuple)
106  constexpr int minimum_user_parameters_required = user_parameter_count - default_arg_count;
107 
108 
109 
110  std::vector<std::unique_ptr<StuffBase>> stuff;
111 
112  info.GetReturnValue().Set(v8toolkit::CastToJS<std::remove_reference_t<ReturnType>>()(info.GetIsolate(),
113  run_function(function, info, std::forward<Args>(
114  ParameterBuilder<Args>().template operator()
115  <(((int)ArgIndexes) - minimum_user_parameters_required), DefaultArgsTuple> (info, i,
116  stuff, std::move(default_args_tuple)
117  ))...)));
118 }
119 };
120 
121 
122 /**
123  * call callable for a normal function with a void return
124  */
125 template<class... Args>
126 struct CallCallable<func::function<void(Args...)>> {
127 
128 template<class DefaultArgsTuple = std::tuple<>, std::size_t... ArgIndexes>
129 void operator()(func::function<void(Args...)> & function,
130  const v8::FunctionCallbackInfo<v8::Value> & info,
131  std::index_sequence<ArgIndexes...>,
132  DefaultArgsTuple && default_args_tuple = DefaultArgsTuple()) {
133 
134  int i = 0;
135 
136  constexpr int user_parameter_count = sizeof...(Args);
137  constexpr int default_arg_count = std::tuple_size<DefaultArgsTuple>::value;
138 
139  // while this is negative, no default argument is available
140 
141  // if there are 3 parameters, 1 default parameter (3-1=2), calls to ParameterBuilder will have positions:
142  // 0 - 2 = -2 (no default available)
143  // 1 - 2 = -1 (no default available)
144  // 2 - 2 = 0 (lookup at std::get<0>(default_args_tuple)
145  constexpr int minimum_user_parameters_required = user_parameter_count - default_arg_count;
146 
147  std::vector<std::unique_ptr<StuffBase>> stuff;
148  run_function(function, info,
149  std::forward<Args>(ParameterBuilder<Args>().
150  template operator()<(((int)ArgIndexes) - minimum_user_parameters_required), DefaultArgsTuple>(info, i, stuff, std::move(default_args_tuple)))...);
151 }
152 };
153 
154 
155 /**
156  * CallCallable for a function directly taking a v8::FunctionCallbackInfo
157  * This requires the function to do everything itself in terms of parsing parameters
158  */
159 template<>
160 struct CallCallable<func::function<void(const v8::FunctionCallbackInfo<v8::Value>&)>> {
161 
162  template<class DefaultArgsTuple = std::tuple<>, std::size_t... ArgIndexes>
163  void operator()(func::function<void(const v8::FunctionCallbackInfo<v8::Value> &)> & function,
164  const v8::FunctionCallbackInfo<v8::Value> & info,
165  std::index_sequence<ArgIndexes...>,
166  DefaultArgsTuple const & default_args_tuple = DefaultArgsTuple()) {
167  static_assert(std::is_same<DefaultArgsTuple, std::tuple<>>::value,
168  "function taking a v8::FunctionCallbackInfo object cannot have default parameters");
169  function(info);
170  }
171 };
172 
173 
174 } // v8toolkit
void operator()(func::function< ReturnType(Args...)> &function, const v8::FunctionCallbackInfo< v8::Value > &info, std::index_sequence< ArgIndexes... >, DefaultArgsTuple &&default_args_tuple=DefaultArgsTuple(), bool return_most_derived=false)
Definition: call_callable.h:89
void operator()(func::function< void(const v8::FunctionCallbackInfo< v8::Value > &)> &function, const v8::FunctionCallbackInfo< v8::Value > &info, std::index_sequence< ArgIndexes... >, DefaultArgsTuple const &default_args_tuple=DefaultArgsTuple())
void operator()(func::function< void(Args...)> &function, const v8::FunctionCallbackInfo< v8::Value > &info, std::index_sequence< ArgIndexes... >, DefaultArgsTuple &&default_args_tuple=DefaultArgsTuple())
internal::ArgsMatcher< InnerMatcher > Args(const InnerMatcher &matcher)
auto run_function(func::function< ReturnType(Args...)> &function, const v8::FunctionCallbackInfo< v8::Value > &info, Ts &&...ts) -> ReturnType
Definition: v8helpers.h:90
void operator()(func::function< void(InitialArg, Args...)> &function, const v8::FunctionCallbackInfo< v8::Value > &info, InitialArg initial_arg, std::index_sequence< ArgIndexes... >, DefaultArgsTuple const &default_args_tuple=DefaultArgsTuple())
Definition: call_callable.h:63
void operator()(func::function< ReturnType(InitialArg, Args...)> &function, const v8::FunctionCallbackInfo< v8::Value > &info, InitialArg initial_arg, std::index_sequence< ArgIndexes... >, DefaultArgsTuple const &default_args_tuple=DefaultArgsTuple())
Definition: call_callable.h:34
const T & move(const T &t)
Definition: gtest-port.h:1317