inst cast to base

This commit is contained in:
BlackMATov
2021-11-27 01:01:54 +07:00
parent 8eb15af7be
commit 0fe5278a03
7 changed files with 538 additions and 96 deletions

View File

@@ -31,6 +31,7 @@ target_compile_options(${PROJECT_NAME}
-Wno-exit-time-destructors -Wno-exit-time-destructors
-Wno-float-equal -Wno-float-equal
-Wno-padded -Wno-padded
-Wno-shadow-field
-Wno-shadow-field-in-constructor -Wno-shadow-field-in-constructor
-Wno-unknown-warning-option -Wno-unknown-warning-option
-Wno-weak-vtables -Wno-weak-vtables

View File

@@ -97,12 +97,12 @@ namespace meta_hpp::detail
arg_base& operator=(const arg_base&) = delete; arg_base& operator=(const arg_base&) = delete;
template < typename T, std::enable_if_t< template < typename T, std::enable_if_t<
std::is_pointer_v<T> || std::is_lvalue_reference_v<T> (std::is_pointer_v<T> || std::is_lvalue_reference_v<T>)
, int> = 0 > , int> = 0 >
explicit arg_base(type_list<T>); explicit arg_base(type_list<T>);
template < typename T, std::enable_if_t< template < typename T, std::enable_if_t<
std::is_rvalue_reference_v<T> || (std::is_rvalue_reference_v<T>) ||
(!std::is_pointer_v<T> && !std::is_reference_v<T>) (!std::is_pointer_v<T> && !std::is_reference_v<T>)
, int> = 0 > , int> = 0 >
explicit arg_base(type_list<T>); explicit arg_base(type_list<T>);
@@ -139,17 +139,16 @@ namespace meta_hpp::detail
arg(const arg&) = delete; arg(const arg&) = delete;
arg& operator=(const arg&) = delete; arg& operator=(const arg&) = delete;
template < typename T, typename Tp = std::decay_t<T>
, std::enable_if_t<std::is_same_v<Tp, value>, int> = 0 >
explicit arg(T&& v);
template < typename T, typename Tp = std::decay_t<T> template < typename T, typename Tp = std::decay_t<T>
, std::enable_if_t<!std::is_same_v<Tp, arg>, int> = 0 , std::enable_if_t<!std::is_same_v<Tp, arg>, int> = 0
, std::enable_if_t<!std::is_same_v<Tp, inst>, int> = 0 , std::enable_if_t<!std::is_same_v<Tp, inst>, int> = 0
, std::enable_if_t<!std::is_same_v<Tp, value>, int> = 0 > , std::enable_if_t<!std::is_same_v<Tp, value>, int> = 0 >
explicit arg(T&& v); explicit arg(T&& v);
explicit arg(value& v);
explicit arg(value&& v);
explicit arg(const value& v);
explicit arg(const value&& v);
template < typename To > template < typename To >
To cast() const; To cast() const;
private: private:
@@ -177,12 +176,12 @@ namespace meta_hpp::detail
inst_base& operator=(const inst_base&) = delete; inst_base& operator=(const inst_base&) = delete;
template < typename T, std::enable_if_t< template < typename T, std::enable_if_t<
std::is_lvalue_reference_v<T> && std::is_class_v<std::remove_reference_t<T>> (std::is_lvalue_reference_v<T> && std::is_class_v<std::remove_reference_t<T>>)
, int> = 0> , int> = 0>
explicit inst_base(type_list<T>); explicit inst_base(type_list<T>);
template < typename T, std::enable_if_t< template < typename T, std::enable_if_t<
std::is_class_v<T> || (std::is_class_v<T>) ||
(std::is_rvalue_reference_v<T> && std::is_class_v<std::remove_reference_t<T>>) (std::is_rvalue_reference_v<T> && std::is_class_v<std::remove_reference_t<T>>)
, int> = 0> , int> = 0>
explicit inst_base(type_list<T>); explicit inst_base(type_list<T>);
@@ -196,14 +195,17 @@ namespace meta_hpp::detail
bool is_lvalue() const noexcept; bool is_lvalue() const noexcept;
bool is_rvalue() const noexcept; bool is_rvalue() const noexcept;
any_type get_raw_type() const noexcept;
ref_types get_ref_type() const noexcept; ref_types get_ref_type() const noexcept;
const class_type& get_raw_type() const noexcept;
template < typename To > template < typename To, std::enable_if_t<
(std::is_class_v<To>) ||
(std::is_reference_v<To> && std::is_class_v<std::remove_reference_t<To>>)
, int> = 0>
bool can_cast_to() const noexcept; bool can_cast_to() const noexcept;
private: private:
any_type raw_type_{};
ref_types ref_type_{}; ref_types ref_type_{};
class_type raw_type_{};
}; };
} }
@@ -220,17 +222,19 @@ namespace meta_hpp::detail
inst& operator=(const inst&) = delete; inst& operator=(const inst&) = delete;
template < typename T, typename Tp = std::decay_t<T> template < typename T, typename Tp = std::decay_t<T>
, std::enable_if_t<std::is_same_v<Tp, value>, int> = 0 >
explicit inst(T&& v);
template < typename T, class_kind Tp = std::decay_t<T>
, std::enable_if_t<!std::is_same_v<Tp, arg>, int> = 0 , std::enable_if_t<!std::is_same_v<Tp, arg>, int> = 0
, std::enable_if_t<!std::is_same_v<Tp, inst>, int> = 0 , std::enable_if_t<!std::is_same_v<Tp, inst>, int> = 0
, std::enable_if_t<!std::is_same_v<Tp, value>, int> = 0 > , std::enable_if_t<!std::is_same_v<Tp, value>, int> = 0 >
explicit inst(T&& v); explicit inst(T&& v);
explicit inst(value& v); template < typename To, std::enable_if_t<
explicit inst(value&& v); (std::is_class_v<To>) ||
explicit inst(const value& v); (std::is_reference_v<To> && std::is_class_v<std::remove_reference_t<To>>)
explicit inst(const value&& v); , int> = 0>
template < typename To >
decltype(auto) cast() const; decltype(auto) cast() const;
private: private:
void* data_{}; void* data_{};

View File

