@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/CMakeLists.txt CHANGED
@@ -38,7 +38,7 @@ target_sources(${napi_js}
38
38
  api/uv_dlib.h.cc
39
39
  api/uv_handle.cc
40
40
  api/uv_scheduler.h.cc
41
- handle/bound_value.cc
41
+ handle/local.cc
42
42
  handle/reference.cc
43
43
  handle/remote.cc
44
44
  handle/types.cc
package/README.md CHANGED
@@ -181,20 +181,20 @@ struct enum_values<enum_test> {
181
181
 
182
182
  ## Variants
183
183
 
184
- `std::variant<std::u16string, double>` could be used to accept *either* a string or a number value.
185
- You can mix and match types as needed.
184
+ `std::variant<std::u16string, std::string, double, std::int32_t>` could be used to accept *either* a
185
+ string or a number value. You can mix and match types as needed. If you use one of the covariant
186
+ types then you must also use its alternative. `std::u16string, std::string`, `double, std::int32_t`,
187
+ and `std::int64_t, js::bigint`.
186
188
 
187
189
 
188
190
  ## Covariants
189
191
 
190
192
  `std::variant<double, int32_t>` can be used to accept *either* a floating point or a signed integer.
191
193
  Note that this uses runtime function calls to resolve the covariance. In v8 it will invoke
192
- `value->IsInt32()` to discover what to return. Napi does not support this, so a `double` will always
193
- be returned.
194
+ `value->IsInt32()` to discover what to return.
194
195
 
195
- `std::variant<std::string, std::u16string>` can be used in a similar way to accept either a UTF-16
196
+ `std::variant<std::u16string, std::string>` can be used in a similar way to accept either a UTF-16
196
197
  string or the optimized ASCII string. This uses `value->IsOneByte()` to resolve the covariance.
197
- Again, in napi a UTF-16 string will always be returned.
198
198
 
199
199
 
200
200
  ## Structures
@@ -274,8 +274,8 @@ export class database {
274
274
  using transfer_type = js::tagged_external<database>;
275
275
 
276
276
  auto query(environment& env, std::string query) -> std::string;
277
- static auto connect(environment& env, std::string uri) -> js::forward<js::napi::value_of<>>;
278
- static auto class_template(environment& env) -> js::napi::value_of<class_tag_of<database>> {
277
+ static auto connect(environment& env, std::string uri) -> js::forward<js::napi::local_of<>>;
278
+ static auto class_template(environment& env) -> js::napi::local_of<class_tag_of<database>> {
279
279
  // incomplete
280
280
  }
281
281
  };
package/_module.cc CHANGED
@@ -1,20 +1,21 @@
1
1
  export module napi_js;
2
2
  export import :accept;
3
3
  export import :api;
4
- export import :bound_value;
5
4
  export import :callback;
6
5
  export import :class_definitions;
7
6
  export import :class_template_storage;
8
7
  export import :environment;
9
8
  export import :error_scope;
10
9
  export import :function_definitions;
10
+ export import :handle.local_of;
11
11
  export import :handle.types;
12
+ export import :handle.value_of;
12
13
  export import :initialize;
13
14
  export import :promise;
14
15
  export import :reference;
15
16
  export import :remote;
16
17
  export import :string_table;
18
+ export import :support.host;
17
19
  export import :utility;
18
- export import :value_handle;
19
20
  export import :value;
20
21
  export import :visit;
package/api/finalizer.cc CHANGED
@@ -43,7 +43,7 @@ auto make_finalizer(std::type_identity<Env> /*type*/, std::shared_ptr<Type> shar
43
43
  template <class Pointer, class Apply>
44
44
  auto apply_finalizer(Pointer smart_ptr, Apply apply) -> decltype(auto) {
45
45
  using element_type = Pointer::element_type;
46
- constexpr auto napi_env_type = []() consteval -> auto {
46
+ constexpr auto napi_env_type = [] consteval -> auto {
47
47
  if constexpr (std::invocable<Apply, element_type*, node_api_basic_finalize, void*>) {
48
48
  return type<node_api_basic_env>;
49
49
  } else {
@@ -48,7 +48,7 @@ class threadsafe_function_of : util::non_copyable {
48
48
 
49
49
  template <class Context, class Message>
50
50
  threadsafe_function_of<Context, Message>::threadsafe_function_of(auto& env, napi_value value, auto&&... args) :
51
- tsfn_{[ & ]() -> auto {
51
+ tsfn_{[ & ] -> auto {
52
52
  constexpr auto name = util::make_consteval_string_view(util::cw<"threadsafe_function_of">);
53
53
  auto resource_name = napi::invoke(napi_create_string_latin1, env, name.data(), name.size());
54
54
  auto context = std::make_unique<storage>(std::forward<decltype(args)>(args)...);
@@ -57,9 +57,7 @@ threadsafe_function_of<Context, Message>::threadsafe_function_of(auto& env, napi
57
57
  auto& context = *static_cast<storage*>(context_ptr);
58
58
  if constexpr (trivial_message) {
59
59
  if (env != nullptr) {
60
- auto message = Message{};
61
- std::memcpy(&message, &data, sizeof(Message));
62
- context(env, value, message);
60
+ context(env, value, util::bit_truncation_cast<Message>(data));
63
61
  }
64
62
  } else {
65
63
  auto message = std::unique_ptr<Message>{static_cast<Message*>(data)};
@@ -134,8 +132,7 @@ auto threadsafe_function_of<Context, Message>::operator()(Message message) const
134
132
  }
135
133
  };
136
134
  if constexpr (trivial_message) {
137
- void* data{};
138
- std::memcpy(&data, &message, sizeof(Message));
135
+ auto* data = util::bit_padding_cast<void*>(message);
139
136
  return check(napi_call_threadsafe_function(tsfn_, data, napi_tsfn_nonblocking));
140
137
  } else {
141
138
  auto message_ptr = std::make_unique<Message>(std::move(message));
@@ -50,7 +50,7 @@ auto uv_scheduler::operator()(auto task, auto&&... args) const -> void {
50
50
  if (shared->is_open) {
51
51
  shared->tasks.emplace_back(
52
52
  [ task = std::move(task),
53
- ... args = std::forward<decltype(args)>(args) ]() mutable -> void {
53
+ ... args = std::forward<decltype(args)>(args) ] mutable -> void {
54
54
  task(std::move(args)...);
55
55
  }
56
56
  );
@@ -0,0 +1,112 @@
1
+ export module napi_js:handle.local_of;
2
+ import :handle.types;
3
+ import auto_js;
4
+ import nodejs;
5
+ import std;
6
+ import util;
7
+
8
+ namespace js::napi {
9
+
10
+ // Map of `local_of<Tag>` to its concrete implementation class
11
+ template <class Tag>
12
+ struct local_specialization;
13
+
14
+ // Tagged napi_value. Each `local_of<T>` inherits from the tag before it which makes overloading
15
+ // acceptor functions naturally hierarchical.
16
+ export template <class Tag>
17
+ class local_of : public local_of<typename Tag::tag_type> {
18
+ protected:
19
+ using local_type = local_specialization<Tag>::type;
20
+ explicit local_of(napi_value value) : local_of<typename Tag::tag_type>{value} {}
21
+
22
+ public:
23
+ local_of() = default;
24
+ using tag_type = Tag;
25
+
26
+ // Constructor from tagged `runtime_handle` flavors
27
+ explicit local_of(local_type value)
28
+ requires(type<local_type> != type<runtime_handle>) :
29
+ local_of{napi_value{value}} {}
30
+
31
+ // "Downcast" to a more specific tag. Potentially unsafe.
32
+ template <std::convertible_to<Tag> To>
33
+ auto cast(To /*tag*/) const -> local_of<To> { return local_of<To>::from(*this); }
34
+
35
+ // Construct from any `napi_value`. Potentially unsafe.
36
+ static auto from(napi_value value_) -> local_of<Tag> { return std::bit_cast<local_of<Tag>>(value_); }
37
+
38
+ // Forward `make` to specialization
39
+ static auto make(auto&&... args) -> local_of<Tag> { return local_type::make(std::forward<decltype(args)>(args)...); }
40
+
41
+ // Dereference operators
42
+ auto operator*() const -> local_type { return std::bit_cast<local_type>(napi_value{*this}); }
43
+ auto operator->() const -> auto { return util::pointer_delegate{**this}; }
44
+ };
45
+
46
+ // Sentinel instantiation
47
+ template <>
48
+ class local_of<void> : public runtime_handle {
49
+ public:
50
+ using runtime_handle::runtime_handle;
51
+ };
52
+
53
+ // Deduction guide
54
+ template <class Type>
55
+ local_of(Type value) -> local_of<typename Type::tag_type>;
56
+
57
+ // Details applied to each level of the `local_of<T>` hierarchy.
58
+ template <class Tag>
59
+ struct local_next : local_specialization<typename Tag::tag_type>::type {
60
+ using local_specialization<typename Tag::tag_type>::type::type;
61
+ using tag_type = Tag;
62
+ };
63
+
64
+ // `local_of<Tag>` implementation specializations. The default specialization selects the nearest
65
+ // specialization, or simply `runtime_handle` as the base class.
66
+ template <class Type> class local_for_class_of;
67
+ template <class Type> class local_for_typed_array_of;
68
+
69
+ template <class Tag>
70
+ struct local_specialization
71
+ : local_specialization<typename Tag::tag_type> {};
72
+
73
+ template <>
74
+ struct local_specialization<void>
75
+ : std::type_identity<runtime_handle> {};
76
+
77
+ template <>
78
+ struct local_specialization<object_tag>
79
+ : std::type_identity<class local_for_object> {};
80
+
81
+ template <>
82
+ struct local_specialization<function_tag>
83
+ : std::type_identity<class local_for_function> {};
84
+
85
+ template <>
86
+ struct local_specialization<typed_array_tag>
87
+ : std::type_identity<class local_for_typed_array> {};
88
+
89
+ template <class Type>
90
+ struct local_specialization<typed_array_tag_of<Type>>
91
+ : std::type_identity<class local_for_typed_array_of<Type>> {};
92
+
93
+ template <>
94
+ struct local_specialization<data_view_tag>
95
+ : std::type_identity<class local_for_data_view> {};
96
+
97
+ template <class Type>
98
+ struct local_specialization<class_tag_of<Type>>
99
+ : std::type_identity<class local_for_class_of<Type>> {};
100
+
101
+ template <>
102
+ struct local_specialization<external_tag>
103
+ : std::type_identity<class local_for_external> {};
104
+
105
+ } // namespace js::napi
106
+
107
+ // Specialize for `js::forward`. Makes `js::forward{local_of<Tag>}` infer
108
+ // `js::forward<Tag, ...>`.
109
+ namespace js {
110
+ template <class Tag>
111
+ struct forward_tag_for<napi::local_of<Tag>> : std::type_identity<Tag> {};
112
+ } // namespace js
@@ -1,6 +1,6 @@
1
1
  export module napi_js:reference;
2
2
  import :api;
3
- import :value_handle;
3
+ import :handle.local_of;
4
4
  import std;
5
5
  import util;
6
6
 
@@ -72,7 +72,7 @@ class reference_handle : util::non_copyable {
72
72
  export template <class Tag>
73
73
  class reference : public reference<typename Tag::tag_type> {
74
74
  public:
75
- using value_type = value_of<Tag>;
75
+ using value_type = local_of<Tag>;
76
76
  using reference<typename Tag::tag_type>::reference;
77
77
 
78
78
  reference() = default;
@@ -86,7 +86,7 @@ class reference : public reference<typename Tag::tag_type> {
86
86
  };
87
87
 
88
88
  template <class Tag>
89
- reference(auto, value_of<Tag>) -> reference<Tag>;
89
+ reference(auto, local_of<Tag>) -> reference<Tag>;
90
90
 
91
91
  // nb: Protected inheritance so that `remote<T> is not comparable to `reference<T>`.
92
92
  template <>
package/handle/remote.cc CHANGED
@@ -24,14 +24,14 @@ class remote : protected reference_handle {
24
24
  using unique_remote = std::unique_ptr<remote, util::function_constant<expire>>;
25
25
 
26
26
  remote() = default;
27
- remote(private_constructor /*private*/, const environment& env, value_of<Tag> value, napi_scheduler scheduler) :
27
+ remote(private_constructor /*private*/, const environment& env, local_of<Tag> value, napi_scheduler scheduler) :
28
28
  reference_handle{napi_env{env}, napi_value{value}},
29
29
  scheduler_{std::move(scheduler)} {}
30
30
 
31
- auto deref(const environment& env) const -> value_of<Tag>;
31
+ auto deref(const environment& env) const -> local_of<Tag>;
32
32
 
33
- static auto make_shared(remote_handle_environment auto& env, value_of<Tag> value) -> std::shared_ptr<remote>;
34
- static auto make_unique(remote_handle_environment auto& env, value_of<Tag> value) -> unique_remote;
33
+ static auto make_shared(remote_handle_environment auto& env, local_of<Tag> value) -> std::shared_ptr<remote>;
34
+ static auto make_unique(remote_handle_environment auto& env, local_of<Tag> value) -> unique_remote;
35
35
 
36
36
  private:
37
37
  napi_scheduler scheduler_;
@@ -45,12 +45,12 @@ export template <class Type>
45
45
  using unique_remote = remote<Type>::unique_remote;
46
46
 
47
47
  export template <class Tag>
48
- auto make_shared_remote(remote_handle_environment auto& env, value_of<Tag> value) -> shared_remote<Tag> {
48
+ auto make_shared_remote(remote_handle_environment auto& env, local_of<Tag> value) -> shared_remote<Tag> {
49
49
  return remote<Tag>::make_shared(env, value);
50
50
  }
51
51
 
52
52
  export template <class Tag>
53
- auto make_unique_remote(remote_handle_environment auto& env, value_of<Tag> value) -> unique_remote<Tag> {
53
+ auto make_unique_remote(remote_handle_environment auto& env, local_of<Tag> value) -> unique_remote<Tag> {
54
54
  return remote<Tag>::make_unique(env, value);
55
55
  }
56
56
 
@@ -68,17 +68,17 @@ auto remote<Tag>::expire(remote* ptr) -> void {
68
68
  }
69
69
 
70
70
  template <class Tag>
71
- auto remote<Tag>::deref(const environment& env) const -> value_of<Tag> {
72
- return value_of<Tag>::from(get_value(napi_env{env}));
71
+ auto remote<Tag>::deref(const environment& env) const -> local_of<Tag> {
72
+ return local_of<Tag>::from(get_value(napi_env{env}));
73
73
  }
74
74
 
75
75
  template <class Tag>
76
- auto remote<Tag>::make_shared(remote_handle_environment auto& env, value_of<Tag> value) -> std::shared_ptr<remote> {
76
+ auto remote<Tag>::make_shared(remote_handle_environment auto& env, local_of<Tag> value) -> std::shared_ptr<remote> {
77
77
  return std::shared_ptr<remote>{new remote{private_constructor{}, env, value, env.scheduler()}, expire};
78
78
  }
79
79
 
80
80
  template <class Tag>
81
- auto remote<Tag>::make_unique(remote_handle_environment auto& env, value_of<Tag> value) -> unique_remote {
81
+ auto remote<Tag>::make_unique(remote_handle_environment auto& env, local_of<Tag> value) -> unique_remote {
82
82
  return unique_remote{new remote{private_constructor{}, env, value, env.scheduler()}};
83
83
  }
84
84
 
package/handle/types.cc CHANGED
@@ -4,14 +4,13 @@ import nodejs;
4
4
 
5
5
  namespace js::napi {
6
6
 
7
- // `value_handle` is the base class of `value_of<T>`, and `bound_value<T>`.
8
- class value_handle {
7
+ // `runtime_handle` is the base class of `local_of<T>` and `value_of<T>` member types.
8
+ class runtime_handle {
9
9
  protected:
10
- explicit value_handle(napi_value value) :
11
- value_{value} {}
12
-
13
10
  public:
14
- value_handle() = default;
11
+ explicit runtime_handle(int, napi_value value) : value_{value} {}
12
+ explicit runtime_handle(napi_value value) : value_{value} {}
13
+ runtime_handle() = default;
15
14
 
16
15
  // Implicit cast back to a `napi_value`
17
16
  // NOLINTNEXTLINE(google-explicit-constructor)
@@ -24,143 +23,11 @@ class value_handle {
24
23
  napi_value value_{};
25
24
  };
26
25
 
27
- // `value_of` forward declarations
26
+ // Forward declarations for handle types which declare template deduction guides on each other.
28
27
  export template <class Tag = value_tag>
29
- class value_of;
30
-
31
- template <class Tag>
32
- class value_next;
33
-
34
- template <class Type>
35
- class value_for_class_of;
36
-
37
- template <class Type>
38
- class value_for_typed_array_of;
39
-
40
- // `bound_value` forward declarations
41
- template <class Tag>
42
- class bound_value;
43
-
44
- template <class Tag>
45
- class bound_value_next;
46
-
47
- template <class Type>
48
- class bound_value_for_typed_array_of;
49
-
50
- // Map of `value_of<Tag>` / `bound_value<Tag>` to concrete implementation classes.
51
- template <class Tag>
52
- struct value_defaults {
53
- using value_type = value_next<Tag>;
54
- using bound_type = bound_value_next<Tag>;
55
- };
56
-
57
- template <class Tag>
58
- struct value_specialization : value_defaults<Tag> {};
59
-
60
- // Typed specializations
61
- template <>
62
- struct value_specialization<boolean_tag> : value_defaults<boolean_tag> {
63
- using bound_type = class bound_value_for_boolean;
64
- };
65
-
66
- template <>
67
- struct value_specialization<false_tag> : value_defaults<false_tag> {
68
- using bound_type = class bound_value_for_false;
69
- };
70
-
71
- template <>
72
- struct value_specialization<true_tag> : value_defaults<true_tag> {
73
- using bound_type = class bound_value_for_true;
74
- };
75
-
76
- template <>
77
- struct value_specialization<number_tag> : value_defaults<number_tag> {
78
- using bound_type = class bound_value_for_number;
79
- };
80
-
81
- template <>
82
- struct value_specialization<bigint_tag> : value_defaults<bigint_tag> {
83
- using bound_type = class bound_value_for_bigint;
84
- };
85
-
86
- template <>
87
- struct value_specialization<string_tag> : value_defaults<string_tag> {
88
- using bound_type = class bound_value_for_string;
89
- };
90
-
91
- template <>
92
- struct value_specialization<date_tag> : value_defaults<date_tag> {
93
- using bound_type = class bound_value_for_date;
94
- };
95
-
96
- template <>
97
- struct value_specialization<object_tag> {
98
- using value_type = class value_for_object;
99
- using bound_type = class bound_value_for_object;
100
- };
101
-
102
- template <>
103
- struct value_specialization<record_tag> : value_defaults<record_tag> {
104
- using bound_type = class bound_value_for_record;
105
- };
106
-
107
- template <>
108
- struct value_specialization<function_tag> : value_defaults<function_tag> {
109
- using value_type = class value_for_function;
110
- };
111
-
112
- template <>
113
- struct value_specialization<data_block_tag> : value_defaults<data_block_tag> {
114
- using bound_type = class bound_value_for_data_block;
115
- };
116
-
117
- template <>
118
- struct value_specialization<array_buffer_tag> : value_defaults<array_buffer_tag> {
119
- using bound_type = class bound_value_for_array_buffer;
120
- };
121
-
122
- template <>
123
- struct value_specialization<shared_array_buffer_tag> : value_defaults<shared_array_buffer_tag> {
124
- using bound_type = class bound_value_for_shared_array_buffer;
125
- };
126
-
127
- template <>
128
- struct value_specialization<array_buffer_view_tag> : value_defaults<array_buffer_view_tag> {
129
- using bound_type = class bound_value_for_array_buffer_view;
130
- };
28
+ class local_of;
131
29
 
132
- template <>
133
- struct value_specialization<typed_array_tag> {
134
- using value_type = class value_for_typed_array;
135
- using bound_type = class bound_value_for_typed_array;
136
- };
137
-
138
- template <class Type>
139
- struct value_specialization<typed_array_tag_of<Type>> {
140
- using value_type = value_for_typed_array_of<Type>;
141
- using bound_type = bound_value_for_typed_array_of<Type>;
142
- };
143
-
144
- template <>
145
- struct value_specialization<data_view_tag> {
146
- using value_type = class value_for_data_view;
147
- using bound_type = class bound_value_for_data_view;
148
- };
149
-
150
- template <class Type>
151
- struct value_specialization<class_tag_of<Type>> : value_defaults<class_tag_of<Type>> {
152
- using value_type = value_for_class_of<Type>;
153
- };
154
-
155
- template <>
156
- struct value_specialization<external_tag> {
157
- using value_type = class value_for_external;
158
- using bound_type = class bound_value_for_external;
159
- };
160
-
161
- template <>
162
- struct value_specialization<vector_tag> : value_defaults<vector_tag> {
163
- using bound_type = class bound_value_for_vector;
164
- };
30
+ export template <class Tag = value_tag>
31
+ class value_of;
165
32
 
166
33
  } // namespace js::napi
package/handle/value.cc CHANGED
@@ -1,55 +1,147 @@
1
- export module napi_js:value_handle;
1
+ export module napi_js:handle.value_of;
2
2
  import :handle.types;
3
- import auto_js;
4
3
  import nodejs;
5
4
  import std;
6
5
 
7
6
  namespace js::napi {
8
7
 
9
- // Heirarchy:
10
- // value_of<object_tag> ->
8
+ // Map of `value_of<Tag>` to concrete implementation classes.
9
+ template <class Tag>
10
+ struct value_specialization;
11
+
12
+ // Heirarchy (for example):
13
+ // value_of<record_tag>
14
+ // value_for_record ->
15
+ // value_next<record_tag> ->
11
16
  // value_for_object ->
12
17
  // value_next<object_tag> ->
13
- // value_of<value_tag> -> ...
18
+ // value_next<value_tag> ->
19
+ // value_next<datum_tag> ->
20
+ // value_of<void>
14
21
 
15
22
  // Details applied to each level of the `value_of<T>` hierarchy.
16
23
  template <class Tag>
17
24
  class value_next : public value_of<typename Tag::tag_type> {
18
25
  public:
19
- using value_of<typename Tag::tag_type>::value_of;
26
+ using tag_type = Tag;
27
+ value_next() = default;
28
+ value_next(auto&& env, local_of<Tag> value, auto&&... rest) :
29
+ value_of<typename Tag::tag_type>{std::forward<decltype(env)>(env), value, std::forward<decltype(rest)>(rest)...} {}
20
30
 
21
- // "Downcast" to a more specific tag. Potentially unsafe.
22
- template <std::convertible_to<Tag> To>
23
- auto cast(To /*tag*/) const -> value_of<To> { return value_of<To>::from(*this); }
24
-
25
- // Construct from any `napi_value`. Potentially unsafe.
26
- static auto from(napi_value value_) -> value_of<Tag> { return std::bit_cast<value_of<Tag>>(value_); }
31
+ // NOLINTNEXTLINE(google-explicit-constructor)
32
+ operator local_of<Tag>() const { return local_of<Tag>::from(napi_value{*this}); }
27
33
  };
28
34
 
29
- // Deduction guide for `value_of{bound_value}`
30
- template <class Type>
31
- requires requires { typename Type::tag_type; }
32
- value_of(Type value) -> value_of<typename Type::tag_type>;
33
-
34
- // Tagged napi_value
35
- export template <class Tag>
36
- class value_of : public value_specialization<Tag>::value_type {
35
+ // Member & method implementation for value semantics objects. It holds the type-erased environment
36
+ // and is used for common operations like casting & iteration.
37
+ template <class Tag>
38
+ class value_of : public value_specialization<Tag>::type {
37
39
  public:
38
- using value_specialization<Tag>::value_type::value_type;
40
+ using value_type = value_specialization<Tag>::type;
41
+ using value_type::value_type;
39
42
  };
40
43
 
41
44
  // Sentinel instantiation
42
45
  template <>
43
- class value_of<void> : public value_handle {
44
- public:
45
- using value_handle::value_handle;
46
+ class value_of<void> : public runtime_handle {
47
+ protected:
48
+ value_of() = default;
49
+ value_of(napi_env env, napi_value value) :
50
+ runtime_handle{value},
51
+ env_{env} {}
52
+
53
+ [[nodiscard]] auto env() const -> napi_env { return env_; }
54
+
55
+ private:
56
+ napi_env env_{};
46
57
  };
47
58
 
48
- } // namespace js::napi
59
+ // Deduction guide
60
+ template <class Tag>
61
+ value_of(auto, local_of<Tag>) -> value_of<Tag>;
62
+
63
+ // `value_of<Tag>` specializations. The default specialization selects `value_next` for the
64
+ // immediate parent tag, instantiating it for each tag unconditionally.
65
+ template <class Type> class value_for_typed_array_of;
49
66
 
50
- // Specialize for `js::forward`. Makes `js::forward{value_of<Tag>}` infer
51
- // `js::forward<Tag, ...>`.
52
- namespace js {
53
67
  template <class Tag>
54
- struct forward_tag_for<napi::value_of<Tag>> : std::type_identity<Tag> {};
55
- } // namespace js
68
+ struct value_specialization
69
+ : std::type_identity<value_next<Tag>> {};
70
+
71
+ template <>
72
+ struct value_specialization<void>
73
+ : std::type_identity<value_of<void>> {};
74
+
75
+ template <>
76
+ struct value_specialization<boolean_tag>
77
+ : std::type_identity<class value_for_boolean> {};
78
+
79
+ template <>
80
+ struct value_specialization<false_tag>
81
+ : std::type_identity<class value_for_false> {};
82
+
83
+ template <>
84
+ struct value_specialization<true_tag>
85
+ : std::type_identity<class value_for_true> {};
86
+
87
+ template <>
88
+ struct value_specialization<number_tag>
89
+ : std::type_identity<class value_for_number> {};
90
+
91
+ template <>
92
+ struct value_specialization<bigint_tag>
93
+ : std::type_identity<class value_for_bigint> {};
94
+
95
+ template <>
96
+ struct value_specialization<string_tag>
97
+ : std::type_identity<class value_for_string> {};
98
+
99
+ template <>
100
+ struct value_specialization<object_tag>
101
+ : std::type_identity<class value_for_object> {};
102
+
103
+ template <>
104
+ struct value_specialization<date_tag>
105
+ : std::type_identity<class value_for_date> {};
106
+
107
+ template <>
108
+ struct value_specialization<record_tag>
109
+ : std::type_identity<class value_for_record> {};
110
+
111
+ template <>
112
+ struct value_specialization<data_block_tag>
113
+ : std::type_identity<class value_for_data_block> {};
114
+
115
+ template <>
116
+ struct value_specialization<array_buffer_tag>
117
+ : std::type_identity<class value_for_array_buffer> {};
118
+
119
+ template <>
120
+ struct value_specialization<shared_array_buffer_tag>
121
+ : std::type_identity<class value_for_shared_array_buffer> {};
122
+
123
+ template <>
124
+ struct value_specialization<array_buffer_view_tag>
125
+ : std::type_identity<class value_for_array_buffer_view> {};
126
+
127
+ template <>
128
+ struct value_specialization<typed_array_tag>
129
+ : std::type_identity<class value_for_typed_array> {};
130
+
131
+ template <class Type>
132
+ struct value_specialization<typed_array_tag_of<Type>>
133
+ : std::type_identity<value_for_typed_array_of<Type>> {};
134
+
135
+ template <>
136
+ struct value_specialization<data_view_tag>
137
+ : std::type_identity<class value_for_data_view> {};
138
+
139
+ template <>
140
+ struct value_specialization<external_tag>
141
+ : std::type_identity<class value_for_external> {};
142
+
143
+ template <>
144
+ struct value_specialization<vector_tag>
145
+ : std::type_identity<class value_for_vector> {};
146
+
147
+ } // namespace js::napi