mirror of
https://github.com/BlackMATov/meta.hpp.git
synced 2025-12-15 03:45:30 +07:00
binds opts with metadata
This commit is contained in:
@@ -9,10 +9,8 @@
|
|||||||
#include "meta_base.hpp"
|
#include "meta_base.hpp"
|
||||||
#include "meta_states.hpp"
|
#include "meta_states.hpp"
|
||||||
|
|
||||||
namespace meta_hpp
|
namespace meta_hpp::detail
|
||||||
{
|
{
|
||||||
namespace detail
|
|
||||||
{
|
|
||||||
template < typename Class, typename... Args >
|
template < typename Class, typename... Args >
|
||||||
concept class_bind_constructor_kind =
|
concept class_bind_constructor_kind =
|
||||||
class_kind<Class> &&
|
class_kind<Class> &&
|
||||||
@@ -37,14 +35,72 @@ namespace meta_hpp
|
|||||||
concept class_bind_method_kind =
|
concept class_bind_method_kind =
|
||||||
class_kind<Class> && method_kind<Method> &&
|
class_kind<Class> && method_kind<Method> &&
|
||||||
stdex::same_as<Class, typename method_traits<Method>::class_type>;
|
stdex::same_as<Class, typename method_traits<Method>::class_type>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace meta_hpp
|
||||||
|
{
|
||||||
|
struct class_opts final {
|
||||||
|
metadata_map metadata{};
|
||||||
|
};
|
||||||
|
|
||||||
|
struct enum_opts final {
|
||||||
|
metadata_map metadata{};
|
||||||
|
};
|
||||||
|
|
||||||
|
struct scope_opts final {
|
||||||
|
metadata_map metadata{};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace meta_hpp
|
||||||
|
{
|
||||||
|
struct argument_opts final {
|
||||||
|
std::string name{};
|
||||||
|
metadata_map metadata{};
|
||||||
|
};
|
||||||
|
|
||||||
|
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 >
|
template < detail::class_kind Class >
|
||||||
class class_bind final {
|
class class_bind final {
|
||||||
public:
|
public:
|
||||||
explicit class_bind();
|
explicit class_bind(class_opts opts);
|
||||||
operator class_type() const noexcept;
|
operator class_type() const noexcept;
|
||||||
|
|
||||||
|
// constructor_
|
||||||
|
|
||||||
template < typename... Args
|
template < typename... Args
|
||||||
, constructor_policy_kind Policy = constructor_policy::as_object >
|
, constructor_policy_kind Policy = constructor_policy::as_object >
|
||||||
class_bind& constructor_(Policy = Policy{})
|
class_bind& constructor_(Policy = Policy{})
|
||||||
@@ -52,38 +108,75 @@ namespace meta_hpp
|
|||||||
|
|
||||||
template < typename... Args
|
template < typename... Args
|
||||||
, constructor_policy_kind Policy = constructor_policy::as_object >
|
, constructor_policy_kind Policy = constructor_policy::as_object >
|
||||||
class_bind& constructor_(
|
class_bind& constructor_(constructor_opts opts, Policy = Policy{})
|
||||||
std::initializer_list<std::string_view> anames,
|
|
||||||
Policy = Policy{})
|
|
||||||
requires detail::class_bind_constructor_kind<Class, Args...>;
|
requires detail::class_bind_constructor_kind<Class, Args...>;
|
||||||
|
|
||||||
|
// destructor_
|
||||||
|
|
||||||
class_bind& destructor_()
|
class_bind& destructor_()
|
||||||
requires detail::class_bind_destructor_kind<Class>;
|
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 >
|
template < detail::class_kind Base >
|
||||||
class_bind& base_()
|
class_bind& base_()
|
||||||
requires detail::class_bind_base_kind<Class, Base>;
|
requires detail::class_bind_base_kind<Class, Base>;
|
||||||
|
|
||||||
template < detail::function_kind Function
|
// function_
|
||||||
, function_policy_kind Policy = function_policy::as_copy >
|
|
||||||
class_bind& function_(std::string name, Function function, Policy = Policy{});
|
|
||||||
|
|
||||||
template < detail::function_kind Function
|
template < detail::function_kind Function
|
||||||
, function_policy_kind Policy = function_policy::as_copy >
|
, function_policy_kind Policy = function_policy::as_copy >
|
||||||
class_bind& function_(
|
class_bind& function_(
|
||||||
std::string name,
|
std::string name,
|
||||||
Function function,
|
Function function,
|
||||||
std::initializer_list<std::string_view> anames,
|
|
||||||
Policy = Policy{});
|
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
|
template < detail::member_kind Member
|
||||||
, member_policy_kind Policy = member_policy::as_copy >
|
, 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>;
|
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
|
template < detail::method_kind Method
|
||||||
, method_policy_kind Policy = method_policy::as_copy >
|
, 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>;
|
requires detail::class_bind_method_kind<Class, Method>;
|
||||||
|
|
||||||
template < detail::method_kind Method
|
template < detail::method_kind Method
|
||||||
@@ -91,13 +184,35 @@ namespace meta_hpp
|
|||||||
class_bind& method_(
|
class_bind& method_(
|
||||||
std::string name,
|
std::string name,
|
||||||
Method method,
|
Method method,
|
||||||
std::initializer_list<std::string_view> anames,
|
method_opts opts,
|
||||||
Policy = Policy{})
|
Policy = Policy{})
|
||||||
requires detail::class_bind_method_kind<Class, Method>;
|
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
|
template < detail::pointer_kind Pointer
|
||||||
, variable_policy_kind Policy = variable_policy::as_copy >
|
, 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:
|
private:
|
||||||
detail::class_type_data_ptr data_;
|
detail::class_type_data_ptr data_;
|
||||||
};
|
};
|
||||||
@@ -108,10 +223,11 @@ namespace meta_hpp
|
|||||||
template < detail::enum_kind Enum >
|
template < detail::enum_kind Enum >
|
||||||
class enum_bind final {
|
class enum_bind final {
|
||||||
public:
|
public:
|
||||||
explicit enum_bind();
|
explicit enum_bind(enum_opts opts);
|
||||||
operator enum_type() const noexcept;
|
operator enum_type() const noexcept;
|
||||||
|
|
||||||
enum_bind& evalue_(std::string name, Enum value);
|
enum_bind& evalue_(std::string name, Enum value);
|
||||||
|
enum_bind& evalue_(std::string name, Enum value, evalue_opts opts);
|
||||||
private:
|
private:
|
||||||
detail::enum_type_data_ptr data_;
|
detail::enum_type_data_ptr data_;
|
||||||
};
|
};
|
||||||
@@ -124,8 +240,8 @@ namespace meta_hpp
|
|||||||
struct local_tag {};
|
struct local_tag {};
|
||||||
struct static_tag {};
|
struct static_tag {};
|
||||||
|
|
||||||
explicit scope_bind(std::string name, local_tag);
|
explicit scope_bind(std::string name, scope_opts opts, local_tag);
|
||||||
explicit scope_bind(std::string_view name, static_tag);
|
explicit scope_bind(std::string_view name, scope_opts opts, static_tag);
|
||||||
operator scope() const noexcept;
|
operator scope() const noexcept;
|
||||||
|
|
||||||
template < detail::class_kind Class >
|
template < detail::class_kind Class >
|
||||||
@@ -134,21 +250,47 @@ namespace meta_hpp
|
|||||||
template < detail::enum_kind Enum >
|
template < detail::enum_kind Enum >
|
||||||
scope_bind& enum_(std::string name);
|
scope_bind& enum_(std::string name);
|
||||||
|
|
||||||
template < detail::function_kind Function
|
// function_
|
||||||
, function_policy_kind Policy = function_policy::as_copy >
|
|
||||||
scope_bind& function_(std::string name, Function function, Policy = Policy{});
|
|
||||||
|
|
||||||
template < detail::function_kind Function
|
template < detail::function_kind Function
|
||||||
, function_policy_kind Policy = function_policy::as_copy >
|
, function_policy_kind Policy = function_policy::as_copy >
|
||||||
scope_bind& function_(
|
scope_bind& function_(
|
||||||
std::string name,
|
std::string name,
|
||||||
Function function,
|
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{});
|
Policy = Policy{});
|
||||||
|
|
||||||
template < detail::pointer_kind Pointer
|
template < detail::pointer_kind Pointer
|
||||||
, variable_policy_kind Policy = variable_policy::as_copy >
|
, 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:
|
private:
|
||||||
detail::scope_state_ptr state_;
|
detail::scope_state_ptr state_;
|
||||||
};
|
};
|
||||||
@@ -157,20 +299,20 @@ namespace meta_hpp
|
|||||||
namespace meta_hpp
|
namespace meta_hpp
|
||||||
{
|
{
|
||||||
template < detail::class_kind Class >
|
template < detail::class_kind Class >
|
||||||
class_bind<Class> class_() {
|
class_bind<Class> class_(class_opts opts = {}) {
|
||||||
return class_bind<Class>{};
|
return class_bind<Class>{std::move(opts)};
|
||||||
}
|
}
|
||||||
|
|
||||||
template < detail::enum_kind Enum >
|
template < detail::enum_kind Enum >
|
||||||
enum_bind<Enum> enum_() {
|
enum_bind<Enum> enum_(enum_opts opts = {}) {
|
||||||
return enum_bind<Enum>{};
|
return enum_bind<Enum>{std::move(opts)};
|
||||||
}
|
}
|
||||||
|
|
||||||
inline scope_bind local_scope_(std::string name) {
|
inline scope_bind local_scope_(std::string name, scope_opts opts = {}) {
|
||||||
return scope_bind{std::move(name), scope_bind::local_tag()};
|
return scope_bind{std::move(name), std::move(opts), scope_bind::local_tag()};
|
||||||
}
|
}
|
||||||
|
|
||||||
inline scope_bind static_scope_(std::string_view name) {
|
inline scope_bind static_scope_(std::string_view name, scope_opts opts = {}) {
|
||||||
return scope_bind{name, scope_bind::static_tag()};
|
return scope_bind{name, std::move(opts), scope_bind::static_tag()};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,14 +14,21 @@
|
|||||||
namespace meta_hpp
|
namespace meta_hpp
|
||||||
{
|
{
|
||||||
template < detail::class_kind Class >
|
template < detail::class_kind Class >
|
||||||
class_bind<Class>::class_bind()
|
class_bind<Class>::class_bind(class_opts opts)
|
||||||
: data_{detail::type_access(detail::resolve_type<Class>())} {}
|
: data_{detail::type_access(detail::resolve_type<Class>())} {
|
||||||
|
data_->metadata.swap(opts.metadata);
|
||||||
|
data_->metadata.merge(opts.metadata);
|
||||||
|
}
|
||||||
|
|
||||||
template < detail::class_kind Class >
|
template < detail::class_kind Class >
|
||||||
class_bind<Class>::operator class_type() const noexcept {
|
class_bind<Class>::operator class_type() const noexcept {
|
||||||
return class_type{data_};
|
return class_type{data_};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// constructor_
|
||||||
|
//
|
||||||
|
|
||||||
template < detail::class_kind Class >
|
template < detail::class_kind Class >
|
||||||
template < typename... Args, constructor_policy_kind Policy >
|
template < typename... Args, constructor_policy_kind Policy >
|
||||||
class_bind<Class>& class_bind<Class>::constructor_(Policy policy)
|
class_bind<Class>& class_bind<Class>::constructor_(Policy policy)
|
||||||
@@ -33,34 +40,50 @@ namespace meta_hpp
|
|||||||
template < detail::class_kind Class >
|
template < detail::class_kind Class >
|
||||||
template < typename... Args, constructor_policy_kind Policy >
|
template < typename... Args, constructor_policy_kind Policy >
|
||||||
class_bind<Class>& class_bind<Class>::constructor_(
|
class_bind<Class>& class_bind<Class>::constructor_(
|
||||||
std::initializer_list<std::string_view> anames,
|
constructor_opts opts,
|
||||||
[[maybe_unused]] Policy policy)
|
[[maybe_unused]] Policy policy)
|
||||||
requires detail::class_bind_constructor_kind<Class, Args...>
|
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");
|
detail::throw_exception_with("provided argument names don't match constructor argument count");
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( std::size_t i = 0; i < anames.size(); ++i ) {
|
for ( std::size_t i = 0; i < opts.arguments.size(); ++i ) {
|
||||||
argument& arg = constructor_state->arguments[i];
|
argument& arg = state->arguments[i];
|
||||||
detail::state_access(arg)->name = std::string{std::data(anames)[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;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// destructor_
|
||||||
|
//
|
||||||
|
|
||||||
template < detail::class_kind Class >
|
template < detail::class_kind Class >
|
||||||
class_bind<Class>& class_bind<Class>::destructor_()
|
class_bind<Class>& class_bind<Class>::destructor_()
|
||||||
requires detail::class_bind_destructor_kind<Class>
|
requires detail::class_bind_destructor_kind<Class>
|
||||||
{
|
{
|
||||||
auto destructor_state = detail::destructor_state::make<Class>();
|
return destructor_({});
|
||||||
data_->destructors.emplace(destructor_state->index, std::move(destructor_state));
|
}
|
||||||
|
|
||||||
|
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;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// base_
|
||||||
|
//
|
||||||
|
|
||||||
template < detail::class_kind Class >
|
template < detail::class_kind Class >
|
||||||
template < detail::class_kind Base >
|
template < detail::class_kind Base >
|
||||||
class_bind<Class>& class_bind<Class>::base_()
|
class_bind<Class>& class_bind<Class>::base_()
|
||||||
@@ -75,9 +98,17 @@ namespace meta_hpp
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// function_
|
||||||
|
//
|
||||||
|
|
||||||
template < detail::class_kind Class >
|
template < detail::class_kind Class >
|
||||||
template < detail::function_kind Function, function_policy_kind Policy >
|
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);
|
return function_(std::move(name), std::move(function), {}, policy);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,37 +117,96 @@ namespace meta_hpp
|
|||||||
class_bind<Class>& class_bind<Class>::function_(
|
class_bind<Class>& class_bind<Class>::function_(
|
||||||
std::string name,
|
std::string name,
|
||||||
Function function,
|
Function function,
|
||||||
std::initializer_list<std::string_view> anames,
|
function_opts opts,
|
||||||
[[maybe_unused]] Policy policy)
|
[[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");
|
detail::throw_exception_with("provided argument names don't match function argument count");
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( std::size_t i = 0; i < anames.size(); ++i ) {
|
for ( std::size_t i = 0; i < arguments.size(); ++i ) {
|
||||||
argument& arg = function_state->arguments[i];
|
argument& arg = state->arguments[i];
|
||||||
detail::state_access(arg)->name = std::string{std::data(anames)[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;
|
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::class_kind Class >
|
||||||
template < detail::member_kind Member, member_policy_kind Policy >
|
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>
|
requires detail::class_bind_member_kind<Class, Member>
|
||||||
{
|
{
|
||||||
auto member_state = detail::member_state::make<Policy>(std::move(name), std::move(member));
|
auto state = detail::member_state::make<Policy>(
|
||||||
data_->members.emplace(member_state->index, std::move(member_state));
|
std::move(name),
|
||||||
|
std::move(member),
|
||||||
|
std::move(opts.metadata));
|
||||||
|
data_->members.insert_or_assign(state->index, std::move(state));
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// method_
|
||||||
|
//
|
||||||
|
|
||||||
template < detail::class_kind Class >
|
template < detail::class_kind Class >
|
||||||
template < detail::method_kind Method, method_policy_kind Policy >
|
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>
|
requires detail::class_bind_method_kind<Class, Method>
|
||||||
{
|
{
|
||||||
return method_(std::move(name), std::move(method), {}, policy);
|
return method_(std::move(name), std::move(method), {}, policy);
|
||||||
@@ -127,30 +217,83 @@ namespace meta_hpp
|
|||||||
class_bind<Class>& class_bind<Class>::method_(
|
class_bind<Class>& class_bind<Class>::method_(
|
||||||
std::string name,
|
std::string name,
|
||||||
Method method,
|
Method method,
|
||||||
std::initializer_list<std::string_view> anames,
|
method_opts opts,
|
||||||
[[maybe_unused]] Policy policy)
|
[[maybe_unused]] Policy policy)
|
||||||
requires detail::class_bind_method_kind<Class, Method>
|
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() ) {
|
if ( opts.arguments.size() > state->arguments.size() ) {
|
||||||
detail::throw_exception_with("provided argument names don't match method argument count");
|
detail::throw_exception_with("provided arguments don't match method argument count");
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( std::size_t i = 0; i < anames.size(); ++i ) {
|
for ( std::size_t i = 0; i < opts.arguments.size(); ++i ) {
|
||||||
argument& arg = method_state->arguments[i];
|
argument& arg = state->arguments[i];
|
||||||
detail::state_access(arg)->name = std::string{std::data(anames)[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;
|
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::class_kind Class >
|
||||||
template < detail::pointer_kind Pointer, variable_policy_kind Policy >
|
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) {
|
class_bind<Class>& class_bind<Class>::variable_(
|
||||||
auto variable_state = detail::variable_state::make<Policy>(std::move(name), std::move(pointer));
|
std::string name,
|
||||||
data_->variables.emplace(variable_state->index, std::move(variable_state));
|
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;
|
return *this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,8 +14,11 @@
|
|||||||
namespace meta_hpp
|
namespace meta_hpp
|
||||||
{
|
{
|
||||||
template < detail::enum_kind Enum >
|
template < detail::enum_kind Enum >
|
||||||
enum_bind<Enum>::enum_bind()
|
enum_bind<Enum>::enum_bind(enum_opts opts)
|
||||||
: data_{detail::type_access(detail::resolve_type<Enum>())} {}
|
: data_{detail::type_access(detail::resolve_type<Enum>())} {
|
||||||
|
data_->metadata.swap(opts.metadata);
|
||||||
|
data_->metadata.merge(opts.metadata);
|
||||||
|
}
|
||||||
|
|
||||||
template < detail::enum_kind Enum >
|
template < detail::enum_kind Enum >
|
||||||
enum_bind<Enum>::operator enum_type() const noexcept {
|
enum_bind<Enum>::operator enum_type() const noexcept {
|
||||||
@@ -24,8 +27,16 @@ namespace meta_hpp
|
|||||||
|
|
||||||
template < detail::enum_kind Enum >
|
template < detail::enum_kind Enum >
|
||||||
enum_bind<Enum>& enum_bind<Enum>::evalue_(std::string name, Enum value) {
|
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));
|
return evalue_(std::move(name), std::move(value), {});
|
||||||
data_->evalues.emplace(evalue_state->index, std::move(evalue_state));
|
}
|
||||||
|
|
||||||
|
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;
|
return *this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,12 +15,15 @@
|
|||||||
namespace meta_hpp
|
namespace meta_hpp
|
||||||
{
|
{
|
||||||
// NOLINTNEXTLINE(readability-named-parameter)
|
// NOLINTNEXTLINE(readability-named-parameter)
|
||||||
inline scope_bind::scope_bind(std::string name, local_tag)
|
inline scope_bind::scope_bind(std::string name, scope_opts opts, local_tag)
|
||||||
: state_{detail::scope_state::make(std::move(name))} {}
|
: state_{detail::scope_state::make(std::move(name), std::move(opts.metadata))} {}
|
||||||
|
|
||||||
// NOLINTNEXTLINE(readability-named-parameter)
|
// NOLINTNEXTLINE(readability-named-parameter)
|
||||||
inline scope_bind::scope_bind(std::string_view name, static_tag)
|
inline scope_bind::scope_bind(std::string_view name, scope_opts opts, static_tag)
|
||||||
: state_{detail::state_access(detail::resolve_scope(name))} {}
|
: 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 {
|
inline scope_bind::operator scope() const noexcept {
|
||||||
return scope{state_};
|
return scope{state_};
|
||||||
@@ -38,8 +41,16 @@ namespace meta_hpp
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// function_
|
||||||
|
//
|
||||||
|
|
||||||
template < detail::function_kind Function, function_policy_kind Policy >
|
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);
|
return function_(std::move(name), std::move(function), {}, policy);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,28 +58,78 @@ namespace meta_hpp
|
|||||||
scope_bind& scope_bind::function_(
|
scope_bind& scope_bind::function_(
|
||||||
std::string name,
|
std::string name,
|
||||||
Function function,
|
Function function,
|
||||||
std::initializer_list<std::string_view> anames,
|
function_opts opts,
|
||||||
[[maybe_unused]] Policy policy)
|
[[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");
|
detail::throw_exception_with("provided argument names don't match function argument count");
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( std::size_t i = 0; i < anames.size(); ++i ) {
|
for ( std::size_t i = 0; i < arguments.size(); ++i ) {
|
||||||
argument& arg = function_state->arguments[i];
|
argument& arg = state->arguments[i];
|
||||||
detail::state_access(arg)->name = std::string{std::data(anames)[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;
|
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 >
|
template < detail::pointer_kind Pointer, variable_policy_kind Policy >
|
||||||
scope_bind& scope_bind::variable_(std::string name, Pointer pointer, [[maybe_unused]] Policy policy) {
|
scope_bind& scope_bind::variable_(
|
||||||
auto variable_state = detail::variable_state::make<Policy>(std::move(name), std::move(pointer));
|
std::string name,
|
||||||
state_->variables.emplace(variable_state->index, std::move(variable_state));
|
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;
|
return *this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
246
untests/meta_states/metadata_tests.cpp
Normal file
246
untests/meta_states/metadata_tests.cpp
Normal file
@@ -0,0 +1,246 @@
|
|||||||
|
/*******************************************************************************
|
||||||
|
* This file is part of the "https://github.com/blackmatov/meta.hpp"
|
||||||
|
* For conditions of distribution and use, see copyright notice in LICENSE.md
|
||||||
|
* Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com)
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
#include "../meta_untests.hpp"
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
enum class color : unsigned {
|
||||||
|
red = 0xFF0000,
|
||||||
|
green = 0x00FF00,
|
||||||
|
blue = 0x0000FF,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ivec2 {
|
||||||
|
int x{};
|
||||||
|
int y{};
|
||||||
|
|
||||||
|
explicit ivec2(int v) : x{v}, y{v} {}
|
||||||
|
ivec2(int x, int y) : x{x}, y{y} {}
|
||||||
|
|
||||||
|
ivec2& add(const ivec2& other) noexcept {
|
||||||
|
x += other.x;
|
||||||
|
y += other.y;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ivec2 iadd(const ivec2& l, const ivec2& r) noexcept {
|
||||||
|
return {l.x + r.x, l.y + r.y};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("meta/meta_states/metadata/enum") {
|
||||||
|
namespace meta = meta_hpp;
|
||||||
|
using namespace std::string_literals;
|
||||||
|
|
||||||
|
meta::enum_<color>({
|
||||||
|
.metadata{
|
||||||
|
{"desc1", meta::uvalue{"enum-desc1"s}},
|
||||||
|
{"desc2", meta::uvalue{"enum-desc2"s}},
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.evalue_("red", color::red, {
|
||||||
|
.metadata{{"desc1", meta::uvalue{"red-color"s}}}
|
||||||
|
})
|
||||||
|
.evalue_("green", color::green, {
|
||||||
|
.metadata{{"desc1", meta::uvalue{"green-color"s}}}
|
||||||
|
})
|
||||||
|
.evalue_("blue", color::blue, {
|
||||||
|
.metadata{{"desc1", meta::uvalue{"blue-color"s}}}
|
||||||
|
});
|
||||||
|
|
||||||
|
// metadata override
|
||||||
|
|
||||||
|
meta::enum_<color>({
|
||||||
|
.metadata{
|
||||||
|
{"desc2", meta::uvalue{"new-enum-desc2"s}},
|
||||||
|
{"desc3", meta::uvalue{"new-enum-desc3"s}},
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
meta::enum_<color>()
|
||||||
|
.evalue_("red", color::red, {
|
||||||
|
.metadata{
|
||||||
|
{"desc2", meta::uvalue{"new-red-color"s}},
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
const meta::enum_type color_type = meta::resolve_type<color>();
|
||||||
|
REQUIRE(color_type);
|
||||||
|
|
||||||
|
SUBCASE("color") {
|
||||||
|
CHECK(color_type.get_metadata().at("desc1") == "enum-desc1"s);
|
||||||
|
CHECK(color_type.get_metadata().at("desc2") == "new-enum-desc2"s);
|
||||||
|
CHECK(color_type.get_metadata().at("desc3") == "new-enum-desc3"s);
|
||||||
|
}
|
||||||
|
|
||||||
|
SUBCASE("color::red") {
|
||||||
|
const meta::evalue red_evalue = color_type.get_evalue("red");
|
||||||
|
REQUIRE(red_evalue);
|
||||||
|
CHECK_FALSE(red_evalue.get_metadata().contains("desc1"));
|
||||||
|
CHECK(red_evalue.get_metadata().at("desc2") == "new-red-color"s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("meta/meta_states/metadata/class") {
|
||||||
|
namespace meta = meta_hpp;
|
||||||
|
using namespace std::string_literals;
|
||||||
|
|
||||||
|
meta::class_<ivec2>({
|
||||||
|
.metadata{
|
||||||
|
{"desc1", meta::uvalue{"class-desc1"s}},
|
||||||
|
{"desc2", meta::uvalue{"class-desc2"s}},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.constructor_<int>({
|
||||||
|
.arguments{{
|
||||||
|
.name{"v"},
|
||||||
|
.metadata{{"desc", meta::uvalue{"the ctor arg"s}}},
|
||||||
|
}},
|
||||||
|
.metadata{{"desc", meta::uvalue{"one arg 2d vector ctor"s}}},
|
||||||
|
})
|
||||||
|
.constructor_<int, int>({
|
||||||
|
.arguments{{
|
||||||
|
.name{"x"},
|
||||||
|
.metadata{{"desc", meta::uvalue{"the 1st ctor arg"s}}},
|
||||||
|
},{
|
||||||
|
.name{"y"},
|
||||||
|
.metadata{{"desc", meta::uvalue{"the 2nd ctor arg"s}}},
|
||||||
|
}},
|
||||||
|
.metadata{{"desc", meta::uvalue{"two args 2d vector ctor"s}}}
|
||||||
|
})
|
||||||
|
.member_("x", &ivec2::x, {
|
||||||
|
.metadata{{"desc", meta::uvalue{"x-member"s}}}
|
||||||
|
})
|
||||||
|
.member_("y", &ivec2::y, {
|
||||||
|
.metadata{{"desc", meta::uvalue{"y-member"s}}}
|
||||||
|
})
|
||||||
|
.method_("add", &ivec2::add, {
|
||||||
|
.arguments{{
|
||||||
|
.name{"other"},
|
||||||
|
.metadata{{"desc", meta::uvalue{"other-arg"s}}}
|
||||||
|
}},
|
||||||
|
.metadata{{"desc", meta::uvalue{"add-method"s}}}
|
||||||
|
})
|
||||||
|
.function_("iadd", &ivec2::iadd, {
|
||||||
|
.arguments{{
|
||||||
|
.name{"l"},
|
||||||
|
.metadata{{"desc", meta::uvalue{"l-arg"s}}}
|
||||||
|
},{
|
||||||
|
.name{"r"},
|
||||||
|
.metadata{{"desc", meta::uvalue{"r-arg"s}}}
|
||||||
|
}},
|
||||||
|
.metadata{{"desc", meta::uvalue{"iadd-function"s}}}
|
||||||
|
});
|
||||||
|
|
||||||
|
// metadata override
|
||||||
|
|
||||||
|
meta::class_<ivec2>({
|
||||||
|
.metadata{
|
||||||
|
{"desc2", meta::uvalue{"new-class-desc2"s}},
|
||||||
|
{"desc3", meta::uvalue{"new-class-desc3"s}},
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
const meta::class_type ivec2_type = meta::resolve_type<ivec2>();
|
||||||
|
REQUIRE(ivec2_type);
|
||||||
|
|
||||||
|
SUBCASE("ivec2") {
|
||||||
|
CHECK(ivec2_type.get_metadata().at("desc1") == "class-desc1"s);
|
||||||
|
CHECK(ivec2_type.get_metadata().at("desc2") == "new-class-desc2"s);
|
||||||
|
CHECK(ivec2_type.get_metadata().at("desc3") == "new-class-desc3"s);
|
||||||
|
}
|
||||||
|
|
||||||
|
SUBCASE("ivec2(int)") {
|
||||||
|
const meta::constructor ivec2_ctor = ivec2_type.get_constructor_with<int>();
|
||||||
|
REQUIRE(ivec2_ctor);
|
||||||
|
|
||||||
|
REQUIRE(ivec2_ctor.get_metadata().contains("desc"));
|
||||||
|
CHECK(ivec2_ctor.get_metadata().at("desc") == "one arg 2d vector ctor"s);
|
||||||
|
|
||||||
|
REQUIRE(ivec2_ctor.get_argument(0));
|
||||||
|
CHECK(ivec2_ctor.get_argument(0).get_name() == "v");
|
||||||
|
CHECK(ivec2_ctor.get_argument(0).get_position() == 0);
|
||||||
|
CHECK(ivec2_ctor.get_argument(0).get_type() == meta::resolve_type<int>());
|
||||||
|
REQUIRE(ivec2_ctor.get_argument(0).get_metadata().contains("desc"));
|
||||||
|
CHECK(ivec2_ctor.get_argument(0).get_metadata().at("desc") == "the ctor arg"s);
|
||||||
|
|
||||||
|
REQUIRE_FALSE(ivec2_ctor.get_argument(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
SUBCASE("ivec2(int, int)") {
|
||||||
|
const meta::constructor ivec2_ctor = ivec2_type.get_constructor_with<int, int>();
|
||||||
|
REQUIRE(ivec2_ctor);
|
||||||
|
|
||||||
|
REQUIRE(ivec2_ctor.get_metadata().contains("desc"));
|
||||||
|
CHECK(ivec2_ctor.get_metadata().at("desc") == "two args 2d vector ctor"s);
|
||||||
|
|
||||||
|
REQUIRE(ivec2_ctor.get_argument(0));
|
||||||
|
CHECK(ivec2_ctor.get_argument(0).get_name() == "x");
|
||||||
|
CHECK(ivec2_ctor.get_argument(0).get_position() == 0);
|
||||||
|
CHECK(ivec2_ctor.get_argument(0).get_type() == meta::resolve_type<int>());
|
||||||
|
REQUIRE(ivec2_ctor.get_argument(0).get_metadata().contains("desc"));
|
||||||
|
CHECK(ivec2_ctor.get_argument(0).get_metadata().at("desc") == "the 1st ctor arg"s);
|
||||||
|
|
||||||
|
REQUIRE(ivec2_ctor.get_argument(1));
|
||||||
|
CHECK(ivec2_ctor.get_argument(1).get_name() == "y");
|
||||||
|
CHECK(ivec2_ctor.get_argument(1).get_position() == 1);
|
||||||
|
CHECK(ivec2_ctor.get_argument(1).get_type() == meta::resolve_type<int>());
|
||||||
|
REQUIRE(ivec2_ctor.get_argument(1).get_metadata().contains("desc"));
|
||||||
|
CHECK(ivec2_ctor.get_argument(1).get_metadata().at("desc") == "the 2nd ctor arg"s);
|
||||||
|
|
||||||
|
REQUIRE_FALSE(ivec2_ctor.get_argument(2));
|
||||||
|
}
|
||||||
|
|
||||||
|
SUBCASE("ivec2::x") {
|
||||||
|
const meta::member ivec2_x = ivec2_type.get_member("x");
|
||||||
|
REQUIRE(ivec2_x);
|
||||||
|
|
||||||
|
REQUIRE(ivec2_x.get_metadata().contains("desc"));
|
||||||
|
CHECK(ivec2_x.get_metadata().at("desc") == "x-member"s);
|
||||||
|
}
|
||||||
|
|
||||||
|
SUBCASE("ivec2::y") {
|
||||||
|
const meta::member ivec2_y = ivec2_type.get_member("y");
|
||||||
|
REQUIRE(ivec2_y);
|
||||||
|
|
||||||
|
REQUIRE(ivec2_y.get_metadata().contains("desc"));
|
||||||
|
CHECK(ivec2_y.get_metadata().at("desc") == "y-member"s);
|
||||||
|
}
|
||||||
|
|
||||||
|
SUBCASE("ivec2::add") {
|
||||||
|
const meta::method ivec2_add = ivec2_type.get_method("add");
|
||||||
|
REQUIRE(ivec2_add);
|
||||||
|
|
||||||
|
REQUIRE(ivec2_add.get_metadata().contains("desc"));
|
||||||
|
CHECK(ivec2_add.get_metadata().at("desc") == "add-method"s);
|
||||||
|
|
||||||
|
REQUIRE(ivec2_add.get_argument(0));
|
||||||
|
REQUIRE(ivec2_add.get_argument(0).get_metadata().contains("desc"));
|
||||||
|
CHECK(ivec2_add.get_argument(0).get_metadata().at("desc") == "other-arg"s);
|
||||||
|
}
|
||||||
|
|
||||||
|
SUBCASE("ivec2::iadd") {
|
||||||
|
const meta::function ivec2_iadd = ivec2_type.get_function("iadd");
|
||||||
|
REQUIRE(ivec2_iadd);
|
||||||
|
|
||||||
|
REQUIRE(ivec2_iadd.get_metadata().contains("desc"));
|
||||||
|
CHECK(ivec2_iadd.get_metadata().at("desc") == "iadd-function"s);
|
||||||
|
|
||||||
|
REQUIRE(ivec2_iadd.get_argument(0));
|
||||||
|
REQUIRE(ivec2_iadd.get_argument(0).get_metadata().contains("desc"));
|
||||||
|
CHECK(ivec2_iadd.get_argument(0).get_metadata().at("desc") == "l-arg"s);
|
||||||
|
|
||||||
|
REQUIRE(ivec2_iadd.get_argument(1));
|
||||||
|
REQUIRE(ivec2_iadd.get_argument(1).get_metadata().contains("desc"));
|
||||||
|
CHECK(ivec2_iadd.get_argument(1).get_metadata().at("desc") == "r-arg"s);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -70,7 +70,7 @@ namespace
|
|||||||
{\
|
{\
|
||||||
using namespace meta::detail;\
|
using namespace meta::detail;\
|
||||||
auto function_ptr = meta::select_overload<int(ToType)>(&FName);\
|
auto function_ptr = meta::select_overload<int(ToType)>(&FName);\
|
||||||
meta::function f_state{function_state::make<meta::function_policy::as_copy>("", function_ptr)};\
|
meta::function f_state{function_state::make<meta::function_policy::as_copy>("", function_ptr, {})};\
|
||||||
\
|
\
|
||||||
if ( std::is_invocable_v<decltype(function_ptr), decltype(FromValue)> ) {\
|
if ( std::is_invocable_v<decltype(function_ptr), decltype(FromValue)> ) {\
|
||||||
CHECK(uarg{FromValue}.can_cast_to<ToType>());\
|
CHECK(uarg{FromValue}.can_cast_to<ToType>());\
|
||||||
@@ -94,7 +94,7 @@ namespace
|
|||||||
{\
|
{\
|
||||||
using namespace meta::detail;\
|
using namespace meta::detail;\
|
||||||
auto function_ptr = meta::select_overload<int(ToType)>(&FName);\
|
auto function_ptr = meta::select_overload<int(ToType)>(&FName);\
|
||||||
meta::function f_state{function_state::make<meta::function_policy::as_copy>("", function_ptr)};\
|
meta::function f_state{function_state::make<meta::function_policy::as_copy>("", function_ptr, {})};\
|
||||||
\
|
\
|
||||||
if ( std::is_invocable_v<decltype(function_ptr), FromType> ) {\
|
if ( std::is_invocable_v<decltype(function_ptr), FromType> ) {\
|
||||||
CHECK(f_state.is_invocable_with<FromType>());\
|
CHECK(f_state.is_invocable_with<FromType>());\
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ namespace
|
|||||||
{\
|
{\
|
||||||
using namespace meta::detail;\
|
using namespace meta::detail;\
|
||||||
auto method_ptr = meta::select_overload<int() Qualifiers>(&clazz::FName);\
|
auto method_ptr = meta::select_overload<int() Qualifiers>(&clazz::FName);\
|
||||||
meta::method m_state{method_state::make<meta::method_policy::as_copy>("", method_ptr)};\
|
meta::method m_state{method_state::make<meta::method_policy::as_copy>("", method_ptr, {})};\
|
||||||
\
|
\
|
||||||
if ( std::is_invocable_v<decltype(method_ptr), decltype(Inst)> ) {\
|
if ( std::is_invocable_v<decltype(method_ptr), decltype(Inst)> ) {\
|
||||||
CHECK(uinst{Inst}.can_cast_to<clazz Qualifiers>());\
|
CHECK(uinst{Inst}.can_cast_to<clazz Qualifiers>());\
|
||||||
@@ -54,7 +54,7 @@ namespace
|
|||||||
{\
|
{\
|
||||||
using namespace meta::detail;\
|
using namespace meta::detail;\
|
||||||
auto method_ptr = meta::select_overload<int() ToQualifiers>(&clazz::FName);\
|
auto method_ptr = meta::select_overload<int() ToQualifiers>(&clazz::FName);\
|
||||||
meta::method m_state{method_state::make<meta::method_policy::as_copy>("", method_ptr)};\
|
meta::method m_state{method_state::make<meta::method_policy::as_copy>("", method_ptr, {})};\
|
||||||
\
|
\
|
||||||
if ( std::is_invocable_v<decltype(method_ptr), FromType> ) {\
|
if ( std::is_invocable_v<decltype(method_ptr), FromType> ) {\
|
||||||
CHECK(m_state.is_invocable_with<FromType>());\
|
CHECK(m_state.is_invocable_with<FromType>());\
|
||||||
|
|||||||
Reference in New Issue
Block a user