@auto_js/napi 0.0.1 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CMakeLists.txt +10 -4
- package/README.md +30 -3
- package/_module.cc +12 -10
- package/api/api.cc +8 -7
- package/api/callback_info.cc +1 -7
- package/api/finalizer.cc +1 -4
- package/api/invoke.cc +4 -9
- package/api/uv_dlib.cc +27 -0
- package/api/uv_dlib.h.cc +21 -0
- package/api/uv_handle.cc +9 -9
- package/api/uv_scheduler.cc +11 -17
- package/api/uv_scheduler.h.cc +3 -6
- package/handle/bound_value.cc +4 -7
- package/handle/reference.cc +9 -5
- package/handle/remote.cc +11 -17
- package/handle/types.cc +61 -46
- package/handle/value.cc +12 -14
- package/package.json +7 -6
- package/support/callback.cc +7 -19
- package/support/callback_storage.cc +4 -9
- package/support/class_template_storage.cc +4 -6
- package/support/container.cc +9 -10
- package/support/environment.cc +32 -20
- package/support/environment.h.cc +8 -18
- package/support/environment_fwd.cc +1 -2
- package/support/error_scope.cc +0 -2
- package/support/initialize.h.cc +2 -5
- package/support/promise.cc +3 -10
- package/support/string_table.cc +3 -5
- package/support/utility.cc +54 -28
- package/transfer/accept.cc +131 -327
- package/transfer/accept.h.cc +390 -0
- package/transfer/visit.cc +201 -132
- package/value/array.cc +1 -3
- package/value/array.h.cc +5 -11
- package/value/array_buffer.cc +109 -0
- package/value/array_buffer.h.cc +150 -0
- package/value/class.cc +12 -21
- package/value/class.h.cc +5 -10
- package/value/external.cc +6 -10
- package/value/function.cc +5 -12
- package/value/function.h.cc +2 -9
- package/value/object.cc +2 -6
- package/value/object.h.cc +7 -15
- package/value/primitive.cc +12 -81
- package/value/primitive.h.cc +6 -64
- package/value/record.cc +38 -0
- package/value/record.h.cc +39 -0
- package/value/value.cc +8 -8
- package/value/dictionary.cc +0 -33
- package/value/dictionary.h.cc +0 -56
|
@@ -0,0 +1,390 @@
|
|
|
1
|
+
export module napi_js:accept;
|
|
2
|
+
import :container;
|
|
3
|
+
import :value;
|
|
4
|
+
import std;
|
|
5
|
+
import util;
|
|
6
|
+
|
|
7
|
+
namespace js::napi {
|
|
8
|
+
|
|
9
|
+
// napi reference acceptor
|
|
10
|
+
struct reaccept_napi_value {
|
|
11
|
+
using reference_type = napi_value;
|
|
12
|
+
|
|
13
|
+
constexpr auto operator()(std::type_identity<napi_value> /*type*/, napi_value value) const -> napi_value {
|
|
14
|
+
return value;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
template <class Tag>
|
|
18
|
+
constexpr auto operator()(std::type_identity<value_of<Tag>> /*type*/, napi_value value) const -> value_of<Tag> {
|
|
19
|
+
return value_of<Tag>::from(value);
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
// Napi acceptor which does not need specialized environment type
|
|
24
|
+
struct accept_basic_napi_value {
|
|
25
|
+
public:
|
|
26
|
+
explicit accept_basic_napi_value(auto* /*transfer*/, auto& env) : env_{env} {}
|
|
27
|
+
|
|
28
|
+
// Declare reference provider
|
|
29
|
+
using accept_reference_type = reaccept_napi_value;
|
|
30
|
+
|
|
31
|
+
// undefined & null
|
|
32
|
+
auto operator()(undefined_tag tag, visit_holder visit, std::monostate subject) const -> value_of<undefined_tag>;
|
|
33
|
+
auto operator()(undefined_tag tag, visit_holder visit, const auto& /*subject*/) const -> value_of<undefined_tag> {
|
|
34
|
+
return (*this)(tag, visit, std::monostate{});
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
auto operator()(null_tag tag, visit_holder visit, std::nullptr_t subject) const -> value_of<null_tag>;
|
|
38
|
+
auto operator()(null_tag tag, visit_holder visit, const auto& /*subject*/) const -> value_of<null_tag> {
|
|
39
|
+
return (*this)(tag, visit, nullptr);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// boolean
|
|
43
|
+
auto operator()(boolean_tag tag, visit_holder visit, bool subject) const -> value_of<boolean_tag>;
|
|
44
|
+
|
|
45
|
+
// number
|
|
46
|
+
auto operator()(number_tag_of<double> tag, visit_holder visit, double subject) const -> value_of<number_tag_of<double>>;
|
|
47
|
+
auto operator()(number_tag_of<std::int32_t> tag, visit_holder visit, std::int32_t subject) const -> value_of<number_tag_of<std::int32_t>>;
|
|
48
|
+
auto operator()(number_tag_of<std::uint32_t> tag, visit_holder visit, std::uint32_t subject) const -> value_of<number_tag_of<std::uint32_t>>;
|
|
49
|
+
|
|
50
|
+
auto operator()(number_tag /*tag*/, visit_holder visit, auto&& subject) const -> value_of<number_tag> {
|
|
51
|
+
return (*this)(number_tag_of<double>{}, visit, double{std::forward<decltype(subject)>(subject)});
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
template <class Type>
|
|
55
|
+
auto operator()(number_tag_of<Type> tag, visit_holder visit, auto&& subject) const -> value_of<number_tag_of<Type>> {
|
|
56
|
+
return (*this)(tag, visit, Type{std::forward<decltype(subject)>(subject)});
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// string
|
|
60
|
+
auto operator()(string_tag_of<char> tag, visit_holder visit, std::string_view subject) const
|
|
61
|
+
-> js::referenceable_value<value_of<string_tag_of<char>>>;
|
|
62
|
+
auto operator()(string_tag_of<char8_t> tag, visit_holder visit, std::u8string_view subject) const
|
|
63
|
+
-> js::referenceable_value<value_of<string_tag_of<char8_t>>>;
|
|
64
|
+
auto operator()(string_tag_of<char16_t> tag, visit_holder visit, std::u16string_view subject) const
|
|
65
|
+
-> js::referenceable_value<value_of<string_tag_of<char16_t>>>;
|
|
66
|
+
|
|
67
|
+
auto operator()(string_tag /*tag*/, visit_holder visit, auto&& subject) const
|
|
68
|
+
-> js::referenceable_value<value_of<string_tag>> {
|
|
69
|
+
auto value = (*this)(string_tag_of<char16_t>{}, visit, std::u16string_view{std::forward<decltype(subject)>(subject)});
|
|
70
|
+
return js::referenceable_value{value_of<string_tag>{*value}};
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
template <class Char>
|
|
74
|
+
auto operator()(string_tag_of<Char> tag, visit_holder visit, std::convertible_to<std::basic_string_view<Char>> auto&& subject) const
|
|
75
|
+
-> js::referenceable_value<value_of<string_tag_of<Char>>> {
|
|
76
|
+
return (*this)(tag, visit, std::basic_string_view<Char>{std::forward<decltype(subject)>(subject)});
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
template <class Char>
|
|
80
|
+
auto operator()(string_tag_of<Char> tag, visit_holder visit, auto&& subject) const
|
|
81
|
+
-> js::referenceable_value<value_of<string_tag_of<Char>>> {
|
|
82
|
+
return (*this)(tag, visit, std::basic_string<Char>{std::forward<decltype(subject)>(subject)});
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// bigint
|
|
86
|
+
auto operator()(bigint_tag_of<std::int64_t> tag, visit_holder visit, std::int64_t subject) const
|
|
87
|
+
-> js::referenceable_value<value_of<bigint_tag_of<std::int64_t>>>;
|
|
88
|
+
auto operator()(bigint_tag_of<std::uint64_t> tag, visit_holder visit, std::uint64_t subject) const
|
|
89
|
+
-> js::referenceable_value<value_of<bigint_tag_of<std::uint64_t>>>;
|
|
90
|
+
auto operator()(bigint_tag_of<js::bigint> tag, visit_holder visit, const js::bigint& subject) const
|
|
91
|
+
-> js::referenceable_value<value_of<bigint_tag_of<js::bigint>>>;
|
|
92
|
+
auto operator()(bigint_tag_of<js::bigint> tag, visit_holder visit, js::bigint&& subject) const
|
|
93
|
+
-> js::referenceable_value<value_of<bigint_tag_of<js::bigint>>>;
|
|
94
|
+
|
|
95
|
+
auto operator()(bigint_tag /*tag*/, visit_holder visit, auto&& subject) const
|
|
96
|
+
-> js::referenceable_value<value_of<bigint_tag>> {
|
|
97
|
+
auto value = (*this)(bigint_tag_of<js::bigint>{}, visit, js::bigint{std::forward<decltype(subject)>(subject)});
|
|
98
|
+
return js::referenceable_value{value_of<bigint_tag>{*value}};
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
template <class Type>
|
|
102
|
+
auto operator()(bigint_tag_of<Type> tag, visit_holder visit, auto&& subject) const
|
|
103
|
+
-> js::referenceable_value<value_of<bigint_tag_of<Type>>> {
|
|
104
|
+
return (*this)(tag, visit, Type{std::forward<decltype(subject)>(subject)});
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// date
|
|
108
|
+
auto operator()(date_tag tag, visit_holder /*visit*/, js_clock::time_point subject) const
|
|
109
|
+
-> js::referenceable_value<value_of<date_tag>>;
|
|
110
|
+
|
|
111
|
+
// error
|
|
112
|
+
auto operator()(error_tag /*tag*/, visit_holder visit, const js::error_value& subject) const
|
|
113
|
+
-> js::referenceable_value<value_of<error_tag>>;
|
|
114
|
+
|
|
115
|
+
auto operator()(error_tag tag, visit_holder visit, const auto& subject) const
|
|
116
|
+
-> js::referenceable_value<value_of<error_tag>> {
|
|
117
|
+
return (*this)(tag, visit, js::error_value{subject});
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// data blocks (array buffer, shared array buffer)
|
|
121
|
+
auto operator()(array_buffer_tag tag, visit_holder visit, const js::array_buffer& subject) const
|
|
122
|
+
-> js::referenceable_value<value_of<array_buffer_tag>>;
|
|
123
|
+
auto operator()(shared_array_buffer_tag tag, visit_holder visit, js::shared_array_buffer&& subject) const
|
|
124
|
+
-> js::referenceable_value<value_of<shared_array_buffer_tag>>;
|
|
125
|
+
auto operator()(shared_array_buffer_tag tag, visit_holder visit, const js::shared_array_buffer& subject) const
|
|
126
|
+
-> js::referenceable_value<value_of<shared_array_buffer_tag>>;
|
|
127
|
+
|
|
128
|
+
// typed arrays & data view
|
|
129
|
+
template <std::convertible_to<array_buffer_view_tag> Tag>
|
|
130
|
+
auto operator()(this const auto& self, Tag /*tag*/, auto& visit, auto&& subject)
|
|
131
|
+
-> js::referenceable_value<value_of<Tag>> {
|
|
132
|
+
auto byte_offset = subject.byte_offset();
|
|
133
|
+
auto length = subject.size();
|
|
134
|
+
// TODO: We accept the nested `buffer` property as a `data_block` which means `make` needs to
|
|
135
|
+
// invoke `is_arraybuffer` on it again even though we knew what it was a moment ago.
|
|
136
|
+
auto buffer = value_of<data_block_tag>::from(visit(std::forward<decltype(subject)>(subject).buffer(), self));
|
|
137
|
+
return js::referenceable_value{value_of<Tag>::make(self.environment(), buffer, byte_offset, length)};
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// extras
|
|
141
|
+
[[nodiscard]] auto environment() const -> environment& { return env_; }
|
|
142
|
+
explicit operator napi_env() const { return napi_env{env_.get()}; }
|
|
143
|
+
|
|
144
|
+
private:
|
|
145
|
+
std::reference_wrapper<napi::environment> env_;
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
// Generic napi acceptor which accepts all value types.
|
|
149
|
+
template <class Environment>
|
|
150
|
+
struct accept_napi_value;
|
|
151
|
+
|
|
152
|
+
template <class Meta>
|
|
153
|
+
using accept_napi_value_with = accept_napi_value<typename Meta::accept_context_type>;
|
|
154
|
+
|
|
155
|
+
template <class Environment>
|
|
156
|
+
struct accept_napi_value : accept_basic_napi_value {
|
|
157
|
+
public:
|
|
158
|
+
explicit accept_napi_value(auto* transfer, auto& env) :
|
|
159
|
+
accept_basic_napi_value{transfer, env} {}
|
|
160
|
+
using accept_basic_napi_value::operator();
|
|
161
|
+
|
|
162
|
+
// function
|
|
163
|
+
template <class Callback>
|
|
164
|
+
auto operator()(function_prototype_tag /*tag*/, visit_holder /*visit*/, js::free_function<Callback> subject) const -> value_of<function_tag> {
|
|
165
|
+
return value_of<function_tag>::make(environment(), std::forward<decltype(subject)>(subject));
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// vectors
|
|
169
|
+
auto operator()(this const auto& self, vector_tag /*tag*/, auto& visit, auto&& subject)
|
|
170
|
+
-> js::deferred_receiver<value_of<vector_tag>, decltype(self), decltype(visit), decltype(subject)> {
|
|
171
|
+
return {
|
|
172
|
+
value_of<vector_tag>::from(napi::invoke(napi_create_array_with_length, napi_env{self}, subject.size())),
|
|
173
|
+
std::forward_as_tuple(self, visit, std::forward<decltype(subject)>(subject)),
|
|
174
|
+
[](value_of<vector_tag> array, auto& self, auto& visit, auto /*&&*/ subject) -> void {
|
|
175
|
+
int ii = 0;
|
|
176
|
+
auto&& range = util::into_range(std::forward<decltype(subject)>(subject));
|
|
177
|
+
for (auto&& subject : util::forward_range(std::forward<decltype(range)>(range))) {
|
|
178
|
+
auto* element = napi_value{visit(std::forward<decltype(subject)>(subject), self)};
|
|
179
|
+
napi::invoke0(napi_set_element, napi_env{self}, napi_value{array}, ii++, element);
|
|
180
|
+
}
|
|
181
|
+
},
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
template <std::size_t Size>
|
|
186
|
+
auto operator()(this const auto& self, tuple_tag<Size> /*tag*/, auto& visit, auto&& subject)
|
|
187
|
+
-> js::deferred_receiver<value_of<vector_tag>, decltype(self), decltype(visit), decltype(subject)> {
|
|
188
|
+
return {
|
|
189
|
+
value_of<vector_tag>::from(napi::invoke(napi_create_array_with_length, napi_env{self}, Size)),
|
|
190
|
+
std::forward_as_tuple(self, visit, std::forward<decltype(subject)>(subject)),
|
|
191
|
+
[](value_of<vector_tag> array, auto& self, auto& visit, auto /*&&*/ tuple) -> void {
|
|
192
|
+
const auto [... indices ] = util::sequence<Size>;
|
|
193
|
+
(..., [ & ]() -> void {
|
|
194
|
+
// nb: This is forwarded to *each* visitor. The visitor should be aware and only lvalue
|
|
195
|
+
// reference members one at a time.
|
|
196
|
+
auto* element = napi_value{visit(indices, std::forward<decltype(tuple)>(tuple), self)};
|
|
197
|
+
napi::invoke0(napi_set_element, napi_env{self}, napi_value{array}, indices, element);
|
|
198
|
+
}());
|
|
199
|
+
}
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// arrays & dictionaries
|
|
204
|
+
auto operator()(this const auto& self, list_tag /*tag*/, auto& visit, auto&& subject)
|
|
205
|
+
-> js::deferred_receiver<value_of<list_tag>, decltype(self), decltype(visit), decltype(subject)> {
|
|
206
|
+
return {
|
|
207
|
+
value_of<list_tag>::from(napi::invoke(napi_create_array, napi_env{self})),
|
|
208
|
+
std::forward_as_tuple(self, visit, std::forward<decltype(subject)>(subject)),
|
|
209
|
+
[](value_of<list_tag> array, auto& self, auto& visit, auto /*&&*/ subject) -> void {
|
|
210
|
+
self.accept_entry_pair_vector(visit, array, std::forward<decltype(subject)>(subject));
|
|
211
|
+
}
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
auto operator()(this const auto& self, dictionary_tag /*tag*/, auto& visit, auto&& subject)
|
|
216
|
+
-> js::deferred_receiver<value_of<dictionary_tag>, decltype(self), decltype(visit), decltype(subject)> {
|
|
217
|
+
return {
|
|
218
|
+
value_of<dictionary_tag>::from(napi::invoke(napi_create_object, napi_env{self})),
|
|
219
|
+
std::forward_as_tuple(self, visit, std::forward<decltype(subject)>(subject)),
|
|
220
|
+
[](value_of<dictionary_tag> object, auto& self, auto& visit, auto /*&&*/ subject) -> void {
|
|
221
|
+
self.accept_entry_pair_vector(visit, object, std::forward<decltype(subject)>(subject));
|
|
222
|
+
}
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
auto accept_entry_pair_vector(this const auto& self, auto& visit, value_of<object_tag> target, auto&& subject) -> void {
|
|
227
|
+
std::vector<napi_property_descriptor> properties;
|
|
228
|
+
auto&& range = util::into_range(std::forward<decltype(subject)>(subject));
|
|
229
|
+
properties.reserve(std::size(range));
|
|
230
|
+
for (auto&& [ key, value ] : util::forward_range(std::forward<decltype(range)>(range))) {
|
|
231
|
+
auto* name = napi_value{visit.first(std::forward<decltype(key)>(key), self)};
|
|
232
|
+
properties.emplace_back(napi_property_descriptor{
|
|
233
|
+
.utf8name{},
|
|
234
|
+
// TODO: `napi_define_properties` only works with string keys but the nested acceptor will
|
|
235
|
+
// accept indexed properties as numeric napi values. `visit.first` should be invoked
|
|
236
|
+
// against something that maybe resolves to `std::variant<int32_t, value_of<name_tag>>`.
|
|
237
|
+
.name = napi::invoke(napi_coerce_to_string, napi_env{self}, name),
|
|
238
|
+
|
|
239
|
+
.method{},
|
|
240
|
+
.getter{},
|
|
241
|
+
.setter{},
|
|
242
|
+
.value = napi_value{visit.second(std::forward<decltype(value)>(value), self)},
|
|
243
|
+
|
|
244
|
+
// NOLINTNEXTLINE(hicpp-signed-bitwise)
|
|
245
|
+
.attributes = static_cast<napi_property_attributes>(napi_writable | napi_enumerable | napi_configurable),
|
|
246
|
+
.data{},
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
napi::invoke0(napi_define_properties, napi_env{self}, napi_value{target}, properties.size(), properties.data());
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// structs
|
|
253
|
+
template <std::size_t Size>
|
|
254
|
+
auto operator()(this const auto& self, struct_tag<Size> /*tag*/, auto& visit, auto&& subject)
|
|
255
|
+
-> js::deferred_receiver<value_of<dictionary_tag>, decltype(self), decltype(visit), decltype(subject)> {
|
|
256
|
+
return {
|
|
257
|
+
value_of<dictionary_tag>::from(napi::invoke(napi_create_object, napi_env{self})),
|
|
258
|
+
std::forward_as_tuple(self, visit, std::forward<decltype(subject)>(subject)),
|
|
259
|
+
[](value_of<dictionary_tag> object, auto& self, auto& visit, auto /*&&*/ subject) -> void {
|
|
260
|
+
self.template accept_entry_pair_struct<Size>(visit, object, std::forward<decltype(subject)>(subject));
|
|
261
|
+
}
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
template <std::size_t Size>
|
|
266
|
+
auto accept_entry_pair_struct(this const auto& self, auto& visit, value_of<object_tag> target, auto&& subject) -> void {
|
|
267
|
+
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init)
|
|
268
|
+
std::array<napi_property_descriptor, Size> properties;
|
|
269
|
+
const auto [... indices ] = util::sequence<Size>;
|
|
270
|
+
(..., [ & ]() -> void {
|
|
271
|
+
// nb: This is forwarded to *each* visitor. The visitor should be aware and only lvalue
|
|
272
|
+
// reference members one at a time.
|
|
273
|
+
auto accept_entry = accept_entry_pair<decltype(self), decltype(self)>{self};
|
|
274
|
+
auto entry = visit(std::integral_constant<std::size_t, indices>{}, std::forward<decltype(subject)>(subject), accept_entry);
|
|
275
|
+
// NOLINTNEXTLINE(modernize-type-traits)
|
|
276
|
+
properties.at(indices) = {
|
|
277
|
+
.utf8name{},
|
|
278
|
+
.name = entry.first,
|
|
279
|
+
|
|
280
|
+
.method{},
|
|
281
|
+
.getter{},
|
|
282
|
+
.setter{},
|
|
283
|
+
.value = entry.second,
|
|
284
|
+
|
|
285
|
+
// NOLINTNEXTLINE(hicpp-signed-bitwise)
|
|
286
|
+
.attributes = static_cast<napi_property_attributes>(napi_writable | napi_enumerable | napi_configurable),
|
|
287
|
+
.data{},
|
|
288
|
+
};
|
|
289
|
+
}());
|
|
290
|
+
napi::invoke0(napi_define_properties, napi_env{self}, napi_value{target}, properties.size(), properties.data());
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
// extras
|
|
294
|
+
[[nodiscard]] auto environment() const -> Environment& {
|
|
295
|
+
return static_cast<Environment&>(accept_basic_napi_value::environment());
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
consteval static auto types(auto /*recursive*/) { return util::type_pack{}; }
|
|
299
|
+
};
|
|
300
|
+
|
|
301
|
+
// `value_of<object_tag>{}.assign(...)` implementation
|
|
302
|
+
struct object_assign_delegate {
|
|
303
|
+
public:
|
|
304
|
+
explicit object_assign_delegate(value_of<object_tag> object) : object_{object} {}
|
|
305
|
+
auto operator*() const { return object_; }
|
|
306
|
+
|
|
307
|
+
private:
|
|
308
|
+
value_of<object_tag> object_;
|
|
309
|
+
};
|
|
310
|
+
|
|
311
|
+
auto value_for_object::assign(this value_of<object_tag> self, auto_environment auto& env, auto source) -> void {
|
|
312
|
+
js::transfer_in<object_assign_delegate>(std::move(source), env, object_assign_delegate{self});
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
} // namespace js::napi
|
|
316
|
+
|
|
317
|
+
namespace js {
|
|
318
|
+
|
|
319
|
+
// Plain napi_value acceptor
|
|
320
|
+
template <>
|
|
321
|
+
struct accept_property_subject<napi_value> : std::type_identity<napi_value> {};
|
|
322
|
+
|
|
323
|
+
template <class Meta>
|
|
324
|
+
struct accept<Meta, napi_value> : napi::accept_napi_value_with<Meta> {
|
|
325
|
+
using accept_type = napi::accept_napi_value_with<Meta>;
|
|
326
|
+
using accept_type::accept_type;
|
|
327
|
+
};
|
|
328
|
+
|
|
329
|
+
// Tagged `value_of<T>` acceptor
|
|
330
|
+
template <>
|
|
331
|
+
struct accept_property_subject<napi::value_of<value_tag>> : std::type_identity<napi_value> {};
|
|
332
|
+
|
|
333
|
+
template <class Meta, class Tag>
|
|
334
|
+
struct accept<Meta, napi::value_of<Tag>> : napi::accept_napi_value_with<Meta> {
|
|
335
|
+
using accept_type = napi::accept_napi_value_with<Meta>;
|
|
336
|
+
using accept_type::accept_type;
|
|
337
|
+
};
|
|
338
|
+
|
|
339
|
+
// Forwarded `value_of<T>` acceptor
|
|
340
|
+
template <class Tag>
|
|
341
|
+
struct accept<void, js::forward<napi::value_of<Tag>, Tag>> {
|
|
342
|
+
auto operator()(Tag /*tag*/, visit_holder /*visit*/, napi::value_of<Tag> subject) const -> js::forward<napi::value_of<Tag>, Tag> {
|
|
343
|
+
return js::forward{napi::value_of<Tag>{subject}, Tag{}};
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
consteval static auto types(auto /*recursive*/) { return util::type_pack{}; }
|
|
347
|
+
};
|
|
348
|
+
|
|
349
|
+
// Object key lookup via napi
|
|
350
|
+
template <class Meta, auto Key, class Type>
|
|
351
|
+
struct accept_property_value<Meta, Key, Type, napi_value> {
|
|
352
|
+
public:
|
|
353
|
+
explicit constexpr accept_property_value(auto* transfer) :
|
|
354
|
+
first{transfer},
|
|
355
|
+
second{transfer} {}
|
|
356
|
+
|
|
357
|
+
auto operator()(dictionary_tag /*tag*/, auto& visit, const auto& subject) const -> Type {
|
|
358
|
+
if (auto local = first(std::type_identity<void>{}, visit.first); subject.has(local)) {
|
|
359
|
+
return visit.second(subject.get(local), second);
|
|
360
|
+
} else {
|
|
361
|
+
return second(undefined_in_tag{}, visit.second, std::monostate{});
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
private:
|
|
366
|
+
mutable visit_key_literal<Key, napi_value> first;
|
|
367
|
+
accept_value<Meta, Type> second;
|
|
368
|
+
};
|
|
369
|
+
|
|
370
|
+
template <class Meta>
|
|
371
|
+
struct accept<Meta, napi::object_assign_delegate> {
|
|
372
|
+
public:
|
|
373
|
+
accept(auto* transfer, auto& env, napi::object_assign_delegate object) :
|
|
374
|
+
accept_{transfer, env},
|
|
375
|
+
object_{object} {}
|
|
376
|
+
|
|
377
|
+
template <std::size_t Size>
|
|
378
|
+
auto operator()(this const auto& self, tuple_tag<Size> /*tag*/, auto& visit, auto&& subject) -> napi::object_assign_delegate {
|
|
379
|
+
self.accept_.template accept_entry_pair_struct<Size>(visit, *self.object_, std::forward<decltype(subject)>(subject));
|
|
380
|
+
return self.object_;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
consteval static auto types(auto recursive) { return accept<Meta, napi_value>::types(recursive); }
|
|
384
|
+
|
|
385
|
+
private:
|
|
386
|
+
accept_value<Meta, napi_value> accept_;
|
|
387
|
+
napi::object_assign_delegate object_;
|
|
388
|
+
};
|
|
389
|
+
|
|
390
|
+
} // namespace js
|