mirror of
https://github.com/BlackMATov/meta.hpp.git
synced 2025-12-16 14:09:02 +07:00
hide all developer stuff to develop directory
This commit is contained in:
18
develop/untests/.clang-tidy
Normal file
18
develop/untests/.clang-tidy
Normal file
@@ -0,0 +1,18 @@
|
||||
---
|
||||
Checks: '-*,
|
||||
|
||||
bugprone-*,
|
||||
-bugprone-easily-swappable-parameters,
|
||||
|
||||
clang-analyzer-*,
|
||||
|
||||
concurrency-*,
|
||||
|
||||
modernize-*,
|
||||
-modernize-avoid-c-arrays,
|
||||
-modernize-use-nodiscard,
|
||||
-modernize-use-trailing-return-type,
|
||||
|
||||
portability-*,
|
||||
'
|
||||
...
|
||||
80
develop/untests/CMakeLists.txt
Normal file
80
develop/untests/CMakeLists.txt
Normal file
@@ -0,0 +1,80 @@
|
||||
project(meta.hpp.untests)
|
||||
|
||||
file(GLOB_RECURSE UNTESTS_SOURCES "*.cpp" "*.hpp")
|
||||
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${UNTESTS_SOURCES})
|
||||
|
||||
add_executable(${PROJECT_NAME} ${UNTESTS_SOURCES})
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE meta.hpp::meta.hpp)
|
||||
|
||||
add_executable(${PROJECT_NAME}.singles ${UNTESTS_SOURCES})
|
||||
target_link_libraries(${PROJECT_NAME}.singles PRIVATE meta.hpp::singles)
|
||||
|
||||
#
|
||||
# setup defines
|
||||
#
|
||||
|
||||
function(setup_defines_for_target TARGET)
|
||||
target_compile_definitions(${TARGET} PRIVATE
|
||||
DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS
|
||||
DOCTEST_CONFIG_USE_STD_HEADERS)
|
||||
endfunction()
|
||||
|
||||
setup_defines_for_target(${PROJECT_NAME})
|
||||
setup_defines_for_target(${PROJECT_NAME}.singles)
|
||||
|
||||
#
|
||||
# setup libraries
|
||||
#
|
||||
|
||||
function(setup_libraries_for_target TARGET)
|
||||
target_link_libraries(${TARGET} PRIVATE doctest::doctest_with_main)
|
||||
|
||||
if(BUILD_WITH_COVERAGE)
|
||||
target_link_libraries(${TARGET} PRIVATE meta.hpp::enable_gcov)
|
||||
endif()
|
||||
|
||||
if(BUILD_WITH_SANITIZERS)
|
||||
target_link_libraries(${TARGET} PRIVATE meta.hpp::enable_asan meta.hpp::enable_ubsan)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
setup_libraries_for_target(${PROJECT_NAME})
|
||||
setup_libraries_for_target(${PROJECT_NAME}.singles)
|
||||
|
||||
#
|
||||
# setup warnings
|
||||
#
|
||||
|
||||
function(setup_warnings_for_target TARGET)
|
||||
target_compile_options(${TARGET}
|
||||
PRIVATE
|
||||
$<$<CXX_COMPILER_ID:MSVC>:
|
||||
/WX /W4>
|
||||
PRIVATE
|
||||
$<$<CXX_COMPILER_ID:GNU>:
|
||||
-Werror -Wall -Wextra -Wpedantic>
|
||||
PRIVATE
|
||||
$<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>>:
|
||||
-Werror -Weverything -Wconversion
|
||||
-Wno-c++98-compat
|
||||
-Wno-c++98-compat-pedantic
|
||||
-Wno-exit-time-destructors
|
||||
-Wno-global-constructors
|
||||
-Wno-padded
|
||||
-Wno-unknown-warning-option
|
||||
-Wno-unneeded-internal-declaration
|
||||
-Wno-unneeded-member-function
|
||||
-Wno-unused-macros
|
||||
-Wno-weak-vtables
|
||||
>)
|
||||
endfunction()
|
||||
|
||||
setup_warnings_for_target(${PROJECT_NAME})
|
||||
setup_warnings_for_target(${PROJECT_NAME}.singles)
|
||||
|
||||
#
|
||||
# add tests
|
||||
#
|
||||
|
||||
add_test(${PROJECT_NAME} ${PROJECT_NAME})
|
||||
add_test(${PROJECT_NAME} ${PROJECT_NAME}.singles)
|
||||
127
develop/untests/meta_base/fixed_function_tests.cpp
Normal file
127
develop/untests/meta_base/fixed_function_tests.cpp
Normal 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-2023, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
******************************************************************************/
|
||||
|
||||
#include "../meta_untests.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
}
|
||||
|
||||
TEST_CASE("meta/meta_base/fixed_function") {
|
||||
namespace meta = meta_hpp;
|
||||
using meta::detail::fixed_function;
|
||||
|
||||
SUBCASE("is_valid") {
|
||||
{
|
||||
fixed_function<void()> ff;
|
||||
CHECK_FALSE(ff);
|
||||
CHECK_FALSE(ff.is_valid());
|
||||
}
|
||||
{
|
||||
fixed_function<void()> ff = []{};
|
||||
CHECK(ff);
|
||||
CHECK(ff.is_valid());
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("ctor") {
|
||||
{
|
||||
auto f1 = []{return 1;};
|
||||
fixed_function<int()> ff{std::move(f1)};
|
||||
CHECK(ff() == 1);
|
||||
|
||||
auto f2 = fixed_function{[]{return 2;}};
|
||||
ff = std::move(f2);
|
||||
CHECK(ff() == 2);
|
||||
}
|
||||
{
|
||||
auto f1 = []() noexcept {return 1;};
|
||||
fixed_function ff{f1};
|
||||
CHECK(ff() == 1);
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("reset") {
|
||||
fixed_function ff = []{return 0;};
|
||||
|
||||
ff.reset();
|
||||
CHECK_FALSE(ff);
|
||||
CHECK_FALSE(ff.is_valid());
|
||||
|
||||
ff = []{return 1;};
|
||||
CHECK(ff);
|
||||
CHECK(ff.is_valid());
|
||||
|
||||
CHECK(ff() == 1);
|
||||
}
|
||||
|
||||
SUBCASE("move") {
|
||||
fixed_function ff = []{return 1;};
|
||||
fixed_function ff2 = std::move(ff);
|
||||
CHECK(ff2() == 1);
|
||||
CHECK_FALSE(ff);
|
||||
}
|
||||
|
||||
SUBCASE("operator=") {
|
||||
{
|
||||
fixed_function<int()> ff;
|
||||
ff = []{return 0;};
|
||||
CHECK(ff() == 0);
|
||||
ff = []{return 1;};
|
||||
CHECK(ff() == 1);
|
||||
|
||||
fixed_function<int()> ff2 = []{return 2;};
|
||||
ff = std::move(ff2);
|
||||
CHECK(ff() == 2);
|
||||
CHECK_FALSE(ff2);
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("swap") {
|
||||
{
|
||||
fixed_function<void()> ff1;
|
||||
fixed_function<void()> ff2;
|
||||
ff1.swap(ff2);
|
||||
CHECK_FALSE(ff1);
|
||||
CHECK_FALSE(ff2);
|
||||
}
|
||||
{
|
||||
fixed_function ff1 = []{return 1;};
|
||||
fixed_function ff2 = []{return 2;};
|
||||
ff1.swap(ff2);
|
||||
CHECK(ff1() == 2);
|
||||
CHECK(ff2() == 1);
|
||||
}
|
||||
{
|
||||
fixed_function<int()> ff1;
|
||||
fixed_function ff2 = []{return 2;};
|
||||
|
||||
ff1.swap(ff2);
|
||||
CHECK(ff1() == 2);
|
||||
CHECK_FALSE(ff2);
|
||||
|
||||
ff1.swap(ff2);
|
||||
CHECK_FALSE(ff1);
|
||||
CHECK(ff2() == 2);
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("-> int") {
|
||||
auto f = [
|
||||
s = std::make_unique<int>(10)
|
||||
](){ return 0; };
|
||||
fixed_function ff = std::move(f);
|
||||
CHECK(ff() == 0);
|
||||
}
|
||||
|
||||
SUBCASE("-> void") {
|
||||
auto f = [
|
||||
s = std::make_unique<int>(10)
|
||||
](){};
|
||||
fixed_function ff = std::move(f);
|
||||
CHECK_NOTHROW(ff());
|
||||
}
|
||||
}
|
||||
171
develop/untests/meta_base/memory_buffer_tests.cpp
Normal file
171
develop/untests/meta_base/memory_buffer_tests.cpp
Normal file
@@ -0,0 +1,171 @@
|
||||
/*******************************************************************************
|
||||
* 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 "../meta_untests.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
}
|
||||
|
||||
TEST_CASE("meta/meta_base/memory_buffer") {
|
||||
namespace meta = meta_hpp;
|
||||
using meta::detail::memory_buffer;
|
||||
|
||||
SUBCASE("ctor/0") {
|
||||
memory_buffer buf;
|
||||
|
||||
CHECK(!buf);
|
||||
CHECK(!buf.is_valid());
|
||||
|
||||
CHECK(buf.get_size() == 0);
|
||||
CHECK(buf.get_align() == std::align_val_t{});
|
||||
|
||||
CHECK(buf.get_memory() == nullptr);
|
||||
CHECK(std::as_const(buf).get_memory() == nullptr);
|
||||
}
|
||||
|
||||
SUBCASE("ctor/1") {
|
||||
memory_buffer buf1{10, std::align_val_t{32}};
|
||||
const void* buf1_memory{buf1.get_memory()};
|
||||
|
||||
memory_buffer buf2{std::move(buf1)};
|
||||
|
||||
{
|
||||
CHECK(!buf1);
|
||||
CHECK(!buf1.is_valid());
|
||||
|
||||
CHECK(buf1.get_size() == 0);
|
||||
CHECK(buf1.get_align() == std::align_val_t{});
|
||||
|
||||
CHECK(buf1.get_memory() == nullptr);
|
||||
CHECK(std::as_const(buf1).get_memory() == nullptr);
|
||||
}
|
||||
|
||||
{
|
||||
CHECK(buf2);
|
||||
CHECK(buf2.is_valid());
|
||||
|
||||
CHECK(buf2.get_size() == 10);
|
||||
CHECK(buf2.get_align() == std::align_val_t{32});
|
||||
|
||||
CHECK(buf2.get_memory() == buf1_memory);
|
||||
CHECK(std::as_const(buf2).get_memory() == buf1_memory);
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("ctor/2") {
|
||||
memory_buffer buf{10, std::align_val_t{32}};
|
||||
|
||||
CHECK(buf);
|
||||
CHECK(buf.is_valid());
|
||||
|
||||
CHECK(buf.get_size() == 10);
|
||||
CHECK(buf.get_align() == std::align_val_t{32});
|
||||
|
||||
CHECK(buf.get_memory());
|
||||
CHECK(std::as_const(buf).get_memory());
|
||||
|
||||
{
|
||||
void* aligned_ptr{buf.get_memory()};
|
||||
std::size_t aligned_size{buf.get_size()};
|
||||
CHECK(std::align(
|
||||
meta::detail::to_underlying(buf.get_align()), buf.get_size(),
|
||||
aligned_ptr, aligned_size) == buf.get_memory());
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("operator=/0") {
|
||||
memory_buffer buf1{10, std::align_val_t{32}};
|
||||
const void* buf1_memory{buf1.get_memory()};
|
||||
|
||||
memory_buffer buf2;
|
||||
buf2 = std::move(buf1);
|
||||
|
||||
{
|
||||
CHECK(!buf1);
|
||||
CHECK(!buf1.is_valid());
|
||||
|
||||
CHECK(buf1.get_size() == 0);
|
||||
CHECK(buf1.get_align() == std::align_val_t{});
|
||||
|
||||
CHECK(buf1.get_memory() == nullptr);
|
||||
CHECK(std::as_const(buf1).get_memory() == nullptr);
|
||||
}
|
||||
|
||||
{
|
||||
CHECK(buf2);
|
||||
CHECK(buf2.is_valid());
|
||||
|
||||
CHECK(buf2.get_size() == 10);
|
||||
CHECK(buf2.get_align() == std::align_val_t{32});
|
||||
|
||||
CHECK(buf2.get_memory() == buf1_memory);
|
||||
CHECK(std::as_const(buf2).get_memory() == buf1_memory);
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("operator=/1") {
|
||||
memory_buffer buf1{10, std::align_val_t{32}};
|
||||
const void* buf1_memory{buf1.get_memory()};
|
||||
|
||||
memory_buffer buf2{20, std::align_val_t{16}};
|
||||
buf2 = std::move(buf1);
|
||||
|
||||
{
|
||||
CHECK(!buf1);
|
||||
CHECK(!buf1.is_valid());
|
||||
|
||||
CHECK(buf1.get_size() == 0);
|
||||
CHECK(buf1.get_align() == std::align_val_t{});
|
||||
|
||||
CHECK(buf1.get_memory() == nullptr);
|
||||
CHECK(std::as_const(buf1).get_memory() == nullptr);
|
||||
}
|
||||
|
||||
{
|
||||
CHECK(buf2);
|
||||
CHECK(buf2.is_valid());
|
||||
|
||||
CHECK(buf2.get_size() == 10);
|
||||
CHECK(buf2.get_align() == std::align_val_t{32});
|
||||
|
||||
CHECK(buf2.get_memory() == buf1_memory);
|
||||
CHECK(std::as_const(buf2).get_memory() == buf1_memory);
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("reset") {
|
||||
memory_buffer buf{10, std::align_val_t{32}};
|
||||
buf.reset();
|
||||
|
||||
CHECK(!buf);
|
||||
CHECK(!buf.is_valid());
|
||||
|
||||
CHECK(buf.get_size() == 0);
|
||||
CHECK(buf.get_align() == std::align_val_t{});
|
||||
|
||||
CHECK(buf.get_memory() == nullptr);
|
||||
CHECK(std::as_const(buf).get_memory() == nullptr);
|
||||
}
|
||||
|
||||
SUBCASE("swap") {
|
||||
memory_buffer buf1{10, std::align_val_t{32}};
|
||||
memory_buffer buf2{15, std::align_val_t{16}};
|
||||
|
||||
const void* buf1_memory{buf1.get_memory()};
|
||||
const void* buf2_memory{buf2.get_memory()};
|
||||
|
||||
meta::detail::swap(buf1, buf2);
|
||||
|
||||
CHECK(buf1.get_size() == 15);
|
||||
CHECK(buf1.get_align() == std::align_val_t{16});
|
||||
CHECK(buf1.get_memory() == buf2_memory);
|
||||
|
||||
CHECK(buf2.get_size() == 10);
|
||||
CHECK(buf2.get_align() == std::align_val_t{32});
|
||||
CHECK(buf2.get_memory() == buf1_memory);
|
||||
}
|
||||
}
|
||||
338
develop/untests/meta_features/diamond_tests.cpp
Normal file
338
develop/untests/meta_features/diamond_tests.cpp
Normal file
@@ -0,0 +1,338 @@
|
||||
/*******************************************************************************
|
||||
* 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 "../meta_untests.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
struct A {
|
||||
A() = default;
|
||||
|
||||
[[maybe_unused]] A(A&&) = default;
|
||||
[[maybe_unused]]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("meta/meta_features/diamond") {
|
||||
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") {
|
||||
using meta::detail::pointer_upcast;
|
||||
{
|
||||
A a;
|
||||
CHECK(pointer_upcast<A>(&a) == &a);
|
||||
CHECK_FALSE(pointer_upcast<B>(&a));
|
||||
CHECK_FALSE(pointer_upcast<C>(&a));
|
||||
CHECK_FALSE(pointer_upcast<D>(&a));
|
||||
CHECK_FALSE(pointer_upcast<E>(&a));
|
||||
}
|
||||
{
|
||||
const B b;
|
||||
CHECK(pointer_upcast<A>(&b) == &b);
|
||||
CHECK(pointer_upcast<B>(&b) == &b);
|
||||
CHECK_FALSE(pointer_upcast<C>(&b));
|
||||
CHECK_FALSE(pointer_upcast<D>(&b));
|
||||
CHECK_FALSE(pointer_upcast<E>(&b));
|
||||
}
|
||||
{
|
||||
C c;
|
||||
CHECK(pointer_upcast<A>(&c) == &c);
|
||||
CHECK_FALSE(pointer_upcast<B>(&c));
|
||||
CHECK(pointer_upcast<C>(&c) == &c);
|
||||
CHECK_FALSE(pointer_upcast<D>(&c));
|
||||
CHECK_FALSE(pointer_upcast<E>(&c));
|
||||
}
|
||||
{
|
||||
const D d;
|
||||
CHECK(pointer_upcast<A>(&d) == &d);
|
||||
CHECK(pointer_upcast<B>(&d) == &d);
|
||||
CHECK(pointer_upcast<C>(&d) == &d);
|
||||
CHECK(pointer_upcast<D>(&d) == &d);
|
||||
CHECK_FALSE(pointer_upcast<E>(&d));
|
||||
}
|
||||
{
|
||||
E e;
|
||||
CHECK_FALSE(pointer_upcast<A>(&e));
|
||||
CHECK_FALSE(pointer_upcast<B>(&e));
|
||||
CHECK_FALSE(pointer_upcast<C>(&e));
|
||||
CHECK_FALSE(pointer_upcast<D>(&e));
|
||||
CHECK(pointer_upcast<E>(&e) == &e);
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("arg/cast") {
|
||||
{
|
||||
A a;
|
||||
meta::uvalue a_val{&a};
|
||||
CHECK(*static_cast<A**>(a_val.data()) == &a);
|
||||
|
||||
meta::detail::uarg 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::uvalue b_val{&b};
|
||||
CHECK(*static_cast<B**>(b_val.data()) == &b);
|
||||
|
||||
meta::detail::uarg 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::uvalue c_val{&c};
|
||||
CHECK(*static_cast<C**>(c_val.data()) == &c);
|
||||
|
||||
meta::detail::uarg 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::uvalue d_val{&d};
|
||||
CHECK(*static_cast<D**>(d_val.data()) == &d);
|
||||
|
||||
meta::detail::uarg 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::uvalue e_val{&e};
|
||||
CHECK(*static_cast<E**>(e_val.data()) == &e);
|
||||
|
||||
meta::detail::uarg 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::uvalue a_val{A{}};
|
||||
meta::detail::uinst 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.get_as<A>());
|
||||
}
|
||||
{
|
||||
meta::uvalue b_val{B{}};
|
||||
meta::detail::uinst 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.get_as<B>());
|
||||
CHECK(&b_inst.cast<B&>() == &b_val.get_as<B>());
|
||||
|
||||
CHECK(&b_inst.cast<A&>() == &b_val.get_as<B>());
|
||||
}
|
||||
{
|
||||
meta::uvalue c_val{C{}};
|
||||
meta::detail::uinst 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.get_as<C>());
|
||||
CHECK(&c_inst.cast<C&>() == &c_val.get_as<C>());
|
||||
}
|
||||
{
|
||||
meta::uvalue d_val{D{}};
|
||||
meta::detail::uinst 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.get_as<D>());
|
||||
CHECK(&d_inst.cast<B&>() == &d_val.get_as<D>());
|
||||
CHECK(&d_inst.cast<C&>() == &d_val.get_as<D>());
|
||||
CHECK(&d_inst.cast<D&>() == &d_val.get_as<D>());
|
||||
|
||||
CHECK(&d_inst.cast<A&>() == &d_val.get_as<D>());
|
||||
CHECK(&d_inst.cast<B&>() == &d_val.get_as<D>());
|
||||
CHECK(&d_inst.cast<C&>() == &d_val.get_as<D>());
|
||||
CHECK(&d_inst.cast<D&>() == &d_val.get_as<D>());
|
||||
}
|
||||
{
|
||||
meta::uvalue e_val{E{}};
|
||||
meta::detail::uinst 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.get_as<E>());
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("resolve_polymorphic_type") {
|
||||
const D d;
|
||||
|
||||
const A& ad = d;
|
||||
const B& bd = d;
|
||||
const C& cd = d;
|
||||
const D& dd = d;
|
||||
|
||||
CHECK(meta::resolve_type(ad) == meta::resolve_type<A>());
|
||||
CHECK(meta::resolve_type(bd) == meta::resolve_type<B>());
|
||||
CHECK(meta::resolve_type(cd) == meta::resolve_type<C>());
|
||||
CHECK(meta::resolve_type(dd) == meta::resolve_type<D>());
|
||||
|
||||
CHECK(meta::resolve_polymorphic_type(ad) == meta::resolve_type<D>());
|
||||
CHECK(meta::resolve_polymorphic_type(bd) == meta::resolve_type<D>());
|
||||
CHECK(meta::resolve_polymorphic_type(cd) == meta::resolve_type<D>());
|
||||
CHECK(meta::resolve_polymorphic_type(dd) == meta::resolve_type<D>());
|
||||
}
|
||||
}
|
||||
38
develop/untests/meta_issues/github_issue_15.cpp
Normal file
38
develop/untests/meta_issues/github_issue_15.cpp
Normal file
@@ -0,0 +1,38 @@
|
||||
/*******************************************************************************
|
||||
* 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 "../meta_untests.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
class rect {
|
||||
public:
|
||||
void get_width(int* v) {
|
||||
*v = 42;
|
||||
}
|
||||
|
||||
static void get_width_static(int* v) {
|
||||
*v = 84;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
TEST_CASE("meta/meta_issues/15") {
|
||||
namespace meta = meta_hpp;
|
||||
|
||||
meta::class_<rect>()
|
||||
.method_("get_width", &rect::get_width)
|
||||
.function_("get_width_static", &rect::get_width_static);
|
||||
|
||||
int v{};
|
||||
rect r{};
|
||||
|
||||
meta::resolve_type(r).get_method("get_width").invoke(r, &v);
|
||||
CHECK(v == 42);
|
||||
|
||||
meta::resolve_type(r).get_function("get_width_static").invoke(&v);
|
||||
CHECK(v == 84);
|
||||
}
|
||||
402
develop/untests/meta_states/ctor_tests.cpp
Normal file
402
develop/untests/meta_states/ctor_tests.cpp
Normal file
@@ -0,0 +1,402 @@
|
||||
/*******************************************************************************
|
||||
* 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 "../meta_untests.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
template < typename Tag >
|
||||
struct clazz {
|
||||
int i{};
|
||||
|
||||
clazz(int ni) : i{ni} {
|
||||
++constructor_counter;
|
||||
}
|
||||
|
||||
clazz(clazz&& other) : i{other.i} {
|
||||
other.i = 0;
|
||||
++move_constructor_counter;
|
||||
}
|
||||
|
||||
clazz(const clazz& other) : i{other.i} {
|
||||
++copy_constructor_counter;
|
||||
}
|
||||
|
||||
clazz& operator=(clazz&& other) = delete;
|
||||
clazz& operator=(const clazz& other) = delete;
|
||||
|
||||
~clazz() {
|
||||
++destructor_counter;
|
||||
}
|
||||
|
||||
inline static int constructor_counter{};
|
||||
inline static int destructor_counter{};
|
||||
inline static int move_constructor_counter{};
|
||||
inline static int copy_constructor_counter{};
|
||||
};
|
||||
|
||||
template < typename Tag >
|
||||
struct clazz_noncopyable {
|
||||
int i{};
|
||||
|
||||
clazz_noncopyable(int ni) : i{ni} {
|
||||
++constructor_counter;
|
||||
}
|
||||
|
||||
clazz_noncopyable(clazz_noncopyable&& other) : i{other.i} {
|
||||
other.i = 0;
|
||||
++move_constructor_counter;
|
||||
}
|
||||
|
||||
clazz_noncopyable(const clazz_noncopyable& other) = delete;
|
||||
clazz_noncopyable& operator=(clazz_noncopyable&& other) = delete;
|
||||
clazz_noncopyable& operator=(const clazz_noncopyable& other) = delete;
|
||||
|
||||
~clazz_noncopyable() {
|
||||
++destructor_counter;
|
||||
}
|
||||
|
||||
inline static int constructor_counter{};
|
||||
inline static int destructor_counter{};
|
||||
inline static int move_constructor_counter{};
|
||||
inline static int copy_constructor_counter{};
|
||||
};
|
||||
}
|
||||
|
||||
TEST_CASE("meta/meta_states/ctor/noncopyable") {
|
||||
namespace meta = meta_hpp;
|
||||
|
||||
using clazz_t = clazz_noncopyable<meta::constructor_policy::as_raw_pointer_t>;
|
||||
|
||||
meta::class_<clazz_t>()
|
||||
.constructor_<int>(meta::constructor_policy::as_raw_pointer)
|
||||
.constructor_<clazz_t&&>(meta::constructor_policy::as_raw_pointer);
|
||||
|
||||
clazz_t::constructor_counter = 0;
|
||||
clazz_t::destructor_counter = 0;
|
||||
clazz_t::move_constructor_counter = 0;
|
||||
clazz_t::copy_constructor_counter = 0;
|
||||
|
||||
const meta::class_type clazz_type = meta::resolve_type<clazz_t>();
|
||||
REQUIRE(clazz_type);
|
||||
|
||||
SUBCASE("int") {
|
||||
{
|
||||
const meta::constructor ctor = clazz_type.get_constructor_with<int>();
|
||||
REQUIRE(ctor);
|
||||
CHECK(ctor.get_type() == meta::resolve_constructor_type<clazz_t, int>());
|
||||
}
|
||||
{
|
||||
const meta::uvalue v = clazz_type.create(42);
|
||||
CHECK(v.get_type() == meta::resolve_type<clazz_t*>());
|
||||
CHECK(v.get_as<clazz_t*>()->i == 42);
|
||||
CHECK(clazz_type.destroy(v));
|
||||
}
|
||||
CHECK(clazz_t::constructor_counter == 1);
|
||||
CHECK(clazz_t::destructor_counter == 1);
|
||||
CHECK(clazz_t::move_constructor_counter == 0);
|
||||
CHECK(clazz_t::copy_constructor_counter == 0);
|
||||
}
|
||||
|
||||
SUBCASE("clazz_t&&") {
|
||||
{
|
||||
const meta::constructor ctor = clazz_type.get_constructor_with<clazz_t&&>();
|
||||
REQUIRE(ctor);
|
||||
CHECK(ctor.get_type() == meta::resolve_constructor_type<clazz_t, clazz_t&&>());
|
||||
}
|
||||
{
|
||||
clazz_t o{42};
|
||||
const meta::uvalue v = clazz_type.create(std::move(o));
|
||||
CHECK(v.get_type() == meta::resolve_type<clazz_t*>());
|
||||
CHECK(v.get_as<clazz_t*>()->i == 42);
|
||||
CHECK(clazz_type.destroy(v));
|
||||
}
|
||||
CHECK(clazz_t::constructor_counter == 1);
|
||||
CHECK(clazz_t::destructor_counter == 2);
|
||||
CHECK(clazz_t::move_constructor_counter == 1);
|
||||
CHECK(clazz_t::copy_constructor_counter == 0);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("meta/meta_states/ctor/as_object") {
|
||||
namespace meta = meta_hpp;
|
||||
|
||||
using clazz_t = clazz<meta::constructor_policy::as_object_t>;
|
||||
|
||||
meta::class_<clazz_t>()
|
||||
.constructor_<int>(meta::constructor_policy::as_object)
|
||||
.constructor_<clazz_t&&>(meta::constructor_policy::as_object)
|
||||
.constructor_<const clazz_t&>(meta::constructor_policy::as_object);
|
||||
|
||||
clazz_t::constructor_counter = 0;
|
||||
clazz_t::destructor_counter = 0;
|
||||
clazz_t::move_constructor_counter = 0;
|
||||
clazz_t::copy_constructor_counter = 0;
|
||||
|
||||
const meta::class_type clazz_type = meta::resolve_type<clazz_t>();
|
||||
REQUIRE(clazz_type);
|
||||
|
||||
alignas(clazz_t) std::byte clazz_mem[sizeof(clazz_t)];
|
||||
|
||||
SUBCASE("int") {
|
||||
{
|
||||
const meta::constructor ctor = clazz_type.get_constructor_with<int>();
|
||||
REQUIRE(ctor);
|
||||
CHECK(ctor.get_type() == meta::resolve_constructor_type<clazz_t, int>());
|
||||
}
|
||||
{
|
||||
const meta::uvalue v = clazz_type.create(42);
|
||||
CHECK(v.get_type() == meta::resolve_type<clazz_t>());
|
||||
CHECK(v.get_as<clazz_t>().i == 42);
|
||||
CHECK_FALSE(clazz_type.destroy(v));
|
||||
}
|
||||
CHECK(clazz_t::constructor_counter == 1);
|
||||
CHECK(clazz_t::destructor_counter == 1);
|
||||
CHECK(clazz_t::move_constructor_counter == 0);
|
||||
CHECK(clazz_t::copy_constructor_counter == 0);
|
||||
}
|
||||
|
||||
SUBCASE("int/inplace") {
|
||||
{
|
||||
const meta::uvalue v = clazz_type
|
||||
.get_constructor_with<int>()
|
||||
.create_at(clazz_mem, 42);
|
||||
|
||||
CHECK(v.get_type() == meta::resolve_type<clazz_t*>());
|
||||
CHECK(v.get_as<clazz_t*>()->i == 42);
|
||||
|
||||
clazz_type.get_destructor().destroy_at(clazz_mem);
|
||||
}
|
||||
CHECK(clazz_t::constructor_counter == 1);
|
||||
CHECK(clazz_t::destructor_counter == 1);
|
||||
CHECK(clazz_t::move_constructor_counter == 0);
|
||||
CHECK(clazz_t::copy_constructor_counter == 0);
|
||||
}
|
||||
|
||||
SUBCASE("clazz_t&&") {
|
||||
{
|
||||
const meta::constructor ctor = clazz_type.get_constructor_with<clazz_t&&>();
|
||||
REQUIRE(ctor);
|
||||
CHECK(ctor.get_type() == meta::resolve_constructor_type<clazz_t, clazz_t&&>());
|
||||
}
|
||||
{
|
||||
clazz_t o{42};
|
||||
const meta::uvalue v = clazz_type.create(std::move(o));
|
||||
CHECK(v.get_type() == meta::resolve_type<clazz_t>());
|
||||
CHECK(v.get_as<clazz_t>().i == 42);
|
||||
CHECK_FALSE(clazz_type.destroy(v));
|
||||
}
|
||||
CHECK(clazz_t::constructor_counter == 1);
|
||||
CHECK(clazz_t::destructor_counter == 2);
|
||||
CHECK(clazz_t::move_constructor_counter == 1);
|
||||
CHECK(clazz_t::copy_constructor_counter == 0);
|
||||
}
|
||||
|
||||
SUBCASE("clazz_t&&/inplace") {
|
||||
{
|
||||
clazz_t o{42};
|
||||
const meta::uvalue v = clazz_type
|
||||
.get_constructor_with<clazz_t&&>()
|
||||
.create_at(clazz_mem, std::move(o));
|
||||
|
||||
CHECK(v.get_type() == meta::resolve_type<clazz_t*>());
|
||||
CHECK(v.get_as<clazz_t*>()->i == 42);
|
||||
|
||||
clazz_type.get_destructor().destroy_at(clazz_mem);
|
||||
}
|
||||
CHECK(clazz_t::constructor_counter == 1);
|
||||
CHECK(clazz_t::destructor_counter == 2);
|
||||
CHECK(clazz_t::move_constructor_counter == 1);
|
||||
CHECK(clazz_t::copy_constructor_counter == 0);
|
||||
}
|
||||
|
||||
SUBCASE("const clazz_t&") {
|
||||
{
|
||||
const meta::constructor ctor = clazz_type.get_constructor_with<const clazz_t&>();
|
||||
REQUIRE(ctor);
|
||||
CHECK(ctor.get_type() == meta::resolve_constructor_type<clazz_t, const clazz_t&>());
|
||||
}
|
||||
{
|
||||
clazz_t o{42};
|
||||
const meta::uvalue v = clazz_type.create(std::as_const(o));
|
||||
CHECK(v.get_type() == meta::resolve_type<clazz_t>());
|
||||
CHECK(v.get_as<clazz_t>().i == 42);
|
||||
CHECK_FALSE(clazz_type.destroy(v));
|
||||
}
|
||||
CHECK(clazz_t::constructor_counter == 1);
|
||||
CHECK(clazz_t::destructor_counter == 2);
|
||||
CHECK(clazz_t::move_constructor_counter == 0);
|
||||
CHECK(clazz_t::copy_constructor_counter == 1);
|
||||
}
|
||||
|
||||
SUBCASE("const clazz_t&/inplace") {
|
||||
{
|
||||
clazz_t o{42};
|
||||
const meta::uvalue v = clazz_type
|
||||
.get_constructor_with<const clazz_t&>()
|
||||
.create_at(clazz_mem, std::as_const(o));
|
||||
|
||||
CHECK(v.get_type() == meta::resolve_type<clazz_t*>());
|
||||
CHECK(v.get_as<clazz_t*>()->i == 42);
|
||||
|
||||
clazz_type.get_destructor().destroy_at(clazz_mem);
|
||||
}
|
||||
CHECK(clazz_t::constructor_counter == 1);
|
||||
CHECK(clazz_t::destructor_counter == 2);
|
||||
CHECK(clazz_t::move_constructor_counter == 0);
|
||||
CHECK(clazz_t::copy_constructor_counter == 1);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("meta/meta_states/ctor/as_raw_pointer") {
|
||||
namespace meta = meta_hpp;
|
||||
|
||||
using clazz_t = clazz<meta::constructor_policy::as_raw_pointer_t>;
|
||||
|
||||
meta::class_<clazz_t>()
|
||||
.constructor_<int>(meta::constructor_policy::as_raw_pointer)
|
||||
.constructor_<clazz_t&&>(meta::constructor_policy::as_raw_pointer)
|
||||
.constructor_<const clazz_t&>(meta::constructor_policy::as_raw_pointer);
|
||||
|
||||
clazz_t::constructor_counter = 0;
|
||||
clazz_t::destructor_counter = 0;
|
||||
clazz_t::move_constructor_counter = 0;
|
||||
clazz_t::copy_constructor_counter = 0;
|
||||
|
||||
const meta::class_type clazz_type = meta::resolve_type<clazz_t>();
|
||||
REQUIRE(clazz_type);
|
||||
|
||||
SUBCASE("int") {
|
||||
{
|
||||
const meta::constructor ctor = clazz_type.get_constructor_with<int>();
|
||||
REQUIRE(ctor);
|
||||
CHECK(ctor.get_type() == meta::resolve_constructor_type<clazz_t, int>());
|
||||
}
|
||||
{
|
||||
const meta::uvalue v = clazz_type.create(42);
|
||||
CHECK(v.get_type() == meta::resolve_type<clazz_t*>());
|
||||
CHECK(v.get_as<clazz_t*>()->i == 42);
|
||||
CHECK(clazz_type.destroy(v));
|
||||
}
|
||||
CHECK(clazz_t::constructor_counter == 1);
|
||||
CHECK(clazz_t::destructor_counter == 1);
|
||||
CHECK(clazz_t::move_constructor_counter == 0);
|
||||
CHECK(clazz_t::copy_constructor_counter == 0);
|
||||
}
|
||||
|
||||
SUBCASE("clazz_t&&") {
|
||||
{
|
||||
const meta::constructor ctor = clazz_type.get_constructor_with<clazz_t&&>();
|
||||
REQUIRE(ctor);
|
||||
CHECK(ctor.get_type() == meta::resolve_constructor_type<clazz_t, clazz_t&&>());
|
||||
}
|
||||
{
|
||||
clazz_t o{42};
|
||||
const meta::uvalue v = clazz_type.create(std::move(o));
|
||||
CHECK(v.get_type() == meta::resolve_type<clazz_t*>());
|
||||
CHECK(v.get_as<clazz_t*>()->i == 42);
|
||||
CHECK(clazz_type.destroy(v));
|
||||
}
|
||||
CHECK(clazz_t::constructor_counter == 1);
|
||||
CHECK(clazz_t::destructor_counter == 2);
|
||||
CHECK(clazz_t::move_constructor_counter == 1);
|
||||
CHECK(clazz_t::copy_constructor_counter == 0);
|
||||
}
|
||||
|
||||
SUBCASE("const clazz_t&") {
|
||||
{
|
||||
const meta::constructor ctor = clazz_type.get_constructor_with<const clazz_t&>();
|
||||
REQUIRE(ctor);
|
||||
CHECK(ctor.get_type() == meta::resolve_constructor_type<clazz_t, const clazz_t&>());
|
||||
}
|
||||
{
|
||||
clazz_t o{42};
|
||||
const meta::uvalue v = clazz_type.create(std::as_const(o));
|
||||
CHECK(v.get_type() == meta::resolve_type<clazz_t*>());
|
||||
CHECK(v.get_as<clazz_t*>()->i == 42);
|
||||
CHECK(clazz_type.destroy(v));
|
||||
}
|
||||
CHECK(clazz_t::constructor_counter == 1);
|
||||
CHECK(clazz_t::destructor_counter == 2);
|
||||
CHECK(clazz_t::move_constructor_counter == 0);
|
||||
CHECK(clazz_t::copy_constructor_counter == 1);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("meta/meta_states/ctor/as_shared_pointer") {
|
||||
namespace meta = meta_hpp;
|
||||
|
||||
using clazz_t = clazz<meta::constructor_policy::as_shared_pointer_t>;
|
||||
|
||||
meta::class_<clazz_t>()
|
||||
.constructor_<int>(meta::constructor_policy::as_shared_pointer)
|
||||
.constructor_<clazz_t&&>(meta::constructor_policy::as_shared_pointer)
|
||||
.constructor_<const clazz_t&>(meta::constructor_policy::as_shared_pointer);
|
||||
|
||||
clazz_t::constructor_counter = 0;
|
||||
clazz_t::destructor_counter = 0;
|
||||
clazz_t::move_constructor_counter = 0;
|
||||
clazz_t::copy_constructor_counter = 0;
|
||||
|
||||
const meta::class_type clazz_type = meta::resolve_type<clazz_t>();
|
||||
REQUIRE(clazz_type);
|
||||
|
||||
SUBCASE("int") {
|
||||
{
|
||||
const meta::constructor ctor = clazz_type.get_constructor_with<int>();
|
||||
REQUIRE(ctor);
|
||||
CHECK(ctor.get_type() == meta::resolve_constructor_type<clazz_t, int>());
|
||||
}
|
||||
{
|
||||
const meta::uvalue v = clazz_type.create(42);
|
||||
CHECK(v.get_type() == meta::resolve_type<std::shared_ptr<clazz_t>>());
|
||||
CHECK(v.get_as<std::shared_ptr<clazz_t>>()->i == 42);
|
||||
CHECK_FALSE(clazz_type.destroy(v));
|
||||
}
|
||||
CHECK(clazz_t::constructor_counter == 1);
|
||||
CHECK(clazz_t::destructor_counter == 1);
|
||||
CHECK(clazz_t::move_constructor_counter == 0);
|
||||
CHECK(clazz_t::copy_constructor_counter == 0);
|
||||
}
|
||||
|
||||
SUBCASE("clazz_t&&") {
|
||||
{
|
||||
const meta::constructor ctor = clazz_type.get_constructor_with<clazz_t&&>();
|
||||
REQUIRE(ctor);
|
||||
CHECK(ctor.get_type() == meta::resolve_constructor_type<clazz_t, clazz_t&&>());
|
||||
}
|
||||
{
|
||||
clazz_t o{42};
|
||||
const meta::uvalue v = clazz_type.create(std::move(o));
|
||||
CHECK(v.get_type() == meta::resolve_type<std::shared_ptr<clazz_t>>());
|
||||
CHECK(v.get_as<std::shared_ptr<clazz_t>>()->i == 42);
|
||||
CHECK_FALSE(clazz_type.destroy(v));
|
||||
}
|
||||
CHECK(clazz_t::constructor_counter == 1);
|
||||
CHECK(clazz_t::destructor_counter == 2);
|
||||
CHECK(clazz_t::move_constructor_counter == 1);
|
||||
CHECK(clazz_t::copy_constructor_counter == 0);
|
||||
}
|
||||
|
||||
SUBCASE("const clazz_t&") {
|
||||
{
|
||||
const meta::constructor ctor = clazz_type.get_constructor_with<const clazz_t&>();
|
||||
REQUIRE(ctor);
|
||||
CHECK(ctor.get_type() == meta::resolve_constructor_type<clazz_t, const clazz_t&>());
|
||||
}
|
||||
{
|
||||
clazz_t o{42};
|
||||
const meta::uvalue v = clazz_type.create(std::as_const(o));
|
||||
CHECK(v.get_type() == meta::resolve_type<std::shared_ptr<clazz_t>>());
|
||||
CHECK(v.get_as<std::shared_ptr<clazz_t>>()->i == 42);
|
||||
CHECK_FALSE(clazz_type.destroy(v));
|
||||
}
|
||||
CHECK(clazz_t::constructor_counter == 1);
|
||||
CHECK(clazz_t::destructor_counter == 2);
|
||||
CHECK(clazz_t::move_constructor_counter == 0);
|
||||
CHECK(clazz_t::copy_constructor_counter == 1);
|
||||
}
|
||||
}
|
||||
99
develop/untests/meta_states/dtor_tests.cpp
Normal file
99
develop/untests/meta_states/dtor_tests.cpp
Normal file
@@ -0,0 +1,99 @@
|
||||
/*******************************************************************************
|
||||
* 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 "../meta_untests.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
class clazz_closed_dtor {
|
||||
public:
|
||||
~clazz_closed_dtor() = delete;
|
||||
};
|
||||
|
||||
class clazz_opened_dtor {
|
||||
public:
|
||||
~clazz_opened_dtor() = default;
|
||||
};
|
||||
|
||||
class clazz_virtual_dtor {
|
||||
public:
|
||||
virtual ~clazz_virtual_dtor() noexcept(false) = default;
|
||||
};
|
||||
|
||||
class clazz_dtor_metadata {
|
||||
public:
|
||||
virtual ~clazz_dtor_metadata() = default;
|
||||
};
|
||||
}
|
||||
|
||||
TEST_CASE("meta/meta_states/dtor") {
|
||||
namespace meta = meta_hpp;
|
||||
using namespace std::string_literals;
|
||||
|
||||
meta::class_<clazz_opened_dtor>();
|
||||
meta::class_<clazz_closed_dtor>();
|
||||
meta::class_<clazz_virtual_dtor>();
|
||||
|
||||
meta::class_<clazz_dtor_metadata>()
|
||||
.destructor_({
|
||||
.metadata{
|
||||
{"desc", meta::uvalue{"virtual dtor"s}}
|
||||
}
|
||||
});
|
||||
|
||||
SUBCASE("closed_dtor") {
|
||||
const meta::class_type clazz_type = meta::resolve_type<clazz_closed_dtor>();
|
||||
REQUIRE(clazz_type);
|
||||
|
||||
CHECK(clazz_type.get_destructors().empty());
|
||||
}
|
||||
|
||||
SUBCASE("opened_dtor") {
|
||||
const meta::class_type clazz_type = meta::resolve_type<clazz_opened_dtor>();
|
||||
REQUIRE(clazz_type);
|
||||
|
||||
REQUIRE(clazz_type.get_destructors().size() == 1);
|
||||
const meta::destructor dtor = clazz_type.get_destructor();
|
||||
|
||||
CHECK(dtor.get_type().get_class_type() == meta::resolve_type<clazz_opened_dtor>());
|
||||
CHECK(dtor.get_type().get_flags() == meta::destructor_flags::is_noexcept);
|
||||
}
|
||||
|
||||
SUBCASE("virtual_dtor") {
|
||||
const meta::class_type clazz_type = meta::resolve_type<clazz_virtual_dtor>();
|
||||
REQUIRE(clazz_type);
|
||||
|
||||
REQUIRE(clazz_type.get_destructors().size() == 1);
|
||||
const meta::destructor dtor = clazz_type.get_destructor();
|
||||
|
||||
CHECK(dtor.get_type().get_class_type() == meta::resolve_type<clazz_virtual_dtor>());
|
||||
CHECK(dtor.get_type().get_flags() == meta::destructor_flags::is_virtual);
|
||||
}
|
||||
|
||||
SUBCASE("virtual_dtor") {
|
||||
const meta::class_type clazz_type = meta::resolve_type<clazz_virtual_dtor>();
|
||||
REQUIRE(clazz_type);
|
||||
|
||||
REQUIRE(clazz_type.get_destructors().size() == 1);
|
||||
const meta::destructor dtor = clazz_type.get_destructor();
|
||||
|
||||
CHECK(dtor.get_type().get_class_type() == meta::resolve_type<clazz_virtual_dtor>());
|
||||
CHECK(dtor.get_type().get_flags() == meta::destructor_flags::is_virtual);
|
||||
}
|
||||
|
||||
SUBCASE("dtor_metadata") {
|
||||
const meta::class_type clazz_type = meta::resolve_type<clazz_dtor_metadata>();
|
||||
REQUIRE(clazz_type);
|
||||
|
||||
REQUIRE(clazz_type.get_destructors().size() == 1);
|
||||
const meta::destructor dtor = clazz_type.get_destructor();
|
||||
|
||||
CHECK(dtor.get_type().get_class_type() == meta::resolve_type<clazz_dtor_metadata>());
|
||||
CHECK(dtor.get_type().get_flags() == (meta::destructor_flags::is_noexcept | meta::destructor_flags::is_virtual));
|
||||
|
||||
CHECK(dtor.get_metadata().at("desc") == "virtual dtor"s);
|
||||
}
|
||||
}
|
||||
62
develop/untests/meta_states/evalue_tests.cpp
Normal file
62
develop/untests/meta_states/evalue_tests.cpp
Normal file
@@ -0,0 +1,62 @@
|
||||
/*******************************************************************************
|
||||
* 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 "../meta_untests.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
enum class color : unsigned {
|
||||
red = 0xFF0000,
|
||||
green = 0x00FF00,
|
||||
blue = 0x0000FF,
|
||||
white = red | green | blue,
|
||||
};
|
||||
}
|
||||
|
||||
TEST_CASE("meta/meta_states/evalue") {
|
||||
namespace meta = meta_hpp;
|
||||
|
||||
meta::enum_<color>()
|
||||
.evalue_("red", color::red)
|
||||
.evalue_("green", color::green)
|
||||
.evalue_("blue", color::blue)
|
||||
.evalue_("white", color::white);
|
||||
|
||||
const meta::enum_type color_type = meta::resolve_type<color>();
|
||||
REQUIRE(color_type);
|
||||
|
||||
SUBCASE("") {
|
||||
const meta::evalue evalue;
|
||||
CHECK_FALSE(evalue);
|
||||
CHECK_FALSE(evalue.is_valid());
|
||||
CHECK(evalue == color_type.get_evalue("non-existent-evalue"));
|
||||
}
|
||||
|
||||
SUBCASE("operators") {
|
||||
const meta::evalue blue_e = color_type.get_evalue("blue");
|
||||
const meta::evalue white_e = color_type.get_evalue("white");
|
||||
CHECK(blue_e == blue_e);
|
||||
CHECK(blue_e != white_e);
|
||||
CHECK((blue_e < white_e || white_e < blue_e));
|
||||
}
|
||||
|
||||
SUBCASE("green") {
|
||||
const meta::evalue evalue = color_type.get_evalue("green");
|
||||
REQUIRE(evalue);
|
||||
|
||||
CHECK(evalue.get_index().get_type() == evalue.get_type());
|
||||
CHECK(evalue.get_index().get_name() == "green");
|
||||
|
||||
CHECK(evalue.get_type() == meta::resolve_type<color>());
|
||||
CHECK(evalue.get_name() == "green");
|
||||
|
||||
CHECK(evalue.get_value() == color::green);
|
||||
CHECK(evalue.get_value().get_type() == color_type);
|
||||
|
||||
CHECK(evalue.get_underlying_value() == meta::detail::to_underlying(color::green));
|
||||
CHECK(evalue.get_underlying_value().get_type() == color_type.get_underlying_type());
|
||||
}
|
||||
}
|
||||
72
develop/untests/meta_states/function2_tests.cpp
Normal file
72
develop/untests/meta_states/function2_tests.cpp
Normal file
@@ -0,0 +1,72 @@
|
||||
/*******************************************************************************
|
||||
* This file is part of the "https://github.com/blackmatov/meta.hpp"
|
||||
* For conditions of distribution and use, see copyright notice in LICENSE.md
|
||||
* Copyright (C) 2021-2023, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
******************************************************************************/
|
||||
|
||||
#include "../meta_untests.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
struct ivec2 {
|
||||
int x{};
|
||||
int y{};
|
||||
|
||||
static ivec2 iadd(const ivec2& l, const ivec2& r) noexcept {
|
||||
return {l.x + r.x, l.y + r.y};
|
||||
}
|
||||
|
||||
static ivec2 isub(const ivec2& l, const ivec2& r) noexcept {
|
||||
return {l.x - r.x, l.y - r.y};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
TEST_CASE("meta/meta_states/function2") {
|
||||
namespace meta = meta_hpp;
|
||||
|
||||
meta::class_<ivec2>()
|
||||
.function_("iadd", &ivec2::iadd, { "l" })
|
||||
.function_("isub", &ivec2::isub, { "l", "r" });
|
||||
|
||||
const meta::class_type ivec2_type = meta::resolve_type<ivec2>();
|
||||
REQUIRE(ivec2_type);
|
||||
|
||||
SUBCASE("iadd2") {
|
||||
const meta::function func = ivec2_type.get_function("iadd");
|
||||
REQUIRE(func);
|
||||
|
||||
CHECK(func.get_arguments().size() == 2);
|
||||
|
||||
REQUIRE(func.get_argument(0));
|
||||
CHECK(func.get_argument(0).get_type() == meta::resolve_type<const ivec2&>());
|
||||
CHECK(func.get_argument(0).get_position() == 0);
|
||||
CHECK(func.get_argument(0).get_name() == "l");
|
||||
|
||||
REQUIRE(func.get_argument(1));
|
||||
CHECK(func.get_argument(1).get_type() == meta::resolve_type<const ivec2&>());
|
||||
CHECK(func.get_argument(1).get_position() == 1);
|
||||
CHECK(func.get_argument(1).get_name() == "");
|
||||
|
||||
CHECK_FALSE(func.get_argument(2));
|
||||
}
|
||||
|
||||
SUBCASE("isub2") {
|
||||
const meta::function func = ivec2_type.get_function("isub");
|
||||
REQUIRE(func);
|
||||
|
||||
REQUIRE(func.get_arguments().size() == 2);
|
||||
|
||||
REQUIRE(func.get_argument(0));
|
||||
CHECK(func.get_argument(0).get_type() == meta::resolve_type<const ivec2&>());
|
||||
CHECK(func.get_argument(0).get_position() == 0);
|
||||
CHECK(func.get_argument(0).get_name() == "l");
|
||||
|
||||
REQUIRE(func.get_argument(1));
|
||||
CHECK(func.get_argument(1).get_type() == meta::resolve_type<const ivec2&>());
|
||||
CHECK(func.get_argument(1).get_position() == 1);
|
||||
CHECK(func.get_argument(1).get_name() == "r");
|
||||
|
||||
CHECK_FALSE(func.get_argument(2));
|
||||
}
|
||||
}
|
||||
247
develop/untests/meta_states/function_tests.cpp
Normal file
247
develop/untests/meta_states/function_tests.cpp
Normal file
@@ -0,0 +1,247 @@
|
||||
/*******************************************************************************
|
||||
* 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 "../meta_untests.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
struct ivec2 {
|
||||
int x{};
|
||||
int y{};
|
||||
|
||||
static ivec2 iadd(const ivec2& l, const ivec2& r) noexcept {
|
||||
return {l.x + r.x, l.y + r.y};
|
||||
}
|
||||
|
||||
static int ilength2(const ivec2& v) noexcept {
|
||||
return v.x * v.x + v.y * v.y;
|
||||
}
|
||||
|
||||
static bool arg_nullptr(const void* ptr) { return ptr == nullptr; }
|
||||
static int arg_bounded_arr(ivec2 vs[2]) { return vs[0].x + vs[0].y + vs[1].x + vs[1].y; }
|
||||
static int arg_unbounded_arr(ivec2 vs[]) { return vs[0].x + vs[0].y + vs[1].x + vs[1].y; }
|
||||
static int arg_bounded_const_arr(const ivec2 vs[2]) { return vs[0].x + vs[0].y + vs[1].x + vs[1].y; }
|
||||
static int arg_unbounded_const_arr(const ivec2 vs[]) { return vs[0].x + vs[0].y + vs[1].x + vs[1].y; }
|
||||
};
|
||||
|
||||
[[maybe_unused]] bool operator==(const ivec2& l, const ivec2& r) noexcept {
|
||||
return l.x == r.x && l.y == r.y;
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("meta/meta_states/function") {
|
||||
namespace meta = meta_hpp;
|
||||
|
||||
meta::class_<ivec2>()
|
||||
.function_("iadd", &ivec2::iadd)
|
||||
.function_("ilength2", &ivec2::ilength2)
|
||||
.function_("arg_nullptr", &ivec2::arg_nullptr)
|
||||
.function_("arg_bounded_arr", &ivec2::arg_bounded_arr)
|
||||
.function_("arg_unbounded_arr", &ivec2::arg_unbounded_arr)
|
||||
.function_("arg_bounded_const_arr", &ivec2::arg_bounded_const_arr)
|
||||
.function_("arg_unbounded_const_arr", &ivec2::arg_unbounded_const_arr);
|
||||
|
||||
const meta::class_type ivec2_type = meta::resolve_type<ivec2>();
|
||||
REQUIRE(ivec2_type);
|
||||
|
||||
SUBCASE("") {
|
||||
const meta::function func;
|
||||
CHECK_FALSE(func);
|
||||
CHECK_FALSE(func.is_valid());
|
||||
CHECK(func == ivec2_type.get_function("non-existent-function"));
|
||||
}
|
||||
|
||||
SUBCASE("operators") {
|
||||
const meta::function iadd_f = ivec2_type.get_function("iadd");
|
||||
const meta::function ilength2_f = ivec2_type.get_function("ilength2");
|
||||
CHECK(iadd_f == iadd_f);
|
||||
CHECK(iadd_f != ilength2_f);
|
||||
CHECK((iadd_f < ilength2_f || ilength2_f < iadd_f));
|
||||
}
|
||||
|
||||
SUBCASE("iadd") {
|
||||
const meta::function func = ivec2_type.get_function("iadd");
|
||||
REQUIRE(func);
|
||||
|
||||
CHECK(func.get_index().get_type() == func.get_type());
|
||||
CHECK(func.get_index().get_name() == "iadd");
|
||||
|
||||
CHECK(func.get_type() == meta::resolve_type(&ivec2::iadd));
|
||||
CHECK(func.get_name() == "iadd");
|
||||
|
||||
CHECK_FALSE(func.is_invocable_with<>());
|
||||
CHECK_FALSE(func.is_invocable_with<int>());
|
||||
CHECK_FALSE(func.is_invocable_with<ivec2, int>());
|
||||
CHECK_FALSE(func.is_invocable_with<int, ivec2>());
|
||||
CHECK_FALSE(func.is_invocable_with<ivec2, ivec2, int>());
|
||||
|
||||
CHECK(func.is_invocable_with<ivec2, ivec2>());
|
||||
CHECK(func.is_invocable_with<const ivec2&, ivec2&&>());
|
||||
|
||||
CHECK_THROWS(func.invoke());
|
||||
CHECK_THROWS(func.invoke(42));
|
||||
CHECK_THROWS(func.invoke(ivec2{}, 42));
|
||||
CHECK_THROWS(func.invoke(42, ivec2{}));
|
||||
CHECK_THROWS(func.invoke(ivec2{}, ivec2{}, 42));
|
||||
|
||||
CHECK(func.invoke(ivec2{1,2}, ivec2{3,4}));
|
||||
CHECK(func.invoke(ivec2{1,2}, ivec2{3,4}) == ivec2{4,6});
|
||||
}
|
||||
|
||||
SUBCASE("ilength2") {
|
||||
const meta::function func = ivec2_type.get_function("ilength2");
|
||||
REQUIRE(func);
|
||||
|
||||
CHECK(func.get_index().get_type() == func.get_type());
|
||||
CHECK(func.get_index().get_name() == "ilength2");
|
||||
|
||||
CHECK(func.get_type() == meta::resolve_type(&ivec2::ilength2));
|
||||
CHECK(func.get_name() == "ilength2");
|
||||
|
||||
CHECK_FALSE(func.is_invocable_with<>());
|
||||
CHECK_FALSE(func.is_invocable_with<int>());
|
||||
CHECK_FALSE(func.is_invocable_with<ivec2, int>());
|
||||
|
||||
CHECK(func.is_invocable_with<ivec2>());
|
||||
CHECK(func.is_invocable_with<const ivec2&>());
|
||||
|
||||
CHECK_THROWS(func.invoke());
|
||||
CHECK_THROWS(func.invoke(42));
|
||||
CHECK_THROWS(func.invoke(ivec2{}, 42));
|
||||
|
||||
CHECK(func.invoke(ivec2{2,3}));
|
||||
CHECK(func.invoke(ivec2{2,3}) == 13);
|
||||
}
|
||||
|
||||
SUBCASE("arg_null") {
|
||||
const meta::function func = ivec2_type.get_function("arg_nullptr");
|
||||
REQUIRE(func);
|
||||
|
||||
CHECK(func.is_invocable_with<int*>());
|
||||
CHECK(func.is_invocable_with<const int*>());
|
||||
CHECK(func.is_invocable_with<std::nullptr_t>());
|
||||
|
||||
int i{42};
|
||||
CHECK(func.invoke(&i) == false);
|
||||
CHECK(func.invoke(nullptr) == true);
|
||||
}
|
||||
|
||||
SUBCASE("arg_arr") {
|
||||
ivec2 bounded_arr[2]{{1,2},{3,4}};
|
||||
ivec2* unbounded_arr = bounded_arr;
|
||||
|
||||
const ivec2 bounded_const_arr[2]{{1,2},{3,4}};
|
||||
const ivec2* unbounded_const_arr = bounded_const_arr;
|
||||
|
||||
{
|
||||
const meta::function func1 = ivec2_type.get_function("arg_bounded_arr");
|
||||
REQUIRE(func1);
|
||||
|
||||
CHECK(func1.is_invocable_with<ivec2*>());
|
||||
CHECK(func1.is_invocable_with<ivec2* const>());
|
||||
CHECK_FALSE(func1.is_invocable_with<const ivec2*>());
|
||||
CHECK_FALSE(func1.is_invocable_with<const ivec2* const>());
|
||||
|
||||
CHECK(func1.invoke(bounded_arr) == 10);
|
||||
CHECK(func1.invoke(unbounded_arr) == 10);
|
||||
CHECK_THROWS(func1.invoke(bounded_const_arr));
|
||||
CHECK_THROWS(func1.invoke(unbounded_const_arr));
|
||||
|
||||
CHECK(func1.invoke(meta::uvalue{bounded_arr}) == 10);
|
||||
CHECK(func1.invoke(meta::uvalue{unbounded_arr}) == 10);
|
||||
CHECK_THROWS(func1.invoke(meta::uvalue{bounded_const_arr}));
|
||||
CHECK_THROWS(func1.invoke(meta::uvalue{unbounded_const_arr}));
|
||||
|
||||
static_assert(std::is_invocable_v<decltype(&ivec2::arg_bounded_arr), decltype(bounded_arr)>);
|
||||
static_assert(std::is_invocable_v<decltype(&ivec2::arg_bounded_arr), decltype(unbounded_arr)>);
|
||||
static_assert(!std::is_invocable_v<decltype(&ivec2::arg_bounded_arr), decltype(bounded_const_arr)>);
|
||||
static_assert(!std::is_invocable_v<decltype(&ivec2::arg_bounded_arr), decltype(unbounded_const_arr)>);
|
||||
}
|
||||
|
||||
{
|
||||
const meta::function func2 = ivec2_type.get_function("arg_unbounded_arr");
|
||||
REQUIRE(func2);
|
||||
|
||||
CHECK(func2.is_invocable_with<ivec2*>());
|
||||
CHECK(func2.is_invocable_with<ivec2* const>());
|
||||
CHECK_FALSE(func2.is_invocable_with<const ivec2*>());
|
||||
CHECK_FALSE(func2.is_invocable_with<const ivec2* const>());
|
||||
|
||||
CHECK(func2.invoke(bounded_arr) == 10);
|
||||
CHECK(func2.invoke(unbounded_arr) == 10);
|
||||
CHECK_THROWS(func2.invoke(bounded_const_arr));
|
||||
CHECK_THROWS(func2.invoke(unbounded_const_arr));
|
||||
|
||||
CHECK(func2.invoke(meta::uvalue{bounded_arr}) == 10);
|
||||
CHECK(func2.invoke(meta::uvalue{unbounded_arr}) == 10);
|
||||
CHECK_THROWS(func2.invoke(meta::uvalue{bounded_const_arr}));
|
||||
CHECK_THROWS(func2.invoke(meta::uvalue{unbounded_const_arr}));
|
||||
|
||||
static_assert(std::is_invocable_v<decltype(&ivec2::arg_unbounded_arr), decltype(bounded_arr)>);
|
||||
static_assert(std::is_invocable_v<decltype(&ivec2::arg_unbounded_arr), decltype(unbounded_arr)>);
|
||||
static_assert(!std::is_invocable_v<decltype(&ivec2::arg_unbounded_arr), decltype(bounded_const_arr)>);
|
||||
static_assert(!std::is_invocable_v<decltype(&ivec2::arg_unbounded_arr), decltype(unbounded_const_arr)>);
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("arg_const_arr") {
|
||||
ivec2 bounded_arr[2]{{1,2},{3,4}};
|
||||
ivec2* unbounded_arr = bounded_arr;
|
||||
|
||||
const ivec2 bounded_const_arr[2]{{1,2},{3,4}};
|
||||
const ivec2* unbounded_const_arr = bounded_const_arr;
|
||||
|
||||
{
|
||||
const meta::function func1 = ivec2_type.get_function("arg_bounded_const_arr");
|
||||
REQUIRE(func1);
|
||||
|
||||
CHECK(func1.is_invocable_with<ivec2*>());
|
||||
CHECK(func1.is_invocable_with<ivec2* const>());
|
||||
CHECK(func1.is_invocable_with<const ivec2*>());
|
||||
CHECK(func1.is_invocable_with<const ivec2* const>());
|
||||
|
||||
CHECK(func1.invoke(bounded_arr) == 10);
|
||||
CHECK(func1.invoke(unbounded_arr) == 10);
|
||||
CHECK(func1.invoke(bounded_const_arr) == 10);
|
||||
CHECK(func1.invoke(unbounded_const_arr) == 10);
|
||||
|
||||
CHECK(func1.invoke(meta::uvalue{bounded_arr}) == 10);
|
||||
CHECK(func1.invoke(meta::uvalue{unbounded_arr}) == 10);
|
||||
CHECK(func1.invoke(meta::uvalue{bounded_const_arr}) == 10);
|
||||
CHECK(func1.invoke(meta::uvalue{unbounded_const_arr}) == 10);
|
||||
|
||||
static_assert(std::is_invocable_v<decltype(&ivec2::arg_bounded_const_arr), decltype(bounded_arr)>);
|
||||
static_assert(std::is_invocable_v<decltype(&ivec2::arg_bounded_const_arr), decltype(unbounded_arr)>);
|
||||
static_assert(std::is_invocable_v<decltype(&ivec2::arg_bounded_const_arr), decltype(bounded_const_arr)>);
|
||||
static_assert(std::is_invocable_v<decltype(&ivec2::arg_bounded_const_arr), decltype(unbounded_const_arr)>);
|
||||
}
|
||||
|
||||
{
|
||||
const meta::function func2 = ivec2_type.get_function("arg_unbounded_const_arr");
|
||||
REQUIRE(func2);
|
||||
|
||||
CHECK(func2.is_invocable_with<ivec2*>());
|
||||
CHECK(func2.is_invocable_with<ivec2* const>());
|
||||
CHECK(func2.is_invocable_with<const ivec2*>());
|
||||
CHECK(func2.is_invocable_with<const ivec2* const>());
|
||||
|
||||
CHECK(func2.invoke(bounded_arr) == 10);
|
||||
CHECK(func2.invoke(unbounded_arr) == 10);
|
||||
CHECK(func2.invoke(bounded_const_arr) == 10);
|
||||
CHECK(func2.invoke(unbounded_const_arr) == 10);
|
||||
|
||||
CHECK(func2.invoke(meta::uvalue{bounded_arr}) == 10);
|
||||
CHECK(func2.invoke(meta::uvalue{unbounded_arr}) == 10);
|
||||
CHECK(func2.invoke(meta::uvalue{bounded_const_arr}) == 10);
|
||||
CHECK(func2.invoke(meta::uvalue{unbounded_const_arr}) == 10);
|
||||
|
||||
static_assert(std::is_invocable_v<decltype(&ivec2::arg_unbounded_const_arr), decltype(bounded_arr)>);
|
||||
static_assert(std::is_invocable_v<decltype(&ivec2::arg_unbounded_const_arr), decltype(unbounded_arr)>);
|
||||
static_assert(std::is_invocable_v<decltype(&ivec2::arg_unbounded_const_arr), decltype(bounded_const_arr)>);
|
||||
static_assert(std::is_invocable_v<decltype(&ivec2::arg_unbounded_const_arr), decltype(unbounded_const_arr)>);
|
||||
}
|
||||
}
|
||||
}
|
||||
313
develop/untests/meta_states/member_tests.cpp
Normal file
313
develop/untests/meta_states/member_tests.cpp
Normal file
@@ -0,0 +1,313 @@
|
||||
/*******************************************************************************
|
||||
* 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 "../meta_untests.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
struct clazz_1 {
|
||||
int int_member = 1;
|
||||
const int const_int_member = 2;
|
||||
std::unique_ptr<int> unique_int_member = std::make_unique<int>(42);
|
||||
};
|
||||
|
||||
struct clazz_2 {};
|
||||
}
|
||||
|
||||
TEST_CASE("meta/meta_states/member") {
|
||||
namespace meta = meta_hpp;
|
||||
|
||||
meta::class_<clazz_1>()
|
||||
.member_("int_member", &clazz_1::int_member)
|
||||
.member_("const_int_member", &clazz_1::const_int_member)
|
||||
// .member_("unique_int_member", &clazz_1::unique_int_member)
|
||||
.member_("unique_int_member_as_ptr", &clazz_1::unique_int_member, meta::member_policy::as_pointer)
|
||||
.member_("unique_int_member_as_ref", &clazz_1::unique_int_member, meta::member_policy::as_reference_wrapper);
|
||||
|
||||
const meta::class_type clazz_1_type = meta::resolve_type<clazz_1>();
|
||||
REQUIRE(clazz_1_type);
|
||||
|
||||
SUBCASE("") {
|
||||
const meta::member member;
|
||||
CHECK_FALSE(member);
|
||||
CHECK_FALSE(member.is_valid());
|
||||
CHECK(member == clazz_1_type.get_member("non-existent-member"));
|
||||
}
|
||||
|
||||
SUBCASE("operators") {
|
||||
meta::member int_member_m = clazz_1_type.get_member("int_member");
|
||||
meta::member const_int_member_m = clazz_1_type.get_member("const_int_member");
|
||||
CHECK(int_member_m == int_member_m);
|
||||
CHECK(int_member_m != const_int_member_m);
|
||||
CHECK((int_member_m < const_int_member_m || const_int_member_m < int_member_m));
|
||||
}
|
||||
|
||||
SUBCASE("int") {
|
||||
meta::member vm = clazz_1_type.get_member("int_member");
|
||||
REQUIRE(vm);
|
||||
|
||||
CHECK(vm.get_type() == meta::resolve_type(&clazz_1::int_member));
|
||||
CHECK(vm.get_name() == "int_member");
|
||||
|
||||
clazz_1 v;
|
||||
clazz_2 v2;
|
||||
|
||||
{
|
||||
CHECK(vm.is_gettable_with<clazz_1>());
|
||||
CHECK(vm.is_gettable_with<clazz_1*>());
|
||||
CHECK(vm.is_gettable_with<clazz_1&>());
|
||||
CHECK(vm.is_gettable_with<clazz_1&&>());
|
||||
CHECK(vm.is_gettable_with<const clazz_1>());
|
||||
CHECK(vm.is_gettable_with<const clazz_1*>());
|
||||
CHECK(vm.is_gettable_with<const clazz_1&>());
|
||||
CHECK(vm.is_gettable_with<const clazz_1&&>());
|
||||
|
||||
CHECK(vm.is_gettable_with(v));
|
||||
CHECK(vm.is_gettable_with(&v));
|
||||
CHECK(vm.is_gettable_with(std::as_const(v)));
|
||||
CHECK(vm.is_gettable_with(&std::as_const(v)));
|
||||
CHECK(vm.is_gettable_with(std::move(v)));
|
||||
CHECK(vm.is_gettable_with(std::move(std::as_const(v))));
|
||||
|
||||
CHECK_FALSE(vm.is_gettable_with<clazz_2>());
|
||||
CHECK_FALSE(vm.is_gettable_with<clazz_2*>());
|
||||
CHECK_FALSE(vm.is_gettable_with(v2));
|
||||
CHECK_FALSE(vm.is_gettable_with(&v2));
|
||||
}
|
||||
|
||||
{
|
||||
CHECK(vm.get(v) == 1);
|
||||
CHECK(vm.get(&v) == 1);
|
||||
CHECK(vm.get(std::as_const(v)) == 1);
|
||||
CHECK(vm.get(&std::as_const(v)) == 1);
|
||||
CHECK(vm.get(std::move(v)) == 1);
|
||||
CHECK(vm.get(std::move(std::as_const(v))) == 1);
|
||||
|
||||
CHECK(vm(v) == 1);
|
||||
CHECK(vm(&v) == 1);
|
||||
CHECK(vm(std::as_const(v)) == 1);
|
||||
CHECK(vm(&std::as_const(v)) == 1);
|
||||
CHECK(vm(std::move(v)) == 1);
|
||||
CHECK(vm(std::move(std::as_const(v))) == 1);
|
||||
|
||||
CHECK_THROWS(std::ignore = vm.get(v2));
|
||||
CHECK_THROWS(std::ignore = vm.get(&v2));
|
||||
CHECK_THROWS(std::ignore = vm(v2));
|
||||
CHECK_THROWS(std::ignore = vm(&v2));
|
||||
}
|
||||
|
||||
{
|
||||
CHECK(vm.is_settable_with<clazz_1, int>());
|
||||
CHECK(vm.is_settable_with<clazz_1*, int>());
|
||||
CHECK(vm.is_settable_with<clazz_1&, int>());
|
||||
CHECK(vm.is_settable_with<clazz_1&&, int>());
|
||||
|
||||
CHECK(vm.is_settable_with<clazz_1, int&&>());
|
||||
CHECK(vm.is_settable_with<clazz_1*, int&&>());
|
||||
CHECK(vm.is_settable_with<clazz_1&, int&&>());
|
||||
CHECK(vm.is_settable_with<clazz_1&&, int&&>());
|
||||
|
||||
CHECK(vm.is_settable_with(v, 10));
|
||||
CHECK(vm.is_settable_with(&v, 10));
|
||||
CHECK(vm.is_settable_with(std::move(v), 12));
|
||||
|
||||
CHECK_FALSE(vm.is_settable_with<clazz_1, float>());
|
||||
CHECK_FALSE(vm.is_settable_with<clazz_1*, float>());
|
||||
CHECK_FALSE(vm.is_settable_with<clazz_1&, float>());
|
||||
CHECK_FALSE(vm.is_settable_with<clazz_1&&, float>());
|
||||
|
||||
CHECK_FALSE(vm.is_settable_with<const clazz_1, int>());
|
||||
CHECK_FALSE(vm.is_settable_with<const clazz_1*, int>());
|
||||
CHECK_FALSE(vm.is_settable_with<const clazz_1&, int>());
|
||||
CHECK_FALSE(vm.is_settable_with<const clazz_1&&, int>());
|
||||
|
||||
CHECK_FALSE(vm.is_settable_with<clazz_2*, int>());
|
||||
CHECK_FALSE(vm.is_settable_with<clazz_2&, int>());
|
||||
|
||||
CHECK_FALSE(vm.is_settable_with(v2, 10));
|
||||
CHECK_FALSE(vm.is_settable_with(&v2, 10));
|
||||
CHECK_FALSE(vm.is_settable_with(std::move(v2), 10));
|
||||
CHECK_FALSE(vm.is_settable_with(v, 10.0));
|
||||
CHECK_FALSE(vm.is_settable_with(&v, 10.0));
|
||||
CHECK_FALSE(vm.is_settable_with(std::move(v), 12.0));
|
||||
}
|
||||
|
||||
{
|
||||
CHECK_NOTHROW(vm.set(v, 10)); CHECK(vm.get(v) == 10);
|
||||
CHECK_NOTHROW(vm.set(&v, 100)); CHECK(vm.get(v) == 100);
|
||||
CHECK_THROWS(vm.set(std::as_const(v), 11)); CHECK(vm.get(v) == 100);
|
||||
CHECK_THROWS(vm.set(&std::as_const(v), 11)); CHECK(vm.get(v) == 100);
|
||||
|
||||
CHECK_NOTHROW(vm.set(std::move(v), 12)); CHECK(vm.get(v) == 12);
|
||||
CHECK_THROWS(vm.set(std::move(std::as_const(v)), 13)); CHECK(vm.get(v) == 12);
|
||||
|
||||
CHECK_NOTHROW(vm(v, 13)); CHECK(vm(v) == 13);
|
||||
CHECK_NOTHROW(vm(&v, 130)); CHECK(vm(v) == 130);
|
||||
CHECK_THROWS(vm(std::as_const(v), 14)); CHECK(vm(v) == 130);
|
||||
CHECK_THROWS(vm(std::as_const(v), 14)); CHECK(vm(v) == 130);
|
||||
|
||||
CHECK_NOTHROW(vm(std::move(v), 15)); CHECK(vm(v) == 15);
|
||||
CHECK_THROWS(vm(std::move(std::as_const(v)), 16)); CHECK(vm(v) == 15);
|
||||
|
||||
CHECK_THROWS(vm.set(v2, 17));
|
||||
CHECK_THROWS(vm.set(&v2, 17));
|
||||
CHECK_THROWS(vm(v2, 17));
|
||||
CHECK_THROWS(vm(&v2, 17));
|
||||
CHECK(vm(v) == 15);
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("const int") {
|
||||
meta::member vm = clazz_1_type.get_member("const_int_member");
|
||||
REQUIRE(vm);
|
||||
|
||||
CHECK(vm.get_type() == meta::resolve_type(&clazz_1::const_int_member));
|
||||
CHECK(vm.get_name() == "const_int_member");
|
||||
|
||||
clazz_1 v;
|
||||
clazz_2 v2;
|
||||
|
||||
{
|
||||
CHECK(vm.is_gettable_with<clazz_1>());
|
||||
CHECK(vm.is_gettable_with<clazz_1*>());
|
||||
CHECK(vm.is_gettable_with<clazz_1&>());
|
||||
CHECK(vm.is_gettable_with<clazz_1&&>());
|
||||
CHECK(vm.is_gettable_with<const clazz_1>());
|
||||
CHECK(vm.is_gettable_with<const clazz_1*>());
|
||||
CHECK(vm.is_gettable_with<const clazz_1&>());
|
||||
CHECK(vm.is_gettable_with<const clazz_1&&>());
|
||||
|
||||
CHECK(vm.is_gettable_with(v));
|
||||
CHECK(vm.is_gettable_with(&v));
|
||||
CHECK(vm.is_gettable_with(std::as_const(v)));
|
||||
CHECK(vm.is_gettable_with(&std::as_const(v)));
|
||||
CHECK(vm.is_gettable_with(std::move(v)));
|
||||
CHECK(vm.is_gettable_with(std::move(std::as_const(v))));
|
||||
|
||||
CHECK_FALSE(vm.is_gettable_with<clazz_2>());
|
||||
CHECK_FALSE(vm.is_gettable_with<clazz_2*>());
|
||||
CHECK_FALSE(vm.is_gettable_with(v2));
|
||||
CHECK_FALSE(vm.is_gettable_with(&v2));
|
||||
}
|
||||
|
||||
{
|
||||
CHECK(vm.get(v) == 2);
|
||||
CHECK(vm.get(&v) == 2);
|
||||
CHECK(vm.get(std::as_const(v)) == 2);
|
||||
CHECK(vm.get(&std::as_const(v)) == 2);
|
||||
CHECK(vm.get(std::move(v)) == 2);
|
||||
CHECK(vm.get(std::move(std::as_const(v))) == 2);
|
||||
|
||||
CHECK(vm(v) == 2);
|
||||
CHECK(vm(&v) == 2);
|
||||
CHECK(vm(std::as_const(v)) == 2);
|
||||
CHECK(vm(&std::as_const(v)) == 2);
|
||||
CHECK(vm(std::move(v)) == 2);
|
||||
CHECK(vm(std::move(std::as_const(v))) == 2);
|
||||
|
||||
CHECK_THROWS(std::ignore = vm.get(v2));
|
||||
CHECK_THROWS(std::ignore = vm.get(&v2));
|
||||
CHECK_THROWS(std::ignore = vm(v2));
|
||||
CHECK_THROWS(std::ignore = vm(&v2));
|
||||
}
|
||||
|
||||
{
|
||||
CHECK_FALSE(vm.is_settable_with<clazz_1, int>());
|
||||
CHECK_FALSE(vm.is_settable_with<clazz_1*, int>());
|
||||
CHECK_FALSE(vm.is_settable_with<clazz_1&, int>());
|
||||
CHECK_FALSE(vm.is_settable_with<clazz_1&&, int>());
|
||||
|
||||
CHECK_FALSE(vm.is_settable_with<clazz_1, int&&>());
|
||||
CHECK_FALSE(vm.is_settable_with<clazz_1*, int&&>());
|
||||
CHECK_FALSE(vm.is_settable_with<clazz_1&, int&&>());
|
||||
CHECK_FALSE(vm.is_settable_with<clazz_1&&, int&&>());
|
||||
|
||||
CHECK_FALSE(vm.is_settable_with<clazz_1, float>());
|
||||
CHECK_FALSE(vm.is_settable_with<clazz_1*, float>());
|
||||
CHECK_FALSE(vm.is_settable_with<clazz_1&, float>());
|
||||
CHECK_FALSE(vm.is_settable_with<clazz_1&&, float>());
|
||||
|
||||
CHECK_FALSE(vm.is_settable_with<const clazz_1, int>());
|
||||
CHECK_FALSE(vm.is_settable_with<const clazz_1*, int>());
|
||||
CHECK_FALSE(vm.is_settable_with<const clazz_1&, int>());
|
||||
CHECK_FALSE(vm.is_settable_with<const clazz_1&&, int>());
|
||||
|
||||
CHECK_FALSE(vm.is_settable_with(v, 10));
|
||||
CHECK_FALSE(vm.is_settable_with(&v, 10));
|
||||
CHECK_FALSE(vm.is_settable_with(std::move(v), 12));
|
||||
|
||||
CHECK_FALSE(vm.is_settable_with<clazz_2*, int>());
|
||||
CHECK_FALSE(vm.is_settable_with<clazz_2&, int>());
|
||||
CHECK_FALSE(vm.is_settable_with(v2, 10));
|
||||
CHECK_FALSE(vm.is_settable_with(&v2, 10));
|
||||
CHECK_FALSE(vm.is_settable_with(std::move(v2), 12));
|
||||
}
|
||||
|
||||
{
|
||||
CHECK_THROWS(vm.set(v, 10)); CHECK(vm.get(v) == 2);
|
||||
CHECK_THROWS(vm.set(&v, 10)); CHECK(vm.get(v) == 2);
|
||||
CHECK_THROWS(vm.set(std::as_const(v), 11)); CHECK(vm.get(v) == 2);
|
||||
CHECK_THROWS(vm.set(&std::as_const(v), 11)); CHECK(vm.get(v) == 2);
|
||||
CHECK_THROWS(vm.set(std::move(v), 12)); CHECK(vm.get(v) == 2);
|
||||
CHECK_THROWS(vm.set(std::move(std::as_const(v)), 16)); CHECK(vm.get(v) == 2);
|
||||
|
||||
CHECK_THROWS(vm(v, 13)); CHECK(vm(v) == 2);
|
||||
CHECK_THROWS(vm(&v, 13)); CHECK(vm(v) == 2);
|
||||
CHECK_THROWS(vm(std::as_const(v), 14)); CHECK(vm(v) == 2);
|
||||
CHECK_THROWS(vm(&std::as_const(v), 14)); CHECK(vm(v) == 2);
|
||||
CHECK_THROWS(vm(std::move(v), 15)); CHECK(vm(v) == 2);
|
||||
CHECK_THROWS(vm(std::move(std::as_const(v)), 16)); CHECK(vm(v) == 2);
|
||||
|
||||
CHECK_THROWS(vm.set(v2, 17));
|
||||
CHECK_THROWS(vm.set(&v2, 17));
|
||||
CHECK_THROWS(vm(v2, 17));
|
||||
CHECK_THROWS(vm(&v2, 17));
|
||||
CHECK(vm(v) == 2);
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("unique_int_member_as_ptr") {
|
||||
meta::member vm = clazz_1_type.get_member("unique_int_member_as_ptr");
|
||||
REQUIRE(vm);
|
||||
|
||||
CHECK(vm.get_type() == meta::resolve_type(&clazz_1::unique_int_member));
|
||||
CHECK(vm.get_name() == "unique_int_member_as_ptr");
|
||||
|
||||
{
|
||||
clazz_1 v;
|
||||
CHECK(vm.get(v).get_type() == meta::resolve_type<std::unique_ptr<int>*>());
|
||||
CHECK(vm.get(v) == std::addressof(v.unique_int_member));
|
||||
}
|
||||
|
||||
{
|
||||
const clazz_1 v;
|
||||
CHECK(vm.get(v).get_type() == meta::resolve_type<const std::unique_ptr<int>*>());
|
||||
CHECK(vm.get(v) == std::addressof(v.unique_int_member));
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("unique_int_member_as_ref") {
|
||||
meta::member vm = clazz_1_type.get_member("unique_int_member_as_ref");
|
||||
REQUIRE(vm);
|
||||
|
||||
CHECK(vm.get_type() == meta::resolve_type(&clazz_1::unique_int_member));
|
||||
CHECK(vm.get_name() == "unique_int_member_as_ref");
|
||||
|
||||
{
|
||||
clazz_1 v;
|
||||
using ref_t = std::reference_wrapper<std::unique_ptr<int>>;
|
||||
CHECK(vm.get(v).get_type() == meta::resolve_type<ref_t>());
|
||||
CHECK(vm.get(v).get_as<ref_t>().get() == v.unique_int_member);
|
||||
}
|
||||
|
||||
{
|
||||
const clazz_1 v;
|
||||
using ref_t = std::reference_wrapper<const std::unique_ptr<int>>;
|
||||
CHECK(vm.get(v).get_type() == meta::resolve_type<ref_t>());
|
||||
CHECK(vm.get(v).get_as<ref_t>().get() == v.unique_int_member);
|
||||
}
|
||||
}
|
||||
}
|
||||
325
develop/untests/meta_states/metadata_tests.cpp
Normal file
325
develop/untests/meta_states/metadata_tests.cpp
Normal file
@@ -0,0 +1,325 @@
|
||||
/*******************************************************************************
|
||||
* 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 "../meta_untests.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
enum class color : unsigned {
|
||||
red = 0xFF0000,
|
||||
green = 0x00FF00,
|
||||
blue = 0x0000FF,
|
||||
};
|
||||
|
||||
struct ivec2 {
|
||||
int x{};
|
||||
int y{};
|
||||
|
||||
[[maybe_unused]] explicit ivec2(int nv) : x{nv}, y{nv} {}
|
||||
[[maybe_unused]] ivec2(int nx, int ny) : x{nx}, y{ny} {}
|
||||
|
||||
ivec2& add(const ivec2& other) noexcept {
|
||||
x += other.x;
|
||||
y += other.y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
static ivec2 iadd(const ivec2& l, const ivec2& r) noexcept {
|
||||
return {l.x + r.x, l.y + r.y};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
TEST_CASE("meta/meta_states/metadata/enum") {
|
||||
namespace meta = meta_hpp;
|
||||
using namespace std::string_literals;
|
||||
|
||||
meta::enum_<color>({
|
||||
{"desc1", meta::uvalue{"enum-desc1"s}},
|
||||
{"desc2", meta::uvalue{"enum-desc2"s}},
|
||||
})
|
||||
.evalue_("red", color::red, {
|
||||
.metadata{{"desc1", meta::uvalue{"red-color"s}}}
|
||||
})
|
||||
.evalue_("green", color::green, {
|
||||
.metadata{{"desc1", meta::uvalue{"green-color"s}}}
|
||||
})
|
||||
.evalue_("blue", color::blue, {
|
||||
.metadata{{"desc1", meta::uvalue{"blue-color"s}}}
|
||||
});
|
||||
|
||||
// metadata override
|
||||
|
||||
meta::enum_<color>({
|
||||
{"desc2", meta::uvalue{"new-enum-desc2"s}},
|
||||
{"desc3", meta::uvalue{"new-enum-desc3"s}},
|
||||
});
|
||||
|
||||
meta::enum_<color>()
|
||||
.evalue_("red", color::red, {
|
||||
.metadata{
|
||||
{"desc2", meta::uvalue{"new-red-color"s}},
|
||||
}
|
||||
});
|
||||
|
||||
//
|
||||
|
||||
const meta::enum_type color_type = meta::resolve_type<color>();
|
||||
REQUIRE(color_type);
|
||||
|
||||
SUBCASE("color") {
|
||||
CHECK(color_type.get_metadata().at("desc1") == "enum-desc1"s);
|
||||
CHECK(color_type.get_metadata().at("desc2") == "new-enum-desc2"s);
|
||||
CHECK(color_type.get_metadata().at("desc3") == "new-enum-desc3"s);
|
||||
}
|
||||
|
||||
SUBCASE("color::red") {
|
||||
const meta::evalue red_evalue = color_type.get_evalue("red");
|
||||
REQUIRE(red_evalue);
|
||||
CHECK_FALSE(red_evalue.get_metadata().contains("desc1"));
|
||||
CHECK(red_evalue.get_metadata().at("desc2") == "new-red-color"s);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("meta/meta_states/metadata/class") {
|
||||
namespace meta = meta_hpp;
|
||||
using namespace std::string_literals;
|
||||
|
||||
meta::class_<ivec2>({
|
||||
{"desc1", meta::uvalue{"class-desc1"s}},
|
||||
{"desc2", meta::uvalue{"class-desc2"s}},
|
||||
})
|
||||
.constructor_<int>({
|
||||
.arguments{{
|
||||
.name{"v"},
|
||||
.metadata{{"desc", meta::uvalue{"the ctor arg"s}}},
|
||||
}},
|
||||
.metadata{{"desc", meta::uvalue{"one arg 2d vector ctor"s}}},
|
||||
})
|
||||
.constructor_<int, int>({
|
||||
.arguments{{
|
||||
.name{"x"},
|
||||
.metadata{{"desc", meta::uvalue{"the 1st ctor arg"s}}},
|
||||
},{
|
||||
.name{"y"},
|
||||
.metadata{{"desc", meta::uvalue{"the 2nd ctor arg"s}}},
|
||||
}},
|
||||
.metadata{{"desc", meta::uvalue{"two args 2d vector ctor"s}}}
|
||||
})
|
||||
.member_("x", &ivec2::x, {
|
||||
.metadata{{"desc", meta::uvalue{"x-member"s}}}
|
||||
})
|
||||
.member_("y", &ivec2::y, {
|
||||
.metadata{{"desc", meta::uvalue{"y-member"s}}}
|
||||
})
|
||||
.method_("add", &ivec2::add, {
|
||||
.arguments{{
|
||||
.name{"other"},
|
||||
.metadata{{"desc", meta::uvalue{"other-arg"s}}}
|
||||
}},
|
||||
.metadata{{"desc", meta::uvalue{"add-method"s}}}
|
||||
})
|
||||
.function_("iadd", &ivec2::iadd, {
|
||||
.arguments{{
|
||||
.name{"l"},
|
||||
.metadata{{"desc", meta::uvalue{"l-arg"s}}}
|
||||
},{
|
||||
.name{"r"},
|
||||
.metadata{{"desc", meta::uvalue{"r-arg"s}}}
|
||||
}},
|
||||
.metadata{{"desc", meta::uvalue{"iadd-function"s}}}
|
||||
});
|
||||
|
||||
// metadata override
|
||||
|
||||
meta::class_<ivec2>({
|
||||
{"desc2", meta::uvalue{"new-class-desc2"s}},
|
||||
{"desc3", meta::uvalue{"new-class-desc3"s}},
|
||||
});
|
||||
|
||||
//
|
||||
|
||||
const meta::class_type ivec2_type = meta::resolve_type<ivec2>();
|
||||
REQUIRE(ivec2_type);
|
||||
|
||||
SUBCASE("ivec2") {
|
||||
CHECK(ivec2_type.get_metadata().at("desc1") == "class-desc1"s);
|
||||
CHECK(ivec2_type.get_metadata().at("desc2") == "new-class-desc2"s);
|
||||
CHECK(ivec2_type.get_metadata().at("desc3") == "new-class-desc3"s);
|
||||
}
|
||||
|
||||
SUBCASE("ivec2(int)") {
|
||||
const meta::constructor ivec2_ctor = ivec2_type.get_constructor_with<int>();
|
||||
REQUIRE(ivec2_ctor);
|
||||
|
||||
REQUIRE(ivec2_ctor.get_metadata().contains("desc"));
|
||||
CHECK(ivec2_ctor.get_metadata().at("desc") == "one arg 2d vector ctor"s);
|
||||
|
||||
REQUIRE(ivec2_ctor.get_argument(0));
|
||||
CHECK(ivec2_ctor.get_argument(0).get_name() == "v");
|
||||
CHECK(ivec2_ctor.get_argument(0).get_position() == 0);
|
||||
CHECK(ivec2_ctor.get_argument(0).get_type() == meta::resolve_type<int>());
|
||||
REQUIRE(ivec2_ctor.get_argument(0).get_metadata().contains("desc"));
|
||||
CHECK(ivec2_ctor.get_argument(0).get_metadata().at("desc") == "the ctor arg"s);
|
||||
|
||||
REQUIRE_FALSE(ivec2_ctor.get_argument(1));
|
||||
}
|
||||
|
||||
SUBCASE("ivec2(int, int)") {
|
||||
const meta::constructor ivec2_ctor = ivec2_type.get_constructor_with<int, int>();
|
||||
REQUIRE(ivec2_ctor);
|
||||
|
||||
REQUIRE(ivec2_ctor.get_metadata().contains("desc"));
|
||||
CHECK(ivec2_ctor.get_metadata().at("desc") == "two args 2d vector ctor"s);
|
||||
|
||||
REQUIRE(ivec2_ctor.get_argument(0));
|
||||
CHECK(ivec2_ctor.get_argument(0).get_name() == "x");
|
||||
CHECK(ivec2_ctor.get_argument(0).get_position() == 0);
|
||||
CHECK(ivec2_ctor.get_argument(0).get_type() == meta::resolve_type<int>());
|
||||
REQUIRE(ivec2_ctor.get_argument(0).get_metadata().contains("desc"));
|
||||
CHECK(ivec2_ctor.get_argument(0).get_metadata().at("desc") == "the 1st ctor arg"s);
|
||||
|
||||
REQUIRE(ivec2_ctor.get_argument(1));
|
||||
CHECK(ivec2_ctor.get_argument(1).get_name() == "y");
|
||||
CHECK(ivec2_ctor.get_argument(1).get_position() == 1);
|
||||
CHECK(ivec2_ctor.get_argument(1).get_type() == meta::resolve_type<int>());
|
||||
REQUIRE(ivec2_ctor.get_argument(1).get_metadata().contains("desc"));
|
||||
CHECK(ivec2_ctor.get_argument(1).get_metadata().at("desc") == "the 2nd ctor arg"s);
|
||||
|
||||
REQUIRE_FALSE(ivec2_ctor.get_argument(2));
|
||||
}
|
||||
|
||||
SUBCASE("ivec2::x") {
|
||||
const meta::member ivec2_x = ivec2_type.get_member("x");
|
||||
REQUIRE(ivec2_x);
|
||||
|
||||
REQUIRE(ivec2_x.get_metadata().contains("desc"));
|
||||
CHECK(ivec2_x.get_metadata().at("desc") == "x-member"s);
|
||||
}
|
||||
|
||||
SUBCASE("ivec2::y") {
|
||||
const meta::member ivec2_y = ivec2_type.get_member("y");
|
||||
REQUIRE(ivec2_y);
|
||||
|
||||
REQUIRE(ivec2_y.get_metadata().contains("desc"));
|
||||
CHECK(ivec2_y.get_metadata().at("desc") == "y-member"s);
|
||||
}
|
||||
|
||||
SUBCASE("ivec2::add") {
|
||||
const meta::method ivec2_add = ivec2_type.get_method("add");
|
||||
REQUIRE(ivec2_add);
|
||||
|
||||
REQUIRE(ivec2_add.get_metadata().contains("desc"));
|
||||
CHECK(ivec2_add.get_metadata().at("desc") == "add-method"s);
|
||||
|
||||
REQUIRE(ivec2_add.get_argument(0));
|
||||
REQUIRE(ivec2_add.get_argument(0).get_metadata().contains("desc"));
|
||||
CHECK(ivec2_add.get_argument(0).get_metadata().at("desc") == "other-arg"s);
|
||||
}
|
||||
|
||||
SUBCASE("ivec2::iadd") {
|
||||
const meta::function ivec2_iadd = ivec2_type.get_function("iadd");
|
||||
REQUIRE(ivec2_iadd);
|
||||
|
||||
REQUIRE(ivec2_iadd.get_metadata().contains("desc"));
|
||||
CHECK(ivec2_iadd.get_metadata().at("desc") == "iadd-function"s);
|
||||
|
||||
REQUIRE(ivec2_iadd.get_argument(0));
|
||||
REQUIRE(ivec2_iadd.get_argument(0).get_metadata().contains("desc"));
|
||||
CHECK(ivec2_iadd.get_argument(0).get_metadata().at("desc") == "l-arg"s);
|
||||
|
||||
REQUIRE(ivec2_iadd.get_argument(1));
|
||||
REQUIRE(ivec2_iadd.get_argument(1).get_metadata().contains("desc"));
|
||||
CHECK(ivec2_iadd.get_argument(1).get_metadata().at("desc") == "r-arg"s);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("meta/meta_states/metadata/scope") {
|
||||
namespace meta = meta_hpp;
|
||||
using namespace std::string_literals;
|
||||
|
||||
SUBCASE("local_scope") {
|
||||
const meta::scope lscope = meta::local_scope_("local-scope", {
|
||||
{"desc", meta::uvalue{"scope-desc"s}}
|
||||
});
|
||||
CHECK(lscope.get_metadata().at("desc") == "scope-desc"s);
|
||||
}
|
||||
|
||||
SUBCASE("static_scope") {
|
||||
meta::static_scope_("meta/meta_states/metadata/scope/static-scope", {
|
||||
{"desc", meta::uvalue{"scope-desc"s}}
|
||||
});
|
||||
CHECK(meta::resolve_scope("meta/meta_states/metadata/scope/static-scope").get_metadata().at("desc") == "scope-desc"s);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("meta/meta_states/metadata/other") {
|
||||
namespace meta = meta_hpp;
|
||||
using namespace std::string_literals;
|
||||
|
||||
SUBCASE("array") {
|
||||
meta::array_<int[]>({
|
||||
{"desc", meta::uvalue{"int[]-type"s}}
|
||||
});
|
||||
CHECK(meta::resolve_type<int[]>().get_metadata().at("desc") == "int[]-type"s);
|
||||
}
|
||||
|
||||
SUBCASE("function") {
|
||||
meta::function_<int(*)(int)>({
|
||||
{"desc", meta::uvalue{"int->int"s}}
|
||||
});
|
||||
CHECK(meta::resolve_type<int(*)(int)>().get_metadata().at("desc") == "int->int"s);
|
||||
}
|
||||
|
||||
SUBCASE("member") {
|
||||
meta::member_<int ivec2::*>({
|
||||
{"desc", meta::uvalue{"ivec2::int"s}}
|
||||
});
|
||||
CHECK(meta::resolve_type<int ivec2::*>().get_metadata().at("desc") == "ivec2::int"s);
|
||||
}
|
||||
|
||||
SUBCASE("method") {
|
||||
meta::method_<int (ivec2::*)(int)>({
|
||||
{"desc", meta::uvalue{"ivec2(int -> int)"s}}
|
||||
});
|
||||
CHECK(meta::resolve_type<int (ivec2::*)(int)>().get_metadata().at("desc") == "ivec2(int -> int)"s);
|
||||
}
|
||||
|
||||
SUBCASE("nullptr") {
|
||||
meta::nullptr_<std::nullptr_t>({
|
||||
{"desc", meta::uvalue{"nullptr_t"s}}
|
||||
});
|
||||
CHECK(meta::resolve_type<std::nullptr_t>().get_metadata().at("desc") == "nullptr_t"s);
|
||||
}
|
||||
|
||||
SUBCASE("number") {
|
||||
meta::number_<int>({
|
||||
{"desc", meta::uvalue{"int-type"s}}
|
||||
});
|
||||
CHECK(meta::resolve_type<int>().get_metadata().at("desc") == "int-type"s);
|
||||
}
|
||||
|
||||
SUBCASE("pointer") {
|
||||
meta::pointer_<int*>({
|
||||
{"desc", meta::uvalue{"int*-type"s}}
|
||||
});
|
||||
CHECK(meta::resolve_type<int*>().get_metadata().at("desc") == "int*-type"s);
|
||||
}
|
||||
|
||||
SUBCASE("reference") {
|
||||
meta::reference_<int&>({
|
||||
{"desc", meta::uvalue{"int&-type"s}}
|
||||
});
|
||||
CHECK(meta::resolve_type<int&>().get_metadata().at("desc") == "int&-type"s);
|
||||
}
|
||||
|
||||
SUBCASE("void") {
|
||||
meta::void_<void>({
|
||||
{"desc", meta::uvalue{"void-type"s}}
|
||||
});
|
||||
CHECK(meta::resolve_type<void>().get_metadata().at("desc") == "void-type"s);
|
||||
}
|
||||
}
|
||||
45
develop/untests/meta_states/method2_tests.cpp
Normal file
45
develop/untests/meta_states/method2_tests.cpp
Normal file
@@ -0,0 +1,45 @@
|
||||
/*******************************************************************************
|
||||
* 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 "../meta_untests.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
struct ivec2 {
|
||||
int x{};
|
||||
int y{};
|
||||
|
||||
ivec2& add(const ivec2& other) {
|
||||
x += other.x;
|
||||
y += other.y;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
TEST_CASE("meta/meta_states/method2") {
|
||||
namespace meta = meta_hpp;
|
||||
|
||||
meta::class_<ivec2>()
|
||||
.method_("add", &ivec2::add, {"other"});
|
||||
|
||||
const meta::class_type ivec2_type = meta::resolve_type<ivec2>();
|
||||
REQUIRE(ivec2_type);
|
||||
|
||||
SUBCASE("add") {
|
||||
const meta::method add_m = ivec2_type.get_method("add");
|
||||
REQUIRE(add_m);
|
||||
|
||||
CHECK(add_m.get_arguments().size() == 1);
|
||||
|
||||
REQUIRE(add_m.get_argument(0));
|
||||
CHECK(add_m.get_argument(0).get_type() == meta::resolve_type<const ivec2&>());
|
||||
CHECK(add_m.get_argument(0).get_position() == 0);
|
||||
CHECK(add_m.get_argument(0).get_name() == "other");
|
||||
|
||||
CHECK_FALSE(add_m.get_argument(1));
|
||||
}
|
||||
}
|
||||
1141
develop/untests/meta_states/method_tests.cpp
Normal file
1141
develop/untests/meta_states/method_tests.cpp
Normal file
File diff suppressed because it is too large
Load Diff
206
develop/untests/meta_states/scope_tests.cpp
Normal file
206
develop/untests/meta_states/scope_tests.cpp
Normal file
@@ -0,0 +1,206 @@
|
||||
/*******************************************************************************
|
||||
* 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 "../meta_untests.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
enum class color {
|
||||
red,
|
||||
green,
|
||||
blue,
|
||||
};
|
||||
|
||||
struct ivec2 {
|
||||
int x{};
|
||||
int y{};
|
||||
};
|
||||
|
||||
struct ivec3 {
|
||||
int x{};
|
||||
int y{};
|
||||
int z{};
|
||||
};
|
||||
|
||||
ivec2 iadd2(const ivec2& l, const ivec2& r) noexcept {
|
||||
return {l.x + r.x, l.y + r.y};
|
||||
}
|
||||
|
||||
ivec3 iadd3(const ivec3& l, const ivec3& r) noexcept {
|
||||
return {l.x + r.x, l.y + r.y, l.z + r.z};
|
||||
}
|
||||
|
||||
int function_overloaded(int i0) { return i0; }
|
||||
int function_overloaded(int i0, int i1) { return i0 + i1; }
|
||||
|
||||
ivec2 static_ivec2 = ivec2{1, 0};
|
||||
const ivec3 static_const_ivec3 = ivec3{1, 0};
|
||||
}
|
||||
|
||||
TEST_CASE("meta/meta_states/scope") {
|
||||
namespace meta = meta_hpp;
|
||||
|
||||
meta::static_scope_("meta/meta_states/scope/math")
|
||||
.typedef_<color>("color")
|
||||
.typedef_<ivec2>("ivec2")
|
||||
.typedef_<ivec3>("ivec3")
|
||||
.function_("iadd2", &iadd2, {"l", "r"})
|
||||
.function_("iadd3", &iadd3, {"l"})
|
||||
.function_("function_overloaded", meta::select_overload<int(int)>(&function_overloaded))
|
||||
.function_("function_overloaded", meta::select_overload<int(int,int)>(&function_overloaded))
|
||||
.variable_("static_ivec2", &static_ivec2)
|
||||
.variable_("static_const_ivec3", &static_const_ivec3);
|
||||
|
||||
const meta::scope math_scope = meta::resolve_scope("meta/meta_states/scope/math");
|
||||
REQUIRE(math_scope);
|
||||
REQUIRE(math_scope.is_valid());
|
||||
|
||||
CHECK(math_scope.get_name() == "meta/meta_states/scope/math");
|
||||
CHECK(math_scope.get_variables().size() == 2);
|
||||
CHECK(math_scope.get_typedefs().size() == 3);
|
||||
|
||||
SUBCASE("") {
|
||||
const meta::scope scope;
|
||||
CHECK_FALSE(scope);
|
||||
CHECK_FALSE(scope.is_valid());
|
||||
}
|
||||
|
||||
SUBCASE("operators") {
|
||||
const meta::scope math1_s = meta::resolve_scope("meta/meta_states/scope/math1");
|
||||
const meta::scope math2_s = meta::resolve_scope("meta/meta_states/scope/math2");
|
||||
CHECK(math1_s == math1_s);
|
||||
CHECK(math1_s != math2_s);
|
||||
CHECK((math1_s < math2_s || math2_s < math1_s));
|
||||
}
|
||||
|
||||
SUBCASE("classes") {
|
||||
CHECK_FALSE(math_scope.get_typedef("non-existent-class"));
|
||||
|
||||
const meta::any_type ivec2_type = math_scope.get_typedef("ivec2");
|
||||
CHECK(ivec2_type == meta::resolve_type<ivec2>());
|
||||
|
||||
const meta::any_type ivec3_type = math_scope.get_typedef("ivec3");
|
||||
CHECK(ivec3_type == meta::resolve_type<ivec3>());
|
||||
}
|
||||
|
||||
SUBCASE("enums") {
|
||||
CHECK_FALSE(math_scope.get_typedef("non-existent-enum"));
|
||||
|
||||
const meta::any_type color_type = math_scope.get_typedef("color");
|
||||
CHECK(color_type == meta::resolve_type<color>());
|
||||
}
|
||||
|
||||
SUBCASE("functions") {
|
||||
CHECK_FALSE(math_scope.get_function("non-existent-function"));
|
||||
|
||||
const meta::function iadd2_func = math_scope.get_function("iadd2");
|
||||
REQUIRE(iadd2_func);
|
||||
|
||||
{
|
||||
CHECK(iadd2_func.get_arguments().size() == 2);
|
||||
|
||||
REQUIRE(iadd2_func.get_argument(0));
|
||||
CHECK(iadd2_func.get_argument(0).get_type() == meta::resolve_type<const ivec2&>());
|
||||
CHECK(iadd2_func.get_argument(0).get_position() == 0);
|
||||
CHECK(iadd2_func.get_argument(0).get_name() == "l");
|
||||
|
||||
REQUIRE(iadd2_func.get_argument(1));
|
||||
CHECK(iadd2_func.get_argument(1).get_type() == meta::resolve_type<const ivec2&>());
|
||||
CHECK(iadd2_func.get_argument(1).get_position() == 1);
|
||||
CHECK(iadd2_func.get_argument(1).get_name() == "r");
|
||||
|
||||
CHECK_FALSE(iadd2_func.get_argument(2));
|
||||
}
|
||||
|
||||
const meta::function iadd3_func = math_scope.get_function("iadd3");
|
||||
REQUIRE(iadd3_func);
|
||||
|
||||
{
|
||||
CHECK(iadd3_func.get_arguments().size() == 2);
|
||||
|
||||
REQUIRE(iadd3_func.get_argument(0));
|
||||
CHECK(iadd3_func.get_argument(0).get_type() == meta::resolve_type<const ivec3&>());
|
||||
CHECK(iadd3_func.get_argument(0).get_position() == 0);
|
||||
CHECK(iadd3_func.get_argument(0).get_name() == "l");
|
||||
|
||||
REQUIRE(iadd3_func.get_argument(1));
|
||||
CHECK(iadd3_func.get_argument(1).get_type() == meta::resolve_type<const ivec3&>());
|
||||
CHECK(iadd3_func.get_argument(1).get_position() == 1);
|
||||
CHECK(iadd3_func.get_argument(1).get_name() == "");
|
||||
|
||||
CHECK_FALSE(iadd3_func.get_argument(2));
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("function_with") {
|
||||
CHECK(math_scope.get_function("function_overloaded"));
|
||||
|
||||
{
|
||||
CHECK_FALSE(math_scope.get_function_with<>("function_overloaded"));
|
||||
CHECK(math_scope.get_function_with<int>("function_overloaded"));
|
||||
CHECK_FALSE(math_scope.get_function_with<int, float>("function_overloaded"));
|
||||
|
||||
CHECK_FALSE(math_scope.get_function_with<>("function_overloaded"));
|
||||
CHECK_FALSE(math_scope.get_function_with<float>("function_overloaded"));
|
||||
CHECK(math_scope.get_function_with<int, int>("function_overloaded"));
|
||||
CHECK_FALSE(math_scope.get_function_with<float, float>("function_overloaded"));
|
||||
|
||||
CHECK_FALSE(math_scope.get_function_with<>("function_overloaded"));
|
||||
CHECK_FALSE(math_scope.get_function_with<double>("function_overloaded"));
|
||||
CHECK_FALSE(math_scope.get_function_with<double, double>("function_overloaded"));
|
||||
}
|
||||
|
||||
{
|
||||
meta::number_type int_type = meta::resolve_type<int>();
|
||||
meta::number_type float_type = meta::resolve_type<float>();
|
||||
meta::number_type double_type = meta::resolve_type<double>();
|
||||
|
||||
CHECK_FALSE(math_scope.get_function_with<>("function_overloaded"));
|
||||
CHECK(math_scope.get_function_with("function_overloaded", {int_type}));
|
||||
CHECK_FALSE(math_scope.get_function_with("function_overloaded", {int_type, float_type}));
|
||||
|
||||
CHECK_FALSE(math_scope.get_function_with("function_overloaded"));
|
||||
CHECK_FALSE(math_scope.get_function_with("function_overloaded", {float_type}));
|
||||
CHECK(math_scope.get_function_with("function_overloaded", {int_type, int_type}));
|
||||
CHECK_FALSE(math_scope.get_function_with("function_overloaded", {float_type, float_type}));
|
||||
|
||||
CHECK_FALSE(math_scope.get_function_with<>("function_overloaded"));
|
||||
CHECK_FALSE(math_scope.get_function_with("function_overloaded", {double_type}));
|
||||
CHECK_FALSE(math_scope.get_function_with("function_overloaded", {double_type, double_type}));
|
||||
}
|
||||
|
||||
{
|
||||
meta::number_type int_type = meta::resolve_type<int>();
|
||||
meta::number_type float_type = meta::resolve_type<float>();
|
||||
meta::number_type double_type = meta::resolve_type<double>();
|
||||
|
||||
CHECK_FALSE(math_scope.get_function_with<>("function_overloaded"));
|
||||
CHECK(math_scope.get_function_with("function_overloaded", meta::any_type_list{int_type}));
|
||||
CHECK_FALSE(math_scope.get_function_with("function_overloaded", meta::any_type_list{int_type, float_type}));
|
||||
|
||||
CHECK_FALSE(math_scope.get_function_with("function_overloaded"));
|
||||
CHECK_FALSE(math_scope.get_function_with("function_overloaded", meta::any_type_list{float_type}));
|
||||
CHECK(math_scope.get_function_with("function_overloaded", meta::any_type_list{int_type, int_type}));
|
||||
CHECK_FALSE(math_scope.get_function_with("function_overloaded", meta::any_type_list{float_type, float_type}));
|
||||
|
||||
CHECK_FALSE(math_scope.get_function_with<>("function_overloaded"));
|
||||
CHECK_FALSE(math_scope.get_function_with("function_overloaded", meta::any_type_list{double_type}));
|
||||
CHECK_FALSE(math_scope.get_function_with("function_overloaded", meta::any_type_list{double_type, double_type}));
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("variables") {
|
||||
CHECK_FALSE(math_scope.get_variable("non-existent-variable"));
|
||||
|
||||
const meta::variable static_ivec2_var = math_scope.get_variable("static_ivec2");
|
||||
REQUIRE(static_ivec2_var);
|
||||
CHECK(static_ivec2_var.get_type().get_data_type() == meta::resolve_type<ivec2>());
|
||||
|
||||
const meta::variable static_const_ivec3_var = math_scope.get_variable("static_const_ivec3");
|
||||
REQUIRE(static_const_ivec3_var);
|
||||
CHECK(static_const_ivec3_var.get_type().get_data_type() == meta::resolve_type<ivec3>());
|
||||
}
|
||||
}
|
||||
234
develop/untests/meta_states/variable_tests.cpp
Normal file
234
develop/untests/meta_states/variable_tests.cpp
Normal file
@@ -0,0 +1,234 @@
|
||||
/*******************************************************************************
|
||||
* 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 "../meta_untests.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
struct clazz_1 {
|
||||
static int int_variable;
|
||||
static const int const_int_variable;
|
||||
|
||||
static int& ref_int_variable;
|
||||
static const int& const_ref_int_variable;
|
||||
|
||||
static std::unique_ptr<int> unique_int_variable;
|
||||
static const std::unique_ptr<int> const_unique_int_variable;
|
||||
};
|
||||
|
||||
int clazz_1::int_variable = 1;
|
||||
const int clazz_1::const_int_variable = 2;
|
||||
|
||||
int& clazz_1::ref_int_variable = clazz_1::int_variable;
|
||||
const int& clazz_1::const_ref_int_variable = clazz_1::const_int_variable;
|
||||
|
||||
std::unique_ptr<int> clazz_1::unique_int_variable = std::make_unique<int>(42);
|
||||
const std::unique_ptr<int> clazz_1::const_unique_int_variable = std::make_unique<int>(42);
|
||||
}
|
||||
|
||||
TEST_CASE("meta/meta_states/variable") {
|
||||
namespace meta = meta_hpp;
|
||||
|
||||
meta::class_<clazz_1>()
|
||||
.variable_("int_variable", &clazz_1::int_variable)
|
||||
.variable_("const_int_variable", &clazz_1::const_int_variable)
|
||||
.variable_("ref_int_variable", &clazz_1::ref_int_variable)
|
||||
.variable_("const_ref_int_variable", &clazz_1::const_ref_int_variable)
|
||||
|
||||
// .variable_("unique_int_variable", &clazz_1::unique_int_variable)
|
||||
.variable_("unique_int_variable_as_ptr", &clazz_1::unique_int_variable, meta::variable_policy::as_pointer)
|
||||
.variable_("unique_int_variable_as_ref", &clazz_1::unique_int_variable, meta::variable_policy::as_reference_wrapper)
|
||||
|
||||
// .variable_("const_unique_int_variable", &clazz_1::const_unique_int_variable)
|
||||
.variable_("const_unique_int_variable_as_ptr", &clazz_1::const_unique_int_variable, meta::variable_policy::as_pointer)
|
||||
.variable_("const_unique_int_variable_as_ref", &clazz_1::const_unique_int_variable, meta::variable_policy::as_reference_wrapper);
|
||||
|
||||
const meta::class_type clazz_1_type = meta::resolve_type<clazz_1>();
|
||||
REQUIRE(clazz_1_type);
|
||||
|
||||
SUBCASE("") {
|
||||
const meta::variable variable;
|
||||
CHECK_FALSE(variable);
|
||||
CHECK_FALSE(variable.is_valid());
|
||||
CHECK(variable == clazz_1_type.get_variable("non-existent-variable"));
|
||||
}
|
||||
|
||||
SUBCASE("operators") {
|
||||
meta::variable int_variable_v = clazz_1_type.get_variable("int_variable");
|
||||
meta::variable const_int_variable_v = clazz_1_type.get_variable("const_int_variable");
|
||||
CHECK(int_variable_v == int_variable_v);
|
||||
CHECK(int_variable_v != const_int_variable_v);
|
||||
CHECK((int_variable_v < const_int_variable_v || const_int_variable_v < int_variable_v));
|
||||
}
|
||||
|
||||
SUBCASE("int") {
|
||||
meta::variable vm = clazz_1_type.get_variable("int_variable");
|
||||
REQUIRE(vm);
|
||||
|
||||
CHECK(vm.get_type() == meta::resolve_type(&clazz_1::int_variable));
|
||||
CHECK(vm.get_name() == "int_variable");
|
||||
|
||||
CHECK(vm.get() == 1);
|
||||
CHECK(vm() == 1);
|
||||
|
||||
CHECK(vm.is_settable_with<int>());
|
||||
CHECK(vm.is_settable_with<int&&>());
|
||||
CHECK(vm.is_settable_with<const int&>());
|
||||
CHECK(vm.is_settable_with(1));
|
||||
|
||||
CHECK_FALSE(vm.is_settable_with<float>());
|
||||
CHECK_FALSE(vm.is_settable_with<float&&>());
|
||||
CHECK_FALSE(vm.is_settable_with<const float&>());
|
||||
CHECK_FALSE(vm.is_settable_with(1.0));
|
||||
|
||||
CHECK_NOTHROW(vm.set(10)); CHECK(vm.get() == 10);
|
||||
CHECK_NOTHROW(vm(11)); CHECK(vm() == 11);
|
||||
}
|
||||
|
||||
SUBCASE("const int") {
|
||||
meta::variable vm = clazz_1_type.get_variable("const_int_variable");
|
||||
REQUIRE(vm);
|
||||
|
||||
CHECK(vm.get_type() == meta::resolve_type(&clazz_1::const_int_variable));
|
||||
CHECK(vm.get_name() == "const_int_variable");
|
||||
|
||||
CHECK(vm.get() == 2);
|
||||
CHECK(vm() == 2);
|
||||
|
||||
CHECK_FALSE(vm.is_settable_with<int>());
|
||||
CHECK_FALSE(vm.is_settable_with<int&&>());
|
||||
CHECK_FALSE(vm.is_settable_with<const int&>());
|
||||
CHECK_FALSE(vm.is_settable_with(1));
|
||||
|
||||
CHECK_FALSE(vm.is_settable_with<float>());
|
||||
CHECK_FALSE(vm.is_settable_with<float&&>());
|
||||
CHECK_FALSE(vm.is_settable_with<const float&>());
|
||||
CHECK_FALSE(vm.is_settable_with(1.0));
|
||||
|
||||
CHECK_THROWS(vm.set(10)); CHECK(vm.get() == 2);
|
||||
CHECK_THROWS(vm(10)); CHECK(vm() == 2);
|
||||
}
|
||||
|
||||
SUBCASE("ref int") {
|
||||
meta::variable vm = clazz_1_type.get_variable("ref_int_variable");
|
||||
REQUIRE(vm);
|
||||
|
||||
CHECK(vm.get_type() == meta::resolve_type(&clazz_1::ref_int_variable));
|
||||
CHECK(vm.get_name() == "ref_int_variable");
|
||||
|
||||
CHECK(vm.get() == 11);
|
||||
CHECK(vm() == 11);
|
||||
|
||||
CHECK(vm.is_settable_with<int>());
|
||||
CHECK(vm.is_settable_with<int&&>());
|
||||
CHECK(vm.is_settable_with<const int&>());
|
||||
CHECK(vm.is_settable_with(1));
|
||||
|
||||
CHECK_FALSE(vm.is_settable_with<float>());
|
||||
CHECK_FALSE(vm.is_settable_with<float&&>());
|
||||
CHECK_FALSE(vm.is_settable_with<const float&>());
|
||||
CHECK_FALSE(vm.is_settable_with(1.0));
|
||||
|
||||
CHECK_NOTHROW(vm.set(20)); CHECK(vm.get() == 20);
|
||||
CHECK_NOTHROW(vm(21)); CHECK(vm() == 21);
|
||||
}
|
||||
|
||||
SUBCASE("const ref int") {
|
||||
meta::variable vm = clazz_1_type.get_variable("const_ref_int_variable");
|
||||
REQUIRE(vm);
|
||||
|
||||
CHECK(vm.get_type() == meta::resolve_type(&clazz_1::const_ref_int_variable));
|
||||
CHECK(vm.get_name() == "const_ref_int_variable");
|
||||
|
||||
CHECK(vm.get() == 2);
|
||||
CHECK(vm() == 2);
|
||||
|
||||
CHECK_FALSE(vm.is_settable_with<int>());
|
||||
CHECK_FALSE(vm.is_settable_with<int&&>());
|
||||
CHECK_FALSE(vm.is_settable_with<const int&>());
|
||||
CHECK_FALSE(vm.is_settable_with(1));
|
||||
|
||||
CHECK_FALSE(vm.is_settable_with<float>());
|
||||
CHECK_FALSE(vm.is_settable_with<float&&>());
|
||||
CHECK_FALSE(vm.is_settable_with<const float&>());
|
||||
CHECK_FALSE(vm.is_settable_with(1.0));
|
||||
|
||||
CHECK_THROWS(vm.set(10)); CHECK(vm.get() == 2);
|
||||
CHECK_THROWS(vm(11)); CHECK(vm() == 2);
|
||||
}
|
||||
|
||||
SUBCASE("unique_int_variable_as_ptr") {
|
||||
meta::variable vm = clazz_1_type.get_variable("unique_int_variable_as_ptr");
|
||||
REQUIRE(vm);
|
||||
|
||||
CHECK(vm.get().get_type() == meta::resolve_type<std::unique_ptr<int>*>());
|
||||
CHECK(vm.get() == std::addressof(clazz_1::unique_int_variable));
|
||||
|
||||
{
|
||||
auto nv = std::make_unique<int>(11);
|
||||
CHECK_NOTHROW(vm.set(std::move(nv)));
|
||||
CHECK(*clazz_1::unique_int_variable == 11);
|
||||
}
|
||||
|
||||
{
|
||||
auto nv = std::make_unique<int>(12);
|
||||
CHECK_THROWS(vm.set(nv));
|
||||
CHECK(*clazz_1::unique_int_variable == 11);
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("unique_int_variable_as_ref") {
|
||||
meta::variable vm = clazz_1_type.get_variable("unique_int_variable_as_ref");
|
||||
REQUIRE(vm);
|
||||
|
||||
using ref_t = std::reference_wrapper<std::unique_ptr<int>>;
|
||||
CHECK(vm.get().get_type() == meta::resolve_type<ref_t>());
|
||||
CHECK(vm.get().get_as<ref_t>().get() == clazz_1::unique_int_variable);
|
||||
|
||||
{
|
||||
auto nv = std::make_unique<int>(13);
|
||||
CHECK_NOTHROW(vm.set(std::move(nv)));
|
||||
CHECK(*clazz_1::unique_int_variable == 13);
|
||||
}
|
||||
|
||||
{
|
||||
auto nv = std::make_unique<int>(14);
|
||||
CHECK_THROWS(vm.set(nv));
|
||||
CHECK(*clazz_1::unique_int_variable == 13);
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("const_unique_int_variable_as_ptr") {
|
||||
meta::variable vm = clazz_1_type.get_variable("const_unique_int_variable_as_ptr");
|
||||
REQUIRE(vm);
|
||||
|
||||
CHECK(vm.get().get_type() == meta::resolve_type<const std::unique_ptr<int>*>());
|
||||
CHECK(vm.get() == std::addressof(clazz_1::const_unique_int_variable));
|
||||
|
||||
{
|
||||
auto nv = std::make_unique<int>(11);
|
||||
CHECK_THROWS(vm.set(nv));
|
||||
CHECK_THROWS(vm.set(std::move(nv)));
|
||||
CHECK(*clazz_1::const_unique_int_variable == 42);
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("const_unique_int_variable_as_ref") {
|
||||
meta::variable vm = clazz_1_type.get_variable("const_unique_int_variable_as_ref");
|
||||
REQUIRE(vm);
|
||||
|
||||
using ref_t = std::reference_wrapper<const std::unique_ptr<int>>;
|
||||
CHECK(vm.get().get_type() == meta::resolve_type<ref_t>());
|
||||
CHECK(vm.get().get_as<ref_t>().get() == clazz_1::const_unique_int_variable);
|
||||
|
||||
{
|
||||
auto nv = std::make_unique<int>(12);
|
||||
CHECK_THROWS(vm.set(nv));
|
||||
CHECK_THROWS(vm.set(std::move(nv)));
|
||||
CHECK(*clazz_1::const_unique_int_variable == 42);
|
||||
}
|
||||
}
|
||||
}
|
||||
258
develop/untests/meta_types/any_type_tests.cpp
Normal file
258
develop/untests/meta_types/any_type_tests.cpp
Normal file
@@ -0,0 +1,258 @@
|
||||
/*******************************************************************************
|
||||
* 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 "../meta_untests.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
struct class_t {
|
||||
class_t() = default;
|
||||
[[maybe_unused]] class_t(int i): member_v{i} {}
|
||||
|
||||
int member_v{};
|
||||
void method_v() {}
|
||||
};
|
||||
|
||||
enum class enum_t {
|
||||
evalue_v,
|
||||
};
|
||||
|
||||
int array_v[42];
|
||||
const class_t class_v;
|
||||
const enum_t enum_v{enum_t::evalue_v};
|
||||
void function_v() {}
|
||||
const int number_v{42};
|
||||
const int* pointer_v{&number_v};
|
||||
}
|
||||
|
||||
TEST_CASE("meta/meta_types/any_type") {
|
||||
namespace meta = meta_hpp;
|
||||
|
||||
meta::class_<class_t>()
|
||||
.constructor_<>()
|
||||
.constructor_<int>();
|
||||
|
||||
SUBCASE("") {
|
||||
const meta::any_type type{};
|
||||
CHECK_FALSE(type);
|
||||
CHECK_FALSE(type.is_valid());
|
||||
|
||||
CHECK_FALSE(type.is_array());
|
||||
CHECK_FALSE(type.as_array());
|
||||
}
|
||||
|
||||
SUBCASE("array") {
|
||||
const meta::any_type& type = meta::resolve_type(array_v);
|
||||
|
||||
REQUIRE(type);
|
||||
REQUIRE(type == meta::resolve_type<decltype(array_v)>());
|
||||
REQUIRE(type.get_id() == meta::resolve_type<decltype(array_v)>().get_id());
|
||||
|
||||
CHECK(type.is_array());
|
||||
CHECK(type.get_kind() == meta::type_kind::array_);
|
||||
|
||||
CHECK_FALSE(type.is_class());
|
||||
CHECK_FALSE(type.as_class());
|
||||
|
||||
const meta::array_type& specific_type = type.as_array();
|
||||
REQUIRE(specific_type);
|
||||
CHECK(specific_type.get_id() == type.get_id());
|
||||
}
|
||||
|
||||
SUBCASE("class") {
|
||||
const meta::any_type& type = meta::resolve_type(class_v);
|
||||
|
||||
REQUIRE(type);
|
||||
REQUIRE(type == meta::resolve_type<decltype(class_v)>());
|
||||
REQUIRE(type.get_id() == meta::resolve_type<decltype(class_v)>().get_id());
|
||||
|
||||
CHECK(type.is_class());
|
||||
CHECK(type.get_kind() == meta::type_kind::class_);
|
||||
|
||||
CHECK_FALSE(type.is_constructor());
|
||||
CHECK_FALSE(type.as_constructor());
|
||||
|
||||
const meta::class_type& specific_type = type.as_class();
|
||||
REQUIRE(specific_type);
|
||||
CHECK(specific_type.get_id() == type.get_id());
|
||||
}
|
||||
|
||||
SUBCASE("ctor") {
|
||||
const meta::any_type& type = meta::resolve_type<class_t>()
|
||||
.get_constructor_with<>()
|
||||
.get_type();
|
||||
|
||||
REQUIRE(type);
|
||||
|
||||
CHECK(type.is_constructor());
|
||||
CHECK(type.get_kind() == meta::type_kind::constructor_);
|
||||
|
||||
CHECK_FALSE(type.is_enum());
|
||||
CHECK_FALSE(type.as_enum());
|
||||
|
||||
const meta::constructor_type& specific_type = type.as_constructor();
|
||||
REQUIRE(specific_type);
|
||||
CHECK(specific_type.get_id() == type.get_id());
|
||||
}
|
||||
|
||||
SUBCASE("enum") {
|
||||
const meta::any_type& type = meta::resolve_type(enum_v);
|
||||
|
||||
REQUIRE(type);
|
||||
REQUIRE(type == meta::resolve_type<decltype(enum_v)>());
|
||||
REQUIRE(type.get_id() == meta::resolve_type<decltype(enum_v)>().get_id());
|
||||
|
||||
CHECK(type.is_enum());
|
||||
CHECK(type.get_kind() == meta::type_kind::enum_);
|
||||
|
||||
CHECK_FALSE(type.is_function());
|
||||
CHECK_FALSE(type.as_function());
|
||||
|
||||
const meta::enum_type& specific_type = type.as_enum();
|
||||
REQUIRE(specific_type);
|
||||
CHECK(specific_type.get_id() == type.get_id());
|
||||
}
|
||||
|
||||
SUBCASE("function") {
|
||||
const meta::any_type& type = meta::resolve_type(&function_v);
|
||||
|
||||
REQUIRE(type);
|
||||
REQUIRE(type == meta::resolve_type<decltype(&function_v)>());
|
||||
REQUIRE(type.get_id() == meta::resolve_type<decltype(&function_v)>().get_id());
|
||||
|
||||
CHECK(type.is_function());
|
||||
CHECK(type.get_kind() == meta::type_kind::function_);
|
||||
|
||||
CHECK_FALSE(type.is_member());
|
||||
CHECK_FALSE(type.as_member());
|
||||
|
||||
const meta::function_type& specific_type = type.as_function();
|
||||
REQUIRE(specific_type);
|
||||
CHECK(specific_type.get_id() == type.get_id());
|
||||
}
|
||||
|
||||
SUBCASE("member") {
|
||||
const meta::any_type& type = meta::resolve_type(&class_t::member_v);
|
||||
|
||||
REQUIRE(type);
|
||||
REQUIRE(type == meta::resolve_type<decltype(&class_t::member_v)>());
|
||||
REQUIRE(type.get_id() == meta::resolve_type<decltype(&class_t::member_v)>().get_id());
|
||||
|
||||
CHECK(type.is_member());
|
||||
CHECK(type.get_kind() == meta::type_kind::member_);
|
||||
|
||||
CHECK_FALSE(type.is_method());
|
||||
CHECK_FALSE(type.as_method());
|
||||
|
||||
const meta::member_type& specific_type = type.as_member();
|
||||
REQUIRE(specific_type);
|
||||
CHECK(specific_type.get_id() == type.get_id());
|
||||
}
|
||||
|
||||
SUBCASE("method") {
|
||||
const meta::any_type& type = meta::resolve_type(&class_t::method_v);
|
||||
|
||||
REQUIRE(type);
|
||||
REQUIRE(type == meta::resolve_type<decltype(&class_t::method_v)>());
|
||||
REQUIRE(type.get_id() == meta::resolve_type<decltype(&class_t::method_v)>().get_id());
|
||||
|
||||
CHECK(type.is_method());
|
||||
CHECK(type.get_kind() == meta::type_kind::method_);
|
||||
|
||||
CHECK_FALSE(type.is_nullptr());
|
||||
CHECK_FALSE(type.as_nullptr());
|
||||
|
||||
const meta::method_type& specific_type = type.as_method();
|
||||
REQUIRE(specific_type);
|
||||
CHECK(specific_type.get_id() == type.get_id());
|
||||
}
|
||||
|
||||
SUBCASE("nullptr") {
|
||||
const meta::any_type& type = meta::resolve_type(nullptr);
|
||||
|
||||
REQUIRE(type);
|
||||
REQUIRE(type == meta::resolve_type<std::nullptr_t>());
|
||||
REQUIRE(type.get_id() == meta::resolve_type<std::nullptr_t>().get_id());
|
||||
|
||||
CHECK(type.is_nullptr());
|
||||
CHECK(type.get_kind() == meta::type_kind::nullptr_);
|
||||
|
||||
CHECK_FALSE(type.is_number());
|
||||
CHECK_FALSE(type.as_number());
|
||||
|
||||
const meta::nullptr_type& specific_type = type.as_nullptr();
|
||||
REQUIRE(specific_type);
|
||||
CHECK(specific_type.get_id() == type.get_id());
|
||||
}
|
||||
|
||||
SUBCASE("number") {
|
||||
const meta::any_type& type = meta::resolve_type(number_v);
|
||||
|
||||
REQUIRE(type);
|
||||
REQUIRE(type == meta::resolve_type<decltype(number_v)>());
|
||||
REQUIRE(type.get_id() == meta::resolve_type<decltype(number_v)>().get_id());
|
||||
|
||||
CHECK(type.is_number());
|
||||
CHECK(type.get_kind() == meta::type_kind::number_);
|
||||
|
||||
CHECK_FALSE(type.is_pointer());
|
||||
CHECK_FALSE(type.as_pointer());
|
||||
|
||||
const meta::number_type& specific_type = type.as_number();
|
||||
REQUIRE(specific_type);
|
||||
CHECK(specific_type.get_id() == type.get_id());
|
||||
}
|
||||
|
||||
SUBCASE("pointer") {
|
||||
const meta::any_type& type = meta::resolve_type(pointer_v);
|
||||
|
||||
REQUIRE(type);
|
||||
REQUIRE(type == meta::resolve_type<decltype(pointer_v)>());
|
||||
REQUIRE(type.get_id() == meta::resolve_type<decltype(pointer_v)>().get_id());
|
||||
|
||||
CHECK(type.is_pointer());
|
||||
CHECK(type.get_kind() == meta::type_kind::pointer_);
|
||||
|
||||
CHECK_FALSE(type.is_reference());
|
||||
CHECK_FALSE(type.as_reference());
|
||||
|
||||
const meta::pointer_type& specific_type = type.as_pointer();
|
||||
REQUIRE(specific_type);
|
||||
CHECK(specific_type.get_id() == type.get_id());
|
||||
}
|
||||
|
||||
SUBCASE("reference") {
|
||||
const meta::any_type& type = meta::resolve_type<const int&>();
|
||||
|
||||
REQUIRE(type);
|
||||
|
||||
CHECK(type.is_reference());
|
||||
CHECK(type.get_kind() == meta::type_kind::reference_);
|
||||
|
||||
CHECK_FALSE(type.is_void());
|
||||
CHECK_FALSE(type.as_void());
|
||||
|
||||
const meta::reference_type& specific_type = type.as_reference();
|
||||
REQUIRE(specific_type);
|
||||
CHECK(specific_type.get_id() == type.get_id());
|
||||
}
|
||||
|
||||
SUBCASE("void") {
|
||||
const meta::any_type& type = meta::resolve_type<void>();
|
||||
|
||||
REQUIRE(type);
|
||||
|
||||
CHECK(type.is_void());
|
||||
CHECK(type.get_kind() == meta::type_kind::void_);
|
||||
|
||||
CHECK_FALSE(type.is_array());
|
||||
CHECK_FALSE(type.as_array());
|
||||
|
||||
const meta::void_type& specific_type = type.as_void();
|
||||
REQUIRE(specific_type);
|
||||
CHECK(specific_type.get_id() == type.get_id());
|
||||
}
|
||||
}
|
||||
41
develop/untests/meta_types/array_type_tests.cpp
Normal file
41
develop/untests/meta_types/array_type_tests.cpp
Normal file
@@ -0,0 +1,41 @@
|
||||
/*******************************************************************************
|
||||
* 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 "../meta_untests.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
}
|
||||
|
||||
TEST_CASE("meta/meta_types/array_type") {
|
||||
namespace meta = meta_hpp;
|
||||
|
||||
SUBCASE("") {
|
||||
const meta::array_type type;
|
||||
CHECK_FALSE(type);
|
||||
CHECK_FALSE(type.is_valid());
|
||||
}
|
||||
|
||||
SUBCASE("int[]") {
|
||||
const meta::array_type type = meta::resolve_type<int[]>();
|
||||
REQUIRE(type);
|
||||
|
||||
CHECK(type.get_flags() == (meta::array_flags::is_unbounded));
|
||||
|
||||
CHECK(type.get_extent() == 0);
|
||||
CHECK(type.get_data_type() == meta::resolve_type<int>());
|
||||
}
|
||||
|
||||
SUBCASE("const unsigned[42][21]") {
|
||||
const meta::array_type type = meta::resolve_type<const unsigned[42][21]>();
|
||||
REQUIRE(type);
|
||||
|
||||
CHECK(type.get_flags() == (meta::array_flags::is_bounded));
|
||||
|
||||
CHECK(type.get_extent() == 42);
|
||||
CHECK(type.get_data_type() == meta::resolve_type<const unsigned[21]>());
|
||||
}
|
||||
}
|
||||
34
develop/untests/meta_types/class_type2_tests.cpp
Normal file
34
develop/untests/meta_types/class_type2_tests.cpp
Normal file
@@ -0,0 +1,34 @@
|
||||
/*******************************************************************************
|
||||
* 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 "../meta_untests.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
struct clazz {
|
||||
struct internal_clazz {};
|
||||
enum class internal_enum {};
|
||||
};
|
||||
}
|
||||
|
||||
TEST_CASE("meta/meta_types/class_type2") {
|
||||
namespace meta = meta_hpp;
|
||||
|
||||
meta::class_<clazz>()
|
||||
.typedef_<clazz::internal_clazz>("internal_clazz")
|
||||
.typedef_<clazz::internal_enum>("internal_enum");
|
||||
|
||||
const meta::class_type clazz_type = meta::resolve_type<clazz>();
|
||||
REQUIRE(clazz_type);
|
||||
|
||||
CHECK(clazz_type.get_typedef("internal_clazz") == meta::resolve_type<clazz::internal_clazz>());
|
||||
CHECK(clazz_type.get_typedef("internal_enum") == meta::resolve_type<clazz::internal_enum>());
|
||||
|
||||
CHECK(clazz_type.get_typedefs() == meta::typedef_map{
|
||||
{"internal_clazz", meta::resolve_type<clazz::internal_clazz>()},
|
||||
{"internal_enum", meta::resolve_type<clazz::internal_enum>()},
|
||||
});
|
||||
}
|
||||
508
develop/untests/meta_types/class_type_tests.cpp
Normal file
508
develop/untests/meta_types/class_type_tests.cpp
Normal file
@@ -0,0 +1,508 @@
|
||||
/*******************************************************************************
|
||||
* 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 "../meta_untests.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
struct base_clazz_1 {
|
||||
base_clazz_1(int) {}
|
||||
|
||||
int base_member_1 = 1;
|
||||
int base_method_1() { return 1; }
|
||||
static int base_function_1() { return 1; }
|
||||
|
||||
int base_method_1_overloaded(int i0) const { return i0; }
|
||||
int base_method_1_overloaded(float f0) const { return static_cast<int>(f0); }
|
||||
|
||||
static int base_function_1_overloaded(int i0) { return i0; }
|
||||
static int base_function_1_overloaded(int i0, int i1) { return i0 + i1; }
|
||||
|
||||
static int base_variable_1;
|
||||
};
|
||||
|
||||
int base_clazz_1::base_variable_1 = 1;
|
||||
|
||||
struct base_clazz_2 {
|
||||
base_clazz_2(float) {}
|
||||
|
||||
float base_member_2 = 2.0f;
|
||||
float base_method_2() { return 2.0f; }
|
||||
static float base_function_2() { return 2.f; }
|
||||
|
||||
static float base_variable_2;
|
||||
};
|
||||
|
||||
float base_clazz_2::base_variable_2 = 2.0f;
|
||||
|
||||
struct derived_clazz : base_clazz_1, base_clazz_2 {
|
||||
[[maybe_unused]] derived_clazz(int i, float f)
|
||||
: base_clazz_1{i}
|
||||
, base_clazz_2{f} {}
|
||||
|
||||
double derived_member = 3.0;
|
||||
double derived_method() { return 3.0; }
|
||||
static double derived_function() { return 3.0; }
|
||||
|
||||
static constexpr double derived_variable = 3.0;
|
||||
};
|
||||
|
||||
struct final_derived_clazz final : derived_clazz {
|
||||
using derived_clazz::derived_clazz;
|
||||
};
|
||||
|
||||
template < typename... Args >
|
||||
struct variadic_clazz {};
|
||||
}
|
||||
|
||||
TEST_CASE("meta/meta_types/class_type") {
|
||||
namespace meta = meta_hpp;
|
||||
|
||||
meta::class_<base_clazz_1>()
|
||||
.constructor_<int>()
|
||||
.member_("base_member_1", &base_clazz_1::base_member_1)
|
||||
.method_("base_method_1", &base_clazz_1::base_method_1)
|
||||
.function_("base_function_1", &base_clazz_1::base_function_1)
|
||||
.method_("base_method_1_overloaded", meta::select_overload<int(int) const>(&base_clazz_1::base_method_1_overloaded))
|
||||
.method_("base_method_1_overloaded", meta::select_overload<int(float) const>(&base_clazz_1::base_method_1_overloaded))
|
||||
.function_("base_function_1_overloaded", meta::select_overload<int(int)>(&base_clazz_1::base_function_1_overloaded))
|
||||
.function_("base_function_1_overloaded", meta::select_overload<int(int,int)>(&base_clazz_1::base_function_1_overloaded))
|
||||
.variable_("base_variable_1", &base_clazz_1::base_variable_1);
|
||||
|
||||
meta::class_<base_clazz_2>()
|
||||
.constructor_<float>()
|
||||
.member_("base_member_2", &base_clazz_2::base_member_2)
|
||||
.method_("base_method_2", &base_clazz_2::base_method_2)
|
||||
.function_("base_function_2", &base_clazz_2::base_function_2)
|
||||
.variable_("base_variable_2", &base_clazz_2::base_variable_2);
|
||||
|
||||
meta::class_<derived_clazz>()
|
||||
.constructor_<int, float>()
|
||||
.base_<base_clazz_1>()
|
||||
.base_<base_clazz_2>()
|
||||
.member_("derived_member", &derived_clazz::derived_member)
|
||||
.method_("derived_method", &derived_clazz::derived_method)
|
||||
.function_("derived_function", &derived_clazz::derived_function)
|
||||
.variable_("derived_variable", &derived_clazz::derived_variable);
|
||||
|
||||
meta::class_<final_derived_clazz>()
|
||||
.constructor_<int, float>()
|
||||
.base_<derived_clazz>();
|
||||
|
||||
const meta::class_type base_clazz_1_type = meta::resolve_type<base_clazz_1>();
|
||||
REQUIRE(base_clazz_1_type);
|
||||
|
||||
const meta::class_type base_clazz_2_type = meta::resolve_type<base_clazz_2>();
|
||||
REQUIRE(base_clazz_2_type);
|
||||
|
||||
const meta::class_type derived_clazz_type = meta::resolve_type<const derived_clazz>();
|
||||
REQUIRE(derived_clazz_type);
|
||||
|
||||
const meta::class_type final_derived_clazz_type = meta::resolve_type<const final_derived_clazz>();
|
||||
REQUIRE(final_derived_clazz_type);
|
||||
|
||||
const meta::class_type variadic_clazz_int_type = meta::resolve_type<variadic_clazz<int>>();
|
||||
REQUIRE(variadic_clazz_int_type);
|
||||
|
||||
const meta::class_type variadic_clazz_int_float_type = meta::resolve_type<variadic_clazz<int, float>>();
|
||||
REQUIRE(variadic_clazz_int_float_type);
|
||||
|
||||
SUBCASE("get_flags") {
|
||||
CHECK(base_clazz_1_type.get_flags() == meta::class_flags{});
|
||||
CHECK(base_clazz_2_type.get_flags() == meta::class_flags{});
|
||||
CHECK(derived_clazz_type.get_flags() == meta::class_flags{});
|
||||
CHECK(final_derived_clazz_type.get_flags() == meta::class_flags::is_final);
|
||||
CHECK(variadic_clazz_int_type.get_flags() == (meta::class_flags::is_empty | meta::class_flags::is_template_instantiation));
|
||||
CHECK(variadic_clazz_int_float_type.get_flags() == (meta::class_flags::is_empty | meta::class_flags::is_template_instantiation));
|
||||
}
|
||||
|
||||
SUBCASE("get_size") {
|
||||
CHECK(base_clazz_1_type.get_size() == sizeof(base_clazz_1));
|
||||
CHECK(base_clazz_2_type.get_size() == sizeof(base_clazz_2));
|
||||
CHECK(derived_clazz_type.get_size() == sizeof(derived_clazz));
|
||||
CHECK(final_derived_clazz_type.get_size() == sizeof(final_derived_clazz));
|
||||
}
|
||||
|
||||
SUBCASE("get_align") {
|
||||
CHECK(base_clazz_1_type.get_align() == alignof(base_clazz_1));
|
||||
CHECK(base_clazz_2_type.get_align() == alignof(base_clazz_2));
|
||||
CHECK(derived_clazz_type.get_align() == alignof(derived_clazz));
|
||||
CHECK(final_derived_clazz_type.get_align() == alignof(final_derived_clazz));
|
||||
}
|
||||
|
||||
SUBCASE("get_arity") {
|
||||
{
|
||||
const meta::class_type type = meta::resolve_type<derived_clazz>();
|
||||
REQUIRE(type);
|
||||
CHECK(type.get_arity() == 0);
|
||||
}
|
||||
{
|
||||
const meta::class_type type = meta::resolve_type<variadic_clazz<int>>();
|
||||
REQUIRE(type);
|
||||
CHECK(type.get_arity() == 1);
|
||||
}
|
||||
{
|
||||
const meta::class_type type = meta::resolve_type<variadic_clazz<int, float>>();
|
||||
REQUIRE(type);
|
||||
CHECK(type.get_arity() == 2);
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("get_argument_type") {
|
||||
{
|
||||
const meta::class_type type = meta::resolve_type<derived_clazz>();
|
||||
REQUIRE(type);
|
||||
CHECK_FALSE(type.get_argument_type(0));
|
||||
}
|
||||
{
|
||||
const meta::class_type type = meta::resolve_type<variadic_clazz<int>>();
|
||||
REQUIRE(type);
|
||||
CHECK(type.get_argument_type(0) == meta::resolve_type<int>());
|
||||
CHECK_FALSE(type.get_argument_type(1));
|
||||
}
|
||||
{
|
||||
const meta::class_type type = meta::resolve_type<variadic_clazz<int, float>>();
|
||||
REQUIRE(type);
|
||||
CHECK(type.get_argument_type(0) == meta::resolve_type<int>());
|
||||
CHECK(type.get_argument_type(1) == meta::resolve_type<float>());
|
||||
CHECK_FALSE(type.get_argument_type(2));
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("get_argument_types") {
|
||||
{
|
||||
const meta::class_type type = meta::resolve_type<derived_clazz>();
|
||||
REQUIRE(type);
|
||||
CHECK(type.get_argument_types() == meta::any_type_list{});
|
||||
}
|
||||
{
|
||||
const meta::class_type type = meta::resolve_type<variadic_clazz<int>>();
|
||||
REQUIRE(type);
|
||||
CHECK(type.get_argument_types() == meta::any_type_list{meta::resolve_type<int>()});
|
||||
}
|
||||
{
|
||||
const meta::class_type type = meta::resolve_type<variadic_clazz<int, float>>();
|
||||
REQUIRE(type);
|
||||
CHECK(type.get_argument_types() == meta::any_type_list{meta::resolve_type<int>(), meta::resolve_type<float>()});
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("get_constructors") {
|
||||
CHECK(base_clazz_1_type.get_constructors().size() == 1);
|
||||
CHECK(base_clazz_2_type.get_constructors().size() == 1);
|
||||
CHECK(derived_clazz_type.get_constructors().size() == 1);
|
||||
CHECK(final_derived_clazz_type.get_constructors().size() == 1);
|
||||
}
|
||||
|
||||
SUBCASE("get_bases") {
|
||||
CHECK(base_clazz_1_type.get_bases() == meta::class_set{});
|
||||
CHECK(base_clazz_2_type.get_bases() == meta::class_set{});
|
||||
CHECK(derived_clazz_type.get_bases() == meta::class_set{base_clazz_1_type, base_clazz_2_type});
|
||||
CHECK(final_derived_clazz_type.get_bases() == meta::class_set{derived_clazz_type});
|
||||
}
|
||||
|
||||
SUBCASE("get_functions") {
|
||||
CHECK(base_clazz_1_type.get_functions().size() == 3);
|
||||
CHECK(base_clazz_2_type.get_functions().size() == 1);
|
||||
CHECK(derived_clazz_type.get_functions().size() == 1);
|
||||
CHECK(final_derived_clazz_type.get_functions().size() == 0);
|
||||
}
|
||||
|
||||
SUBCASE("get_members") {
|
||||
CHECK(base_clazz_1_type.get_members().size() == 1);
|
||||
CHECK(base_clazz_2_type.get_members().size() == 1);
|
||||
CHECK(derived_clazz_type.get_members().size() == 1);
|
||||
CHECK(final_derived_clazz_type.get_members().size() == 0);
|
||||
}
|
||||
|
||||
SUBCASE("get_methods") {
|
||||
CHECK(base_clazz_1_type.get_methods().size() == 3);
|
||||
CHECK(base_clazz_2_type.get_methods().size() == 1);
|
||||
CHECK(derived_clazz_type.get_methods().size() == 1);
|
||||
CHECK(final_derived_clazz_type.get_methods().size() == 0);
|
||||
}
|
||||
|
||||
SUBCASE("get_variables") {
|
||||
CHECK(base_clazz_1_type.get_variables().size() == 1);
|
||||
CHECK(base_clazz_2_type.get_variables().size() == 1);
|
||||
CHECK(derived_clazz_type.get_variables().size() == 1);
|
||||
CHECK(final_derived_clazz_type.get_variables().size() == 0);
|
||||
}
|
||||
|
||||
SUBCASE("is_base_of") {
|
||||
{
|
||||
CHECK_FALSE(base_clazz_1_type.is_base_of<base_clazz_1>());
|
||||
CHECK_FALSE(base_clazz_1_type.is_base_of(base_clazz_1_type));
|
||||
|
||||
CHECK_FALSE(base_clazz_1_type.is_base_of<base_clazz_2>());
|
||||
CHECK_FALSE(base_clazz_1_type.is_base_of(base_clazz_2_type));
|
||||
|
||||
CHECK(base_clazz_1_type.is_base_of<derived_clazz>());
|
||||
CHECK(base_clazz_1_type.is_base_of(derived_clazz_type));
|
||||
|
||||
CHECK(base_clazz_1_type.is_base_of<final_derived_clazz>());
|
||||
CHECK(base_clazz_1_type.is_base_of(final_derived_clazz_type));
|
||||
}
|
||||
|
||||
{
|
||||
CHECK_FALSE(base_clazz_2_type.is_base_of<base_clazz_1>());
|
||||
CHECK_FALSE(base_clazz_2_type.is_base_of(base_clazz_1_type));
|
||||
|
||||
CHECK_FALSE(base_clazz_2_type.is_base_of<base_clazz_2>());
|
||||
CHECK_FALSE(base_clazz_2_type.is_base_of(base_clazz_2_type));
|
||||
|
||||
CHECK(base_clazz_2_type.is_base_of<derived_clazz>());
|
||||
CHECK(base_clazz_2_type.is_base_of(derived_clazz_type));
|
||||
|
||||
CHECK(base_clazz_2_type.is_base_of<final_derived_clazz>());
|
||||
CHECK(base_clazz_2_type.is_base_of(final_derived_clazz_type));
|
||||
}
|
||||
|
||||
{
|
||||
CHECK_FALSE(derived_clazz_type.is_base_of<base_clazz_1>());
|
||||
CHECK_FALSE(derived_clazz_type.is_base_of(base_clazz_1_type));
|
||||
|
||||
CHECK_FALSE(derived_clazz_type.is_base_of<base_clazz_2>());
|
||||
CHECK_FALSE(derived_clazz_type.is_base_of(base_clazz_2_type));
|
||||
|
||||
CHECK_FALSE(derived_clazz_type.is_base_of<derived_clazz>());
|
||||
CHECK_FALSE(derived_clazz_type.is_base_of(derived_clazz_type));
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("is_derived_from") {
|
||||
{
|
||||
CHECK_FALSE(base_clazz_1_type.is_derived_from<base_clazz_1>());
|
||||
CHECK_FALSE(base_clazz_1_type.is_derived_from(base_clazz_1_type));
|
||||
|
||||
CHECK_FALSE(base_clazz_1_type.is_derived_from<base_clazz_2>());
|
||||
CHECK_FALSE(base_clazz_1_type.is_derived_from(base_clazz_2_type));
|
||||
|
||||
CHECK_FALSE(base_clazz_1_type.is_derived_from<derived_clazz>());
|
||||
CHECK_FALSE(base_clazz_1_type.is_derived_from(derived_clazz_type));
|
||||
}
|
||||
|
||||
{
|
||||
CHECK_FALSE(base_clazz_2_type.is_derived_from<base_clazz_1>());
|
||||
CHECK_FALSE(base_clazz_2_type.is_derived_from(base_clazz_1_type));
|
||||
|
||||
CHECK_FALSE(base_clazz_2_type.is_derived_from<base_clazz_2>());
|
||||
CHECK_FALSE(base_clazz_2_type.is_derived_from(base_clazz_2_type));
|
||||
|
||||
CHECK_FALSE(base_clazz_2_type.is_derived_from<derived_clazz>());
|
||||
CHECK_FALSE(base_clazz_2_type.is_derived_from(derived_clazz_type));
|
||||
}
|
||||
|
||||
{
|
||||
CHECK(derived_clazz_type.is_derived_from<base_clazz_1>());
|
||||
CHECK(derived_clazz_type.is_derived_from(base_clazz_1_type));
|
||||
|
||||
CHECK(derived_clazz_type.is_derived_from<base_clazz_2>());
|
||||
CHECK(derived_clazz_type.is_derived_from(base_clazz_2_type));
|
||||
|
||||
CHECK_FALSE(derived_clazz_type.is_derived_from<derived_clazz>());
|
||||
CHECK_FALSE(derived_clazz_type.is_derived_from(derived_clazz_type));
|
||||
}
|
||||
|
||||
{
|
||||
CHECK(final_derived_clazz_type.is_derived_from<base_clazz_1>());
|
||||
CHECK(final_derived_clazz_type.is_derived_from(base_clazz_1_type));
|
||||
|
||||
CHECK(final_derived_clazz_type.is_derived_from<base_clazz_2>());
|
||||
CHECK(final_derived_clazz_type.is_derived_from(base_clazz_2_type));
|
||||
|
||||
CHECK(final_derived_clazz_type.is_derived_from<derived_clazz>());
|
||||
CHECK(final_derived_clazz_type.is_derived_from(derived_clazz_type));
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("get_function") {
|
||||
CHECK(base_clazz_1_type.get_function("base_function_1"));
|
||||
CHECK_FALSE(base_clazz_1_type.get_function("base_function_2"));
|
||||
CHECK_FALSE(base_clazz_1_type.get_function("derived_function"));
|
||||
|
||||
CHECK_FALSE(base_clazz_2_type.get_function("base_function_1"));
|
||||
CHECK(base_clazz_2_type.get_function("base_function_2"));
|
||||
CHECK_FALSE(base_clazz_2_type.get_function("derived_function"));
|
||||
|
||||
CHECK(derived_clazz_type.get_function("base_function_1"));
|
||||
CHECK(derived_clazz_type.get_function("base_function_2"));
|
||||
CHECK(derived_clazz_type.get_function("derived_function"));
|
||||
}
|
||||
|
||||
SUBCASE("get_member") {
|
||||
CHECK(base_clazz_1_type.get_member("base_member_1"));
|
||||
CHECK_FALSE(base_clazz_1_type.get_member("base_member_2"));
|
||||
CHECK_FALSE(base_clazz_1_type.get_member("derived_member"));
|
||||
|
||||
CHECK_FALSE(base_clazz_2_type.get_member("base_member_1"));
|
||||
CHECK(base_clazz_2_type.get_member("base_member_2"));
|
||||
CHECK_FALSE(base_clazz_2_type.get_member("derived_member"));
|
||||
|
||||
CHECK(derived_clazz_type.get_member("base_member_1"));
|
||||
CHECK(derived_clazz_type.get_member("base_member_2"));
|
||||
CHECK(derived_clazz_type.get_member("derived_member"));
|
||||
}
|
||||
|
||||
SUBCASE("get_method") {
|
||||
CHECK(base_clazz_1_type.get_method("base_method_1"));
|
||||
CHECK_FALSE(base_clazz_1_type.get_method("base_method_2"));
|
||||
CHECK_FALSE(base_clazz_1_type.get_method("derived_method"));
|
||||
|
||||
CHECK_FALSE(base_clazz_2_type.get_method("base_method_1"));
|
||||
CHECK(base_clazz_2_type.get_method("base_method_2"));
|
||||
CHECK_FALSE(base_clazz_2_type.get_method("derived_method"));
|
||||
|
||||
CHECK(derived_clazz_type.get_method("base_method_1"));
|
||||
CHECK(derived_clazz_type.get_method("base_method_2"));
|
||||
CHECK(derived_clazz_type.get_method("derived_method"));
|
||||
}
|
||||
|
||||
SUBCASE("get_variable") {
|
||||
CHECK(base_clazz_1_type.get_variable("base_variable_1"));
|
||||
CHECK_FALSE(base_clazz_1_type.get_variable("base_variable_2"));
|
||||
CHECK_FALSE(base_clazz_1_type.get_variable("derived_variable"));
|
||||
|
||||
CHECK_FALSE(base_clazz_2_type.get_variable("base_variable_1"));
|
||||
CHECK(base_clazz_2_type.get_variable("base_variable_2"));
|
||||
CHECK_FALSE(base_clazz_2_type.get_variable("derived_variable"));
|
||||
|
||||
CHECK(derived_clazz_type.get_variable("base_variable_1"));
|
||||
CHECK(derived_clazz_type.get_variable("base_variable_2"));
|
||||
CHECK(derived_clazz_type.get_variable("derived_variable"));
|
||||
}
|
||||
|
||||
SUBCASE("get_constructor_with") {
|
||||
{
|
||||
CHECK_FALSE(base_clazz_1_type.get_constructor_with<>());
|
||||
CHECK(base_clazz_1_type.get_constructor_with<int>());
|
||||
CHECK_FALSE(base_clazz_1_type.get_constructor_with<float>());
|
||||
}
|
||||
{
|
||||
CHECK_FALSE(base_clazz_2_type.get_constructor_with<>());
|
||||
CHECK_FALSE(base_clazz_2_type.get_constructor_with<int>());
|
||||
CHECK(base_clazz_2_type.get_constructor_with<float>());
|
||||
}
|
||||
{
|
||||
CHECK_FALSE(derived_clazz_type.get_constructor_with<>());
|
||||
CHECK_FALSE(derived_clazz_type.get_constructor_with<int>());
|
||||
CHECK_FALSE(derived_clazz_type.get_constructor_with<float>());
|
||||
CHECK(derived_clazz_type.get_constructor_with<int, float>());
|
||||
CHECK_FALSE(derived_clazz_type.get_constructor_with<float, int>());
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("get_function_with") {
|
||||
CHECK(base_clazz_1_type.get_function("base_function_1_overloaded"));
|
||||
|
||||
{
|
||||
CHECK_FALSE(base_clazz_1_type.get_function_with<>("base_function_1_overloaded"));
|
||||
CHECK(base_clazz_1_type.get_function_with<int>("base_function_1_overloaded"));
|
||||
CHECK_FALSE(base_clazz_1_type.get_function_with<int, float>("base_function_1_overloaded"));
|
||||
|
||||
CHECK_FALSE(base_clazz_1_type.get_function_with<>("base_function_1_overloaded"));
|
||||
CHECK_FALSE(base_clazz_1_type.get_function_with<float>("base_function_1_overloaded"));
|
||||
CHECK(base_clazz_1_type.get_function_with<int, int>("base_function_1_overloaded"));
|
||||
CHECK_FALSE(base_clazz_1_type.get_function_with<float, float>("base_function_1_overloaded"));
|
||||
|
||||
CHECK_FALSE(base_clazz_1_type.get_function_with<>("base_function_1_overloaded"));
|
||||
CHECK_FALSE(base_clazz_1_type.get_function_with<double>("base_function_1_overloaded"));
|
||||
CHECK_FALSE(base_clazz_1_type.get_function_with<double, double>("base_function_1_overloaded"));
|
||||
}
|
||||
|
||||
{
|
||||
meta::number_type int_type = meta::resolve_type<int>();
|
||||
meta::number_type float_type = meta::resolve_type<float>();
|
||||
meta::number_type double_type = meta::resolve_type<double>();
|
||||
|
||||
CHECK_FALSE(base_clazz_1_type.get_function_with<>("base_function_1_overloaded"));
|
||||
CHECK(base_clazz_1_type.get_function_with("base_function_1_overloaded", {int_type}));
|
||||
CHECK_FALSE(base_clazz_1_type.get_function_with("base_function_1_overloaded", {int_type, float_type}));
|
||||
|
||||
CHECK_FALSE(base_clazz_1_type.get_function_with("base_function_1_overloaded"));
|
||||
CHECK_FALSE(base_clazz_1_type.get_function_with("base_function_1_overloaded", {float_type}));
|
||||
CHECK(base_clazz_1_type.get_function_with("base_function_1_overloaded", {int_type, int_type}));
|
||||
CHECK_FALSE(base_clazz_1_type.get_function_with("base_function_1_overloaded", {float_type, float_type}));
|
||||
|
||||
CHECK_FALSE(base_clazz_1_type.get_function_with<>("base_function_1_overloaded"));
|
||||
CHECK_FALSE(base_clazz_1_type.get_function_with("base_function_1_overloaded", {double_type}));
|
||||
CHECK_FALSE(base_clazz_1_type.get_function_with("base_function_1_overloaded", {double_type, double_type}));
|
||||
}
|
||||
|
||||
{
|
||||
meta::number_type int_type = meta::resolve_type<int>();
|
||||
meta::number_type float_type = meta::resolve_type<float>();
|
||||
meta::number_type double_type = meta::resolve_type<double>();
|
||||
|
||||
CHECK_FALSE(base_clazz_1_type.get_function_with<>("base_function_1_overloaded"));
|
||||
CHECK(base_clazz_1_type.get_function_with("base_function_1_overloaded", meta::any_type_list{int_type}));
|
||||
CHECK_FALSE(base_clazz_1_type.get_function_with("base_function_1_overloaded", meta::any_type_list{int_type, float_type}));
|
||||
|
||||
CHECK_FALSE(base_clazz_1_type.get_function_with("base_function_1_overloaded"));
|
||||
CHECK_FALSE(base_clazz_1_type.get_function_with("base_function_1_overloaded", meta::any_type_list{float_type}));
|
||||
CHECK(base_clazz_1_type.get_function_with("base_function_1_overloaded", meta::any_type_list{int_type, int_type}));
|
||||
CHECK_FALSE(base_clazz_1_type.get_function_with("base_function_1_overloaded", meta::any_type_list{float_type, float_type}));
|
||||
|
||||
CHECK_FALSE(base_clazz_1_type.get_function_with<>("base_function_1_overloaded"));
|
||||
CHECK_FALSE(base_clazz_1_type.get_function_with("base_function_1_overloaded", meta::any_type_list{double_type}));
|
||||
CHECK_FALSE(base_clazz_1_type.get_function_with("base_function_1_overloaded", meta::any_type_list{double_type, double_type}));
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("get_method_with") {
|
||||
CHECK(base_clazz_1_type.get_method("base_method_1_overloaded"));
|
||||
|
||||
{
|
||||
CHECK_FALSE(base_clazz_1_type.get_method_with<>("base_method_1_overloaded"));
|
||||
CHECK(base_clazz_1_type.get_method_with<int>("base_method_1_overloaded"));
|
||||
CHECK_FALSE(base_clazz_1_type.get_method_with<int, int>("base_method_1_overloaded"));
|
||||
|
||||
CHECK_FALSE(base_clazz_1_type.get_method_with<>("base_method_1_overloaded"));
|
||||
CHECK(base_clazz_1_type.get_method_with<float>("base_method_1_overloaded"));
|
||||
CHECK_FALSE(base_clazz_1_type.get_method_with<float, float>("base_method_1_overloaded"));
|
||||
|
||||
CHECK_FALSE(base_clazz_1_type.get_method_with<>("base_method_1_overloaded"));
|
||||
CHECK_FALSE(base_clazz_1_type.get_method_with<double>("base_method_1_overloaded"));
|
||||
CHECK_FALSE(base_clazz_1_type.get_method_with<double, double>("base_method_1_overloaded"));
|
||||
}
|
||||
|
||||
{
|
||||
meta::number_type int_type = meta::resolve_type<int>();
|
||||
meta::number_type float_type = meta::resolve_type<float>();
|
||||
meta::number_type double_type = meta::resolve_type<double>();
|
||||
|
||||
CHECK_FALSE(base_clazz_1_type.get_method_with<>("base_method_1_overloaded"));
|
||||
CHECK(base_clazz_1_type.get_method_with("base_method_1_overloaded", {int_type}));
|
||||
CHECK_FALSE(base_clazz_1_type.get_method_with("base_method_1_overloaded", {int_type, int_type}));
|
||||
|
||||
CHECK_FALSE(base_clazz_1_type.get_method_with("base_method_1_overloaded"));
|
||||
CHECK(base_clazz_1_type.get_method_with("base_method_1_overloaded", {float_type}));
|
||||
CHECK_FALSE(base_clazz_1_type.get_method_with("base_method_1_overloaded", {float_type, float_type}));
|
||||
|
||||
CHECK_FALSE(base_clazz_1_type.get_method_with<>("base_method_1_overloaded"));
|
||||
CHECK_FALSE(base_clazz_1_type.get_method_with("base_method_1_overloaded", {double_type}));
|
||||
CHECK_FALSE(base_clazz_1_type.get_method_with("base_method_1_overloaded", {double_type, double_type}));
|
||||
}
|
||||
|
||||
{
|
||||
meta::number_type int_type = meta::resolve_type<int>();
|
||||
meta::number_type float_type = meta::resolve_type<float>();
|
||||
meta::number_type double_type = meta::resolve_type<double>();
|
||||
|
||||
CHECK_FALSE(base_clazz_1_type.get_method_with<>("base_method_1_overloaded"));
|
||||
CHECK(base_clazz_1_type.get_method_with("base_method_1_overloaded", meta::any_type_list{int_type}));
|
||||
CHECK_FALSE(base_clazz_1_type.get_method_with("base_method_1_overloaded", meta::any_type_list{int_type, int_type}));
|
||||
|
||||
CHECK_FALSE(base_clazz_1_type.get_method_with("base_method_1_overloaded"));
|
||||
CHECK(base_clazz_1_type.get_method_with("base_method_1_overloaded", meta::any_type_list{float_type}));
|
||||
CHECK_FALSE(base_clazz_1_type.get_method_with("base_method_1_overloaded", meta::any_type_list{float_type, float_type}));
|
||||
|
||||
CHECK_FALSE(base_clazz_1_type.get_method_with<>("base_method_1_overloaded"));
|
||||
CHECK_FALSE(base_clazz_1_type.get_method_with("base_method_1_overloaded", meta::any_type_list{double_type}));
|
||||
CHECK_FALSE(base_clazz_1_type.get_method_with("base_method_1_overloaded", meta::any_type_list{double_type, double_type}));
|
||||
}
|
||||
}
|
||||
}
|
||||
164
develop/untests/meta_types/enum_type_tests.cpp
Normal file
164
develop/untests/meta_types/enum_type_tests.cpp
Normal file
@@ -0,0 +1,164 @@
|
||||
/*******************************************************************************
|
||||
* 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 "../meta_untests.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
enum class color : unsigned {
|
||||
red = 0xFF0000,
|
||||
green = 0x00FF00,
|
||||
blue = 0x0000FF,
|
||||
white = red | green | blue,
|
||||
};
|
||||
|
||||
enum ecolor : int {
|
||||
ecolor_red = 0xFF0000,
|
||||
ecolor_green = 0x00FF00,
|
||||
ecolor_blue = 0x0000FF,
|
||||
ecolor_white = ecolor_red | ecolor_green | ecolor_blue,
|
||||
};
|
||||
}
|
||||
|
||||
TEST_CASE("meta/meta_types/enum_type") {
|
||||
namespace meta = meta_hpp;
|
||||
|
||||
meta::enum_<color>()
|
||||
.evalue_("red", color::red)
|
||||
.evalue_("green", color::green)
|
||||
.evalue_("blue", color::blue)
|
||||
.evalue_("white", color::white);
|
||||
|
||||
meta::enum_<ecolor>()
|
||||
.evalue_("red", ecolor_red)
|
||||
.evalue_("green", ecolor_green)
|
||||
.evalue_("blue", ecolor_blue)
|
||||
.evalue_("white", ecolor_white);
|
||||
|
||||
SUBCASE("color") {
|
||||
const meta::enum_type color_type = meta::resolve_type<color>();
|
||||
REQUIRE(color_type);
|
||||
|
||||
CHECK(color_type.get_id() == meta::resolve_type(color{}).get_id());
|
||||
CHECK(color_type.get_flags() == meta::enum_flags::is_scoped);
|
||||
CHECK(color_type.get_underlying_type() == meta::resolve_type<unsigned>());
|
||||
|
||||
CHECK(color_type.get_evalues().size() == 4);
|
||||
}
|
||||
|
||||
SUBCASE("ecolor") {
|
||||
const meta::enum_type ecolor_type = meta::resolve_type<ecolor>();
|
||||
REQUIRE(ecolor_type);
|
||||
|
||||
CHECK(ecolor_type.get_id() == meta::resolve_type(ecolor{}).get_id());
|
||||
CHECK(ecolor_type.get_flags() == meta::enum_flags{});
|
||||
CHECK(ecolor_type.get_underlying_type() == meta::resolve_type<int>());
|
||||
|
||||
CHECK(ecolor_type.get_evalues().size() == 4);
|
||||
}
|
||||
|
||||
SUBCASE("const color") {
|
||||
const meta::enum_type color_type = meta::resolve_type<const color>();
|
||||
REQUIRE(color_type);
|
||||
|
||||
CHECK(color_type.get_id() == meta::resolve_type(color{}).get_id());
|
||||
CHECK(color_type.get_flags() == meta::enum_flags::is_scoped);
|
||||
CHECK(color_type.get_underlying_type() == meta::resolve_type<unsigned>());
|
||||
|
||||
CHECK(color_type.get_evalues().size() == 4);
|
||||
}
|
||||
|
||||
SUBCASE("const ecolor") {
|
||||
const meta::enum_type ecolor_type = meta::resolve_type<const ecolor>();
|
||||
REQUIRE(ecolor_type);
|
||||
|
||||
CHECK(ecolor_type.get_id() == meta::resolve_type(ecolor{}).get_id());
|
||||
CHECK(ecolor_type.get_flags() == meta::enum_flags{});
|
||||
CHECK(ecolor_type.get_underlying_type() == meta::resolve_type<int>());
|
||||
|
||||
CHECK(ecolor_type.get_evalues().size() == 4);
|
||||
}
|
||||
|
||||
SUBCASE("color/get_evalue") {
|
||||
const meta::enum_type color_type = meta::resolve_type<color>();
|
||||
REQUIRE(color_type);
|
||||
|
||||
{
|
||||
const meta::evalue green_value = color_type.get_evalue("green");
|
||||
REQUIRE(green_value);
|
||||
CHECK(green_value.get_value() == color::green);
|
||||
CHECK(green_value.get_underlying_value() == meta::detail::to_underlying(color::green));
|
||||
}
|
||||
|
||||
{
|
||||
const meta::evalue yellow_value = color_type.get_evalue("yellow");
|
||||
CHECK_FALSE(yellow_value);
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("ecolor/get_evalue") {
|
||||
const meta::enum_type ecolor_type = meta::resolve_type<ecolor>();
|
||||
REQUIRE(ecolor_type);
|
||||
|
||||
{
|
||||
const meta::evalue green_value = ecolor_type.get_evalue("green");
|
||||
REQUIRE(green_value);
|
||||
CHECK(green_value.get_value() == ecolor_green);
|
||||
CHECK(green_value.get_underlying_value() == meta::detail::to_underlying(ecolor_green));
|
||||
}
|
||||
|
||||
{
|
||||
const meta::evalue yellow_value = ecolor_type.get_evalue("yellow");
|
||||
CHECK_FALSE(yellow_value);
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("color/value_to_name") {
|
||||
const meta::enum_type color_type = meta::resolve_type<color>();
|
||||
REQUIRE(color_type);
|
||||
|
||||
CHECK(color_type.value_to_name(color::red) == "red");
|
||||
CHECK(color_type.value_to_name(color::blue) == "blue");
|
||||
CHECK(color_type.value_to_name(color{100500}).empty());
|
||||
}
|
||||
|
||||
SUBCASE("ecolor/value_to_name") {
|
||||
const meta::enum_type ecolor_type = meta::resolve_type<ecolor>();
|
||||
REQUIRE(ecolor_type);
|
||||
|
||||
CHECK(ecolor_type.value_to_name(ecolor_red) == "red");
|
||||
CHECK(ecolor_type.value_to_name(ecolor_blue) == "blue");
|
||||
CHECK(ecolor_type.value_to_name(ecolor{100500}).empty());
|
||||
}
|
||||
|
||||
SUBCASE("color/name_to_value") {
|
||||
const meta::enum_type color_type = meta::resolve_type<color>();
|
||||
REQUIRE(color_type);
|
||||
|
||||
{
|
||||
REQUIRE(color_type.name_to_value("blue"));
|
||||
CHECK(color_type.name_to_value("blue") == color::blue);
|
||||
}
|
||||
|
||||
{
|
||||
REQUIRE_FALSE(color_type.name_to_value("yellow"));
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("ecolor/name_to_value") {
|
||||
const meta::enum_type ecolor_type = meta::resolve_type<ecolor>();
|
||||
REQUIRE(ecolor_type);
|
||||
|
||||
{
|
||||
REQUIRE(ecolor_type.name_to_value("blue"));
|
||||
CHECK(ecolor_type.name_to_value("blue") == ecolor_blue);
|
||||
}
|
||||
|
||||
{
|
||||
REQUIRE_FALSE(ecolor_type.name_to_value("yellow"));
|
||||
}
|
||||
}
|
||||
}
|
||||
121
develop/untests/meta_types/function_type_tests.cpp
Normal file
121
develop/untests/meta_types/function_type_tests.cpp
Normal file
@@ -0,0 +1,121 @@
|
||||
/*******************************************************************************
|
||||
* 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 "../meta_untests.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
struct ivec2 {
|
||||
int x{};
|
||||
int y{};
|
||||
};
|
||||
|
||||
void arg_copy(ivec2) {}
|
||||
void arg_ref_noexcept(ivec2&) noexcept {}
|
||||
void arg_cref_noexcept(const ivec2&) noexcept {}
|
||||
|
||||
void arg_bounded_arr(ivec2[2]) {}
|
||||
void arg_unbounded_arr(ivec2[]) {}
|
||||
void arg_bounded_const_arr(const ivec2[2]) {}
|
||||
void arg_unbounded_const_arr(const ivec2[]) {}
|
||||
}
|
||||
|
||||
TEST_CASE("meta/meta_types/function_type") {
|
||||
namespace meta = meta_hpp;
|
||||
|
||||
SUBCASE("") {
|
||||
const meta::function_type type;
|
||||
CHECK_FALSE(type);
|
||||
CHECK_FALSE(type.is_valid());
|
||||
}
|
||||
|
||||
SUBCASE("arg_copy") {
|
||||
const meta::function_type type = meta::resolve_type(&arg_copy);
|
||||
REQUIRE(type);
|
||||
|
||||
CHECK(type.get_id() == meta::resolve_type(&arg_copy).get_id());
|
||||
CHECK(type.get_flags() == meta::function_flags{});
|
||||
|
||||
CHECK(type.get_arity() == 1);
|
||||
CHECK(type.get_return_type() == meta::resolve_type<void>());
|
||||
CHECK(type.get_argument_types() == meta::any_type_list{meta::resolve_type<ivec2>()});
|
||||
|
||||
CHECK(type.get_argument_type(0) == meta::resolve_type<ivec2>());
|
||||
CHECK_FALSE(type.get_argument_type(1));
|
||||
}
|
||||
|
||||
SUBCASE("arg_ref_noexcept") {
|
||||
const meta::function_type type = meta::resolve_type(&arg_ref_noexcept);
|
||||
REQUIRE(type);
|
||||
|
||||
CHECK(type.get_id() == meta::resolve_type(&arg_ref_noexcept).get_id());
|
||||
CHECK(type.get_flags() == meta::function_flags::is_noexcept);
|
||||
CHECK(type.get_argument_types() == meta::any_type_list{meta::resolve_type<ivec2&>()});
|
||||
|
||||
CHECK(type.get_argument_type(0) == meta::resolve_type<ivec2&>());
|
||||
CHECK_FALSE(type.get_argument_type(1));
|
||||
}
|
||||
|
||||
SUBCASE("arg_cref_noexcept") {
|
||||
const meta::function_type type = meta::resolve_type(&arg_cref_noexcept);
|
||||
REQUIRE(type);
|
||||
|
||||
CHECK(type.get_id() == meta::resolve_type(&arg_cref_noexcept).get_id());
|
||||
CHECK(type.get_flags() == meta::function_flags::is_noexcept);
|
||||
CHECK(type.get_argument_types() == meta::any_type_list{meta::resolve_type<const ivec2&>()});
|
||||
|
||||
CHECK(type.get_argument_type(0) == meta::resolve_type<const ivec2&>());
|
||||
CHECK_FALSE(type.get_argument_type(1));
|
||||
}
|
||||
|
||||
SUBCASE("arg_bounded_arr") {
|
||||
const meta::function_type type = meta::resolve_type(&arg_bounded_arr);
|
||||
REQUIRE(type);
|
||||
|
||||
CHECK(type.get_id() == meta::resolve_type(&arg_bounded_arr).get_id());
|
||||
CHECK(type.get_flags() == meta::function_flags{});
|
||||
CHECK(type.get_argument_types() == meta::any_type_list{meta::resolve_type<ivec2*>()});
|
||||
|
||||
CHECK(type.get_argument_type(0) == meta::resolve_type<ivec2*>());
|
||||
CHECK_FALSE(type.get_argument_type(1));
|
||||
}
|
||||
|
||||
SUBCASE("arg_unbounded_arr") {
|
||||
const meta::function_type type = meta::resolve_type(&arg_unbounded_arr);
|
||||
REQUIRE(type);
|
||||
|
||||
CHECK(type.get_id() == meta::resolve_type(&arg_unbounded_arr).get_id());
|
||||
CHECK(type.get_flags() == meta::function_flags{});
|
||||
CHECK(type.get_argument_types() == meta::any_type_list{meta::resolve_type<ivec2*>()});
|
||||
|
||||
CHECK(type.get_argument_type(0) == meta::resolve_type<ivec2*>());
|
||||
CHECK_FALSE(type.get_argument_type(1));
|
||||
}
|
||||
|
||||
SUBCASE("arg_bounded_const_arr") {
|
||||
const meta::function_type type = meta::resolve_type(&arg_bounded_const_arr);
|
||||
REQUIRE(type);
|
||||
|
||||
CHECK(type.get_id() == meta::resolve_type(&arg_bounded_const_arr).get_id());
|
||||
CHECK(type.get_flags() == meta::function_flags{});
|
||||
CHECK(type.get_argument_types() == meta::any_type_list{meta::resolve_type<const ivec2*>()});
|
||||
|
||||
CHECK(type.get_argument_type(0) == meta::resolve_type<const ivec2*>());
|
||||
CHECK_FALSE(type.get_argument_type(1));
|
||||
}
|
||||
|
||||
SUBCASE("arg_unbounded_const_arr") {
|
||||
const meta::function_type type = meta::resolve_type(&arg_unbounded_const_arr);
|
||||
REQUIRE(type);
|
||||
|
||||
CHECK(type.get_id() == meta::resolve_type(&arg_unbounded_const_arr).get_id());
|
||||
CHECK(type.get_flags() == meta::function_flags{});
|
||||
CHECK(type.get_argument_types() == meta::any_type_list{meta::resolve_type<const ivec2*>()});
|
||||
|
||||
CHECK(type.get_argument_type(0) == meta::resolve_type<const ivec2*>());
|
||||
CHECK_FALSE(type.get_argument_type(1));
|
||||
}
|
||||
}
|
||||
47
develop/untests/meta_types/member_type_tests.cpp
Normal file
47
develop/untests/meta_types/member_type_tests.cpp
Normal file
@@ -0,0 +1,47 @@
|
||||
/*******************************************************************************
|
||||
* 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 "../meta_untests.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
struct clazz_1 {
|
||||
int int_member = 1;
|
||||
const int const_int_member = 2;
|
||||
};
|
||||
}
|
||||
|
||||
TEST_CASE("meta/meta_types/member_type") {
|
||||
namespace meta = meta_hpp;
|
||||
|
||||
SUBCASE("") {
|
||||
const meta::member_type type;
|
||||
CHECK_FALSE(type);
|
||||
CHECK_FALSE(type.is_valid());
|
||||
}
|
||||
|
||||
SUBCASE("int") {
|
||||
const meta::member_type type = meta::resolve_type(&clazz_1::int_member);
|
||||
REQUIRE(type);
|
||||
|
||||
CHECK(type.get_id() == meta::resolve_type(&clazz_1::int_member).get_id());
|
||||
CHECK(type.get_flags() == meta::member_flags{});
|
||||
|
||||
CHECK(type.get_owner_type() == meta::resolve_type<clazz_1>());
|
||||
CHECK(type.get_value_type() == meta::resolve_type<int>());
|
||||
}
|
||||
|
||||
SUBCASE("const int") {
|
||||
const meta::member_type type = meta::resolve_type(&clazz_1::const_int_member);
|
||||
REQUIRE(type);
|
||||
|
||||
CHECK(type.get_id() == meta::resolve_type(&clazz_1::const_int_member).get_id());
|
||||
CHECK(type.get_flags() == meta::member_flags::is_readonly);
|
||||
|
||||
CHECK(type.get_owner_type() == meta::resolve_type<clazz_1>());
|
||||
CHECK(type.get_value_type() == meta::resolve_type<int>());
|
||||
}
|
||||
}
|
||||
68
develop/untests/meta_types/method_type_tests.cpp
Normal file
68
develop/untests/meta_types/method_type_tests.cpp
Normal file
@@ -0,0 +1,68 @@
|
||||
/*******************************************************************************
|
||||
* 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 "../meta_untests.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
struct ivec2 {
|
||||
int x{};
|
||||
int y{};
|
||||
|
||||
int& at(std::size_t i) {
|
||||
switch ( i ) {
|
||||
case 0: return x;
|
||||
case 1: return y;
|
||||
default: throw std::out_of_range("ivec2::at");
|
||||
}
|
||||
}
|
||||
|
||||
int length2() const noexcept {
|
||||
return x * x + y * y;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
TEST_CASE("meta/meta_types/method_type") {
|
||||
namespace meta = meta_hpp;
|
||||
|
||||
SUBCASE("") {
|
||||
const meta::method_type type;
|
||||
CHECK_FALSE(type);
|
||||
CHECK_FALSE(type.is_valid());
|
||||
}
|
||||
|
||||
SUBCASE("ivec2::at") {
|
||||
const meta::method_type type = meta::resolve_type(&ivec2::at);
|
||||
REQUIRE(type);
|
||||
|
||||
CHECK(type.get_id() == meta::resolve_type(&ivec2::at).get_id());
|
||||
CHECK(type.get_flags() == meta::method_flags{});
|
||||
|
||||
CHECK(type.get_arity() == 1);
|
||||
CHECK(type.get_owner_type() == meta::resolve_type<ivec2>());
|
||||
CHECK(type.get_return_type() == meta::resolve_type<int&>());
|
||||
CHECK(type.get_argument_types() == meta::any_type_list{meta::resolve_type<std::size_t>()});
|
||||
|
||||
CHECK(type.get_argument_type(0) == meta::resolve_type<std::size_t>());
|
||||
CHECK_FALSE(type.get_argument_type(1));
|
||||
}
|
||||
|
||||
SUBCASE("ivec2::length2") {
|
||||
const meta::method_type type = meta::resolve_type(&ivec2::length2);
|
||||
REQUIRE(type);
|
||||
|
||||
CHECK(type.get_id() == meta::resolve_type(&ivec2::length2).get_id());
|
||||
CHECK(type.get_flags() == (meta::method_flags::is_const | meta::method_flags::is_noexcept));
|
||||
|
||||
CHECK(type.get_arity() == 0);
|
||||
CHECK(type.get_owner_type() == meta::resolve_type<ivec2>());
|
||||
CHECK(type.get_return_type() == meta::resolve_type<int>());
|
||||
CHECK(type.get_argument_types() == meta::any_type_list{});
|
||||
|
||||
CHECK_FALSE(type.get_argument_type(0));
|
||||
}
|
||||
}
|
||||
54
develop/untests/meta_types/number_type_tests.cpp
Normal file
54
develop/untests/meta_types/number_type_tests.cpp
Normal file
@@ -0,0 +1,54 @@
|
||||
/*******************************************************************************
|
||||
* 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 "../meta_untests.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
}
|
||||
|
||||
TEST_CASE("meta/meta_types/number_type") {
|
||||
namespace meta = meta_hpp;
|
||||
|
||||
SUBCASE("") {
|
||||
const meta::number_type type;
|
||||
CHECK_FALSE(type);
|
||||
CHECK_FALSE(type.is_valid());
|
||||
}
|
||||
|
||||
SUBCASE("int") {
|
||||
const meta::number_type type = meta::resolve_type<int>();
|
||||
REQUIRE(type);
|
||||
|
||||
CHECK(type.get_size() == sizeof(int));
|
||||
CHECK(type.get_align() == alignof(int));
|
||||
CHECK(type.get_flags() == (
|
||||
meta::number_flags::is_signed |
|
||||
meta::number_flags::is_integral));
|
||||
}
|
||||
|
||||
SUBCASE("const float") {
|
||||
const meta::number_type type = meta::resolve_type<const float>();
|
||||
REQUIRE(type);
|
||||
|
||||
CHECK(type.get_size() == sizeof(float));
|
||||
CHECK(type.get_align() == alignof(float));
|
||||
CHECK(type.get_flags() == (
|
||||
meta::number_flags::is_signed |
|
||||
meta::number_flags::is_floating_point));
|
||||
}
|
||||
|
||||
SUBCASE("const unsigned long long") {
|
||||
const meta::number_type type = meta::resolve_type<const unsigned long long>();
|
||||
REQUIRE(type);
|
||||
|
||||
CHECK(type.get_size() == sizeof(unsigned long long));
|
||||
CHECK(type.get_align() == alignof(unsigned long long));
|
||||
CHECK(type.get_flags() == (
|
||||
meta::number_flags::is_unsigned |
|
||||
meta::number_flags::is_integral));
|
||||
}
|
||||
}
|
||||
57
develop/untests/meta_types/pointer_type_tests.cpp
Normal file
57
develop/untests/meta_types/pointer_type_tests.cpp
Normal file
@@ -0,0 +1,57 @@
|
||||
/*******************************************************************************
|
||||
* 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 "../meta_untests.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
}
|
||||
|
||||
TEST_CASE("meta/meta_types/pointer_type") {
|
||||
namespace meta = meta_hpp;
|
||||
|
||||
SUBCASE("") {
|
||||
const meta::pointer_type type;
|
||||
CHECK_FALSE(type);
|
||||
CHECK_FALSE(type.is_valid());
|
||||
}
|
||||
|
||||
SUBCASE("int*") {
|
||||
const meta::pointer_type type = meta::resolve_type<int*>();
|
||||
REQUIRE(type);
|
||||
|
||||
CHECK(type.get_id() == meta::resolve_type<int*>().get_id());
|
||||
CHECK(type.get_flags() == meta::pointer_flags{});
|
||||
CHECK(type.get_data_type() == meta::resolve_type<int>());
|
||||
}
|
||||
|
||||
SUBCASE("const int* const") {
|
||||
const meta::pointer_type type = meta::resolve_type<const int* const>();
|
||||
REQUIRE(type);
|
||||
|
||||
CHECK(type.get_id() == meta::resolve_type<const int*>().get_id());
|
||||
CHECK(type.get_flags() == meta::pointer_flags::is_readonly);
|
||||
CHECK(type.get_data_type() == meta::resolve_type<int>());
|
||||
}
|
||||
|
||||
SUBCASE("int**") {
|
||||
const meta::pointer_type type = meta::resolve_type<int**>();
|
||||
REQUIRE(type);
|
||||
|
||||
CHECK(type.get_id() == meta::resolve_type<int**>().get_id());
|
||||
CHECK(type.get_flags() == meta::pointer_flags{});
|
||||
CHECK(type.get_data_type() == meta::resolve_type<int*>());
|
||||
}
|
||||
|
||||
SUBCASE("const int* const*") {
|
||||
const meta::pointer_type type = meta::resolve_type<const int* const*>();
|
||||
REQUIRE(type);
|
||||
|
||||
CHECK(type.get_id() == meta::resolve_type<const int* const*>().get_id());
|
||||
CHECK(type.get_flags() == meta::pointer_flags::is_readonly);
|
||||
CHECK(type.get_data_type() == meta::resolve_type<const int*>());
|
||||
}
|
||||
}
|
||||
57
develop/untests/meta_types/reference_type_tests.cpp
Normal file
57
develop/untests/meta_types/reference_type_tests.cpp
Normal file
@@ -0,0 +1,57 @@
|
||||
/*******************************************************************************
|
||||
* 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 "../meta_untests.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
}
|
||||
|
||||
TEST_CASE("meta/meta_types/reference_type") {
|
||||
namespace meta = meta_hpp;
|
||||
|
||||
SUBCASE("") {
|
||||
const meta::reference_type type;
|
||||
CHECK_FALSE(type);
|
||||
CHECK_FALSE(type.is_valid());
|
||||
}
|
||||
|
||||
SUBCASE("int&") {
|
||||
const meta::reference_type type = meta::resolve_type<int&>();
|
||||
REQUIRE(type);
|
||||
|
||||
CHECK(type.get_id() == meta::resolve_type<int&>().get_id());
|
||||
CHECK(type.get_flags() == (meta::reference_flags::is_lvalue));
|
||||
CHECK(type.get_data_type() == meta::resolve_type<int>());
|
||||
}
|
||||
|
||||
SUBCASE("const int&") {
|
||||
const meta::reference_type type = meta::resolve_type<const int&>();
|
||||
REQUIRE(type);
|
||||
|
||||
CHECK(type.get_id() == meta::resolve_type<const int&>().get_id());
|
||||
CHECK(type.get_flags() == (meta::reference_flags::is_readonly | meta::reference_flags::is_lvalue));
|
||||
CHECK(type.get_data_type() == meta::resolve_type<int>());
|
||||
}
|
||||
|
||||
SUBCASE("int&&") {
|
||||
const meta::reference_type type = meta::resolve_type<int&&>();
|
||||
REQUIRE(type);
|
||||
|
||||
CHECK(type.get_id() == meta::resolve_type<int&&>().get_id());
|
||||
CHECK(type.get_flags() == (meta::reference_flags::is_rvalue));
|
||||
CHECK(type.get_data_type() == meta::resolve_type<int>());
|
||||
}
|
||||
|
||||
SUBCASE("const int&&") {
|
||||
const meta::reference_type type = meta::resolve_type<const int&&>();
|
||||
REQUIRE(type);
|
||||
|
||||
CHECK(type.get_id() == meta::resolve_type<const int&&>().get_id());
|
||||
CHECK(type.get_flags() == (meta::reference_flags::is_readonly | meta::reference_flags::is_rvalue));
|
||||
CHECK(type.get_data_type() == meta::resolve_type<int>());
|
||||
}
|
||||
}
|
||||
44
develop/untests/meta_types/void_type_tests.cpp
Normal file
44
develop/untests/meta_types/void_type_tests.cpp
Normal file
@@ -0,0 +1,44 @@
|
||||
/*******************************************************************************
|
||||
* 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 "../meta_untests.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
}
|
||||
|
||||
TEST_CASE("meta/meta_types/void_type") {
|
||||
namespace meta = meta_hpp;
|
||||
|
||||
SUBCASE("") {
|
||||
const meta::void_type type;
|
||||
CHECK_FALSE(type);
|
||||
CHECK_FALSE(type.is_valid());
|
||||
}
|
||||
|
||||
SUBCASE("void") {
|
||||
const meta::void_type type = meta::resolve_type<void>();
|
||||
REQUIRE(type);
|
||||
|
||||
CHECK(type.get_id() == meta::resolve_type<void>().get_id());
|
||||
}
|
||||
|
||||
SUBCASE("void*") {
|
||||
void* ptr{};
|
||||
const meta::pointer_type ptr_type = meta::resolve_type(ptr);
|
||||
CHECK(ptr_type == meta::resolve_type<void*>());
|
||||
CHECK_FALSE(ptr_type.get_flags().has(meta::pointer_flags::is_readonly));
|
||||
CHECK(ptr_type.get_data_type() == meta::resolve_type<void>());
|
||||
}
|
||||
|
||||
SUBCASE("const void*") {
|
||||
const void* ptr{};
|
||||
const meta::pointer_type ptr_type = meta::resolve_type(ptr);
|
||||
CHECK(ptr_type == meta::resolve_type<const void*>());
|
||||
CHECK(ptr_type.get_flags().has(meta::pointer_flags::is_readonly));
|
||||
CHECK(ptr_type.get_data_type() == meta::resolve_type<void>());
|
||||
}
|
||||
}
|
||||
11
develop/untests/meta_untests.cpp
Normal file
11
develop/untests/meta_untests.cpp
Normal file
@@ -0,0 +1,11 @@
|
||||
/*******************************************************************************
|
||||
* 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 "meta_untests.hpp"
|
||||
|
||||
TEST_CASE("meta_hpp") {
|
||||
namespace meta = meta_hpp;
|
||||
}
|
||||
11
develop/untests/meta_untests.hpp
Normal file
11
develop/untests/meta_untests.hpp
Normal file
@@ -0,0 +1,11 @@
|
||||
/*******************************************************************************
|
||||
* 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 <meta.hpp/meta_all.hpp>
|
||||
#include <doctest/doctest.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
352
develop/untests/meta_utilities/arg2_tests.cpp
Normal file
352
develop/untests/meta_utilities/arg2_tests.cpp
Normal 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-2023, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
******************************************************************************/
|
||||
|
||||
#include "../meta_untests.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
struct A {
|
||||
A() = default;
|
||||
virtual ~A() = default;
|
||||
|
||||
[[maybe_unused]] A(A&&) noexcept { ++move_ctors_; }
|
||||
[[maybe_unused]] 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 bi = 2;
|
||||
[[maybe_unused, nodiscard]] int f() const { return bi; }
|
||||
};
|
||||
|
||||
struct C : virtual A {
|
||||
int ci = 3;
|
||||
[[maybe_unused, nodiscard]] int f() const { return ci; }
|
||||
};
|
||||
|
||||
struct D : B, C {
|
||||
int di = 4;
|
||||
[[maybe_unused, nodiscard]] int f() const { return di; }
|
||||
};
|
||||
}
|
||||
|
||||
TEST_CASE("meta/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("meta/meta_utilities/arg2/cast") {
|
||||
namespace meta = meta_hpp;
|
||||
using meta::detail::uarg;
|
||||
|
||||
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(uarg{LV()}.can_cast_to<A>());
|
||||
CHECK(uarg{LV()}.can_cast_to<const A>());
|
||||
CHECK(uarg{LV()}.can_cast_to<A&>());
|
||||
CHECK(uarg{LV()}.can_cast_to<const A&>());
|
||||
CHECK_FALSE(uarg{LV()}.can_cast_to<A&&>());
|
||||
CHECK_FALSE(uarg{LV()}.can_cast_to<const A&&>());
|
||||
|
||||
CHECK(A::copy_ctors_ == 0);
|
||||
CHECK(A::move_ctors_ == 0);
|
||||
|
||||
CHECK(uarg{LV()}.cast<A>().f() == 1);
|
||||
CHECK(uarg{LV()}.cast<const A>().f() == 1);
|
||||
CHECK(uarg{LV()}.cast<A&>().f() == 1);
|
||||
CHECK(uarg{LV()}.cast<const A&>().f() == 1);
|
||||
CHECK_THROWS(std::ignore = uarg{LV()}.cast<A&&>());
|
||||
CHECK_THROWS(std::ignore = uarg{LV()}.cast<const A&&>());
|
||||
|
||||
CHECK(A::copy_ctors_ == 2);
|
||||
CHECK(A::move_ctors_ == 0);
|
||||
}
|
||||
|
||||
SUBCASE("CLV") {
|
||||
CHECK(uarg{CLV()}.can_cast_to<A>());
|
||||
CHECK(uarg{CLV()}.can_cast_to<const A>());
|
||||
CHECK_FALSE(uarg{CLV()}.can_cast_to<A&>());
|
||||
CHECK(uarg{CLV()}.can_cast_to<const A&>());
|
||||
CHECK_FALSE(uarg{CLV()}.can_cast_to<A&&>());
|
||||
CHECK_FALSE(uarg{CLV()}.can_cast_to<const A&&>());
|
||||
|
||||
CHECK(A::copy_ctors_ == 0);
|
||||
CHECK(A::move_ctors_ == 0);
|
||||
|
||||
CHECK(uarg{CLV()}.cast<A>().f() == 1);
|
||||
CHECK(uarg{CLV()}.cast<const A>().f() == 1);
|
||||
CHECK_THROWS(std::ignore = uarg{CLV()}.cast<A&>());
|
||||
CHECK(uarg{CLV()}.cast<const A&>().f() == 1);
|
||||
CHECK_THROWS(std::ignore = uarg{CLV()}.cast<A&&>());
|
||||
CHECK_THROWS(std::ignore = uarg{CLV()}.cast<const A&&>());
|
||||
|
||||
CHECK(A::copy_ctors_ == 2);
|
||||
CHECK(A::move_ctors_ == 0);
|
||||
}
|
||||
|
||||
SUBCASE("XV") {
|
||||
CHECK(uarg{XV()}.can_cast_to<A>());
|
||||
CHECK(uarg{XV()}.can_cast_to<const A>());
|
||||
CHECK_FALSE(uarg{XV()}.can_cast_to<A&>());
|
||||
CHECK(uarg{XV()}.can_cast_to<const A&>());
|
||||
CHECK(uarg{XV()}.can_cast_to<A&&>());
|
||||
CHECK(uarg{XV()}.can_cast_to<const A&&>());
|
||||
|
||||
CHECK(A::copy_ctors_ == 0);
|
||||
CHECK(A::move_ctors_ == 0);
|
||||
|
||||
CHECK(uarg{XV()}.cast<A>().f() == 1);
|
||||
CHECK(uarg{XV()}.cast<const A>().f() == 1);
|
||||
CHECK_THROWS(std::ignore = uarg{XV()}.cast<A&>());
|
||||
CHECK(uarg{XV()}.cast<const A&>().f() == 1);
|
||||
CHECK(uarg{XV()}.cast<A&&>().f() == 1);
|
||||
CHECK(uarg{XV()}.cast<const A&&>().f() == 1);
|
||||
|
||||
CHECK(A::copy_ctors_ == 0);
|
||||
CHECK(A::move_ctors_ == 2);
|
||||
}
|
||||
|
||||
SUBCASE("CXV") {
|
||||
CHECK(uarg{CXV()}.can_cast_to<A>());
|
||||
CHECK(uarg{CXV()}.can_cast_to<const A>());
|
||||
CHECK_FALSE(uarg{CXV()}.can_cast_to<A&>());
|
||||
CHECK(uarg{CXV()}.can_cast_to<const A&>());
|
||||
CHECK_FALSE(uarg{CXV()}.can_cast_to<A&&>());
|
||||
CHECK(uarg{CXV()}.can_cast_to<const A&&>());
|
||||
|
||||
CHECK(A::copy_ctors_ == 0);
|
||||
CHECK(A::move_ctors_ == 0);
|
||||
|
||||
CHECK(uarg{CXV()}.cast<A>().f() == 1);
|
||||
CHECK(uarg{CXV()}.cast<const A>().f() == 1);
|
||||
CHECK_THROWS(std::ignore = uarg{CXV()}.cast<A&>());
|
||||
CHECK(uarg{CXV()}.cast<const A&>().f() == 1);
|
||||
CHECK_THROWS(std::ignore = uarg{CXV()}.cast<A&&>());
|
||||
CHECK(uarg{CXV()}.cast<const A&&>().f() == 1);
|
||||
|
||||
CHECK(A::copy_ctors_ == 2);
|
||||
CHECK(A::move_ctors_ == 0);
|
||||
}
|
||||
|
||||
SUBCASE("PRV") {
|
||||
CHECK(uarg{PRV()}.can_cast_to<A>());
|
||||
CHECK(uarg{PRV()}.can_cast_to<const A>());
|
||||
CHECK_FALSE(uarg{PRV()}.can_cast_to<A&>());
|
||||
CHECK(uarg{PRV()}.can_cast_to<const A&>());
|
||||
CHECK(uarg{PRV()}.can_cast_to<A&&>());
|
||||
CHECK(uarg{PRV()}.can_cast_to<const A&&>());
|
||||
|
||||
CHECK(A::copy_ctors_ == 0);
|
||||
CHECK(A::move_ctors_ == 0);
|
||||
|
||||
CHECK(uarg{PRV()}.cast<A>().f() == 1);
|
||||
CHECK(uarg{PRV()}.cast<const A>().f() == 1);
|
||||
CHECK_THROWS(std::ignore = uarg{PRV()}.cast<A&>());
|
||||
CHECK(uarg{PRV()}.cast<const A&>().f() == 1);
|
||||
CHECK(uarg{PRV()}.cast<A&&>().f() == 1);
|
||||
CHECK(uarg{PRV()}.cast<const A&&>().f() == 1);
|
||||
|
||||
CHECK(A::copy_ctors_ == 0);
|
||||
CHECK(A::move_ctors_ == 2);
|
||||
}
|
||||
|
||||
SUBCASE("CPRV") {
|
||||
CHECK(uarg{CPRV()}.can_cast_to<A>());
|
||||
CHECK(uarg{CPRV()}.can_cast_to<const A>());
|
||||
CHECK_FALSE(uarg{CPRV()}.can_cast_to<A&>());
|
||||
CHECK(uarg{CPRV()}.can_cast_to<const A&>());
|
||||
CHECK_FALSE(uarg{CPRV()}.can_cast_to<A&&>());
|
||||
CHECK(uarg{CPRV()}.can_cast_to<const A&&>());
|
||||
|
||||
CHECK(A::copy_ctors_ == 0);
|
||||
CHECK(A::move_ctors_ == 0);
|
||||
|
||||
CHECK(uarg{CPRV()}.cast<A>().f() == 1);
|
||||
CHECK(uarg{CPRV()}.cast<const A>().f() == 1);
|
||||
CHECK_THROWS(std::ignore = uarg{CPRV()}.cast<A&>());
|
||||
CHECK(uarg{CPRV()}.cast<const A&>().f() == 1);
|
||||
CHECK_THROWS(std::ignore = uarg{CPRV()}.cast<A&&>());
|
||||
CHECK(uarg{CPRV()}.cast<const A&&>().f() == 1);
|
||||
|
||||
CHECK(A::copy_ctors_ == 2);
|
||||
CHECK(A::move_ctors_ == 0);
|
||||
}
|
||||
|
||||
SUBCASE("LV_PTR") {
|
||||
CHECK(uarg{LV_PTR()}.can_cast_to<A*>());
|
||||
CHECK(uarg{LV_PTR()}.can_cast_to<A* const>());
|
||||
CHECK(uarg{LV_PTR()}.can_cast_to<const A*>());
|
||||
CHECK(uarg{LV_PTR()}.can_cast_to<const A* const>());
|
||||
|
||||
CHECK(uarg{LV_PTR()}.cast<A*>()->f() == 1);
|
||||
CHECK(uarg{LV_PTR()}.cast<A* const>()->f() == 1);
|
||||
CHECK(uarg{LV_PTR()}.cast<const A*>()->f() == 1);
|
||||
CHECK(uarg{LV_PTR()}.cast<const A* const>()->f() == 1);
|
||||
}
|
||||
|
||||
SUBCASE("LV_CPTR") {
|
||||
CHECK_FALSE(uarg{LV_CPTR()}.can_cast_to<A*>());
|
||||
CHECK_FALSE(uarg{LV_CPTR()}.can_cast_to<A* const>());
|
||||
CHECK(uarg{LV_CPTR()}.can_cast_to<const A*>());
|
||||
CHECK(uarg{LV_CPTR()}.can_cast_to<const A* const>());
|
||||
|
||||
CHECK_THROWS(std::ignore = uarg{LV_CPTR()}.cast<A*>());
|
||||
CHECK_THROWS(std::ignore = uarg{LV_CPTR()}.cast<A* const>());
|
||||
CHECK(uarg{LV_CPTR()}.cast<const A*>()->f() == 1);
|
||||
CHECK(uarg{LV_CPTR()}.cast<const A* const>()->f() == 1);
|
||||
}
|
||||
|
||||
SUBCASE("CLV_PTR") {
|
||||
CHECK(uarg{CLV_PTR()}.can_cast_to<A*>());
|
||||
CHECK(uarg{CLV_PTR()}.can_cast_to<A* const>());
|
||||
CHECK(uarg{CLV_PTR()}.can_cast_to<const A*>());
|
||||
CHECK(uarg{CLV_PTR()}.can_cast_to<const A* const>());
|
||||
|
||||
CHECK(uarg{CLV_PTR()}.cast<A*>()->f() == 1);
|
||||
CHECK(uarg{CLV_PTR()}.cast<A* const>()->f() == 1);
|
||||
CHECK(uarg{CLV_PTR()}.cast<const A*>()->f() == 1);
|
||||
CHECK(uarg{CLV_PTR()}.cast<const A* const>()->f() == 1);
|
||||
}
|
||||
|
||||
SUBCASE("CLV_CPTR") {
|
||||
CHECK_FALSE(uarg{CLV_CPTR()}.can_cast_to<A*>());
|
||||
CHECK_FALSE(uarg{CLV_CPTR()}.can_cast_to<A* const>());
|
||||
CHECK(uarg{CLV_CPTR()}.can_cast_to<const A*>());
|
||||
CHECK(uarg{CLV_CPTR()}.can_cast_to<const A* const>());
|
||||
|
||||
CHECK_THROWS(std::ignore = uarg{CLV_CPTR()}.cast<A*>());
|
||||
CHECK_THROWS(std::ignore = uarg{CLV_CPTR()}.cast<A* const>());
|
||||
CHECK(uarg{CLV_CPTR()}.cast<const A*>()->f() == 1);
|
||||
CHECK(uarg{CLV_CPTR()}.cast<const A* const>()->f() == 1);
|
||||
}
|
||||
|
||||
SUBCASE("XV_PTR") {
|
||||
CHECK(uarg{XV_PTR()}.can_cast_to<A*>());
|
||||
CHECK(uarg{XV_PTR()}.can_cast_to<A* const>());
|
||||
CHECK(uarg{XV_PTR()}.can_cast_to<const A*>());
|
||||
CHECK(uarg{XV_PTR()}.can_cast_to<const A* const>());
|
||||
|
||||
CHECK(uarg{XV_PTR()}.cast<A*>()->f() == 1);
|
||||
CHECK(uarg{XV_PTR()}.cast<A* const>()->f() == 1);
|
||||
CHECK(uarg{XV_PTR()}.cast<const A*>()->f() == 1);
|
||||
CHECK(uarg{XV_PTR()}.cast<const A* const>()->f() == 1);
|
||||
}
|
||||
|
||||
SUBCASE("XV_CPTR") {
|
||||
CHECK_FALSE(uarg{XV_CPTR()}.can_cast_to<A*>());
|
||||
CHECK_FALSE(uarg{XV_CPTR()}.can_cast_to<A* const>());
|
||||
CHECK(uarg{XV_CPTR()}.can_cast_to<const A*>());
|
||||
CHECK(uarg{XV_CPTR()}.can_cast_to<const A* const>());
|
||||
|
||||
CHECK_THROWS(std::ignore = uarg{XV_CPTR()}.cast<A*>());
|
||||
CHECK_THROWS(std::ignore = uarg{XV_CPTR()}.cast<A* const>());
|
||||
CHECK(uarg{XV_CPTR()}.cast<const A*>()->f() == 1);
|
||||
CHECK(uarg{XV_CPTR()}.cast<const A* const>()->f() == 1);
|
||||
}
|
||||
|
||||
SUBCASE("CXV_PTR") {
|
||||
CHECK(uarg{CXV_PTR()}.can_cast_to<A*>());
|
||||
CHECK(uarg{CXV_PTR()}.can_cast_to<A* const>());
|
||||
CHECK(uarg{CXV_PTR()}.can_cast_to<const A*>());
|
||||
CHECK(uarg{CXV_PTR()}.can_cast_to<const A* const>());
|
||||
|
||||
CHECK(uarg{CXV_PTR()}.cast<A*>()->f() == 1);
|
||||
CHECK(uarg{CXV_PTR()}.cast<A* const>()->f() == 1);
|
||||
CHECK(uarg{CXV_PTR()}.cast<const A*>()->f() == 1);
|
||||
CHECK(uarg{CXV_PTR()}.cast<const A* const>()->f() == 1);
|
||||
}
|
||||
|
||||
SUBCASE("CXV_CPTR") {
|
||||
CHECK_FALSE(uarg{CXV_CPTR()}.can_cast_to<A*>());
|
||||
CHECK_FALSE(uarg{CXV_CPTR()}.can_cast_to<A* const>());
|
||||
CHECK(uarg{CXV_CPTR()}.can_cast_to<const A*>());
|
||||
CHECK(uarg{CXV_CPTR()}.can_cast_to<const A* const>());
|
||||
|
||||
CHECK_THROWS(std::ignore = uarg{CXV_CPTR()}.cast<A*>());
|
||||
CHECK_THROWS(std::ignore = uarg{CXV_CPTR()}.cast<A* const>());
|
||||
CHECK(uarg{CXV_CPTR()}.cast<const A*>()->f() == 1);
|
||||
CHECK(uarg{CXV_CPTR()}.cast<const A* const>()->f() == 1);
|
||||
}
|
||||
|
||||
SUBCASE("PRV_PTR") {
|
||||
CHECK(uarg{PRV_PTR()}.can_cast_to<A*>());
|
||||
CHECK(uarg{PRV_PTR()}.can_cast_to<A* const>());
|
||||
CHECK(uarg{PRV_PTR()}.can_cast_to<const A*>());
|
||||
CHECK(uarg{PRV_PTR()}.can_cast_to<const A* const>());
|
||||
|
||||
CHECK(uarg{PRV_PTR()}.cast<A*>()->f() == 1);
|
||||
CHECK(uarg{PRV_PTR()}.cast<A* const>()->f() == 1);
|
||||
CHECK(uarg{PRV_PTR()}.cast<const A*>()->f() == 1);
|
||||
CHECK(uarg{PRV_PTR()}.cast<const A* const>()->f() == 1);
|
||||
}
|
||||
|
||||
SUBCASE("PRV_CPTR") {
|
||||
CHECK_FALSE(uarg{PRV_CPTR()}.can_cast_to<A*>());
|
||||
CHECK_FALSE(uarg{PRV_CPTR()}.can_cast_to<A* const>());
|
||||
CHECK(uarg{PRV_CPTR()}.can_cast_to<const A*>());
|
||||
CHECK(uarg{PRV_CPTR()}.can_cast_to<const A* const>());
|
||||
|
||||
CHECK_THROWS(std::ignore = uarg{PRV_CPTR()}.cast<A*>());
|
||||
CHECK_THROWS(std::ignore = uarg{PRV_CPTR()}.cast<A* const>());
|
||||
CHECK(uarg{PRV_CPTR()}.cast<const A*>()->f() == 1);
|
||||
CHECK(uarg{PRV_CPTR()}.cast<const A* const>()->f() == 1);
|
||||
}
|
||||
}
|
||||
127
develop/untests/meta_utilities/arg3_tests.cpp
Normal file
127
develop/untests/meta_utilities/arg3_tests.cpp
Normal 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-2023, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
******************************************************************************/
|
||||
|
||||
#include "../meta_untests.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 bi = 2;
|
||||
[[maybe_unused, nodiscard]] int f() const { return bi; }
|
||||
};
|
||||
|
||||
struct C : virtual A {
|
||||
int ci = 3;
|
||||
[[maybe_unused, nodiscard]] int f() const { return ci; }
|
||||
};
|
||||
|
||||
struct D : B, C {
|
||||
int di = 4;
|
||||
[[maybe_unused, nodiscard]] int f() const { return di; }
|
||||
};
|
||||
}
|
||||
|
||||
TEST_CASE("meta/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("meta/meta_utilities/arg3/cast") {
|
||||
namespace meta = meta_hpp;
|
||||
using meta::detail::uarg;
|
||||
|
||||
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(uarg{LV()}.can_cast_to<A>());
|
||||
CHECK_FALSE(uarg{LV()}.can_cast_to<const A>());
|
||||
|
||||
CHECK_THROWS(std::ignore = uarg{LV()}.cast<A>());
|
||||
CHECK_THROWS(std::ignore = uarg{LV()}.cast<const A>());
|
||||
}
|
||||
|
||||
SUBCASE("CLV") {
|
||||
CHECK_FALSE(uarg{CLV()}.can_cast_to<A>());
|
||||
CHECK_FALSE(uarg{CLV()}.can_cast_to<const A>());
|
||||
|
||||
CHECK_THROWS(std::ignore = uarg{CLV()}.cast<A>());
|
||||
CHECK_THROWS(std::ignore = uarg{CLV()}.cast<const A>());
|
||||
}
|
||||
|
||||
SUBCASE("XV") {
|
||||
CHECK_FALSE(uarg{XV()}.can_cast_to<A>());
|
||||
CHECK_FALSE(uarg{XV()}.can_cast_to<const A>());
|
||||
|
||||
CHECK_THROWS(std::ignore = uarg{XV()}.cast<A>());
|
||||
CHECK_THROWS(std::ignore = uarg{XV()}.cast<const A>());
|
||||
}
|
||||
|
||||
SUBCASE("CXV") {
|
||||
CHECK_FALSE(uarg{CXV()}.can_cast_to<A>());
|
||||
CHECK_FALSE(uarg{CXV()}.can_cast_to<const A>());
|
||||
|
||||
CHECK_THROWS(std::ignore = uarg{CXV()}.cast<A>());
|
||||
CHECK_THROWS(std::ignore = uarg{CXV()}.cast<const A>());
|
||||
}
|
||||
|
||||
SUBCASE("PRV") {
|
||||
CHECK_FALSE(uarg{PRV()}.can_cast_to<A>());
|
||||
CHECK_FALSE(uarg{PRV()}.can_cast_to<const A>());
|
||||
|
||||
CHECK_THROWS(std::ignore = uarg{PRV()}.cast<A>());
|
||||
CHECK_THROWS(std::ignore = uarg{PRV()}.cast<const A>());
|
||||
}
|
||||
|
||||
SUBCASE("CPRV") {
|
||||
CHECK_FALSE(uarg{CPRV()}.can_cast_to<A>());
|
||||
CHECK_FALSE(uarg{CPRV()}.can_cast_to<const A>());
|
||||
|
||||
CHECK_THROWS(std::ignore = uarg{CPRV()}.cast<A>());
|
||||
CHECK_THROWS(std::ignore = uarg{CPRV()}.cast<const A>());
|
||||
}
|
||||
}
|
||||
144
develop/untests/meta_utilities/arg4_tests.cpp
Normal file
144
develop/untests/meta_utilities/arg4_tests.cpp
Normal 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-2023, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
******************************************************************************/
|
||||
|
||||
#include "../meta_untests.hpp"
|
||||
|
||||
TEST_CASE("meta/meta_utilities/arg4/cast") {
|
||||
namespace meta = meta_hpp;
|
||||
using meta::detail::uarg;
|
||||
|
||||
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(uarg{LV_PTR()}.can_cast_to<int*>());
|
||||
CHECK(uarg{LV_PTR()}.can_cast_to<int* const>());
|
||||
CHECK(uarg{LV_PTR()}.can_cast_to<const int*>());
|
||||
CHECK(uarg{LV_PTR()}.can_cast_to<const int* const>());
|
||||
|
||||
CHECK(*uarg{LV_PTR()}.cast<int*>() == 42);
|
||||
CHECK(*uarg{LV_PTR()}.cast<int* const>() == 42);
|
||||
CHECK(*uarg{LV_PTR()}.cast<const int*>() == 42);
|
||||
CHECK(*uarg{LV_PTR()}.cast<const int* const>() == 42);
|
||||
}
|
||||
|
||||
SUBCASE("CLV_PTR") {
|
||||
CHECK(uarg{CLV_PTR()}.can_cast_to<int*>());
|
||||
CHECK(uarg{CLV_PTR()}.can_cast_to<int* const>());
|
||||
CHECK(uarg{CLV_PTR()}.can_cast_to<const int*>());
|
||||
CHECK(uarg{CLV_PTR()}.can_cast_to<const int* const>());
|
||||
|
||||
CHECK(*uarg{CLV_PTR()}.cast<int*>() == 42);
|
||||
CHECK(*uarg{CLV_PTR()}.cast<int* const>() == 42);
|
||||
CHECK(*uarg{CLV_PTR()}.cast<const int*>() == 42);
|
||||
CHECK(*uarg{CLV_PTR()}.cast<const int* const>() == 42);
|
||||
}
|
||||
|
||||
SUBCASE("XV_PTR") {
|
||||
CHECK(uarg{XV_PTR()}.can_cast_to<int*>());
|
||||
CHECK(uarg{XV_PTR()}.can_cast_to<int* const>());
|
||||
CHECK(uarg{XV_PTR()}.can_cast_to<const int*>());
|
||||
CHECK(uarg{XV_PTR()}.can_cast_to<const int* const>());
|
||||
|
||||
CHECK(*uarg{XV_PTR()}.cast<int*>() == 42);
|
||||
CHECK(*uarg{XV_PTR()}.cast<int* const>() == 42);
|
||||
CHECK(*uarg{XV_PTR()}.cast<const int*>() == 42);
|
||||
CHECK(*uarg{XV_PTR()}.cast<const int* const>() == 42);
|
||||
}
|
||||
|
||||
SUBCASE("CXV_PTR") {
|
||||
CHECK(uarg{CXV_PTR()}.can_cast_to<int*>());
|
||||
CHECK(uarg{CXV_PTR()}.can_cast_to<int* const>());
|
||||
CHECK(uarg{CXV_PTR()}.can_cast_to<const int*>());
|
||||
CHECK(uarg{CXV_PTR()}.can_cast_to<const int* const>());
|
||||
|
||||
CHECK(*uarg{CXV_PTR()}.cast<int*>() == 42);
|
||||
CHECK(*uarg{CXV_PTR()}.cast<int* const>() == 42);
|
||||
CHECK(*uarg{CXV_PTR()}.cast<const int*>() == 42);
|
||||
CHECK(*uarg{CXV_PTR()}.cast<const int* const>() == 42);
|
||||
}
|
||||
|
||||
SUBCASE("PRV_PTR") {
|
||||
CHECK(uarg{PRV_PTR()}.can_cast_to<int*>());
|
||||
CHECK(uarg{PRV_PTR()}.can_cast_to<int* const>());
|
||||
CHECK(uarg{PRV_PTR()}.can_cast_to<const int*>());
|
||||
CHECK(uarg{PRV_PTR()}.can_cast_to<const int* const>());
|
||||
|
||||
CHECK(*uarg{PRV_PTR()}.cast<int*>() == 42);
|
||||
CHECK(*uarg{PRV_PTR()}.cast<int* const>() == 42);
|
||||
CHECK(*uarg{PRV_PTR()}.cast<const int*>() == 42);
|
||||
CHECK(*uarg{PRV_PTR()}.cast<const int* const>() == 42);
|
||||
}
|
||||
|
||||
SUBCASE("LV_CPTR") {
|
||||
CHECK_FALSE(uarg{LV_CPTR()}.can_cast_to<int*>());
|
||||
CHECK_FALSE(uarg{LV_CPTR()}.can_cast_to<int* const>());
|
||||
CHECK(uarg{LV_CPTR()}.can_cast_to<const int*>());
|
||||
CHECK(uarg{LV_CPTR()}.can_cast_to<const int* const>());
|
||||
|
||||
CHECK_THROWS(std::ignore = uarg{LV_CPTR()}.cast<int*>());
|
||||
CHECK_THROWS(std::ignore = uarg{LV_CPTR()}.cast<int* const>());
|
||||
CHECK(*uarg{LV_CPTR()}.cast<const int*>() == 42);
|
||||
CHECK(*uarg{LV_CPTR()}.cast<const int* const>() == 42);
|
||||
}
|
||||
|
||||
SUBCASE("CLV_CPTR") {
|
||||
CHECK_FALSE(uarg{CLV_CPTR()}.can_cast_to<int*>());
|
||||
CHECK_FALSE(uarg{CLV_CPTR()}.can_cast_to<int* const>());
|
||||
CHECK(uarg{CLV_CPTR()}.can_cast_to<const int*>());
|
||||
CHECK(uarg{CLV_CPTR()}.can_cast_to<const int* const>());
|
||||
|
||||
CHECK_THROWS(std::ignore = uarg{CLV_CPTR()}.cast<int*>());
|
||||
CHECK_THROWS(std::ignore = uarg{CLV_CPTR()}.cast<int* const>());
|
||||
CHECK(*uarg{CLV_CPTR()}.cast<const int*>() == 42);
|
||||
CHECK(*uarg{CLV_CPTR()}.cast<const int* const>() == 42);
|
||||
}
|
||||
|
||||
SUBCASE("XV_CPTR") {
|
||||
CHECK_FALSE(uarg{XV_CPTR()}.can_cast_to<int*>());
|
||||
CHECK_FALSE(uarg{XV_CPTR()}.can_cast_to<int* const>());
|
||||
CHECK(uarg{XV_CPTR()}.can_cast_to<const int*>());
|
||||
CHECK(uarg{XV_CPTR()}.can_cast_to<const int* const>());
|
||||
|
||||
CHECK_THROWS(std::ignore = uarg{XV_CPTR()}.cast<int*>());
|
||||
CHECK_THROWS(std::ignore = uarg{XV_CPTR()}.cast<int* const>());
|
||||
CHECK(*uarg{XV_CPTR()}.cast<const int*>() == 42);
|
||||
CHECK(*uarg{XV_CPTR()}.cast<const int* const>() == 42);
|
||||
}
|
||||
|
||||
SUBCASE("CXV_CPTR") {
|
||||
CHECK_FALSE(uarg{CXV_CPTR()}.can_cast_to<int*>());
|
||||
CHECK_FALSE(uarg{CXV_CPTR()}.can_cast_to<int* const>());
|
||||
CHECK(uarg{CXV_CPTR()}.can_cast_to<const int*>());
|
||||
CHECK(uarg{CXV_CPTR()}.can_cast_to<const int* const>());
|
||||
|
||||
CHECK_THROWS(std::ignore = uarg{CXV_CPTR()}.cast<int*>());
|
||||
CHECK_THROWS(std::ignore = uarg{CXV_CPTR()}.cast<int* const>());
|
||||
CHECK(*uarg{CXV_CPTR()}.cast<const int*>() == 42);
|
||||
CHECK(*uarg{CXV_CPTR()}.cast<const int* const>() == 42);
|
||||
}
|
||||
|
||||
SUBCASE("PRV_CPTR") {
|
||||
CHECK_FALSE(uarg{PRV_CPTR()}.can_cast_to<int*>());
|
||||
CHECK_FALSE(uarg{PRV_CPTR()}.can_cast_to<int* const>());
|
||||
CHECK(uarg{PRV_CPTR()}.can_cast_to<const int*>());
|
||||
CHECK(uarg{PRV_CPTR()}.can_cast_to<const int* const>());
|
||||
|
||||
CHECK_THROWS(std::ignore = uarg{PRV_CPTR()}.cast<int*>());
|
||||
CHECK_THROWS(std::ignore = uarg{PRV_CPTR()}.cast<int* const>());
|
||||
CHECK(*uarg{PRV_CPTR()}.cast<const int*>() == 42);
|
||||
CHECK(*uarg{PRV_CPTR()}.cast<const int* const>() == 42);
|
||||
}
|
||||
}
|
||||
254
develop/untests/meta_utilities/arg5_tests.cpp
Normal file
254
develop/untests/meta_utilities/arg5_tests.cpp
Normal file
@@ -0,0 +1,254 @@
|
||||
/*******************************************************************************
|
||||
* 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 "../meta_untests.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;
|
||||
};
|
||||
|
||||
struct B : virtual A {
|
||||
int bi = 2;
|
||||
};
|
||||
|
||||
struct C : virtual A {
|
||||
int ci = 3;
|
||||
};
|
||||
|
||||
struct D : B, C {
|
||||
int di = 4;
|
||||
};
|
||||
}
|
||||
|
||||
TEST_CASE("meta/meta_utilities/arg5") {
|
||||
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("meta/meta_utilities/arg5/cast") {
|
||||
namespace meta = meta_hpp;
|
||||
using meta::detail::uarg;
|
||||
|
||||
SUBCASE("int[2]") {
|
||||
int arr[2]{1,2};
|
||||
CHECK(uarg(arr).get_raw_type() == meta::resolve_type(arr));
|
||||
|
||||
static_assert(std::is_invocable_v<void(int*), int (&) [2]>);
|
||||
static_assert(std::is_invocable_v<void(const int*), int (&) [2]>);
|
||||
static_assert(std::is_invocable_v<void(int* const), int (&) [2]>);
|
||||
static_assert(std::is_invocable_v<void(const int* const), int (&) [2]>);
|
||||
|
||||
CHECK(uarg(arr).can_cast_to<int*>());
|
||||
CHECK(uarg(arr).can_cast_to<const int*>());
|
||||
CHECK(uarg(arr).can_cast_to<int* const>());
|
||||
CHECK(uarg(arr).can_cast_to<const int* const>());
|
||||
|
||||
CHECK(uarg(arr).cast<int*>() == static_cast<int*>(arr));
|
||||
CHECK(uarg(arr).cast<const int*>() == static_cast<const int*>(arr));
|
||||
CHECK(uarg(arr).cast<int* const>() == static_cast<int*>(arr));
|
||||
CHECK(uarg(arr).cast<const int* const>() == static_cast<const int*>(arr));
|
||||
}
|
||||
|
||||
SUBCASE("const int[2]") {
|
||||
const int arr[2]{1,2};
|
||||
CHECK(uarg(arr).get_raw_type() == meta::resolve_type(arr));
|
||||
|
||||
static_assert(!std::is_invocable_v<void(int*), const int (&) [2]>);
|
||||
static_assert(std::is_invocable_v<void(const int*), const int (&) [2]>);
|
||||
static_assert(!std::is_invocable_v<void(int* const), const int (&) [2]>);
|
||||
static_assert(std::is_invocable_v<void(const int* const), const int (&) [2]>);
|
||||
|
||||
CHECK_FALSE(uarg(arr).can_cast_to<int*>());
|
||||
CHECK(uarg(arr).can_cast_to<const int*>());
|
||||
CHECK_FALSE(uarg(arr).can_cast_to<int* const>());
|
||||
CHECK(uarg(arr).can_cast_to<const int* const>());
|
||||
|
||||
CHECK_THROWS(std::ignore = uarg(arr).cast<int*>());
|
||||
CHECK(uarg(arr).cast<const int*>() == static_cast<const int*>(arr));
|
||||
CHECK_THROWS(std::ignore = uarg(arr).cast<int* const>());
|
||||
CHECK(uarg(arr).cast<const int* const>() == static_cast<const int*>(arr));
|
||||
}
|
||||
|
||||
SUBCASE("D[2]") {
|
||||
D arr[2];
|
||||
CHECK(uarg(arr).get_raw_type() == meta::resolve_type(arr));
|
||||
|
||||
static_assert(std::is_invocable_v<void(A*), D (&) [2]>);
|
||||
static_assert(std::is_invocable_v<void(const A*), D (&) [2]>);
|
||||
static_assert(std::is_invocable_v<void(A* const), D (&) [2]>);
|
||||
static_assert(std::is_invocable_v<void(const A* const), D (&) [2]>);
|
||||
|
||||
CHECK(uarg(arr).can_cast_to<A*>());
|
||||
CHECK(uarg(arr).can_cast_to<const A*>());
|
||||
CHECK(uarg(arr).can_cast_to<A* const>());
|
||||
CHECK(uarg(arr).can_cast_to<const A* const>());
|
||||
|
||||
CHECK(uarg(arr).cast<A*>() == static_cast<A*>(arr));
|
||||
CHECK(uarg(arr).cast<const A*>() == static_cast<const A*>(arr));
|
||||
CHECK(uarg(arr).cast<A* const>() == static_cast<A*>(arr));
|
||||
CHECK(uarg(arr).cast<const A* const>() == static_cast<const A*>(arr));
|
||||
}
|
||||
|
||||
SUBCASE("const D[2]") {
|
||||
const D arr[2];
|
||||
CHECK(uarg(arr).get_raw_type() == meta::resolve_type(arr));
|
||||
|
||||
static_assert(!std::is_invocable_v<void(A*), const D (&) [2]>);
|
||||
static_assert(std::is_invocable_v<void(const A*), const D (&) [2]>);
|
||||
static_assert(!std::is_invocable_v<void(A* const), const D (&) [2]>);
|
||||
static_assert(std::is_invocable_v<void(const A* const), const D (&) [2]>);
|
||||
|
||||
CHECK_FALSE(uarg(arr).can_cast_to<A*>());
|
||||
CHECK(uarg(arr).can_cast_to<const A*>());
|
||||
CHECK_FALSE(uarg(arr).can_cast_to<A* const>());
|
||||
CHECK(uarg(arr).can_cast_to<const A* const>());
|
||||
|
||||
CHECK_THROWS(std::ignore = uarg(arr).cast<A*>());
|
||||
CHECK(uarg(arr).cast<const A*>() == static_cast<const A*>(arr));
|
||||
CHECK_THROWS(std::ignore = uarg(arr).cast<A* const>());
|
||||
CHECK(uarg(arr).cast<const A* const>() == static_cast<const A*>(arr));
|
||||
}
|
||||
|
||||
SUBCASE("&") {
|
||||
using T = D[2];
|
||||
static T src{};
|
||||
|
||||
{
|
||||
auto LV = []() -> T& { return src; };
|
||||
CHECK(uarg{LV()}.get_raw_type() == meta::resolve_type<D[2]>());
|
||||
|
||||
static_assert(std::is_invocable_v<void(A*), decltype(LV())>);
|
||||
static_assert(std::is_invocable_v<void(const A*), decltype(LV())>);
|
||||
static_assert(std::is_invocable_v<void(A* const), decltype(LV())>);
|
||||
static_assert(std::is_invocable_v<void(const A* const), decltype(LV())>);
|
||||
|
||||
CHECK_NOTHROW([](A*){}(LV()));
|
||||
CHECK_NOTHROW([](const A*){}(LV()));
|
||||
CHECK_NOTHROW([](A* const){}(LV()));
|
||||
CHECK_NOTHROW([](const A* const){}(LV()));
|
||||
|
||||
CHECK(uarg(LV()).cast<A*>() == static_cast<A*>(src));
|
||||
CHECK(uarg(LV()).cast<const A*>() == static_cast<const A*>(src));
|
||||
CHECK(uarg(LV()).cast<A* const>() == static_cast<A*>(src));
|
||||
CHECK(uarg(LV()).cast<const A* const>() == static_cast<const A*>(src));
|
||||
}
|
||||
|
||||
{
|
||||
auto CLV = []() -> const T& { return src; };
|
||||
CHECK(uarg{CLV()}.get_raw_type() == meta::resolve_type<D[2]>());
|
||||
|
||||
static_assert(!std::is_invocable_v<void(A*), decltype(CLV())>);
|
||||
static_assert(std::is_invocable_v<void(const A*), decltype(CLV())>);
|
||||
static_assert(!std::is_invocable_v<void(A* const), decltype(CLV())>);
|
||||
static_assert(std::is_invocable_v<void(const A* const), decltype(CLV())>);
|
||||
|
||||
CHECK_THROWS(std::ignore = uarg(CLV()).cast<A*>());
|
||||
CHECK(uarg(CLV()).cast<const A*>() == static_cast<const A*>(src));
|
||||
CHECK_THROWS(std::ignore = uarg(CLV()).cast<A* const>());
|
||||
CHECK(uarg(CLV()).cast<const A* const>() == static_cast<const A*>(src));
|
||||
}
|
||||
|
||||
{
|
||||
auto XV = []() -> T&& { return std::move(src); };
|
||||
CHECK(uarg{XV()}.get_raw_type() == meta::resolve_type<D[2]>());
|
||||
|
||||
static_assert(std::is_invocable_v<void(A*), decltype(XV())>);
|
||||
static_assert(std::is_invocable_v<void(const A*), decltype(XV())>);
|
||||
static_assert(std::is_invocable_v<void(A* const), decltype(XV())>);
|
||||
static_assert(std::is_invocable_v<void(const A* const), decltype(XV())>);
|
||||
|
||||
CHECK(uarg(XV()).cast<A*>() == static_cast<A*>(src));
|
||||
CHECK(uarg(XV()).cast<const A*>() == static_cast<const A*>(src));
|
||||
CHECK(uarg(XV()).cast<A* const>() == static_cast<A*>(src));
|
||||
CHECK(uarg(XV()).cast<const A* const>() == static_cast<const A*>(src));
|
||||
}
|
||||
|
||||
{
|
||||
auto CXV = []() -> const T&& { return std::move(src); };
|
||||
CHECK(uarg{CXV()}.get_raw_type() == meta::resolve_type<D[2]>());
|
||||
|
||||
static_assert(!std::is_invocable_v<void(A*), decltype(CXV())>);
|
||||
static_assert(std::is_invocable_v<void(const A*), decltype(CXV())>);
|
||||
static_assert(!std::is_invocable_v<void(A* const), decltype(CXV())>);
|
||||
static_assert(std::is_invocable_v<void(const A* const), decltype(CXV())>);
|
||||
|
||||
CHECK_THROWS(std::ignore = uarg(CXV()).cast<A*>());
|
||||
CHECK(uarg(CXV()).cast<const A*>() == static_cast<const A*>(src));
|
||||
CHECK_THROWS(std::ignore = uarg(CXV()).cast<A* const>());
|
||||
CHECK(uarg(CXV()).cast<const A* const>() == static_cast<const A*>(src));
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("*") {
|
||||
{
|
||||
static D arr[2]{};
|
||||
|
||||
static_assert(std::is_invocable_v<void(D (&) [2]), D (&) [2]>);
|
||||
static_assert(std::is_invocable_v<void(const D (&) [2]), D (&) [2]>);
|
||||
static_assert(std::is_invocable_v<void(D (*) [2]), D (*) [2]>);
|
||||
static_assert(std::is_invocable_v<void(const D (*) [2]), D (*) [2]>);
|
||||
static_assert(std::is_invocable_v<void(D (* const) [2]), D (*) [2]>);
|
||||
static_assert(std::is_invocable_v<void(const D (* const) [2]), D (*) [2]>);
|
||||
|
||||
CHECK(uarg{arr}.can_cast_to<D (&) [2]>());
|
||||
CHECK(uarg{arr}.can_cast_to<const D (&) [2]>());
|
||||
CHECK(uarg{&arr}.can_cast_to<D (*) [2]>());
|
||||
CHECK(uarg{&arr}.can_cast_to<const D (*) [2]>());
|
||||
CHECK(uarg{&arr}.can_cast_to<D (* const) [2]>());
|
||||
CHECK(uarg{&arr}.can_cast_to<const D (* const) [2]>());
|
||||
|
||||
CHECK(&uarg{arr}.cast<D (&) [2]>() == &arr);
|
||||
CHECK(&uarg{arr}.cast<const D (&) [2]>() == &arr);
|
||||
CHECK(uarg{&arr}.cast<D (*) [2]>() == &arr);
|
||||
CHECK(uarg{&arr}.cast<const D (*) [2]>() == &arr);
|
||||
CHECK(uarg{&arr}.cast<D (* const) [2]>() == &arr);
|
||||
CHECK(uarg{&arr}.cast<const D (* const) [2]>() == &arr);
|
||||
}
|
||||
|
||||
{
|
||||
static const D arr[2]{};
|
||||
|
||||
static_assert(!std::is_invocable_v<void(D (&) [2]), const D (&) [2]>);
|
||||
static_assert(std::is_invocable_v<void(const D (&) [2]), const D (&) [2]>);
|
||||
static_assert(!std::is_invocable_v<void(D (*) [2]), const D (*) [2]>);
|
||||
static_assert(std::is_invocable_v<void(const D (*) [2]), const D (*) [2]>);
|
||||
static_assert(!std::is_invocable_v<void(D (* const) [2]), const D (*) [2]>);
|
||||
static_assert(std::is_invocable_v<void(const D (* const) [2]), const D (*) [2]>);
|
||||
|
||||
CHECK_FALSE(uarg{arr}.can_cast_to<D (&) [2]>());
|
||||
CHECK(uarg{arr}.can_cast_to<const D (&) [2]>());
|
||||
CHECK_FALSE(uarg{&arr}.can_cast_to<D (*) [2]>());
|
||||
CHECK(uarg{&arr}.can_cast_to<const D (*) [2]>());
|
||||
CHECK_FALSE(uarg{&arr}.can_cast_to<D (* const) [2]>());
|
||||
CHECK(uarg{&arr}.can_cast_to<const D (* const) [2]>());
|
||||
|
||||
CHECK_THROWS(std::ignore = &uarg{arr}.cast<D (&) [2]>());
|
||||
CHECK(&uarg{arr}.cast<const D (&) [2]>() == &arr);
|
||||
CHECK_THROWS(std::ignore = uarg{&arr}.cast<D (*) [2]>());
|
||||
CHECK(uarg{&arr}.cast<const D (*) [2]>() == &arr);
|
||||
CHECK_THROWS(std::ignore = uarg{&arr}.cast<D (* const) [2]>());
|
||||
CHECK(uarg{&arr}.cast<const D (* const) [2]>() == &arr);
|
||||
}
|
||||
}
|
||||
}
|
||||
70
develop/untests/meta_utilities/arg6_tests.cpp
Normal file
70
develop/untests/meta_utilities/arg6_tests.cpp
Normal file
@@ -0,0 +1,70 @@
|
||||
/*******************************************************************************
|
||||
* 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 "../meta_untests.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
struct base {
|
||||
base() = default;
|
||||
base(const base&) = default;
|
||||
virtual ~base() = default;
|
||||
virtual int int_method() const = 0;
|
||||
};
|
||||
|
||||
struct clazz : base {
|
||||
int int_member{42};
|
||||
int int_method() const override { return int_member; }
|
||||
};
|
||||
|
||||
using int_member_t = int clazz::*;
|
||||
using int_method_t = int (clazz::*)() const;
|
||||
|
||||
int func_with_member(const clazz& cl, int_member_t m) {
|
||||
return cl.*m;
|
||||
}
|
||||
|
||||
int func_with_method(const clazz& cl, int_method_t m) {
|
||||
return (cl.*m)();
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("meta/meta_utilities/arg6") {
|
||||
namespace meta = meta_hpp;
|
||||
using meta::detail::uarg;
|
||||
|
||||
const meta::scope scope = meta::local_scope_("scope")
|
||||
.function_("func_with_member", &func_with_member)
|
||||
.function_("func_with_method", &func_with_method);
|
||||
|
||||
SUBCASE("int_member") {
|
||||
const meta::function f = scope.get_function("func_with_member");
|
||||
REQUIRE(f);
|
||||
|
||||
clazz cl;
|
||||
CHECK(f.is_invocable_with<clazz&, int_member_t>());
|
||||
|
||||
CHECK(f.is_invocable_with(cl, &clazz::int_member));
|
||||
CHECK(f.invoke(cl, &clazz::int_member) == 42);
|
||||
|
||||
CHECK(f.is_invocable_with(meta::uvalue{cl}, meta::uvalue{&clazz::int_member}));
|
||||
CHECK(f.invoke(meta::uvalue{cl}, meta::uvalue{&clazz::int_member}) == 42);
|
||||
}
|
||||
|
||||
SUBCASE("int_method") {
|
||||
const meta::function f = scope.get_function("func_with_method");
|
||||
REQUIRE(f);
|
||||
|
||||
clazz cl;
|
||||
CHECK(f.is_invocable_with<clazz&, int_method_t>());
|
||||
|
||||
CHECK(f.is_invocable_with(cl, &clazz::int_method));
|
||||
CHECK(f.invoke(cl, &clazz::int_method) == 42);
|
||||
|
||||
CHECK(f.is_invocable_with(meta::uvalue{cl}, meta::uvalue{&clazz::int_method}));
|
||||
CHECK(f.invoke(meta::uvalue{cl}, meta::uvalue{&clazz::int_method}) == 42);
|
||||
}
|
||||
}
|
||||
196
develop/untests/meta_utilities/arg7_tests.cpp
Normal file
196
develop/untests/meta_utilities/arg7_tests.cpp
Normal file
@@ -0,0 +1,196 @@
|
||||
/*******************************************************************************
|
||||
* 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 "../meta_untests.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;
|
||||
};
|
||||
|
||||
struct B : virtual A {
|
||||
int bi = 2;
|
||||
};
|
||||
|
||||
struct C : virtual A {
|
||||
int ci = 3;
|
||||
};
|
||||
|
||||
struct D : B, C {
|
||||
int di = 4;
|
||||
};
|
||||
}
|
||||
|
||||
TEST_CASE("meta/meta_utilities/arg7") {
|
||||
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("meta/meta_utilities/arg7/cast/to_void") {
|
||||
namespace meta = meta_hpp;
|
||||
using meta::detail::uarg;
|
||||
|
||||
SUBCASE("int* -> void*") {
|
||||
int i{42};
|
||||
|
||||
static_assert(std::is_invocable_v<void(void*), int*>);
|
||||
static_assert(std::is_invocable_v<void(const void*), int*>);
|
||||
|
||||
CHECK(uarg{&i}.can_cast_to<void*>());
|
||||
CHECK(uarg{&i}.can_cast_to<const void*>());
|
||||
|
||||
CHECK(uarg{&i}.cast<void*>() == &i);
|
||||
CHECK(uarg{&i}.cast<const void*>() == &i);
|
||||
}
|
||||
|
||||
SUBCASE("const int* -> void*") {
|
||||
const int i{42};
|
||||
|
||||
static_assert(!std::is_invocable_v<void(void*), const int*>);
|
||||
static_assert(std::is_invocable_v<void(const void*), const int*>);
|
||||
|
||||
CHECK_FALSE(uarg{&i}.can_cast_to<void*>());
|
||||
CHECK(uarg{&i}.can_cast_to<const void*>());
|
||||
|
||||
CHECK_THROWS(std::ignore = uarg{&i}.cast<void*>());
|
||||
CHECK(uarg{&i}.cast<const void*>() == &i);
|
||||
}
|
||||
|
||||
SUBCASE("D* -> void*") {
|
||||
D d;
|
||||
|
||||
static_assert(std::is_invocable_v<void(void*), D*>);
|
||||
static_assert(std::is_invocable_v<void(const void*), D*>);
|
||||
|
||||
CHECK(uarg{&d}.can_cast_to<void*>());
|
||||
CHECK(uarg{&d}.can_cast_to<const void*>());
|
||||
|
||||
CHECK(uarg{&d}.cast<void*>() == &d);
|
||||
CHECK(uarg{&d}.cast<const void*>() == &d);
|
||||
}
|
||||
|
||||
SUBCASE("const D* -> void*") {
|
||||
const D d;
|
||||
|
||||
static_assert(!std::is_invocable_v<void(void*), const D*>);
|
||||
static_assert(std::is_invocable_v<void(const void*), const D*>);
|
||||
|
||||
CHECK_FALSE(uarg{&d}.can_cast_to<void*>());
|
||||
CHECK(uarg{&d}.can_cast_to<const void*>());
|
||||
|
||||
CHECK_THROWS(std::ignore = uarg{&d}.cast<void*>());
|
||||
CHECK(uarg{&d}.cast<const void*>() == &d);
|
||||
}
|
||||
|
||||
SUBCASE("D[2] -> void*") {
|
||||
D arr[2];
|
||||
|
||||
static_assert(std::is_invocable_v<void(void*), D (&) [2]>);
|
||||
static_assert(std::is_invocable_v<void(const void*), D (&) [2]>);
|
||||
|
||||
CHECK(uarg{arr}.can_cast_to<void*>());
|
||||
CHECK(uarg{arr}.can_cast_to<const void*>());
|
||||
|
||||
CHECK(uarg{arr}.cast<void*>() == &arr);
|
||||
CHECK(uarg{arr}.cast<const void*>() == &arr);
|
||||
}
|
||||
|
||||
SUBCASE("const D[2] -> void*") {
|
||||
const D arr[2];
|
||||
|
||||
static_assert(!std::is_invocable_v<void(void*), const D (&) [2]>);
|
||||
static_assert(std::is_invocable_v<void(const void*), const D (&) [2]>);
|
||||
|
||||
CHECK_FALSE(uarg{arr}.can_cast_to<void*>());
|
||||
CHECK(uarg{arr}.can_cast_to<const void*>());
|
||||
|
||||
CHECK_THROWS(std::ignore = uarg{arr}.cast<void*>());
|
||||
CHECK(uarg{arr}.cast<const void*>() == &arr);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("meta/meta_utilities/arg7/cast/from_nullptr") {
|
||||
namespace meta = meta_hpp;
|
||||
using meta::detail::uarg;
|
||||
|
||||
SUBCASE("nullptr -> *") {
|
||||
static_assert(std::is_invocable_v<void(int*), std::nullptr_t>);
|
||||
static_assert(std::is_invocable_v<void(int*), std::nullptr_t&>);
|
||||
static_assert(std::is_invocable_v<void(int*), std::nullptr_t&&>);
|
||||
static_assert(std::is_invocable_v<void(int*), const std::nullptr_t>);
|
||||
static_assert(std::is_invocable_v<void(int*), const std::nullptr_t&>);
|
||||
static_assert(std::is_invocable_v<void(int*), const std::nullptr_t&&>);
|
||||
|
||||
static_assert(std::is_invocable_v<void(const D*), std::nullptr_t>);
|
||||
static_assert(std::is_invocable_v<void(const D*), std::nullptr_t&>);
|
||||
static_assert(std::is_invocable_v<void(const D*), std::nullptr_t&&>);
|
||||
static_assert(std::is_invocable_v<void(const D*), const std::nullptr_t>);
|
||||
static_assert(std::is_invocable_v<void(const D*), const std::nullptr_t&>);
|
||||
static_assert(std::is_invocable_v<void(const D*), const std::nullptr_t&&>);
|
||||
|
||||
std::nullptr_t n1{nullptr};
|
||||
const std::nullptr_t n2{nullptr};
|
||||
|
||||
CHECK(uarg{n1}.can_cast_to<int*>());
|
||||
CHECK(uarg{std::move(n1)}.can_cast_to<int*>());
|
||||
CHECK(uarg{n2}.can_cast_to<int*>());
|
||||
CHECK(uarg{std::move(n2)}.can_cast_to<int*>());
|
||||
|
||||
CHECK(uarg{n1}.can_cast_to<const int*>());
|
||||
CHECK(uarg{std::move(n1)}.can_cast_to<const int*>());
|
||||
CHECK(uarg{n2}.can_cast_to<const int*>());
|
||||
CHECK(uarg{std::move(n2)}.can_cast_to<const int*>());
|
||||
|
||||
CHECK(uarg{n1}.can_cast_to<D*>());
|
||||
CHECK(uarg{std::move(n1)}.can_cast_to<D*>());
|
||||
CHECK(uarg{n2}.can_cast_to<D*>());
|
||||
CHECK(uarg{std::move(n2)}.can_cast_to<D*>());
|
||||
|
||||
CHECK(uarg{n1}.can_cast_to<const D*>());
|
||||
CHECK(uarg{std::move(n1)}.can_cast_to<const D*>());
|
||||
CHECK(uarg{n2}.can_cast_to<const D*>());
|
||||
CHECK(uarg{std::move(n2)}.can_cast_to<const D*>());
|
||||
|
||||
//
|
||||
|
||||
CHECK(uarg{n1}.cast<int*>() == nullptr);
|
||||
CHECK(uarg{std::move(n1)}.cast<int*>() == nullptr);
|
||||
CHECK(uarg{n2}.cast<int*>() == nullptr);
|
||||
CHECK(uarg{std::move(n2)}.cast<int*>() == nullptr);
|
||||
|
||||
CHECK(uarg{n1}.cast<const int*>() == nullptr);
|
||||
CHECK(uarg{std::move(n1)}.cast<const int*>() == nullptr);
|
||||
CHECK(uarg{n2}.cast<const int*>() == nullptr);
|
||||
CHECK(uarg{std::move(n2)}.cast<const int*>() == nullptr);
|
||||
|
||||
CHECK(uarg{n1}.cast<D*>() == nullptr);
|
||||
CHECK(uarg{std::move(n1)}.cast<D*>() == nullptr);
|
||||
CHECK(uarg{n2}.cast<D*>() == nullptr);
|
||||
CHECK(uarg{std::move(n2)}.cast<D*>() == nullptr);
|
||||
|
||||
CHECK(uarg{n1}.cast<const D*>() == nullptr);
|
||||
CHECK(uarg{std::move(n1)}.cast<const D*>() == nullptr);
|
||||
CHECK(uarg{n2}.cast<const D*>() == nullptr);
|
||||
CHECK(uarg{std::move(n2)}.cast<const D*>() == nullptr);
|
||||
}
|
||||
}
|
||||
1476
develop/untests/meta_utilities/arg_tests.cpp
Normal file
1476
develop/untests/meta_utilities/arg_tests.cpp
Normal file
File diff suppressed because it is too large
Load Diff
84
develop/untests/meta_utilities/detail_tests.cpp
Normal file
84
develop/untests/meta_utilities/detail_tests.cpp
Normal file
@@ -0,0 +1,84 @@
|
||||
/*******************************************************************************
|
||||
* 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 "../meta_untests.hpp"
|
||||
|
||||
TEST_CASE("meta/meta_utilities/detail") {
|
||||
namespace meta = meta_hpp;
|
||||
|
||||
SUBCASE("cvref_traits") {
|
||||
static_assert(!meta::detail::cvref_traits<int>::is_lvalue);
|
||||
static_assert(!meta::detail::cvref_traits<int>::is_rvalue);
|
||||
static_assert(!meta::detail::cvref_traits<int>::is_const);
|
||||
static_assert(!meta::detail::cvref_traits<int>::is_volatile);
|
||||
|
||||
static_assert(!meta::detail::cvref_traits<const int>::is_lvalue);
|
||||
static_assert(!meta::detail::cvref_traits<const int>::is_rvalue);
|
||||
static_assert(meta::detail::cvref_traits<const int>::is_const);
|
||||
static_assert(!meta::detail::cvref_traits<const int>::is_volatile);
|
||||
|
||||
static_assert(!meta::detail::cvref_traits<const volatile int>::is_lvalue);
|
||||
static_assert(!meta::detail::cvref_traits<const volatile int>::is_rvalue);
|
||||
static_assert(meta::detail::cvref_traits<const volatile int>::is_const);
|
||||
static_assert(meta::detail::cvref_traits<const volatile int>::is_volatile);
|
||||
|
||||
static_assert(meta::detail::cvref_traits<int&>::is_lvalue);
|
||||
static_assert(!meta::detail::cvref_traits<int&>::is_rvalue);
|
||||
static_assert(!meta::detail::cvref_traits<int&>::is_const);
|
||||
static_assert(!meta::detail::cvref_traits<int&>::is_volatile);
|
||||
|
||||
static_assert(meta::detail::cvref_traits<const int&>::is_lvalue);
|
||||
static_assert(!meta::detail::cvref_traits<const int&>::is_rvalue);
|
||||
static_assert(meta::detail::cvref_traits<const int&>::is_const);
|
||||
static_assert(!meta::detail::cvref_traits<const int&>::is_volatile);
|
||||
|
||||
static_assert(meta::detail::cvref_traits<const volatile int&>::is_lvalue);
|
||||
static_assert(!meta::detail::cvref_traits<const volatile int&>::is_rvalue);
|
||||
static_assert(meta::detail::cvref_traits<const volatile int&>::is_const);
|
||||
static_assert(meta::detail::cvref_traits<const volatile int&>::is_volatile);
|
||||
|
||||
static_assert(!meta::detail::cvref_traits<int&&>::is_lvalue);
|
||||
static_assert(meta::detail::cvref_traits<int&&>::is_rvalue);
|
||||
static_assert(!meta::detail::cvref_traits<int&&>::is_const);
|
||||
static_assert(!meta::detail::cvref_traits<int&&>::is_volatile);
|
||||
|
||||
static_assert(!meta::detail::cvref_traits<const int&&>::is_lvalue);
|
||||
static_assert(meta::detail::cvref_traits<const int&&>::is_rvalue);
|
||||
static_assert(meta::detail::cvref_traits<const int&&>::is_const);
|
||||
static_assert(!meta::detail::cvref_traits<const int&&>::is_volatile);
|
||||
|
||||
static_assert(!meta::detail::cvref_traits<const volatile int&&>::is_lvalue);
|
||||
static_assert(meta::detail::cvref_traits<const volatile int&&>::is_rvalue);
|
||||
static_assert(meta::detail::cvref_traits<const volatile int&&>::is_const);
|
||||
static_assert(meta::detail::cvref_traits<const volatile int&&>::is_volatile);
|
||||
}
|
||||
|
||||
SUBCASE("cvref_traits::copy_to") {
|
||||
static_assert(std::is_same_v<meta::detail::cvref_traits<float>::copy_to<int>, int>);
|
||||
static_assert(std::is_same_v<meta::detail::cvref_traits<const float>::copy_to<int>, const int>);
|
||||
static_assert(std::is_same_v<meta::detail::cvref_traits<const volatile float>::copy_to<int>, const volatile int>);
|
||||
static_assert(std::is_same_v<meta::detail::cvref_traits<float&>::copy_to<int>, int&>);
|
||||
static_assert(std::is_same_v<meta::detail::cvref_traits<const float&>::copy_to<int>, const int&>);
|
||||
static_assert(std::is_same_v<meta::detail::cvref_traits<volatile float&>::copy_to<int>, volatile int&>);
|
||||
static_assert(std::is_same_v<meta::detail::cvref_traits<const volatile float&&>::copy_to<int>, const volatile int&&>);
|
||||
|
||||
static_assert(std::is_same_v<meta::detail::cvref_traits<float>::copy_to<int&>, int>);
|
||||
static_assert(std::is_same_v<meta::detail::cvref_traits<const float>::copy_to<int&>, const int>);
|
||||
static_assert(std::is_same_v<meta::detail::cvref_traits<const volatile float>::copy_to<int&>, const volatile int>);
|
||||
static_assert(std::is_same_v<meta::detail::cvref_traits<float&>::copy_to<int&>, int&>);
|
||||
static_assert(std::is_same_v<meta::detail::cvref_traits<const float&>::copy_to<int&>, const int&>);
|
||||
static_assert(std::is_same_v<meta::detail::cvref_traits<volatile float&>::copy_to<int&>, volatile int&>);
|
||||
static_assert(std::is_same_v<meta::detail::cvref_traits<const volatile float&&>::copy_to<int&>, const volatile int&&>);
|
||||
|
||||
static_assert(std::is_same_v<meta::detail::cvref_traits<float>::copy_to<const volatile int&&>, int>);
|
||||
static_assert(std::is_same_v<meta::detail::cvref_traits<const float>::copy_to<const volatile int&&>, const int>);
|
||||
static_assert(std::is_same_v<meta::detail::cvref_traits<const volatile float>::copy_to<const volatile int&&>, const volatile int>);
|
||||
static_assert(std::is_same_v<meta::detail::cvref_traits<float&>::copy_to<const volatile int&&>, int&>);
|
||||
static_assert(std::is_same_v<meta::detail::cvref_traits<const float&>::copy_to<const volatile int&&>, const int&>);
|
||||
static_assert(std::is_same_v<meta::detail::cvref_traits<volatile float&>::copy_to<const volatile int&&>, volatile int&>);
|
||||
static_assert(std::is_same_v<meta::detail::cvref_traits<const volatile float&&>::copy_to<const volatile int&&>, const volatile int&&>);
|
||||
}
|
||||
}
|
||||
99
develop/untests/meta_utilities/hash_tests.cpp
Normal file
99
develop/untests/meta_utilities/hash_tests.cpp
Normal file
@@ -0,0 +1,99 @@
|
||||
/*******************************************************************************
|
||||
* 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 "../meta_untests.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
const double pi_v{3.1415926536};
|
||||
|
||||
enum class color : unsigned {
|
||||
red = 0xFF0000,
|
||||
green = 0x00FF00,
|
||||
blue = 0x0000FF,
|
||||
};
|
||||
|
||||
struct ivec2 {
|
||||
int x{};
|
||||
int y{};
|
||||
|
||||
[[maybe_unused]] explicit ivec2(int nv) : x{nv}, y{nv} {}
|
||||
[[maybe_unused]] ivec2(int nx, int ny) : x{nx}, y{ny} {}
|
||||
|
||||
ivec2& add(const ivec2& other) noexcept {
|
||||
x += other.x;
|
||||
y += other.y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
static ivec2 iadd(const ivec2& l, const ivec2& r) noexcept {
|
||||
return {l.x + r.x, l.y + r.y};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
TEST_CASE("meta/meta_utilities/hash") {
|
||||
namespace meta = meta_hpp;
|
||||
|
||||
meta::enum_<color>()
|
||||
.evalue_("red", color::red)
|
||||
.evalue_("green", color::green)
|
||||
.evalue_("blue", color::blue);
|
||||
|
||||
meta::class_<ivec2>()
|
||||
.constructor_<int>()
|
||||
.constructor_<int, int>()
|
||||
.destructor_()
|
||||
.member_("x", &ivec2::x)
|
||||
.member_("y", &ivec2::y)
|
||||
.method_("add", &ivec2::add)
|
||||
.function_("iadd", &ivec2::iadd);
|
||||
|
||||
const meta::class_type ivec2_type = meta::resolve_type<ivec2>();
|
||||
const meta::constructor ivec2_ctor = ivec2_type.get_constructor_with<int>();
|
||||
const meta::destructor ivec2_dtor = ivec2_type.get_destructors().begin()->second;
|
||||
const meta::function ivec2_function = ivec2_type.get_function("iadd");
|
||||
const meta::argument ivec2_function_arg = ivec2_function.get_argument(0);
|
||||
const meta::member ivec2_member = ivec2_type.get_member("x");
|
||||
const meta::method ivec2_method = ivec2_type.get_method("add");
|
||||
|
||||
const meta::enum_type color_type = meta::resolve_type<color>();
|
||||
const meta::evalue red_color = color_type.get_evalue("red");
|
||||
|
||||
const meta::scope local_scope = meta::local_scope_("local-scope")
|
||||
.variable_("pi_v", &pi_v);
|
||||
|
||||
const meta::variable pi_variable = local_scope.get_variable("pi_v");
|
||||
|
||||
SUBCASE("index_family") {
|
||||
std::hash<meta::argument_index>{}(ivec2_function_arg.get_index());
|
||||
std::hash<meta::constructor_index>{}(ivec2_ctor.get_index());
|
||||
std::hash<meta::destructor_index>{}(ivec2_dtor.get_index());
|
||||
std::hash<meta::evalue_index>{}(red_color.get_index());
|
||||
std::hash<meta::function_index>{}(ivec2_function.get_index());
|
||||
std::hash<meta::member_index>{}(ivec2_member.get_index());
|
||||
std::hash<meta::method_index>{}(ivec2_method.get_index());
|
||||
std::hash<meta::scope_index>{}(local_scope.get_index());
|
||||
std::hash<meta::variable_index>{}(pi_variable.get_index());
|
||||
}
|
||||
|
||||
SUBCASE("type_family") {
|
||||
std::hash<meta::any_type>{}(meta::resolve_type<ivec2>());
|
||||
std::hash<meta::array_type>{}(meta::resolve_type<int[]>());
|
||||
std::hash<meta::class_type>{}(meta::resolve_type<ivec2>());
|
||||
std::hash<meta::constructor_type>{}(ivec2_ctor.get_type());
|
||||
std::hash<meta::destructor_type>{}(ivec2_dtor.get_type());
|
||||
std::hash<meta::enum_type>{}(red_color.get_type());
|
||||
std::hash<meta::function_type>{}(ivec2_function.get_type());
|
||||
std::hash<meta::member_type>{}(ivec2_member.get_type());
|
||||
std::hash<meta::method_type>{}(ivec2_method.get_type());
|
||||
std::hash<meta::nullptr_type>{}(meta::resolve_type<std::nullptr_t>());
|
||||
std::hash<meta::number_type>{}(meta::resolve_type<int>());
|
||||
std::hash<meta::pointer_type>{}(meta::resolve_type<int*>());
|
||||
std::hash<meta::reference_type>{}(meta::resolve_type<int&>());
|
||||
std::hash<meta::void_type>{}(meta::resolve_type<void>());
|
||||
}
|
||||
}
|
||||
384
develop/untests/meta_utilities/inst_tests.cpp
Normal file
384
develop/untests/meta_utilities/inst_tests.cpp
Normal file
@@ -0,0 +1,384 @@
|
||||
/*******************************************************************************
|
||||
* 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 "../meta_untests.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
struct fake {
|
||||
int i = 10;
|
||||
};
|
||||
|
||||
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(*-macro-usage)
|
||||
#define META_HPP_CHECK_INVOCABLE(Inst, FName, Qualifiers)\
|
||||
{\
|
||||
using namespace meta::detail;\
|
||||
auto method_ptr = meta::select_overload<int() Qualifiers>(&clazz::FName);\
|
||||
meta::method m_state{method_state::make<meta::method_policy::as_copy_t>("", method_ptr, {})};\
|
||||
\
|
||||
if ( std::is_invocable_v<decltype(method_ptr), decltype(Inst)> ) {\
|
||||
CHECK(uinst{Inst}.can_cast_to<clazz Qualifiers>());\
|
||||
CHECK(uinst_base{type_list<decltype(Inst)>{}}.can_cast_to<clazz Qualifiers>());\
|
||||
CHECK_NOTHROW(std::ignore = uinst{Inst}.cast<clazz Qualifiers>());\
|
||||
\
|
||||
CHECK(m_state.is_invocable_with<decltype(Inst)>());\
|
||||
CHECK(m_state.invoke(Inst) == 1);\
|
||||
} else {\
|
||||
CHECK_FALSE(uinst{Inst}.can_cast_to<clazz Qualifiers>());\
|
||||
CHECK_FALSE(uinst_base{type_list<decltype(Inst)>{}}.can_cast_to<clazz Qualifiers>());\
|
||||
CHECK_THROWS(std::ignore = uinst{Inst}.cast<clazz Qualifiers>());\
|
||||
\
|
||||
CHECK_FALSE(m_state.is_invocable_with<decltype(Inst)>());\
|
||||
CHECK_THROWS(m_state.invoke(Inst));\
|
||||
}\
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE(*-macro-usage)
|
||||
#define META_HPP_CHECK_INVOCABLE_2(FromValue, FName, FromType, ToQualifiers)\
|
||||
{\
|
||||
using namespace meta::detail;\
|
||||
auto method_ptr = meta::select_overload<int() ToQualifiers>(&clazz::FName);\
|
||||
meta::method m_state{method_state::make<meta::method_policy::as_copy_t>("", method_ptr, {})};\
|
||||
\
|
||||
if ( std::is_invocable_v<decltype(method_ptr), FromType> ) {\
|
||||
CHECK(m_state.is_invocable_with<FromType>());\
|
||||
CHECK(m_state.is_invocable_with(FromValue));\
|
||||
CHECK(m_state.invoke(FromValue) == 1);\
|
||||
} else {\
|
||||
CHECK_FALSE(m_state.is_invocable_with<FromType>());\
|
||||
CHECK_FALSE(m_state.is_invocable_with(FromValue));\
|
||||
CHECK_THROWS(m_state.invoke(FromValue));\
|
||||
}\
|
||||
}
|
||||
|
||||
TEST_CASE("meta/meta_utilities/inst2") {
|
||||
namespace meta = meta_hpp;
|
||||
|
||||
meta::class_<fake>();
|
||||
meta::class_<clazz>();
|
||||
meta::class_<dclazz>().base_<fake>().base_<clazz>();
|
||||
}
|
||||
|
||||
TEST_CASE("meta/meta_utilities/inst2/refs") {
|
||||
namespace meta = meta_hpp;
|
||||
|
||||
{
|
||||
// lvalue
|
||||
auto LV = []() -> clazz& { static clazz v; return v; };
|
||||
auto LV2 = []() -> dclazz& { static dclazz v; return v; };
|
||||
|
||||
{
|
||||
meta::detail::uinst i{LV()};
|
||||
CHECK(i.get_raw_type() == meta::resolve_type<clazz>());
|
||||
CHECK(i.get_ref_type() == meta::detail::uinst::ref_types::lvalue);
|
||||
}
|
||||
|
||||
META_HPP_CHECK_INVOCABLE(LV(), m1, )
|
||||
META_HPP_CHECK_INVOCABLE(LV(), m2, &)
|
||||
META_HPP_CHECK_INVOCABLE(LV(), m3, &&)
|
||||
META_HPP_CHECK_INVOCABLE(LV(), m4, const)
|
||||
META_HPP_CHECK_INVOCABLE(LV(), m5, const &)
|
||||
META_HPP_CHECK_INVOCABLE(LV(), m6, const &&)
|
||||
|
||||
META_HPP_CHECK_INVOCABLE(LV2(), m1, )
|
||||
META_HPP_CHECK_INVOCABLE(LV2(), m2, &)
|
||||
META_HPP_CHECK_INVOCABLE(LV2(), m3, &&)
|
||||
META_HPP_CHECK_INVOCABLE(LV2(), m4, const)
|
||||
META_HPP_CHECK_INVOCABLE(LV2(), m5, const &)
|
||||
META_HPP_CHECK_INVOCABLE(LV2(), m6, const &&)
|
||||
}
|
||||
|
||||
{
|
||||
// const lvalue
|
||||
auto CLV = []() -> const clazz& { static clazz v; return v; };
|
||||
auto CLV2 = []() -> const dclazz& { static dclazz v; return v; };
|
||||
|
||||
{
|
||||
meta::detail::uinst i{CLV()};
|
||||
CHECK(i.get_raw_type() == meta::resolve_type<clazz>());
|
||||
CHECK(i.get_ref_type() == meta::detail::uinst::ref_types::const_lvalue);
|
||||
}
|
||||
|
||||
META_HPP_CHECK_INVOCABLE(CLV(), m1, )
|
||||
META_HPP_CHECK_INVOCABLE(CLV(), m2, &)
|
||||
META_HPP_CHECK_INVOCABLE(CLV(), m3, &&)
|
||||
META_HPP_CHECK_INVOCABLE(CLV(), m4, const)
|
||||
META_HPP_CHECK_INVOCABLE(CLV(), m5, const &)
|
||||
META_HPP_CHECK_INVOCABLE(CLV(), m6, const &&)
|
||||
|
||||
META_HPP_CHECK_INVOCABLE(CLV2(), m1, )
|
||||
META_HPP_CHECK_INVOCABLE(CLV2(), m2, &)
|
||||
META_HPP_CHECK_INVOCABLE(CLV2(), m3, &&)
|
||||
META_HPP_CHECK_INVOCABLE(CLV2(), m4, const)
|
||||
META_HPP_CHECK_INVOCABLE(CLV2(), m5, const &)
|
||||
META_HPP_CHECK_INVOCABLE(CLV2(), m6, const &&)
|
||||
}
|
||||
|
||||
{
|
||||
// xvalue
|
||||
auto XV = []() -> clazz&& { static clazz v; return std::move(v); };
|
||||
auto XV2 = []() -> dclazz&& { static dclazz v; return std::move(v); };
|
||||
|
||||
{
|
||||
meta::detail::uinst i{XV()};
|
||||
CHECK(i.get_raw_type() == meta::resolve_type<clazz>());
|
||||
CHECK(i.get_ref_type() == meta::detail::uinst::ref_types::rvalue);
|
||||
}
|
||||
|
||||
META_HPP_CHECK_INVOCABLE(XV(), m1, )
|
||||
META_HPP_CHECK_INVOCABLE(XV(), m2, &)
|
||||
META_HPP_CHECK_INVOCABLE(XV(), m3, &&)
|
||||
META_HPP_CHECK_INVOCABLE(XV(), m4, const)
|
||||
META_HPP_CHECK_INVOCABLE(XV(), m5, const &)
|
||||
META_HPP_CHECK_INVOCABLE(XV(), m6, const &&)
|
||||
|
||||
META_HPP_CHECK_INVOCABLE(XV2(), m1, )
|
||||
META_HPP_CHECK_INVOCABLE(XV2(), m2, &)
|
||||
META_HPP_CHECK_INVOCABLE(XV2(), m3, &&)
|
||||
META_HPP_CHECK_INVOCABLE(XV2(), m4, const)
|
||||
META_HPP_CHECK_INVOCABLE(XV2(), m5, const &)
|
||||
META_HPP_CHECK_INVOCABLE(XV2(), m6, const &&)
|
||||
}
|
||||
|
||||
{
|
||||
// const xvalue
|
||||
auto CXV = []() -> const clazz&& { static clazz v; return std::move(v); };
|
||||
auto CXV2 = []() -> const dclazz&& { static dclazz v; return std::move(v); };
|
||||
|
||||
{
|
||||
meta::detail::uinst i{CXV()};
|
||||
CHECK(i.get_raw_type() == meta::resolve_type<clazz>());
|
||||
CHECK(i.get_ref_type() == meta::detail::uinst::ref_types::const_rvalue);
|
||||
}
|
||||
|
||||
META_HPP_CHECK_INVOCABLE(CXV(), m1, )
|
||||
META_HPP_CHECK_INVOCABLE(CXV(), m2, &)
|
||||
META_HPP_CHECK_INVOCABLE(CXV(), m3, &&)
|
||||
META_HPP_CHECK_INVOCABLE(CXV(), m4, const)
|
||||
META_HPP_CHECK_INVOCABLE(CXV(), m5, const &)
|
||||
META_HPP_CHECK_INVOCABLE(CXV(), m6, const &&)
|
||||
|
||||
META_HPP_CHECK_INVOCABLE(CXV2(), m1, )
|
||||
META_HPP_CHECK_INVOCABLE(CXV2(), m2, &)
|
||||
META_HPP_CHECK_INVOCABLE(CXV2(), m3, &&)
|
||||
META_HPP_CHECK_INVOCABLE(CXV2(), m4, const)
|
||||
META_HPP_CHECK_INVOCABLE(CXV2(), m5, const &)
|
||||
META_HPP_CHECK_INVOCABLE(CXV2(), m6, const &&)
|
||||
}
|
||||
|
||||
{
|
||||
// prvalue
|
||||
auto PRV = []() -> clazz { return clazz{}; };
|
||||
auto PRV2 = []() -> dclazz { return dclazz{}; };
|
||||
|
||||
{
|
||||
meta::detail::uinst i{PRV()};
|
||||
CHECK(i.get_raw_type() == meta::resolve_type<clazz>());
|
||||
CHECK(i.get_ref_type() == meta::detail::uinst::ref_types::rvalue);
|
||||
}
|
||||
|
||||
META_HPP_CHECK_INVOCABLE(PRV(), m1, )
|
||||
META_HPP_CHECK_INVOCABLE(PRV(), m2, &)
|
||||
META_HPP_CHECK_INVOCABLE(PRV(), m3, &&)
|
||||
META_HPP_CHECK_INVOCABLE(PRV(), m4, const)
|
||||
META_HPP_CHECK_INVOCABLE(PRV(), m5, const &)
|
||||
META_HPP_CHECK_INVOCABLE(PRV(), m6, const &&)
|
||||
|
||||
META_HPP_CHECK_INVOCABLE(PRV2(), m1, )
|
||||
META_HPP_CHECK_INVOCABLE(PRV2(), m2, &)
|
||||
META_HPP_CHECK_INVOCABLE(PRV2(), m3, &&)
|
||||
META_HPP_CHECK_INVOCABLE(PRV2(), m4, const)
|
||||
META_HPP_CHECK_INVOCABLE(PRV2(), m5, const &)
|
||||
META_HPP_CHECK_INVOCABLE(PRV2(), m6, const &&)
|
||||
}
|
||||
|
||||
{
|
||||
// const prvalue
|
||||
auto CPRV = []() -> const clazz { return clazz{}; };
|
||||
auto CPRV2 = []() -> const dclazz { return dclazz{}; };
|
||||
|
||||
{
|
||||
meta::detail::uinst i{CPRV()};
|
||||
CHECK(i.get_raw_type() == meta::resolve_type<clazz>());
|
||||
CHECK(i.get_ref_type() == meta::detail::uinst::ref_types::const_rvalue);
|
||||
}
|
||||
|
||||
META_HPP_CHECK_INVOCABLE(CPRV(), m1, )
|
||||
META_HPP_CHECK_INVOCABLE(CPRV(), m2, &)
|
||||
META_HPP_CHECK_INVOCABLE(CPRV(), m3, &&)
|
||||
META_HPP_CHECK_INVOCABLE(CPRV(), m4, const)
|
||||
META_HPP_CHECK_INVOCABLE(CPRV(), m5, const &)
|
||||
META_HPP_CHECK_INVOCABLE(CPRV(), m6, const &&)
|
||||
|
||||
META_HPP_CHECK_INVOCABLE(CPRV2(), m1, )
|
||||
META_HPP_CHECK_INVOCABLE(CPRV2(), m2, &)
|
||||
META_HPP_CHECK_INVOCABLE(CPRV2(), m3, &&)
|
||||
META_HPP_CHECK_INVOCABLE(CPRV2(), m4, const)
|
||||
META_HPP_CHECK_INVOCABLE(CPRV2(), m5, const &)
|
||||
META_HPP_CHECK_INVOCABLE(CPRV2(), m6, const &&)
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("meta/meta_utilities/inst2/values") {
|
||||
namespace meta = meta_hpp;
|
||||
|
||||
{
|
||||
// lvalue
|
||||
auto LV = []() -> meta::uvalue& { static meta::uvalue v{clazz{}}; return v; };
|
||||
auto LV2 = []() -> meta::uvalue& { static meta::uvalue v{dclazz{}}; return v; };
|
||||
|
||||
meta::detail::uarg a{LV()};
|
||||
CHECK(a.get_raw_type() == meta::resolve_type<clazz>());
|
||||
CHECK(a.get_ref_type() == meta::detail::uarg::ref_types::lvalue);
|
||||
|
||||
META_HPP_CHECK_INVOCABLE_2(LV(), m1, clazz&, )
|
||||
META_HPP_CHECK_INVOCABLE_2(LV(), m2, clazz&, &)
|
||||
META_HPP_CHECK_INVOCABLE_2(LV(), m3, clazz&, &&)
|
||||
META_HPP_CHECK_INVOCABLE_2(LV(), m4, clazz&, const)
|
||||
META_HPP_CHECK_INVOCABLE_2(LV(), m5, clazz&, const &)
|
||||
META_HPP_CHECK_INVOCABLE_2(LV(), m6, clazz&, const &&)
|
||||
|
||||
META_HPP_CHECK_INVOCABLE_2(LV2(), m1, dclazz&, )
|
||||
META_HPP_CHECK_INVOCABLE_2(LV2(), m2, dclazz&, &)
|
||||
META_HPP_CHECK_INVOCABLE_2(LV2(), m3, dclazz&, &&)
|
||||
META_HPP_CHECK_INVOCABLE_2(LV2(), m4, dclazz&, const)
|
||||
META_HPP_CHECK_INVOCABLE_2(LV2(), m5, dclazz&, const &)
|
||||
META_HPP_CHECK_INVOCABLE_2(LV2(), m6, dclazz&, const &&)
|
||||
}
|
||||
|
||||
{
|
||||
// const lvalue
|
||||
auto CLV = []() -> const meta::uvalue& { static meta::uvalue v{clazz{}}; return v; };
|
||||
auto CLV2 = []() -> const meta::uvalue& { static meta::uvalue v{dclazz{}}; return v; };
|
||||
|
||||
meta::detail::uarg a{CLV()};
|
||||
CHECK(a.get_raw_type() == meta::resolve_type<clazz>());
|
||||
CHECK(a.get_ref_type() == meta::detail::uarg::ref_types::const_lvalue);
|
||||
|
||||
META_HPP_CHECK_INVOCABLE_2(CLV(), m1, const clazz&, )
|
||||
META_HPP_CHECK_INVOCABLE_2(CLV(), m2, const clazz&, &)
|
||||
META_HPP_CHECK_INVOCABLE_2(CLV(), m3, const clazz&, &&)
|
||||
META_HPP_CHECK_INVOCABLE_2(CLV(), m4, const clazz&, const)
|
||||
META_HPP_CHECK_INVOCABLE_2(CLV(), m5, const clazz&, const &)
|
||||
META_HPP_CHECK_INVOCABLE_2(CLV(), m6, const clazz&, const &&)
|
||||
|
||||
META_HPP_CHECK_INVOCABLE_2(CLV2(), m1, const dclazz&, )
|
||||
META_HPP_CHECK_INVOCABLE_2(CLV2(), m2, const dclazz&, &)
|
||||
META_HPP_CHECK_INVOCABLE_2(CLV2(), m3, const dclazz&, &&)
|
||||
META_HPP_CHECK_INVOCABLE_2(CLV2(), m4, const dclazz&, const)
|
||||
META_HPP_CHECK_INVOCABLE_2(CLV2(), m5, const dclazz&, const &)
|
||||
META_HPP_CHECK_INVOCABLE_2(CLV2(), m6, const dclazz&, const &&)
|
||||
}
|
||||
|
||||
{
|
||||
// xvalue
|
||||
auto XV = []() -> meta::uvalue&& { static meta::uvalue v{clazz{}}; return std::move(v); };
|
||||
auto XV2 = []() -> meta::uvalue&& { static meta::uvalue v{dclazz{}}; return std::move(v); };
|
||||
|
||||
meta::detail::uarg a{XV()};
|
||||
CHECK(a.get_raw_type() == meta::resolve_type<clazz>());
|
||||
CHECK(a.get_ref_type() == meta::detail::uarg::ref_types::rvalue);
|
||||
|
||||
META_HPP_CHECK_INVOCABLE_2(XV(), m1, clazz&&, )
|
||||
META_HPP_CHECK_INVOCABLE_2(XV(), m2, clazz&&, &)
|
||||
META_HPP_CHECK_INVOCABLE_2(XV(), m3, clazz&&, &&)
|
||||
META_HPP_CHECK_INVOCABLE_2(XV(), m4, clazz&&, const)
|
||||
META_HPP_CHECK_INVOCABLE_2(XV(), m5, clazz&&, const &)
|
||||
META_HPP_CHECK_INVOCABLE_2(XV(), m6, clazz&&, const &&)
|
||||
|
||||
META_HPP_CHECK_INVOCABLE_2(XV2(), m1, dclazz&&, )
|
||||
META_HPP_CHECK_INVOCABLE_2(XV2(), m2, dclazz&&, &)
|
||||
META_HPP_CHECK_INVOCABLE_2(XV2(), m3, dclazz&&, &&)
|
||||
META_HPP_CHECK_INVOCABLE_2(XV2(), m4, dclazz&&, const)
|
||||
META_HPP_CHECK_INVOCABLE_2(XV2(), m5, dclazz&&, const &)
|
||||
META_HPP_CHECK_INVOCABLE_2(XV2(), m6, dclazz&&, const &&)
|
||||
}
|
||||
|
||||
{
|
||||
// const xvalue
|
||||
auto CXV = []() -> const meta::uvalue&& { static meta::uvalue v{clazz{}}; return std::move(v); };
|
||||
auto CXV2 = []() -> const meta::uvalue&& { static meta::uvalue v{dclazz{}}; return std::move(v); };
|
||||
|
||||
meta::detail::uarg a{CXV()};
|
||||
CHECK(a.get_raw_type() == meta::resolve_type<clazz>());
|
||||
CHECK(a.get_ref_type() == meta::detail::uarg::ref_types::const_rvalue);
|
||||
|
||||
META_HPP_CHECK_INVOCABLE_2(CXV(), m1, const clazz&&, )
|
||||
META_HPP_CHECK_INVOCABLE_2(CXV(), m2, const clazz&&, &)
|
||||
META_HPP_CHECK_INVOCABLE_2(CXV(), m3, const clazz&&, &&)
|
||||
META_HPP_CHECK_INVOCABLE_2(CXV(), m4, const clazz&&, const)
|
||||
META_HPP_CHECK_INVOCABLE_2(CXV(), m5, const clazz&&, const &)
|
||||
META_HPP_CHECK_INVOCABLE_2(CXV(), m6, const clazz&&, const &&)
|
||||
|
||||
META_HPP_CHECK_INVOCABLE_2(CXV2(), m1, const dclazz&&, )
|
||||
META_HPP_CHECK_INVOCABLE_2(CXV2(), m2, const dclazz&&, &)
|
||||
META_HPP_CHECK_INVOCABLE_2(CXV2(), m3, const dclazz&&, &&)
|
||||
META_HPP_CHECK_INVOCABLE_2(CXV2(), m4, const dclazz&&, const)
|
||||
META_HPP_CHECK_INVOCABLE_2(CXV2(), m5, const dclazz&&, const &)
|
||||
META_HPP_CHECK_INVOCABLE_2(CXV2(), m6, const dclazz&&, const &&)
|
||||
}
|
||||
|
||||
{
|
||||
// prvalue
|
||||
auto PRV = []() -> meta::uvalue { return meta::uvalue{clazz{}}; };
|
||||
auto PRV2 = []() -> meta::uvalue { return meta::uvalue{dclazz{}}; };
|
||||
|
||||
meta::detail::uarg a{PRV()};
|
||||
CHECK(a.get_raw_type() == meta::resolve_type<clazz>());
|
||||
CHECK(a.get_ref_type() == meta::detail::uarg::ref_types::rvalue);
|
||||
|
||||
META_HPP_CHECK_INVOCABLE_2(PRV(), m1, clazz, )
|
||||
META_HPP_CHECK_INVOCABLE_2(PRV(), m2, clazz, &)
|
||||
META_HPP_CHECK_INVOCABLE_2(PRV(), m3, clazz, &&)
|
||||
META_HPP_CHECK_INVOCABLE_2(PRV(), m4, clazz, const)
|
||||
META_HPP_CHECK_INVOCABLE_2(PRV(), m5, clazz, const &)
|
||||
META_HPP_CHECK_INVOCABLE_2(PRV(), m6, clazz, const &&)
|
||||
|
||||
META_HPP_CHECK_INVOCABLE_2(PRV2(), m1, dclazz, )
|
||||
META_HPP_CHECK_INVOCABLE_2(PRV2(), m2, dclazz, &)
|
||||
META_HPP_CHECK_INVOCABLE_2(PRV2(), m3, dclazz, &&)
|
||||
META_HPP_CHECK_INVOCABLE_2(PRV2(), m4, dclazz, const)
|
||||
META_HPP_CHECK_INVOCABLE_2(PRV2(), m5, dclazz, const &)
|
||||
META_HPP_CHECK_INVOCABLE_2(PRV2(), m6, dclazz, const &&)
|
||||
}
|
||||
|
||||
{
|
||||
// const prvalue
|
||||
auto CPRV = []() -> const meta::uvalue { return meta::uvalue{clazz{}}; };
|
||||
auto CPRV2 = []() -> const meta::uvalue { return meta::uvalue{dclazz{}}; };
|
||||
|
||||
meta::detail::uarg a{CPRV()};
|
||||
CHECK(a.get_raw_type() == meta::resolve_type<clazz>());
|
||||
CHECK(a.get_ref_type() == meta::detail::uarg::ref_types::const_rvalue);
|
||||
|
||||
META_HPP_CHECK_INVOCABLE_2(CPRV(), m1, const clazz, )
|
||||
META_HPP_CHECK_INVOCABLE_2(CPRV(), m2, const clazz, &)
|
||||
META_HPP_CHECK_INVOCABLE_2(CPRV(), m3, const clazz, &&)
|
||||
META_HPP_CHECK_INVOCABLE_2(CPRV(), m4, const clazz, const)
|
||||
META_HPP_CHECK_INVOCABLE_2(CPRV(), m5, const clazz, const &)
|
||||
META_HPP_CHECK_INVOCABLE_2(CPRV(), m6, const clazz, const &&)
|
||||
|
||||
META_HPP_CHECK_INVOCABLE_2(CPRV2(), m1, const dclazz, )
|
||||
META_HPP_CHECK_INVOCABLE_2(CPRV2(), m2, const dclazz, &)
|
||||
META_HPP_CHECK_INVOCABLE_2(CPRV2(), m3, const dclazz, &&)
|
||||
META_HPP_CHECK_INVOCABLE_2(CPRV2(), m4, const dclazz, const)
|
||||
META_HPP_CHECK_INVOCABLE_2(CPRV2(), m5, const dclazz, const &)
|
||||
META_HPP_CHECK_INVOCABLE_2(CPRV2(), m6, const dclazz, const &&)
|
||||
}
|
||||
}
|
||||
85
develop/untests/meta_utilities/invoke_tests.cpp
Normal file
85
develop/untests/meta_utilities/invoke_tests.cpp
Normal file
@@ -0,0 +1,85 @@
|
||||
/*******************************************************************************
|
||||
* 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 "../meta_untests.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
struct clazz {
|
||||
int member{1};
|
||||
int method(int i) const { return i; }
|
||||
static int function(int i) { return i; }
|
||||
};
|
||||
}
|
||||
|
||||
TEST_CASE("meta/meta_utilities/invoke") {
|
||||
namespace meta = meta_hpp;
|
||||
|
||||
meta::class_<clazz>()
|
||||
.member_("member", &clazz::member)
|
||||
.method_("method", &clazz::method)
|
||||
.function_("function", &clazz::function);
|
||||
|
||||
const meta::class_type& clazz_type = meta::resolve_type<clazz>();
|
||||
REQUIRE(clazz_type);
|
||||
|
||||
const meta::member& clazz_member = clazz_type.get_member("member");
|
||||
const meta::method& clazz_method = clazz_type.get_method("method");
|
||||
const meta::function& clazz_function = clazz_type.get_function("function");
|
||||
REQUIRE((clazz_member && clazz_method && clazz_function));
|
||||
|
||||
{
|
||||
CHECK(meta::invoke(&clazz::function, 3) == 3);
|
||||
CHECK(meta::invoke(&clazz::function, meta::uvalue(3)) == 3);
|
||||
CHECK(meta::invoke(clazz_function, 3) == 3);
|
||||
CHECK(meta::invoke(clazz_function, meta::uvalue(3)) == 3);
|
||||
|
||||
CHECK(meta::is_invocable_with(clazz_function, 3));
|
||||
CHECK(meta::is_invocable_with(clazz_function, meta::uvalue(3)));
|
||||
CHECK(meta::is_invocable_with<int>(clazz_function));
|
||||
|
||||
using function_t = decltype(&clazz::function);
|
||||
CHECK(meta::is_invocable_with<function_t>(3));
|
||||
CHECK(meta::is_invocable_with<function_t>(meta::uvalue(3)));
|
||||
CHECK(meta::is_invocable_with<function_t, int>());
|
||||
}
|
||||
|
||||
{
|
||||
clazz cl;
|
||||
|
||||
CHECK(meta::invoke(&clazz::member, cl) == 1);
|
||||
CHECK(meta::invoke(&clazz::member, meta::uvalue{cl}) == 1);
|
||||
CHECK(meta::invoke(clazz_member, cl) == 1);
|
||||
CHECK(meta::invoke(clazz_member, meta::uvalue{cl}) == 1);
|
||||
|
||||
CHECK(meta::is_invocable_with(clazz_member, cl));
|
||||
CHECK(meta::is_invocable_with(clazz_member, meta::uvalue{cl}));
|
||||
CHECK(meta::is_invocable_with<const clazz&>(clazz_member));
|
||||
|
||||
using member_t = decltype(&clazz::member);
|
||||
CHECK(meta::is_invocable_with<member_t>(cl));
|
||||
CHECK(meta::is_invocable_with<member_t>(meta::uvalue{cl}));
|
||||
CHECK(meta::is_invocable_with<member_t, const clazz&>());
|
||||
}
|
||||
|
||||
{
|
||||
clazz cl;
|
||||
|
||||
CHECK(meta::invoke(&clazz::method, cl, 2) == 2);
|
||||
CHECK(meta::invoke(&clazz::method, meta::uvalue{cl}, meta::uvalue(2)) == 2);
|
||||
CHECK(meta::invoke(clazz_method, cl, 2) == 2);
|
||||
CHECK(meta::invoke(clazz_method, meta::uvalue{cl}, meta::uvalue(2)) == 2);
|
||||
|
||||
CHECK(meta::is_invocable_with(clazz_method, cl, 2));
|
||||
CHECK(meta::is_invocable_with(clazz_method, meta::uvalue{cl}, meta::uvalue(2)));
|
||||
CHECK(meta::is_invocable_with<const clazz&, int>(clazz_method));
|
||||
|
||||
using method_t = decltype(&clazz::method);
|
||||
CHECK(meta::is_invocable_with<method_t>(cl, 2));
|
||||
CHECK(meta::is_invocable_with<method_t>(meta::uvalue{cl}, meta::uvalue(2)));
|
||||
CHECK(meta::is_invocable_with<method_t, const clazz&, int>());
|
||||
}
|
||||
}
|
||||
413
develop/untests/meta_utilities/value2_tests.cpp
Normal file
413
develop/untests/meta_utilities/value2_tests.cpp
Normal file
@@ -0,0 +1,413 @@
|
||||
/*******************************************************************************
|
||||
* 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 "../meta_untests.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
struct ivec2 final {
|
||||
int x{};
|
||||
int y{};
|
||||
|
||||
ivec2() = delete;
|
||||
|
||||
[[maybe_unused]] explicit ivec2(int nv): x{nv}, y{nv} {}
|
||||
[[maybe_unused]] ivec2(int nx, int ny): x{nx}, y{ny} {}
|
||||
|
||||
[[maybe_unused]] ivec2(ivec2&& other) noexcept
|
||||
: x{other.x}
|
||||
, y{other.y} {
|
||||
other.x = 0;
|
||||
other.y = 0;
|
||||
++move_constructor_counter;
|
||||
}
|
||||
|
||||
[[maybe_unused]] ivec2(const ivec2& other) noexcept
|
||||
: x{other.x}
|
||||
, y{other.y} {
|
||||
++copy_constructor_counter;
|
||||
}
|
||||
|
||||
~ivec2() noexcept {
|
||||
++destructor_counter;
|
||||
}
|
||||
|
||||
ivec2& operator=(ivec2&& other) = delete;
|
||||
ivec2& operator=(const ivec2& other) = delete;
|
||||
|
||||
static int destructor_counter;
|
||||
static int move_constructor_counter;
|
||||
static int copy_constructor_counter;
|
||||
};
|
||||
|
||||
struct ivec2_big final {
|
||||
int x{};
|
||||
int y{};
|
||||
|
||||
int dummy[42]{};
|
||||
|
||||
ivec2_big() = delete;
|
||||
|
||||
[[maybe_unused]] explicit ivec2_big(int nv): x{nv}, y{nv} {}
|
||||
[[maybe_unused]] ivec2_big(int nx, int ny): x{nx}, y{ny} {}
|
||||
|
||||
[[maybe_unused]] ivec2_big(ivec2_big&& other) noexcept
|
||||
: x{other.x}
|
||||
, y{other.y} {
|
||||
other.x = 0;
|
||||
other.y = 0;
|
||||
++move_constructor_counter;
|
||||
}
|
||||
|
||||
[[maybe_unused]] ivec2_big(const ivec2_big& other) noexcept
|
||||
: x{other.x}
|
||||
, y{other.y} {
|
||||
++copy_constructor_counter;
|
||||
}
|
||||
|
||||
~ivec2_big() noexcept {
|
||||
++destructor_counter;
|
||||
}
|
||||
|
||||
ivec2_big& operator=(ivec2_big&& other) = delete;
|
||||
ivec2_big& operator=(const ivec2_big& other) = delete;
|
||||
|
||||
static int destructor_counter;
|
||||
static int move_constructor_counter;
|
||||
static int copy_constructor_counter;
|
||||
};
|
||||
|
||||
[[maybe_unused]] bool operator==(const ivec2& l, const ivec2& r) noexcept {
|
||||
return l.x == r.x && l.y == r.y;
|
||||
}
|
||||
|
||||
[[maybe_unused]] bool operator==(const ivec2_big& l, const ivec2_big& r) noexcept {
|
||||
return l.x == r.x && l.y == r.y;
|
||||
}
|
||||
|
||||
int ivec2::destructor_counter{0};
|
||||
int ivec2::move_constructor_counter{0};
|
||||
int ivec2::copy_constructor_counter{0};
|
||||
|
||||
int ivec2_big::destructor_counter{0};
|
||||
int ivec2_big::move_constructor_counter{0};
|
||||
int ivec2_big::copy_constructor_counter{0};
|
||||
}
|
||||
|
||||
TEST_CASE("meta/meta_utilities/value2") {
|
||||
namespace meta = meta_hpp;
|
||||
|
||||
meta::class_<ivec2>()
|
||||
.constructor_<int>()
|
||||
.constructor_<int, int>()
|
||||
.constructor_<ivec2&&>()
|
||||
.constructor_<const ivec2&>()
|
||||
.member_("x", &ivec2::x)
|
||||
.member_("y", &ivec2::y);
|
||||
|
||||
meta::class_<ivec2_big>()
|
||||
.constructor_<int>()
|
||||
.constructor_<int, int>()
|
||||
.constructor_<ivec2_big&&>()
|
||||
.constructor_<const ivec2_big&>()
|
||||
.member_("x", &ivec2_big::x)
|
||||
.member_("y", &ivec2_big::y);
|
||||
}
|
||||
|
||||
TEST_CASE("meta/meta_utilities/value2/counters/small") {
|
||||
namespace meta = meta_hpp;
|
||||
|
||||
ivec2::destructor_counter = 0;
|
||||
ivec2::move_constructor_counter = 0;
|
||||
ivec2::copy_constructor_counter = 0;
|
||||
|
||||
SUBCASE("def ctor") {
|
||||
{
|
||||
meta::uvalue v{};
|
||||
CHECK(ivec2::destructor_counter == 0);
|
||||
CHECK(ivec2::move_constructor_counter == 0);
|
||||
CHECK(ivec2::copy_constructor_counter == 0);
|
||||
}
|
||||
CHECK(ivec2::destructor_counter == 0);
|
||||
CHECK(ivec2::move_constructor_counter == 0);
|
||||
CHECK(ivec2::copy_constructor_counter == 0);
|
||||
}
|
||||
|
||||
SUBCASE("val ctor") {
|
||||
{
|
||||
meta::uvalue v{ivec2{1,2}};
|
||||
CHECK(ivec2::destructor_counter == 1);
|
||||
CHECK(ivec2::move_constructor_counter == 1);
|
||||
CHECK(ivec2::copy_constructor_counter == 0);
|
||||
}
|
||||
CHECK(ivec2::destructor_counter == 2);
|
||||
CHECK(ivec2::move_constructor_counter == 1);
|
||||
CHECK(ivec2::copy_constructor_counter == 0);
|
||||
}
|
||||
|
||||
SUBCASE("move ctor") {
|
||||
{
|
||||
meta::uvalue v1{ivec2{1,2}};
|
||||
meta::uvalue v2{std::move(v1)};
|
||||
|
||||
CHECK_FALSE(v1);
|
||||
CHECK(v2.get_as<ivec2>().x == 1);
|
||||
|
||||
CHECK(ivec2::destructor_counter == 2);
|
||||
CHECK(ivec2::move_constructor_counter == 2);
|
||||
CHECK(ivec2::copy_constructor_counter == 0);
|
||||
}
|
||||
CHECK(ivec2::destructor_counter == 3);
|
||||
CHECK(ivec2::move_constructor_counter == 2);
|
||||
CHECK(ivec2::copy_constructor_counter == 0);
|
||||
}
|
||||
|
||||
SUBCASE("copy ctor") {
|
||||
{
|
||||
meta::uvalue v1{ivec2{1,2}};
|
||||
meta::uvalue v2{std::as_const(v1)};
|
||||
|
||||
CHECK(v1.get_as<ivec2>().x == 1);
|
||||
CHECK(v2.get_as<ivec2>().y == 2);
|
||||
|
||||
CHECK(ivec2::destructor_counter == 1);
|
||||
CHECK(ivec2::move_constructor_counter == 1);
|
||||
CHECK(ivec2::copy_constructor_counter == 1);
|
||||
}
|
||||
CHECK(ivec2::destructor_counter == 3);
|
||||
CHECK(ivec2::move_constructor_counter == 1);
|
||||
CHECK(ivec2::copy_constructor_counter == 1);
|
||||
}
|
||||
|
||||
SUBCASE("swap") {
|
||||
{
|
||||
meta::uvalue v1{ivec2{1,2}};
|
||||
meta::uvalue v2{ivec2{3,4}};
|
||||
CHECK(ivec2::destructor_counter == 2);
|
||||
CHECK(ivec2::move_constructor_counter == 2);
|
||||
CHECK(ivec2::copy_constructor_counter == 0);
|
||||
|
||||
v1.swap(v2);
|
||||
CHECK(v1.get_as<ivec2>().x == 3);
|
||||
CHECK(v2.get_as<ivec2>().x == 1);
|
||||
|
||||
CHECK(ivec2::destructor_counter == 5);
|
||||
CHECK(ivec2::move_constructor_counter == 5);
|
||||
CHECK(ivec2::copy_constructor_counter == 0);
|
||||
}
|
||||
CHECK(ivec2::destructor_counter == 7);
|
||||
CHECK(ivec2::move_constructor_counter == 5);
|
||||
CHECK(ivec2::copy_constructor_counter == 0);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("meta/meta_utilities/value2/counters/big") {
|
||||
namespace meta = meta_hpp;
|
||||
|
||||
ivec2_big::destructor_counter = 0;
|
||||
ivec2_big::move_constructor_counter = 0;
|
||||
ivec2_big::copy_constructor_counter = 0;
|
||||
|
||||
SUBCASE("def ctor") {
|
||||
{
|
||||
meta::uvalue v{};
|
||||
CHECK(ivec2_big::destructor_counter == 0);
|
||||
CHECK(ivec2_big::move_constructor_counter == 0);
|
||||
CHECK(ivec2_big::copy_constructor_counter == 0);
|
||||
}
|
||||
CHECK(ivec2_big::destructor_counter == 0);
|
||||
CHECK(ivec2_big::move_constructor_counter == 0);
|
||||
CHECK(ivec2_big::copy_constructor_counter == 0);
|
||||
}
|
||||
|
||||
SUBCASE("val ctor") {
|
||||
{
|
||||
meta::uvalue v{ivec2_big{1,2}};
|
||||
CHECK(ivec2_big::destructor_counter == 1);
|
||||
CHECK(ivec2_big::move_constructor_counter == 1);
|
||||
CHECK(ivec2_big::copy_constructor_counter == 0);
|
||||
}
|
||||
CHECK(ivec2_big::destructor_counter == 2);
|
||||
CHECK(ivec2_big::move_constructor_counter == 1);
|
||||
CHECK(ivec2_big::copy_constructor_counter == 0);
|
||||
}
|
||||
|
||||
SUBCASE("move ctor") {
|
||||
{
|
||||
meta::uvalue v1{ivec2_big{1,2}};
|
||||
meta::uvalue v2{std::move(v1)};
|
||||
|
||||
CHECK_FALSE(v1);
|
||||
CHECK(v2.get_as<ivec2_big>().x == 1);
|
||||
|
||||
CHECK(ivec2_big::destructor_counter == 1);
|
||||
CHECK(ivec2_big::move_constructor_counter == 1);
|
||||
CHECK(ivec2_big::copy_constructor_counter == 0);
|
||||
}
|
||||
CHECK(ivec2_big::destructor_counter == 2);
|
||||
CHECK(ivec2_big::move_constructor_counter == 1);
|
||||
CHECK(ivec2_big::copy_constructor_counter == 0);
|
||||
}
|
||||
|
||||
SUBCASE("copy ctor") {
|
||||
{
|
||||
meta::uvalue v1{ivec2_big{1,2}};
|
||||
meta::uvalue v2{std::as_const(v1)};
|
||||
|
||||
CHECK(v1.get_as<ivec2_big>().x == 1);
|
||||
CHECK(v2.get_as<ivec2_big>().y == 2);
|
||||
|
||||
CHECK(ivec2_big::destructor_counter == 1);
|
||||
CHECK(ivec2_big::move_constructor_counter == 1);
|
||||
CHECK(ivec2_big::copy_constructor_counter == 1);
|
||||
}
|
||||
CHECK(ivec2_big::destructor_counter == 3);
|
||||
CHECK(ivec2_big::move_constructor_counter == 1);
|
||||
CHECK(ivec2_big::copy_constructor_counter == 1);
|
||||
}
|
||||
|
||||
SUBCASE("swap") {
|
||||
{
|
||||
meta::uvalue v1{ivec2_big{1,2}};
|
||||
meta::uvalue v2{ivec2_big{3,4}};
|
||||
CHECK(ivec2_big::destructor_counter == 2);
|
||||
CHECK(ivec2_big::move_constructor_counter == 2);
|
||||
CHECK(ivec2_big::copy_constructor_counter == 0);
|
||||
|
||||
v1.swap(v2);
|
||||
CHECK(v1.get_as<ivec2_big>().x == 3);
|
||||
CHECK(v2.get_as<ivec2_big>().x == 1);
|
||||
|
||||
CHECK(ivec2_big::destructor_counter == 2);
|
||||
CHECK(ivec2_big::move_constructor_counter == 2);
|
||||
CHECK(ivec2_big::copy_constructor_counter == 0);
|
||||
}
|
||||
CHECK(ivec2_big::destructor_counter == 4);
|
||||
CHECK(ivec2_big::move_constructor_counter == 2);
|
||||
CHECK(ivec2_big::copy_constructor_counter == 0);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("meta/meta_utilities/value2/counters/swap") {
|
||||
namespace meta = meta_hpp;
|
||||
|
||||
ivec2::destructor_counter = 0;
|
||||
ivec2::move_constructor_counter = 0;
|
||||
ivec2::copy_constructor_counter = 0;
|
||||
|
||||
ivec2_big::destructor_counter = 0;
|
||||
ivec2_big::move_constructor_counter = 0;
|
||||
ivec2_big::copy_constructor_counter = 0;
|
||||
|
||||
SUBCASE("empty/small") {
|
||||
{
|
||||
meta::uvalue v1{};
|
||||
meta::uvalue v2{ivec2{1,2}};
|
||||
|
||||
CHECK(ivec2::destructor_counter == 1);
|
||||
CHECK(ivec2::move_constructor_counter == 1);
|
||||
CHECK(ivec2::copy_constructor_counter == 0);
|
||||
|
||||
v1.swap(v2);
|
||||
CHECK(v1.get_as<ivec2>().x == 1);
|
||||
CHECK_FALSE(v2);
|
||||
|
||||
CHECK(ivec2::destructor_counter == 2);
|
||||
CHECK(ivec2::move_constructor_counter == 2);
|
||||
CHECK(ivec2::copy_constructor_counter == 0);
|
||||
|
||||
v1.swap(v2);
|
||||
CHECK_FALSE(v1);
|
||||
CHECK(v2.get_as<ivec2>().y == 2);
|
||||
|
||||
CHECK(ivec2::destructor_counter == 3);
|
||||
CHECK(ivec2::move_constructor_counter == 3);
|
||||
CHECK(ivec2::copy_constructor_counter == 0);
|
||||
}
|
||||
|
||||
CHECK(ivec2::destructor_counter == 4);
|
||||
CHECK(ivec2::move_constructor_counter == 3);
|
||||
CHECK(ivec2::copy_constructor_counter == 0);
|
||||
}
|
||||
|
||||
SUBCASE("empty/big") {
|
||||
{
|
||||
meta::uvalue v1{};
|
||||
meta::uvalue v2{ivec2_big{3,4}};
|
||||
|
||||
CHECK(ivec2_big::destructor_counter == 1);
|
||||
CHECK(ivec2_big::move_constructor_counter == 1);
|
||||
CHECK(ivec2_big::copy_constructor_counter == 0);
|
||||
|
||||
v1.swap(v2);
|
||||
CHECK(v1.get_as<ivec2_big>().x == 3);
|
||||
CHECK_FALSE(v2);
|
||||
|
||||
CHECK(ivec2_big::destructor_counter == 1);
|
||||
CHECK(ivec2_big::move_constructor_counter == 1);
|
||||
CHECK(ivec2_big::copy_constructor_counter == 0);
|
||||
|
||||
v1.swap(v2);
|
||||
CHECK_FALSE(v1);
|
||||
CHECK(v2.get_as<ivec2_big>().y == 4);
|
||||
|
||||
CHECK(ivec2_big::destructor_counter == 1);
|
||||
CHECK(ivec2_big::move_constructor_counter == 1);
|
||||
CHECK(ivec2_big::copy_constructor_counter == 0);
|
||||
}
|
||||
|
||||
CHECK(ivec2_big::destructor_counter == 2);
|
||||
CHECK(ivec2_big::move_constructor_counter == 1);
|
||||
CHECK(ivec2_big::copy_constructor_counter == 0);
|
||||
}
|
||||
|
||||
SUBCASE("small/big") {
|
||||
{
|
||||
meta::uvalue v1{ivec2{1,2}};
|
||||
meta::uvalue v2{ivec2_big{3,4}};
|
||||
|
||||
CHECK(ivec2::destructor_counter == 1);
|
||||
CHECK(ivec2::move_constructor_counter == 1);
|
||||
CHECK(ivec2::copy_constructor_counter == 0);
|
||||
|
||||
CHECK(ivec2_big::destructor_counter == 1);
|
||||
CHECK(ivec2_big::move_constructor_counter == 1);
|
||||
CHECK(ivec2_big::copy_constructor_counter == 0);
|
||||
|
||||
v1.swap(v2);
|
||||
CHECK(v1.get_as<ivec2_big>().x == 3);
|
||||
CHECK(v2.get_as<ivec2>().x == 1);
|
||||
|
||||
CHECK(ivec2::destructor_counter == 2);
|
||||
CHECK(ivec2::move_constructor_counter == 2);
|
||||
CHECK(ivec2::copy_constructor_counter == 0);
|
||||
|
||||
CHECK(ivec2_big::destructor_counter == 1);
|
||||
CHECK(ivec2_big::move_constructor_counter == 1);
|
||||
CHECK(ivec2_big::copy_constructor_counter == 0);
|
||||
|
||||
v1.swap(v2);
|
||||
CHECK(v1.get_as<ivec2>().y == 2);
|
||||
CHECK(v2.get_as<ivec2_big>().y == 4);
|
||||
|
||||
CHECK(ivec2::destructor_counter == 3);
|
||||
CHECK(ivec2::move_constructor_counter == 3);
|
||||
CHECK(ivec2::copy_constructor_counter == 0);
|
||||
|
||||
CHECK(ivec2_big::destructor_counter == 1);
|
||||
CHECK(ivec2_big::move_constructor_counter == 1);
|
||||
CHECK(ivec2_big::copy_constructor_counter == 0);
|
||||
}
|
||||
|
||||
CHECK(ivec2::destructor_counter == 4);
|
||||
CHECK(ivec2::move_constructor_counter == 3);
|
||||
CHECK(ivec2::copy_constructor_counter == 0);
|
||||
|
||||
CHECK(ivec2_big::destructor_counter == 2);
|
||||
CHECK(ivec2_big::move_constructor_counter == 1);
|
||||
CHECK(ivec2_big::copy_constructor_counter == 0);
|
||||
}
|
||||
}
|
||||
326
develop/untests/meta_utilities/value3_tests.cpp
Normal file
326
develop/untests/meta_utilities/value3_tests.cpp
Normal file
@@ -0,0 +1,326 @@
|
||||
/*******************************************************************************
|
||||
* 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 "../meta_untests.hpp"
|
||||
|
||||
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/value4") {
|
||||
namespace meta = meta_hpp;
|
||||
|
||||
meta::class_<base0>();
|
||||
|
||||
meta::class_<base1>()
|
||||
.base_<base0>();
|
||||
|
||||
meta::class_<base2>()
|
||||
.base_<base0>();
|
||||
|
||||
meta::class_<derived>()
|
||||
.base_<base1>()
|
||||
.base_<base2>();
|
||||
|
||||
meta::class_<derived2>()
|
||||
.base_<base1>()
|
||||
.base_<base2>();
|
||||
}
|
||||
|
||||
TEST_CASE("meta/meta_utilities/value4/get_type") {
|
||||
namespace meta = meta_hpp;
|
||||
|
||||
SUBCASE("from ref") {
|
||||
{
|
||||
derived d{};
|
||||
CHECK(meta::uvalue{d}.get_type() == meta::resolve_type<derived>());
|
||||
}
|
||||
{
|
||||
const derived d{};
|
||||
CHECK(meta::uvalue{d}.get_type() == meta::resolve_type<derived>());
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("from ptr") {
|
||||
{
|
||||
derived d{};
|
||||
derived* pd = &d;
|
||||
CHECK(meta::uvalue{pd}.get_type() == meta::resolve_type<derived*>());
|
||||
}
|
||||
{
|
||||
derived d{};
|
||||
derived* const pd = &d;
|
||||
CHECK(meta::uvalue{pd}.get_type() == meta::resolve_type<derived*>());
|
||||
}
|
||||
{
|
||||
derived d{};
|
||||
const derived* pd = &d;
|
||||
CHECK(meta::uvalue{pd}.get_type() == meta::resolve_type<const derived*>());
|
||||
}
|
||||
{
|
||||
derived d{};
|
||||
const derived* const pd = &d;
|
||||
CHECK(meta::uvalue{pd}.get_type() == meta::resolve_type<const derived*>());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("meta/meta_utilities/value4/get_as") {
|
||||
namespace meta = meta_hpp;
|
||||
|
||||
static_assert(std::is_same_v<decltype(std::declval<meta::uvalue&>().get_as<derived>()), derived&>);
|
||||
static_assert(std::is_same_v<decltype(std::declval<meta::uvalue&&>().get_as<derived>()), derived&>);
|
||||
static_assert(std::is_same_v<decltype(std::declval<const meta::uvalue&>().get_as<derived>()), const derived&>);
|
||||
static_assert(std::is_same_v<decltype(std::declval<const meta::uvalue&&>().get_as<derived>()), const derived&>);
|
||||
|
||||
static_assert(std::is_same_v<decltype(std::declval<meta::uvalue&>().get_as<derived*>()), derived*>);
|
||||
static_assert(std::is_same_v<decltype(std::declval<meta::uvalue&&>().get_as<derived*>()), derived*>);
|
||||
static_assert(std::is_same_v<decltype(std::declval<const meta::uvalue&>().get_as<derived*>()), derived*>);
|
||||
static_assert(std::is_same_v<decltype(std::declval<const meta::uvalue&&>().get_as<derived*>()), derived*>);
|
||||
|
||||
static_assert(std::is_same_v<decltype(std::declval<meta::uvalue&>().get_as<const derived*>()), const derived*>);
|
||||
static_assert(std::is_same_v<decltype(std::declval<meta::uvalue&&>().get_as<const derived*>()), const derived*>);
|
||||
static_assert(std::is_same_v<decltype(std::declval<const meta::uvalue&>().get_as<const derived*>()), const derived*>);
|
||||
static_assert(std::is_same_v<decltype(std::declval<const meta::uvalue&&>().get_as<const derived*>()), const derived*>);
|
||||
|
||||
SUBCASE("derived to derived") {
|
||||
{
|
||||
meta::uvalue v{derived{}};
|
||||
CHECK(v.get_as<derived>().l == 168);
|
||||
CHECK_THROWS(std::ignore = v.get_as<derived2>());
|
||||
}
|
||||
{
|
||||
const meta::uvalue v{derived{}};
|
||||
CHECK(v.get_as<derived>().l == 168);
|
||||
CHECK_THROWS(std::ignore = v.get_as<derived2>());
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("derived to base") {
|
||||
{
|
||||
meta::uvalue v{derived{}};
|
||||
CHECK(v.get_as<base2>().k == 84);
|
||||
}
|
||||
{
|
||||
const meta::uvalue v{derived{}};
|
||||
CHECK(v.get_as<base2>().k == 84);
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("voidptr") {
|
||||
{
|
||||
derived d{};
|
||||
meta::uvalue v{&d};
|
||||
CHECK(v.get_as<void*>() == &d);
|
||||
CHECK(v.get_as<const void*>() == &d);
|
||||
}
|
||||
{
|
||||
const derived d{};
|
||||
meta::uvalue v{&d};
|
||||
CHECK_THROWS(std::ignore = v.get_as<void*>());
|
||||
CHECK(v.get_as<const void*>() == &d);
|
||||
}
|
||||
{
|
||||
meta::uvalue v{derived{}};
|
||||
CHECK_THROWS(std::ignore = v.get_as<void*>());
|
||||
CHECK_THROWS(std::ignore = v.get_as<const void*>());
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("nullptr") {
|
||||
{
|
||||
meta::uvalue v{nullptr};
|
||||
CHECK(v.get_as<void*>() == nullptr);
|
||||
CHECK(v.get_as<const void*>() == nullptr);
|
||||
CHECK(v.get_as<derived*>() == nullptr);
|
||||
CHECK(v.get_as<const derived*>() == nullptr);
|
||||
|
||||
CHECK_THROWS(std::ignore = v.get_as<derived>());
|
||||
}
|
||||
{
|
||||
const meta::uvalue v{nullptr};
|
||||
CHECK(v.get_as<void*>() == nullptr);
|
||||
CHECK(v.get_as<const void*>() == nullptr);
|
||||
CHECK(v.get_as<derived*>() == nullptr);
|
||||
CHECK(v.get_as<const derived*>() == nullptr);
|
||||
|
||||
CHECK_THROWS(std::ignore = v.get_as<derived>());
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("derived* to derived*") {
|
||||
{
|
||||
derived d{};
|
||||
meta::uvalue v{&d};
|
||||
CHECK(v.get_as<derived*>()->l == 168);
|
||||
CHECK(v.get_as<const derived*>()->l == 168);
|
||||
|
||||
CHECK_THROWS(std::ignore = v.get_as<derived2*>());
|
||||
CHECK_THROWS(std::ignore = v.get_as<const derived2*>());
|
||||
}
|
||||
{
|
||||
const derived d{};
|
||||
meta::uvalue v{&d};
|
||||
CHECK(v.get_as<const derived*>()->l == 168);
|
||||
|
||||
CHECK_THROWS(std::ignore = v.get_as<const derived2*>());
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("derived* to base*") {
|
||||
{
|
||||
derived d{};
|
||||
meta::uvalue v{&d};
|
||||
CHECK(v.get_as<base2*>()->k == 84);
|
||||
CHECK(v.get_as<const base2*>()->k == 84);
|
||||
}
|
||||
|
||||
{
|
||||
const derived d{};
|
||||
meta::uvalue v{&d};
|
||||
CHECK_THROWS(std::ignore = v.get_as<base2*>());
|
||||
CHECK(v.get_as<const base2*>()->k == 84);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("meta/meta_utilities/value4/try_get_as") {
|
||||
namespace meta = meta_hpp;
|
||||
|
||||
static_assert(std::is_same_v<decltype(std::declval<meta::uvalue&>().try_get_as<derived>()), derived*>);
|
||||
static_assert(std::is_same_v<decltype(std::declval<meta::uvalue&&>().try_get_as<derived>()), derived*>);
|
||||
static_assert(std::is_same_v<decltype(std::declval<const meta::uvalue&>().try_get_as<derived>()), const derived*>);
|
||||
static_assert(std::is_same_v<decltype(std::declval<const meta::uvalue&&>().try_get_as<derived>()), const derived*>);
|
||||
|
||||
static_assert(std::is_same_v<decltype(std::declval<meta::uvalue&>().try_get_as<derived*>()), derived*>);
|
||||
static_assert(std::is_same_v<decltype(std::declval<meta::uvalue&&>().try_get_as<derived*>()), derived*>);
|
||||
static_assert(std::is_same_v<decltype(std::declval<const meta::uvalue&>().try_get_as<derived*>()), derived*>);
|
||||
static_assert(std::is_same_v<decltype(std::declval<const meta::uvalue&&>().try_get_as<derived*>()), derived*>);
|
||||
|
||||
static_assert(std::is_same_v<decltype(std::declval<meta::uvalue&>().try_get_as<const derived*>()), const derived*>);
|
||||
static_assert(std::is_same_v<decltype(std::declval<meta::uvalue&&>().try_get_as<const derived*>()), const derived*>);
|
||||
static_assert(std::is_same_v<decltype(std::declval<const meta::uvalue&>().try_get_as<const derived*>()), const derived*>);
|
||||
static_assert(std::is_same_v<decltype(std::declval<const meta::uvalue&&>().try_get_as<const derived*>()), const derived*>);
|
||||
|
||||
SUBCASE("derived to derived") {
|
||||
{
|
||||
meta::uvalue v{derived{}};
|
||||
CHECK(v.try_get_as<derived>()->l == 168);
|
||||
CHECK_FALSE(v.try_get_as<derived2>());
|
||||
}
|
||||
{
|
||||
const meta::uvalue v{derived{}};
|
||||
CHECK(v.try_get_as<derived>()->l == 168);
|
||||
CHECK_FALSE(v.try_get_as<derived2>());
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("derived to base") {
|
||||
{
|
||||
meta::uvalue v{derived{}};
|
||||
CHECK(v.try_get_as<base2>()->k == 84);
|
||||
}
|
||||
{
|
||||
const meta::uvalue v{derived{}};
|
||||
CHECK(v.try_get_as<base2>()->k == 84);
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("voidptr") {
|
||||
{
|
||||
derived d{};
|
||||
meta::uvalue v{&d};
|
||||
CHECK(v.try_get_as<void*>() == &d);
|
||||
CHECK(v.try_get_as<const void*>() == &d);
|
||||
}
|
||||
{
|
||||
const derived d{};
|
||||
meta::uvalue v{&d};
|
||||
CHECK_FALSE(v.try_get_as<void*>());
|
||||
CHECK(v.try_get_as<const void*>() == &d);
|
||||
}
|
||||
{
|
||||
meta::uvalue v{derived{}};
|
||||
CHECK_FALSE(v.try_get_as<void*>());
|
||||
CHECK_FALSE(v.try_get_as<const void*>());
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("nullptr") {
|
||||
{
|
||||
meta::uvalue v{nullptr};
|
||||
CHECK(v.try_get_as<void*>() == nullptr);
|
||||
CHECK(v.try_get_as<const void*>() == nullptr);
|
||||
CHECK(v.try_get_as<derived*>() == nullptr);
|
||||
CHECK(v.try_get_as<const derived*>() == nullptr);
|
||||
|
||||
CHECK_FALSE(v.try_get_as<derived>());
|
||||
}
|
||||
{
|
||||
const meta::uvalue v{nullptr};
|
||||
CHECK(v.try_get_as<void*>() == nullptr);
|
||||
CHECK(v.try_get_as<const void*>() == nullptr);
|
||||
CHECK(v.try_get_as<derived*>() == nullptr);
|
||||
CHECK(v.try_get_as<const derived*>() == nullptr);
|
||||
|
||||
CHECK_FALSE(v.try_get_as<derived>());
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("derived* to derived*") {
|
||||
{
|
||||
derived d{};
|
||||
meta::uvalue v{&d};
|
||||
CHECK(v.try_get_as<derived*>()->l == 168);
|
||||
CHECK(v.try_get_as<const derived*>()->l == 168);
|
||||
|
||||
CHECK_FALSE(v.try_get_as<derived2*>());
|
||||
CHECK_FALSE(v.try_get_as<const derived2*>());
|
||||
}
|
||||
{
|
||||
const derived d{};
|
||||
meta::uvalue v{&d};
|
||||
CHECK(v.try_get_as<const derived*>()->l == 168);
|
||||
|
||||
CHECK_FALSE(v.try_get_as<const derived2*>());
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("derived* to base*") {
|
||||
{
|
||||
derived d{};
|
||||
meta::uvalue v{&d};
|
||||
CHECK(v.try_get_as<base2*>()->k == 84);
|
||||
CHECK(v.try_get_as<const base2*>()->k == 84);
|
||||
}
|
||||
|
||||
{
|
||||
const derived d{};
|
||||
meta::uvalue v{&d};
|
||||
CHECK_FALSE(v.try_get_as<base2*>());
|
||||
CHECK(v.try_get_as<const base2*>()->k == 84);
|
||||
}
|
||||
}
|
||||
}
|
||||
262
develop/untests/meta_utilities/value4_tests.cpp
Normal file
262
develop/untests/meta_utilities/value4_tests.cpp
Normal file
@@ -0,0 +1,262 @@
|
||||
/*******************************************************************************
|
||||
* 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 "../meta_untests.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
struct clazz_throw_dtor {
|
||||
int i{};
|
||||
|
||||
[[maybe_unused]]
|
||||
clazz_throw_dtor() {
|
||||
++constructor_counter;
|
||||
}
|
||||
|
||||
[[maybe_unused]]
|
||||
clazz_throw_dtor(int ni) : i{ni} {
|
||||
++constructor_counter;
|
||||
}
|
||||
|
||||
[[maybe_unused]]
|
||||
clazz_throw_dtor(clazz_throw_dtor&& other)
|
||||
: i{other.i} {
|
||||
other.i = 0;
|
||||
++move_constructor_counter;
|
||||
}
|
||||
|
||||
[[maybe_unused]]
|
||||
clazz_throw_dtor(const clazz_throw_dtor& other)
|
||||
: i{other.i} {
|
||||
++copy_constructor_counter;
|
||||
}
|
||||
|
||||
~clazz_throw_dtor() noexcept(false) {
|
||||
++destructor_counter;
|
||||
}
|
||||
|
||||
static clazz_throw_dtor make(int ni) {
|
||||
return {ni};
|
||||
}
|
||||
|
||||
inline static int destructor_counter{};
|
||||
inline static int constructor_counter{};
|
||||
inline static int move_constructor_counter{};
|
||||
inline static int copy_constructor_counter{};
|
||||
};
|
||||
}
|
||||
|
||||
TEST_CASE("meta/meta_utilities/value5") {
|
||||
namespace meta = meta_hpp;
|
||||
|
||||
meta::class_<clazz_throw_dtor>()
|
||||
.function_("make", &clazz_throw_dtor::make);
|
||||
}
|
||||
|
||||
TEST_CASE("meta/meta_utilities/value5/throw_dtor") {
|
||||
namespace meta = meta_hpp;
|
||||
|
||||
SUBCASE("value") {
|
||||
meta::uvalue v{clazz_throw_dtor{42}};
|
||||
|
||||
CHECK(v.get_type() == meta::resolve_type<clazz_throw_dtor>());
|
||||
CHECK(v.get_as<clazz_throw_dtor>().i == 42);
|
||||
}
|
||||
|
||||
SUBCASE("ptr_deref") {
|
||||
clazz_throw_dtor obj{42};
|
||||
|
||||
meta::uvalue v_ptr{&obj};
|
||||
CHECK(v_ptr.get_type() == meta::resolve_type<clazz_throw_dtor*>());
|
||||
CHECK(v_ptr.get_as<clazz_throw_dtor*>() == &obj);
|
||||
|
||||
meta::uvalue v = *v_ptr;
|
||||
CHECK(v.get_type() == meta::resolve_type<clazz_throw_dtor>());
|
||||
CHECK(v.get_as<clazz_throw_dtor>().i == 42);
|
||||
}
|
||||
|
||||
SUBCASE("array_index") {
|
||||
clazz_throw_dtor objs[2]{42, 21};
|
||||
|
||||
meta::uvalue v_ptr{objs};
|
||||
CHECK(v_ptr.get_type() == meta::resolve_type<clazz_throw_dtor*>());
|
||||
CHECK(v_ptr.get_as<clazz_throw_dtor*>() == objs);
|
||||
|
||||
meta::uvalue v = v_ptr[1];
|
||||
CHECK(v.get_type() == meta::resolve_type<clazz_throw_dtor>());
|
||||
CHECK(v.get_as<clazz_throw_dtor>().i == 21);
|
||||
}
|
||||
|
||||
SUBCASE("as_return_value") {
|
||||
meta::class_type clazz_throw_dtor_type = meta::resolve_type<clazz_throw_dtor>();
|
||||
meta::function clazz_throw_dtor_make_function = clazz_throw_dtor_type.get_function("make");
|
||||
|
||||
meta::uvalue v{clazz_throw_dtor_make_function(42)};
|
||||
CHECK(v.get_type() == meta::resolve_type<clazz_throw_dtor>());
|
||||
CHECK(v.get_as<clazz_throw_dtor>().i == 42);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("meta/meta_utilities/value5/inplace") {
|
||||
namespace meta = meta_hpp;
|
||||
|
||||
clazz_throw_dtor::destructor_counter = 0;
|
||||
clazz_throw_dtor::constructor_counter = 0;
|
||||
clazz_throw_dtor::move_constructor_counter = 0;
|
||||
clazz_throw_dtor::copy_constructor_counter = 0;
|
||||
|
||||
SUBCASE("def") {
|
||||
meta::uvalue v = meta::make_uvalue<clazz_throw_dtor>();
|
||||
CHECK(v.get_type() == meta::resolve_type<clazz_throw_dtor>());
|
||||
CHECK(v.get_as<clazz_throw_dtor>().i == 0);
|
||||
|
||||
CHECK(clazz_throw_dtor::destructor_counter == 0);
|
||||
CHECK(clazz_throw_dtor::constructor_counter == 1);
|
||||
CHECK(clazz_throw_dtor::move_constructor_counter == 0);
|
||||
CHECK(clazz_throw_dtor::copy_constructor_counter == 0);
|
||||
}
|
||||
|
||||
SUBCASE("args") {
|
||||
meta::uvalue v = meta::make_uvalue<std::vector<clazz_throw_dtor>>(2, 42);
|
||||
CHECK(v.get_type() == meta::resolve_type<std::vector<clazz_throw_dtor>>());
|
||||
|
||||
CHECK(v[0].get_type() == meta::resolve_type<clazz_throw_dtor>());
|
||||
CHECK(v[0].get_as<clazz_throw_dtor>().i == 42);
|
||||
|
||||
CHECK(v[1].get_type() == meta::resolve_type<clazz_throw_dtor>());
|
||||
CHECK(v[1].get_as<clazz_throw_dtor>().i == 42);
|
||||
}
|
||||
|
||||
SUBCASE("args/counters") {
|
||||
{
|
||||
meta::uvalue v = meta::make_uvalue<std::vector<clazz_throw_dtor>>(2, 42);
|
||||
CHECK(v.get_type() == meta::resolve_type<std::vector<clazz_throw_dtor>>());
|
||||
}
|
||||
CHECK(clazz_throw_dtor::destructor_counter == 3);
|
||||
CHECK(clazz_throw_dtor::constructor_counter == 1);
|
||||
CHECK(clazz_throw_dtor::move_constructor_counter == 0);
|
||||
CHECK(clazz_throw_dtor::copy_constructor_counter == 2);
|
||||
}
|
||||
|
||||
SUBCASE("ilist/1") {
|
||||
meta::uvalue v = meta::make_uvalue<std::vector<int>>({21, 42});
|
||||
CHECK(v.get_type() == meta::resolve_type<std::vector<int>>());
|
||||
|
||||
CHECK(v[0].get_type() == meta::resolve_type<int>());
|
||||
CHECK(v[0].get_as<int>() == 21);
|
||||
|
||||
CHECK(v[1].get_type() == meta::resolve_type<int>());
|
||||
CHECK(v[1].get_as<int>() == 42);
|
||||
}
|
||||
|
||||
SUBCASE("ilist/2") {
|
||||
meta::uvalue v = meta::make_uvalue<std::vector<int>>({21, 42}, std::allocator<int>{});
|
||||
CHECK(v.get_type() == meta::resolve_type<std::vector<int, std::allocator<int>>>());
|
||||
|
||||
CHECK(v[0].get_type() == meta::resolve_type<int>());
|
||||
CHECK(v[0].get_as<int>() == 21);
|
||||
|
||||
CHECK(v[1].get_type() == meta::resolve_type<int>());
|
||||
CHECK(v[1].get_as<int>() == 42);
|
||||
}
|
||||
|
||||
SUBCASE("ilist/counters") {
|
||||
{
|
||||
meta::uvalue v = meta::make_uvalue<std::vector<clazz_throw_dtor>>({
|
||||
clazz_throw_dtor{21},
|
||||
clazz_throw_dtor{42}});
|
||||
CHECK(v.get_type() == meta::resolve_type<std::vector<clazz_throw_dtor>>());
|
||||
}
|
||||
CHECK(clazz_throw_dtor::destructor_counter == 4);
|
||||
CHECK(clazz_throw_dtor::constructor_counter == 2);
|
||||
CHECK(clazz_throw_dtor::move_constructor_counter == 0);
|
||||
CHECK(clazz_throw_dtor::copy_constructor_counter == 2);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("meta/meta_utilities/value5/emplace") {
|
||||
namespace meta = meta_hpp;
|
||||
|
||||
clazz_throw_dtor::destructor_counter = 0;
|
||||
clazz_throw_dtor::constructor_counter = 0;
|
||||
clazz_throw_dtor::move_constructor_counter = 0;
|
||||
clazz_throw_dtor::copy_constructor_counter = 0;
|
||||
|
||||
SUBCASE("def") {
|
||||
{
|
||||
meta::uvalue v = meta::make_uvalue<clazz_throw_dtor>(21);
|
||||
CHECK(v.emplace<clazz_throw_dtor>().i == 0);
|
||||
CHECK(v.get_type() == meta::resolve_type<clazz_throw_dtor>());
|
||||
CHECK(v.get_as<clazz_throw_dtor>().i == 0);
|
||||
}
|
||||
CHECK(clazz_throw_dtor::destructor_counter == 2);
|
||||
CHECK(clazz_throw_dtor::constructor_counter == 2);
|
||||
CHECK(clazz_throw_dtor::move_constructor_counter == 0);
|
||||
CHECK(clazz_throw_dtor::copy_constructor_counter == 0);
|
||||
}
|
||||
|
||||
SUBCASE("args") {
|
||||
meta::uvalue v = meta::make_uvalue<clazz_throw_dtor>(21);
|
||||
v.emplace<std::vector<clazz_throw_dtor>>(2, 42);
|
||||
CHECK(v.get_type() == meta::resolve_type<std::vector<clazz_throw_dtor>>());
|
||||
|
||||
CHECK(v[0].get_type() == meta::resolve_type<clazz_throw_dtor>());
|
||||
CHECK(v[0].get_as<clazz_throw_dtor>().i == 42);
|
||||
|
||||
CHECK(v[1].get_type() == meta::resolve_type<clazz_throw_dtor>());
|
||||
CHECK(v[1].get_as<clazz_throw_dtor>().i == 42);
|
||||
}
|
||||
|
||||
SUBCASE("args/counters") {
|
||||
{
|
||||
meta::uvalue v = meta::make_uvalue<clazz_throw_dtor>(21);
|
||||
v.emplace<std::vector<clazz_throw_dtor>>(2, 42);
|
||||
CHECK(v.get_type() == meta::resolve_type<std::vector<clazz_throw_dtor>>());
|
||||
}
|
||||
CHECK(clazz_throw_dtor::destructor_counter == 4);
|
||||
CHECK(clazz_throw_dtor::constructor_counter == 2);
|
||||
CHECK(clazz_throw_dtor::move_constructor_counter == 0);
|
||||
CHECK(clazz_throw_dtor::copy_constructor_counter == 2);
|
||||
}
|
||||
|
||||
SUBCASE("ilist/1") {
|
||||
meta::uvalue v = meta::make_uvalue<clazz_throw_dtor>(84);
|
||||
v.emplace<std::vector<int>>({21, 42});
|
||||
CHECK(v.get_type() == meta::resolve_type<std::vector<int>>());
|
||||
|
||||
CHECK(v[0].get_type() == meta::resolve_type<int>());
|
||||
CHECK(v[0].get_as<int>() == 21);
|
||||
|
||||
CHECK(v[1].get_type() == meta::resolve_type<int>());
|
||||
CHECK(v[1].get_as<int>() == 42);
|
||||
}
|
||||
|
||||
SUBCASE("ilist/2") {
|
||||
meta::uvalue v = meta::make_uvalue<clazz_throw_dtor>(84);
|
||||
v.emplace<std::vector<int>>({21, 42}, std::allocator<int>{});
|
||||
CHECK(v.get_type() == meta::resolve_type<std::vector<int, std::allocator<int>>>());
|
||||
|
||||
CHECK(v[0].get_type() == meta::resolve_type<int>());
|
||||
CHECK(v[0].get_as<int>() == 21);
|
||||
|
||||
CHECK(v[1].get_type() == meta::resolve_type<int>());
|
||||
CHECK(v[1].get_as<int>() == 42);
|
||||
}
|
||||
|
||||
SUBCASE("ilist/counters") {
|
||||
{
|
||||
meta::uvalue v = meta::make_uvalue<clazz_throw_dtor>(84);
|
||||
v.emplace<std::vector<clazz_throw_dtor>>({
|
||||
clazz_throw_dtor{21},
|
||||
clazz_throw_dtor{42}});
|
||||
CHECK(v.get_type() == meta::resolve_type<std::vector<clazz_throw_dtor>>());
|
||||
}
|
||||
CHECK(clazz_throw_dtor::destructor_counter == 5);
|
||||
CHECK(clazz_throw_dtor::constructor_counter == 3);
|
||||
CHECK(clazz_throw_dtor::move_constructor_counter == 0);
|
||||
CHECK(clazz_throw_dtor::copy_constructor_counter == 2);
|
||||
}
|
||||
}
|
||||
573
develop/untests/meta_utilities/value_tests.cpp
Normal file
573
develop/untests/meta_utilities/value_tests.cpp
Normal file
@@ -0,0 +1,573 @@
|
||||
/*******************************************************************************
|
||||
* 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 "../meta_untests.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
struct ivec2 {
|
||||
int x{};
|
||||
int y{};
|
||||
|
||||
ivec2() = delete;
|
||||
|
||||
[[maybe_unused]] explicit ivec2(int nv): x{nv}, y{nv} {}
|
||||
[[maybe_unused]] ivec2(int nx, int ny): x{nx}, y{ny} {}
|
||||
|
||||
[[maybe_unused]] ivec2(ivec2&& other) noexcept
|
||||
: x{other.x}
|
||||
, y{other.y} {
|
||||
other.x = 0;
|
||||
other.y = 0;
|
||||
++move_constructor_counter;
|
||||
}
|
||||
|
||||
[[maybe_unused]] ivec2(const ivec2& other) noexcept
|
||||
: x{other.x}
|
||||
, y{other.y} {
|
||||
++copy_constructor_counter;
|
||||
}
|
||||
|
||||
ivec2& add(const ivec2& other) {
|
||||
x += other.x;
|
||||
y += other.y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ivec2& operator=(ivec2&& other) = delete;
|
||||
ivec2& operator=(const ivec2& other) = delete;
|
||||
public:
|
||||
static int move_constructor_counter;
|
||||
static int copy_constructor_counter;
|
||||
};
|
||||
|
||||
struct ivec3 {
|
||||
int x{};
|
||||
int y{};
|
||||
int z{};
|
||||
|
||||
ivec3() = delete;
|
||||
|
||||
[[maybe_unused]] explicit ivec3(int nv): x{nv}, y{nv}, z{nv} {}
|
||||
[[maybe_unused]] ivec3(int nx, int ny, int nz): x{nx}, y{ny}, z{nz} {}
|
||||
};
|
||||
|
||||
int ivec2::move_constructor_counter{0};
|
||||
int ivec2::copy_constructor_counter{0};
|
||||
|
||||
ivec2 iadd2(ivec2 l, ivec2 r) {
|
||||
return {l.x + r.x, l.y + r.y};
|
||||
}
|
||||
|
||||
[[maybe_unused]] bool operator<(const ivec2& l, const ivec2& r) noexcept {
|
||||
return (l.x < r.x) || (l.x == r.x && l.y < r.y);
|
||||
}
|
||||
|
||||
[[maybe_unused]] bool operator==(const ivec2& l, const ivec2& r) noexcept {
|
||||
return l.x == r.x && l.y == r.y;
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("meta/meta_utilities/value/ivec2") {
|
||||
namespace meta = meta_hpp;
|
||||
|
||||
meta::class_<ivec2>()
|
||||
.constructor_<int>()
|
||||
.constructor_<int, int>()
|
||||
.constructor_<ivec2&&>()
|
||||
.constructor_<const ivec2&>()
|
||||
.member_("x", &ivec2::x)
|
||||
.member_("y", &ivec2::y);
|
||||
}
|
||||
|
||||
TEST_CASE("meta/meta_utilities/value/ivec3") {
|
||||
namespace meta = meta_hpp;
|
||||
|
||||
meta::class_<ivec3>()
|
||||
.constructor_<int>()
|
||||
.constructor_<int, int, int>()
|
||||
.constructor_<ivec3&&>()
|
||||
.constructor_<const ivec3&>()
|
||||
.member_("x", &ivec3::x)
|
||||
.member_("y", &ivec3::y)
|
||||
.member_("z", &ivec3::z);
|
||||
}
|
||||
|
||||
TEST_CASE("meta/meta_utilities/value") {
|
||||
namespace meta = meta_hpp;
|
||||
using namespace std::string_literals;
|
||||
|
||||
ivec2::move_constructor_counter = 0;
|
||||
ivec2::copy_constructor_counter = 0;
|
||||
|
||||
SUBCASE("cast types") {
|
||||
static_assert(std::is_same_v<
|
||||
decltype(std::declval<meta::uvalue&>().get_as<ivec2>()),
|
||||
ivec2&>);
|
||||
static_assert(std::is_same_v<
|
||||
decltype(std::declval<meta::uvalue&&>().get_as<ivec2>()),
|
||||
ivec2&>);
|
||||
static_assert(std::is_same_v<
|
||||
decltype(std::declval<const meta::uvalue&>().get_as<ivec2>()),
|
||||
const ivec2&>);
|
||||
static_assert(std::is_same_v<
|
||||
decltype(std::declval<const meta::uvalue&&>().get_as<ivec2>()),
|
||||
const ivec2&>);
|
||||
}
|
||||
|
||||
SUBCASE("ivec2{}") {
|
||||
{
|
||||
meta::uvalue val{};
|
||||
|
||||
CHECK(!val);
|
||||
CHECK_FALSE(val);
|
||||
|
||||
CHECK_FALSE(val.is_valid());
|
||||
CHECK(val.data() == nullptr);
|
||||
CHECK(std::as_const(val).data() == nullptr);
|
||||
CHECK(std::as_const(val).cdata() == nullptr);
|
||||
|
||||
CHECK_FALSE(*val);
|
||||
CHECK_FALSE(val[0]);
|
||||
|
||||
CHECK_FALSE(val.try_get_as<ivec2>());
|
||||
CHECK_FALSE(std::as_const(val).try_get_as<ivec2>());
|
||||
|
||||
CHECK_THROWS(std::ignore = val.get_as<int>());
|
||||
CHECK_THROWS(std::ignore = std::as_const(val).get_as<int>());
|
||||
CHECK_THROWS(std::ignore = std::move(val).get_as<int>());
|
||||
CHECK_THROWS(std::ignore = std::move(std::as_const(val)).get_as<int>());
|
||||
}
|
||||
|
||||
{
|
||||
CHECK_FALSE(1 < meta::uvalue{});
|
||||
CHECK(meta::uvalue{} < 1);
|
||||
}
|
||||
|
||||
{
|
||||
CHECK_FALSE(1 == meta::uvalue{});
|
||||
CHECK_FALSE(meta::uvalue{} == 1);
|
||||
}
|
||||
|
||||
{
|
||||
CHECK(1 != meta::uvalue{});
|
||||
CHECK(meta::uvalue{} != 1);
|
||||
}
|
||||
|
||||
CHECK_FALSE(meta::uvalue{} == 0);
|
||||
CHECK_FALSE(meta::uvalue{} == nullptr);
|
||||
CHECK(meta::uvalue{}.get_type() == meta::resolve_type<void>());
|
||||
}
|
||||
|
||||
SUBCASE("ivec2&") {
|
||||
ivec2 v{1,2};
|
||||
ivec2& vr = v;
|
||||
|
||||
meta::uvalue val{vr};
|
||||
CHECK(ivec2::move_constructor_counter == 0);
|
||||
CHECK(ivec2::copy_constructor_counter == 1);
|
||||
|
||||
CHECK(val.get_type() == meta::resolve_type<ivec2>());
|
||||
|
||||
CHECK(*static_cast<const ivec2*>(val.data()) == vr);
|
||||
CHECK(*static_cast<const ivec2*>(val.cdata()) == vr);
|
||||
CHECK(*static_cast<const ivec2*>(std::as_const(val).data()) == vr);
|
||||
CHECK(*static_cast<const ivec2*>(std::as_const(val).cdata()) == vr);
|
||||
|
||||
CHECK(val == ivec2{1,2});
|
||||
|
||||
CHECK(val.get_as<ivec2>() == ivec2{1,2});
|
||||
CHECK(std::as_const(val).get_as<ivec2>() == ivec2{1,2});
|
||||
CHECK(std::move(val).get_as<ivec2>() == ivec2{1,2});
|
||||
CHECK(std::move(std::as_const(val)).get_as<ivec2>() == ivec2{1,2});
|
||||
|
||||
CHECK_THROWS(std::ignore = val.get_as<ivec3>());
|
||||
CHECK_THROWS(std::ignore = std::as_const(val).get_as<ivec3>());
|
||||
CHECK_THROWS(std::ignore = std::move(val).get_as<ivec3>());
|
||||
CHECK_THROWS(std::ignore = std::move(std::as_const(val)).get_as<ivec3>());
|
||||
|
||||
CHECK(val.get_as<ivec2>() == ivec2{1,2});
|
||||
CHECK(std::as_const(val).get_as<ivec2>() == ivec2{1,2});
|
||||
CHECK_FALSE(val.try_get_as<ivec3>());
|
||||
CHECK_FALSE(std::as_const(val).try_get_as<ivec3>());
|
||||
}
|
||||
|
||||
SUBCASE("const ivec2&") {
|
||||
const ivec2 v{1,2};
|
||||
const ivec2& vr = v;
|
||||
|
||||
meta::uvalue val{vr};
|
||||
CHECK(ivec2::move_constructor_counter == 0);
|
||||
CHECK(ivec2::copy_constructor_counter == 1);
|
||||
|
||||
CHECK(val.get_type() == meta::resolve_type<ivec2>());
|
||||
|
||||
CHECK(*static_cast<const ivec2*>(val.data()) == vr);
|
||||
CHECK(*static_cast<const ivec2*>(val.cdata()) == vr);
|
||||
CHECK(*static_cast<const ivec2*>(std::as_const(val).data()) == vr);
|
||||
CHECK(*static_cast<const ivec2*>(std::as_const(val).cdata()) == vr);
|
||||
|
||||
CHECK(val == ivec2{1,2});
|
||||
|
||||
CHECK(val.get_as<ivec2>() == ivec2{1,2});
|
||||
CHECK(std::as_const(val).get_as<ivec2>() == ivec2{1,2});
|
||||
CHECK(std::move(val).get_as<ivec2>() == ivec2{1,2});
|
||||
CHECK(std::move(std::as_const(val)).get_as<ivec2>() == ivec2{1,2});
|
||||
|
||||
CHECK_THROWS(std::ignore = val.get_as<ivec3>());
|
||||
CHECK_THROWS(std::ignore = std::as_const(val).get_as<ivec3>());
|
||||
CHECK_THROWS(std::ignore = std::move(val).get_as<ivec3>());
|
||||
CHECK_THROWS(std::ignore = std::move(std::as_const(val)).get_as<ivec3>());
|
||||
|
||||
CHECK(val.get_as<ivec2>() == ivec2{1,2});
|
||||
CHECK(std::as_const(val).get_as<ivec2>() == ivec2{1,2});
|
||||
CHECK_FALSE(val.try_get_as<ivec3>());
|
||||
CHECK_FALSE(std::as_const(val).try_get_as<ivec3>());
|
||||
}
|
||||
|
||||
SUBCASE("ivec2&&") {
|
||||
ivec2 v{1,2};
|
||||
|
||||
meta::uvalue val{std::move(v)};
|
||||
CHECK(ivec2::move_constructor_counter == 1);
|
||||
CHECK(ivec2::copy_constructor_counter == 0);
|
||||
|
||||
CHECK(val.get_type() == meta::resolve_type<ivec2>());
|
||||
|
||||
CHECK(val == ivec2{1,2});
|
||||
|
||||
CHECK(val.get_as<ivec2>() == ivec2{1,2});
|
||||
CHECK(std::as_const(val).get_as<ivec2>() == ivec2{1,2});
|
||||
CHECK(std::move(val).get_as<ivec2>() == ivec2{1,2});
|
||||
CHECK(std::move(std::as_const(val)).get_as<ivec2>() == ivec2{1,2});
|
||||
|
||||
CHECK_THROWS(std::ignore = val.get_as<ivec3>());
|
||||
CHECK_THROWS(std::ignore = std::as_const(val).get_as<ivec3>());
|
||||
CHECK_THROWS(std::ignore = std::move(val).get_as<ivec3>());
|
||||
CHECK_THROWS(std::ignore = std::move(std::as_const(val)).get_as<ivec3>());
|
||||
|
||||
CHECK(val.get_as<ivec2>() == ivec2{1,2});
|
||||
CHECK(std::as_const(val).get_as<ivec2>() == ivec2{1,2});
|
||||
CHECK_FALSE(val.try_get_as<ivec3>());
|
||||
CHECK_FALSE(std::as_const(val).try_get_as<ivec3>());
|
||||
}
|
||||
|
||||
SUBCASE("const ivec2&&") {
|
||||
const ivec2 v{1,2};
|
||||
|
||||
meta::uvalue val{std::move(v)};
|
||||
CHECK(ivec2::move_constructor_counter == 0);
|
||||
CHECK(ivec2::copy_constructor_counter == 1);
|
||||
|
||||
CHECK(val.get_type() == meta::resolve_type<ivec2>());
|
||||
|
||||
CHECK(val == ivec2{1,2});
|
||||
|
||||
CHECK(val.get_as<ivec2>() == ivec2{1,2});
|
||||
CHECK(std::as_const(val).get_as<ivec2>() == ivec2{1,2});
|
||||
CHECK(std::move(val).get_as<ivec2>() == ivec2{1,2});
|
||||
CHECK(std::move(std::as_const(val)).get_as<ivec2>() == ivec2{1,2});
|
||||
|
||||
CHECK_THROWS(std::ignore = val.get_as<ivec3>());
|
||||
CHECK_THROWS(std::ignore = std::as_const(val).get_as<ivec3>());
|
||||
CHECK_THROWS(std::ignore = std::move(val).get_as<ivec3>());
|
||||
CHECK_THROWS(std::ignore = std::move(std::as_const(val)).get_as<ivec3>());
|
||||
|
||||
CHECK(val.get_as<ivec2>() == ivec2{1,2});
|
||||
CHECK(std::as_const(val).get_as<ivec2>() == ivec2{1,2});
|
||||
CHECK_FALSE(val.try_get_as<ivec3>());
|
||||
CHECK_FALSE(std::as_const(val).try_get_as<ivec3>());
|
||||
}
|
||||
|
||||
SUBCASE("value(value&&)") {
|
||||
ivec2 v{1,2};
|
||||
meta::uvalue val_src{std::move(v)};
|
||||
CHECK(ivec2::move_constructor_counter == 1);
|
||||
CHECK(ivec2::copy_constructor_counter == 0);
|
||||
|
||||
meta::uvalue val_dst{std::move(val_src)};
|
||||
CHECK(val_dst == ivec2{1,2});
|
||||
CHECK(ivec2::move_constructor_counter == 2);
|
||||
CHECK(ivec2::copy_constructor_counter == 0);
|
||||
}
|
||||
|
||||
SUBCASE("value(const meta::value&)") {
|
||||
const ivec2 v{1,2};
|
||||
meta::uvalue val_src{v};
|
||||
CHECK(ivec2::move_constructor_counter == 0);
|
||||
CHECK(ivec2::copy_constructor_counter == 1);
|
||||
|
||||
meta::uvalue val_dst{val_src};
|
||||
CHECK(val_dst == ivec2{1,2});
|
||||
CHECK(ivec2::move_constructor_counter == 0);
|
||||
CHECK(ivec2::copy_constructor_counter == 2);
|
||||
|
||||
CHECK(val_src == ivec2{1,2});
|
||||
CHECK(val_src.data() != val_dst.data());
|
||||
}
|
||||
|
||||
SUBCASE("value& operator=(T&&)") {
|
||||
meta::uvalue val{10};
|
||||
|
||||
val = 20;
|
||||
CHECK(val == 20);
|
||||
|
||||
val = "hello"s;
|
||||
CHECK(val == "hello"s);
|
||||
}
|
||||
|
||||
SUBCASE("value& operator=(value&&)") {
|
||||
meta::uvalue val_src1{"world"s};
|
||||
meta::uvalue val_src2{ivec2{1,2}};
|
||||
CHECK(ivec2::move_constructor_counter == 1);
|
||||
CHECK(ivec2::copy_constructor_counter == 0);
|
||||
|
||||
meta::uvalue val_dst{"hello"s};
|
||||
|
||||
val_dst = std::move(val_src1);
|
||||
CHECK(val_dst == "world"s);
|
||||
CHECK(ivec2::move_constructor_counter == 1);
|
||||
CHECK(ivec2::copy_constructor_counter == 0);
|
||||
|
||||
val_dst = std::move(val_src2);
|
||||
CHECK(val_dst == ivec2{1,2});
|
||||
CHECK(ivec2::move_constructor_counter == 3);
|
||||
CHECK(ivec2::copy_constructor_counter == 0);
|
||||
}
|
||||
|
||||
SUBCASE("value& operator=(const meta::value&)") {
|
||||
meta::uvalue val_src1{"world"s};
|
||||
meta::uvalue val_src2{ivec2{1,2}};
|
||||
CHECK(ivec2::move_constructor_counter == 1);
|
||||
CHECK(ivec2::copy_constructor_counter == 0);
|
||||
|
||||
meta::uvalue val_dst{"hello"s};
|
||||
|
||||
val_dst = val_src1;
|
||||
CHECK(val_dst == "world"s);
|
||||
CHECK(ivec2::move_constructor_counter == 1);
|
||||
CHECK(ivec2::copy_constructor_counter == 0);
|
||||
|
||||
val_dst = val_src2;
|
||||
CHECK(val_dst == ivec2{1,2});
|
||||
CHECK(ivec2::move_constructor_counter == 2);
|
||||
CHECK(ivec2::copy_constructor_counter == 1);
|
||||
|
||||
CHECK(val_src2 == ivec2{1,2});
|
||||
CHECK(val_src2.data() != val_dst.data());
|
||||
}
|
||||
|
||||
SUBCASE("swap") {
|
||||
meta::uvalue val1{"world"s};
|
||||
meta::uvalue val2{ivec2{1,2}};
|
||||
CHECK(ivec2::move_constructor_counter == 1);
|
||||
CHECK(ivec2::copy_constructor_counter == 0);
|
||||
|
||||
val1.swap(val2);
|
||||
CHECK(val1 == ivec2{1,2});
|
||||
CHECK(val2 == "world"s);
|
||||
CHECK(ivec2::move_constructor_counter == 2);
|
||||
CHECK(ivec2::copy_constructor_counter == 0);
|
||||
|
||||
swap(val1, val2);
|
||||
CHECK(val1 == "world"s);
|
||||
CHECK(val2 == ivec2{1,2});
|
||||
}
|
||||
|
||||
SUBCASE("ostream") {
|
||||
std::stringstream str_stream;
|
||||
CHECK_NOTHROW(str_stream << meta::uvalue{21} << " " << meta::uvalue{42});
|
||||
CHECK_THROWS((str_stream << meta::uvalue{ivec2{1,2}}));
|
||||
REQUIRE(str_stream.str() == "21 42");
|
||||
}
|
||||
|
||||
SUBCASE("istream") {
|
||||
std::stringstream str_stream{"21 42"};
|
||||
|
||||
meta::uvalue v{ivec2{1,2}};
|
||||
CHECK_THROWS(str_stream >> v);
|
||||
|
||||
v = meta::uvalue{0};
|
||||
CHECK_NOTHROW(str_stream >> v);
|
||||
CHECK(v == 21);
|
||||
CHECK_NOTHROW(str_stream >> v);
|
||||
CHECK(v == 42);
|
||||
}
|
||||
|
||||
SUBCASE("operator<") {
|
||||
CHECK(meta::uvalue{ivec2{1,2}} < ivec2{1,3});
|
||||
CHECK_FALSE(meta::uvalue{ivec2{1,3}} < ivec2{1,2});
|
||||
|
||||
CHECK(ivec2{1,2} < meta::uvalue{ivec2{1,3}});
|
||||
CHECK_FALSE(ivec2{1,3} < meta::uvalue{ivec2{1,2}});
|
||||
}
|
||||
|
||||
SUBCASE("operator==") {
|
||||
CHECK(meta::uvalue{ivec2{1,2}} == ivec2{1,2});
|
||||
CHECK_FALSE(meta::uvalue{ivec2{1,2}} == ivec2{1,3});
|
||||
|
||||
CHECK(ivec2{1,2} == meta::uvalue{ivec2{1,2}});
|
||||
CHECK_FALSE(ivec2{1,3} == meta::uvalue{ivec2{1,2}});
|
||||
}
|
||||
|
||||
SUBCASE("deref") {
|
||||
{
|
||||
int i{42};
|
||||
const meta::uvalue v{*meta::uvalue{&i}};
|
||||
CHECK(v.get_type() == meta::resolve_type<int>());
|
||||
CHECK(v.data() != &i);
|
||||
}
|
||||
{
|
||||
const char i{42};
|
||||
const meta::uvalue v{*meta::uvalue{&i}};
|
||||
CHECK(v.get_type() == meta::resolve_type<char>());
|
||||
CHECK(v.data() != &i);
|
||||
}
|
||||
{
|
||||
const int i{42};
|
||||
const int* const pi = &i;
|
||||
const meta::uvalue v{*meta::uvalue{&pi}};
|
||||
CHECK(v.get_type() == meta::resolve_type<const int*>() );
|
||||
CHECK(v.get_as<const int*>() == pi);
|
||||
}
|
||||
{
|
||||
int i{42};
|
||||
|
||||
void* p1 = &i;
|
||||
const void* p2 = &i;
|
||||
void* const& p3 = &i;
|
||||
const void* const& p4 = &i;
|
||||
|
||||
CHECK_THROWS(std::ignore = *meta::uvalue(p1));
|
||||
CHECK_THROWS(std::ignore = *meta::uvalue(p2));
|
||||
CHECK_THROWS(std::ignore = *meta::uvalue(p3));
|
||||
CHECK_THROWS(std::ignore = *meta::uvalue(p4));
|
||||
}
|
||||
{
|
||||
ivec2 v{1,2};
|
||||
meta::uvalue vp{&v};
|
||||
CHECK(ivec2::move_constructor_counter == 0);
|
||||
CHECK(ivec2::copy_constructor_counter == 0);
|
||||
|
||||
[[maybe_unused]] meta::uvalue vv1{*vp};
|
||||
CHECK((ivec2::move_constructor_counter == 0 || ivec2::move_constructor_counter == 1 || ivec2::move_constructor_counter == 2));
|
||||
CHECK(ivec2::copy_constructor_counter == 1);
|
||||
|
||||
[[maybe_unused]] meta::uvalue vv2{*std::move(vp)};
|
||||
CHECK((ivec2::move_constructor_counter == 0 || ivec2::move_constructor_counter == 2 || ivec2::move_constructor_counter == 4));
|
||||
CHECK(ivec2::copy_constructor_counter == 2);
|
||||
|
||||
[[maybe_unused]] meta::uvalue vv3{*std::as_const(vp)};
|
||||
CHECK((ivec2::move_constructor_counter == 0 || ivec2::move_constructor_counter == 3 || ivec2::move_constructor_counter == 6));
|
||||
CHECK(ivec2::copy_constructor_counter == 3);
|
||||
}
|
||||
{
|
||||
meta::uvalue v{std::make_shared<int>(42)};
|
||||
CHECK(*v == 42);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("meta/meta_utilities/value/arrays") {
|
||||
namespace meta = meta_hpp;
|
||||
|
||||
SUBCASE("int[3]") {
|
||||
int arr[3]{1,2,3};
|
||||
meta::uvalue v{arr};
|
||||
CHECK(v.get_type() == meta::resolve_type<int*>());
|
||||
CHECK(v[0] == 1);
|
||||
CHECK(v[1] == 2);
|
||||
CHECK(v[2] == 3);
|
||||
}
|
||||
|
||||
SUBCASE("const int[3]") {
|
||||
const int arr[3]{1,2,3};
|
||||
meta::uvalue v{arr};
|
||||
CHECK(v.get_type() == meta::resolve_type<const int*>());
|
||||
CHECK(v[0] == 1);
|
||||
CHECK(v[1] == 2);
|
||||
CHECK(v[2] == 3);
|
||||
}
|
||||
|
||||
SUBCASE("std::array") {
|
||||
meta::uvalue v{std::array{1,2,3}};
|
||||
CHECK(v.get_type() == meta::resolve_type<std::array<int, 3>>());
|
||||
CHECK(v[0] == 1);
|
||||
CHECK(v[1] == 2);
|
||||
CHECK(v[2] == 3);
|
||||
}
|
||||
|
||||
SUBCASE("std::string") {
|
||||
meta::uvalue v{std::string{"hi!"}};
|
||||
CHECK(v.get_type() == meta::resolve_type<std::string>());
|
||||
CHECK(v[0] == 'h');
|
||||
CHECK(v[1] == 'i');
|
||||
CHECK(v[2] == '!');
|
||||
}
|
||||
|
||||
SUBCASE("std::span") {
|
||||
std::vector arr{1,2,3};
|
||||
meta::uvalue v{std::span{arr}};
|
||||
CHECK(v.get_type() == meta::resolve_type<std::span<int>>());
|
||||
CHECK(v[0] == 1);
|
||||
CHECK(v[1] == 2);
|
||||
CHECK(v[2] == 3);
|
||||
}
|
||||
|
||||
SUBCASE("std::vector") {
|
||||
const meta::uvalue v{std::vector{1,2,3}};
|
||||
CHECK(v.get_type() == meta::resolve_type<std::vector<int>>());
|
||||
CHECK(v[0] == 1);
|
||||
CHECK(v[1] == 2);
|
||||
CHECK(v[2] == 3);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("meta/meta_utilities/value/functions") {
|
||||
namespace meta = meta_hpp;
|
||||
|
||||
SUBCASE("add") {
|
||||
{
|
||||
meta::uvalue v{&ivec2::add};
|
||||
CHECK(v.get_type() == meta::resolve_type<ivec2&(ivec2::*)(const ivec2&)>());
|
||||
CHECK(v.get_as<decltype(&ivec2::add)>() == &ivec2::add);
|
||||
CHECK((ivec2{1,2}.*(v.get_as<decltype(&ivec2::add)>()))(ivec2{3,4}) == ivec2(4,6));
|
||||
}
|
||||
{
|
||||
const meta::uvalue v{&ivec2::add};
|
||||
CHECK(v.get_type() == meta::resolve_type<ivec2&(ivec2::*)(const ivec2&)>());
|
||||
CHECK(v.get_as<decltype(&ivec2::add)>() == &ivec2::add);
|
||||
CHECK((ivec2{1,2}.*(v.get_as<decltype(&ivec2::add)>()))(ivec2{3,4}) == ivec2(4,6));
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("iadd2") {
|
||||
{
|
||||
meta::uvalue v{iadd2};
|
||||
CHECK(v.get_type() == meta::resolve_type<ivec2(*)(ivec2, ivec2)>());
|
||||
CHECK((v.get_as<decltype(&iadd2)>() == &iadd2));
|
||||
CHECK((v.get_as<decltype(&iadd2)>())(ivec2{1,2}, ivec2{3,4}) == ivec2{4,6});
|
||||
}
|
||||
{
|
||||
meta::uvalue v{&iadd2};
|
||||
CHECK(v.get_type() == meta::resolve_type<ivec2(*)(ivec2, ivec2)>());
|
||||
CHECK((v.get_as<decltype(&iadd2)>() == &iadd2));
|
||||
CHECK((v.get_as<decltype(&iadd2)>())(ivec2{1,2}, ivec2{3,4}) == ivec2{4,6});
|
||||
}
|
||||
{
|
||||
const meta::uvalue v{iadd2};
|
||||
CHECK(v.get_type() == meta::resolve_type<ivec2(*)(ivec2, ivec2)>());
|
||||
CHECK((v.get_as<decltype(&iadd2)>() == &iadd2));
|
||||
CHECK((v.get_as<decltype(&iadd2)>())(ivec2{1,2}, ivec2{3,4}) == ivec2{4,6});
|
||||
}
|
||||
{
|
||||
const meta::uvalue v{&iadd2};
|
||||
CHECK(v.get_type() == meta::resolve_type<ivec2(*)(ivec2, ivec2)>());
|
||||
CHECK((v.get_as<decltype(&iadd2)>() == &iadd2));
|
||||
CHECK((v.get_as<decltype(&iadd2)>())(ivec2{1,2}, ivec2{3,4}) == ivec2{4,6});
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user