v8toolkit  0.0.1
Utility library for embedding V8 Javascript engine in a c++ program
casts.hpp
Go to the documentation of this file.
1 #ifndef CASTS_HPP
2 #define CASTS_HPP
3 
4 #include <assert.h>
5 
6 #include <type_traits>
7 #include <string>
8 #include <vector>
9 #include <map>
10 #include <unordered_map>
11 #include <list>
12 #include <deque>
13 #include <array>
14 #include <memory>
15 #include <utility>
16 #include <set>
17 #include "v8.h"
18 #include "wrapped_class_base.h"
19 #include "v8helpers.h"
20 
21 namespace v8toolkit {
22 
23 
24 // always returns false, but can be used to make something dependent
25 template<class T>
26 struct always_false : public std::false_type {};
27 
28 template <class T> constexpr bool always_false_v = always_false<T>::value;
29 
30 
31 template<class T, class = void>
32 struct is_wrapped_type : public std::false_type {};
33 
34 template<class T>
35 struct is_wrapped_type<T, std::enable_if_t<std::is_base_of<v8toolkit::WrappedClassBase, T>::value>> : public std::true_type {};
36 
37 
38 template<class T>
40 
41 template<typename T, class = void>
42 struct CastToNative;
43 
44 template<class T, class = void>
46 
47 template<class T>
48 struct cast_to_native_supports_default_value<T, void_t<std::result_of_t<CastToNative<T>(v8::Isolate *)>>> : public std::true_type {};
49 
51 
52 
53 // if it's any compination of a reference to a pointer to a wrapped type
54 template<class T>
55 constexpr bool is_wrapped_typeish_v =
57  std::remove_pointer_t<
58  std::remove_reference_t<T>
59  >
60  >::value;
61 
62 
63  // if a value to send to a macro has a comma in it, use this instead so it is parsed as a comma character in the value
64  // and not separating another parameter to the template
65 #define V8TOOLKIT_COMMA ,
66 
67 
68  // add inside CastToNative::operator() to have it handle values that are functions
69 #define HANDLE_FUNCTION_VALUES \
70  { \
71  if (value->IsFunction()) { \
72  value = v8toolkit::call_simple_javascript_function(isolate, v8::Local<v8::Function>::Cast(value)); \
73  } \
74  }
75 
76 
77 #define CAST_TO_NATIVE_CLASS_ONLY(TYPE) \
78 template<> \
79  struct v8toolkit::CastToNative<TYPE> { \
80  TYPE operator()(v8::Isolate * isolate, v8::Local<v8::Value> value) const; \
81  static constexpr bool callable(){return true;} /* It wouldn't be selected if it weren't callable */ \
82 };
83 
84 
85 #define CAST_TO_NATIVE_CODE(TYPE, CODE) \
86  TYPE CastToNative<TYPE>::operator()(v8::Isolate * isolate, v8::Local<v8::Value> value) const CODE
87 
88 
89 #define CAST_TO_NATIVE(TYPE, CODE) \
90  CAST_TO_NATIVE_CLASS_ONLY(TYPE) \
91  inline CAST_TO_NATIVE_CODE(TYPE, CODE)
92 
93 
94 
95 
96 #define CAST_TO_JS(TYPE, FUNCTION_BODY) \
97 template<> \
98  struct v8toolkit::CastToJS<TYPE> { \
99  v8::Local<v8::Value> operator()(v8::Isolate * isolate, TYPE const & value) const FUNCTION_BODY \
100 };
101 
102 /**
103 * Casts from a boxed Javascript type to a native type
104 */
105 template<typename T, class>
106 struct CastToNative {
107  template<class U = T> // just to make it dependent so the static_asserts don't fire before `callable` can be called
108  void operator()(v8::Isolate * isolate, v8::Local<v8::Value> value) const {
109  static_assert(!std::is_pointer<T>::value, "Cannot CastToNative to a pointer type of an unwrapped type");
110  static_assert(!(std::is_lvalue_reference<T>::value && !std::is_const<std::remove_reference_t<T>>::value),
111  "Cannot CastToNative to a non-const "
112  "lvalue reference of an unwrapped type because there is no lvalue variable to send");
113  static_assert(!is_wrapped_type_v<T>,
114  "CastToNative<SomeWrappedType> shouldn't fall through to this specialization");
115  static_assert(always_false_v<T>, "Invalid CastToNative configuration");
116  }
117  static constexpr bool callable(){return false;}
118 };
119 
120 
121 //template<class T>
122 //struct is_wrapped_type<T, std::enable_if_t<std::is_reference<
123 // typename std::result_of_t<
124 // CastToNative<
125 // std::remove_pointer_t<
126 // std::remove_reference_t<T>
127 // > /* remove_pointer */
128 // >(v8::Isolate*, v8::Local<v8::Value>) /* CastToNative */
129 // > /* result_of */
130 //>::value>> : public std::true_type {};
131 
132 
133 
134 template<>
135 struct CastToNative<void> {
136  void operator()(v8::Isolate * isolate, v8::Local<v8::Value> value) const {}
137  static constexpr bool callable(){return true;}
138 };
139 
140 
141 CAST_TO_NATIVE(bool, {HANDLE_FUNCTION_VALUES; return static_cast<bool>(value->ToBoolean()->Value());});
142 
143 
144 
145 // integers
146 CAST_TO_NATIVE(long long, {HANDLE_FUNCTION_VALUES; return static_cast<long long>(value->ToInteger()->Value());});
147 CAST_TO_NATIVE(unsigned long long, {HANDLE_FUNCTION_VALUES; return static_cast<unsigned long long>(value->ToInteger()->Value());});
148 
149 CAST_TO_NATIVE(long, {HANDLE_FUNCTION_VALUES; return static_cast<long>(value->ToInteger()->Value());});
150 CAST_TO_NATIVE(unsigned long, {HANDLE_FUNCTION_VALUES; return static_cast<unsigned long>(value->ToInteger()->Value());});
151 
152 CAST_TO_NATIVE(int, {HANDLE_FUNCTION_VALUES; return static_cast<int>(value->ToInteger()->Value());});
153 CAST_TO_NATIVE(unsigned int, {HANDLE_FUNCTION_VALUES; return static_cast<unsigned int>(value->ToInteger()->Value());});
154 
155 CAST_TO_NATIVE(short, {HANDLE_FUNCTION_VALUES; return static_cast<short>(value->ToInteger()->Value());});
156 CAST_TO_NATIVE(unsigned short, {HANDLE_FUNCTION_VALUES; return static_cast<unsigned short>(value->ToInteger()->Value());});
157 
158 CAST_TO_NATIVE(char, {HANDLE_FUNCTION_VALUES; return static_cast<char>(value->ToInteger()->Value());});
159 CAST_TO_NATIVE(unsigned char, {HANDLE_FUNCTION_VALUES; return static_cast<unsigned char>(value->ToInteger()->Value());});
160 
161 CAST_TO_NATIVE(wchar_t, {HANDLE_FUNCTION_VALUES; return static_cast<wchar_t>(value->ToInteger()->Value());});
162 CAST_TO_NATIVE(char16_t, {HANDLE_FUNCTION_VALUES; return static_cast<char16_t>(value->ToInteger()->Value());});
163 
164 CAST_TO_NATIVE(char32_t, {HANDLE_FUNCTION_VALUES; return static_cast<char32_t>(value->ToInteger()->Value());});
165 
166 
167 
168 
169 template<class... Ts, std::size_t... Is>
170 std::tuple<Ts...> cast_to_native_tuple_helper(v8::Isolate *isolate, v8::Local<v8::Array> array, std::tuple<Ts...>, std::index_sequence<Is...>) {
171  return std::tuple<Ts...>(CastToNative<Ts>()(isolate, array->Get(Is))...);
172 }
173 
174 template<class... Ts>
175 struct CastToNative<std::tuple<Ts...>>
176 {
177  std::tuple<Ts...> operator()(v8::Isolate *isolate, v8::Local<v8::Value> value) const {
178  if (!value->IsArray()) {
179  throw v8toolkit::CastException(fmt::format("CastToNative tried to create a {} object but was not given a JavaScript array", demangle<std::tuple<Ts...>>()));
180  }
182 
183  return cast_to_native_tuple_helper(isolate, array, std::tuple<Ts...>(), std::index_sequence_for<Ts...>());
184  }
185  static constexpr bool callable(){return true;}
186 
187 
188 };
189 
190 // If the type returns an rvalue, then the the const version is the same as the non-const version
191 template<class T>
192 struct CastToNative<T const,
193  std::enable_if_t<!is_wrapped_type_v<T>>> {
194  T operator()(v8::Isolate * isolate, v8::Local<v8::Value> value) const {
195  return CastToNative<T>()(isolate, value);
196  }
197 };
198 
199 
200 // A T const & can take an rvalue, so send it one, since an actual object isn't available for non-wrapped types
201 template<class T>
202 struct CastToNative<T const &, std::enable_if_t<!is_wrapped_type_v<T>>> {
203  T operator()(v8::Isolate * isolate, v8::Local<v8::Value> value) const {
204  return CastToNative<T const>()(isolate, value);
205  }
206  static constexpr bool callable(){return true;}
207 
208 };
209 
210 // A T && can take an rvalue, so send it one, since a previously existing object isn't available for non-wrapped types
211 template<class T>
212 struct CastToNative<T &&, std::enable_if_t<!is_wrapped_type_v<T>>> {
213  T operator()(v8::Isolate * isolate, v8::Local<v8::Value> value) const {
214  return CastToNative<T const>()(isolate, value);
215  }
216  static constexpr bool callable(){return true;}
217 
218 };
219 
220 
221 
222 template<template<class,class> class ContainerTemplate, class FirstT, class SecondT>
223 ContainerTemplate<FirstT, SecondT> pair_type_helper(v8::Isolate * isolate, v8::Local<v8::Value> value) {
225  if (value->IsArray()) {
226  auto length = get_array_length(isolate, value);
227  if (length != 2) {
228  auto error = fmt::format("Array to std::pair must be length 2, but was {}", length);
229  isolate->ThrowException(v8::String::NewFromUtf8(isolate, error.c_str()));
230  throw v8toolkit::CastException(error);
231  }
232  auto context = isolate->GetCurrentContext();
233  auto array = get_value_as<v8::Array>(value);
234  auto first = array->Get(context, 0).ToLocalChecked();
235  auto second = array->Get(context, 1).ToLocalChecked();
236  return std::pair<FirstT, SecondT>(v8toolkit::CastToNative<FirstT>()(isolate, first),
237  v8toolkit::CastToNative<SecondT>()(isolate, second));
238 
239  } else {
240  auto error = fmt::format("CastToNative<std::pair<T>> requires an array but instead got %s\n", stringify_value(isolate, value));
241  std::cout << error << std::endl;
242  throw v8toolkit::CastException(error);
243  }
244 }
245 
246 
247 template<class FirstT, class SecondT>
248 struct v8toolkit::CastToNative<std::pair<FirstT, SecondT>>{
249  std::pair<FirstT, SecondT> operator()(v8::Isolate * isolate, v8::Local<v8::Value> value) const {
250  return pair_type_helper<std::pair, FirstT, SecondT>(isolate, value);
251  }
252 };
253 
254 
255 CAST_TO_NATIVE(float, {HANDLE_FUNCTION_VALUES; return static_cast<float>(value->ToNumber()->Value());});
256 CAST_TO_NATIVE(double, {HANDLE_FUNCTION_VALUES; return static_cast<double>(value->ToNumber()->Value());});
257 CAST_TO_NATIVE(long double, {HANDLE_FUNCTION_VALUES; return static_cast<long double>(value->ToNumber()->Value());});
258 
259 
260 
261 template<>
262 struct CastToNative<v8::Local<v8::Function>> {
263  v8::Local<v8::Function> operator()(v8::Isolate * isolate, v8::Local<v8::Value> value) const {
264  if(value->IsFunction()) {
265  return v8::Local<v8::Function>::Cast(value);
266  } else {
267  throw CastException(fmt::format(
268  "CastToNative<v8::Local<v8::Function>> requires a javascript function but instead got '{}'",
269  stringify_value(isolate, value)));
270  }
271  }
272  static constexpr bool callable(){return true;}
273 
274 };
275 
276 /**
277  * char * and const char * are the only types that don't actually return their own type. Since a buffer is needed
278  * to store the string, a std::unique_ptr<char[]> is returned.
279  */
280 template<>
281 struct CastToNative<char *> {
282  std::unique_ptr<char[]> operator()(v8::Isolate * isolate, v8::Local<v8::Value> value) const {
284  return std::unique_ptr<char[]>(strdup(*v8::String::Utf8Value(value)));
285  }
286  static constexpr bool callable(){return true;}
287 
288 };
289 template<>
290 struct CastToNative<const char *> {
291  std::unique_ptr<char[]> operator()(v8::Isolate * isolate, v8::Local<v8::Value> value) const {
293  return CastToNative<char *>()(isolate, value);
294  }
295  static constexpr bool callable(){return true;}
296 
297 };
298 
301  return std::string(*v8::String::Utf8Value(value));
302 });
303 
304 
305 template<template<class,class...> class VectorTemplate, class T, class... Rest>
306 auto vector_type_helper(v8::Isolate * isolate, v8::Local<v8::Value> value) ->
307  VectorTemplate<std::remove_reference_t<std::result_of_t<CastToNative<T>(v8::Isolate *, v8::Local<v8::Value>)>>, Rest...>
308 {
309  using ValueType = std::remove_reference_t<std::result_of_t<CastToNative<T>(v8::Isolate *, v8::Local<v8::Value>)>>;
310  static_assert(!std::is_reference<ValueType>::value, "vector-like value type cannot be reference");
311  using ResultType = VectorTemplate<ValueType, Rest...>;
313  auto context = isolate->GetCurrentContext();
314  ResultType v;
315  if (value->IsArray()) {
316  auto array = v8::Local<v8::Object>::Cast(value);
317  auto array_length = get_array_length(isolate, array);
318  for (int i = 0; i < array_length; i++) {
319  auto value = array->Get(context, i).ToLocalChecked();
320  v.emplace_back(std::forward<T>(CastToNative<T>()(isolate, value)));
321  }
322  } else {
323  throw CastException(fmt::format("CastToNative<std::vector-like<{}>> requires an array but instead got JS: '{}'",
324  demangle<T>(),
325  stringify_value(isolate, value)));
326  }
327  return v;
328 }
329 
330 
331 template<template<class,class...> class SetTemplate, class T, class... Rest>
332 auto set_type_helper(v8::Isolate * isolate, v8::Local<v8::Value> value) ->
333 SetTemplate<std::remove_reference_t<std::result_of_t<CastToNative<T>(v8::Isolate *, v8::Local<v8::Value>)>>, Rest...>
334 {
335  using ValueType = std::remove_reference_t<std::result_of_t<CastToNative<T>(v8::Isolate *, v8::Local<v8::Value>)>>;
336  static_assert(!std::is_reference<ValueType>::value, "Set-like value type cannot be reference");
337  using ResultType = SetTemplate<ValueType, Rest...>;
339  auto context = isolate->GetCurrentContext();
340  ResultType set;
341  if (value->IsArray()) {
342  auto array = v8::Local<v8::Object>::Cast(value);
343  auto array_length = get_array_length(isolate, array);
344  for (int i = 0; i < array_length; i++) {
345  auto value = array->Get(context, i).ToLocalChecked();
346  set.emplace(std::forward<T>(CastToNative<T>()(isolate, value)));
347  }
348  } else {
349  throw CastException(fmt::format("CastToNative<std::vector-like<{}>> requires an array but instead got JS: '{}'",
350  demangle<T>(),
351  stringify_value(isolate, value)));
352  }
353  return set;
354 }
355 
356 
357 
358 //Returns a vector of the requested type unless CastToNative on ElementType returns a different type, such as for char*, const char *
359 // Must make copies of all the values
360 template<class T, class... Rest>
361 struct CastToNative<std::vector<T, Rest...>, std::enable_if_t<std::is_copy_constructible<T>::value>> {
362  using ResultType = std::vector<std::remove_reference_t<std::result_of_t<CastToNative<T>(v8::Isolate *, v8::Local<v8::Value>)>>, Rest...>;
363 
364  ResultType operator()(v8::Isolate *isolate, v8::Local<v8::Value> value) const {
365  return vector_type_helper<std::vector, T, Rest...>(isolate, value);
366  }
367  static constexpr bool callable(){return true;}
368 
369 };
370 
371 // can move the elements if the underlying JS objects own their memory or can do copies if copyable, othewrise throws
372 // SFINAE on this is required for disambiguation, even though it can't ever catch anything
373 template<class T, class... Rest>
374 struct CastToNative<std::vector<T, Rest...> &&, std::enable_if_t<!is_wrapped_type_v<std::vector<T, Rest...>>>> {
375  using ResultType = std::vector<std::remove_reference_t<std::result_of_t<CastToNative<T>(v8::Isolate *, v8::Local<v8::Value>)>>, Rest...>;
376 
377  ResultType operator()(v8::Isolate *isolate, v8::Local<v8::Value> value) const {
378  return vector_type_helper<std::vector, std::add_rvalue_reference_t<T>, Rest...>(isolate, value);
379  }
380  static constexpr bool callable(){return true;}
381 
382 };
383 
384 
385 template<class T, class... Rest>
386 struct CastToNative<std::set<T, Rest...>, std::enable_if_t<!is_wrapped_type_v<std::set<T, Rest...>>>> {
387  using ResultType = std::set<std::remove_reference_t<std::result_of_t<CastToNative<T>(v8::Isolate *, v8::Local<v8::Value>)>>, Rest...>;
388 
389  ResultType operator()(v8::Isolate *isolate, v8::Local<v8::Value> value) const {
390  return set_type_helper<std::set, std::add_rvalue_reference_t<T>, Rest...>(isolate, value);
391  }
392  static constexpr bool callable(){return true;}
393 
394 };
395 
396 
397 
398 
399 
400 
401 
402 // Cast a copyable, standard type to a unique_ptr
403 template<class T, class... Rest>
404 struct CastToNative<std::unique_ptr<T, Rest...>,
405  std::enable_if_t<
406  std::is_copy_constructible<T>::value &&
407  !is_wrapped_type_v<T>
408  >// end enable_if_t
409 >// end template
410 {
411  std::unique_ptr<T, Rest...> operator()(v8::Isolate * isolate, v8::Local<v8::Value> value) const {
412  return std::unique_ptr<T, Rest...>(new T(CastToNative<T>()(isolate, value)));
413  }
414  static constexpr bool callable(){return true;}
415 
416 };
417 
418 
419 template<class T>
420 struct CastToNative<v8::Local<T>> {
421  v8::Local<T> operator()(v8::Isolate * isolate, v8::Local<T> value) const {
422  return value;
423  }
424  static constexpr bool callable(){return true;}
425 
426 };
427 
428 // cannot cast a non-copyable, standard type to a unique_ptr
429 template<class T, class... Rest>
430 struct CastToNative<std::unique_ptr<T, Rest...>, std::enable_if_t<!std::is_copy_constructible<T>::value && !is_wrapped_type_v<T>>>; // INTENTIONALLY NOT IMPLEMENTED
431 
432 template<template<class,class,class...> class ContainerTemplate, class Key, class Value, class... Rest>
433 ContainerTemplate<Key, Value, Rest...> map_type_helper(v8::Isolate * isolate, v8::Local<v8::Value> value) {
434 
435  // MapType operator()(v8::Isolate * isolate, v8::Local<v8::Value> value) const {
436  if (!value->IsObject()) {
437  throw CastException(
438  fmt::format("Javascript Object type must be passed in to convert to std::map - instead got {}",
439  stringify_value(isolate, value)));
440  }
441 
442  auto context = isolate->GetCurrentContext();
443 
444  ContainerTemplate<Key, Value, Rest...> results;
445  for_each_own_property(context, value->ToObject(),
446  [isolate, &results](v8::Local<v8::Value> key, v8::Local<v8::Value> value) {
447  results.emplace(v8toolkit::CastToNative<Key>()(isolate, key),
448  v8toolkit::CastToNative<Value>()(isolate, value));
449  });
450  return results;
451 }
452 
453 template<class Key, class Value, class... Args>
454 struct CastToNative<std::map<Key, Value, Args...>> {
455  std::map<Key, Value, Args...> operator()(v8::Isolate * isolate, v8::Local<v8::Value> value) const {
456  return map_type_helper<std::map, Key, Value, Args...>(isolate, value);
457  }
458  static constexpr bool callable(){return true;}
459 
460 };
461 
462 template<template<class,class,class...> class ContainerTemplate, class Key, class Value, class... Rest>
463 ContainerTemplate<Key, Value, Rest...> multimap_type_helper(v8::Isolate * isolate, v8::Local<v8::Value> value) {
464 
465  if (!value->IsObject()) {
466  throw CastException(
467  fmt::format("Javascript Object type must be passed in to convert to std::map - instead got {}",
468  stringify_value(isolate, value)));
469  }
470 
471  auto context = isolate->GetCurrentContext();
472 
473  ContainerTemplate<Key, Value, Rest...> results;
474  for_each_own_property(context, value->ToObject(),
476  v8toolkit::for_each_value(context, value, [&](v8::Local<v8::Value> sub_value){
477  results.emplace(v8toolkit::CastToNative<Key>()(isolate, key),
478  v8toolkit::CastToNative<Value>()(isolate, sub_value));
479  });
480  });
481  return results;
482 }
483 
484 
485 
486 template<class Key, class Value, class... Args>
487 struct CastToNative<std::multimap<Key, Value, Args...>> {
488 
489  using ResultType = std::multimap<Key, Value, Args...>;
490 
491  ResultType operator()(v8::Isolate * isolate, v8::Local<v8::Value> value) const {
492  return multimap_type_helper<std::multimap, Key, Value, Args...>(isolate, value);
493  }
494  static constexpr bool callable(){return true;}
495 
496 };
497 
498 
499 //
500 
501 
502 /**
503 * Casts from a native type to a boxed Javascript type
504 */
505 
506 template<typename T, class = void>
507 struct CastToJS {
508  static_assert(always_false_v<T>, "Fallback CastToJS template isn't allowed");
509 };
510 
511 
512 template<class T>
513 struct CastToJS<T &, std::enable_if_t<!is_wrapped_type_v<T>>> {
514  v8::Local<v8::Value> operator()(v8::Isolate * isolate, T const & value) const {
515  return CastToJS<T>()(isolate, value);
516  }
517 };
518 
519 
520 template<class T>
521 struct CastToJS<T *, std::enable_if_t<!is_wrapped_type_v<T>>> {
522  v8::Local<v8::Value> operator()(v8::Isolate * isolate, T * const value) const {
523  if (value == nullptr) {
524  return v8::Undefined(isolate);
525  } else {
526  return CastToJS<T>()(isolate, *value);
527  }
528  }
529 };
530 
531 
532 
533 /**
534  * For non-wrapped types, the result of casting to a const type is the same as casting to the non-const type. A copy.
535  * @tparam T
536  */
537 template<class T>
538 struct CastToJS<T const,
539  std::enable_if_t<!is_wrapped_type_v<T>> // enable_if
540 > {
541  v8::Local<v8::Value> operator()(v8::Isolate * isolate, T const & value) const {
542  return v8toolkit::CastToJS<T>()(isolate, value);
543  }
544 };
545 
546 
547 
548 
549 CAST_TO_JS(bool, {return v8::Boolean::New(isolate, value);});
550 
551 //TODO: Should all these operator()'s be const?
552 // integers
553 CAST_TO_JS(char, {return v8::Integer::New(isolate, value);});
554 CAST_TO_JS(unsigned char, {return v8::Integer::New(isolate, value);});
555 
556 CAST_TO_JS(wchar_t, {return v8::Number::New(isolate, value);});
557 CAST_TO_JS(char16_t, {return v8::Integer::New(isolate, value);});
558 CAST_TO_JS(char32_t, {return v8::Integer::New(isolate, value);});
559 CAST_TO_JS(short, {return v8::Integer::New(isolate, value);});
560 CAST_TO_JS(unsigned short, {return v8::Integer::New(isolate, value);});
561 
562 
563 
564 CAST_TO_JS(int, {return v8::Number::New(isolate, value);});
565 
566 CAST_TO_JS(unsigned int, {return v8::Number::New(isolate, value);});
567 CAST_TO_JS(long, {return v8::Number::New(isolate, value);});
568 
569 CAST_TO_JS(unsigned long, {return v8::Number::New(isolate, value);});
570 CAST_TO_JS(long long, {return v8::Number::New(isolate, static_cast<double>(value));});
571 CAST_TO_JS(unsigned long long, {return v8::Number::New(isolate, static_cast<double>(value));});
572 
573 
574 
575 // floats
576 CAST_TO_JS(float, {return v8::Number::New(isolate, value);});
577 CAST_TO_JS(double, {return v8::Number::New(isolate, value);});
578 CAST_TO_JS(long double, {return v8::Number::New(isolate, value);});
579 
580 
581 CAST_TO_JS(std::string, {return v8::String::NewFromUtf8(isolate, value.c_str(), v8::String::kNormalString, value.length());});
582 
583 CAST_TO_JS(char *, {return v8::String::NewFromUtf8(isolate, value);});
584 CAST_TO_JS(char const *, {return v8::String::NewFromUtf8(isolate, value);});
585 
586 template<class T>
587 struct CastToJS<T**> {
588  v8::Local<v8::Value> operator()(v8::Isolate * isolate, const T** multi_pointer) {
589  return CastToJS<T*>(isolate, *multi_pointer);
590  }
591 };
592 
593 
594 template<class R, class... Params>
595 struct CastToJS<std::function<R(Params...)>> {
596  v8::Local<v8::Value> operator()(v8::Isolate * isolate, std::function<R(Params...)> & function) {
597  return v8::String::NewFromUtf8(isolate, "CastToJS of std::function not supported yet");
598  }
599 };
600 
601 
602 
603 /**
604 * Special passthrough type for objects that want to take javascript object objects directly
605 */
606 template<class T>
607 struct CastToJS<v8::Local<T>> {
608  v8::Local<T> operator()(v8::Isolate * isolate, v8::Local<T> value){
609  //return v8::Local<v8::Value>::New(isolate, object);
610  return value;
611  }
612  v8::Local<T> operator()(v8::Isolate * isolate, v8::Global<T> && value){
613  //return v8::Local<v8::Value>::New(isolate, object);
614  return value.Get(isolate);
615  }
616 };
617 
618 
619 
620 
621 template<class T>
622 struct CastToJS<v8::Global<T>> {
623  v8::Local<T> operator()(v8::Isolate * isolate, v8::Local<T> & value) {
624  value;
625  }
626  v8::Local<T> operator()(v8::Isolate * isolate, v8::Global<T> const & value) {
627  return value.Get(isolate);
628  }
629 };
630 
631 
632 
633 
634 // CastToJS<std::pair<>>
635 template<class T1, class T2>
636 struct CastToJS<std::pair<T1, T2>> {
637  v8::Local<v8::Value> operator()(v8::Isolate *isolate, std::pair<T1, T2> const & pair);
638  v8::Local<v8::Value> operator()(v8::Isolate *isolate, std::pair<T1, T2> && pair) {
639  return this->operator()(isolate, pair);
640  }
641 };
642 
643 
644 template<template<class, class, class...> class MapTemplate, class KeyType, class ValueType, class ReferenceTypeIndicator, class... Rest>
645 v8::Local<v8::Value> cast_to_js_map_helper(v8::Isolate * isolate, MapTemplate<KeyType, ValueType, Rest...> const & map) {
646  assert(isolate->InContext());
647  auto context = isolate->GetCurrentContext();
648  auto object = v8::Object::New(isolate);
649 
650  using KeyForwardT = std::conditional_t<std::is_rvalue_reference_v<ReferenceTypeIndicator>, std::add_rvalue_reference_t<KeyType>, std::add_lvalue_reference_t<KeyType>>;
651  using ValueForwardT = std::conditional_t<std::is_rvalue_reference_v<ReferenceTypeIndicator>, std::add_rvalue_reference_t<ValueType>, std::add_lvalue_reference_t<ValueType>>;
652 
653 
654  for(auto & pair : map) {
655  (void) object->Set(context,
656  CastToJS<std::remove_reference_t<KeyType>> ()(isolate, std::forward<KeyForwardT> (const_cast<KeyForwardT> (pair.first ))),
657  CastToJS<std::remove_reference_t<ValueType>>()(isolate, std::forward<ValueForwardT>(const_cast<ValueForwardT>(pair.second)))
658  );
659  }
660  return object;
661 }
662 
663 
664 template<template<class...> class VectorTemplate, class ValueType, class... Rest>
665 v8::Local<v8::Value> cast_to_js_vector_helper(v8::Isolate * isolate, VectorTemplate<std::remove_reference_t<ValueType>, Rest...> const & vector) {
666 
667  assert(isolate->InContext());
668  auto context = isolate->GetCurrentContext();
669  auto array = v8::Array::New(isolate);
670 
671  int i = 0;
672  for (auto & element : vector) {
673  (void) array->Set(context, i, CastToJS<std::remove_reference_t<ValueType>>()(isolate, std::forward<ValueType>(const_cast<ValueType>(element))));
674  i++;
675  }
676  return array;
677 }
678 
679 
680 // CastToJS<std::vector<>>
681 template<class T, class... Rest>
682 struct CastToJS<std::vector<T, Rest...>> {
683  v8::Local<v8::Value> operator()(v8::Isolate *isolate, std::vector<T, Rest...> const & vector);
684  v8::Local<v8::Value> operator()(v8::Isolate *isolate, std::vector<T, Rest...> && vector);
685 };
686 
687 
688 // CastToJS<std::list>
689 template<class U, class... Rest>
690 struct CastToJS<std::list<U, Rest...>> {
691  v8::Local<v8::Value> operator()(v8::Isolate *isolate, std::list<U, Rest...> & list);
692  v8::Local<v8::Value> operator()(v8::Isolate *isolate, std::list<U, Rest...> && list) {
693  return this->operator()(isolate, list);
694  }
695 };
696 
697 // CastToJS<std::map>
698 template<class KeyType, class ValueType, class... Rest>
699 struct CastToJS<std::map<KeyType, ValueType, Rest...>> {
700  v8::Local<v8::Value> operator()(v8::Isolate *isolate, std::map<KeyType, ValueType, Rest...> const & map) {
701  return cast_to_js_map_helper<std::map, KeyType, ValueType, int&, Rest...>(isolate, map);
702  }
703 
704  v8::Local<v8::Value> operator()(v8::Isolate *isolate, std::map<KeyType, ValueType, Rest...> && map) {
705  return cast_to_js_map_helper<std::map, KeyType, ValueType, int&&, Rest...>(isolate, map);
706  }
707 
708 };
709 
710 // CastToJS<std::multimap>
711 template<class A, class B, class... Rest>
712 struct CastToJS<std::multimap<A, B, Rest...>> {
713  v8::Local<v8::Value> operator()(v8::Isolate *isolate, std::multimap<A, B, Rest...> & multimap);
714  v8::Local<v8::Value> operator()(v8::Isolate *isolate, std::multimap<A, B, Rest...> && multimap) {
715  return this->operator()(isolate, multimap);
716  }
717 };
718 
719 
720 // CastToJS<std::undordered:map>
721 template<class A, class B, class... Rest>
722 struct CastToJS<std::unordered_map<A, B, Rest...>> {
723  v8::Local<v8::Value> operator()(v8::Isolate *isolate, std::unordered_map<A, B, Rest...> & unorderedmap);
724  v8::Local<v8::Value> operator()(v8::Isolate *isolate, std::unordered_map<A, B, Rest...> && unorderedmap) {
725  return this->operator()(isolate, unorderedmap);
726  }
727 };
728 
729 // CastToJS<std::deque>
730 template<class T, class... Rest>
731 struct CastToJS<std::deque<T, Rest...>> {
732  v8::Local<v8::Value> operator()(v8::Isolate *isolate, std::deque<T, Rest...> & deque);
733  v8::Local<v8::Value> operator()(v8::Isolate *isolate, std::deque<T, Rest...> && deque) {
734  return this->operator()(isolate, deque);
735  }
736 };
737 
738 // CastToJS<std::array>
739 template<class T, std::size_t N>
740 struct CastToJS<std::array<T, N>> {
741  v8::Local<v8::Value> operator()(v8::Isolate *isolate, std::array<T, N> & arr);
742  v8::Local<v8::Value> operator()(v8::Isolate *isolate, std::array<T, N> && arr) {
743  return this->operator()(isolate, arr);
744  }
745 };
746 
747 
748 
749 /**
750  * This is for when a function returns a std::unique - meaning it likely allocated new memory on its own
751  * If this is being sent back to JS, the unique_ptr must release the memory, because the unique_ptr is going to
752  * go out of scope immediately
753  *
754  * These functions are not const because they call unique_ptr::release
755  */
756 template<class T, class... Rest>
757 struct CastToJS<std::unique_ptr<T, Rest...>, std::enable_if_t<!is_wrapped_type_v<T>>> {
758 
759  v8::Local<v8::Value> operator()(v8::Isolate *isolate, std::unique_ptr<T, Rest...> & unique_ptr) {
760  return CastToJS<T>()(isolate, *unique_ptr.get());
761  }
762 
763 
764  v8::Local<v8::Value> operator()(v8::Isolate *isolate, std::unique_ptr<T, Rest...> && unique_ptr) {
765  auto result = CastToJS<T>()(isolate, std::move(*unique_ptr));
766  unique_ptr.reset();
767  return result;
768  }
769 };
770 
771 
772 /**
773  * If a data structure contains a unique_ptr and that is being returned, the unique_ptr should not ::release()
774  * its memory. This is treated just as if the call were returning a T* instead of a unique_ptr<T>
775  */
776 template<class T, class... Rest>
777 struct CastToJS<std::unique_ptr<T, Rest...> &, std::enable_if_t<!is_wrapped_type_v<std::unique_ptr<T, Rest...>>>> {
778  v8::Local<v8::Value> operator()(v8::Isolate *isolate, std::unique_ptr<T, Rest...> const & unique_ptr) {
779 // fprintf(stderr, "**NOT** releasing UNIQUE_PTR MEMORY for ptr type %s\n", demangle<T>().c_str());
780  if (unique_ptr.get() == nullptr) {
781  return v8::Undefined(isolate);
782  } else {
783  return CastToJS<T*>()(isolate, unique_ptr.get());
784  }
785  }
786 };
787 template<class T, class... Rest>
788 struct CastToJS<std::unique_ptr<T, Rest...> const &, std::enable_if_t<!is_wrapped_type_v<std::unique_ptr<T, Rest...> const>>> {
789  v8::Local<v8::Value> operator()(v8::Isolate *isolate, std::unique_ptr<T, Rest...> const & unique_ptr) {
790 // fprintf(stderr, "**NOT** releasing UNIQUE_PTR MEMORY for ptr type %s\n", demangle<T>().c_str());
791 
792  if (unique_ptr.get() == nullptr) {
793  return v8::Undefined(isolate);
794  } else {
795  return CastToJS<T*>()(isolate, unique_ptr.get());
796  }
797  }
798 };
799 
800 
801 
802 template<class T>
803 struct CastToJS<std::shared_ptr<T>> {
804  v8::Local<v8::Value> operator()(v8::Isolate *isolate, std::shared_ptr<T> const & shared_ptr) {
805  return CastToJS<T>()(isolate, *shared_ptr.get());
806  }
807 };
808 
809 
810 
811 
812 template<class T, class... Rest>
813 v8::Local<v8::Value> CastToJS<std::vector<T, Rest...>>::operator()(v8::Isolate *isolate, std::vector<T, Rest...> const & vector) {
814  return cast_to_js_vector_helper<std::vector, T&, Rest...>(isolate, vector);
815 }
816 
817 template<class T, class... Rest>
818 v8::Local<v8::Value> CastToJS<std::vector<T, Rest...>>::operator()(v8::Isolate *isolate, std::vector<T, Rest...> && vector) {
819  return cast_to_js_vector_helper<std::vector, T&&, Rest...>(isolate, vector);
820 }
821 
822 
823 
824 
825 
826 /**
827 * supports lists containing any type also supported by CastToJS to javascript arrays
828 */
829 template<class T, class... Rest> v8::Local<v8::Value>
830 CastToJS<std::list<T, Rest...>>::operator()(v8::Isolate * isolate, std::list<T, Rest...> & list) {
831  assert(isolate->InContext());
832  auto context = isolate->GetCurrentContext();
833  auto array = v8::Array::New(isolate);
834  int i = 0;
835  for (auto & element : list) {
836  (void)array->Set(context, i, CastToJS<T>()(isolate, element));
837  i++;
838  }
839  return array;
840 }
841 
842 
843 
844 
845 template<template<class,class,class...> class MultiMapLike, class A, class B, class... Rest>
846 v8::Local<v8::Object> casttojs_multimaplike(v8::Isolate * isolate, MultiMapLike<A, B, Rest...> const & map) {
847  assert(isolate->InContext());
848  auto context = isolate->GetCurrentContext();
849  auto object = v8::Object::New(isolate);
850  for(auto & pair : map){
851  auto key = CastToJS<A>()(isolate, const_cast<A&>(pair.first));
852  auto value = CastToJS<B>()(isolate, const_cast<B&>(pair.second));
853 
854  // check to see if a value with this key has already been added
855  bool default_value = true;
856  bool object_has_key = object->Has(context, key).FromMaybe(default_value);
857  if(!object_has_key) {
858  // get the existing array, add this value to the end
859  auto array = v8::Array::New(isolate);
860  (void)array->Set(context, 0, value);
861  (void)object->Set(context, key, array);
862  } else {
863  // create an array, add the current value to it, then add it to the object
864  auto existing_array_value = object->Get(context, key).ToLocalChecked();
865  v8::Handle<v8::Array> existing_array = v8::Handle<v8::Array>::Cast(existing_array_value);
866 
867  //find next array position to insert into (is there no better way to push onto the end of an array?)
868  int i = 0;
869  while(existing_array->Has(context, i).FromMaybe(default_value)){i++;}
870  (void)existing_array->Set(context, i, value);
871  }
872  }
873  return object;
874 }
875 
876 /**
877 * supports maps containing any type also supported by CastToJS to javascript arrays
878 * It creates an object of key => [values...]
879 * All values are arrays, even if there is only one value in the array.
880 */
881 template<class A, class B, class... Rest> v8::Local<v8::Value>
882 CastToJS<std::multimap<A, B, Rest...>>::operator()(v8::Isolate * isolate, std::multimap<A, B, Rest...> & map){
883  return casttojs_multimaplike(isolate, map);
884 }
885 
886 
887 
888 
889 
890 
891 template<class T1, class T2> v8::Local<v8::Value>
892 CastToJS<std::pair<T1, T2>>::operator()(v8::Isolate *isolate, std::pair<T1, T2> const & pair) {
893 
894  assert(isolate->InContext());
895  auto context = isolate->GetCurrentContext();
896  auto array = v8::Array::New(isolate);
897  (void) array->Set(context, 0, CastToJS<T1 &>()(isolate, pair.first));
898  (void) array->Set(context, 1, CastToJS<T2 &>()(isolate, pair.second));
899  return array;
900 }
901 
902 
903 
904 
905 template<int position, class T>
907 
908 template<class... Args>
909 struct CastTupleToJS<0, std::tuple<Args...>> {
910  v8::Local<v8::Array> operator()(v8::Isolate * isolate, std::tuple<Args...> & tuple){
911  constexpr int array_position = sizeof...(Args) - 0 - 1;
912 
913  assert(isolate->InContext());
914  auto context = isolate->GetCurrentContext();
915  auto array = v8::Array::New(isolate);
916  using TuplePositionType = typename std::tuple_element<array_position, std::tuple<Args...>>::type;
917 
918  (void)array->Set(context,
919  array_position,
920  CastToJS<TuplePositionType>()(isolate,
921  std::get<array_position>(tuple)));
922  return array;
923  }
924 };
925 
926 template<int position, class... Args>
927 struct CastTupleToJS<position, std::tuple<Args...>> {
928  v8::Local<v8::Array> operator()(v8::Isolate * isolate, std::tuple<Args...> & tuple){
929  constexpr int array_position = sizeof...(Args) - position - 1;
930  using TuplePositionType = typename std::tuple_element<array_position, std::tuple<Args...>>::type;
931 
932  assert(isolate->InContext());
933  auto context = isolate->GetCurrentContext();
934  auto array = CastTupleToJS<position - 1, std::tuple<Args...>>()(isolate, tuple);
935  (void)array->Set(context,
936  array_position,
937  CastToJS<TuplePositionType>()(isolate,
938  std::get<array_position>(tuple)));
939  return array;
940  }
941 };
942 
943 
944 
945 template<class... Args>
946 struct CastToJS<std::tuple<Args...>> {
947  v8::Local<v8::Value> operator()(v8::Isolate *isolate, std::tuple<Args...> tuple) {
948  return CastTupleToJS<sizeof...(Args) - 1, std::tuple<Args...>>()(isolate, tuple);
949  }
950 };
951 
952 
953 /**
954 * supports unordered_maps containing any type also supported by CastToJS to javascript arrays
955 */
956 template<class A, class B, class... Rest> v8::Local<v8::Value>
957 CastToJS<std::unordered_map<A, B, Rest...>>::operator()(v8::Isolate * isolate, std::unordered_map<A, B, Rest...> & map){
958  assert(isolate->InContext());
959  auto context = isolate->GetCurrentContext();
960  auto object = v8::Object::New(isolate);
961  for(auto pair : map){
962  (void)object->Set(context, CastToJS<A&>()(isolate, pair.first), CastToJS<B&>()(isolate, pair.second));
963  }
964  return object;
965 }
966 
967 
968 
969 
970 /**
971 * supports deques containing any type also supported by CastToJS to javascript arrays
972 */
973 template<class T, class... Rest> v8::Local<v8::Value>
974 CastToJS<std::deque<T, Rest...>>::operator()(v8::Isolate * isolate, std::deque<T, Rest...> & deque) {
975  assert(isolate->InContext());
976  auto context = isolate->GetCurrentContext();
977  auto array = v8::Array::New(isolate);
978  auto size = deque.size();
979  for(unsigned int i = 0; i < size; i++) {
980  (void)array->Set(context, i, CastToJS<T>()(isolate, deque.at(i)));
981  }
982  return array;
983 }
984 
985 
986 
987  template<class T, std::size_t N> v8::Local<v8::Value>
988 CastToJS<std::array<T, N>>::operator()(v8::Isolate * isolate, std::array<T, N> & arr) {
989  assert(isolate->InContext());
990  auto context = isolate->GetCurrentContext();
991  auto array = v8::Array::New(isolate);
992  // auto size = arr.size();
993  for(unsigned int i = 0; i < N; i++) {
994  (void)array->Set(context, i, CastToJS<T>()(isolate, arr[i]));
995  }
996  return array;
997 }
998 
999 
1000 
1001 //TODO: forward_list
1002 
1003 //TODO: stack
1004 
1005 
1006 
1007 template<class T, class... Rest>
1008 struct CastToJS<std::set<T, Rest...>> {
1009  v8::Local<v8::Value> operator()(v8::Isolate *isolate, std::set<T, Rest...> const & set) {
1010  return cast_to_js_vector_helper<std::set, T&, Rest...>(isolate, set);
1011  }
1012  v8::Local<v8::Value> operator()(v8::Isolate *isolate, std::set<T, Rest...> && set) {
1013  return cast_to_js_vector_helper<std::set, T&&, Rest...>(isolate, set);
1014  }
1015 };
1016 
1017 
1018 
1019 
1020 
1021 //TODO: unordered_set
1022 
1023 
1024 
1025 
1026 template<class ReturnT, class... Args>
1027 struct CastToNative<std::function<ReturnT(Args...)>> {
1028  std::function<ReturnT(Args...)> operator()(v8::Isolate * isolate, v8::Local<v8::Value> value) const;
1029 };
1030 
1031 } // end namespace v8toolkit
1032 
1033 
1034 #ifdef V8TOOLKIT_ENABLE_EASTL_SUPPORT
1035 #include "casts_eastl.hpp"
1036 #endif
1037 
1038 #endif // CASTS_HPP
Definition: sample.cpp:17
v8::Local< v8::Value > operator()(v8::Isolate *isolate, std::multimap< A, B, Rest... > &&multimap)
Definition: casts.hpp:714
T operator()(v8::Isolate *isolate, v8::Local< v8::Value > value) const
Definition: casts.hpp:213
v8::Local< v8::Value > operator()(v8::Isolate *isolate, std::tuple< Args... > tuple)
Definition: casts.hpp:947
v8::Local< v8::Value > operator()(v8::Isolate *isolate, std::unique_ptr< T, Rest... > const &unique_ptr)
Definition: casts.hpp:778
v8::Local< T > operator()(v8::Isolate *isolate, v8::Local< T > value)
Definition: casts.hpp:608
void for_each_value(const v8::Local< v8::Context > context, const v8::Local< v8::Value > value, Callable callable)
Definition: v8helpers.h:349
ContainerTemplate< FirstT, SecondT > pair_type_helper(v8::Isolate *isolate, v8::Local< v8::Value > value)
Definition: casts.hpp:223
v8::Local< T > operator()(v8::Isolate *isolate, v8::Local< T > value) const
Definition: casts.hpp:421
v8::Local< v8::Value > operator()(v8::Isolate *isolate, std::shared_ptr< T > const &shared_ptr)
Definition: casts.hpp:804
::std::string string
Definition: gtest-port.h:1097
int get_array_length(v8::Isolate *isolate, v8::Local< v8::Value > array_value)
Definition: v8helpers.cpp:85
static constexpr bool callable()
Definition: casts.hpp:137
std::unique_ptr< T, Rest... > operator()(v8::Isolate *isolate, v8::Local< v8::Value > value) const
Definition: casts.hpp:411
v8::Local< v8::Value > operator()(v8::Isolate *isolate, std::function< R(Params...)> &function)
Definition: casts.hpp:596
STL namespace.
v8::Local< v8::Value > operator()(v8::Isolate *isolate, std::set< T, Rest... > const &set)
Definition: casts.hpp:1009
v8::Local< v8::Value > operator()(v8::Isolate *isolate, std::pair< T1, T2 > &&pair)
Definition: casts.hpp:638
static constexpr bool callable()
Definition: casts.hpp:295
std::string stringify_value(v8::Isolate *isolate, const v8::Local< v8::Value > &value, bool show_all_properties=false, std::vector< v8::Local< v8::Value >> &&processed_values=std::vector< v8::Local< v8::Value >>{})
Definition: v8helpers.cpp:187
ContainerTemplate< Key, Value, Rest... > multimap_type_helper(v8::Isolate *isolate, v8::Local< v8::Value > value)
Definition: casts.hpp:463
T operator()(v8::Isolate *isolate, v8::Local< v8::Value > value) const
Definition: casts.hpp:194
v8::Local< v8::Value > operator()(v8::Isolate *isolate, std::list< U, Rest... > &&list)
Definition: casts.hpp:692
v8::Local< v8::Value > operator()(v8::Isolate *isolate, std::map< KeyType, ValueType, Rest... > &&map)
Definition: casts.hpp:704
v8::Local< v8::Value > operator()(v8::Isolate *isolate, T *const value) const
Definition: casts.hpp:522
CAST_TO_NATIVE(bool,{HANDLE_FUNCTION_VALUES;return static_cast< bool >(value->ToBoolean() ->Value());})
bool_constant< true > true_type
Definition: gtest-port.h:2210
v8::Local< v8::Value > operator()(v8::Isolate *isolate, T const &value) const
Definition: casts.hpp:541
std::tuple< Ts... > operator()(v8::Isolate *isolate, v8::Local< v8::Value > value) const
Definition: casts.hpp:177
auto vector_type_helper(v8::Isolate *isolate, v8::Local< v8::Value > value) -> VectorTemplate< std::remove_reference_t< std::result_of_t< CastToNative< T >(v8::Isolate *, v8::Local< v8::Value >)>>, Rest... >
Definition: casts.hpp:306
internal::ArgsMatcher< InnerMatcher > Args(const InnerMatcher &matcher)
bool_constant< false > false_type
Definition: gtest-port.h:2209
CAST_TO_JS(bool,{return v8::Boolean::New(isolate, value);})
std::unique_ptr< char[]> operator()(v8::Isolate *isolate, v8::Local< v8::Value > value) const
Definition: casts.hpp:291
void void_t
Definition: v8helpers.h:62
std::map< Key, Value, Args... > operator()(v8::Isolate *isolate, v8::Local< v8::Value > value) const
Definition: casts.hpp:455
v8::Local< v8::Value > operator()(v8::Isolate *isolate, std::unique_ptr< T, Rest... > const &unique_ptr)
Definition: casts.hpp:789
auto set_type_helper(v8::Isolate *isolate, v8::Local< v8::Value > value) -> SetTemplate< std::remove_reference_t< std::result_of_t< CastToNative< T >(v8::Isolate *, v8::Local< v8::Value >)>>, Rest... >
Definition: casts.hpp:332
Definition: sample.cpp:29
v8::Local< v8::Value > operator()(v8::Isolate *isolate, std::map< KeyType, ValueType, Rest... > const &map)
Definition: casts.hpp:700
static constexpr bool callable()
Definition: casts.hpp:117
std::string & demangle()
Definition: v8helpers.h:145
v8::Local< T > operator()(v8::Isolate *isolate, v8::Local< T > &value)
Definition: casts.hpp:623
v8::Local< v8::Value > operator()(v8::Isolate *isolate, const T **multi_pointer)
Definition: casts.hpp:588
bool Value(const T &value, M matcher)
void operator()(v8::Isolate *isolate, v8::Local< v8::Value > value) const
Definition: casts.hpp:108
static constexpr bool callable()
Definition: casts.hpp:286
std::set< std::remove_reference_t< std::result_of_t< CastToNative< T >(v8::Isolate *, v8::Local< v8::Value >)>>, Rest... > ResultType
Definition: casts.hpp:387
v8::Local< v8::Array > operator()(v8::Isolate *isolate, std::tuple< Args... > &tuple)
Definition: casts.hpp:928
std::vector< std::remove_reference_t< std::result_of_t< CastToNative< T >(v8::Isolate *, v8::Local< v8::Value >)>>, Rest... > ResultType
Definition: casts.hpp:375
v8::Local< v8::Value > operator()(v8::Isolate *isolate, std::unique_ptr< T, Rest... > &unique_ptr)
Definition: casts.hpp:759
T operator()(v8::Isolate *isolate, v8::Local< v8::Value > value) const
Definition: casts.hpp:203
v8::Local< v8::Object > casttojs_multimaplike(v8::Isolate *isolate, MultiMapLike< A, B, Rest... > const &map)
Definition: casts.hpp:846
v8::Local< v8::Value > cast_to_js_map_helper(v8::Isolate *isolate, MapTemplate< KeyType, ValueType, Rest... > const &map)
Definition: casts.hpp:645
ResultType operator()(v8::Isolate *isolate, v8::Local< v8::Value > value) const
Definition: casts.hpp:491
std::tuple< Ts... > cast_to_native_tuple_helper(v8::Isolate *isolate, v8::Local< v8::Array > array, std::tuple< Ts... >, std::index_sequence< Is... >)
Definition: casts.hpp:170
v8::Local< v8::Function > operator()(v8::Isolate *isolate, v8::Local< v8::Value > value) const
Definition: casts.hpp:263
v8::Local< v8::Array > operator()(v8::Isolate *isolate, std::tuple< Args... > &tuple)
Definition: casts.hpp:910
std::vector< std::remove_reference_t< std::result_of_t< CastToNative< T >(v8::Isolate *, v8::Local< v8::Value >)>>, Rest... > ResultType
Definition: casts.hpp:362
std::pair< FirstT, SecondT > operator()(v8::Isolate *isolate, v8::Local< v8::Value > value) const
Definition: casts.hpp:249
constexpr bool always_false_v
Definition: casts.hpp:28
Matcher< T > A()
ContainerTemplate< Key, Value, Rest... > map_type_helper(v8::Isolate *isolate, v8::Local< v8::Value > value)
Definition: casts.hpp:433
v8::Local< v8::Value > operator()(v8::Isolate *isolate, std::array< T, N > &&arr)
Definition: casts.hpp:742
v8::Local< T > operator()(v8::Isolate *isolate, v8::Global< T > &&value)
Definition: casts.hpp:612
constexpr bool cast_to_native_supports_default_value_v
Definition: casts.hpp:50
std::unique_ptr< char[]> operator()(v8::Isolate *isolate, v8::Local< v8::Value > value) const
Definition: casts.hpp:282
v8::Local< T > operator()(v8::Isolate *isolate, v8::Global< T > const &value)
Definition: casts.hpp:626
std::multimap< Key, Value, Args... > ResultType
Definition: casts.hpp:489
constexpr bool is_wrapped_typeish_v
Definition: casts.hpp:55
v8::Local< v8::Value > operator()(v8::Isolate *isolate, std::set< T, Rest... > &&set)
Definition: casts.hpp:1012
void for_each_own_property(const v8::Local< v8::Context > context, const v8::Local< v8::Object > object, T callable)
Definition: v8helpers.h:399
void operator()(v8::Isolate *isolate, v8::Local< v8::Value > value) const
Definition: casts.hpp:136
static constexpr bool callable()
Definition: casts.hpp:424
v8::Local< v8::Value > operator()(v8::Isolate *isolate, std::deque< T, Rest... > &&deque)
Definition: casts.hpp:733
internal::KeyMatcher< M > Key(M inner_matcher)
v8::Local< v8::Value > cast_to_js_vector_helper(v8::Isolate *isolate, VectorTemplate< std::remove_reference_t< ValueType >, Rest... > const &vector)
Definition: casts.hpp:665
v8::Local< v8::Value > operator()(v8::Isolate *isolate, T const &value) const
Definition: casts.hpp:514
const T & move(const T &t)
Definition: gtest-port.h:1317
#define HANDLE_FUNCTION_VALUES
Definition: casts.hpp:69
constexpr bool is_wrapped_type_v
Definition: casts.hpp:39
v8::Local< v8::Value > operator()(v8::Isolate *isolate, std::unique_ptr< T, Rest... > &&unique_ptr)
Definition: casts.hpp:764
v8::Local< v8::Value > operator()(v8::Isolate *isolate, std::unordered_map< A, B, Rest... > &&unorderedmap)
Definition: casts.hpp:724