@auto_js/napi 0.0.8 → 0.0.10

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/transfer/visit.cc CHANGED
@@ -22,9 +22,9 @@ struct visit_property_name {
22
22
 
23
23
  template <class Accept>
24
24
  auto operator()(napi_value subject, const Accept& accept) -> accept_target_t<Accept> {
25
- return visit_.get().lookup_or_visit(subject, [ & ]() -> accept_target_t<Accept> {
25
+ return visit_.get().lookup_or_visit(subject, [ & ] -> accept_target_t<Accept> {
26
26
  auto accept_as = [ & ]<class Tag>(Tag tag) -> auto {
27
- auto value = bound_value{napi_env{visit_.get()}, value_of<Tag>::from(subject)};
27
+ auto value = value_of{napi_env{visit_.get()}, local_of<Tag>::from(subject)};
28
28
  return accept(tag, *this, value);
29
29
  };
30
30
  switch (napi::invoke(napi_typeof, napi_env{visit_.get()}, subject)) {
@@ -50,17 +50,17 @@ struct visit_napi_key_literal {
50
50
 
51
51
  auto operator()(const auto& /*could_be_literally_anything*/, const auto& accept_or_visit) -> napi_value {
52
52
  const auto make = util::overloaded{
53
- [](auto& env, std::string_view subject) -> napi::value_of<string_tag_of<char>> {
53
+ [](auto& env, std::string_view subject) -> napi::local_of<string_tag_of<char>> {
54
54
  auto* value = napi::invoke(node_api_create_property_key_latin1, napi_env{env}, subject.data(), subject.length());
55
- return napi::value_of<string_tag_of<char>>::from(value);
55
+ return napi::local_of<string_tag_of<char>>::from(value);
56
56
  },
57
- [](auto& env, std::u16string_view subject) -> napi::value_of<string_tag_of<char16_t>> {
57
+ [](auto& env, std::u16string_view subject) -> napi::local_of<string_tag_of<char16_t>> {
58
58
  auto* value = napi::invoke(node_api_create_property_key_utf16, napi_env{env}, subject.data(), subject.length());
59
- return napi::value_of<string_tag_of<char16_t>>::from(value);
59
+ return napi::local_of<string_tag_of<char16_t>>::from(value);
60
60
  },
61
- [](auto& env, std::u8string_view subject) -> napi::value_of<string_tag_of<char8_t>> {
61
+ [](auto& env, std::u8string_view subject) -> napi::local_of<string_tag_of<char8_t>> {
62
62
  auto* value = napi::invoke(node_api_create_property_key_utf8, napi_env{env}, reinterpret_cast<const char*>(subject.data()), subject.length());
63
- return napi::value_of<string_tag_of<char8_t>>::from(value);
63
+ return napi::local_of<string_tag_of<char8_t>>::from(value);
64
64
  },
65
65
  };
66
66
  if (local_key_ == napi_value{}) {
@@ -109,40 +109,40 @@ struct visit_value : reference_map_t<Reference, reference_map_type> {
109
109
  // If the private `immediate` operation is defined: this public operation will first
110
110
  // perform a reference map lookup, then delegate to the private operation if not found.
111
111
  template <class Tag, class Accept>
112
- auto operator()(value_of<Tag> subject, const Accept& accept) -> accept_target_t<Accept>
112
+ auto operator()(local_of<Tag> subject, const Accept& accept) -> accept_target_t<Accept>
113
113
  requires requires { immediate(subject, accept); } {
114
- return lookup_or_visit(subject, [ & ]() -> accept_target_t<Accept> {
114
+ return lookup_or_visit(subject, [ & ] -> accept_target_t<Accept> {
115
115
  return immediate(subject, accept);
116
116
  });
117
117
  }
118
118
 
119
119
  // Visit operations for non-refable types.
120
120
  template <class Accept>
121
- auto operator()(value_of<null_tag> subject, const Accept& accept) -> accept_target_t<Accept> {
121
+ auto operator()(local_of<null_tag> subject, const Accept& accept) -> accept_target_t<Accept> {
122
122
  return immediate(subject, accept);
123
123
  }
124
124
 
125
125
  template <class Accept>
126
- auto operator()(value_of<undefined_tag> subject, const Accept& accept) -> accept_target_t<Accept> {
126
+ auto operator()(local_of<undefined_tag> subject, const Accept& accept) -> accept_target_t<Accept> {
127
127
  return immediate(subject, accept);
128
128
  }
129
129
 
130
130
  template <class Accept>
131
- auto operator()(value_of<boolean_tag> subject, const Accept& accept) -> accept_target_t<Accept> {
131
+ auto operator()(local_of<boolean_tag> subject, const Accept& accept) -> accept_target_t<Accept> {
132
132
  return immediate(subject, accept);
133
133
  }
134
134
 
135
135
  template <class Accept>
136
- auto operator()(value_of<number_tag> subject, const Accept& accept) -> accept_target_t<Accept> {
136
+ auto operator()(local_of<number_tag> subject, const Accept& accept) -> accept_target_t<Accept> {
137
137
  if (maybe_is_number_int32(subject).value_or(false)) {
138
- return immediate(value_of<number_tag_of<std::int32_t>>::from(subject), accept);
138
+ return immediate(local_of<number_tag_of<std::int32_t>>::from(subject), accept);
139
139
  } else {
140
- return immediate(value_of<number_tag_of<double>>::from(subject), accept);
140
+ return immediate(local_of<number_tag_of<double>>::from(subject), accept);
141
141
  }
142
142
  }
143
143
 
144
144
  template <class Accept, class Type>
145
- auto operator()(value_of<number_tag_of<Type>> subject, const Accept& accept) -> accept_target_t<Accept> {
145
+ auto operator()(local_of<number_tag_of<Type>> subject, const Accept& accept) -> accept_target_t<Accept> {
146
146
  return immediate(subject, accept);
147
147
  }
148
148
 
@@ -151,32 +151,32 @@ struct visit_value : reference_map_t<Reference, reference_map_type> {
151
151
  auto operator()(napi_value subject, const Accept& accept) -> accept_target_t<Accept> {
152
152
 
153
153
  // Check the reference map, and lookup type via napi
154
- return lookup_or_visit(subject, [ & ]() -> accept_target_t<Accept> {
154
+ return lookup_or_visit(subject, [ & ] -> accept_target_t<Accept> {
155
155
  // This is the pure-napi implementation
156
156
  auto slow_path = util::overloaded{
157
- [ & ]() -> accept_target_t<Accept> {
157
+ [ & ] -> accept_target_t<Accept> {
158
158
  auto type_of = napi::invoke(napi_typeof, napi_env{*this}, subject);
159
159
  switch (type_of) {
160
160
  case napi_undefined:
161
- return (*this)(value_of<undefined_tag>::from(subject), accept);
161
+ return (*this)(local_of<undefined_tag>::from(subject), accept);
162
162
  case napi_null:
163
- return (*this)(value_of<null_tag>::from(subject), accept);
163
+ return (*this)(local_of<null_tag>::from(subject), accept);
164
164
  case napi_boolean:
165
- return (*this)(value_of<boolean_tag>::from(subject), accept);
165
+ return (*this)(local_of<boolean_tag>::from(subject), accept);
166
166
  case napi_number:
167
- return (*this)(value_of<number_tag>::from(subject), accept);
167
+ return (*this)(local_of<number_tag>::from(subject), accept);
168
168
  case napi_string:
169
- return immediate(value_of<string_tag>::from(subject), accept);
169
+ return immediate(local_of<string_tag>::from(subject), accept);
170
170
  case napi_symbol:
171
- return immediate(value_of<symbol_tag>::from(subject), accept);
171
+ return immediate(local_of<symbol_tag>::from(subject), accept);
172
172
  case napi_object:
173
- return immediate(value_of<object_tag>::from(subject), accept);
173
+ return immediate(local_of<object_tag>::from(subject), accept);
174
174
  case napi_function:
175
- return immediate(value_of<function_tag>::from(subject), accept);
175
+ return immediate(local_of<function_tag>::from(subject), accept);
176
176
  case napi_external:
177
- return immediate(value_of<external_tag>::from(subject), accept);
177
+ return immediate(local_of<external_tag>::from(subject), accept);
178
178
  case napi_bigint:
179
- return immediate(value_of<bigint_tag>::from(subject), accept);
179
+ return immediate(local_of<bigint_tag>::from(subject), accept);
180
180
  }
181
181
  std::unreachable();
182
182
  },
@@ -187,16 +187,16 @@ struct visit_value : reference_map_t<Reference, reference_map_type> {
187
187
  // Universal fast checks
188
188
  auto fast_path = util::overloaded{
189
189
  [ & ](undefined_tag /*tag*/, auto next) -> accept_target_t<Accept> {
190
- return fast_is_undefined(napi_env{*this}, subject) ? (*this)(value_of<undefined_tag>::from(subject), accept) : next();
190
+ return fast_is_undefined(napi_env{*this}, subject) ? (*this)(local_of<undefined_tag>::from(subject), accept) : next();
191
191
  },
192
192
  [ & ](null_tag /*tag*/, auto next) -> accept_target_t<Accept> {
193
- return fast_is_null(napi_env{*this}, subject) ? (*this)(value_of<null_tag>::from(subject), accept) : next();
193
+ return fast_is_null(napi_env{*this}, subject) ? (*this)(local_of<null_tag>::from(subject), accept) : next();
194
194
  },
195
195
  [ & ](boolean_tag /*tag*/, auto next) -> accept_target_t<Accept> {
196
196
  if (fast_is_false(napi_env{*this}, subject)) {
197
- return (*this)(value_of<false_tag>::from(subject), accept);
197
+ return (*this)(local_of<false_tag>::from(subject), accept);
198
198
  } else if (fast_is_true(napi_env{*this}, subject)) {
199
- return (*this)(value_of<true_tag>::from(subject), accept);
199
+ return (*this)(local_of<true_tag>::from(subject), accept);
200
200
  } else {
201
201
  return next();
202
202
  }
@@ -206,27 +206,27 @@ struct visit_value : reference_map_t<Reference, reference_map_type> {
206
206
  // Extended fast checks
207
207
  auto extended_fast_path = util::overloaded{
208
208
  [ & ](number_tag /*tag*/, auto next) -> accept_target_t<Accept> {
209
- return fast_is_number(subject) ? (*this)(value_of<number_tag>::from(subject), accept) : next();
209
+ return fast_is_number(subject) ? (*this)(local_of<number_tag>::from(subject), accept) : next();
210
210
  },
211
211
  [ & ](string_tag /*tag*/, auto next) -> accept_target_t<Accept> {
212
- return fast_is_string(subject) ? immediate(value_of<string_tag>::from(subject), accept) : next();
212
+ return fast_is_string(subject) ? immediate(local_of<string_tag>::from(subject), accept) : next();
213
213
  },
214
214
  [ & ](bigint_tag /*tag*/, auto next) -> accept_target_t<Accept> {
215
- return fast_is_bigint(subject) ? immediate(value_of<bigint_tag>::from(subject), accept) : next();
215
+ return fast_is_bigint(subject) ? immediate(local_of<bigint_tag>::from(subject), accept) : next();
216
216
  },
217
217
  [ & ](date_tag /*tag*/, auto next) -> accept_target_t<Accept> {
218
- return napi::invoke(napi_is_date, napi_env{*this}, subject) ? immediate(value_of<date_tag>::from(subject), accept) : next();
218
+ return napi::invoke(napi_is_date, napi_env{*this}, subject) ? immediate(local_of<date_tag>::from(subject), accept) : next();
219
219
  },
220
220
  [ & ](list_tag /*tag*/, auto next) -> accept_target_t<Accept> {
221
- return fast_is_array(subject) ? immediate(value_of<list_tag>::from(subject), accept) : next();
221
+ return fast_is_array(subject) ? immediate(local_of<list_tag>::from(subject), accept) : next();
222
222
  },
223
223
  [ & ](object_tag /*tag*/, auto next) -> accept_target_t<Accept> {
224
224
  // nb: You can't really skip the subsequent is promise, is date, is arraybuffer, etc
225
225
  // checks. We don't really want to accept those types here, I don't think..
226
- return fast_is_object(subject) ? immediate(value_of<object_tag>::from(subject), accept) : next();
226
+ return fast_is_object(subject) ? immediate(local_of<object_tag>::from(subject), accept) : next();
227
227
  },
228
228
  [ & ](function_tag /*tag*/, auto next) -> accept_target_t<Accept> {
229
- return fast_is_function(subject) ? immediate(value_of<function_tag>::from(subject), accept) : next();
229
+ return fast_is_function(subject) ? immediate(local_of<function_tag>::from(subject), accept) : next();
230
230
  },
231
231
 
232
232
  // Skip these, otherwise `number_tag` and `string_tag` are invoked twice, which we don't
@@ -246,8 +246,8 @@ struct visit_value : reference_map_t<Reference, reference_map_type> {
246
246
  }
247
247
 
248
248
  template <class Accept>
249
- auto operator()(value_of<data_block_tag> subject, const Accept& accept) -> accept_target_t<Accept> {
250
- return lookup_or_visit(subject, [ & ]() -> accept_target_t<Accept> {
249
+ auto operator()(local_of<data_block_tag> subject, const Accept& accept) -> accept_target_t<Accept> {
250
+ return lookup_or_visit(subject, [ & ] -> accept_target_t<Accept> {
251
251
  return util::template_traverse(
252
252
  accept_tags_of_v<Accept>,
253
253
  util::overloaded{
@@ -257,7 +257,7 @@ struct visit_value : reference_map_t<Reference, reference_map_type> {
257
257
  [ & ](shared_array_buffer_tag /*tag*/, auto next) -> accept_target_t<Accept> { return next(); },
258
258
 
259
259
  // Slow path
260
- [ & ]() -> accept_target_t<Accept> {
260
+ [ & ] -> accept_target_t<Accept> {
261
261
  return immediate(subject, accept);
262
262
  }
263
263
  }
@@ -274,79 +274,79 @@ struct visit_value : reference_map_t<Reference, reference_map_type> {
274
274
  // I think this only applies to `symbol_tag`
275
275
  template <class Accept, class Tag>
276
276
  requires std::is_convertible_v<Tag, primitive_tag>
277
- auto immediate(value_of<Tag> subject, const Accept& accept) -> accept_target_t<Accept> {
277
+ auto immediate(local_of<Tag> subject, const Accept& accept) -> accept_target_t<Accept> {
278
278
  return accept_tagged(subject, accept);
279
279
  }
280
280
 
281
281
  // strings
282
282
  template <class Accept>
283
- auto immediate(value_of<string_tag> subject, const Accept& accept) -> accept_target_t<Accept> {
283
+ auto immediate(local_of<string_tag> subject, const Accept& accept) -> accept_target_t<Accept> {
284
284
  if (maybe_is_string_latin1(subject).value_or(false)) {
285
- return accept_tagged(value_of<string_tag_of<char>>::from(subject), accept);
285
+ return accept_tagged(local_of<string_tag_of<char>>::from(subject), accept);
286
286
  } else {
287
- return accept_tagged(value_of<string_tag_of<char16_t>>::from(subject), accept);
287
+ return accept_tagged(local_of<string_tag_of<char16_t>>::from(subject), accept);
288
288
  }
289
289
  }
290
290
 
291
291
  // bigint
292
292
  template <class Accept>
293
- auto immediate(value_of<bigint_tag> subject, const Accept& accept) -> accept_target_t<Accept> {
294
- return accept_tagged(value_of<bigint_tag_of<bigint>>::from(subject), accept);
293
+ auto immediate(local_of<bigint_tag> subject, const Accept& accept) -> accept_target_t<Accept> {
294
+ return accept_tagged(local_of<bigint_tag_of<bigint>>::from(subject), accept);
295
295
  }
296
296
 
297
297
  // date
298
298
  template <class Accept>
299
- auto immediate(value_of<object_tag> subject, const Accept& accept) -> accept_target_t<Accept> {
299
+ auto immediate(local_of<object_tag> subject, const Accept& accept) -> accept_target_t<Accept> {
300
300
  if (napi::invoke(napi_is_array, napi_env{*this}, subject)) {
301
- return immediate(value_of<list_tag>::from(subject), accept);
301
+ return immediate(local_of<list_tag>::from(subject), accept);
302
302
  } else if (napi::invoke(napi_is_date, napi_env{*this}, subject)) {
303
- return immediate(value_of<date_tag>::from(subject), accept);
303
+ return immediate(local_of<date_tag>::from(subject), accept);
304
304
  } else if (napi::invoke(napi_is_typedarray, napi_env{*this}, subject)) {
305
- return immediate(value_of<typed_array_tag>::from(subject), accept);
305
+ return immediate(local_of<typed_array_tag>::from(subject), accept);
306
306
  } else if (napi::invoke(napi_is_dataview, napi_env{*this}, subject)) {
307
- return immediate(value_of<data_view_tag>::from(subject), accept);
307
+ return immediate(local_of<data_view_tag>::from(subject), accept);
308
308
  } else if (maybe_is_shared_array_buffer(env_.get(), subject).value_or(false)) {
309
- return immediate(value_of<shared_array_buffer_tag>::from(subject), accept);
309
+ return immediate(local_of<shared_array_buffer_tag>::from(subject), accept);
310
310
  } else if (is_object_array_buffer(env_.get(), subject)) {
311
- return immediate(value_of<array_buffer_tag>::from(subject), accept);
311
+ return immediate(local_of<array_buffer_tag>::from(subject), accept);
312
312
  } else if (napi::invoke(napi_is_promise, napi_env{*this}, subject)) {
313
- return immediate(value_of<promise_tag>::from(subject), accept);
313
+ return immediate(local_of<promise_tag>::from(subject), accept);
314
314
  } else {
315
- return immediate(value_of<dictionary_tag>::from(subject), accept);
315
+ return immediate(local_of<dictionary_tag>::from(subject), accept);
316
316
  }
317
317
  }
318
318
 
319
319
  // date
320
320
  template <class Accept>
321
- auto immediate(value_of<date_tag> subject, const Accept& accept) -> accept_target_t<Accept> {
321
+ auto immediate(local_of<date_tag> subject, const Accept& accept) -> accept_target_t<Accept> {
322
322
  return accept_tagged(subject, accept);
323
323
  }
324
324
 
325
325
  // data blocks
326
326
  template <class Accept>
327
- auto immediate(value_of<data_block_tag> subject, const Accept& accept) -> accept_target_t<Accept> {
327
+ auto immediate(local_of<data_block_tag> subject, const Accept& accept) -> accept_target_t<Accept> {
328
328
  if (is_data_block_array_buffer(env_.get(), subject)) {
329
- return immediate(value_of<array_buffer_tag>::from(subject), accept);
329
+ return immediate(local_of<array_buffer_tag>::from(subject), accept);
330
330
  } else {
331
- return immediate(value_of<shared_array_buffer_tag>::from(subject), accept);
331
+ return immediate(local_of<shared_array_buffer_tag>::from(subject), accept);
332
332
  }
333
333
  }
334
334
 
335
335
  template <class Accept, class Tag>
336
336
  requires std::is_convertible_v<Tag, data_block_tag>
337
- auto immediate(value_of<Tag> subject, const Accept& accept) -> accept_target_t<Accept> {
337
+ auto immediate(local_of<Tag> subject, const Accept& accept) -> accept_target_t<Accept> {
338
338
  return accept_tagged(subject, accept);
339
339
  }
340
340
 
341
341
  // array buffer views
342
342
  template <class Accept>
343
- auto immediate(value_of<typed_array_tag> subject, const Accept& accept) -> accept_target_t<Accept> {
344
- auto bound_subject_variant = bound_value_for_typed_array::make_bound(environment(), subject);
343
+ auto immediate(local_of<typed_array_tag> subject, const Accept& accept) -> accept_target_t<Accept> {
344
+ auto bound_subject_variant = value_for_typed_array::make_bound(environment(), subject);
345
345
  if (bound_subject_variant.index() == std::variant_npos) {
346
346
  std::unreachable();
347
347
  } else {
348
348
  return std::visit(
349
- [ & ]<class Tag>(bound_value<Tag> value) -> accept_target_t<Accept> {
349
+ [ & ]<class Tag>(value_of<Tag> value) -> accept_target_t<Accept> {
350
350
  return accept(Tag{}, *this, value);
351
351
  },
352
352
  bound_subject_variant
@@ -355,53 +355,87 @@ struct visit_value : reference_map_t<Reference, reference_map_type> {
355
355
  }
356
356
 
357
357
  template <class Accept>
358
- auto immediate(value_of<data_view_tag> subject, const Accept& accept) -> accept_target_t<Accept> {
358
+ auto immediate(local_of<data_view_tag> subject, const Accept& accept) -> accept_target_t<Accept> {
359
359
  return accept_tagged(subject, accept);
360
360
  }
361
361
 
362
362
  // externals
363
363
  template <class Accept>
364
- auto immediate(value_of<external_tag> subject, const Accept& accept) -> accept_target_t<Accept> {
364
+ auto immediate(local_of<external_tag> subject, const Accept& accept) -> accept_target_t<Accept> {
365
365
  return accept_tagged(subject, accept);
366
366
  }
367
367
 
368
368
  // promise
369
369
  template <class Accept>
370
- auto immediate(value_of<promise_tag> subject, const Accept& accept) -> accept_target_t<Accept> {
370
+ auto immediate(local_of<promise_tag> subject, const Accept& accept) -> accept_target_t<Accept> {
371
371
  return accept_tagged(subject, accept);
372
372
  }
373
373
 
374
374
  // function
375
375
  template <class Accept>
376
- auto immediate(value_of<function_tag> subject, const Accept& accept) -> accept_target_t<Accept> {
376
+ auto immediate(local_of<function_tag> subject, const Accept& accept) -> accept_target_t<Accept> {
377
377
  return accept_tagged(subject, accept);
378
378
  }
379
379
 
380
380
  // array
381
381
  template <class Accept>
382
- auto immediate(value_of<list_tag> subject, const Accept& accept) -> accept_target_t<Accept> {
383
- auto target = napi::bound_value{napi_env{*this}, value_of<list_tag>::from(subject)};
382
+ auto immediate(local_of<list_tag> subject, const Accept& accept) -> accept_target_t<Accept> {
383
+ auto target = napi::value_of{napi_env{*this}, local_of<list_tag>::from(subject)};
384
384
  auto visit_entry = visit_entry_pair<visit_property_name<visit_value>, visit_value&>{*this};
385
385
  return accept(list_tag{}, visit_entry, target);
386
386
  }
387
387
 
388
388
  // object / record
389
389
  template <class Accept>
390
- auto immediate(value_of<dictionary_tag> subject, const Accept& accept) -> accept_target_t<Accept> {
391
- auto target = napi::bound_value{napi_env{*this}, value_of<dictionary_tag>::from(subject)};
390
+ auto immediate(local_of<dictionary_tag> subject, const Accept& accept) -> accept_target_t<Accept> {
391
+ auto target = napi::value_of{napi_env{*this}, local_of<dictionary_tag>::from(subject)};
392
392
  auto visit_entry = visit_entry_pair<visit_property_name<visit_value>, visit_value&>{*this};
393
393
  return accept(dictionary_tag{}, visit_entry, target);
394
394
  }
395
395
 
396
- // Convenience function which wraps in `napi::bound_value` and invokes `accept`.
396
+ // Convenience function which wraps in `napi::value_of` and invokes `accept`.
397
397
  template <class Tag, class Accept>
398
- [[nodiscard]] auto accept_tagged(value_of<Tag> subject, const Accept& accept) -> accept_target_t<Accept> {
399
- return accept(Tag{}, *this, napi::bound_value{environment(), subject});
398
+ [[nodiscard]] auto accept_tagged(local_of<Tag> subject, const Accept& accept) -> accept_target_t<Accept> {
399
+ return accept(Tag{}, *this, napi::value_of{environment(), subject});
400
400
  }
401
401
 
402
402
  std::reference_wrapper<Environment> env_;
403
403
  };
404
404
 
405
+ // Forward `value_of<T>` back to acceptor
406
+ template <class Meta, class Tag>
407
+ struct visit_napi_value_of {
408
+ private:
409
+ using visit_type = visit_value_with<Meta>;
410
+
411
+ public:
412
+ constexpr explicit visit_napi_value_of(auto* transfer, auto& environment) : visit_{transfer, environment} {}
413
+
414
+ template <class Accept>
415
+ constexpr auto operator()(value_of<Tag> subject, const Accept& accept) -> accept_target_t<Accept> {
416
+ return accept(Tag{}, visit_, subject);
417
+ }
418
+
419
+ template <class Accept>
420
+ requires std::is_same_v<Tag, object_tag>
421
+ constexpr auto operator()(value_of<object_tag> subject, const Accept& accept) -> accept_target_t<Accept> {
422
+ auto visit_entry = visit_entry_pair<visit_property_name<visit_type>, visit_type&>{visit_};
423
+ return accept(object_tag{}, visit_entry, subject);
424
+ }
425
+
426
+ template <class Accept>
427
+ requires std::is_same_v<Tag, list_tag>
428
+ constexpr auto operator()(value_of<list_tag> subject, const Accept& accept) -> accept_target_t<Accept> {
429
+ auto visit_entry = visit_entry_pair<visit_property_name<visit_type>, visit_type&>{visit_};
430
+ return accept(list_tag{}, visit_entry, subject);
431
+ }
432
+
433
+ consteval static auto types(auto /*recursive*/) { return util::type_pack{}; }
434
+
435
+ private:
436
+ visit_type visit_;
437
+ };
438
+
405
439
  } // namespace js::napi
406
440
 
407
441
  namespace js {
@@ -413,10 +447,19 @@ struct visit<Meta, napi_value> : napi::visit_value_with<Meta> {
413
447
  };
414
448
 
415
449
  template <class Meta, class Tag>
416
- struct visit<Meta, napi::value_of<Tag>> : napi::visit_value_with<Meta> {
450
+ struct visit<Meta, napi::local_of<Tag>> : napi::visit_value_with<Meta> {
417
451
  using napi::visit_value_with<Meta>::visit_value_with;
418
452
  };
419
453
 
454
+ // Pass through `value_of<Tag>`
455
+ template <class Meta, class Tag>
456
+ struct visit<Meta, napi::value_of<Tag>> : napi::visit_napi_value_of<Meta, Tag> {
457
+ using napi::visit_napi_value_of<Meta, Tag>::visit_napi_value_of;
458
+ };
459
+
460
+ template <class Tag>
461
+ struct visit_subject_for<napi::value_of<Tag>> : std::type_identity<napi_value> {};
462
+
420
463
  // Object key maker via napi
421
464
  template <auto Key>
422
465
  struct visit_key_literal<Key, napi_value> : napi::visit_napi_key_literal<Key> {
package/value/array.cc CHANGED
@@ -1,29 +1,27 @@
1
1
  module napi_js;
2
- import :api;
3
- import :bound_value;
4
2
 
5
3
  namespace js::napi {
6
4
 
7
- auto bound_value_for_vector::begin() const -> iterator {
5
+ auto value_for_vector::begin() const -> iterator {
8
6
  return {*this, 0};
9
7
  }
10
8
 
11
- auto bound_value_for_vector::end() const -> iterator {
9
+ auto value_for_vector::end() const -> iterator {
12
10
  return {*this, size()};
13
11
  }
14
12
 
15
- auto bound_value_for_vector::size() const -> std::uint32_t {
13
+ auto value_for_vector::size() const -> std::uint32_t {
16
14
  if (size_ == 0) {
17
15
  size_ = napi::invoke(napi_get_array_length, env(), napi_value{*this}) + 1;
18
16
  }
19
17
  return size_ - 1;
20
18
  }
21
19
 
22
- bound_value_for_vector::iterator::iterator(bound_value_for_vector subject, size_type index) :
20
+ value_for_vector::iterator::iterator(value_for_vector subject, size_type index) :
23
21
  subject_{subject},
24
22
  index_{index} {}
25
23
 
26
- auto bound_value_for_vector::iterator::operator*() const -> value_type {
24
+ auto value_for_vector::iterator::operator*() const -> value_type {
27
25
  return value_type::from(napi::invoke(napi_get_element, subject_.env(), napi_value{subject_}, index_));
28
26
  }
29
27
 
package/value/array.h.cc CHANGED
@@ -5,11 +5,11 @@ import util;
5
5
 
6
6
  namespace js::napi {
7
7
 
8
- class bound_value_for_vector : public bound_value_next<vector_tag> {
8
+ class value_for_vector : public value_next<vector_tag> {
9
9
  public:
10
10
  class iterator;
11
- using bound_value_next<vector_tag>::bound_value_next;
12
- using value_type = value_of<value_tag>;
11
+ using value_next<vector_tag>::value_next;
12
+ using value_type = local_of<value_tag>;
13
13
 
14
14
  [[nodiscard]] auto begin() const -> iterator;
15
15
  [[nodiscard]] auto end() const -> iterator;
@@ -19,15 +19,15 @@ class bound_value_for_vector : public bound_value_next<vector_tag> {
19
19
  mutable std::uint32_t size_{};
20
20
  };
21
21
 
22
- class bound_value_for_vector::iterator : public util::random_access_iterator_facade<std::int32_t, std::int64_t> {
22
+ class value_for_vector::iterator : public util::random_access_iterator_facade<std::int32_t, std::int64_t> {
23
23
  public:
24
24
  using arithmetic_facade::operator+;
25
25
  using difference_type = arithmetic_facade::difference_type;
26
26
  using size_type = std::uint32_t;
27
- using value_type = bound_value_for_vector::value_type;
27
+ using value_type = value_for_vector::value_type;
28
28
 
29
29
  iterator() = default;
30
- iterator(bound_value_for_vector subject, size_type index);
30
+ iterator(value_for_vector subject, size_type index);
31
31
 
32
32
  auto operator*() const -> value_type;
33
33
 
@@ -42,7 +42,7 @@ class bound_value_for_vector::iterator : public util::random_access_iterator_fac
42
42
  private:
43
43
  auto operator+() const -> size_type { return index_; }
44
44
 
45
- bound_value_for_vector subject_;
45
+ value_for_vector subject_;
46
46
  size_type index_{};
47
47
  };
48
48
 
@@ -1,14 +1,11 @@
1
1
  module napi_js;
2
- import :api;
3
- import :array_buffer;
4
- import :support.host;
5
2
  import std;
6
3
  import v8;
7
4
 
8
5
  namespace js::napi {
9
6
 
10
- // `bound_value_for_data_block`
11
- bound_value_for_data_block::operator std::span<std::byte>() const {
7
+ // `value_for_data_block`
8
+ value_for_data_block::operator std::span<std::byte>() const {
12
9
  // NOLINTNEXTLINE(cppcoreguidelines-init-variables)
13
10
  void* bytes;
14
11
  // NOLINTNEXTLINE(cppcoreguidelines-init-variables)
@@ -17,25 +14,25 @@ bound_value_for_data_block::operator std::span<std::byte>() const {
17
14
  return std::span{reinterpret_cast<std::byte*>(bytes), byte_length};
18
15
  }
19
16
 
20
- // `bound_value_for_array_buffer`
21
- bound_value_for_array_buffer::operator js::array_buffer() const {
17
+ // `value_for_array_buffer`
18
+ value_for_array_buffer::operator js::array_buffer() const {
22
19
  return js::array_buffer{std::span<std::byte>{*this}};
23
20
  }
24
21
 
25
- // `bound_value_for_shared_array_buffer`
26
- bound_value_for_shared_array_buffer::operator js::shared_array_buffer() const {
27
- auto byte_length = shared_array_buffer_get_byte_length(value_of{*this});
28
- auto backing_store = shared_array_buffer_get_backing_store(value_of{*this});
22
+ // `value_for_shared_array_buffer`
23
+ value_for_shared_array_buffer::operator js::shared_array_buffer() const {
24
+ auto byte_length = shared_array_buffer_get_byte_length(local_of{*this});
25
+ auto backing_store = shared_array_buffer_get_backing_store(local_of{*this});
29
26
  return js::shared_array_buffer{byte_length, std::move(backing_store)};
30
27
  }
31
28
 
32
- // `value_for_typed_array`
33
- auto value_for_typed_array::make(const environment& env, napi_typedarray_type type_tag, value_of<array_buffer_tag> buffer, std::size_t byte_offset, std::size_t length) -> value_of<typed_array_tag> {
34
- return value_of<typed_array_tag>::from(napi::invoke(napi_create_typedarray, napi_env{env}, type_tag, length, napi_value{buffer}, byte_offset));
29
+ // `local_for_typed_array`
30
+ auto local_for_typed_array::make(const environment& env, napi_typedarray_type type_tag, local_of<array_buffer_tag> buffer, std::size_t byte_offset, std::size_t length) -> local_of<typed_array_tag> {
31
+ return local_of<typed_array_tag>::from(napi::invoke(napi_create_typedarray, napi_env{env}, type_tag, length, napi_value{buffer}, byte_offset));
35
32
  }
36
33
 
37
- // `bound_value_for_typed_array`
38
- auto bound_value_for_typed_array::make_bound(const environment& env, value_of<typed_array_tag> typed_array) -> any_bound_typed_array {
34
+ // `value_for_typed_array`
35
+ auto value_for_typed_array::make_bound(const environment& env, local_of<typed_array_tag> typed_array) -> any_value_typed_array {
39
36
  // NOLINTNEXTLINE(cppcoreguidelines-init-variables)
40
37
  napi_typedarray_type type_tag;
41
38
  // NOLINTNEXTLINE(cppcoreguidelines-init-variables)
@@ -45,8 +42,8 @@ auto bound_value_for_typed_array::make_bound(const environment& env, value_of<ty
45
42
  // NOLINTNEXTLINE(cppcoreguidelines-init-variables)
46
43
  std::size_t byte_offset;
47
44
  napi::invoke0(napi_get_typedarray_info, env, napi_value{typed_array}, &type_tag, &length, nullptr, &array_buffer, &byte_offset);
48
- const auto make = [ & ]<class Tag>(Tag /*tag*/) -> any_bound_typed_array {
49
- return bound_value<Tag>{env, value_of<Tag>::from(typed_array), std::tuple{value_of<data_block_tag>::from(array_buffer), byte_offset, length}};
45
+ const auto make = [ & ]<class Tag>(Tag /*tag*/) -> any_value_typed_array {
46
+ return value_of<Tag>{env, local_of<Tag>::from(typed_array), std::tuple{local_of<data_block_tag>::from(array_buffer), byte_offset, length}};
50
47
  };
51
48
  switch (type_tag) {
52
49
  case napi_bigint64_array: return make(typed_array_tag_of<std::int64_t>{});
@@ -65,26 +62,26 @@ auto bound_value_for_typed_array::make_bound(const environment& env, value_of<ty
65
62
  std::unreachable();
66
63
  }
67
64
 
68
- // `value_for_data_view`
69
- auto value_for_data_view::make(const environment& env, value_of<data_block_tag> buffer, std::size_t byte_offset, std::size_t length) -> value_of<data_view_tag> {
65
+ // `local_for_data_view`
66
+ auto local_for_data_view::make(const environment& env, local_of<data_block_tag> buffer, std::size_t byte_offset, std::size_t length) -> local_of<data_view_tag> {
70
67
  if (napi::invoke(napi_is_arraybuffer, napi_env{env}, buffer)) {
71
- return make(env, value_of<array_buffer_tag>::from(buffer), byte_offset, length);
68
+ return make(env, local_of<array_buffer_tag>::from(buffer), byte_offset, length);
72
69
  } else {
73
- return make(env, value_of<shared_array_buffer_tag>::from(buffer), byte_offset, length);
70
+ return make(env, local_of<shared_array_buffer_tag>::from(buffer), byte_offset, length);
74
71
  }
75
72
  }
76
73
 
77
- auto value_for_data_view::make(const environment& env, value_of<array_buffer_tag> buffer, std::size_t byte_offset, std::size_t length) -> value_of<data_view_tag> {
78
- return value_of<data_view_tag>::from(napi::invoke(napi_create_dataview, napi_env{env}, length, napi_value{buffer}, byte_offset));
74
+ auto local_for_data_view::make(const environment& env, local_of<array_buffer_tag> buffer, std::size_t byte_offset, std::size_t length) -> local_of<data_view_tag> {
75
+ return local_of<data_view_tag>::from(napi::invoke(napi_create_dataview, napi_env{env}, length, napi_value{buffer}, byte_offset));
79
76
  }
80
77
 
81
- auto value_for_data_view::make(const environment& /*env*/, value_of<shared_array_buffer_tag> buffer, std::size_t byte_offset, std::size_t length) -> value_of<data_view_tag> {
78
+ auto local_for_data_view::make(const environment& /*env*/, local_of<shared_array_buffer_tag> buffer, std::size_t byte_offset, std::size_t length) -> local_of<data_view_tag> {
82
79
  return make_sab_data_view(buffer, byte_offset, length);
83
80
  }
84
81
 
85
- // `bound_value_for_data_view`
86
- bound_value_for_data_view::bound_value_for_data_view(napi_env env, value_of<data_view_tag> data_view) :
87
- bound_value_next{
82
+ // `value_for_data_view`
83
+ value_for_data_view::value_for_data_view(napi_env env, local_of<data_view_tag> data_view) :
84
+ value_next{
88
85
  env,
89
86
  data_view,
90
87
  [ & ] -> auto {
@@ -95,7 +92,7 @@ bound_value_for_data_view::bound_value_for_data_view(napi_env env, value_of<data
95
92
  // NOLINTNEXTLINE(cppcoreguidelines-init-variables)
96
93
  std::size_t byte_offset;
97
94
  napi::invoke0(napi_get_dataview_info, env, napi_value{data_view}, &length, nullptr, &array_buffer, &byte_offset);
98
- return std::tuple{value_of<data_block_tag>::from(array_buffer), byte_offset, length};
95
+ return std::tuple{local_of<data_block_tag>::from(array_buffer), byte_offset, length};
99
96
  }(),
100
97
  } {}
101
98