Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
emscripten-core
GitHub Repository: emscripten-core/emscripten
Path: blob/main/test/embind/test_custom_marshal.cpp
4150 views
1
// Copyright 2019 The Emscripten Authors. All rights reserved.
2
// Emscripten is available under two separate licenses, the MIT license and the
3
// University of Illinois/NCSA Open Source License. Both these licenses can be
4
// found in the LICENSE file.
5
6
#include <stdio.h>
7
#include <emscripten.h>
8
#include <emscripten/bind.h>
9
#include <emscripten/val.h>
10
#include <type_traits>
11
#include <string>
12
13
using namespace emscripten;
14
15
// Class which wraps int and have no explicit or implicit conversions.
16
struct IntWrapper {
17
int get() const {
18
return value;
19
}
20
static IntWrapper create(int v) {
21
return IntWrapper(v);
22
}
23
24
private:
25
explicit IntWrapper(int v) : value(v) {}
26
int value;
27
};
28
29
// Need for SFINAE-based specialization testing.
30
template<typename T> struct IsIntWrapper : std::false_type {};
31
template<> struct IsIntWrapper<IntWrapper> : std::true_type {};
32
33
// We will pass IntWrapper between C++ and JavaScript via IntWrapperIntermediate
34
// which should be already registered by embind on both C++ and JavaScript sides.
35
// That way we can write C++ conversions only and use standard JS conversions.
36
using IntWrapperIntermediate = int;
37
38
// Specify custom (un)marshalling for all types satisfying IsIntWrapper.
39
namespace emscripten {
40
namespace internal {
41
template<typename T>
42
struct TypeID<T, typename std::enable_if<IsIntWrapper<T>::value, void>::type> {
43
static constexpr TYPEID get() {
44
return TypeID<IntWrapperIntermediate>::get();
45
}
46
};
47
48
template<typename T>
49
struct BindingType<T, typename std::enable_if<IsIntWrapper<T>::value, void>::type> {
50
typedef typename BindingType<IntWrapperIntermediate>::WireType WireType;
51
52
constexpr static WireType toWireType(const T& v, rvp::default_tag) {
53
return BindingType<IntWrapperIntermediate>::toWireType(v.get(), rvp::default_tag{});
54
}
55
constexpr static T fromWireType(WireType v) {
56
return T::create(BindingType<IntWrapperIntermediate>::fromWireType(v));
57
}
58
};
59
} // namespace internal
60
} // namespace emscripten
61
62
template<typename T>
63
void test() {
64
IntWrapper x = IntWrapper::create(10);
65
val js_func = val::module_property("js_func");
66
IntWrapper y = js_func(val(std::forward<T>(x))).as<IntWrapper>();
67
printf("C++ got %d\n", y.get());
68
}
69
70
int main(int argc, char **argv) {
71
test<IntWrapper>();
72
test<IntWrapper&>();
73
test<const IntWrapper>();
74
test<const IntWrapper&>();
75
return 0;
76
}
77
78