mirror of
https://github.com/BlackMATov/meta.hpp.git
synced 2025-12-15 03:45:30 +07:00
check class member pointers arg
This commit is contained in:
@@ -200,8 +200,7 @@ namespace meta_hpp::detail
|
|||||||
const any_type& from_data_type = from_type_array.get_data_type();
|
const any_type& from_data_type = from_type_array.get_data_type();
|
||||||
|
|
||||||
if ( to_data_type == from_data_type ) {
|
if ( to_data_type == from_data_type ) {
|
||||||
void* to_ptr = static_cast<void*>(data_);
|
return static_cast<to_raw_type_cv>(data_);
|
||||||
return static_cast<to_raw_type_cv>(to_ptr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( to_data_type.is_class() && from_data_type.is_class() ) {
|
if ( to_data_type.is_class() && from_data_type.is_class() ) {
|
||||||
@@ -223,30 +222,27 @@ namespace meta_hpp::detail
|
|||||||
void** from_data_ptr = static_cast<void**>(data_);
|
void** from_data_ptr = static_cast<void**>(data_);
|
||||||
|
|
||||||
if ( to_data_type == from_data_type ) {
|
if ( to_data_type == from_data_type ) {
|
||||||
void* to_data_ptr = *from_data_ptr;
|
return static_cast<to_raw_type_cv>(*from_data_ptr);
|
||||||
return static_cast<to_raw_type_cv>(to_data_ptr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( to_data_type.is_class() && from_data_type.is_class() ) {
|
if ( to_data_type.is_class() && from_data_type.is_class() ) {
|
||||||
const class_type& to_data_class = to_data_type.as_class();
|
const class_type& to_data_class = to_data_type.as_class();
|
||||||
const class_type& from_data_class = from_data_type.as_class();
|
const class_type& from_data_class = from_data_type.as_class();
|
||||||
|
|
||||||
void* to_data_ptr = detail::pointer_upcast(*from_data_ptr, from_data_class, to_data_class);
|
void* to_ptr = detail::pointer_upcast(*from_data_ptr, from_data_class, to_data_class);
|
||||||
return static_cast<to_raw_type_cv>(to_data_ptr);
|
return static_cast<to_raw_type_cv>(to_ptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if constexpr ( std::is_reference_v<To> ) {
|
if constexpr ( std::is_reference_v<To> ) {
|
||||||
if ( to_type == from_type ) {
|
if ( to_type == from_type ) {
|
||||||
void* to_ptr = static_cast<void*>(data_);
|
|
||||||
|
|
||||||
if constexpr ( std::is_lvalue_reference_v<To> ) {
|
if constexpr ( std::is_lvalue_reference_v<To> ) {
|
||||||
return *static_cast<to_raw_type_cv*>(to_ptr);
|
return *static_cast<to_raw_type_cv*>(data_);
|
||||||
}
|
}
|
||||||
|
|
||||||
if constexpr ( std::is_rvalue_reference_v<To> ) {
|
if constexpr ( std::is_rvalue_reference_v<To> ) {
|
||||||
return std::move(*static_cast<to_raw_type_cv*>(to_ptr));
|
return std::move(*static_cast<to_raw_type_cv*>(data_));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,12 @@
|
|||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
struct clazz {
|
struct base {
|
||||||
|
virtual ~base() = default;
|
||||||
|
virtual int pure_virtual_method() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct clazz : base {
|
||||||
clazz() = default;
|
clazz() = default;
|
||||||
|
|
||||||
clazz(clazz&&) = delete;
|
clazz(clazz&&) = delete;
|
||||||
@@ -36,10 +41,14 @@ namespace
|
|||||||
|
|
||||||
int const_method_rref() const && { return 11; }
|
int const_method_rref() const && { return 11; }
|
||||||
int const_method_noexcept_rref() const && noexcept { return 12; }
|
int const_method_noexcept_rref() const && noexcept { return 12; }
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
int pure_virtual_method() override { return -1; }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct derived_clazz : clazz {
|
struct derived_clazz : clazz {
|
||||||
[[maybe_unused]] derived_clazz() = default;
|
int pure_virtual_method() override { return -2; }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct clazz2 {};
|
struct clazz2 {};
|
||||||
@@ -48,10 +57,12 @@ namespace
|
|||||||
TEST_CASE("meta/meta_states/method") {
|
TEST_CASE("meta/meta_states/method") {
|
||||||
namespace meta = meta_hpp;
|
namespace meta = meta_hpp;
|
||||||
|
|
||||||
meta::class_<derived_clazz>()
|
meta::class_<base>()
|
||||||
.base_<clazz>();
|
.method_("pure_virtual_method", &base::pure_virtual_method);
|
||||||
|
|
||||||
meta::class_<clazz>()
|
meta::class_<clazz>()
|
||||||
|
.base_<base>()
|
||||||
|
|
||||||
.method_("non_const_method", &clazz::non_const_method)
|
.method_("non_const_method", &clazz::non_const_method)
|
||||||
.method_("non_const_method_noexcept", &clazz::non_const_method_noexcept)
|
.method_("non_const_method_noexcept", &clazz::non_const_method_noexcept)
|
||||||
|
|
||||||
@@ -70,6 +81,9 @@ TEST_CASE("meta/meta_states/method") {
|
|||||||
.method_("const_method_rref", &clazz::const_method_rref)
|
.method_("const_method_rref", &clazz::const_method_rref)
|
||||||
.method_("const_method_noexcept_rref", &clazz::const_method_noexcept_rref);
|
.method_("const_method_noexcept_rref", &clazz::const_method_noexcept_rref);
|
||||||
|
|
||||||
|
meta::class_<derived_clazz>()
|
||||||
|
.base_<clazz>();
|
||||||
|
|
||||||
const meta::class_type ct = meta::resolve_type<clazz>();
|
const meta::class_type ct = meta::resolve_type<clazz>();
|
||||||
REQUIRE(ct);
|
REQUIRE(ct);
|
||||||
|
|
||||||
@@ -627,4 +641,30 @@ TEST_CASE("meta/meta_states/method") {
|
|||||||
static_assert(std::is_invocable_v<decltype(&clazz::const_method_noexcept_rref), derived_clazz&&>);
|
static_assert(std::is_invocable_v<decltype(&clazz::const_method_noexcept_rref), derived_clazz&&>);
|
||||||
static_assert(std::is_invocable_v<decltype(&clazz::const_method_noexcept_rref), const derived_clazz&&>);
|
static_assert(std::is_invocable_v<decltype(&clazz::const_method_noexcept_rref), const derived_clazz&&>);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SUBCASE("pure_virtual_method") {
|
||||||
|
const meta::method mi = ct.get_method("pure_virtual_method");
|
||||||
|
REQUIRE(mi);
|
||||||
|
|
||||||
|
CHECK(mi.get_name() == "pure_virtual_method");
|
||||||
|
|
||||||
|
{
|
||||||
|
CHECK(mi.get_type().get_arity() == 0);
|
||||||
|
CHECK(mi.get_type().get_owner_type() == meta::resolve_type<base>());
|
||||||
|
CHECK(mi.get_type().get_return_type() == meta::resolve_type<int>());
|
||||||
|
CHECK(mi.get_type().get_flags() == meta::method_flags{});
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
clazz cl;
|
||||||
|
CHECK(mi.is_invocable_with<clazz&>());
|
||||||
|
CHECK(mi.invoke(cl) == -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
derived_clazz dcl;
|
||||||
|
CHECK(mi.is_invocable_with<derived_clazz&>());
|
||||||
|
CHECK(mi.invoke(dcl) == -2);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
72
untests/meta_utilities/arg6_tests.cpp
Normal file
72
untests/meta_utilities/arg6_tests.cpp
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
/*******************************************************************************
|
||||||
|
* 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, by Matvey Cherevko (blackmatov@gmail.com)
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
#include "../meta_untests.hpp"
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
struct base {
|
||||||
|
virtual ~base() = default;
|
||||||
|
virtual int int_method() const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct clazz : base {
|
||||||
|
int int_member{42};
|
||||||
|
int int_method() const override { return int_member; }
|
||||||
|
};
|
||||||
|
|
||||||
|
using int_member_t = int clazz::*;
|
||||||
|
using int_method_t = int (clazz::*)() const;
|
||||||
|
|
||||||
|
int func_with_member(const clazz& cl, int_member_t m) {
|
||||||
|
return std::invoke(m, cl);
|
||||||
|
}
|
||||||
|
|
||||||
|
int func_with_method(const clazz& cl, int_method_t m) {
|
||||||
|
return std::invoke(m, cl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("meta/meta_utilities/arg6") {
|
||||||
|
namespace meta = meta_hpp;
|
||||||
|
using meta::detail::arg;
|
||||||
|
|
||||||
|
const meta::scope scope = meta::local_scope_("scope")
|
||||||
|
.function_("func_with_member", &func_with_member)
|
||||||
|
.function_("func_with_method", &func_with_method);
|
||||||
|
|
||||||
|
SUBCASE("int_member") {
|
||||||
|
static_assert(sizeof(int_member_t) == 8);
|
||||||
|
|
||||||
|
const meta::function f = scope.get_function("func_with_member");
|
||||||
|
REQUIRE(f);
|
||||||
|
|
||||||
|
clazz cl;
|
||||||
|
CHECK(f.is_invocable_with<clazz&, int_member_t>());
|
||||||
|
|
||||||
|
CHECK(f.is_invocable_with(cl, &clazz::int_member));
|
||||||
|
CHECK(f.invoke(cl, &clazz::int_member) == 42);
|
||||||
|
|
||||||
|
CHECK(f.is_invocable_with(meta::value{cl}, meta::value{&clazz::int_member}));
|
||||||
|
CHECK(f.invoke(meta::value{cl}, meta::value{&clazz::int_member}) == 42);
|
||||||
|
}
|
||||||
|
|
||||||
|
SUBCASE("int_method") {
|
||||||
|
static_assert(sizeof(int_method_t) == 16);
|
||||||
|
|
||||||
|
const meta::function f = scope.get_function("func_with_method");
|
||||||
|
REQUIRE(f);
|
||||||
|
|
||||||
|
clazz cl;
|
||||||
|
CHECK(f.is_invocable_with<clazz&, int_method_t>());
|
||||||
|
|
||||||
|
CHECK(f.is_invocable_with(cl, &clazz::int_method));
|
||||||
|
CHECK(f.invoke(cl, &clazz::int_method) == 42);
|
||||||
|
|
||||||
|
CHECK(f.is_invocable_with(meta::value{cl}, meta::value{&clazz::int_method}));
|
||||||
|
CHECK(f.invoke(meta::value{cl}, meta::value{&clazz::int_method}) == 42);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user