mirror of
https://github.com/BlackMATov/meta.hpp.git
synced 2025-12-16 22:17:02 +07:00
class bind concepts instead static assets
This commit is contained in:
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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_;
|
||||||
|
|||||||
@@ -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));
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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_);
|
||||||
|
|||||||
@@ -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*>());
|
||||||
|
|||||||
Reference in New Issue
Block a user