-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathnostl.h
170 lines (143 loc) · 5.11 KB
/
nostl.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
#pragma once
#include <map>
#include <notypes.h>
#include <notypescript.h>
#include <string>
#include <vector>
namespace Nobind {
namespace Typemap {
template <typename V, typename T> class FromJSVector {
std::remove_cv_t<std::remove_reference_t<V>> val_;
size_t len_;
std::vector<FromJS_t<T>> tms_;
public:
NOBIND_INLINE explicit FromJSVector(const Napi::Value &val) {
if (!val.IsArray()) {
throw Napi::TypeError::New(val.Env(), "Expected an array");
}
Napi::Array array = val.As<Napi::Array>();
len_ = array.Length();
tms_.reserve(len_);
for (size_t i = 0; i < array.Length(); i++) {
tms_.emplace_back(array.Get(i));
}
}
#ifndef NOBIND_NO_ASYNC_LOCKING
NOBIND_INLINE void Lock() NOBIND_NOEXCEPT {
if constexpr (FromJSTypemapHasLocking<FromJS_t<T>>::lock) {
for (auto &el : tms_) {
el.Lock();
}
}
}
NOBIND_INLINE void Unlock() NOBIND_NOEXCEPT {
if constexpr (FromJSTypemapHasLocking<FromJS_t<T>>::unlock) {
for (auto &el : tms_) {
el.Unlock();
}
}
}
#endif
NOBIND_INLINE V Get() {
for (auto &el : tms_) {
val_.push_back(el.Get());
}
return val_;
}
FromJSVector(const FromJSVector &) = delete;
FromJSVector(FromJSVector &&) = default;
static std::string TSType() { return createTSArray<T>(); };
};
template <typename V, typename T, const ReturnAttribute &RETATTR> class ToJSVector {
Napi::Env env_;
std::remove_cv_t<std::remove_reference_t<V>> val_;
public:
NOBIND_INLINE explicit ToJSVector(Napi::Env env, V val) : env_(env), val_(val) {}
NOBIND_INLINE Napi::Value Get() {
Napi::Array array = Napi::Array::New(env_, val_.size());
for (size_t i = 0; i < val_.size(); i++) {
array.Set(i, ToJS<T, RETATTR>(env_, val_[i]).Get());
}
return array;
}
ToJSVector(const ToJSVector &) = delete;
ToJSVector(ToJSVector &&) = default;
static std::string TSType() { return createTSArray<T>(); };
};
template <typename M, typename T> class FromJSMap {
std::remove_cv_t<std::remove_reference_t<M>> val_;
size_t len_;
std::map<std::string, FromJS_t<T>> tms_;
public:
NOBIND_INLINE explicit FromJSMap(const Napi::Value &val) {
if (!val.IsObject()) {
throw Napi::TypeError::New(val.Env(), "Expected an object");
}
Napi::Object object = val.ToObject();
for (auto prop : object) {
auto tm = FromJSValue<T>(prop.second);
tms_.emplace(prop.first.ToString().Utf8Value(), prop.second);
val_.insert({prop.first.ToString().Utf8Value(), tm.Get()});
}
}
NOBIND_INLINE M Get() {
for (auto &el : tms_) {
val_.insert({el.first, el.second.Get()});
}
return val_;
}
#ifndef NOBIND_NO_ASYNC_LOCKING
NOBIND_INLINE void Lock() NOBIND_NOEXCEPT {
if constexpr (FromJSTypemapHasLocking<FromJS_t<T>>::lock) {
for (auto &el : tms_) {
el.second.Lock();
}
}
}
NOBIND_INLINE void Unlock() NOBIND_NOEXCEPT {
if constexpr (FromJSTypemapHasLocking<FromJS_t<T>>::unlock) {
for (auto &el : tms_) {
el.second.Unlock();
}
}
}
#endif
FromJSMap(const FromJSMap &) = delete;
FromJSMap(FromJSMap &&) = default;
static std::string TSType() { return createTSRecord<std::string, T>(); };
};
template <typename M, typename T, const ReturnAttribute &RETATTR> class ToJSMap {
Napi::Env env_;
std::remove_cv_t<std::remove_reference_t<M>> val_;
public:
NOBIND_INLINE explicit ToJSMap(Napi::Env env, M val) : env_(env), val_(val) {}
NOBIND_INLINE Napi::Value Get() {
Napi::Object object = Napi::Object::New(env_);
for (auto &prop : val_) {
object.Set(Napi::String::New(env_, prop.first), ToJS<T, RETATTR>(env_, prop.second).Get());
}
return object;
}
ToJSMap(const ToJSMap &) = delete;
ToJSMap(ToJSMap &&) = default;
static std::string TSType() { return createTSRecord<std::string, T>(); };
};
#define TYPEMAPS_FOR_STL(CONTAINER, CLASS) \
template <typename T> struct FromJS<CONTAINER> : public FromJS##CLASS<CONTAINER, T> { \
using FromJS##CLASS<CONTAINER, T>::FromJS##CLASS; \
}; \
template <typename T, const ReturnAttribute &RETATTR> \
struct ToJS<CONTAINER, RETATTR> : public ToJS##CLASS<CONTAINER, T, RETATTR> { \
using ToJS##CLASS<CONTAINER, T, RETATTR>::ToJS##CLASS; \
};
TYPEMAPS_FOR_STL(std::vector<T>, Vector);
TYPEMAPS_FOR_STL(std::vector<T> &, Vector);
TYPEMAPS_FOR_STL(const std::vector<T>, Vector);
TYPEMAPS_FOR_STL(const std::vector<T> &, Vector);
template <typename T> using string_map = std::map<std::string, T>;
TYPEMAPS_FOR_STL(string_map<T>, Map);
TYPEMAPS_FOR_STL(string_map<T> &, Map);
TYPEMAPS_FOR_STL(const string_map<T>, Map);
TYPEMAPS_FOR_STL(const string_map<T> &, Map);
} // namespace Typemap
} // namespace Nobind