class bind concepts instead static assets

This commit is contained in:
BlackMATov
2022-01-16 14:50:11 +07:00
parent 0564b10557
commit 4bfdc9d69b
6 changed files with 61 additions and 22 deletions

View File

@@ -47,7 +47,7 @@ namespace meta_hpp
} }
template < typename Signature, typename Class > template < typename Signature, typename Class >
constexpr auto select(Signature Class::*func) -> decltype(func) { constexpr auto select(Signature Class::*func) noexcept -> Signature Class::* {
return func; return func;
} }

View File

@@ -9,6 +9,37 @@
#include "meta_base.hpp" #include "meta_base.hpp"
#include "meta_states.hpp" #include "meta_states.hpp"
namespace meta_hpp::detail
{
template < typename Class, typename... Args >
concept class_bind_ctor_kind =
class_kind<Class> &&
requires(Args&&... args) { { Class{std::forward<Args>(args)...} }; };
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 Function >
concept class_bind_function_kind =
class_kind<Class> && function_kind<Function>;
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>;
template < typename Class, typename Pointer >
concept class_bind_variable_kind =
class_kind<Class> && pointer_kind<Pointer>;
}
namespace meta_hpp namespace meta_hpp
{ {
template < detail::class_kind Class > template < detail::class_kind Class >
@@ -18,21 +49,27 @@ namespace meta_hpp
operator class_type() const noexcept; operator class_type() const noexcept;
template < typename... Args > template < typename... Args >
requires detail::class_bind_ctor_kind<Class, Args...>
class_bind& ctor_(); class_bind& ctor_();
template < detail::class_kind Base > template < detail::class_kind Base >
requires detail::class_bind_base_kind<Class, Base>
class_bind& base_(); class_bind& base_();
template < detail::function_kind Function > template < detail::function_kind Function >
requires detail::class_bind_function_kind<Class, Function>
class_bind& function_(std::string name, Function function); class_bind& function_(std::string name, Function function);
template < detail::member_kind Member > template < detail::member_kind Member >
requires detail::class_bind_member_kind<Class, Member>
class_bind& member_(std::string name, Member member); class_bind& member_(std::string name, Member member);
template < detail::method_kind Method > template < detail::method_kind Method >
requires detail::class_bind_method_kind<Class, Method>
class_bind& method_(std::string name, Method method); class_bind& method_(std::string name, Method method);
template < detail::pointer_kind Pointer > template < detail::pointer_kind Pointer >
requires detail::class_bind_variable_kind<Class, Pointer>
class_bind& variable_(std::string name, Pointer pointer); class_bind& variable_(std::string name, Pointer pointer);
private: private:
detail::class_type_data_ptr data_; detail::class_type_data_ptr data_;

View File

@@ -22,8 +22,8 @@ namespace meta_hpp
template < detail::class_kind Class > template < detail::class_kind Class >
template < typename... Args > template < typename... Args >
requires detail::class_bind_ctor_kind<Class, Args...>
class_bind<Class>& class_bind<Class>::ctor_() { class_bind<Class>& class_bind<Class>::ctor_() {
static_assert(detail::stdex::constructible_from<Class, Args...>);
auto ctor_state = detail::ctor_state::make<Class, Args...>(); auto ctor_state = detail::ctor_state::make<Class, Args...>();
data_->ctors.emplace(ctor_state->index, std::move(ctor_state)); data_->ctors.emplace(ctor_state->index, std::move(ctor_state));
return *this; return *this;
@@ -31,8 +31,8 @@ namespace meta_hpp
template < detail::class_kind Class > template < detail::class_kind Class >
template < detail::class_kind Base > template < detail::class_kind Base >
requires detail::class_bind_base_kind<Class, Base>
class_bind<Class>& class_bind<Class>::base_() { class_bind<Class>& class_bind<Class>::base_() {
static_assert(detail::stdex::derived_from<Class, Base>);
data_->bases.emplace(resolve_type<Base>()); data_->bases.emplace(resolve_type<Base>());
data_->bases_info.emplace(resolve_type<Base>(), detail::class_type_data::base_info{ data_->bases_info.emplace(resolve_type<Base>(), detail::class_type_data::base_info{
.upcast = +[](void* derived) -> void* { .upcast = +[](void* derived) -> void* {
@@ -44,6 +44,7 @@ namespace meta_hpp
template < detail::class_kind Class > template < detail::class_kind Class >
template < detail::function_kind Function > template < detail::function_kind Function >
requires detail::class_bind_function_kind<Class, Function>
class_bind<Class>& class_bind<Class>::function_(std::string name, Function function) { class_bind<Class>& class_bind<Class>::function_(std::string name, Function function) {
auto function_state = detail::function_state::make<Function>(std::move(name), std::move(function)); auto function_state = detail::function_state::make<Function>(std::move(name), std::move(function));
data_->functions.emplace(function_state->index, std::move(function_state)); data_->functions.emplace(function_state->index, std::move(function_state));
@@ -52,8 +53,8 @@ namespace meta_hpp
template < detail::class_kind Class > template < detail::class_kind Class >
template < detail::member_kind Member > template < detail::member_kind Member >
requires detail::class_bind_member_kind<Class, Member>
class_bind<Class>& class_bind<Class>::member_(std::string name, Member member) { class_bind<Class>& class_bind<Class>::member_(std::string name, Member member) {
static_assert(std::is_same_v<Class, typename detail::member_traits<Member>::class_type>);
auto member_state = detail::member_state::make<Member>(std::move(name), std::move(member)); auto member_state = detail::member_state::make<Member>(std::move(name), std::move(member));
data_->members.emplace(member_state->index, std::move(member_state)); data_->members.emplace(member_state->index, std::move(member_state));
return *this; return *this;
@@ -61,8 +62,8 @@ namespace meta_hpp
template < detail::class_kind Class > template < detail::class_kind Class >
template < detail::method_kind Method > template < detail::method_kind Method >
requires detail::class_bind_method_kind<Class, Method>
class_bind<Class>& class_bind<Class>::method_(std::string name, Method method) { class_bind<Class>& class_bind<Class>::method_(std::string name, Method method) {
static_assert(std::is_same_v<Class, typename detail::method_traits<Method>::class_type>);
auto method_state = detail::method_state::make<Method>(std::move(name), std::move(method)); auto method_state = detail::method_state::make<Method>(std::move(name), std::move(method));
data_->methods.emplace(method_state->index, std::move(method_state)); data_->methods.emplace(method_state->index, std::move(method_state));
return *this; return *this;
@@ -70,6 +71,7 @@ namespace meta_hpp
template < detail::class_kind Class > template < detail::class_kind Class >
template < detail::pointer_kind Pointer > template < detail::pointer_kind Pointer >
requires detail::class_bind_variable_kind<Class, Pointer>
class_bind<Class>& class_bind<Class>::variable_(std::string name, Pointer pointer) { class_bind<Class>& class_bind<Class>::variable_(std::string name, Pointer pointer) {
auto variable_state = detail::variable_state::make<Pointer>(std::move(name), std::move(pointer)); auto variable_state = detail::variable_state::make<Pointer>(std::move(name), std::move(pointer));
data_->variables.emplace(variable_state->index, std::move(variable_state)); data_->variables.emplace(variable_state->index, std::move(variable_state));

View File

@@ -122,7 +122,7 @@ TEST_CASE("meta/meta_states/function") {
CHECK(func.is_invocable_with<int*>()); CHECK(func.is_invocable_with<int*>());
CHECK(func.is_invocable_with<const int*>()); CHECK(func.is_invocable_with<const int*>());
CHECK(func.is_invocable_with<nullptr_t>()); CHECK(func.is_invocable_with<std::nullptr_t>());
int i{42}; int i{42};
CHECK(func.invoke(&i) == false); CHECK(func.invoke(&i) == false);

View File

@@ -174,8 +174,8 @@ TEST_CASE("meta/meta_types/any_type") {
const meta::any_type& type = meta::resolve_type(nullptr); const meta::any_type& type = meta::resolve_type(nullptr);
REQUIRE(type); REQUIRE(type);
REQUIRE(type == meta::resolve_type<nullptr_t>()); REQUIRE(type == meta::resolve_type<std::nullptr_t>());
REQUIRE(type.get_id() == meta::resolve_type<nullptr_t>().get_id()); REQUIRE(type.get_id() == meta::resolve_type<std::nullptr_t>().get_id());
CHECK(type.is_nullptr()); CHECK(type.is_nullptr());
CHECK(type.get_kind() == meta::type_kind::nullptr_); CHECK(type.get_kind() == meta::type_kind::nullptr_);

View File

@@ -134,22 +134,22 @@ TEST_CASE("meta/meta_utilities/arg7/cast/from_nullptr") {
using meta::detail::arg; using meta::detail::arg;
SUBCASE("nullptr -> *") { SUBCASE("nullptr -> *") {
static_assert(std::is_invocable_v<void(int*), nullptr_t>); static_assert(std::is_invocable_v<void(int*), std::nullptr_t>);
static_assert(std::is_invocable_v<void(int*), nullptr_t&>); static_assert(std::is_invocable_v<void(int*), std::nullptr_t&>);
static_assert(std::is_invocable_v<void(int*), nullptr_t&&>); static_assert(std::is_invocable_v<void(int*), std::nullptr_t&&>);
static_assert(std::is_invocable_v<void(int*), const nullptr_t>); static_assert(std::is_invocable_v<void(int*), const std::nullptr_t>);
static_assert(std::is_invocable_v<void(int*), const nullptr_t&>); static_assert(std::is_invocable_v<void(int*), const std::nullptr_t&>);
static_assert(std::is_invocable_v<void(int*), const nullptr_t&&>); static_assert(std::is_invocable_v<void(int*), const std::nullptr_t&&>);
static_assert(std::is_invocable_v<void(const D*), nullptr_t>); static_assert(std::is_invocable_v<void(const D*), std::nullptr_t>);
static_assert(std::is_invocable_v<void(const D*), nullptr_t&>); static_assert(std::is_invocable_v<void(const D*), std::nullptr_t&>);
static_assert(std::is_invocable_v<void(const D*), nullptr_t&&>); static_assert(std::is_invocable_v<void(const D*), std::nullptr_t&&>);
static_assert(std::is_invocable_v<void(const D*), const nullptr_t>); static_assert(std::is_invocable_v<void(const D*), const std::nullptr_t>);
static_assert(std::is_invocable_v<void(const D*), const nullptr_t&>); static_assert(std::is_invocable_v<void(const D*), const std::nullptr_t&>);
static_assert(std::is_invocable_v<void(const D*), const nullptr_t&&>); static_assert(std::is_invocable_v<void(const D*), const std::nullptr_t&&>);
nullptr_t n1{nullptr}; std::nullptr_t n1{nullptr};
const nullptr_t n2{nullptr}; const std::nullptr_t n2{nullptr};
CHECK(arg{n1}.can_cast_to<int*>()); CHECK(arg{n1}.can_cast_to<int*>());
CHECK(arg{std::move(n1)}.can_cast_to<int*>()); CHECK(arg{std::move(n1)}.can_cast_to<int*>());