/******************************************************************************* * 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-2023, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #include #include namespace { struct base0 { int i{21}; }; struct base1 : virtual base0 { int j{42}; }; struct base2 : virtual base0 { int k{84}; }; struct derived : base1, base2 { int l{168}; }; struct derived2 : base1, base2 { int m{336}; }; } TEST_CASE("meta/meta_utilities/value3") { namespace meta = meta_hpp; meta::class_(); meta::class_() .base_(); meta::class_() .base_(); meta::class_() .base_() .base_(); meta::class_() .base_() .base_(); } TEST_CASE("meta/meta_utilities/value3/get_type") { namespace meta = meta_hpp; SUBCASE("from ref") { { derived d{}; CHECK(meta::uvalue{d}.get_type() == meta::resolve_type()); } { const derived d{}; CHECK(meta::uvalue{d}.get_type() == meta::resolve_type()); } } SUBCASE("from ptr") { { derived d{}; derived* pd = &d; CHECK(meta::uvalue{pd}.get_type() == meta::resolve_type()); } { derived d{}; derived* const pd = &d; CHECK(meta::uvalue{pd}.get_type() == meta::resolve_type()); } { derived d{}; const derived* pd = &d; CHECK(meta::uvalue{pd}.get_type() == meta::resolve_type()); } { derived d{}; const derived* const pd = &d; CHECK(meta::uvalue{pd}.get_type() == meta::resolve_type()); } } } TEST_CASE("meta/meta_utilities/value3/get_as") { namespace meta = meta_hpp; static_assert(std::is_same_v().get_as()), derived&>); static_assert(std::is_same_v().get_as()), derived>); static_assert(std::is_same_v().get_as()), const derived&>); static_assert(std::is_same_v().get_as()), const derived&>); static_assert(std::is_same_v().get_as()), derived*>); static_assert(std::is_same_v().get_as()), derived*>); static_assert(std::is_same_v().get_as()), derived*>); static_assert(std::is_same_v().get_as()), derived*>); static_assert(std::is_same_v().get_as()), const derived*>); static_assert(std::is_same_v().get_as()), const derived*>); static_assert(std::is_same_v().get_as()), const derived*>); static_assert(std::is_same_v().get_as()), const derived*>); SUBCASE("derived to derived") { { meta::uvalue v{derived{}}; CHECK(v.get_as().l == 168); CHECK_THROWS(std::ignore = v.get_as()); } { const meta::uvalue v{derived{}}; CHECK(v.get_as().l == 168); CHECK_THROWS(std::ignore = v.get_as()); } } SUBCASE("derived to base") { { meta::uvalue v{derived{}}; CHECK(v.get_as().k == 84); } { const meta::uvalue v{derived{}}; CHECK(v.get_as().k == 84); } } SUBCASE("voidptr") { { derived d{}; meta::uvalue v{&d}; CHECK(v.get_as() == &d); CHECK(v.get_as() == &d); } { const derived d{}; meta::uvalue v{&d}; CHECK_THROWS(std::ignore = v.get_as()); CHECK(v.get_as() == &d); } { meta::uvalue v{derived{}}; CHECK_THROWS(std::ignore = v.get_as()); CHECK_THROWS(std::ignore = v.get_as()); } } SUBCASE("nullptr") { { meta::uvalue v{nullptr}; CHECK(v.get_as() == nullptr); CHECK(v.get_as() == nullptr); CHECK(v.get_as() == nullptr); CHECK(v.get_as() == nullptr); CHECK_THROWS(std::ignore = v.get_as()); } { const meta::uvalue v{nullptr}; CHECK(v.get_as() == nullptr); CHECK(v.get_as() == nullptr); CHECK(v.get_as() == nullptr); CHECK(v.get_as() == nullptr); CHECK_THROWS(std::ignore = v.get_as()); } } SUBCASE("derived* to derived*") { { derived d{}; meta::uvalue v{&d}; CHECK(v.get_as()->l == 168); CHECK(v.get_as()->l == 168); CHECK_THROWS(std::ignore = v.get_as()); CHECK_THROWS(std::ignore = v.get_as()); } { const derived d{}; meta::uvalue v{&d}; CHECK(v.get_as()->l == 168); CHECK_THROWS(std::ignore = v.get_as()); } } SUBCASE("derived* to base*") { { derived d{}; meta::uvalue v{&d}; CHECK(v.get_as()->k == 84); CHECK(v.get_as()->k == 84); } { const derived d{}; meta::uvalue v{&d}; CHECK_THROWS(std::ignore = v.get_as()); CHECK(v.get_as()->k == 84); } } } TEST_CASE("meta/meta_utilities/value3/try_get_as") { namespace meta = meta_hpp; static_assert(std::is_same_v().try_get_as()), derived*>); static_assert(std::is_same_v().try_get_as()), derived*>); static_assert(std::is_same_v().try_get_as()), const derived*>); static_assert(std::is_same_v().try_get_as()), const derived*>); static_assert(std::is_same_v().try_get_as()), derived*>); static_assert(std::is_same_v().try_get_as()), derived*>); static_assert(std::is_same_v().try_get_as()), derived*>); static_assert(std::is_same_v().try_get_as()), derived*>); static_assert(std::is_same_v().try_get_as()), const derived*>); static_assert(std::is_same_v().try_get_as()), const derived*>); static_assert(std::is_same_v().try_get_as()), const derived*>); static_assert(std::is_same_v().try_get_as()), const derived*>); SUBCASE("derived to derived") { { meta::uvalue v{derived{}}; CHECK(v.try_get_as()->l == 168); CHECK_FALSE(v.try_get_as()); } { const meta::uvalue v{derived{}}; CHECK(v.try_get_as()->l == 168); CHECK_FALSE(v.try_get_as()); } } SUBCASE("derived to base") { { meta::uvalue v{derived{}}; CHECK(v.try_get_as()->k == 84); } { const meta::uvalue v{derived{}}; CHECK(v.try_get_as()->k == 84); } } SUBCASE("voidptr") { { derived d{}; meta::uvalue v{&d}; CHECK(v.try_get_as() == &d); CHECK(v.try_get_as() == &d); } { const derived d{}; meta::uvalue v{&d}; CHECK_FALSE(v.try_get_as()); CHECK(v.try_get_as() == &d); } { meta::uvalue v{derived{}}; CHECK_FALSE(v.try_get_as()); CHECK_FALSE(v.try_get_as()); } } SUBCASE("nullptr") { { meta::uvalue v{nullptr}; CHECK(v.try_get_as() == nullptr); CHECK(v.try_get_as() == nullptr); CHECK(v.try_get_as() == nullptr); CHECK(v.try_get_as() == nullptr); CHECK_FALSE(v.try_get_as()); } { const meta::uvalue v{nullptr}; CHECK(v.try_get_as() == nullptr); CHECK(v.try_get_as() == nullptr); CHECK(v.try_get_as() == nullptr); CHECK(v.try_get_as() == nullptr); CHECK_FALSE(v.try_get_as()); } } SUBCASE("derived* to derived*") { { derived d{}; meta::uvalue v{&d}; CHECK(v.try_get_as()->l == 168); CHECK(v.try_get_as()->l == 168); CHECK_FALSE(v.try_get_as()); CHECK_FALSE(v.try_get_as()); } { const derived d{}; meta::uvalue v{&d}; CHECK(v.try_get_as()->l == 168); CHECK_FALSE(v.try_get_as()); } } SUBCASE("derived* to base*") { { derived d{}; meta::uvalue v{&d}; CHECK(v.try_get_as()->k == 84); CHECK(v.try_get_as()->k == 84); } { const derived d{}; meta::uvalue v{&d}; CHECK_FALSE(v.try_get_as()); CHECK(v.try_get_as()->k == 84); } } }