diff --git a/untests/meta_features/diamond_tests.cpp b/untests/meta_features/diamond_tests.cpp new file mode 100644 index 0000000..008a5ca --- /dev/null +++ b/untests/meta_features/diamond_tests.cpp @@ -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_(); + meta::class_().base_(); + meta::class_().base_(); + meta::class_().base_().base_(); + meta::class_(); + + // * <- B <- * + // A D + // * <- C <- * + + const meta::class_type A_type = meta::resolve_type(); + const meta::class_type B_type = meta::resolve_type(); + const meta::class_type C_type = meta::resolve_type(); + const meta::class_type D_type = meta::resolve_type(); + const meta::class_type E_type = meta::resolve_type(); + + 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); + CHECK_FALSE(meta::pointer_upcast(&a)); + CHECK_FALSE(meta::pointer_upcast(&a)); + CHECK_FALSE(meta::pointer_upcast(&a)); + CHECK_FALSE(meta::pointer_upcast(&a)); + } + { + B b; + CHECK(meta::pointer_upcast(&b) == &b); + CHECK(meta::pointer_upcast(&b) == &b); + CHECK_FALSE(meta::pointer_upcast(&b)); + CHECK_FALSE(meta::pointer_upcast(&b)); + CHECK_FALSE(meta::pointer_upcast(&b)); + } + { + C c; + CHECK(meta::pointer_upcast(&c) == &c); + CHECK_FALSE(meta::pointer_upcast(&c)); + CHECK(meta::pointer_upcast(&c) == &c); + CHECK_FALSE(meta::pointer_upcast(&c)); + CHECK_FALSE(meta::pointer_upcast(&c)); + } + { + D d; + CHECK(meta::pointer_upcast(&d) == &d); + CHECK(meta::pointer_upcast(&d) == &d); + CHECK(meta::pointer_upcast(&d) == &d); + CHECK(meta::pointer_upcast(&d) == &d); + CHECK_FALSE(meta::pointer_upcast(&d)); + } + { + E e; + CHECK_FALSE(meta::pointer_upcast(&e)); + CHECK_FALSE(meta::pointer_upcast(&e)); + CHECK_FALSE(meta::pointer_upcast(&e)); + CHECK_FALSE(meta::pointer_upcast(&e)); + CHECK(meta::pointer_upcast(&e) == &e); + } + } + + SUBCASE("arg/cast") { + { + A a; + meta::value a_val{&a}; + CHECK(*static_cast(a_val.data()) == &a); + + meta::detail::arg a_arg{a_val}; + + CHECK(a_arg.can_cast_to()); + CHECK(!a_arg.can_cast_to()); + CHECK(!a_arg.can_cast_to()); + CHECK(!a_arg.can_cast_to()); + CHECK(!a_arg.can_cast_to()); + + CHECK(a_arg.cast() == static_cast(&a)); + } + { + B b; + meta::value b_val{&b}; + CHECK(*static_cast(b_val.data()) == &b); + + meta::detail::arg b_arg{b_val}; + + CHECK(b_arg.can_cast_to()); + CHECK(b_arg.can_cast_to()); + CHECK(!b_arg.can_cast_to()); + CHECK(!b_arg.can_cast_to()); + CHECK(!b_arg.can_cast_to()); + + CHECK(b_arg.cast() == static_cast(&b)); + CHECK(b_arg.cast() == static_cast(&b)); + } + { + C c; + meta::value c_val{&c}; + CHECK(*static_cast(c_val.data()) == &c); + + meta::detail::arg c_arg{c_val}; + + CHECK(c_arg.can_cast_to()); + CHECK(!c_arg.can_cast_to()); + CHECK(c_arg.can_cast_to()); + CHECK(!c_arg.can_cast_to()); + CHECK(!c_arg.can_cast_to()); + + CHECK(c_arg.cast() == static_cast(&c)); + CHECK(c_arg.cast() == static_cast(&c)); + } + { + D d; + meta::value d_val{&d}; + CHECK(*static_cast(d_val.data()) == &d); + + meta::detail::arg d_arg{d_val}; + + CHECK(d_arg.can_cast_to()); + CHECK(d_arg.can_cast_to()); + CHECK(d_arg.can_cast_to()); + CHECK(d_arg.can_cast_to()); + CHECK(!d_arg.can_cast_to()); + + CHECK(d_arg.cast() == static_cast(&d)); + CHECK(d_arg.cast() == static_cast(&d)); + CHECK(d_arg.cast() == static_cast(&d)); + CHECK(d_arg.cast() == static_cast(&d)); + } + { + E e; + meta::value e_val{&e}; + CHECK(*static_cast(e_val.data()) == &e); + + meta::detail::arg e_arg{e_val}; + + CHECK(!e_arg.can_cast_to()); + CHECK(!e_arg.can_cast_to()); + CHECK(!e_arg.can_cast_to()); + CHECK(!e_arg.can_cast_to()); + CHECK(e_arg.can_cast_to()); + + CHECK(e_arg.cast() == static_cast(&e)); + } + } + + SUBCASE("inst/cast") { + { + meta::value a_val{A{}}; + meta::detail::inst a_inst{a_val}; + + CHECK(a_inst.can_cast_to()); + CHECK_FALSE(a_inst.can_cast_to()); + CHECK_FALSE(a_inst.can_cast_to()); + CHECK_FALSE(a_inst.can_cast_to()); + CHECK_FALSE(a_inst.can_cast_to()); + + CHECK(&a_inst.cast() == a_val.try_cast()); + } + { + meta::value b_val{B{}}; + meta::detail::inst b_inst{b_val}; + + CHECK(b_inst.can_cast_to()); + CHECK(b_inst.can_cast_to()); + CHECK_FALSE(b_inst.can_cast_to()); + CHECK_FALSE(b_inst.can_cast_to()); + CHECK_FALSE(b_inst.can_cast_to()); + + CHECK(&b_inst.cast() == b_val.try_cast()); + CHECK(&b_inst.cast() == b_val.try_cast()); + + CHECK(&b_inst.cast() == b_val.try_cast()); + } + { + meta::value c_val{C{}}; + meta::detail::inst c_inst{c_val}; + + CHECK(c_inst.can_cast_to()); + CHECK_FALSE(c_inst.can_cast_to()); + CHECK(c_inst.can_cast_to()); + CHECK_FALSE(c_inst.can_cast_to()); + CHECK_FALSE(c_inst.can_cast_to()); + + CHECK(&c_inst.cast() == c_val.try_cast()); + CHECK(&c_inst.cast() == c_val.try_cast()); + } + { + meta::value d_val{D{}}; + meta::detail::inst d_inst{d_val}; + + CHECK(d_inst.can_cast_to()); + CHECK(d_inst.can_cast_to()); + CHECK(d_inst.can_cast_to()); + CHECK(d_inst.can_cast_to()); + CHECK_FALSE(d_inst.can_cast_to()); + + CHECK(&d_inst.cast() == d_val.try_cast()); + CHECK(&d_inst.cast() == d_val.try_cast()); + CHECK(&d_inst.cast() == d_val.try_cast()); + CHECK(&d_inst.cast() == d_val.try_cast()); + + CHECK(&d_inst.cast() == d_val.try_cast()); + CHECK(&d_inst.cast() == d_val.try_cast()); + CHECK(&d_inst.cast() == d_val.try_cast()); + CHECK(&d_inst.cast() == d_val.try_cast()); + } + { + meta::value e_val{E{}}; + meta::detail::inst e_inst{e_val}; + + CHECK_FALSE(e_inst.can_cast_to()); + CHECK_FALSE(e_inst.can_cast_to()); + CHECK_FALSE(e_inst.can_cast_to()); + CHECK_FALSE(e_inst.can_cast_to()); + CHECK(e_inst.can_cast_to()); + + CHECK(&e_inst.cast() == e_val.try_cast()); + } + } +} diff --git a/untests/meta_utilities/arg2_tests.cpp b/untests/meta_utilities/arg2_tests.cpp new file mode 100644 index 0000000..74e6289 --- /dev/null +++ b/untests/meta_utilities/arg2_tests.cpp @@ -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_(); + meta::class_().base_(); + meta::class_().base_(); + meta::class_().base_().base_(); +} + +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()); + CHECK(arg{LV()}.can_cast_to()); + CHECK(arg{LV()}.can_cast_to()); + CHECK(arg{LV()}.can_cast_to()); + CHECK_FALSE(arg{LV()}.can_cast_to()); + CHECK_FALSE(arg{LV()}.can_cast_to()); + + CHECK(A::copy_ctors_ == 0); + CHECK(A::move_ctors_ == 0); + + CHECK(arg{LV()}.cast().f() == 1); + CHECK(arg{LV()}.cast().f() == 1); + CHECK(arg{LV()}.cast().f() == 1); + CHECK(arg{LV()}.cast().f() == 1); + CHECK_THROWS(std::ignore = arg{LV()}.cast()); + CHECK_THROWS(std::ignore = arg{LV()}.cast()); + + CHECK(A::copy_ctors_ == 2); + CHECK(A::move_ctors_ == 0); + } + + SUBCASE("CLV") { + CHECK(arg{CLV()}.can_cast_to()); + CHECK(arg{CLV()}.can_cast_to()); + CHECK_FALSE(arg{CLV()}.can_cast_to()); + CHECK(arg{CLV()}.can_cast_to()); + CHECK_FALSE(arg{CLV()}.can_cast_to()); + CHECK_FALSE(arg{CLV()}.can_cast_to()); + + CHECK(A::copy_ctors_ == 0); + CHECK(A::move_ctors_ == 0); + + CHECK(arg{CLV()}.cast().f() == 1); + CHECK(arg{CLV()}.cast().f() == 1); + CHECK_THROWS(std::ignore = arg{CLV()}.cast()); + CHECK(arg{CLV()}.cast().f() == 1); + CHECK_THROWS(std::ignore = arg{CLV()}.cast()); + CHECK_THROWS(std::ignore = arg{CLV()}.cast()); + + CHECK(A::copy_ctors_ == 2); + CHECK(A::move_ctors_ == 0); + } + + SUBCASE("XV") { + CHECK(arg{XV()}.can_cast_to()); + CHECK(arg{XV()}.can_cast_to()); + CHECK_FALSE(arg{XV()}.can_cast_to()); + CHECK(arg{XV()}.can_cast_to()); + CHECK(arg{XV()}.can_cast_to()); + CHECK(arg{XV()}.can_cast_to()); + + CHECK(A::copy_ctors_ == 0); + CHECK(A::move_ctors_ == 0); + + CHECK(arg{XV()}.cast().f() == 1); + CHECK(arg{XV()}.cast().f() == 1); + CHECK_THROWS(std::ignore = arg{XV()}.cast()); + CHECK(arg{XV()}.cast().f() == 1); + CHECK(arg{XV()}.cast().f() == 1); + CHECK(arg{XV()}.cast().f() == 1); + + CHECK(A::copy_ctors_ == 0); + CHECK(A::move_ctors_ == 2); + } + + SUBCASE("CXV") { + CHECK(arg{CXV()}.can_cast_to()); + CHECK(arg{CXV()}.can_cast_to()); + CHECK_FALSE(arg{CXV()}.can_cast_to()); + CHECK(arg{CXV()}.can_cast_to()); + CHECK_FALSE(arg{CXV()}.can_cast_to()); + CHECK(arg{CXV()}.can_cast_to()); + + CHECK(A::copy_ctors_ == 0); + CHECK(A::move_ctors_ == 0); + + CHECK(arg{CXV()}.cast().f() == 1); + CHECK(arg{CXV()}.cast().f() == 1); + CHECK_THROWS(std::ignore = arg{CXV()}.cast()); + CHECK(arg{CXV()}.cast().f() == 1); + CHECK_THROWS(std::ignore = arg{CXV()}.cast()); + CHECK(arg{CXV()}.cast().f() == 1); + + CHECK(A::copy_ctors_ == 2); + CHECK(A::move_ctors_ == 0); + } + + SUBCASE("PRV") { + CHECK(arg{PRV()}.can_cast_to()); + CHECK(arg{PRV()}.can_cast_to()); + CHECK_FALSE(arg{PRV()}.can_cast_to()); + CHECK(arg{PRV()}.can_cast_to()); + CHECK(arg{PRV()}.can_cast_to()); + CHECK(arg{PRV()}.can_cast_to()); + + CHECK(A::copy_ctors_ == 0); + CHECK(A::move_ctors_ == 0); + + CHECK(arg{PRV()}.cast().f() == 1); + CHECK(arg{PRV()}.cast().f() == 1); + CHECK_THROWS(std::ignore = arg{PRV()}.cast()); + CHECK(arg{PRV()}.cast().f() == 1); + CHECK(arg{PRV()}.cast().f() == 1); + CHECK(arg{PRV()}.cast().f() == 1); + + CHECK(A::copy_ctors_ == 0); + CHECK(A::move_ctors_ == 2); + } + + SUBCASE("CPRV") { + CHECK(arg{CPRV()}.can_cast_to()); + CHECK(arg{CPRV()}.can_cast_to()); + CHECK_FALSE(arg{CPRV()}.can_cast_to()); + CHECK(arg{CPRV()}.can_cast_to()); + CHECK_FALSE(arg{CPRV()}.can_cast_to()); + CHECK(arg{CPRV()}.can_cast_to()); + + CHECK(A::copy_ctors_ == 0); + CHECK(A::move_ctors_ == 0); + + CHECK(arg{CPRV()}.cast().f() == 1); + CHECK(arg{CPRV()}.cast().f() == 1); + CHECK_THROWS(std::ignore = arg{CPRV()}.cast()); + CHECK(arg{CPRV()}.cast().f() == 1); + CHECK_THROWS(std::ignore = arg{CPRV()}.cast()); + CHECK(arg{CPRV()}.cast().f() == 1); + + CHECK(A::copy_ctors_ == 2); + CHECK(A::move_ctors_ == 0); + } + + SUBCASE("LV_PTR") { + CHECK(arg{LV_PTR()}.can_cast_to()); + CHECK(arg{LV_PTR()}.can_cast_to()); + CHECK(arg{LV_PTR()}.can_cast_to()); + CHECK(arg{LV_PTR()}.can_cast_to()); + + CHECK(arg{LV_PTR()}.cast()->f() == 1); + CHECK(arg{LV_PTR()}.cast()->f() == 1); + CHECK(arg{LV_PTR()}.cast()->f() == 1); + CHECK(arg{LV_PTR()}.cast()->f() == 1); + } + + SUBCASE("LV_CPTR") { + CHECK_FALSE(arg{LV_CPTR()}.can_cast_to()); + CHECK_FALSE(arg{LV_CPTR()}.can_cast_to()); + CHECK(arg{LV_CPTR()}.can_cast_to()); + CHECK(arg{LV_CPTR()}.can_cast_to()); + + CHECK_THROWS(std::ignore = arg{LV_CPTR()}.cast()); + CHECK_THROWS(std::ignore = arg{LV_CPTR()}.cast()); + CHECK(arg{LV_CPTR()}.cast()->f() == 1); + CHECK(arg{LV_CPTR()}.cast()->f() == 1); + } + + SUBCASE("CLV_PTR") { + CHECK(arg{CLV_PTR()}.can_cast_to()); + CHECK(arg{CLV_PTR()}.can_cast_to()); + CHECK(arg{CLV_PTR()}.can_cast_to()); + CHECK(arg{CLV_PTR()}.can_cast_to()); + + CHECK(arg{CLV_PTR()}.cast()->f() == 1); + CHECK(arg{CLV_PTR()}.cast()->f() == 1); + CHECK(arg{CLV_PTR()}.cast()->f() == 1); + CHECK(arg{CLV_PTR()}.cast()->f() == 1); + } + + SUBCASE("CLV_CPTR") { + CHECK_FALSE(arg{CLV_CPTR()}.can_cast_to()); + CHECK_FALSE(arg{CLV_CPTR()}.can_cast_to()); + CHECK(arg{CLV_CPTR()}.can_cast_to()); + CHECK(arg{CLV_CPTR()}.can_cast_to()); + + CHECK_THROWS(std::ignore = arg{CLV_CPTR()}.cast()); + CHECK_THROWS(std::ignore = arg{CLV_CPTR()}.cast()); + CHECK(arg{CLV_CPTR()}.cast()->f() == 1); + CHECK(arg{CLV_CPTR()}.cast()->f() == 1); + } + + SUBCASE("XV_PTR") { + CHECK(arg{XV_PTR()}.can_cast_to()); + CHECK(arg{XV_PTR()}.can_cast_to()); + CHECK(arg{XV_PTR()}.can_cast_to()); + CHECK(arg{XV_PTR()}.can_cast_to()); + + CHECK(arg{XV_PTR()}.cast()->f() == 1); + CHECK(arg{XV_PTR()}.cast()->f() == 1); + CHECK(arg{XV_PTR()}.cast()->f() == 1); + CHECK(arg{XV_PTR()}.cast()->f() == 1); + } + + SUBCASE("XV_CPTR") { + CHECK_FALSE(arg{XV_CPTR()}.can_cast_to()); + CHECK_FALSE(arg{XV_CPTR()}.can_cast_to()); + CHECK(arg{XV_CPTR()}.can_cast_to()); + CHECK(arg{XV_CPTR()}.can_cast_to()); + + CHECK_THROWS(std::ignore = arg{XV_CPTR()}.cast()); + CHECK_THROWS(std::ignore = arg{XV_CPTR()}.cast()); + CHECK(arg{XV_CPTR()}.cast()->f() == 1); + CHECK(arg{XV_CPTR()}.cast()->f() == 1); + } + + SUBCASE("CXV_PTR") { + CHECK(arg{CXV_PTR()}.can_cast_to()); + CHECK(arg{CXV_PTR()}.can_cast_to()); + CHECK(arg{CXV_PTR()}.can_cast_to()); + CHECK(arg{CXV_PTR()}.can_cast_to()); + + CHECK(arg{CXV_PTR()}.cast()->f() == 1); + CHECK(arg{CXV_PTR()}.cast()->f() == 1); + CHECK(arg{CXV_PTR()}.cast()->f() == 1); + CHECK(arg{CXV_PTR()}.cast()->f() == 1); + } + + SUBCASE("CXV_CPTR") { + CHECK_FALSE(arg{CXV_CPTR()}.can_cast_to()); + CHECK_FALSE(arg{CXV_CPTR()}.can_cast_to()); + CHECK(arg{CXV_CPTR()}.can_cast_to()); + CHECK(arg{CXV_CPTR()}.can_cast_to()); + + CHECK_THROWS(std::ignore = arg{CXV_CPTR()}.cast()); + CHECK_THROWS(std::ignore = arg{CXV_CPTR()}.cast()); + CHECK(arg{CXV_CPTR()}.cast()->f() == 1); + CHECK(arg{CXV_CPTR()}.cast()->f() == 1); + } + + SUBCASE("PRV_PTR") { + CHECK(arg{PRV_PTR()}.can_cast_to()); + CHECK(arg{PRV_PTR()}.can_cast_to()); + CHECK(arg{PRV_PTR()}.can_cast_to()); + CHECK(arg{PRV_PTR()}.can_cast_to()); + + CHECK(arg{PRV_PTR()}.cast()->f() == 1); + CHECK(arg{PRV_PTR()}.cast()->f() == 1); + CHECK(arg{PRV_PTR()}.cast()->f() == 1); + CHECK(arg{PRV_PTR()}.cast()->f() == 1); + } + + SUBCASE("PRV_CPTR") { + CHECK_FALSE(arg{PRV_CPTR()}.can_cast_to()); + CHECK_FALSE(arg{PRV_CPTR()}.can_cast_to()); + CHECK(arg{PRV_CPTR()}.can_cast_to()); + CHECK(arg{PRV_CPTR()}.can_cast_to()); + + CHECK_THROWS(std::ignore = arg{PRV_CPTR()}.cast()); + CHECK_THROWS(std::ignore = arg{PRV_CPTR()}.cast()); + CHECK(arg{PRV_CPTR()}.cast()->f() == 1); + CHECK(arg{PRV_CPTR()}.cast()->f() == 1); + } +} diff --git a/untests/meta_utilities/arg3_tests.cpp b/untests/meta_utilities/arg3_tests.cpp new file mode 100644 index 0000000..0506a36 --- /dev/null +++ b/untests/meta_utilities/arg3_tests.cpp @@ -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_(); + meta::class_().base_(); + meta::class_().base_(); + meta::class_().base_().base_(); +} + +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()); + CHECK_FALSE(arg{LV()}.can_cast_to()); + + CHECK_THROWS(std::ignore = arg{LV()}.cast()); + CHECK_THROWS(std::ignore = arg{LV()}.cast()); + } + + SUBCASE("CLV") { + CHECK_FALSE(arg{CLV()}.can_cast_to()); + CHECK_FALSE(arg{CLV()}.can_cast_to()); + + CHECK_THROWS(std::ignore = arg{CLV()}.cast()); + CHECK_THROWS(std::ignore = arg{CLV()}.cast()); + } + + SUBCASE("XV") { + CHECK_FALSE(arg{XV()}.can_cast_to()); + CHECK_FALSE(arg{XV()}.can_cast_to()); + + CHECK_THROWS(std::ignore = arg{XV()}.cast()); + CHECK_THROWS(std::ignore = arg{XV()}.cast()); + } + + SUBCASE("CXV") { + CHECK_FALSE(arg{CXV()}.can_cast_to()); + CHECK_FALSE(arg{CXV()}.can_cast_to()); + + CHECK_THROWS(std::ignore = arg{CXV()}.cast()); + CHECK_THROWS(std::ignore = arg{CXV()}.cast()); + } + + SUBCASE("PRV") { + CHECK_FALSE(arg{PRV()}.can_cast_to()); + CHECK_FALSE(arg{PRV()}.can_cast_to()); + + CHECK_THROWS(std::ignore = arg{PRV()}.cast()); + CHECK_THROWS(std::ignore = arg{PRV()}.cast()); + } + + SUBCASE("CPRV") { + CHECK_FALSE(arg{CPRV()}.can_cast_to()); + CHECK_FALSE(arg{CPRV()}.can_cast_to()); + + CHECK_THROWS(std::ignore = arg{CPRV()}.cast()); + CHECK_THROWS(std::ignore = arg{CPRV()}.cast()); + } +} diff --git a/untests/meta_utilities/arg4_tests.cpp b/untests/meta_utilities/arg4_tests.cpp new file mode 100644 index 0000000..51ea113 --- /dev/null +++ b/untests/meta_utilities/arg4_tests.cpp @@ -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()); + CHECK(arg{LV_PTR()}.can_cast_to()); + CHECK(arg{LV_PTR()}.can_cast_to()); + CHECK(arg{LV_PTR()}.can_cast_to()); + + CHECK(*arg{LV_PTR()}.cast() == 42); + CHECK(*arg{LV_PTR()}.cast() == 42); + CHECK(*arg{LV_PTR()}.cast() == 42); + CHECK(*arg{LV_PTR()}.cast() == 42); + } + + SUBCASE("CLV_PTR") { + CHECK(arg{CLV_PTR()}.can_cast_to()); + CHECK(arg{CLV_PTR()}.can_cast_to()); + CHECK(arg{CLV_PTR()}.can_cast_to()); + CHECK(arg{CLV_PTR()}.can_cast_to()); + + CHECK(*arg{CLV_PTR()}.cast() == 42); + CHECK(*arg{CLV_PTR()}.cast() == 42); + CHECK(*arg{CLV_PTR()}.cast() == 42); + CHECK(*arg{CLV_PTR()}.cast() == 42); + } + + SUBCASE("XV_PTR") { + CHECK(arg{XV_PTR()}.can_cast_to()); + CHECK(arg{XV_PTR()}.can_cast_to()); + CHECK(arg{XV_PTR()}.can_cast_to()); + CHECK(arg{XV_PTR()}.can_cast_to()); + + CHECK(*arg{XV_PTR()}.cast() == 42); + CHECK(*arg{XV_PTR()}.cast() == 42); + CHECK(*arg{XV_PTR()}.cast() == 42); + CHECK(*arg{XV_PTR()}.cast() == 42); + } + + SUBCASE("CXV_PTR") { + CHECK(arg{CXV_PTR()}.can_cast_to()); + CHECK(arg{CXV_PTR()}.can_cast_to()); + CHECK(arg{CXV_PTR()}.can_cast_to()); + CHECK(arg{CXV_PTR()}.can_cast_to()); + + CHECK(*arg{CXV_PTR()}.cast() == 42); + CHECK(*arg{CXV_PTR()}.cast() == 42); + CHECK(*arg{CXV_PTR()}.cast() == 42); + CHECK(*arg{CXV_PTR()}.cast() == 42); + } + + SUBCASE("PRV_PTR") { + CHECK(arg{PRV_PTR()}.can_cast_to()); + CHECK(arg{PRV_PTR()}.can_cast_to()); + CHECK(arg{PRV_PTR()}.can_cast_to()); + CHECK(arg{PRV_PTR()}.can_cast_to()); + + CHECK(*arg{PRV_PTR()}.cast() == 42); + CHECK(*arg{PRV_PTR()}.cast() == 42); + CHECK(*arg{PRV_PTR()}.cast() == 42); + CHECK(*arg{PRV_PTR()}.cast() == 42); + } + + SUBCASE("LV_CPTR") { + CHECK_FALSE(arg{LV_CPTR()}.can_cast_to()); + CHECK_FALSE(arg{LV_CPTR()}.can_cast_to()); + CHECK(arg{LV_CPTR()}.can_cast_to()); + CHECK(arg{LV_CPTR()}.can_cast_to()); + + CHECK_THROWS(std::ignore = arg{LV_CPTR()}.cast()); + CHECK_THROWS(std::ignore = arg{LV_CPTR()}.cast()); + CHECK(*arg{LV_CPTR()}.cast() == 42); + CHECK(*arg{LV_CPTR()}.cast() == 42); + } + + SUBCASE("CLV_CPTR") { + CHECK_FALSE(arg{CLV_CPTR()}.can_cast_to()); + CHECK_FALSE(arg{CLV_CPTR()}.can_cast_to()); + CHECK(arg{CLV_CPTR()}.can_cast_to()); + CHECK(arg{CLV_CPTR()}.can_cast_to()); + + CHECK_THROWS(std::ignore = arg{CLV_CPTR()}.cast()); + CHECK_THROWS(std::ignore = arg{CLV_CPTR()}.cast()); + CHECK(*arg{CLV_CPTR()}.cast() == 42); + CHECK(*arg{CLV_CPTR()}.cast() == 42); + } + + SUBCASE("XV_CPTR") { + CHECK_FALSE(arg{XV_CPTR()}.can_cast_to()); + CHECK_FALSE(arg{XV_CPTR()}.can_cast_to()); + CHECK(arg{XV_CPTR()}.can_cast_to()); + CHECK(arg{XV_CPTR()}.can_cast_to()); + + CHECK_THROWS(std::ignore = arg{XV_CPTR()}.cast()); + CHECK_THROWS(std::ignore = arg{XV_CPTR()}.cast()); + CHECK(*arg{XV_CPTR()}.cast() == 42); + CHECK(*arg{XV_CPTR()}.cast() == 42); + } + + SUBCASE("CXV_CPTR") { + CHECK_FALSE(arg{CXV_CPTR()}.can_cast_to()); + CHECK_FALSE(arg{CXV_CPTR()}.can_cast_to()); + CHECK(arg{CXV_CPTR()}.can_cast_to()); + CHECK(arg{CXV_CPTR()}.can_cast_to()); + + CHECK_THROWS(std::ignore = arg{CXV_CPTR()}.cast()); + CHECK_THROWS(std::ignore = arg{CXV_CPTR()}.cast()); + CHECK(*arg{CXV_CPTR()}.cast() == 42); + CHECK(*arg{CXV_CPTR()}.cast() == 42); + } + + SUBCASE("PRV_CPTR") { + CHECK_FALSE(arg{PRV_CPTR()}.can_cast_to()); + CHECK_FALSE(arg{PRV_CPTR()}.can_cast_to()); + CHECK(arg{PRV_CPTR()}.can_cast_to()); + CHECK(arg{PRV_CPTR()}.can_cast_to()); + + CHECK_THROWS(std::ignore = arg{PRV_CPTR()}.cast()); + CHECK_THROWS(std::ignore = arg{PRV_CPTR()}.cast()); + CHECK(*arg{PRV_CPTR()}.cast() == 42); + CHECK(*arg{PRV_CPTR()}.cast() == 42); + } +} diff --git a/untests/meta_utilities/arg_tests.cpp b/untests/meta_utilities/arg_tests.cpp index a6f0ed1..6fd0222 100644 --- a/untests/meta_utilities/arg_tests.cpp +++ b/untests/meta_utilities/arg_tests.cpp @@ -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 ) {\ CHECK(arg{FromValue}.can_cast_to());\ CHECK(arg_base{type_list{}}.can_cast_to());\ - CHECK_NOTHROW(arg{FromValue}.cast());\ + CHECK_NOTHROW(std::ignore = arg{FromValue}.cast());\ \ CHECK(f_state.is_invocable_with());\ CHECK(f_state.invoke(FromValue) == 1);\ } else {\ CHECK_FALSE(arg{FromValue}.can_cast_to());\ CHECK_FALSE(arg_base{type_list{}}.can_cast_to());\ - CHECK_THROWS(arg{FromValue}.cast());\ + CHECK_THROWS(std::ignore = arg{FromValue}.cast());\ \ CHECK_FALSE(f_state.is_invocable_with());\ 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_() - .base_(); + meta::class_(); + meta::class_(); + meta::class_().base_().base_(); } 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()); @@ -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()); @@ -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()); @@ -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()); @@ -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()); @@ -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()); @@ -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()); @@ -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()); @@ -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()); @@ -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()); @@ -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()); @@ -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()); @@ -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()); @@ -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()); @@ -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()); @@ -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()); @@ -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()); @@ -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()); @@ -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()); @@ -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()); @@ -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()); @@ -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()); @@ -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()); @@ -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()); @@ -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()); @@ -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()); @@ -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()); @@ -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()); @@ -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()); @@ -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()); @@ -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()); @@ -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()); @@ -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()); diff --git a/untests/meta_utilities/inst_tests.cpp b/untests/meta_utilities/inst_tests.cpp index 0549475..969240a 100644 --- a/untests/meta_utilities/inst_tests.cpp +++ b/untests/meta_utilities/inst_tests.cpp @@ -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 ) {\ CHECK(inst{Inst}.can_cast_to());\ CHECK(inst_base{type_list{}}.can_cast_to());\ - CHECK_NOTHROW(inst{Inst}.cast());\ + CHECK_NOTHROW(std::ignore = inst{Inst}.cast());\ \ CHECK(m_state.is_invocable_with());\ CHECK(m_state.invoke(Inst) == 1);\ } else {\ CHECK_FALSE(inst{Inst}.can_cast_to());\ CHECK_FALSE(inst_base{type_list{}}.can_cast_to());\ - CHECK_THROWS(inst{Inst}.cast());\ + CHECK_THROWS(std::ignore = inst{Inst}.cast());\ \ CHECK_FALSE(m_state.is_invocable_with());\ 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_() - .base_(); + meta::class_(); + meta::class_(); + meta::class_().base_().base_(); } TEST_CASE("features/meta_utilities/inst2/refs") {