@@ -12,14 +12,14 @@
namespace meta_hpp::detail namespace meta_hpp::detail
{ {
template < typename T, std::enable_if_t< template < typename T, std::enable_if_t<
std::is_pointer_v<T> || std::is_lvalue_reference_v<T> (std::is_pointer_v<T> || std::is_lvalue_reference_v<T>)
, int> > , int> >
arg_base::arg_base(type_list<T>) arg_base::arg_base(type_list<T>)
: raw_type_{resolve_type<std::remove_cvref_t<T>>()} : raw_type_{resolve_type<std::remove_cvref_t<T>>()}
, ref_type_{std::is_const_v<std::remove_reference_t<T>> ? ref_types::cref : ref_types::ref} {} , ref_type_{std::is_const_v<std::remove_reference_t<T>> ? ref_types::cref : ref_types::ref} {}
template < typename T, std::enable_if_t< template < typename T, std::enable_if_t<
std::is_rvalue_reference_v<T> || (std::is_rvalue_reference_v<T>) ||
(!std::is_pointer_v<T> && !std::is_reference_v<T>) (!std::is_pointer_v<T> && !std::is_reference_v<T>)
, int> > , int> >
arg_base::arg_base(type_list<T>) arg_base::arg_base(type_list<T>)
@@ -126,6 +126,12 @@ namespace meta_hpp::detail
namespace meta_hpp::detail namespace meta_hpp::detail
{ {
template < typename T, typename Tp
, std::enable_if_t<std::is_same_v<Tp, value>, int> >
arg::arg(T&& v)
: arg_base{std::forward<T>(v)}
, data_{const_cast<void*>(v.data())} {}
template < typename T, typename Tp template < typename T, typename Tp
, std::enable_if_t<!std::is_same_v<Tp, arg>, int> , std::enable_if_t<!std::is_same_v<Tp, arg>, int>
, std::enable_if_t<!std::is_same_v<Tp, inst>, int> , std::enable_if_t<!std::is_same_v<Tp, inst>, int>
@@ -134,22 +140,6 @@ namespace meta_hpp::detail
: arg_base{type_list<T&&>{}} : arg_base{type_list<T&&>{}}
, data_{const_cast<std::remove_cvref_t<T>*>(std::addressof(v))} {} , data_{const_cast<std::remove_cvref_t<T>*>(std::addressof(v))} {}
inline arg::arg(value& v)
: arg_base{v}
, data_{const_cast<void*>(v.data())} {}
inline arg::arg(value&& v)
: arg_base{v}
, data_{const_cast<void*>(v.data())} {}
inline arg::arg(const value& v)
: arg_base{v}
, data_{const_cast<void*>(v.data())} {}
inline arg::arg(const value&& v)
: arg_base{v}
, data_{const_cast<void*>(v.data())} {}
template < typename To > template < typename To >
To arg::cast() const { To arg::cast() const {
if ( !can_cast_to<To>() ) { if ( !can_cast_to<To>() ) {

View File

@@ -12,35 +12,51 @@
namespace meta_hpp::detail namespace meta_hpp::detail
{ {
template < typename T, std::enable_if_t< template < typename T, std::enable_if_t<
std::is_lvalue_reference_v<T> && std::is_class_v<std::remove_reference_t<T>> (std::is_lvalue_reference_v<T> && std::is_class_v<std::remove_reference_t<T>>)
, int> > , int> >
inst_base::inst_base(type_list<T>) inst_base::inst_base(type_list<T>)
: raw_type_{resolve_type<std::remove_cvref_t<T>>()} : ref_type_{std::is_const_v<std::remove_reference_t<T>> ? ref_types::cref : ref_types::ref}
, ref_type_{std::is_const_v<std::remove_reference_t<T>> ? ref_types::cref : ref_types::ref} {} , raw_type_{resolve_type<std::remove_cvref_t<T>>()} {}
template < typename T, std::enable_if_t< template < typename T, std::enable_if_t<
std::is_class_v<T> || (std::is_class_v<T>) ||
(std::is_rvalue_reference_v<T> && std::is_class_v<std::remove_reference_t<T>>) (std::is_rvalue_reference_v<T> && std::is_class_v<std::remove_reference_t<T>>)
, int> > , int> >
inst_base::inst_base(type_list<T>) inst_base::inst_base(type_list<T>)
: raw_type_{resolve_type<std::remove_cvref_t<T>>()} : ref_type_{std::is_const_v<std::remove_reference_t<T>> ? ref_types::crref : ref_types::rref}
, ref_type_{std::is_const_v<std::remove_reference_t<T>> ? ref_types::crref : ref_types::rref} {} , raw_type_{resolve_type<std::remove_cvref_t<T>>()} {}
inline inst_base::inst_base(value& v) inline inst_base::inst_base(value& v)
: raw_type_{v.get_type()} : ref_type_{ref_types::ref}
, ref_type_{ref_types::ref} {} , raw_type_{v.get_type().as_class()} {
if ( !v.get_type().is_class() ) {
throw std::logic_error("an attempt to create an instance with a non-class value type");
}
}
inline inst_base::inst_base(value&& v) inline inst_base::inst_base(value&& v)
: raw_type_{v.get_type()} : ref_type_{ref_types::rref}
, ref_type_{ref_types::rref} {} , raw_type_{v.get_type().as_class()} {
if ( !v.get_type().is_class() ) {
throw std::logic_error("an attempt to create an instance with a non-class value type");
}
}
inline inst_base::inst_base(const value& v) inline inst_base::inst_base(const value& v)
: raw_type_{v.get_type()} : ref_type_{ref_types::cref}
, ref_type_{ref_types::cref} {} , raw_type_{v.get_type().as_class()} {
if ( !v.get_type().is_class() ) {
throw std::logic_error("an attempt to create an instance with a non-class value type");
}
}
inline inst_base::inst_base(const value&& v) inline inst_base::inst_base(const value&& v)
: raw_type_{v.get_type()} : ref_type_{ref_types::crref}
, ref_type_{ref_types::crref} {} , raw_type_{v.get_type().as_class()} {
if ( !v.get_type().is_class() ) {
throw std::logic_error("an attempt to create an instance with a non-class value type");
}
}
inline bool inst_base::is_const() const noexcept { inline bool inst_base::is_const() const noexcept {
return ref_type_ == ref_types::cref return ref_type_ == ref_types::cref
@@ -57,20 +73,19 @@ namespace meta_hpp::detail
|| ref_type_ == ref_types::crref; || ref_type_ == ref_types::crref;
} }
inline any_type inst_base::get_raw_type() const noexcept {
return raw_type_;
}
inline inst_base::ref_types inst_base::get_ref_type() const noexcept { inline inst_base::ref_types inst_base::get_ref_type() const noexcept {
return ref_type_; return ref_type_;
} }
template < typename To > inline const class_type& inst_base::get_raw_type() const noexcept {
bool inst_base::can_cast_to() const noexcept { return raw_type_;
static_assert( }
std::is_class_v<To> ||
(std::is_reference_v<To> && std::is_class_v<std::remove_reference_t<To>>));
template < typename To, std::enable_if_t<
(std::is_class_v<To>) ||
(std::is_reference_v<To> && std::is_class_v<std::remove_reference_t<To>>)
, int> >
bool inst_base::can_cast_to() const noexcept {
constexpr bool to_const = std::is_const_v<std::remove_reference_t<To>>; constexpr bool to_const = std::is_const_v<std::remove_reference_t<To>>;
if constexpr ( !to_const ) { if constexpr ( !to_const ) {
@@ -92,13 +107,21 @@ namespace meta_hpp::detail
} }
using to_raw_type = std::remove_cvref_t<To>; using to_raw_type = std::remove_cvref_t<To>;
return get_raw_type() == resolve_type<to_raw_type>();
return get_raw_type() == resolve_type<to_raw_type>()
|| get_raw_type().is_derived_from(resolve_type<to_raw_type>());
} }
} }
namespace meta_hpp::detail namespace meta_hpp::detail
{ {
template < typename T, typename Tp template < typename T, typename Tp
, std::enable_if_t<std::is_same_v<Tp, value>, int> >
inst::inst(T&& v)
: inst_base{std::forward<T>(v)}
, data_{const_cast<void*>(v.data())} {}
template < typename T, class_kind Tp
, std::enable_if_t<!std::is_same_v<Tp, arg>, int> , std::enable_if_t<!std::is_same_v<Tp, arg>, int>
, std::enable_if_t<!std::is_same_v<Tp, inst>, int> , std::enable_if_t<!std::is_same_v<Tp, inst>, int>
, std::enable_if_t<!std::is_same_v<Tp, value>, int> > , std::enable_if_t<!std::is_same_v<Tp, value>, int> >
@@ -106,26 +129,13 @@ namespace meta_hpp::detail
: inst_base{type_list<T&&>{}} : inst_base{type_list<T&&>{}}
, data_{const_cast<std::remove_cvref_t<T>*>(std::addressof(v))} {} , data_{const_cast<std::remove_cvref_t<T>*>(std::addressof(v))} {}
inline inst::inst(value& v) template < typename To, std::enable_if_t<
: inst_base{v} (std::is_class_v<To>) ||
, data_{const_cast<void*>(v.data())} {} (std::is_reference_v<To> && std::is_class_v<std::remove_reference_t<To>>)
, int> >
inline inst::inst(value&& v)
: inst_base{v}
, data_{const_cast<void*>(v.data())} {}
inline inst::inst(const value& v)
: inst_base{v}
, data_{const_cast<void*>(v.data())} {}
inline inst::inst(const value&& v)
: inst_base{v}
, data_{const_cast<void*>(v.data())} {}
template < typename To >
decltype(auto) inst::cast() const { decltype(auto) inst::cast() const {
if ( !can_cast_to<To>() ) { if ( !can_cast_to<To>() ) {
throw std::logic_error("bad inst cast"); throw std::logic_error("bad an instance cast");
} }
if constexpr ( std::is_reference_v<To> ) { if constexpr ( std::is_reference_v<To> ) {

View File

@@ -58,12 +58,19 @@ namespace
int const_method_noexcept_rref_volatile() volatile const && noexcept { return 12; } int const_method_noexcept_rref_volatile() volatile const && noexcept { return 12; }
}; };
struct derived_clazz : clazz {
[[maybe_unused]] derived_clazz() = default;
};
struct clazz2 {}; struct clazz2 {};
} }
TEST_CASE("meta/meta_states/method") { TEST_CASE("meta/meta_states/method") {
namespace meta = meta_hpp; namespace meta = meta_hpp;
meta::class_<derived_clazz>()
.base_<clazz>();
meta::class_<clazz>() meta::class_<clazz>()
.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)
@@ -151,6 +158,16 @@ TEST_CASE("meta/meta_states/method") {
CHECK_FALSE(mi2.is_invocable_with<const clazz&>()); CHECK_FALSE(mi2.is_invocable_with<const clazz&>());
CHECK(mi2.is_invocable_with<clazz&&>()); CHECK(mi2.is_invocable_with<clazz&&>());
CHECK_FALSE(mi2.is_invocable_with<const clazz&&>()); CHECK_FALSE(mi2.is_invocable_with<const clazz&&>());
CHECK(mi.is_invocable_with<derived_clazz&>());
CHECK_FALSE(mi.is_invocable_with<const derived_clazz&>());
CHECK(mi.is_invocable_with<derived_clazz&&>());
CHECK_FALSE(mi.is_invocable_with<const derived_clazz&&>());
CHECK(mi2.is_invocable_with<derived_clazz&>());
CHECK_FALSE(mi2.is_invocable_with<const derived_clazz&>());
CHECK(mi2.is_invocable_with<derived_clazz&&>());
CHECK_FALSE(mi2.is_invocable_with<const derived_clazz&&>());
} }
{ {
@@ -176,6 +193,16 @@ TEST_CASE("meta/meta_states/method") {
static_assert(!std::is_invocable_v<decltype(&clazz::non_const_method_volatile), const clazz&>); static_assert(!std::is_invocable_v<decltype(&clazz::non_const_method_volatile), const clazz&>);
static_assert(std::is_invocable_v<decltype(&clazz::non_const_method_volatile), clazz&&>); static_assert(std::is_invocable_v<decltype(&clazz::non_const_method_volatile), clazz&&>);
static_assert(!std::is_invocable_v<decltype(&clazz::non_const_method_volatile), const clazz&&>); static_assert(!std::is_invocable_v<decltype(&clazz::non_const_method_volatile), const clazz&&>);
static_assert(std::is_invocable_v<decltype(&clazz::non_const_method), derived_clazz&>);
static_assert(!std::is_invocable_v<decltype(&clazz::non_const_method), const derived_clazz&>);
static_assert(std::is_invocable_v<decltype(&clazz::non_const_method), derived_clazz&&>);
static_assert(!std::is_invocable_v<decltype(&clazz::non_const_method), const derived_clazz&&>);
static_assert(std::is_invocable_v<decltype(&clazz::non_const_method_volatile), derived_clazz&>);
static_assert(!std::is_invocable_v<decltype(&clazz::non_const_method_volatile), const derived_clazz&>);
static_assert(std::is_invocable_v<decltype(&clazz::non_const_method_volatile), derived_clazz&&>);
static_assert(!std::is_invocable_v<decltype(&clazz::non_const_method_volatile), const derived_clazz&&>);
} }
SUBCASE("non_const_method_noexcept") { SUBCASE("non_const_method_noexcept") {
@@ -210,6 +237,16 @@ TEST_CASE("meta/meta_states/method") {
CHECK_FALSE(mi2.is_invocable_with<const clazz&>()); CHECK_FALSE(mi2.is_invocable_with<const clazz&>());
CHECK(mi2.is_invocable_with<clazz&&>()); CHECK(mi2.is_invocable_with<clazz&&>());
CHECK_FALSE(mi2.is_invocable_with<const clazz&&>()); CHECK_FALSE(mi2.is_invocable_with<const clazz&&>());
CHECK(mi.is_invocable_with<derived_clazz&>());
CHECK_FALSE(mi.is_invocable_with<const derived_clazz&>());
CHECK(mi.is_invocable_with<derived_clazz&&>());
CHECK_FALSE(mi.is_invocable_with<const derived_clazz&&>());
CHECK(mi2.is_invocable_with<derived_clazz&>());
CHECK_FALSE(mi2.is_invocable_with<const derived_clazz&>());
CHECK(mi2.is_invocable_with<derived_clazz&&>());
CHECK_FALSE(mi2.is_invocable_with<const derived_clazz&&>());
} }
{ {
@@ -235,6 +272,16 @@ TEST_CASE("meta/meta_states/method") {
static_assert(!std::is_invocable_v<decltype(&clazz::non_const_method_noexcept_volatile), const clazz&>); static_assert(!std::is_invocable_v<decltype(&clazz::non_const_method_noexcept_volatile), const clazz&>);
static_assert(std::is_invocable_v<decltype(&clazz::non_const_method_noexcept_volatile), clazz&&>); static_assert(std::is_invocable_v<decltype(&clazz::non_const_method_noexcept_volatile), clazz&&>);
static_assert(!std::is_invocable_v<decltype(&clazz::non_const_method_noexcept_volatile), const clazz&&>); static_assert(!std::is_invocable_v<decltype(&clazz::non_const_method_noexcept_volatile), const clazz&&>);
static_assert(std::is_invocable_v<decltype(&clazz::non_const_method_noexcept), derived_clazz&>);
static_assert(!std::is_invocable_v<decltype(&clazz::non_const_method_noexcept), const derived_clazz&>);
static_assert(std::is_invocable_v<decltype(&clazz::non_const_method_noexcept), derived_clazz&&>);
static_assert(!std::is_invocable_v<decltype(&clazz::non_const_method_noexcept), const derived_clazz&&>);
static_assert(std::is_invocable_v<decltype(&clazz::non_const_method_noexcept_volatile), derived_clazz&>);
static_assert(!std::is_invocable_v<decltype(&clazz::non_const_method_noexcept_volatile), const derived_clazz&>);
static_assert(std::is_invocable_v<decltype(&clazz::non_const_method_noexcept_volatile), derived_clazz&&>);
static_assert(!std::is_invocable_v<decltype(&clazz::non_const_method_noexcept_volatile), const derived_clazz&&>);
} }
SUBCASE("const_method") { SUBCASE("const_method") {
@@ -269,6 +316,16 @@ TEST_CASE("meta/meta_states/method") {
CHECK(mi2.is_invocable_with<const clazz&>()); CHECK(mi2.is_invocable_with<const clazz&>());
CHECK(mi2.is_invocable_with<clazz&&>()); CHECK(mi2.is_invocable_with<clazz&&>());
CHECK(mi2.is_invocable_with<const clazz&&>()); CHECK(mi2.is_invocable_with<const clazz&&>());
CHECK(mi.is_invocable_with<derived_clazz&>());
CHECK(mi.is_invocable_with<const derived_clazz&>());
CHECK(mi.is_invocable_with<derived_clazz&&>());
CHECK(mi.is_invocable_with<const derived_clazz&&>());
CHECK(mi2.is_invocable_with<derived_clazz&>());
CHECK(mi2.is_invocable_with<const derived_clazz&>());
CHECK(mi2.is_invocable_with<derived_clazz&&>());
CHECK(mi2.is_invocable_with<const derived_clazz&&>());
} }
{ {
@@ -294,6 +351,16 @@ TEST_CASE("meta/meta_states/method") {
static_assert(std::is_invocable_v<decltype(&clazz::const_method_volatile), const clazz&>); static_assert(std::is_invocable_v<decltype(&clazz::const_method_volatile), const clazz&>);
static_assert(std::is_invocable_v<decltype(&clazz::const_method_volatile), clazz&&>); static_assert(std::is_invocable_v<decltype(&clazz::const_method_volatile), clazz&&>);
static_assert(std::is_invocable_v<decltype(&clazz::const_method_volatile), const clazz&&>); static_assert(std::is_invocable_v<decltype(&clazz::const_method_volatile), const clazz&&>);
static_assert(std::is_invocable_v<decltype(&clazz::const_method), derived_clazz&>);
static_assert(std::is_invocable_v<decltype(&clazz::const_method), const derived_clazz&>);
static_assert(std::is_invocable_v<decltype(&clazz::const_method), derived_clazz&&>);
static_assert(std::is_invocable_v<decltype(&clazz::const_method), const derived_clazz&&>);
static_assert(std::is_invocable_v<decltype(&clazz::const_method_volatile), derived_clazz&>);
static_assert(std::is_invocable_v<decltype(&clazz::const_method_volatile), const derived_clazz&>);
static_assert(std::is_invocable_v<decltype(&clazz::const_method_volatile), derived_clazz&&>);
static_assert(std::is_invocable_v<decltype(&clazz::const_method_volatile), const derived_clazz&&>);
} }
SUBCASE("const_method_noexcept") { SUBCASE("const_method_noexcept") {
@@ -328,6 +395,16 @@ TEST_CASE("meta/meta_states/method") {
CHECK(mi2.is_invocable_with<const clazz&>()); CHECK(mi2.is_invocable_with<const clazz&>());
CHECK(mi2.is_invocable_with<clazz&&>()); CHECK(mi2.is_invocable_with<clazz&&>());
CHECK(mi2.is_invocable_with<const clazz&&>()); CHECK(mi2.is_invocable_with<const clazz&&>());
CHECK(mi.is_invocable_with<derived_clazz&>());
CHECK(mi.is_invocable_with<const derived_clazz&>());
CHECK(mi.is_invocable_with<derived_clazz&&>());
CHECK(mi.is_invocable_with<const derived_clazz&&>());
CHECK(mi2.is_invocable_with<derived_clazz&>());
CHECK(mi2.is_invocable_with<const derived_clazz&>());
CHECK(mi2.is_invocable_with<derived_clazz&&>());
CHECK(mi2.is_invocable_with<const derived_clazz&&>());
} }
{ {
@@ -353,6 +430,16 @@ TEST_CASE("meta/meta_states/method") {
static_assert(std::is_invocable_v<decltype(&clazz::const_method_noexcept_volatile), const clazz&>); static_assert(std::is_invocable_v<decltype(&clazz::const_method_noexcept_volatile), const clazz&>);
static_assert(std::is_invocable_v<decltype(&clazz::const_method_noexcept_volatile), clazz&&>); static_assert(std::is_invocable_v<decltype(&clazz::const_method_noexcept_volatile), clazz&&>);
static_assert(std::is_invocable_v<decltype(&clazz::const_method_noexcept_volatile), const clazz&&>); static_assert(std::is_invocable_v<decltype(&clazz::const_method_noexcept_volatile), const clazz&&>);
static_assert(std::is_invocable_v<decltype(&clazz::const_method_noexcept), derived_clazz&>);
static_assert(std::is_invocable_v<decltype(&clazz::const_method_noexcept), const derived_clazz&>);
static_assert(std::is_invocable_v<decltype(&clazz::const_method_noexcept), derived_clazz&&>);
static_assert(std::is_invocable_v<decltype(&clazz::const_method_noexcept), const derived_clazz&&>);
static_assert(std::is_invocable_v<decltype(&clazz::const_method_noexcept_volatile), derived_clazz&>);
static_assert(std::is_invocable_v<decltype(&clazz::const_method_noexcept_volatile), const derived_clazz&>);
static_assert(std::is_invocable_v<decltype(&clazz::const_method_noexcept_volatile), derived_clazz&&>);
static_assert(std::is_invocable_v<decltype(&clazz::const_method_noexcept_volatile), const derived_clazz&&>);
} }
SUBCASE("non_const_method_ref") { SUBCASE("non_const_method_ref") {
@@ -387,6 +474,16 @@ TEST_CASE("meta/meta_states/method") {
CHECK_FALSE(mi2.is_invocable_with<const clazz&>()); CHECK_FALSE(mi2.is_invocable_with<const clazz&>());
CHECK_FALSE(mi2.is_invocable_with<clazz&&>()); CHECK_FALSE(mi2.is_invocable_with<clazz&&>());
CHECK_FALSE(mi2.is_invocable_with<const clazz&&>()); CHECK_FALSE(mi2.is_invocable_with<const clazz&&>());
CHECK(mi.is_invocable_with<derived_clazz&>());
CHECK_FALSE(mi.is_invocable_with<const derived_clazz&>());
CHECK_FALSE(mi.is_invocable_with<derived_clazz&&>());
CHECK_FALSE(mi.is_invocable_with<const derived_clazz&&>());
CHECK(mi2.is_invocable_with<derived_clazz&>());
CHECK_FALSE(mi2.is_invocable_with<const derived_clazz&>());
CHECK_FALSE(mi2.is_invocable_with<derived_clazz&&>());
CHECK_FALSE(mi2.is_invocable_with<const derived_clazz&&>());
} }
{ {
@@ -412,6 +509,16 @@ TEST_CASE("meta/meta_states/method") {
static_assert(!std::is_invocable_v<decltype(&clazz::non_const_method_ref_volatile), const clazz&>); static_assert(!std::is_invocable_v<decltype(&clazz::non_const_method_ref_volatile), const clazz&>);
static_assert(!std::is_invocable_v<decltype(&clazz::non_const_method_ref_volatile), clazz&&>); static_assert(!std::is_invocable_v<decltype(&clazz::non_const_method_ref_volatile), clazz&&>);
static_assert(!std::is_invocable_v<decltype(&clazz::non_const_method_ref_volatile), const clazz&&>); static_assert(!std::is_invocable_v<decltype(&clazz::non_const_method_ref_volatile), const clazz&&>);
static_assert(std::is_invocable_v<decltype(&clazz::non_const_method_ref), derived_clazz&>);
static_assert(!std::is_invocable_v<decltype(&clazz::non_const_method_ref), const derived_clazz&>);
static_assert(!std::is_invocable_v<decltype(&clazz::non_const_method_ref), derived_clazz&&>);
static_assert(!std::is_invocable_v<decltype(&clazz::non_const_method_ref), const derived_clazz&&>);
static_assert(std::is_invocable_v<decltype(&clazz::non_const_method_ref_volatile), derived_clazz&>);
static_assert(!std::is_invocable_v<decltype(&clazz::non_const_method_ref_volatile), const derived_clazz&>);
static_assert(!std::is_invocable_v<decltype(&clazz::non_const_method_ref_volatile), derived_clazz&&>);
static_assert(!std::is_invocable_v<decltype(&clazz::non_const_method_ref_volatile), const derived_clazz&&>);
} }
SUBCASE("non_const_method_noexcept_ref") { SUBCASE("non_const_method_noexcept_ref") {
@@ -446,6 +553,16 @@ TEST_CASE("meta/meta_states/method") {
CHECK_FALSE(mi2.is_invocable_with<const clazz&>()); CHECK_FALSE(mi2.is_invocable_with<const clazz&>());
CHECK_FALSE(mi2.is_invocable_with<clazz&&>()); CHECK_FALSE(mi2.is_invocable_with<clazz&&>());
CHECK_FALSE(mi2.is_invocable_with<const clazz&&>()); CHECK_FALSE(mi2.is_invocable_with<const clazz&&>());
CHECK(mi.is_invocable_with<derived_clazz&>());
CHECK_FALSE(mi.is_invocable_with<const derived_clazz&>());
CHECK_FALSE(mi.is_invocable_with<derived_clazz&&>());
CHECK_FALSE(mi.is_invocable_with<const derived_clazz&&>());
CHECK(mi2.is_invocable_with<derived_clazz&>());
CHECK_FALSE(mi2.is_invocable_with<const derived_clazz&>());
CHECK_FALSE(mi2.is_invocable_with<derived_clazz&&>());
CHECK_FALSE(mi2.is_invocable_with<const derived_clazz&&>());
} }
{ {
@@ -471,6 +588,16 @@ TEST_CASE("meta/meta_states/method") {
static_assert(!std::is_invocable_v<decltype(&clazz::non_const_method_noexcept_ref_volatile), const clazz&>); static_assert(!std::is_invocable_v<decltype(&clazz::non_const_method_noexcept_ref_volatile), const clazz&>);
static_assert(!std::is_invocable_v<decltype(&clazz::non_const_method_noexcept_ref_volatile), clazz&&>); static_assert(!std::is_invocable_v<decltype(&clazz::non_const_method_noexcept_ref_volatile), clazz&&>);
static_assert(!std::is_invocable_v<decltype(&clazz::non_const_method_noexcept_ref_volatile), const clazz&&>); static_assert(!std::is_invocable_v<decltype(&clazz::non_const_method_noexcept_ref_volatile), const clazz&&>);
static_assert(std::is_invocable_v<decltype(&clazz::non_const_method_noexcept_ref), derived_clazz&>);
static_assert(!std::is_invocable_v<decltype(&clazz::non_const_method_noexcept_ref), const derived_clazz&>);
static_assert(!std::is_invocable_v<decltype(&clazz::non_const_method_noexcept_ref), derived_clazz&&>);
static_assert(!std::is_invocable_v<decltype(&clazz::non_const_method_noexcept_ref), const derived_clazz&&>);
static_assert(std::is_invocable_v<decltype(&clazz::non_const_method_noexcept_ref_volatile), derived_clazz&>);
static_assert(!std::is_invocable_v<decltype(&clazz::non_const_method_noexcept_ref_volatile), const derived_clazz&>);
static_assert(!std::is_invocable_v<decltype(&clazz::non_const_method_noexcept_ref_volatile), derived_clazz&&>);
static_assert(!std::is_invocable_v<decltype(&clazz::non_const_method_noexcept_ref_volatile), const derived_clazz&&>);
} }
SUBCASE("const_method_ref") { SUBCASE("const_method_ref") {
@@ -505,6 +632,16 @@ TEST_CASE("meta/meta_states/method") {
CHECK(mi2.is_invocable_with<const clazz&>()); CHECK(mi2.is_invocable_with<const clazz&>());
CHECK_FALSE(mi2.is_invocable_with<clazz&&>()); CHECK_FALSE(mi2.is_invocable_with<clazz&&>());
CHECK_FALSE(mi2.is_invocable_with<const clazz&&>()); CHECK_FALSE(mi2.is_invocable_with<const clazz&&>());
CHECK(mi.is_invocable_with<derived_clazz&>());
CHECK(mi.is_invocable_with<const derived_clazz&>());
CHECK_FALSE(mi.is_invocable_with<derived_clazz&&>());
CHECK_FALSE(mi.is_invocable_with<const derived_clazz&&>());
CHECK(mi2.is_invocable_with<derived_clazz&>());
CHECK(mi2.is_invocable_with<const derived_clazz&>());
CHECK_FALSE(mi2.is_invocable_with<derived_clazz&&>());
CHECK_FALSE(mi2.is_invocable_with<const derived_clazz&&>());
} }
{ {
@@ -530,6 +667,16 @@ TEST_CASE("meta/meta_states/method") {
static_assert(std::is_invocable_v<decltype(&clazz::const_method_ref_volatile), const clazz&>); static_assert(std::is_invocable_v<decltype(&clazz::const_method_ref_volatile), const clazz&>);
static_assert(!std::is_invocable_v<decltype(&clazz::const_method_ref_volatile), clazz&&>); static_assert(!std::is_invocable_v<decltype(&clazz::const_method_ref_volatile), clazz&&>);
static_assert(!std::is_invocable_v<decltype(&clazz::const_method_ref_volatile), const clazz&&>); static_assert(!std::is_invocable_v<decltype(&clazz::const_method_ref_volatile), const clazz&&>);
static_assert(std::is_invocable_v<decltype(&clazz::const_method_ref), derived_clazz&>);
static_assert(std::is_invocable_v<decltype(&clazz::const_method_ref), const derived_clazz&>);
//static_assert(!std::is_invocable_v<decltype(&clazz::const_method_ref), derived_clazz&&>); // msvc issue
//static_assert(!std::is_invocable_v<decltype(&clazz::const_method_ref), const derived_clazz&&>); // msvc issue
static_assert(std::is_invocable_v<decltype(&clazz::const_method_ref_volatile), derived_clazz&>);
static_assert(std::is_invocable_v<decltype(&clazz::const_method_ref_volatile), const derived_clazz&>);
static_assert(!std::is_invocable_v<decltype(&clazz::const_method_ref_volatile), derived_clazz&&>);
static_assert(!std::is_invocable_v<decltype(&clazz::const_method_ref_volatile), const derived_clazz&&>);
} }
SUBCASE("const_method_noexcept_ref") { SUBCASE("const_method_noexcept_ref") {
@@ -564,6 +711,16 @@ TEST_CASE("meta/meta_states/method") {
CHECK(mi2.is_invocable_with<const clazz&>()); CHECK(mi2.is_invocable_with<const clazz&>());
CHECK_FALSE(mi2.is_invocable_with<clazz&&>()); CHECK_FALSE(mi2.is_invocable_with<clazz&&>());
CHECK_FALSE(mi2.is_invocable_with<const clazz&&>()); CHECK_FALSE(mi2.is_invocable_with<const clazz&&>());
CHECK(mi.is_invocable_with<derived_clazz&>());
CHECK(mi.is_invocable_with<const derived_clazz&>());
CHECK_FALSE(mi.is_invocable_with<derived_clazz&&>());
CHECK_FALSE(mi.is_invocable_with<const derived_clazz&&>());
CHECK(mi2.is_invocable_with<derived_clazz&>());
CHECK(mi2.is_invocable_with<const derived_clazz&>());
CHECK_FALSE(mi2.is_invocable_with<derived_clazz&&>());
CHECK_FALSE(mi2.is_invocable_with<const derived_clazz&&>());
} }
{ {
@@ -589,6 +746,16 @@ TEST_CASE("meta/meta_states/method") {
static_assert(std::is_invocable_v<decltype(&clazz::const_method_noexcept_ref_volatile), const clazz&>); static_assert(std::is_invocable_v<decltype(&clazz::const_method_noexcept_ref_volatile), const clazz&>);
static_assert(!std::is_invocable_v<decltype(&clazz::const_method_noexcept_ref_volatile), clazz&&>); static_assert(!std::is_invocable_v<decltype(&clazz::const_method_noexcept_ref_volatile), clazz&&>);
static_assert(!std::is_invocable_v<decltype(&clazz::const_method_noexcept_ref_volatile), const clazz&&>); static_assert(!std::is_invocable_v<decltype(&clazz::const_method_noexcept_ref_volatile), const clazz&&>);
static_assert(std::is_invocable_v<decltype(&clazz::const_method_noexcept_ref), derived_clazz&>);
static_assert(std::is_invocable_v<decltype(&clazz::const_method_noexcept_ref), const derived_clazz&>);
//static_assert(!std::is_invocable_v<decltype(&clazz::const_method_noexcept_ref), derived_clazz&&>); // msvc issue
//static_assert(!std::is_invocable_v<decltype(&clazz::const_method_noexcept_ref), const derived_clazz&&>); // msvc issue
static_assert(std::is_invocable_v<decltype(&clazz::const_method_noexcept_ref_volatile), derived_clazz&>);
static_assert(std::is_invocable_v<decltype(&clazz::const_method_noexcept_ref_volatile), const derived_clazz&>);
static_assert(!std::is_invocable_v<decltype(&clazz::const_method_noexcept_ref_volatile), derived_clazz&&>);
static_assert(!std::is_invocable_v<decltype(&clazz::const_method_noexcept_ref_volatile), const derived_clazz&&>);
} }
SUBCASE("non_const_method_rref") { SUBCASE("non_const_method_rref") {
@@ -623,6 +790,16 @@ TEST_CASE("meta/meta_states/method") {
CHECK_FALSE(mi2.is_invocable_with<const clazz&>()); CHECK_FALSE(mi2.is_invocable_with<const clazz&>());
CHECK(mi2.is_invocable_with<clazz&&>()); CHECK(mi2.is_invocable_with<clazz&&>());
CHECK_FALSE(mi2.is_invocable_with<const clazz&&>()); CHECK_FALSE(mi2.is_invocable_with<const clazz&&>());
CHECK_FALSE(mi.is_invocable_with<derived_clazz&>());
CHECK_FALSE(mi.is_invocable_with<const derived_clazz&>());
CHECK(mi.is_invocable_with<derived_clazz&&>());
CHECK_FALSE(mi.is_invocable_with<const derived_clazz&&>());
CHECK_FALSE(mi2.is_invocable_with<derived_clazz&>());
CHECK_FALSE(mi2.is_invocable_with<const derived_clazz&>());
CHECK(mi2.is_invocable_with<derived_clazz&&>());
CHECK_FALSE(mi2.is_invocable_with<const derived_clazz&&>());
} }
{ {
@@ -648,6 +825,16 @@ TEST_CASE("meta/meta_states/method") {
static_assert(!std::is_invocable_v<decltype(&clazz::non_const_method_rref_volatile), const clazz&>); static_assert(!std::is_invocable_v<decltype(&clazz::non_const_method_rref_volatile), const clazz&>);
static_assert(std::is_invocable_v<decltype(&clazz::non_const_method_rref_volatile), clazz&&>); static_assert(std::is_invocable_v<decltype(&clazz::non_const_method_rref_volatile), clazz&&>);
static_assert(!std::is_invocable_v<decltype(&clazz::non_const_method_rref_volatile), const clazz&&>); static_assert(!std::is_invocable_v<decltype(&clazz::non_const_method_rref_volatile), const clazz&&>);
static_assert(!std::is_invocable_v<decltype(&clazz::non_const_method_rref), derived_clazz&>);
static_assert(!std::is_invocable_v<decltype(&clazz::non_const_method_rref), const derived_clazz&>);
static_assert(std::is_invocable_v<decltype(&clazz::non_const_method_rref), derived_clazz&&>);
static_assert(!std::is_invocable_v<decltype(&clazz::non_const_method_rref), const derived_clazz&&>);
static_assert(!std::is_invocable_v<decltype(&clazz::non_const_method_rref_volatile), derived_clazz&>);
static_assert(!std::is_invocable_v<decltype(&clazz::non_const_method_rref_volatile), const derived_clazz&>);
static_assert(std::is_invocable_v<decltype(&clazz::non_const_method_rref_volatile), derived_clazz&&>);
static_assert(!std::is_invocable_v<decltype(&clazz::non_const_method_rref_volatile), const derived_clazz&&>);
} }
SUBCASE("non_const_method_noexcept_rref") { SUBCASE("non_const_method_noexcept_rref") {
@@ -682,6 +869,16 @@ TEST_CASE("meta/meta_states/method") {
CHECK_FALSE(mi2.is_invocable_with<const clazz&>()); CHECK_FALSE(mi2.is_invocable_with<const clazz&>());
CHECK(mi2.is_invocable_with<clazz&&>()); CHECK(mi2.is_invocable_with<clazz&&>());
CHECK_FALSE(mi2.is_invocable_with<const clazz&&>()); CHECK_FALSE(mi2.is_invocable_with<const clazz&&>());
CHECK_FALSE(mi.is_invocable_with<derived_clazz&>());
CHECK_FALSE(mi.is_invocable_with<const derived_clazz&>());
CHECK(mi.is_invocable_with<derived_clazz&&>());
CHECK_FALSE(mi.is_invocable_with<const derived_clazz&&>());
CHECK_FALSE(mi2.is_invocable_with<derived_clazz&>());
CHECK_FALSE(mi2.is_invocable_with<const derived_clazz&>());
CHECK(mi2.is_invocable_with<derived_clazz&&>());
CHECK_FALSE(mi2.is_invocable_with<const derived_clazz&&>());
} }
{ {
@@ -707,6 +904,16 @@ TEST_CASE("meta/meta_states/method") {
static_assert(!std::is_invocable_v<decltype(&clazz::non_const_method_noexcept_rref_volatile), const clazz&>); static_assert(!std::is_invocable_v<decltype(&clazz::non_const_method_noexcept_rref_volatile), const clazz&>);
static_assert(std::is_invocable_v<decltype(&clazz::non_const_method_noexcept_rref_volatile), clazz&&>); static_assert(std::is_invocable_v<decltype(&clazz::non_const_method_noexcept_rref_volatile), clazz&&>);
static_assert(!std::is_invocable_v<decltype(&clazz::non_const_method_noexcept_rref_volatile), const clazz&&>); static_assert(!std::is_invocable_v<decltype(&clazz::non_const_method_noexcept_rref_volatile), const clazz&&>);
static_assert(!std::is_invocable_v<decltype(&clazz::non_const_method_noexcept_rref), derived_clazz&>);
static_assert(!std::is_invocable_v<decltype(&clazz::non_const_method_noexcept_rref), const derived_clazz&>);
static_assert(std::is_invocable_v<decltype(&clazz::non_const_method_noexcept_rref), derived_clazz&&>);
static_assert(!std::is_invocable_v<decltype(&clazz::non_const_method_noexcept_rref), const derived_clazz&&>);
static_assert(!std::is_invocable_v<decltype(&clazz::non_const_method_noexcept_rref_volatile), derived_clazz&>);
static_assert(!std::is_invocable_v<decltype(&clazz::non_const_method_noexcept_rref_volatile), const derived_clazz&>);
static_assert(std::is_invocable_v<decltype(&clazz::non_const_method_noexcept_rref_volatile), derived_clazz&&>);
static_assert(!std::is_invocable_v<decltype(&clazz::non_const_method_noexcept_rref_volatile), const derived_clazz&&>);
} }
SUBCASE("const_method_rref") { SUBCASE("const_method_rref") {
@@ -741,6 +948,16 @@ TEST_CASE("meta/meta_states/method") {
CHECK_FALSE(mi2.is_invocable_with<const clazz&>()); CHECK_FALSE(mi2.is_invocable_with<const clazz&>());
CHECK(mi2.is_invocable_with<clazz&&>()); CHECK(mi2.is_invocable_with<clazz&&>());
CHECK(mi2.is_invocable_with<const clazz&&>()); CHECK(mi2.is_invocable_with<const clazz&&>());
CHECK_FALSE(mi.is_invocable_with<derived_clazz&>());
CHECK_FALSE(mi.is_invocable_with<const derived_clazz&>());
CHECK(mi.is_invocable_with<derived_clazz&&>());
CHECK(mi.is_invocable_with<const derived_clazz&&>());
CHECK_FALSE(mi2.is_invocable_with<derived_clazz&>());
CHECK_FALSE(mi2.is_invocable_with<const derived_clazz&>());
CHECK(mi2.is_invocable_with<derived_clazz&&>());
CHECK(mi2.is_invocable_with<const derived_clazz&&>());
} }
{ {
@@ -766,6 +983,16 @@ TEST_CASE("meta/meta_states/method") {
static_assert(!std::is_invocable_v<decltype(&clazz::const_method_rref_volatile), const clazz&>); static_assert(!std::is_invocable_v<decltype(&clazz::const_method_rref_volatile), const clazz&>);
static_assert(std::is_invocable_v<decltype(&clazz::const_method_rref_volatile), clazz&&>); static_assert(std::is_invocable_v<decltype(&clazz::const_method_rref_volatile), clazz&&>);
static_assert(std::is_invocable_v<decltype(&clazz::const_method_rref_volatile), const clazz&&>); static_assert(std::is_invocable_v<decltype(&clazz::const_method_rref_volatile), const clazz&&>);
static_assert(!std::is_invocable_v<decltype(&clazz::const_method_rref), derived_clazz&>);
static_assert(!std::is_invocable_v<decltype(&clazz::const_method_rref), const derived_clazz&>);
static_assert(std::is_invocable_v<decltype(&clazz::const_method_rref), derived_clazz&&>);
static_assert(std::is_invocable_v<decltype(&clazz::const_method_rref), const derived_clazz&&>);
static_assert(!std::is_invocable_v<decltype(&clazz::const_method_rref_volatile), derived_clazz&>);
static_assert(!std::is_invocable_v<decltype(&clazz::const_method_rref_volatile), const derived_clazz&>);
static_assert(std::is_invocable_v<decltype(&clazz::const_method_rref_volatile), derived_clazz&&>);
static_assert(std::is_invocable_v<decltype(&clazz::const_method_rref_volatile), const derived_clazz&&>);
} }
SUBCASE("const_method_noexcept_rref") { SUBCASE("const_method_noexcept_rref") {
@@ -800,6 +1027,16 @@ TEST_CASE("meta/meta_states/method") {
CHECK_FALSE(mi2.is_invocable_with<const clazz&>()); CHECK_FALSE(mi2.is_invocable_with<const clazz&>());
CHECK(mi2.is_invocable_with<clazz&&>()); CHECK(mi2.is_invocable_with<clazz&&>());
CHECK(mi2.is_invocable_with<const clazz&&>()); CHECK(mi2.is_invocable_with<const clazz&&>());
CHECK_FALSE(mi.is_invocable_with<derived_clazz&>());
CHECK_FALSE(mi.is_invocable_with<const derived_clazz&>());
CHECK(mi.is_invocable_with<derived_clazz&&>());
CHECK(mi.is_invocable_with<const derived_clazz&&>());
CHECK_FALSE(mi2.is_invocable_with<derived_clazz&>());
CHECK_FALSE(mi2.is_invocable_with<const derived_clazz&>());
CHECK(mi2.is_invocable_with<derived_clazz&&>());
CHECK(mi2.is_invocable_with<const derived_clazz&&>());
} }
{ {
@@ -825,5 +1062,15 @@ TEST_CASE("meta/meta_states/method") {
static_assert(!std::is_invocable_v<decltype(&clazz::const_method_noexcept_rref_volatile), const clazz&>); static_assert(!std::is_invocable_v<decltype(&clazz::const_method_noexcept_rref_volatile), const clazz&>);
static_assert(std::is_invocable_v<decltype(&clazz::const_method_noexcept_rref_volatile), clazz&&>); static_assert(std::is_invocable_v<decltype(&clazz::const_method_noexcept_rref_volatile), clazz&&>);
static_assert(std::is_invocable_v<decltype(&clazz::const_method_noexcept_rref_volatile), const clazz&&>); static_assert(std::is_invocable_v<decltype(&clazz::const_method_noexcept_rref_volatile), const 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), 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_volatile), derived_clazz&>);
static_assert(!std::is_invocable_v<decltype(&clazz::const_method_noexcept_rref_volatile), const derived_clazz&>);
static_assert(std::is_invocable_v<decltype(&clazz::const_method_noexcept_rref_volatile), derived_clazz&&>);
static_assert(std::is_invocable_v<decltype(&clazz::const_method_noexcept_rref_volatile), const derived_clazz&&>);
} }
} }

View File

@@ -69,6 +69,128 @@ namespace
} }
} }
TEST_CASE("features/meta_utilities/arg/from_value") {
namespace meta = meta_hpp;
SUBCASE("ptr") {
ivec2 v{1,2};
ivec2* vp = &v;
meta::value vvp{vp};
meta::detail::arg a{vvp};
CHECK(a.get_raw_type() == meta::resolve_type<ivec2*>());
CHECK(a.get_ref_type() == meta::detail::arg::ref_types::ref);
}
SUBCASE("rptr") {
ivec2 v{1,2};
ivec2* vp = &v;
meta::value vvp{vp};
meta::detail::arg a{std::move(vvp)};
CHECK(a.get_raw_type() == meta::resolve_type<ivec2*>());
CHECK(a.get_ref_type() == meta::detail::arg::ref_types::rref);
}
SUBCASE("ptr_c") {
ivec2 v{1,2};
ivec2* const vp = &v;
const meta::value vvp{vp};
meta::detail::arg a{vvp};
CHECK(a.get_raw_type() == meta::resolve_type<ivec2*>());
CHECK(a.get_ref_type() == meta::detail::arg::ref_types::cref);
}
SUBCASE("rptr_c") {
ivec2 v{1,2};
ivec2* const vp = &v;
const meta::value vvp{vp};
meta::detail::arg a{std::move(vvp)};
CHECK(a.get_raw_type() == meta::resolve_type<ivec2*>());
CHECK(a.get_ref_type() == meta::detail::arg::ref_types::crref);
}
SUBCASE("cptr") {
const ivec2 v{1,2};
const ivec2* vp = &v;
meta::value vvp{vp};
meta::detail::arg a{vvp};
CHECK(a.get_raw_type() == meta::resolve_type<const ivec2*>());
CHECK(a.get_ref_type() == meta::detail::arg::ref_types::ref);
}
SUBCASE("crptr") {
const ivec2 v{1,2};
const ivec2* vp = &v;
meta::value vvp{vp};
meta::detail::arg a{std::move(vvp)};
CHECK(a.get_raw_type() == meta::resolve_type<const ivec2*>());
CHECK(a.get_ref_type() == meta::detail::arg::ref_types::rref);
}
SUBCASE("cptr_c") {
const ivec2 v{1,2};
const ivec2* const vp = &v;
const meta::value vvp{vp};
meta::detail::arg a{vvp};
CHECK(a.get_raw_type() == meta::resolve_type<const ivec2*>());
CHECK(a.get_ref_type() == meta::detail::arg::ref_types::cref);
}
SUBCASE("crptr_c") {
const ivec2 v{1,2};
const ivec2* const vp = &v;
const meta::value vvp{vp};
meta::detail::arg a{std::move(vvp)};
CHECK(a.get_raw_type() == meta::resolve_type<const ivec2*>());
CHECK(a.get_ref_type() == meta::detail::arg::ref_types::crref);
}
SUBCASE("ref") {
ivec2 v{1,2};
ivec2& vr = v;
meta::value vvr{vr};
meta::detail::arg a{vvr};
CHECK(a.get_raw_type() == meta::resolve_type<ivec2>());
CHECK(a.get_ref_type() == meta::detail::arg::ref_types::ref);
}
SUBCASE("cref") {
const ivec2 v{1,2};
const ivec2& vr = v;
const meta::value vvr{vr};
meta::detail::arg a{vvr};
CHECK(a.get_raw_type() == meta::resolve_type<ivec2>());
CHECK(a.get_ref_type() == meta::detail::arg::ref_types::cref);
}
SUBCASE("rref") {
ivec2 v{1,2};
meta::value vv{v};
meta::detail::arg a{std::move(vv)};
CHECK(a.get_raw_type() == meta::resolve_type<ivec2>());
CHECK(a.get_ref_type() == meta::detail::arg::ref_types::rref);
}
SUBCASE("crref") {
const ivec2 v{1,2};
const meta::value vv{v};
meta::detail::arg a{std::move(vv)};
CHECK(a.get_raw_type() == meta::resolve_type<ivec2>());
CHECK(a.get_ref_type() == meta::detail::arg::ref_types::crref);
}
}
TEST_CASE("features/meta_utilities/arg/type") { TEST_CASE("features/meta_utilities/arg/type") {
namespace meta = meta_hpp; namespace meta = meta_hpp;

View File

@@ -31,42 +31,110 @@ namespace
ivec2& operator=(ivec2&&) = delete; ivec2& operator=(ivec2&&) = delete;
ivec2& operator=(const ivec2&) = delete; ivec2& operator=(const ivec2&) = delete;
}; };
struct derived_ivec2 : ivec2 {
[[maybe_unused]] derived_ivec2() = default;
[[maybe_unused]] explicit derived_ivec2(int v): ivec2{v, v} {}
[[maybe_unused]] derived_ivec2(int x, int y): ivec2{x, y} {}
};
} }
TEST_CASE("features/meta_utilities/inst") { TEST_CASE("features/meta_utilities/inst") {
namespace meta = meta_hpp; namespace meta = meta_hpp;
SUBCASE("ref") { SUBCASE("ref") {
ivec2 v{1,2}; {
ivec2& vr = v; derived_ivec2 v{1,2};
meta::detail::inst a{vr}; derived_ivec2& vr = v;
meta::detail::inst a{vr};
CHECK(a.get_raw_type() == meta::resolve_type<ivec2>()); CHECK(a.get_raw_type() == meta::resolve_type<derived_ivec2>());
CHECK(a.get_ref_type() == meta::detail::inst::ref_types::ref); CHECK(a.get_ref_type() == meta::detail::inst::ref_types::ref);
}
{
meta::value v{derived_ivec2{1,2}};
meta::value& vr = v;
meta::detail::inst a{vr};
CHECK(a.get_raw_type() == meta::resolve_type<derived_ivec2>());
CHECK(a.get_ref_type() == meta::detail::inst::ref_types::ref);
CHECK(a.can_cast_to<derived_ivec2>());
CHECK(a.can_cast_to<derived_ivec2&>());
CHECK(a.can_cast_to<const derived_ivec2&>());
CHECK_FALSE(a.can_cast_to<derived_ivec2&&>());
CHECK_FALSE(a.can_cast_to<const derived_ivec2&&>());
}
} }
SUBCASE("cref") { SUBCASE("cref") {
const ivec2 v{1,2}; {
const ivec2& vr = v; const derived_ivec2 v{1,2};
meta::detail::inst a{vr}; const derived_ivec2& vr = v;
meta::detail::inst a{vr};
CHECK(a.get_raw_type() == meta::resolve_type<ivec2>()); CHECK(a.get_raw_type() == meta::resolve_type<derived_ivec2>());
CHECK(a.get_ref_type() == meta::detail::inst::ref_types::cref); CHECK(a.get_ref_type() == meta::detail::inst::ref_types::cref);
}
{
const meta::value v{derived_ivec2{1,2}};
const meta::value& vr = v;
meta::detail::inst a{vr};
CHECK(a.get_raw_type() == meta::resolve_type<derived_ivec2>());
CHECK(a.get_ref_type() == meta::detail::inst::ref_types::cref);
CHECK_FALSE(a.can_cast_to<derived_ivec2>());
CHECK_FALSE(a.can_cast_to<derived_ivec2&>());
CHECK(a.can_cast_to<const derived_ivec2&>());
CHECK_FALSE(a.can_cast_to<derived_ivec2&&>());
CHECK_FALSE(a.can_cast_to<const derived_ivec2&&>());
}
} }
SUBCASE("rref") { SUBCASE("rref") {
ivec2 v{1,2}; {
meta::detail::inst a{std::move(v)}; derived_ivec2 v{1,2};
meta::detail::inst a{std::move(v)};
CHECK(a.get_raw_type() == meta::resolve_type<ivec2>()); CHECK(a.get_raw_type() == meta::resolve_type<derived_ivec2>());
CHECK(a.get_ref_type() == meta::detail::inst::ref_types::rref); CHECK(a.get_ref_type() == meta::detail::inst::ref_types::rref);
}
{
meta::value v{derived_ivec2{1,2}};
meta::detail::inst a{std::move(v)};
CHECK(a.get_raw_type() == meta::resolve_type<derived_ivec2>());
CHECK(a.get_ref_type() == meta::detail::inst::ref_types::rref);
CHECK(a.can_cast_to<derived_ivec2>());
CHECK_FALSE(a.can_cast_to<derived_ivec2&>());
CHECK_FALSE(a.can_cast_to<const derived_ivec2&>());
CHECK(a.can_cast_to<derived_ivec2&&>());
CHECK(a.can_cast_to<const derived_ivec2&&>());
}
} }
SUBCASE("crref") { SUBCASE("crref") {
const ivec2 v{1,2}; {
meta::detail::inst a{std::move(v)}; const derived_ivec2 v{1,2};
meta::detail::inst a{std::move(v)};
CHECK(a.get_raw_type() == meta::resolve_type<ivec2>()); CHECK(a.get_raw_type() == meta::resolve_type<derived_ivec2>());
CHECK(a.get_ref_type() == meta::detail::inst::ref_types::crref); CHECK(a.get_ref_type() == meta::detail::inst::ref_types::crref);
}
{
const meta::value v{derived_ivec2{1,2}};
meta::detail::inst a{std::move(v)};
CHECK(a.get_raw_type() == meta::resolve_type<derived_ivec2>());
CHECK(a.get_ref_type() == meta::detail::inst::ref_types::crref);
CHECK_FALSE(a.can_cast_to<derived_ivec2>());
CHECK_FALSE(a.can_cast_to<derived_ivec2&>());
CHECK_FALSE(a.can_cast_to<const derived_ivec2&>());
CHECK_FALSE(a.can_cast_to<derived_ivec2&&>());
CHECK(a.can_cast_to<const derived_ivec2&&>());
}
} }
} }