new arg ind inst tests

This commit is contained in:
BlackMATov
2022-01-07 18:28:36 +07:00
parent 4ec160d292
commit 856ffc8cdc
6 changed files with 1298 additions and 89 deletions

View File

@@ -0,0 +1,318 @@
/*******************************************************************************
* 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_tests.hpp"
namespace
{
struct A {
A() = default;
A(A&&) = default;
A(const A&) = default;
A& operator=(A&&) = delete;
A& operator=(const A&) = delete;
virtual ~A() = default;
};
struct B : virtual A {};
struct C : virtual A {};
struct D : B, C {};
struct E {};
}
TEST_CASE("features/features/diamond_inheritance") {
namespace meta = meta_hpp;
meta::class_<A>();
meta::class_<B>().base_<A>();
meta::class_<C>().base_<A>();
meta::class_<D>().base_<B>().base_<C>();
meta::class_<E>();
// * <- B <- *
// A D
// * <- C <- *
const meta::class_type A_type = meta::resolve_type<A>();
const meta::class_type B_type = meta::resolve_type<B>();
const meta::class_type C_type = meta::resolve_type<C>();
const meta::class_type D_type = meta::resolve_type<D>();
const meta::class_type E_type = meta::resolve_type<E>();
REQUIRE(A_type);
REQUIRE(B_type);
REQUIRE(C_type);
REQUIRE(D_type);
REQUIRE(E_type);
SUBCASE("is_base_of") {
CHECK(!A_type.is_base_of(A_type));
CHECK(A_type.is_base_of(B_type));
CHECK(A_type.is_base_of(C_type));
CHECK(A_type.is_base_of(D_type));
CHECK(!A_type.is_base_of(E_type));
CHECK(!B_type.is_base_of(A_type));
CHECK(!B_type.is_base_of(B_type));
CHECK(!B_type.is_base_of(C_type));
CHECK(B_type.is_base_of(D_type));
CHECK(!B_type.is_base_of(E_type));
CHECK(!C_type.is_base_of(A_type));
CHECK(!C_type.is_base_of(B_type));
CHECK(!C_type.is_base_of(C_type));
CHECK(C_type.is_base_of(D_type));
CHECK(!C_type.is_base_of(E_type));
CHECK(!D_type.is_base_of(A_type));
CHECK(!D_type.is_base_of(B_type));
CHECK(!D_type.is_base_of(C_type));
CHECK(!D_type.is_base_of(D_type));
CHECK(!D_type.is_base_of(E_type));
CHECK(!E_type.is_base_of(A_type));
CHECK(!E_type.is_base_of(B_type));
CHECK(!E_type.is_base_of(C_type));
CHECK(!E_type.is_base_of(D_type));
CHECK(!E_type.is_base_of(E_type));
}
SUBCASE("is_derived_from") {
CHECK(!A_type.is_derived_from(A_type));
CHECK(!A_type.is_derived_from(B_type));
CHECK(!A_type.is_derived_from(C_type));
CHECK(!A_type.is_derived_from(D_type));
CHECK(!A_type.is_derived_from(E_type));
CHECK(B_type.is_derived_from(A_type));
CHECK(!B_type.is_derived_from(B_type));
CHECK(!B_type.is_derived_from(C_type));
CHECK(!B_type.is_derived_from(D_type));
CHECK(!B_type.is_derived_from(E_type));
CHECK(C_type.is_derived_from(A_type));
CHECK(!C_type.is_derived_from(B_type));
CHECK(!C_type.is_derived_from(C_type));
CHECK(!C_type.is_derived_from(D_type));
CHECK(!C_type.is_derived_from(E_type));
CHECK(D_type.is_derived_from(A_type));
CHECK(D_type.is_derived_from(B_type));
CHECK(D_type.is_derived_from(C_type));
CHECK(!D_type.is_derived_from(D_type));
CHECK(!D_type.is_derived_from(E_type));
CHECK(!E_type.is_derived_from(A_type));
CHECK(!E_type.is_derived_from(B_type));
CHECK(!E_type.is_derived_from(C_type));
CHECK(!E_type.is_derived_from(D_type));
CHECK(!E_type.is_derived_from(E_type));
}
SUBCASE("pointer_upcast") {
{
A a;
CHECK(meta::pointer_upcast<A>(&a) == &a);
CHECK_FALSE(meta::pointer_upcast<B>(&a));
CHECK_FALSE(meta::pointer_upcast<C>(&a));
CHECK_FALSE(meta::pointer_upcast<D>(&a));
CHECK_FALSE(meta::pointer_upcast<E>(&a));
}
{
B b;
CHECK(meta::pointer_upcast<A>(&b) == &b);
CHECK(meta::pointer_upcast<B>(&b) == &b);
CHECK_FALSE(meta::pointer_upcast<C>(&b));
CHECK_FALSE(meta::pointer_upcast<D>(&b));
CHECK_FALSE(meta::pointer_upcast<E>(&b));
}
{
C c;
CHECK(meta::pointer_upcast<A>(&c) == &c);
CHECK_FALSE(meta::pointer_upcast<B>(&c));
CHECK(meta::pointer_upcast<C>(&c) == &c);
CHECK_FALSE(meta::pointer_upcast<D>(&c));
CHECK_FALSE(meta::pointer_upcast<E>(&c));
}
{
D d;
CHECK(meta::pointer_upcast<A>(&d) == &d);
CHECK(meta::pointer_upcast<B>(&d) == &d);
CHECK(meta::pointer_upcast<C>(&d) == &d);
CHECK(meta::pointer_upcast<D>(&d) == &d);
CHECK_FALSE(meta::pointer_upcast<E>(&d));
}
{
E e;
CHECK_FALSE(meta::pointer_upcast<A>(&e));
CHECK_FALSE(meta::pointer_upcast<B>(&e));
CHECK_FALSE(meta::pointer_upcast<C>(&e));
CHECK_FALSE(meta::pointer_upcast<D>(&e));
CHECK(meta::pointer_upcast<E>(&e) == &e);
}
}
SUBCASE("arg/cast") {
{
A a;
meta::value a_val{&a};
CHECK(*static_cast<A**>(a_val.data()) == &a);
meta::detail::arg a_arg{a_val};
CHECK(a_arg.can_cast_to<A*>());
CHECK(!a_arg.can_cast_to<B*>());
CHECK(!a_arg.can_cast_to<C*>());
CHECK(!a_arg.can_cast_to<D*>());
CHECK(!a_arg.can_cast_to<E*>());
CHECK(a_arg.cast<A*>() == static_cast<A*>(&a));
}
{
B b;
meta::value b_val{&b};
CHECK(*static_cast<B**>(b_val.data()) == &b);
meta::detail::arg b_arg{b_val};
CHECK(b_arg.can_cast_to<A*>());
CHECK(b_arg.can_cast_to<B*>());
CHECK(!b_arg.can_cast_to<C*>());
CHECK(!b_arg.can_cast_to<D*>());
CHECK(!b_arg.can_cast_to<E*>());
CHECK(b_arg.cast<A*>() == static_cast<A*>(&b));
CHECK(b_arg.cast<B*>() == static_cast<B*>(&b));
}
{
C c;
meta::value c_val{&c};
CHECK(*static_cast<C**>(c_val.data()) == &c);
meta::detail::arg c_arg{c_val};
CHECK(c_arg.can_cast_to<A*>());
CHECK(!c_arg.can_cast_to<B*>());
CHECK(c_arg.can_cast_to<C*>());
CHECK(!c_arg.can_cast_to<D*>());
CHECK(!c_arg.can_cast_to<E*>());
CHECK(c_arg.cast<A*>() == static_cast<A*>(&c));
CHECK(c_arg.cast<C*>() == static_cast<C*>(&c));
}
{
D d;
meta::value d_val{&d};
CHECK(*static_cast<D**>(d_val.data()) == &d);
meta::detail::arg d_arg{d_val};
CHECK(d_arg.can_cast_to<A*>());
CHECK(d_arg.can_cast_to<B*>());
CHECK(d_arg.can_cast_to<C*>());
CHECK(d_arg.can_cast_to<D*>());
CHECK(!d_arg.can_cast_to<E*>());
CHECK(d_arg.cast<A*>() == static_cast<A*>(&d));
CHECK(d_arg.cast<B*>() == static_cast<B*>(&d));
CHECK(d_arg.cast<C*>() == static_cast<C*>(&d));
CHECK(d_arg.cast<D*>() == static_cast<D*>(&d));
}
{
E e;
meta::value e_val{&e};
CHECK(*static_cast<E**>(e_val.data()) == &e);
meta::detail::arg e_arg{e_val};
CHECK(!e_arg.can_cast_to<A*>());
CHECK(!e_arg.can_cast_to<B*>());
CHECK(!e_arg.can_cast_to<C*>());
CHECK(!e_arg.can_cast_to<D*>());
CHECK(e_arg.can_cast_to<E*>());
CHECK(e_arg.cast<E*>() == static_cast<E*>(&e));
}
}
SUBCASE("inst/cast") {
{
meta::value a_val{A{}};
meta::detail::inst a_inst{a_val};
CHECK(a_inst.can_cast_to<A&>());
CHECK_FALSE(a_inst.can_cast_to<B&>());
CHECK_FALSE(a_inst.can_cast_to<C&>());
CHECK_FALSE(a_inst.can_cast_to<D&>());
CHECK_FALSE(a_inst.can_cast_to<E&>());
CHECK(&a_inst.cast<A&>() == a_val.try_cast<A>());
}
{
meta::value b_val{B{}};
meta::detail::inst b_inst{b_val};
CHECK(b_inst.can_cast_to<A&>());
CHECK(b_inst.can_cast_to<B&>());
CHECK_FALSE(b_inst.can_cast_to<C&>());
CHECK_FALSE(b_inst.can_cast_to<D&>());
CHECK_FALSE(b_inst.can_cast_to<E&>());
CHECK(&b_inst.cast<A&>() == b_val.try_cast<B>());
CHECK(&b_inst.cast<B&>() == b_val.try_cast<B>());
CHECK(&b_inst.cast<A&>() == b_val.try_cast<B>());
}
{
meta::value c_val{C{}};
meta::detail::inst c_inst{c_val};
CHECK(c_inst.can_cast_to<A&>());
CHECK_FALSE(c_inst.can_cast_to<B&>());
CHECK(c_inst.can_cast_to<C&>());
CHECK_FALSE(c_inst.can_cast_to<D&>());
CHECK_FALSE(c_inst.can_cast_to<E&>());
CHECK(&c_inst.cast<A&>() == c_val.try_cast<C>());
CHECK(&c_inst.cast<C&>() == c_val.try_cast<C>());
}
{
meta::value d_val{D{}};
meta::detail::inst d_inst{d_val};
CHECK(d_inst.can_cast_to<A&>());
CHECK(d_inst.can_cast_to<B&>());
CHECK(d_inst.can_cast_to<C&>());
CHECK(d_inst.can_cast_to<D&>());
CHECK_FALSE(d_inst.can_cast_to<E&>());
CHECK(&d_inst.cast<A&>() == d_val.try_cast<D>());
CHECK(&d_inst.cast<B&>() == d_val.try_cast<D>());
CHECK(&d_inst.cast<C&>() == d_val.try_cast<D>());
CHECK(&d_inst.cast<D&>() == d_val.try_cast<D>());
CHECK(&d_inst.cast<A&>() == d_val.try_cast<D>());
CHECK(&d_inst.cast<B&>() == d_val.try_cast<D>());
CHECK(&d_inst.cast<C&>() == d_val.try_cast<D>());
CHECK(&d_inst.cast<D&>() == d_val.try_cast<D>());
}
{
meta::value e_val{E{}};
meta::detail::inst e_inst{e_val};
CHECK_FALSE(e_inst.can_cast_to<A&>());
CHECK_FALSE(e_inst.can_cast_to<B&>());
CHECK_FALSE(e_inst.can_cast_to<C&>());
CHECK_FALSE(e_inst.can_cast_to<D&>());
CHECK(e_inst.can_cast_to<E&>());
CHECK(&e_inst.cast<E&>() == e_val.try_cast<E>());
}
}
}

View File

@@ -0,0 +1,352 @@
/*******************************************************************************
* 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_tests.hpp"
namespace
{
struct A {
A() = default;
virtual ~A() = default;
A(A&&) noexcept { ++move_ctors_; }
A(const A&) { ++copy_ctors_; }
A& operator=(A&&) = delete;
A& operator=(const A&) = delete;
int i = 1;
[[maybe_unused, nodiscard]] int f() const { return i; }
static int copy_ctors_;
static int move_ctors_;
};
int A::copy_ctors_{};
int A::move_ctors_{};
struct B : virtual A {
int i = 2;
[[maybe_unused, nodiscard]] int f() const { return i; }
};
struct C : virtual A {
int i = 3;
[[maybe_unused, nodiscard]] int f() const { return i; }
};
struct D : B, C {
int i = 4;
[[maybe_unused, nodiscard]] int f() const { return i; }
};
}
TEST_CASE("features/meta_utilities/arg2") {
namespace meta = meta_hpp;
// * <- B <- *
// A D
// * <- C <- *
meta::class_<A>();
meta::class_<B>().base_<A>();
meta::class_<C>().base_<A>();
meta::class_<D>().base_<B>().base_<C>();
}
TEST_CASE("features/meta_utilities/arg2/cast") {
namespace meta = meta_hpp;
using meta::detail::arg;
auto LV = []() -> D& { static D v; return v; };
auto CLV = []() -> const D& { static D v; return v; };
auto XV = []() -> D&& { static D v; return std::move(v); };
auto CXV = []() -> const D&& { static D v; return std::move(v); };
auto PRV = []() -> D { return D{}; };
auto CPRV = []() -> const D { return D{}; };
auto LV_PTR = []() -> D*& { static D v; static D* p{&v}; return p; };
auto LV_CPTR = []() -> const D*& { static D v; static const D* p{&v}; return p; };
auto CLV_PTR = []() -> D* const& { static D v; static D* p{&v}; return p; };
auto CLV_CPTR = []() -> const D* const& { static D v; static const D* p{&v}; return p; };
auto XV_PTR = []() -> D*&& { static D v; static D* p{&v}; return std::move(p); };
auto XV_CPTR = []() -> const D*&& { static D v; static const D* p{&v}; return std::move(p); };
auto CXV_PTR = []() -> D* const&& { static D v; static D* p{&v}; return std::move(p); };
auto CXV_CPTR = []() -> const D* const&& { static D v; static const D* p{&v}; return std::move(p); };
auto PRV_PTR = []() -> D* { static D v; static D* p{&v}; return p; };
auto PRV_CPTR = []() -> const D* { static D v; static const D* p{&v}; return p; };
// *------------------------------------------------------------*
// | ======> | T, const T | T& | const T& | T&& | const T&& |
// |---------*------------*------*----------*------*------------|
// | LV | Cc | ++ | ++ | | |
// |---------*------------*------*----------*------*------------|
// | CLV | Cc | | ++ | | |
// |---------*------------*------*----------*------*------------|
// | XV | Mc | | ++ | ++ | ++ |
// |---------*------------*------*----------*------*------------|
// | CXV | Cc | | ++ | | ++ |
// |---------*------------*------*----------*------*------------|
// | PRV | ++ | | ++ | ++ | ++ |
// |---------*------------*------*----------*------*------------|
// | CPRV | ++ | | ++ | | ++ |
// *------------------------------------------------------------*
A::copy_ctors_ = 0;
A::move_ctors_ = 0;
SUBCASE("LV") {
CHECK(arg{LV()}.can_cast_to<A>());
CHECK(arg{LV()}.can_cast_to<const A>());
CHECK(arg{LV()}.can_cast_to<A&>());
CHECK(arg{LV()}.can_cast_to<const A&>());
CHECK_FALSE(arg{LV()}.can_cast_to<A&&>());
CHECK_FALSE(arg{LV()}.can_cast_to<const A&&>());
CHECK(A::copy_ctors_ == 0);
CHECK(A::move_ctors_ == 0);
CHECK(arg{LV()}.cast<A>().f() == 1);
CHECK(arg{LV()}.cast<const A>().f() == 1);
CHECK(arg{LV()}.cast<A&>().f() == 1);
CHECK(arg{LV()}.cast<const A&>().f() == 1);
CHECK_THROWS(std::ignore = arg{LV()}.cast<A&&>());
CHECK_THROWS(std::ignore = arg{LV()}.cast<const A&&>());
CHECK(A::copy_ctors_ == 2);
CHECK(A::move_ctors_ == 0);
}
SUBCASE("CLV") {
CHECK(arg{CLV()}.can_cast_to<A>());
CHECK(arg{CLV()}.can_cast_to<const A>());
CHECK_FALSE(arg{CLV()}.can_cast_to<A&>());
CHECK(arg{CLV()}.can_cast_to<const A&>());
CHECK_FALSE(arg{CLV()}.can_cast_to<A&&>());
CHECK_FALSE(arg{CLV()}.can_cast_to<const A&&>());
CHECK(A::copy_ctors_ == 0);
CHECK(A::move_ctors_ == 0);
CHECK(arg{CLV()}.cast<A>().f() == 1);
CHECK(arg{CLV()}.cast<const A>().f() == 1);
CHECK_THROWS(std::ignore = arg{CLV()}.cast<A&>());
CHECK(arg{CLV()}.cast<const A&>().f() == 1);
CHECK_THROWS(std::ignore = arg{CLV()}.cast<A&&>());
CHECK_THROWS(std::ignore = arg{CLV()}.cast<const A&&>());
CHECK(A::copy_ctors_ == 2);
CHECK(A::move_ctors_ == 0);
}
SUBCASE("XV") {
CHECK(arg{XV()}.can_cast_to<A>());
CHECK(arg{XV()}.can_cast_to<const A>());
CHECK_FALSE(arg{XV()}.can_cast_to<A&>());
CHECK(arg{XV()}.can_cast_to<const A&>());
CHECK(arg{XV()}.can_cast_to<A&&>());
CHECK(arg{XV()}.can_cast_to<const A&&>());
CHECK(A::copy_ctors_ == 0);
CHECK(A::move_ctors_ == 0);
CHECK(arg{XV()}.cast<A>().f() == 1);
CHECK(arg{XV()}.cast<const A>().f() == 1);
CHECK_THROWS(std::ignore = arg{XV()}.cast<A&>());
CHECK(arg{XV()}.cast<const A&>().f() == 1);
CHECK(arg{XV()}.cast<A&&>().f() == 1);
CHECK(arg{XV()}.cast<const A&&>().f() == 1);
CHECK(A::copy_ctors_ == 0);
CHECK(A::move_ctors_ == 2);
}
SUBCASE("CXV") {
CHECK(arg{CXV()}.can_cast_to<A>());
CHECK(arg{CXV()}.can_cast_to<const A>());
CHECK_FALSE(arg{CXV()}.can_cast_to<A&>());
CHECK(arg{CXV()}.can_cast_to<const A&>());
CHECK_FALSE(arg{CXV()}.can_cast_to<A&&>());
CHECK(arg{CXV()}.can_cast_to<const A&&>());
CHECK(A::copy_ctors_ == 0);
CHECK(A::move_ctors_ == 0);
CHECK(arg{CXV()}.cast<A>().f() == 1);
CHECK(arg{CXV()}.cast<const A>().f() == 1);
CHECK_THROWS(std::ignore = arg{CXV()}.cast<A&>());
CHECK(arg{CXV()}.cast<const A&>().f() == 1);
CHECK_THROWS(std::ignore = arg{CXV()}.cast<A&&>());
CHECK(arg{CXV()}.cast<const A&&>().f() == 1);
CHECK(A::copy_ctors_ == 2);
CHECK(A::move_ctors_ == 0);
}
SUBCASE("PRV") {
CHECK(arg{PRV()}.can_cast_to<A>());
CHECK(arg{PRV()}.can_cast_to<const A>());
CHECK_FALSE(arg{PRV()}.can_cast_to<A&>());
CHECK(arg{PRV()}.can_cast_to<const A&>());
CHECK(arg{PRV()}.can_cast_to<A&&>());
CHECK(arg{PRV()}.can_cast_to<const A&&>());
CHECK(A::copy_ctors_ == 0);
CHECK(A::move_ctors_ == 0);
CHECK(arg{PRV()}.cast<A>().f() == 1);
CHECK(arg{PRV()}.cast<const A>().f() == 1);
CHECK_THROWS(std::ignore = arg{PRV()}.cast<A&>());
CHECK(arg{PRV()}.cast<const A&>().f() == 1);
CHECK(arg{PRV()}.cast<A&&>().f() == 1);
CHECK(arg{PRV()}.cast<const A&&>().f() == 1);
CHECK(A::copy_ctors_ == 0);
CHECK(A::move_ctors_ == 2);
}
SUBCASE("CPRV") {
CHECK(arg{CPRV()}.can_cast_to<A>());
CHECK(arg{CPRV()}.can_cast_to<const A>());
CHECK_FALSE(arg{CPRV()}.can_cast_to<A&>());
CHECK(arg{CPRV()}.can_cast_to<const A&>());
CHECK_FALSE(arg{CPRV()}.can_cast_to<A&&>());
CHECK(arg{CPRV()}.can_cast_to<const A&&>());
CHECK(A::copy_ctors_ == 0);
CHECK(A::move_ctors_ == 0);
CHECK(arg{CPRV()}.cast<A>().f() == 1);
CHECK(arg{CPRV()}.cast<const A>().f() == 1);
CHECK_THROWS(std::ignore = arg{CPRV()}.cast<A&>());
CHECK(arg{CPRV()}.cast<const A&>().f() == 1);
CHECK_THROWS(std::ignore = arg{CPRV()}.cast<A&&>());
CHECK(arg{CPRV()}.cast<const A&&>().f() == 1);
CHECK(A::copy_ctors_ == 2);
CHECK(A::move_ctors_ == 0);
}
SUBCASE("LV_PTR") {
CHECK(arg{LV_PTR()}.can_cast_to<A*>());
CHECK(arg{LV_PTR()}.can_cast_to<A* const>());
CHECK(arg{LV_PTR()}.can_cast_to<const A*>());
CHECK(arg{LV_PTR()}.can_cast_to<const A* const>());
CHECK(arg{LV_PTR()}.cast<A*>()->f() == 1);
CHECK(arg{LV_PTR()}.cast<A* const>()->f() == 1);
CHECK(arg{LV_PTR()}.cast<const A*>()->f() == 1);
CHECK(arg{LV_PTR()}.cast<const A* const>()->f() == 1);
}
SUBCASE("LV_CPTR") {
CHECK_FALSE(arg{LV_CPTR()}.can_cast_to<A*>());
CHECK_FALSE(arg{LV_CPTR()}.can_cast_to<A* const>());
CHECK(arg{LV_CPTR()}.can_cast_to<const A*>());
CHECK(arg{LV_CPTR()}.can_cast_to<const A* const>());
CHECK_THROWS(std::ignore = arg{LV_CPTR()}.cast<A*>());
CHECK_THROWS(std::ignore = arg{LV_CPTR()}.cast<A* const>());
CHECK(arg{LV_CPTR()}.cast<const A*>()->f() == 1);
CHECK(arg{LV_CPTR()}.cast<const A* const>()->f() == 1);
}
SUBCASE("CLV_PTR") {
CHECK(arg{CLV_PTR()}.can_cast_to<A*>());
CHECK(arg{CLV_PTR()}.can_cast_to<A* const>());
CHECK(arg{CLV_PTR()}.can_cast_to<const A*>());
CHECK(arg{CLV_PTR()}.can_cast_to<const A* const>());
CHECK(arg{CLV_PTR()}.cast<A*>()->f() == 1);
CHECK(arg{CLV_PTR()}.cast<A* const>()->f() == 1);
CHECK(arg{CLV_PTR()}.cast<const A*>()->f() == 1);
CHECK(arg{CLV_PTR()}.cast<const A* const>()->f() == 1);
}
SUBCASE("CLV_CPTR") {
CHECK_FALSE(arg{CLV_CPTR()}.can_cast_to<A*>());
CHECK_FALSE(arg{CLV_CPTR()}.can_cast_to<A* const>());
CHECK(arg{CLV_CPTR()}.can_cast_to<const A*>());
CHECK(arg{CLV_CPTR()}.can_cast_to<const A* const>());
CHECK_THROWS(std::ignore = arg{CLV_CPTR()}.cast<A*>());
CHECK_THROWS(std::ignore = arg{CLV_CPTR()}.cast<A* const>());
CHECK(arg{CLV_CPTR()}.cast<const A*>()->f() == 1);
CHECK(arg{CLV_CPTR()}.cast<const A* const>()->f() == 1);
}
SUBCASE("XV_PTR") {
CHECK(arg{XV_PTR()}.can_cast_to<A*>());
CHECK(arg{XV_PTR()}.can_cast_to<A* const>());
CHECK(arg{XV_PTR()}.can_cast_to<const A*>());
CHECK(arg{XV_PTR()}.can_cast_to<const A* const>());
CHECK(arg{XV_PTR()}.cast<A*>()->f() == 1);
CHECK(arg{XV_PTR()}.cast<A* const>()->f() == 1);
CHECK(arg{XV_PTR()}.cast<const A*>()->f() == 1);
CHECK(arg{XV_PTR()}.cast<const A* const>()->f() == 1);
}
SUBCASE("XV_CPTR") {
CHECK_FALSE(arg{XV_CPTR()}.can_cast_to<A*>());
CHECK_FALSE(arg{XV_CPTR()}.can_cast_to<A* const>());
CHECK(arg{XV_CPTR()}.can_cast_to<const A*>());
CHECK(arg{XV_CPTR()}.can_cast_to<const A* const>());
CHECK_THROWS(std::ignore = arg{XV_CPTR()}.cast<A*>());
CHECK_THROWS(std::ignore = arg{XV_CPTR()}.cast<A* const>());
CHECK(arg{XV_CPTR()}.cast<const A*>()->f() == 1);
CHECK(arg{XV_CPTR()}.cast<const A* const>()->f() == 1);
}
SUBCASE("CXV_PTR") {
CHECK(arg{CXV_PTR()}.can_cast_to<A*>());
CHECK(arg{CXV_PTR()}.can_cast_to<A* const>());
CHECK(arg{CXV_PTR()}.can_cast_to<const A*>());
CHECK(arg{CXV_PTR()}.can_cast_to<const A* const>());
CHECK(arg{CXV_PTR()}.cast<A*>()->f() == 1);
CHECK(arg{CXV_PTR()}.cast<A* const>()->f() == 1);
CHECK(arg{CXV_PTR()}.cast<const A*>()->f() == 1);
CHECK(arg{CXV_PTR()}.cast<const A* const>()->f() == 1);
}
SUBCASE("CXV_CPTR") {
CHECK_FALSE(arg{CXV_CPTR()}.can_cast_to<A*>());
CHECK_FALSE(arg{CXV_CPTR()}.can_cast_to<A* const>());
CHECK(arg{CXV_CPTR()}.can_cast_to<const A*>());
CHECK(arg{CXV_CPTR()}.can_cast_to<const A* const>());
CHECK_THROWS(std::ignore = arg{CXV_CPTR()}.cast<A*>());
CHECK_THROWS(std::ignore = arg{CXV_CPTR()}.cast<A* const>());
CHECK(arg{CXV_CPTR()}.cast<const A*>()->f() == 1);
CHECK(arg{CXV_CPTR()}.cast<const A* const>()->f() == 1);
}
SUBCASE("PRV_PTR") {
CHECK(arg{PRV_PTR()}.can_cast_to<A*>());
CHECK(arg{PRV_PTR()}.can_cast_to<A* const>());
CHECK(arg{PRV_PTR()}.can_cast_to<const A*>());
CHECK(arg{PRV_PTR()}.can_cast_to<const A* const>());
CHECK(arg{PRV_PTR()}.cast<A*>()->f() == 1);
CHECK(arg{PRV_PTR()}.cast<A* const>()->f() == 1);
CHECK(arg{PRV_PTR()}.cast<const A*>()->f() == 1);
CHECK(arg{PRV_PTR()}.cast<const A* const>()->f() == 1);
}
SUBCASE("PRV_CPTR") {
CHECK_FALSE(arg{PRV_CPTR()}.can_cast_to<A*>());
CHECK_FALSE(arg{PRV_CPTR()}.can_cast_to<A* const>());
CHECK(arg{PRV_CPTR()}.can_cast_to<const A*>());
CHECK(arg{PRV_CPTR()}.can_cast_to<const A* const>());
CHECK_THROWS(std::ignore = arg{PRV_CPTR()}.cast<A*>());
CHECK_THROWS(std::ignore = arg{PRV_CPTR()}.cast<A* const>());
CHECK(arg{PRV_CPTR()}.cast<const A*>()->f() == 1);
CHECK(arg{PRV_CPTR()}.cast<const A* const>()->f() == 1);
}
}

View File

@@ -0,0 +1,127 @@
/*******************************************************************************
* 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_tests.hpp"
namespace
{
struct A {
A() = default;
virtual ~A() = default;
A(A&&) = delete;
A(const A&) = delete;
A& operator=(A&&) = delete;
A& operator=(const A&) = delete;
int i = 1;
[[maybe_unused, nodiscard]] int f() const { return i; }
};
struct B : virtual A {
int i = 2;
[[maybe_unused, nodiscard]] int f() const { return i; }
};
struct C : virtual A {
int i = 3;
[[maybe_unused, nodiscard]] int f() const { return i; }
};
struct D : B, C {
int i = 4;
[[maybe_unused, nodiscard]] int f() const { return i; }
};
}
TEST_CASE("features/meta_utilities/arg3") {
namespace meta = meta_hpp;
// * <- B <- *
// A D
// * <- C <- *
meta::class_<A>();
meta::class_<B>().base_<A>();
meta::class_<C>().base_<A>();
meta::class_<D>().base_<B>().base_<C>();
}
TEST_CASE("features/meta_utilities/arg3/cast") {
namespace meta = meta_hpp;
using meta::detail::arg;
auto LV = []() -> D& { static D v; return v; };
auto CLV = []() -> const D& { static D v; return v; };
auto XV = []() -> D&& { static D v; return std::move(v); };
auto CXV = []() -> const D&& { static D v; return std::move(v); };
auto PRV = []() -> D { return D{}; };
auto CPRV = []() -> const D { return D{}; };
// *------------------------------------------------------------*
// | ======> | T, const T | T& | const T& | T&& | const T&& |
// |---------*------------*------*----------*------*------------|
// | LV | Cc | ++ | ++ | | |
// |---------*------------*------*----------*------*------------|
// | CLV | Cc | | ++ | | |
// |---------*------------*------*----------*------*------------|
// | XV | Mc | | ++ | ++ | ++ |
// |---------*------------*------*----------*------*------------|
// | CXV | Cc | | ++ | | ++ |
// |---------*------------*------*----------*------*------------|
// | PRV | ++ | | ++ | ++ | ++ |
// |---------*------------*------*----------*------*------------|
// | CPRV | ++ | | ++ | | ++ |
// *------------------------------------------------------------*
SUBCASE("LV") {
CHECK_FALSE(arg{LV()}.can_cast_to<A>());
CHECK_FALSE(arg{LV()}.can_cast_to<const A>());
CHECK_THROWS(std::ignore = arg{LV()}.cast<A>());
CHECK_THROWS(std::ignore = arg{LV()}.cast<const A>());
}
SUBCASE("CLV") {
CHECK_FALSE(arg{CLV()}.can_cast_to<A>());
CHECK_FALSE(arg{CLV()}.can_cast_to<const A>());
CHECK_THROWS(std::ignore = arg{CLV()}.cast<A>());
CHECK_THROWS(std::ignore = arg{CLV()}.cast<const A>());
}
SUBCASE("XV") {
CHECK_FALSE(arg{XV()}.can_cast_to<A>());
CHECK_FALSE(arg{XV()}.can_cast_to<const A>());
CHECK_THROWS(std::ignore = arg{XV()}.cast<A>());
CHECK_THROWS(std::ignore = arg{XV()}.cast<const A>());
}
SUBCASE("CXV") {
CHECK_FALSE(arg{CXV()}.can_cast_to<A>());
CHECK_FALSE(arg{CXV()}.can_cast_to<const A>());
CHECK_THROWS(std::ignore = arg{CXV()}.cast<A>());
CHECK_THROWS(std::ignore = arg{CXV()}.cast<const A>());
}
SUBCASE("PRV") {
CHECK_FALSE(arg{PRV()}.can_cast_to<A>());
CHECK_FALSE(arg{PRV()}.can_cast_to<const A>());
CHECK_THROWS(std::ignore = arg{PRV()}.cast<A>());
CHECK_THROWS(std::ignore = arg{PRV()}.cast<const A>());
}
SUBCASE("CPRV") {
CHECK_FALSE(arg{CPRV()}.can_cast_to<A>());
CHECK_FALSE(arg{CPRV()}.can_cast_to<const A>());
CHECK_THROWS(std::ignore = arg{CPRV()}.cast<A>());
CHECK_THROWS(std::ignore = arg{CPRV()}.cast<const A>());
}
}

View File

@@ -0,0 +1,144 @@
/*******************************************************************************
* 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_tests.hpp"
TEST_CASE("features/meta_utilities/arg4/cast") {
namespace meta = meta_hpp;
using meta::detail::arg;
auto LV_PTR = []() -> int*& { static int v{42}; static int* p{&v}; return p; };
auto CLV_PTR = []() -> int* const& { static int v{42}; static int* p{&v}; return p; };
auto XV_PTR = []() -> int*&& { static int v{42}; static int* p{&v}; return std::move(p); };
auto CXV_PTR = []() -> int* const&& { static int v{42}; static int* p{&v}; return std::move(p); };
auto PRV_PTR = []() -> int* { static int v{42}; static int* p{&v}; return p; };
auto LV_CPTR = []() -> const int*& { static int v{42}; static const int* p{&v}; return p; };
auto CLV_CPTR = []() -> const int* const& { static int v{42}; static const int* p{&v}; return p; };
auto XV_CPTR = []() -> const int*&& { static int v{42}; static const int* p{&v}; return std::move(p); };
auto CXV_CPTR = []() -> const int* const&& { static int v{42}; static const int* p{&v}; return std::move(p); };
auto PRV_CPTR = []() -> const int* { static int v{42}; static const int* p{&v}; return p; };
SUBCASE("LV_PTR") {
CHECK(arg{LV_PTR()}.can_cast_to<int*>());
CHECK(arg{LV_PTR()}.can_cast_to<int* const>());
CHECK(arg{LV_PTR()}.can_cast_to<const int*>());
CHECK(arg{LV_PTR()}.can_cast_to<const int* const>());
CHECK(*arg{LV_PTR()}.cast<int*>() == 42);
CHECK(*arg{LV_PTR()}.cast<int* const>() == 42);
CHECK(*arg{LV_PTR()}.cast<const int*>() == 42);
CHECK(*arg{LV_PTR()}.cast<const int* const>() == 42);
}
SUBCASE("CLV_PTR") {
CHECK(arg{CLV_PTR()}.can_cast_to<int*>());
CHECK(arg{CLV_PTR()}.can_cast_to<int* const>());
CHECK(arg{CLV_PTR()}.can_cast_to<const int*>());
CHECK(arg{CLV_PTR()}.can_cast_to<const int* const>());
CHECK(*arg{CLV_PTR()}.cast<int*>() == 42);
CHECK(*arg{CLV_PTR()}.cast<int* const>() == 42);
CHECK(*arg{CLV_PTR()}.cast<const int*>() == 42);
CHECK(*arg{CLV_PTR()}.cast<const int* const>() == 42);
}
SUBCASE("XV_PTR") {
CHECK(arg{XV_PTR()}.can_cast_to<int*>());
CHECK(arg{XV_PTR()}.can_cast_to<int* const>());
CHECK(arg{XV_PTR()}.can_cast_to<const int*>());
CHECK(arg{XV_PTR()}.can_cast_to<const int* const>());
CHECK(*arg{XV_PTR()}.cast<int*>() == 42);
CHECK(*arg{XV_PTR()}.cast<int* const>() == 42);
CHECK(*arg{XV_PTR()}.cast<const int*>() == 42);
CHECK(*arg{XV_PTR()}.cast<const int* const>() == 42);
}
SUBCASE("CXV_PTR") {
CHECK(arg{CXV_PTR()}.can_cast_to<int*>());
CHECK(arg{CXV_PTR()}.can_cast_to<int* const>());
CHECK(arg{CXV_PTR()}.can_cast_to<const int*>());
CHECK(arg{CXV_PTR()}.can_cast_to<const int* const>());
CHECK(*arg{CXV_PTR()}.cast<int*>() == 42);
CHECK(*arg{CXV_PTR()}.cast<int* const>() == 42);
CHECK(*arg{CXV_PTR()}.cast<const int*>() == 42);
CHECK(*arg{CXV_PTR()}.cast<const int* const>() == 42);
}
SUBCASE("PRV_PTR") {
CHECK(arg{PRV_PTR()}.can_cast_to<int*>());
CHECK(arg{PRV_PTR()}.can_cast_to<int* const>());
CHECK(arg{PRV_PTR()}.can_cast_to<const int*>());
CHECK(arg{PRV_PTR()}.can_cast_to<const int* const>());
CHECK(*arg{PRV_PTR()}.cast<int*>() == 42);
CHECK(*arg{PRV_PTR()}.cast<int* const>() == 42);
CHECK(*arg{PRV_PTR()}.cast<const int*>() == 42);
CHECK(*arg{PRV_PTR()}.cast<const int* const>() == 42);
}
SUBCASE("LV_CPTR") {
CHECK_FALSE(arg{LV_CPTR()}.can_cast_to<int*>());
CHECK_FALSE(arg{LV_CPTR()}.can_cast_to<int* const>());
CHECK(arg{LV_CPTR()}.can_cast_to<const int*>());
CHECK(arg{LV_CPTR()}.can_cast_to<const int* const>());
CHECK_THROWS(std::ignore = arg{LV_CPTR()}.cast<int*>());
CHECK_THROWS(std::ignore = arg{LV_CPTR()}.cast<int* const>());
CHECK(*arg{LV_CPTR()}.cast<const int*>() == 42);
CHECK(*arg{LV_CPTR()}.cast<const int* const>() == 42);
}
SUBCASE("CLV_CPTR") {
CHECK_FALSE(arg{CLV_CPTR()}.can_cast_to<int*>());
CHECK_FALSE(arg{CLV_CPTR()}.can_cast_to<int* const>());
CHECK(arg{CLV_CPTR()}.can_cast_to<const int*>());
CHECK(arg{CLV_CPTR()}.can_cast_to<const int* const>());
CHECK_THROWS(std::ignore = arg{CLV_CPTR()}.cast<int*>());
CHECK_THROWS(std::ignore = arg{CLV_CPTR()}.cast<int* const>());
CHECK(*arg{CLV_CPTR()}.cast<const int*>() == 42);
CHECK(*arg{CLV_CPTR()}.cast<const int* const>() == 42);
}
SUBCASE("XV_CPTR") {
CHECK_FALSE(arg{XV_CPTR()}.can_cast_to<int*>());
CHECK_FALSE(arg{XV_CPTR()}.can_cast_to<int* const>());
CHECK(arg{XV_CPTR()}.can_cast_to<const int*>());
CHECK(arg{XV_CPTR()}.can_cast_to<const int* const>());
CHECK_THROWS(std::ignore = arg{XV_CPTR()}.cast<int*>());
CHECK_THROWS(std::ignore = arg{XV_CPTR()}.cast<int* const>());
CHECK(*arg{XV_CPTR()}.cast<const int*>() == 42);
CHECK(*arg{XV_CPTR()}.cast<const int* const>() == 42);
}
SUBCASE("CXV_CPTR") {
CHECK_FALSE(arg{CXV_CPTR()}.can_cast_to<int*>());
CHECK_FALSE(arg{CXV_CPTR()}.can_cast_to<int* const>());
CHECK(arg{CXV_CPTR()}.can_cast_to<const int*>());
CHECK(arg{CXV_CPTR()}.can_cast_to<const int* const>());
CHECK_THROWS(std::ignore = arg{CXV_CPTR()}.cast<int*>());
CHECK_THROWS(std::ignore = arg{CXV_CPTR()}.cast<int* const>());
CHECK(*arg{CXV_CPTR()}.cast<const int*>() == 42);
CHECK(*arg{CXV_CPTR()}.cast<const int* const>() == 42);
}
SUBCASE("PRV_CPTR") {
CHECK_FALSE(arg{PRV_CPTR()}.can_cast_to<int*>());
CHECK_FALSE(arg{PRV_CPTR()}.can_cast_to<int* const>());
CHECK(arg{PRV_CPTR()}.can_cast_to<const int*>());
CHECK(arg{PRV_CPTR()}.can_cast_to<const int* const>());
CHECK_THROWS(std::ignore = arg{PRV_CPTR()}.cast<int*>());
CHECK_THROWS(std::ignore = arg{PRV_CPTR()}.cast<int* const>());
CHECK(*arg{PRV_CPTR()}.cast<const int*>() == 42);
CHECK(*arg{PRV_CPTR()}.cast<const int* const>() == 42);
}
}

View File

@@ -8,44 +8,64 @@
namespace
{
struct clazz;
struct dclazz;
struct fake {
int i = 10;
};
struct clazz {
[[maybe_unused]] clazz() = default;
[[maybe_unused]] clazz(clazz&&) = default;
[[maybe_unused]] clazz(const clazz&) = default;
clazz& operator=(clazz&&) = delete;
clazz& operator=(const clazz&) = delete;
int ii = 1;
};
struct dclazz : clazz {
[[maybe_unused]] dclazz() = default;
[[maybe_unused]] dclazz(dclazz&&) = default;
[[maybe_unused]] dclazz(const dclazz&) = default;
dclazz& operator=(dclazz&&) = delete;
dclazz& operator=(const dclazz&) = delete;
struct dclazz : fake, clazz {
};
int f1(clazz) { return 1; }
int f2(const clazz) { return 1; }
int f3(clazz&) { return 1; }
int f4(const clazz&) { return 1; }
int f5(clazz&&) { return 1; }
int f6(const clazz&&) { return 1; }
int f1(int v) { return v; }
int f2(const int v) { return v; }
int f3(int& v) { return v; }
int f4(const int& v) { return v; }
int f5(int&& v) { return v; }
int f6(const int&& v) { return v; }
int f1(clazz*) { return 1; }
int f2(clazz* const) { return 1; }
// int f3(clazz*&) { return 1; }
// int f4(clazz* const&) { return 1; }
// int f5(clazz*&&) { return 1; }
// int f6(clazz* const&&) { return 1; }
int f1(clazz v) { return v.ii; }
int f2(const clazz v) { return v.ii; }
int f3(clazz& v) { return v.ii; }
int f4(const clazz& v) { return v.ii; }
int f5(clazz&& v) { return v.ii; }
int f6(const clazz&& v) { return v.ii; }
int f1(const clazz*) { return 1; }
int f2(const clazz* const) { return 1; }
// int f3(const clazz*&) { return 1; }
// int f4(const clazz* const&) { return 1; }
// int f5(const clazz*&&) { return 1; }
// int f6(const clazz* const&&) { return 1; }
int f1(int* v) { return *v; }
int f2(int* const v) { return *v; }
// int f3(int*&) { return *v; }
// int f4(int* const&) { return *v; }
// int f5(int*&&) { return *v; }
// int f6(int* const&&) { return *v; }
int f1(clazz* v) { return v->ii; }
int f2(clazz* const v) { return v->ii; }
// int f3(clazz*&) { return v->ii; }
// int f4(clazz* const&) { return v->ii; }
// int f5(clazz*&&) { return v->ii; }
// int f6(clazz* const&&) { return v->ii; }
int f1(const int* v) { return *v; }
int f2(const int* const v) { return *v; }
// int f3(const int*&) { return *v; }
// int f4(const int* const&) { return *v; }
// int f5(const int*&&) { return *v; }
// int f6(const int* const&&) { return *v; }
int f1(const clazz* v) { return v->ii; }
int f2(const clazz* const v) { return v->ii; }
// int f3(const clazz*&) { return v->ii; }
// int f4(const clazz* const&) { return v->ii; }
// int f5(const clazz*&&) { return v->ii; }
// int f6(const clazz* const&&) { return v->ii; }
}
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define META_HPP_CHECK_INVOCABLE(FromValue, FName, ToType)\
{\
using namespace meta::detail;\
@@ -55,20 +75,21 @@ namespace
if ( std::is_invocable_v<decltype(function_ptr), decltype(FromValue)> ) {\
CHECK(arg{FromValue}.can_cast_to<ToType>());\
CHECK(arg_base{type_list<decltype(FromValue)>{}}.can_cast_to<ToType>());\
CHECK_NOTHROW(arg{FromValue}.cast<ToType>());\
CHECK_NOTHROW(std::ignore = arg{FromValue}.cast<ToType>());\
\
CHECK(f_state.is_invocable_with<decltype(FromValue)>());\
CHECK(f_state.invoke(FromValue) == 1);\
} else {\
CHECK_FALSE(arg{FromValue}.can_cast_to<ToType>());\
CHECK_FALSE(arg_base{type_list<decltype(FromValue)>{}}.can_cast_to<ToType>());\
CHECK_THROWS(arg{FromValue}.cast<ToType>());\
CHECK_THROWS(std::ignore = arg{FromValue}.cast<ToType>());\
\
CHECK_FALSE(f_state.is_invocable_with<decltype(FromValue)>());\
CHECK_THROWS(f_state.invoke(FromValue));\
}\
}
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define META_HPP_CHECK_INVOCABLE_2(FromValue, FName, FromType, ToType)\
{\
using namespace meta::detail;\
@@ -89,8 +110,9 @@ namespace
TEST_CASE("features/meta_utilities/arg") {
namespace meta = meta_hpp;
meta::class_<dclazz>()
.base_<clazz>();
meta::class_<fake>();
meta::class_<clazz>();
meta::class_<dclazz>().base_<fake>().base_<clazz>();
}
TEST_CASE("features/meta_utilities/arg/refs") {
@@ -100,6 +122,7 @@ TEST_CASE("features/meta_utilities/arg/refs") {
// lvalue
auto LV = []() -> clazz& { static clazz v; return v; };
auto LV2 = []() -> dclazz& { static dclazz v; return v; };
auto LV3 = []() -> int& { static int v{1}; return v; };
meta::detail::arg a{LV()};
CHECK(a.get_raw_type() == meta::resolve_type<clazz>());
@@ -118,12 +141,20 @@ TEST_CASE("features/meta_utilities/arg/refs") {
META_HPP_CHECK_INVOCABLE(LV2(), f4, const clazz&)
META_HPP_CHECK_INVOCABLE(LV2(), f5, clazz&&)
META_HPP_CHECK_INVOCABLE(LV2(), f6, const clazz&&)
META_HPP_CHECK_INVOCABLE(LV3(), f1, int)
META_HPP_CHECK_INVOCABLE(LV3(), f2, const int)
META_HPP_CHECK_INVOCABLE(LV3(), f3, int&)
META_HPP_CHECK_INVOCABLE(LV3(), f4, const int&)
META_HPP_CHECK_INVOCABLE(LV3(), f5, int&&)
META_HPP_CHECK_INVOCABLE(LV3(), f6, const int&&)
}
{
// const lvalue
auto CLV = []() -> const clazz& { static clazz v; return v; };
auto CLV2 = []() -> const dclazz& { static dclazz v; return v; };
auto CLV3 = []() -> const int& { static int v{1}; return v; };
meta::detail::arg a{CLV()};
CHECK(a.get_raw_type() == meta::resolve_type<clazz>());
@@ -142,12 +173,20 @@ TEST_CASE("features/meta_utilities/arg/refs") {
META_HPP_CHECK_INVOCABLE(CLV2(), f4, const clazz&)
META_HPP_CHECK_INVOCABLE(CLV2(), f5, clazz&&)
META_HPP_CHECK_INVOCABLE(CLV2(), f6, const clazz&&)
META_HPP_CHECK_INVOCABLE(CLV3(), f1, int)
META_HPP_CHECK_INVOCABLE(CLV3(), f2, const int)
META_HPP_CHECK_INVOCABLE(CLV3(), f3, int&)
META_HPP_CHECK_INVOCABLE(CLV3(), f4, const int&)
META_HPP_CHECK_INVOCABLE(CLV3(), f5, int&&)
META_HPP_CHECK_INVOCABLE(CLV3(), f6, const int&&)
}
{
// xvalue
auto XV = []() -> clazz&& { static clazz v; return std::move(v); };
auto XV2 = []() -> dclazz&& { static dclazz v; return std::move(v); };
auto XV3 = []() -> int&& { static int v{1}; return std::move(v); };
meta::detail::arg a{XV()};
CHECK(a.get_raw_type() == meta::resolve_type<clazz>());
@@ -166,12 +205,20 @@ TEST_CASE("features/meta_utilities/arg/refs") {
META_HPP_CHECK_INVOCABLE(XV2(), f4, const clazz&)
META_HPP_CHECK_INVOCABLE(XV2(), f5, clazz&&)
META_HPP_CHECK_INVOCABLE(XV2(), f6, const clazz&&)
META_HPP_CHECK_INVOCABLE(XV3(), f1, int)
META_HPP_CHECK_INVOCABLE(XV3(), f2, const int)
META_HPP_CHECK_INVOCABLE(XV3(), f3, int&)
META_HPP_CHECK_INVOCABLE(XV3(), f4, const int&)
META_HPP_CHECK_INVOCABLE(XV3(), f5, int&&)
META_HPP_CHECK_INVOCABLE(XV3(), f6, const int&&)
}
{
// const xvalue
auto CXV = []() -> const clazz&& { static clazz v; return std::move(v); };
auto CXV2 = []() -> const dclazz&& { static dclazz v; return std::move(v); };
auto CXV3 = []() -> const int&& { static int v{1}; return std::move(v); };
meta::detail::arg a{CXV()};
CHECK(a.get_raw_type() == meta::resolve_type<clazz>());
@@ -190,12 +237,20 @@ TEST_CASE("features/meta_utilities/arg/refs") {
META_HPP_CHECK_INVOCABLE(CXV2(), f4, const clazz&)
META_HPP_CHECK_INVOCABLE(CXV2(), f5, clazz&&)
META_HPP_CHECK_INVOCABLE(CXV2(), f6, const clazz&&)
META_HPP_CHECK_INVOCABLE(CXV3(), f1, int)
META_HPP_CHECK_INVOCABLE(CXV3(), f2, const int)
META_HPP_CHECK_INVOCABLE(CXV3(), f3, int&)
META_HPP_CHECK_INVOCABLE(CXV3(), f4, const int&)
META_HPP_CHECK_INVOCABLE(CXV3(), f5, int&&)
META_HPP_CHECK_INVOCABLE(CXV3(), f6, const int&&)
}
{
// prvalue
auto PRV = []() -> clazz { return clazz{}; };
auto PRV2 = []() -> dclazz { return dclazz{}; };
auto PRV3 = []() -> int { return int{1}; };
meta::detail::arg a{PRV()};
CHECK(a.get_raw_type() == meta::resolve_type<clazz>());
@@ -214,6 +269,13 @@ TEST_CASE("features/meta_utilities/arg/refs") {
META_HPP_CHECK_INVOCABLE(PRV2(), f4, const clazz&)
META_HPP_CHECK_INVOCABLE(PRV2(), f5, clazz&&)
META_HPP_CHECK_INVOCABLE(PRV2(), f6, const clazz&&)
META_HPP_CHECK_INVOCABLE(PRV3(), f1, int)
META_HPP_CHECK_INVOCABLE(PRV3(), f2, const int)
META_HPP_CHECK_INVOCABLE(PRV3(), f3, int&)
META_HPP_CHECK_INVOCABLE(PRV3(), f4, const int&)
META_HPP_CHECK_INVOCABLE(PRV3(), f5, int&&)
META_HPP_CHECK_INVOCABLE(PRV3(), f6, const int&&)
}
{
@@ -247,8 +309,9 @@ TEST_CASE("features/meta_utilities/arg/ptrs") {
{
// lvalue
{
auto LV_PTR = []() -> clazz*& { static clazz* p{}; return p; };
auto LV2_PTR = []() -> dclazz*& { static dclazz* p{}; return p; };
auto LV_PTR = []() -> clazz*& { static clazz v; static clazz* p{&v}; return p; };
auto LV2_PTR = []() -> dclazz*& { static dclazz v; static dclazz* p{&v}; return p; };
auto LV3_PTR = []() -> int*& { static int v{1}; static int* p{&v}; return p; };
meta::detail::arg a{LV_PTR()};
CHECK(a.get_raw_type() == meta::resolve_type<clazz*>());
@@ -281,10 +344,25 @@ TEST_CASE("features/meta_utilities/arg/ptrs") {
// META_HPP_CHECK_INVOCABLE(LV2_PTR(), f4, const clazz* const&)
// META_HPP_CHECK_INVOCABLE(LV2_PTR(), f5, const clazz*&&)
// META_HPP_CHECK_INVOCABLE(LV2_PTR(), f6, const clazz* const&&)
META_HPP_CHECK_INVOCABLE(LV3_PTR(), f1, int*)
META_HPP_CHECK_INVOCABLE(LV3_PTR(), f2, int* const)
// META_HPP_CHECK_INVOCABLE(LV3_PTR(), f3, int*&)
// META_HPP_CHECK_INVOCABLE(LV3_PTR(), f4, int* const&)
// META_HPP_CHECK_INVOCABLE(LV3_PTR(), f5, int*&&)
// META_HPP_CHECK_INVOCABLE(LV3_PTR(), f6, int* const&&)
META_HPP_CHECK_INVOCABLE(LV3_PTR(), f1, const int*)
META_HPP_CHECK_INVOCABLE(LV3_PTR(), f2, const int* const)
// META_HPP_CHECK_INVOCABLE(LV3_PTR(), f3, const int*&)
// META_HPP_CHECK_INVOCABLE(LV3_PTR(), f4, const int* const&)
// META_HPP_CHECK_INVOCABLE(LV3_PTR(), f5, const int*&&)
// META_HPP_CHECK_INVOCABLE(LV3_PTR(), f6, const int* const&&)
}
{
auto LV_CPTR = []() -> const clazz*& { static const clazz* p{}; return p; };
auto LV2_CPTR = []() -> const dclazz*& { static const dclazz* p{}; return p; };
auto LV_CPTR = []() -> const clazz*& { static clazz v; static const clazz* p{&v}; return p; };
auto LV2_CPTR = []() -> const dclazz*& { static dclazz v; static const dclazz* p{&v}; return p; };
auto LV3_CPTR = []() -> const int*& { static int v{1}; static const int* p{&v}; return p; };
meta::detail::arg a{LV_CPTR()};
CHECK(a.get_raw_type() == meta::resolve_type<const clazz*>());
@@ -317,14 +395,29 @@ TEST_CASE("features/meta_utilities/arg/ptrs") {
// META_HPP_CHECK_INVOCABLE(LV2_CPTR(), f4, const clazz* const&)
// META_HPP_CHECK_INVOCABLE(LV2_CPTR(), f5, const clazz*&&)
// META_HPP_CHECK_INVOCABLE(LV2_CPTR(), f6, const clazz* const&&)
META_HPP_CHECK_INVOCABLE(LV3_CPTR(), f1, int*)
META_HPP_CHECK_INVOCABLE(LV3_CPTR(), f2, int* const)
// META_HPP_CHECK_INVOCABLE(LV3_CPTR(), f3, int*&)
// META_HPP_CHECK_INVOCABLE(LV3_CPTR(), f4, int* const&)
// META_HPP_CHECK_INVOCABLE(LV3_CPTR(), f5, int*&&)
// META_HPP_CHECK_INVOCABLE(LV3_CPTR(), f6, int* const&&)
META_HPP_CHECK_INVOCABLE(LV3_CPTR(), f1, const int*)
META_HPP_CHECK_INVOCABLE(LV3_CPTR(), f2, const int* const)
// META_HPP_CHECK_INVOCABLE(LV3_CPTR(), f3, const int*&)
// META_HPP_CHECK_INVOCABLE(LV3_CPTR(), f4, const int* const&)
// META_HPP_CHECK_INVOCABLE(LV3_CPTR(), f5, const int*&&)
// META_HPP_CHECK_INVOCABLE(LV3_CPTR(), f6, const int* const&&)
}
}
{
// const lvalue
{
auto CLV_PTR = []() -> clazz* const& { static clazz* p{}; return p; };
auto CLV2_PTR = []() -> dclazz* const& { static dclazz* p{}; return p; };
auto CLV_PTR = []() -> clazz* const& { static clazz v; static clazz* p{&v}; return p; };
auto CLV2_PTR = []() -> dclazz* const& { static dclazz v; static dclazz* p{&v}; return p; };
auto CLV3_PTR = []() -> int* const& { static int v{1}; static int* p{&v}; return p; };
meta::detail::arg a{CLV_PTR()};
CHECK(a.get_raw_type() == meta::resolve_type<clazz*>());
@@ -357,10 +450,25 @@ TEST_CASE("features/meta_utilities/arg/ptrs") {
// META_HPP_CHECK_INVOCABLE(CLV2_PTR(), f4, const clazz* const&)
// META_HPP_CHECK_INVOCABLE(CLV2_PTR(), f5, const clazz*&&)
// META_HPP_CHECK_INVOCABLE(CLV2_PTR(), f6, const clazz* const&&)
META_HPP_CHECK_INVOCABLE(CLV3_PTR(), f1, int*)
META_HPP_CHECK_INVOCABLE(CLV3_PTR(), f2, int* const)
// META_HPP_CHECK_INVOCABLE(CLV3_PTR(), f3, int*&)
// META_HPP_CHECK_INVOCABLE(CLV3_PTR(), f4, int* const&)
// META_HPP_CHECK_INVOCABLE(CLV3_PTR(), f5, int*&&)
// META_HPP_CHECK_INVOCABLE(CLV3_PTR(), f6, int* const&&)
META_HPP_CHECK_INVOCABLE(CLV3_PTR(), f1, const int*)
META_HPP_CHECK_INVOCABLE(CLV3_PTR(), f2, const int* const)
// META_HPP_CHECK_INVOCABLE(CLV3_PTR(), f3, const int*&)
// META_HPP_CHECK_INVOCABLE(CLV3_PTR(), f4, const int* const&)
// META_HPP_CHECK_INVOCABLE(CLV3_PTR(), f5, const int*&&)
// META_HPP_CHECK_INVOCABLE(CLV3_PTR(), f6, const int* const&&)
}
{
auto CLV_CPTR = []() -> const clazz* const& { static const clazz* p{}; return p; };
auto CLV2_CPTR = []() -> const dclazz* const& { static const dclazz* p{}; return p; };
auto CLV_CPTR = []() -> const clazz* const& { static clazz v; static const clazz* p{&v}; return p; };
auto CLV2_CPTR = []() -> const dclazz* const& { static dclazz v; static const dclazz* p{&v}; return p; };
auto CLV3_CPTR = []() -> const int* const& { static int v{1}; static const int* p{&v}; return p; };
meta::detail::arg a{CLV_CPTR()};
CHECK(a.get_raw_type() == meta::resolve_type<const clazz*>());
@@ -393,14 +501,29 @@ TEST_CASE("features/meta_utilities/arg/ptrs") {
// META_HPP_CHECK_INVOCABLE(CLV2_CPTR(), f4, const clazz* const&)
// META_HPP_CHECK_INVOCABLE(CLV2_CPTR(), f5, const clazz*&&)
// META_HPP_CHECK_INVOCABLE(CLV2_CPTR(), f6, const clazz* const&&)
META_HPP_CHECK_INVOCABLE(CLV3_CPTR(), f1, int*)
META_HPP_CHECK_INVOCABLE(CLV3_CPTR(), f2, int* const)
// META_HPP_CHECK_INVOCABLE(CLV3_CPTR(), f3, int*&)
// META_HPP_CHECK_INVOCABLE(CLV3_CPTR(), f4, int* const&)
// META_HPP_CHECK_INVOCABLE(CLV3_CPTR(), f5, int*&&)
// META_HPP_CHECK_INVOCABLE(CLV3_CPTR(), f6, int* const&&)
META_HPP_CHECK_INVOCABLE(CLV3_CPTR(), f1, const int*)
META_HPP_CHECK_INVOCABLE(CLV3_CPTR(), f2, const int* const)
// META_HPP_CHECK_INVOCABLE(CLV3_CPTR(), f3, const int*&)
// META_HPP_CHECK_INVOCABLE(CLV3_CPTR(), f4, const int* const&)
// META_HPP_CHECK_INVOCABLE(CLV3_CPTR(), f5, const int*&&)
// META_HPP_CHECK_INVOCABLE(CLV3_CPTR(), f6, const int* const&&)
}
}
{
// xvalue
{
auto XV_PTR = []() -> clazz*&& { static clazz* p{}; return std::move(p); };
auto XV2_PTR = []() -> dclazz*&& { static dclazz* p{}; return std::move(p); };
auto XV_PTR = []() -> clazz*&& { static clazz v; static clazz* p{&v}; return std::move(p); };
auto XV2_PTR = []() -> dclazz*&& { static dclazz v; static dclazz* p{&v}; return std::move(p); };
auto XV3_PTR = []() -> int*&& { static int v{1}; static int* p{&v}; return std::move(p); };
meta::detail::arg a{XV_PTR()};
CHECK(a.get_raw_type() == meta::resolve_type<clazz*>());
@@ -433,10 +556,25 @@ TEST_CASE("features/meta_utilities/arg/ptrs") {
// META_HPP_CHECK_INVOCABLE(XV2_PTR(), f4, const clazz* const&)
// META_HPP_CHECK_INVOCABLE(XV2_PTR(), f5, const clazz*&&)
// META_HPP_CHECK_INVOCABLE(XV2_PTR(), f6, const clazz* const&&)
META_HPP_CHECK_INVOCABLE(XV3_PTR(), f1, int*)
META_HPP_CHECK_INVOCABLE(XV3_PTR(), f2, int* const)
// META_HPP_CHECK_INVOCABLE(XV3_PTR(), f3, int*&)
// META_HPP_CHECK_INVOCABLE(XV3_PTR(), f4, int* const&)
// META_HPP_CHECK_INVOCABLE(XV3_PTR(), f5, int*&&)
// META_HPP_CHECK_INVOCABLE(XV3_PTR(), f6, int* const&&)
META_HPP_CHECK_INVOCABLE(XV3_PTR(), f1, const int*)
META_HPP_CHECK_INVOCABLE(XV3_PTR(), f2, const int* const)
// META_HPP_CHECK_INVOCABLE(XV3_PTR(), f3, const int*&)
// META_HPP_CHECK_INVOCABLE(XV3_PTR(), f4, const int* const&)
// META_HPP_CHECK_INVOCABLE(XV3_PTR(), f5, const int*&&)
// META_HPP_CHECK_INVOCABLE(XV3_PTR(), f6, const int* const&&)
}
{
auto XV_CPTR = []() -> const clazz*&& { static const clazz* p{}; return std::move(p); };
auto XV2_CPTR = []() -> const dclazz*&& { static const dclazz* p{}; return std::move(p); };
auto XV_CPTR = []() -> const clazz*&& { static clazz v; static const clazz* p{&v}; return std::move(p); };
auto XV2_CPTR = []() -> const dclazz*&& { static dclazz v; static const dclazz* p{&v}; return std::move(p); };
auto XV3_CPTR = []() -> const int*&& { static int v{1}; static const int* p{&v}; return std::move(p); };
meta::detail::arg a{XV_CPTR()};
CHECK(a.get_raw_type() == meta::resolve_type<const clazz*>());
@@ -469,14 +607,29 @@ TEST_CASE("features/meta_utilities/arg/ptrs") {
// META_HPP_CHECK_INVOCABLE(XV2_CPTR(), f4, const clazz* const&)
// META_HPP_CHECK_INVOCABLE(XV2_CPTR(), f5, const clazz*&&)
// META_HPP_CHECK_INVOCABLE(XV2_CPTR(), f6, const clazz* const&&)
META_HPP_CHECK_INVOCABLE(XV3_CPTR(), f1, int*)
META_HPP_CHECK_INVOCABLE(XV3_CPTR(), f2, int* const)
// META_HPP_CHECK_INVOCABLE(XV3_CPTR(), f3, int*&)
// META_HPP_CHECK_INVOCABLE(XV3_CPTR(), f4, int* const&)
// META_HPP_CHECK_INVOCABLE(XV3_CPTR(), f5, int*&&)
// META_HPP_CHECK_INVOCABLE(XV3_CPTR(), f6, int* const&&)
META_HPP_CHECK_INVOCABLE(XV3_CPTR(), f1, const int*)
META_HPP_CHECK_INVOCABLE(XV3_CPTR(), f2, const int* const)
// META_HPP_CHECK_INVOCABLE(XV3_CPTR(), f3, const int*&)
// META_HPP_CHECK_INVOCABLE(XV3_CPTR(), f4, const int* const&)
// META_HPP_CHECK_INVOCABLE(XV3_CPTR(), f5, const int*&&)
// META_HPP_CHECK_INVOCABLE(XV3_CPTR(), f6, const int* const&&)
}
}
{
// const xvalue
{
auto CXV_PTR = []() -> clazz* const&& { static clazz* p{}; return std::move(p); };
auto CXV2_PTR = []() -> dclazz* const&& { static dclazz* p{}; return std::move(p); };
auto CXV_PTR = []() -> clazz* const&& { static clazz v; static clazz* p{&v}; return std::move(p); };
auto CXV2_PTR = []() -> dclazz* const&& { static dclazz v; static dclazz* p{&v}; return std::move(p); };
auto CXV3_PTR = []() -> int* const&& { static int v{1}; static int* p{&v}; return std::move(p); };
meta::detail::arg a{CXV_PTR()};
CHECK(a.get_raw_type() == meta::resolve_type<clazz*>());
@@ -509,10 +662,25 @@ TEST_CASE("features/meta_utilities/arg/ptrs") {
// META_HPP_CHECK_INVOCABLE(CXV2_PTR(), f4, const clazz* const&)
// META_HPP_CHECK_INVOCABLE(CXV2_PTR(), f5, const clazz*&&)
// META_HPP_CHECK_INVOCABLE(CXV2_PTR(), f6, const clazz* const&&)
META_HPP_CHECK_INVOCABLE(CXV3_PTR(), f1, int*)
META_HPP_CHECK_INVOCABLE(CXV3_PTR(), f2, int* const)
// META_HPP_CHECK_INVOCABLE(CXV3_PTR(), f3, int*&)
// META_HPP_CHECK_INVOCABLE(CXV3_PTR(), f4, int* const&)
// META_HPP_CHECK_INVOCABLE(CXV3_PTR(), f5, int*&&)
// META_HPP_CHECK_INVOCABLE(CXV3_PTR(), f6, int* const&&)
META_HPP_CHECK_INVOCABLE(CXV3_PTR(), f1, const int*)
META_HPP_CHECK_INVOCABLE(CXV3_PTR(), f2, const int* const)
// META_HPP_CHECK_INVOCABLE(CXV3_PTR(), f3, const int*&)
// META_HPP_CHECK_INVOCABLE(CXV3_PTR(), f4, const int* const&)
// META_HPP_CHECK_INVOCABLE(CXV3_PTR(), f5, const int*&&)
// META_HPP_CHECK_INVOCABLE(CXV3_PTR(), f6, const int* const&&)
}
{
auto CXV_CPTR = []() -> const clazz* const&& { static const clazz* p{}; return std::move(p); };
auto CXV2_CPTR = []() -> const dclazz* const&& { static const dclazz* p{}; return std::move(p); };
auto CXV_CPTR = []() -> const clazz* const&& { static clazz v; static const clazz* p{&v}; return std::move(p); };
auto CXV2_CPTR = []() -> const dclazz* const&& { static dclazz v; static const dclazz* p{&v}; return std::move(p); };
auto CXV3_CPTR = []() -> const int* const&& { static int v{1}; static const int* p{&v}; return std::move(p); };
meta::detail::arg a{CXV_CPTR()};
CHECK(a.get_raw_type() == meta::resolve_type<const clazz*>());
@@ -545,14 +713,29 @@ TEST_CASE("features/meta_utilities/arg/ptrs") {
// META_HPP_CHECK_INVOCABLE(CXV2_CPTR(), f4, const clazz* const&)
// META_HPP_CHECK_INVOCABLE(CXV2_CPTR(), f5, const clazz*&&)
// META_HPP_CHECK_INVOCABLE(CXV2_CPTR(), f6, const clazz* const&&)
META_HPP_CHECK_INVOCABLE(CXV3_CPTR(), f1, int*)
META_HPP_CHECK_INVOCABLE(CXV3_CPTR(), f2, int* const)
// META_HPP_CHECK_INVOCABLE(CXV3_CPTR(), f3, int*&)
// META_HPP_CHECK_INVOCABLE(CXV3_CPTR(), f4, int* const&)
// META_HPP_CHECK_INVOCABLE(CXV3_CPTR(), f5, int*&&)
// META_HPP_CHECK_INVOCABLE(CXV3_CPTR(), f6, int* const&&)
META_HPP_CHECK_INVOCABLE(CXV3_CPTR(), f1, const int*)
META_HPP_CHECK_INVOCABLE(CXV3_CPTR(), f2, const int* const)
// META_HPP_CHECK_INVOCABLE(CXV3_CPTR(), f3, const int*&)
// META_HPP_CHECK_INVOCABLE(CXV3_CPTR(), f4, const int* const&)
// META_HPP_CHECK_INVOCABLE(CXV3_CPTR(), f5, const int*&&)
// META_HPP_CHECK_INVOCABLE(CXV3_CPTR(), f6, const int* const&&)
}
}
{
// prvalue
{
auto PRV_PTR = []() -> clazz* { static clazz* p{}; return p; };
auto PRV2_PTR = []() -> dclazz* { static dclazz* p{}; return p; };
auto PRV_PTR = []() -> clazz* { static clazz v; static clazz* p{&v}; return p; };
auto PRV2_PTR = []() -> dclazz* { static dclazz v; static dclazz* p{&v}; return p; };
auto PRV3_PTR = []() -> int* { static int v{1}; static int* p{&v}; return p; };
meta::detail::arg a{PRV_PTR()};
CHECK(a.get_raw_type() == meta::resolve_type<clazz*>());
@@ -585,10 +768,25 @@ TEST_CASE("features/meta_utilities/arg/ptrs") {
// META_HPP_CHECK_INVOCABLE(PRV2_PTR(), f4, const clazz* const&)
// META_HPP_CHECK_INVOCABLE(PRV2_PTR(), f5, const clazz*&&)
// META_HPP_CHECK_INVOCABLE(PRV2_PTR(), f6, const clazz* const&&)
META_HPP_CHECK_INVOCABLE(PRV3_PTR(), f1, int*)
META_HPP_CHECK_INVOCABLE(PRV3_PTR(), f2, int* const)
// META_HPP_CHECK_INVOCABLE(PRV3_PTR(), f3, int*&)
// META_HPP_CHECK_INVOCABLE(PRV3_PTR(), f4, int* const&)
// META_HPP_CHECK_INVOCABLE(PRV3_PTR(), f5, int*&&)
// META_HPP_CHECK_INVOCABLE(PRV3_PTR(), f6, int* const&&)
META_HPP_CHECK_INVOCABLE(PRV3_PTR(), f1, const int*)
META_HPP_CHECK_INVOCABLE(PRV3_PTR(), f2, const int* const)
// META_HPP_CHECK_INVOCABLE(PRV3_PTR(), f3, const int*&)
// META_HPP_CHECK_INVOCABLE(PRV3_PTR(), f4, const int* const&)
// META_HPP_CHECK_INVOCABLE(PRV3_PTR(), f5, const int*&&)
// META_HPP_CHECK_INVOCABLE(PRV3_PTR(), f6, const int* const&&)
}
{
auto PRV_CPTR = []() -> const clazz* { static const clazz* p{}; return p; };
auto PRV2_CPTR = []() -> const dclazz* { static const dclazz* p{}; return p; };
auto PRV_CPTR = []() -> const clazz* { static clazz v; static const clazz* p{&v}; return p; };
auto PRV2_CPTR = []() -> const dclazz* { static dclazz v; static const dclazz* p{&v}; return p; };
auto PRV3_CPTR = []() -> const int* { static int v{1}; static const int* p{&v}; return p; };
meta::detail::arg a{PRV_CPTR()};
CHECK(a.get_raw_type() == meta::resolve_type<const clazz*>());
@@ -621,6 +819,20 @@ TEST_CASE("features/meta_utilities/arg/ptrs") {
// META_HPP_CHECK_INVOCABLE(PRV2_CPTR(), f4, const clazz* const&)
// META_HPP_CHECK_INVOCABLE(PRV2_CPTR(), f5, const clazz*&&)
// META_HPP_CHECK_INVOCABLE(PRV2_CPTR(), f6, const clazz* const&&)
META_HPP_CHECK_INVOCABLE(PRV3_CPTR(), f1, int*)
META_HPP_CHECK_INVOCABLE(PRV3_CPTR(), f2, int* const)
// META_HPP_CHECK_INVOCABLE(PRV3_CPTR(), f3, int*&)
// META_HPP_CHECK_INVOCABLE(PRV3_CPTR(), f4, int* const&)
// META_HPP_CHECK_INVOCABLE(PRV3_CPTR(), f5, int*&&)
// META_HPP_CHECK_INVOCABLE(PRV3_CPTR(), f6, int* const&&)
META_HPP_CHECK_INVOCABLE(PRV3_CPTR(), f1, const int*)
META_HPP_CHECK_INVOCABLE(PRV3_CPTR(), f2, const int* const)
// META_HPP_CHECK_INVOCABLE(PRV3_CPTR(), f3, const int*&)
// META_HPP_CHECK_INVOCABLE(PRV3_CPTR(), f4, const int* const&)
// META_HPP_CHECK_INVOCABLE(PRV3_CPTR(), f5, const int*&&)
// META_HPP_CHECK_INVOCABLE(PRV3_CPTR(), f6, const int* const&&)
}
}
}
@@ -631,6 +843,7 @@ TEST_CASE("features/meta_utilities/arg/values") {
{
auto LV = []() -> meta::value& { static meta::value v{clazz{}}; return v; };
auto LV2 = []() -> meta::value& { static meta::value v{dclazz{}}; return v; };
auto LV3 = []() -> meta::value& { static meta::value v{int{1}}; return v; };
meta::detail::arg a{LV()};
CHECK(a.get_raw_type() == meta::resolve_type<clazz>());
@@ -649,11 +862,19 @@ TEST_CASE("features/meta_utilities/arg/values") {
META_HPP_CHECK_INVOCABLE_2(LV2(), f4, dclazz&, const clazz&)
META_HPP_CHECK_INVOCABLE_2(LV2(), f5, dclazz&, clazz&&)
META_HPP_CHECK_INVOCABLE_2(LV2(), f6, dclazz&, const clazz&&)
META_HPP_CHECK_INVOCABLE_2(LV3(), f1, int&, int)
META_HPP_CHECK_INVOCABLE_2(LV3(), f2, int&, const int)
META_HPP_CHECK_INVOCABLE_2(LV3(), f3, int&, int&)
META_HPP_CHECK_INVOCABLE_2(LV3(), f4, int&, const int&)
META_HPP_CHECK_INVOCABLE_2(LV3(), f5, int&, int&&)
META_HPP_CHECK_INVOCABLE_2(LV3(), f6, int&, const int&&)
}
{
auto CLV = []() -> const meta::value& { static meta::value v{clazz{}}; return v; };
auto CLV2 = []() -> const meta::value& { static meta::value v{dclazz{}}; return v; };
auto CLV3 = []() -> const meta::value& { static meta::value v{int{1}}; return v; };
meta::detail::arg a{CLV()};
CHECK(a.get_raw_type() == meta::resolve_type<clazz>());
@@ -672,11 +893,19 @@ TEST_CASE("features/meta_utilities/arg/values") {
META_HPP_CHECK_INVOCABLE_2(CLV2(), f4, const dclazz&, const clazz&)
META_HPP_CHECK_INVOCABLE_2(CLV2(), f5, const dclazz&, clazz&&)
META_HPP_CHECK_INVOCABLE_2(CLV2(), f6, const dclazz&, const clazz&&)
META_HPP_CHECK_INVOCABLE_2(CLV3(), f1, const int&, int)
META_HPP_CHECK_INVOCABLE_2(CLV3(), f2, const int&, const int)
META_HPP_CHECK_INVOCABLE_2(CLV3(), f3, const int&, int&)
META_HPP_CHECK_INVOCABLE_2(CLV3(), f4, const int&, const int&)
META_HPP_CHECK_INVOCABLE_2(CLV3(), f5, const int&, int&&)
META_HPP_CHECK_INVOCABLE_2(CLV3(), f6, const int&, const int&&)
}
{
auto XV = []() -> meta::value&& { static meta::value v{clazz{}}; return std::move(v); };
auto XV2 = []() -> meta::value&& { static meta::value v{dclazz{}}; return std::move(v); };
auto XV3 = []() -> meta::value&& { static meta::value v{int{1}}; return std::move(v); };
meta::detail::arg a{XV()};
CHECK(a.get_raw_type() == meta::resolve_type<clazz>());
@@ -695,11 +924,19 @@ TEST_CASE("features/meta_utilities/arg/values") {
META_HPP_CHECK_INVOCABLE_2(XV2(), f4, dclazz&&, const clazz&)
META_HPP_CHECK_INVOCABLE_2(XV2(), f5, dclazz&&, clazz&&)
META_HPP_CHECK_INVOCABLE_2(XV2(), f6, dclazz&&, const clazz&&)
META_HPP_CHECK_INVOCABLE_2(XV3(), f1, int&&, int)
META_HPP_CHECK_INVOCABLE_2(XV3(), f2, int&&, const int)
META_HPP_CHECK_INVOCABLE_2(XV3(), f3, int&&, int&)
META_HPP_CHECK_INVOCABLE_2(XV3(), f4, int&&, const int&)
META_HPP_CHECK_INVOCABLE_2(XV3(), f5, int&&, int&&)
META_HPP_CHECK_INVOCABLE_2(XV3(), f6, int&&, const int&&)
}
{
auto CXV = []() -> const meta::value&& { static meta::value v{clazz{}}; return std::move(v); };
auto CXV2 = []() -> const meta::value&& { static meta::value v{dclazz{}}; return std::move(v); };
auto CXV3 = []() -> const meta::value&& { static meta::value v{int{1}}; return std::move(v); };
meta::detail::arg a{CXV()};
CHECK(a.get_raw_type() == meta::resolve_type<clazz>());
@@ -718,11 +955,19 @@ TEST_CASE("features/meta_utilities/arg/values") {
META_HPP_CHECK_INVOCABLE_2(CXV2(), f4, const dclazz&&, const clazz&)
META_HPP_CHECK_INVOCABLE_2(CXV2(), f5, const dclazz&&, clazz&&)
META_HPP_CHECK_INVOCABLE_2(CXV2(), f6, const dclazz&&, const clazz&&)
META_HPP_CHECK_INVOCABLE_2(CXV3(), f1, const int&&, int)
META_HPP_CHECK_INVOCABLE_2(CXV3(), f2, const int&&, const int)
META_HPP_CHECK_INVOCABLE_2(CXV3(), f3, const int&&, int&)
META_HPP_CHECK_INVOCABLE_2(CXV3(), f4, const int&&, const int&)
META_HPP_CHECK_INVOCABLE_2(CXV3(), f5, const int&&, int&&)
META_HPP_CHECK_INVOCABLE_2(CXV3(), f6, const int&&, const int&&)
}
{
auto PRV = []() -> meta::value { return meta::value{clazz{}}; };
auto PRV2 = []() -> meta::value { return meta::value{dclazz{}}; };
auto PRV3 = []() -> meta::value { return meta::value{int{1}}; };
meta::detail::arg a{PRV()};
CHECK(a.get_raw_type() == meta::resolve_type<clazz>());
@@ -741,11 +986,19 @@ TEST_CASE("features/meta_utilities/arg/values") {
META_HPP_CHECK_INVOCABLE_2(PRV2(), f4, dclazz, const clazz&)
META_HPP_CHECK_INVOCABLE_2(PRV2(), f5, dclazz, clazz&&)
META_HPP_CHECK_INVOCABLE_2(PRV2(), f6, dclazz, const clazz&&)
META_HPP_CHECK_INVOCABLE_2(PRV3(), f1, int, int)
META_HPP_CHECK_INVOCABLE_2(PRV3(), f2, int, const int)
META_HPP_CHECK_INVOCABLE_2(PRV3(), f3, int, int&)
META_HPP_CHECK_INVOCABLE_2(PRV3(), f4, int, const int&)
META_HPP_CHECK_INVOCABLE_2(PRV3(), f5, int, int&&)
META_HPP_CHECK_INVOCABLE_2(PRV3(), f6, int, const int&&)
}
{
auto CPRV = []() -> const meta::value { return meta::value{clazz{}}; };
auto CPRV2 = []() -> const meta::value { return meta::value{dclazz{}}; };
auto CPRV3 = []() -> const meta::value { return meta::value{int{1}}; };
meta::detail::arg a{CPRV()};
CHECK(a.get_raw_type() == meta::resolve_type<clazz>());
@@ -764,6 +1017,13 @@ TEST_CASE("features/meta_utilities/arg/values") {
META_HPP_CHECK_INVOCABLE_2(CPRV2(), f4, const dclazz, const clazz&)
META_HPP_CHECK_INVOCABLE_2(CPRV2(), f5, const dclazz, clazz&&)
META_HPP_CHECK_INVOCABLE_2(CPRV2(), f6, const dclazz, const clazz&&)
META_HPP_CHECK_INVOCABLE_2(CPRV3(), f1, const int, int)
META_HPP_CHECK_INVOCABLE_2(CPRV3(), f2, const int, const int)
META_HPP_CHECK_INVOCABLE_2(CPRV3(), f3, const int, int&)
META_HPP_CHECK_INVOCABLE_2(CPRV3(), f4, const int, const int&)
META_HPP_CHECK_INVOCABLE_2(CPRV3(), f5, const int, int&&)
META_HPP_CHECK_INVOCABLE_2(CPRV3(), f6, const int, const int&&)
}
}
@@ -771,8 +1031,8 @@ TEST_CASE("features/meta_utilities/arg/ptr_values") {
namespace meta = meta_hpp;
{
auto LV_PTR = []() -> meta::value& { static clazz* p{}; static meta::value v{p}; return v; };
auto LV2_PTR = []() -> meta::value& { static dclazz* p{}; static meta::value v{p}; return v; };
auto LV_PTR = []() -> meta::value& { static clazz v; static clazz* p{&v}; static meta::value vv{p}; return vv; };
auto LV2_PTR = []() -> meta::value& { static dclazz v; static dclazz* p{&v}; static meta::value vv{p}; return vv; };
meta::detail::arg a{LV_PTR()};
CHECK(a.get_raw_type() == meta::resolve_type<clazz*>());
@@ -808,8 +1068,8 @@ TEST_CASE("features/meta_utilities/arg/ptr_values") {
}
{
auto LV_CPTR = []() -> meta::value& { static const clazz* p{}; static meta::value v{p}; return v; };
auto LV2_CPTR = []() -> meta::value& { static const dclazz* p{}; static meta::value v{p}; return v; };
auto LV_CPTR = []() -> meta::value& { static clazz v; static const clazz* p{&v}; static meta::value vv{p}; return vv; };
auto LV2_CPTR = []() -> meta::value& { static dclazz v; static const dclazz* p{&v}; static meta::value vv{p}; return vv; };
meta::detail::arg a{LV_CPTR()};
CHECK(a.get_raw_type() == meta::resolve_type<const clazz*>());
@@ -845,8 +1105,8 @@ TEST_CASE("features/meta_utilities/arg/ptr_values") {
}
{
auto CLV_PTR = []() -> const meta::value& { static clazz* p{}; static meta::value v{p}; return v; };
auto CLV2_PTR = []() -> const meta::value& { static dclazz* p{}; static meta::value v{p}; return v; };
auto CLV_PTR = []() -> const meta::value& { static clazz v; static clazz* p{&v}; static meta::value vv{p}; return vv; };
auto CLV2_PTR = []() -> const meta::value& { static dclazz v; static dclazz* p{&v}; static meta::value vv{p}; return vv; };
meta::detail::arg a{CLV_PTR()};
CHECK(a.get_raw_type() == meta::resolve_type<clazz*>());
@@ -882,8 +1142,8 @@ TEST_CASE("features/meta_utilities/arg/ptr_values") {
}
{
auto CLV_CPTR = []() -> const meta::value& { static const clazz* p{}; static meta::value v{p}; return v; };
auto CLV2_CPTR = []() -> const meta::value& { static const dclazz* p{}; static meta::value v{p}; return v; };
auto CLV_CPTR = []() -> const meta::value& { static clazz v; static const clazz* p{&v}; static meta::value vv{p}; return vv; };
auto CLV2_CPTR = []() -> const meta::value& { static dclazz v; static const dclazz* p{&v}; static meta::value vv{p}; return vv; };
meta::detail::arg a{CLV_CPTR()};
CHECK(a.get_raw_type() == meta::resolve_type<const clazz*>());
@@ -919,8 +1179,8 @@ TEST_CASE("features/meta_utilities/arg/ptr_values") {
}
{
auto XV_PTR = []() -> meta::value&& { static clazz* p{}; static meta::value v{std::move(p)}; return std::move(v); };
auto XV2_PTR = []() -> meta::value&& { static dclazz* p{}; static meta::value v{std::move(p)}; return std::move(v); };
auto XV_PTR = []() -> meta::value&& { static clazz v; static clazz* p{&v}; static meta::value vv{std::move(p)}; return std::move(vv); };
auto XV2_PTR = []() -> meta::value&& { static dclazz v; static dclazz* p{&v}; static meta::value vv{std::move(p)}; return std::move(vv); };
meta::detail::arg a{XV_PTR()};
CHECK(a.get_raw_type() == meta::resolve_type<clazz*>());
@@ -956,8 +1216,8 @@ TEST_CASE("features/meta_utilities/arg/ptr_values") {
}
{
auto XV_CPTR = []() -> meta::value&& { static const clazz* p{}; static meta::value v{std::move(p)}; return std::move(v); };
auto XV2_CPTR = []() -> meta::value&& { static const dclazz* p{}; static meta::value v{std::move(p)}; return std::move(v); };
auto XV_CPTR = []() -> meta::value&& { static clazz v; static const clazz* p{&v}; static meta::value vv{std::move(p)}; return std::move(vv); };
auto XV2_CPTR = []() -> meta::value&& { static dclazz v; static const dclazz* p{&v}; static meta::value vv{std::move(p)}; return std::move(vv); };
meta::detail::arg a{XV_CPTR()};
CHECK(a.get_raw_type() == meta::resolve_type<const clazz*>());
@@ -993,8 +1253,8 @@ TEST_CASE("features/meta_utilities/arg/ptr_values") {
}
{
auto CXV_PTR = []() -> const meta::value&& { static clazz* p{}; static meta::value v{std::move(p)}; return std::move(v); };
auto CXV2_PTR = []() -> const meta::value&& { static dclazz* p{}; static meta::value v{std::move(p)}; return std::move(v); };
auto CXV_PTR = []() -> const meta::value&& { static clazz v; static clazz* p{&v}; static meta::value vv{std::move(p)}; return std::move(vv); };
auto CXV2_PTR = []() -> const meta::value&& { static dclazz v; static dclazz* p{&v}; static meta::value vv{std::move(p)}; return std::move(vv); };
meta::detail::arg a{CXV_PTR()};
CHECK(a.get_raw_type() == meta::resolve_type<clazz*>());
@@ -1030,8 +1290,8 @@ TEST_CASE("features/meta_utilities/arg/ptr_values") {
}
{
auto CXV_CPTR = []() -> const meta::value&& { static const clazz* p{}; static meta::value v{std::move(p)}; return std::move(v); };
auto CXV2_CPTR = []() -> const meta::value&& { static const dclazz* p{}; static meta::value v{std::move(p)}; return std::move(v); };
auto CXV_CPTR = []() -> const meta::value&& { static clazz v; static const clazz* p{&v}; static meta::value vv{std::move(p)}; return std::move(vv); };
auto CXV2_CPTR = []() -> const meta::value&& { static dclazz v; static const dclazz* p{&v}; static meta::value vv{std::move(p)}; return std::move(vv); };
meta::detail::arg a{CXV_CPTR()};
CHECK(a.get_raw_type() == meta::resolve_type<const clazz*>());
@@ -1067,8 +1327,8 @@ TEST_CASE("features/meta_utilities/arg/ptr_values") {
}
{
auto PRV_PTR = []() -> meta::value { static clazz* p{}; static meta::value v{p}; return v; };
auto PRV2_PTR = []() -> meta::value { static dclazz* p{}; static meta::value v{p}; return v; };
auto PRV_PTR = []() -> meta::value { static clazz v; static clazz* p{&v}; static meta::value vv{p}; return vv; };
auto PRV2_PTR = []() -> meta::value { static dclazz v; static dclazz* p{&v}; static meta::value vv{p}; return vv; };
meta::detail::arg a{PRV_PTR()};
CHECK(a.get_raw_type() == meta::resolve_type<clazz*>());
@@ -1104,8 +1364,8 @@ TEST_CASE("features/meta_utilities/arg/ptr_values") {
}
{
auto PRV_CPTR = []() -> meta::value { static const clazz* p{}; static meta::value v{p}; return v; };
auto PRV2_CPTR = []() -> meta::value { static const dclazz* p{}; static meta::value v{p}; return v; };
auto PRV_CPTR = []() -> meta::value { static clazz v; static const clazz* p{&v}; static meta::value vv{p}; return vv; };
auto PRV2_CPTR = []() -> meta::value { static dclazz v; static const dclazz* p{&v}; static meta::value vv{p}; return vv; };
meta::detail::arg a{PRV_CPTR()};
CHECK(a.get_raw_type() == meta::resolve_type<const clazz*>());
@@ -1141,8 +1401,8 @@ TEST_CASE("features/meta_utilities/arg/ptr_values") {
}
{
auto CPRV_PTR = []() -> const meta::value { static clazz* p{}; static meta::value v{p}; return v; };
auto CPRV2_PTR = []() -> const meta::value { static dclazz* p{}; static meta::value v{p}; return v; };
auto CPRV_PTR = []() -> const meta::value { static clazz v; static clazz* p{&v}; static meta::value vv{p}; return vv; };
auto CPRV2_PTR = []() -> const meta::value { static dclazz v; static dclazz* p{&v}; static meta::value vv{p}; return vv; };
meta::detail::arg a{CPRV_PTR()};
CHECK(a.get_raw_type() == meta::resolve_type<clazz*>());
@@ -1178,8 +1438,8 @@ TEST_CASE("features/meta_utilities/arg/ptr_values") {
}
{
auto CPRV_CPTR = []() -> const meta::value { static const clazz* p{}; static meta::value v{p}; return v; };
auto CPRV2_CPTR = []() -> const meta::value { static const dclazz* p{}; static meta::value v{p}; return v; };
auto CPRV_CPTR = []() -> const meta::value { static clazz v; static const clazz* p{&v}; static meta::value vv{p}; return vv; };
auto CPRV2_CPTR = []() -> const meta::value { static dclazz v; static const dclazz* p{&v}; static meta::value vv{p}; return vv; };
meta::detail::arg a{CPRV_CPTR()};
CHECK(a.get_raw_type() == meta::resolve_type<const clazz*>());

View File

@@ -8,18 +8,24 @@
namespace
{
struct clazz {
int m1() { return 1; }
int m2() & { return 1; }
int m3() && { return 1; }
int m4() const { return 1; }
int m5() const & { return 1; }
int m6() const && { return 1; }
struct fake {
int i = 10;
};
struct dclazz : clazz {};
struct clazz {
int ii = 1;
[[nodiscard]] int m1() { return ii; }
[[nodiscard]] int m2() & { return ii; }
[[nodiscard]] int m3() && { return ii; }
[[nodiscard]] int m4() const { return ii; }
[[nodiscard]] int m5() const & { return ii; }
[[nodiscard]] int m6() const && { return ii; }
};
struct dclazz : fake, clazz {};
}
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define META_HPP_CHECK_INVOCABLE(Inst, FName, Qualifiers)\
{\
using namespace meta::detail;\
@@ -29,20 +35,21 @@ namespace
if ( std::is_invocable_v<decltype(method_ptr), decltype(Inst)> ) {\
CHECK(inst{Inst}.can_cast_to<clazz Qualifiers>());\
CHECK(inst_base{type_list<decltype(Inst)>{}}.can_cast_to<clazz Qualifiers>());\
CHECK_NOTHROW(inst{Inst}.cast<clazz Qualifiers>());\
CHECK_NOTHROW(std::ignore = inst{Inst}.cast<clazz Qualifiers>());\
\
CHECK(m_state.is_invocable_with<decltype(Inst)>());\
CHECK(m_state.invoke(Inst) == 1);\
} else {\
CHECK_FALSE(inst{Inst}.can_cast_to<clazz Qualifiers>());\
CHECK_FALSE(inst_base{type_list<decltype(Inst)>{}}.can_cast_to<clazz Qualifiers>());\
CHECK_THROWS(inst{Inst}.cast<clazz Qualifiers>());\
CHECK_THROWS(std::ignore = inst{Inst}.cast<clazz Qualifiers>());\
\
CHECK_FALSE(m_state.is_invocable_with<decltype(Inst)>());\
CHECK_THROWS(m_state.invoke(Inst));\
}\
}
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define META_HPP_CHECK_INVOCABLE_2(FromValue, FName, FromType, ToQualifiers)\
{\
using namespace meta::detail;\
@@ -63,8 +70,9 @@ namespace
TEST_CASE("features/meta_utilities/inst2") {
namespace meta = meta_hpp;
meta::class_<dclazz>()
.base_<clazz>();
meta::class_<fake>();
meta::class_<clazz>();
meta::class_<dclazz>().base_<fake>().base_<clazz>();
}
TEST_CASE("features/meta_utilities/inst2/refs") {