binds opts with metadata

This commit is contained in:
BlackMATov
2022-02-12 08:07:46 +07:00
parent 201fdbf1cb
commit aa24ed37e8
7 changed files with 711 additions and 108 deletions

View File

@@ -9,42 +9,98 @@
#include "meta_base.hpp"
#include "meta_states.hpp"
namespace meta_hpp::detail
{
template < typename Class, typename... Args >
concept class_bind_constructor_kind =
class_kind<Class> &&
requires(Args&&... args) { { Class{std::forward<Args>(args)...} }; };
template < typename Class >
concept class_bind_destructor_kind =
class_kind<Class> &&
requires(Class&& inst) { { inst.~Class() }; };
template < typename Class, typename Base >
concept class_bind_base_kind =
class_kind<Class> && class_kind<Base> &&
stdex::derived_from<Class, Base>;
template < typename Class, typename Member >
concept class_bind_member_kind =
class_kind<Class> && member_kind<Member> &&
stdex::same_as<Class, typename member_traits<Member>::class_type>;
template < typename Class, typename Method >
concept class_bind_method_kind =
class_kind<Class> && method_kind<Method> &&
stdex::same_as<Class, typename method_traits<Method>::class_type>;
}
namespace meta_hpp
{
namespace detail
{
template < typename Class, typename... Args >
concept class_bind_constructor_kind =
class_kind<Class> &&
requires(Args&&... args) { { Class{std::forward<Args>(args)...} }; };
struct class_opts final {
metadata_map metadata{};
};
template < typename Class >
concept class_bind_destructor_kind =
class_kind<Class> &&
requires(Class&& inst) { { inst.~Class() }; };
struct enum_opts final {
metadata_map metadata{};
};
template < typename Class, typename Base >
concept class_bind_base_kind =
class_kind<Class> && class_kind<Base> &&
stdex::derived_from<Class, Base>;
struct scope_opts final {
metadata_map metadata{};
};
}
template < typename Class, typename Member >
concept class_bind_member_kind =
class_kind<Class> && member_kind<Member> &&
stdex::same_as<Class, typename member_traits<Member>::class_type>;
namespace meta_hpp
{
struct argument_opts final {
std::string name{};
metadata_map metadata{};
};
template < typename Class, typename Method >
concept class_bind_method_kind =
class_kind<Class> && method_kind<Method> &&
stdex::same_as<Class, typename method_traits<Method>::class_type>;
}
struct constructor_opts final {
std::vector<argument_opts> arguments{};
metadata_map metadata{};
};
struct destructor_opts final {
metadata_map metadata{};
};
struct evalue_opts final {
metadata_map metadata{};
};
struct function_opts final {
std::vector<argument_opts> arguments{};
metadata_map metadata{};
};
struct member_opts final {
metadata_map metadata{};
};
struct method_opts final {
std::vector<argument_opts> arguments{};
metadata_map metadata{};
};
struct variable_opts final {
metadata_map metadata{};
};
}
namespace meta_hpp
{
template < detail::class_kind Class >
class class_bind final {
public:
explicit class_bind();
explicit class_bind(class_opts opts);
operator class_type() const noexcept;
// constructor_
template < typename... Args
, constructor_policy_kind Policy = constructor_policy::as_object >
class_bind& constructor_(Policy = Policy{})
@@ -52,38 +108,75 @@ namespace meta_hpp
template < typename... Args
, constructor_policy_kind Policy = constructor_policy::as_object >
class_bind& constructor_(
std::initializer_list<std::string_view> anames,
Policy = Policy{})
class_bind& constructor_(constructor_opts opts, Policy = Policy{})
requires detail::class_bind_constructor_kind<Class, Args...>;
// destructor_
class_bind& destructor_()
requires detail::class_bind_destructor_kind<Class>;
class_bind& destructor_(destructor_opts opts)
requires detail::class_bind_destructor_kind<Class>;
// base_
template < detail::class_kind Base >
class_bind& base_()
requires detail::class_bind_base_kind<Class, Base>;
template < detail::function_kind Function
, function_policy_kind Policy = function_policy::as_copy >
class_bind& function_(std::string name, Function function, Policy = Policy{});
// function_
template < detail::function_kind Function
, function_policy_kind Policy = function_policy::as_copy >
class_bind& function_(
std::string name,
Function function,
std::initializer_list<std::string_view> anames,
Policy = Policy{});
template < detail::function_kind Function
, function_policy_kind Policy = function_policy::as_copy >
class_bind& function_(
std::string name,
Function function,
function_opts opts,
Policy = Policy{});
template < detail::function_kind Function
, function_policy_kind Policy = function_policy::as_copy >
class_bind& function_(
std::string name,
Function function,
std::initializer_list<std::string_view> arguments,
Policy = Policy{});
// member_
template < detail::member_kind Member
, member_policy_kind Policy = member_policy::as_copy >
class_bind& member_(std::string name, Member member, Policy = Policy{})
class_bind& member_(
std::string name,
Member member,
Policy = Policy{})
requires detail::class_bind_member_kind<Class, Member>;
template < detail::member_kind Member
, member_policy_kind Policy = member_policy::as_copy >
class_bind& member_(
std::string name,
Member member,
member_opts opts,
Policy = Policy{})
requires detail::class_bind_member_kind<Class, Member>;
// method_
template < detail::method_kind Method
, method_policy_kind Policy = method_policy::as_copy >
class_bind& method_(std::string name, Method method, Policy = Policy{})
class_bind& method_(
std::string name,
Method method,
Policy = Policy{})
requires detail::class_bind_method_kind<Class, Method>;
template < detail::method_kind Method
@@ -91,13 +184,35 @@ namespace meta_hpp
class_bind& method_(
std::string name,
Method method,
std::initializer_list<std::string_view> anames,
method_opts opts,
Policy = Policy{})
requires detail::class_bind_method_kind<Class, Method>;
template < detail::method_kind Method
, method_policy_kind Policy = method_policy::as_copy >
class_bind& method_(
std::string name,
Method method,
std::initializer_list<std::string_view> arguments,
Policy = Policy{})
requires detail::class_bind_method_kind<Class, Method>;
// variable_
template < detail::pointer_kind Pointer
, variable_policy_kind Policy = variable_policy::as_copy >
class_bind& variable_(std::string name, Pointer pointer, Policy = Policy{});
class_bind& variable_(
std::string name,
Pointer pointer,
Policy = Policy{});
template < detail::pointer_kind Pointer
, variable_policy_kind Policy = variable_policy::as_copy >
class_bind& variable_(
std::string name,
Pointer pointer,
variable_opts opts,
Policy = Policy{});
private:
detail::class_type_data_ptr data_;
};
@@ -108,10 +223,11 @@ namespace meta_hpp
template < detail::enum_kind Enum >
class enum_bind final {
public:
explicit enum_bind();
explicit enum_bind(enum_opts opts);
operator enum_type() const noexcept;
enum_bind& evalue_(std::string name, Enum value);
enum_bind& evalue_(std::string name, Enum value, evalue_opts opts);
private:
detail::enum_type_data_ptr data_;
};
@@ -124,8 +240,8 @@ namespace meta_hpp
struct local_tag {};
struct static_tag {};
explicit scope_bind(std::string name, local_tag);
explicit scope_bind(std::string_view name, static_tag);
explicit scope_bind(std::string name, scope_opts opts, local_tag);
explicit scope_bind(std::string_view name, scope_opts opts, static_tag);
operator scope() const noexcept;
template < detail::class_kind Class >
@@ -134,21 +250,47 @@ namespace meta_hpp
template < detail::enum_kind Enum >
scope_bind& enum_(std::string name);
template < detail::function_kind Function
, function_policy_kind Policy = function_policy::as_copy >
scope_bind& function_(std::string name, Function function, Policy = Policy{});
// function_
template < detail::function_kind Function
, function_policy_kind Policy = function_policy::as_copy >
scope_bind& function_(
std::string name,
Function function,
std::initializer_list<std::string_view> anames,
Policy = Policy{});
template < detail::function_kind Function
, function_policy_kind Policy = function_policy::as_copy >
scope_bind& function_(
std::string name,
Function function,
function_opts opts,
Policy = Policy{});
template < detail::function_kind Function
, function_policy_kind Policy = function_policy::as_copy >
scope_bind& function_(
std::string name,
Function function,
std::initializer_list<std::string_view> arguments,
Policy = Policy{});
// variable_
template < detail::pointer_kind Pointer
, variable_policy_kind Policy = variable_policy::as_copy >
scope_bind& variable_(
std::string name,
Pointer pointer,
Policy = Policy{});
template < detail::pointer_kind Pointer
, variable_policy_kind Policy = variable_policy::as_copy >
scope_bind& variable_(std::string name, Pointer pointer, Policy = Policy{});
scope_bind& variable_(
std::string name,
Pointer pointer,
variable_opts opts,
Policy = Policy{});
private:
detail::scope_state_ptr state_;
};
@@ -157,20 +299,20 @@ namespace meta_hpp
namespace meta_hpp
{
template < detail::class_kind Class >
class_bind<Class> class_() {
return class_bind<Class>{};
class_bind<Class> class_(class_opts opts = {}) {
return class_bind<Class>{std::move(opts)};
}
template < detail::enum_kind Enum >
enum_bind<Enum> enum_() {
return enum_bind<Enum>{};
enum_bind<Enum> enum_(enum_opts opts = {}) {
return enum_bind<Enum>{std::move(opts)};
}
inline scope_bind local_scope_(std::string name) {
return scope_bind{std::move(name), scope_bind::local_tag()};
inline scope_bind local_scope_(std::string name, scope_opts opts = {}) {
return scope_bind{std::move(name), std::move(opts), scope_bind::local_tag()};
}
inline scope_bind static_scope_(std::string_view name) {
return scope_bind{name, scope_bind::static_tag()};
inline scope_bind static_scope_(std::string_view name, scope_opts opts = {}) {
return scope_bind{name, std::move(opts), scope_bind::static_tag()};
}
}

View File

@@ -14,14 +14,21 @@
namespace meta_hpp
{
template < detail::class_kind Class >
class_bind<Class>::class_bind()
: data_{detail::type_access(detail::resolve_type<Class>())} {}
class_bind<Class>::class_bind(class_opts opts)
: data_{detail::type_access(detail::resolve_type<Class>())} {
data_->metadata.swap(opts.metadata);
data_->metadata.merge(opts.metadata);
}
template < detail::class_kind Class >
class_bind<Class>::operator class_type() const noexcept {
return class_type{data_};
}
//
// constructor_
//
template < detail::class_kind Class >
template < typename... Args, constructor_policy_kind Policy >
class_bind<Class>& class_bind<Class>::constructor_(Policy policy)
@@ -33,34 +40,50 @@ namespace meta_hpp
template < detail::class_kind Class >
template < typename... Args, constructor_policy_kind Policy >
class_bind<Class>& class_bind<Class>::constructor_(
std::initializer_list<std::string_view> anames,
constructor_opts opts,
[[maybe_unused]] Policy policy)
requires detail::class_bind_constructor_kind<Class, Args...>
{
auto constructor_state = detail::constructor_state::make<Policy, Class, Args...>();
auto state = detail::constructor_state::make<Policy, Class, Args...>(std::move(opts.metadata));
if ( anames.size() > constructor_state->arguments.size() ) {
if ( opts.arguments.size() > state->arguments.size() ) {
detail::throw_exception_with("provided argument names don't match constructor argument count");
}
for ( std::size_t i = 0; i < anames.size(); ++i ) {
argument& arg = constructor_state->arguments[i];
detail::state_access(arg)->name = std::string{std::data(anames)[i]};
for ( std::size_t i = 0; i < opts.arguments.size(); ++i ) {
argument& arg = state->arguments[i];
detail::state_access(arg)->name = std::move(opts.arguments[i].name);
detail::state_access(arg)->metadata = std::move(opts.arguments[i].metadata);
}
data_->constructors.emplace(constructor_state->index, std::move(constructor_state));
data_->constructors.insert_or_assign(state->index, std::move(state));
return *this;
}
//
// destructor_
//
template < detail::class_kind Class >
class_bind<Class>& class_bind<Class>::destructor_()
requires detail::class_bind_destructor_kind<Class>
{
auto destructor_state = detail::destructor_state::make<Class>();
data_->destructors.emplace(destructor_state->index, std::move(destructor_state));
return destructor_({});
}
template < detail::class_kind Class >
class_bind<Class>& class_bind<Class>::destructor_(destructor_opts opts)
requires detail::class_bind_destructor_kind<Class>
{
auto state = detail::destructor_state::make<Class>(std::move(opts.metadata));
data_->destructors.insert_or_assign(state->index, std::move(state));
return *this;
}
//
// base_
//
template < detail::class_kind Class >
template < detail::class_kind Base >
class_bind<Class>& class_bind<Class>::base_()
@@ -75,9 +98,17 @@ namespace meta_hpp
return *this;
}
//
// function_
//
template < detail::class_kind Class >
template < detail::function_kind Function, function_policy_kind Policy >
class_bind<Class>& class_bind<Class>::function_(std::string name, Function function, Policy policy) {
class_bind<Class>& class_bind<Class>::function_(
std::string name,
Function function,
Policy policy)
{
return function_(std::move(name), std::move(function), {}, policy);
}
@@ -86,37 +117,96 @@ namespace meta_hpp
class_bind<Class>& class_bind<Class>::function_(
std::string name,
Function function,
std::initializer_list<std::string_view> anames,
function_opts opts,
[[maybe_unused]] Policy policy)
{
auto function_state = detail::function_state::make<Policy>(std::move(name), std::move(function));
auto state = detail::function_state::make<Policy>(
std::move(name),
std::move(function),
std::move(opts.metadata));
if ( anames.size() > function_state->arguments.size() ) {
if ( opts.arguments.size() > state->arguments.size() ) {
detail::throw_exception_with("provided arguments don't match function argument count");
}
for ( std::size_t i = 0; i < opts.arguments.size(); ++i ) {
argument& arg = state->arguments[i];
detail::state_access(arg)->name = std::move(opts.arguments[i].name);
detail::state_access(arg)->metadata = std::move(opts.arguments[i].metadata);
}
data_->functions.insert_or_assign(state->index, std::move(state));
return *this;
}
template < detail::class_kind Class >
template < detail::function_kind Function, function_policy_kind Policy >
class_bind<Class>& class_bind<Class>::function_(
std::string name,
Function function,
std::initializer_list<std::string_view> arguments,
[[maybe_unused]] Policy policy)
{
auto state = detail::function_state::make<Policy>(
std::move(name),
std::move(function),
{});
if ( arguments.size() > state->arguments.size() ) {
detail::throw_exception_with("provided argument names don't match function argument count");
}
for ( std::size_t i = 0; i < anames.size(); ++i ) {
argument& arg = function_state->arguments[i];
detail::state_access(arg)->name = std::string{std::data(anames)[i]};
for ( std::size_t i = 0; i < arguments.size(); ++i ) {
argument& arg = state->arguments[i];
detail::state_access(arg)->name = std::data(arguments)[i];
}
data_->functions.emplace(function_state->index, std::move(function_state));
data_->functions.insert_or_assign(state->index, std::move(state));
return *this;
}
//
// member_
//
template < detail::class_kind Class >
template < detail::member_kind Member, member_policy_kind Policy >
class_bind<Class>& class_bind<Class>::member_(
std::string name,
Member member,
Policy policy)
requires detail::class_bind_member_kind<Class, Member>
{
return member_(std::move(name), std::move(member), {}, policy);
}
template < detail::class_kind Class >
template < detail::member_kind Member, member_policy_kind Policy >
class_bind<Class>& class_bind<Class>::member_(std::string name, Member member, [[maybe_unused]] Policy policy)
class_bind<Class>& class_bind<Class>::member_(
std::string name,
Member member,
member_opts opts,
[[maybe_unused]] Policy policy)
requires detail::class_bind_member_kind<Class, Member>
{
auto member_state = detail::member_state::make<Policy>(std::move(name), std::move(member));
data_->members.emplace(member_state->index, std::move(member_state));
auto state = detail::member_state::make<Policy>(
std::move(name),
std::move(member),
std::move(opts.metadata));
data_->members.insert_or_assign(state->index, std::move(state));
return *this;
}
//
// method_
//
template < detail::class_kind Class >
template < detail::method_kind Method, method_policy_kind Policy >
class_bind<Class>& class_bind<Class>::method_(std::string name, Method method, Policy policy)
class_bind<Class>& class_bind<Class>::method_(
std::string name,
Method method,
Policy policy)
requires detail::class_bind_method_kind<Class, Method>
{
return method_(std::move(name), std::move(method), {}, policy);
@@ -127,30 +217,83 @@ namespace meta_hpp
class_bind<Class>& class_bind<Class>::method_(
std::string name,
Method method,
std::initializer_list<std::string_view> anames,
method_opts opts,
[[maybe_unused]] Policy policy)
requires detail::class_bind_method_kind<Class, Method>
{
auto method_state = detail::method_state::make<Policy>(std::move(name), std::move(method));
auto state = detail::method_state::make<Policy>(
std::move(name),
std::move(method),
std::move(opts.metadata));
if ( anames.size() > method_state->arguments.size() ) {
detail::throw_exception_with("provided argument names don't match method argument count");
if ( opts.arguments.size() > state->arguments.size() ) {
detail::throw_exception_with("provided arguments don't match method argument count");
}
for ( std::size_t i = 0; i < anames.size(); ++i ) {
argument& arg = method_state->arguments[i];
detail::state_access(arg)->name = std::string{std::data(anames)[i]};
for ( std::size_t i = 0; i < opts.arguments.size(); ++i ) {
argument& arg = state->arguments[i];
detail::state_access(arg)->name = std::move(opts.arguments[i].name);
detail::state_access(arg)->metadata = std::move(opts.arguments[i].metadata);
}
data_->methods.emplace(method_state->index, std::move(method_state));
data_->methods.insert_or_assign(state->index, std::move(state));
return *this;
}
template < detail::class_kind Class >
template < detail::method_kind Method, method_policy_kind Policy >
class_bind<Class>& class_bind<Class>::method_(
std::string name,
Method method,
std::initializer_list<std::string_view> arguments,
[[maybe_unused]] Policy policy)
requires detail::class_bind_method_kind<Class, Method>
{
auto state = detail::method_state::make<Policy>(
std::move(name),
std::move(method),
{});
if ( arguments.size() > state->arguments.size() ) {
detail::throw_exception_with("provided argument names don't match method argument count");
}
for ( std::size_t i = 0; i < arguments.size(); ++i ) {
argument& arg = state->arguments[i];
detail::state_access(arg)->name = std::data(arguments)[i];
}
data_->methods.insert_or_assign(state->index, std::move(state));
return *this;
}
//
// variable_
//
template < detail::class_kind Class >
template < detail::pointer_kind Pointer, variable_policy_kind Policy >
class_bind<Class>& class_bind<Class>::variable_( std::string name, Pointer pointer, [[maybe_unused]] Policy policy) {
auto variable_state = detail::variable_state::make<Policy>(std::move(name), std::move(pointer));
data_->variables.emplace(variable_state->index, std::move(variable_state));
class_bind<Class>& class_bind<Class>::variable_(
std::string name,
Pointer pointer,
Policy policy)
{
return variable_(std::move(name), std::move(pointer), {}, policy);
}
template < detail::class_kind Class >
template < detail::pointer_kind Pointer, variable_policy_kind Policy >
class_bind<Class>& class_bind<Class>::variable_(
std::string name,
Pointer pointer,
variable_opts opts,
[[maybe_unused]] Policy policy)
{
auto state = detail::variable_state::make<Policy>(
std::move(name),
std::move(pointer),
std::move(opts.metadata));
data_->variables.insert_or_assign(state->index, std::move(state));
return *this;
}
}

View File

@@ -14,8 +14,11 @@
namespace meta_hpp
{
template < detail::enum_kind Enum >
enum_bind<Enum>::enum_bind()
: data_{detail::type_access(detail::resolve_type<Enum>())} {}
enum_bind<Enum>::enum_bind(enum_opts opts)
: data_{detail::type_access(detail::resolve_type<Enum>())} {
data_->metadata.swap(opts.metadata);
data_->metadata.merge(opts.metadata);
}
template < detail::enum_kind Enum >
enum_bind<Enum>::operator enum_type() const noexcept {
@@ -24,8 +27,16 @@ namespace meta_hpp
template < detail::enum_kind Enum >
enum_bind<Enum>& enum_bind<Enum>::evalue_(std::string name, Enum value) {
auto evalue_state = detail::evalue_state::make(std::move(name), std::move(value));
data_->evalues.emplace(evalue_state->index, std::move(evalue_state));
return evalue_(std::move(name), std::move(value), {});
}
template < detail::enum_kind Enum >
enum_bind<Enum>& enum_bind<Enum>::evalue_(std::string name, Enum value, evalue_opts opts) {
auto state = detail::evalue_state::make(
std::move(name),
std::move(value),
std::move(opts.metadata));
data_->evalues.insert_or_assign(state->index, std::move(state));
return *this;
}
}

View File

@@ -15,12 +15,15 @@
namespace meta_hpp
{
// NOLINTNEXTLINE(readability-named-parameter)
inline scope_bind::scope_bind(std::string name, local_tag)
: state_{detail::scope_state::make(std::move(name))} {}
inline scope_bind::scope_bind(std::string name, scope_opts opts, local_tag)
: state_{detail::scope_state::make(std::move(name), std::move(opts.metadata))} {}
// NOLINTNEXTLINE(readability-named-parameter)
inline scope_bind::scope_bind(std::string_view name, static_tag)
: state_{detail::state_access(detail::resolve_scope(name))} {}
inline scope_bind::scope_bind(std::string_view name, scope_opts opts, static_tag)
: state_{detail::state_access(detail::resolve_scope(name))} {
state_->metadata.swap(opts.metadata);
state_->metadata.merge(opts.metadata);
}
inline scope_bind::operator scope() const noexcept {
return scope{state_};
@@ -38,8 +41,16 @@ namespace meta_hpp
return *this;
}
//
// function_
//
template < detail::function_kind Function, function_policy_kind Policy >
scope_bind& scope_bind::function_(std::string name, Function function, Policy policy) {
scope_bind& scope_bind::function_(
std::string name,
Function function,
Policy policy)
{
return function_(std::move(name), std::move(function), {}, policy);
}
@@ -47,28 +58,78 @@ namespace meta_hpp
scope_bind& scope_bind::function_(
std::string name,
Function function,
std::initializer_list<std::string_view> anames,
function_opts opts,
[[maybe_unused]] Policy policy)
{
auto function_state = detail::function_state::make<Policy>(std::move(name), std::move(function));
auto state = detail::function_state::make<Policy>(
std::move(name),
std::move(function),
std::move(opts.metadata));
if ( anames.size() > function_state->arguments.size() ) {
if ( opts.arguments.size() > state->arguments.size() ) {
detail::throw_exception_with("provided arguments don't match function argument count");
}
for ( std::size_t i = 0; i < opts.arguments.size(); ++i ) {
argument& arg = state->arguments[i];
detail::state_access(arg)->name = std::move(opts.arguments[i].name);
detail::state_access(arg)->metadata = std::move(opts.arguments[i].metadata);
}
state_->functions.insert_or_assign(state->index, std::move(state));
return *this;
}
template < detail::function_kind Function, function_policy_kind Policy >
scope_bind& scope_bind::function_(
std::string name,
Function function,
std::initializer_list<std::string_view> arguments,
[[maybe_unused]] Policy policy)
{
auto state = detail::function_state::make<Policy>(
std::move(name),
std::move(function),
{});
if ( arguments.size() > state->arguments.size() ) {
detail::throw_exception_with("provided argument names don't match function argument count");
}
for ( std::size_t i = 0; i < anames.size(); ++i ) {
argument& arg = function_state->arguments[i];
detail::state_access(arg)->name = std::string{std::data(anames)[i]};
for ( std::size_t i = 0; i < arguments.size(); ++i ) {
argument& arg = state->arguments[i];
detail::state_access(arg)->name = std::data(arguments)[i];
}
state_->functions.emplace(function_state->index, std::move(function_state));
state_->functions.insert_or_assign(state->index, std::move(state));
return *this;
}
//
// variable_
//
template < detail::pointer_kind Pointer, variable_policy_kind Policy >
scope_bind& scope_bind::variable_(
std::string name,
Pointer pointer,
Policy policy)
{
return variable_(std::move(name), std::move(pointer), {}, policy);
}
template < detail::pointer_kind Pointer, variable_policy_kind Policy >
scope_bind& scope_bind::variable_(std::string name, Pointer pointer, [[maybe_unused]] Policy policy) {
auto variable_state = detail::variable_state::make<Policy>(std::move(name), std::move(pointer));
state_->variables.emplace(variable_state->index, std::move(variable_state));
scope_bind& scope_bind::variable_(
std::string name,
Pointer pointer,
variable_opts opts,
[[maybe_unused]] Policy policy)
{
auto state = detail::variable_state::make<Policy>(
std::move(name),
std::move(pointer),
std::move(opts.metadata));
state_->variables.insert_or_assign(state->index, std::move(state));
return *this;
}
}