mirror of
https://github.com/BlackMATov/meta.hpp.git
synced 2025-12-16 22:17:02 +07:00
139 lines
4.9 KiB
C++
139 lines
4.9 KiB
C++
/*******************************************************************************
|
|
* This file is part of the "https://github.com/blackmatov/meta.hpp"
|
|
* For conditions of distribution and use, see copyright notice in LICENSE.md
|
|
* Copyright (C) 2021, by Matvey Cherevko (blackmatov@gmail.com)
|
|
******************************************************************************/
|
|
|
|
#include <meta.hpp/meta_class.hpp>
|
|
#include <meta.hpp/meta_ctor.hpp>
|
|
|
|
#include "doctest/doctest.hpp"
|
|
|
|
namespace
|
|
{
|
|
class clazz {
|
|
public:
|
|
int v1{1};
|
|
int v2{2};
|
|
|
|
clazz() = default;
|
|
clazz(int v): v1{v}, v2{v} {}
|
|
clazz(int v1, int v2): v1{v1}, v2{v2} {}
|
|
};
|
|
}
|
|
|
|
TEST_CASE("meta/ctor") {
|
|
namespace meta = meta_hpp;
|
|
|
|
const meta::ctor_info ctor0 = meta::ctor_<>().make_info<clazz>();
|
|
const meta::ctor_info ctor1 = meta::ctor_<int>().make_info<clazz>();
|
|
const meta::ctor_info ctor2 = meta::ctor_<int, int>().make_info<clazz>();
|
|
|
|
SUBCASE("arity") {
|
|
CHECK(ctor0.arity() == 0u);
|
|
CHECK(ctor1.arity() == 1u);
|
|
CHECK(ctor2.arity() == 2u);
|
|
}
|
|
|
|
SUBCASE("return_type") {
|
|
CHECK(ctor0.return_type() == meta::get_family_id<clazz>());
|
|
CHECK(ctor1.return_type() == meta::get_family_id<clazz>());
|
|
CHECK(ctor2.return_type() == meta::get_family_id<clazz>());
|
|
}
|
|
|
|
SUBCASE("argument_types") {
|
|
CHECK_FALSE(ctor0.argument_type(0u));
|
|
|
|
CHECK(ctor1.argument_type(0u) == meta::get_family_id<int>());
|
|
CHECK_FALSE(ctor1.argument_type(1u));
|
|
|
|
CHECK(ctor2.argument_type(0u) == meta::get_family_id<int>());
|
|
CHECK(ctor2.argument_type(1u) == meta::get_family_id<int>());
|
|
CHECK_FALSE(ctor2.argument_type(2u));
|
|
}
|
|
|
|
SUBCASE("invoke0") {
|
|
CHECK(ctor0().cast<const clazz&>().v1 == 1);
|
|
CHECK(ctor0().cast<const clazz&>().v2 == 2);
|
|
CHECK_THROWS_AS(ctor0(1), std::logic_error);
|
|
|
|
CHECK(ctor0.invoke().cast<const clazz&>().v1 == 1);
|
|
CHECK(ctor0.invoke().cast<const clazz&>().v2 == 2);
|
|
CHECK_THROWS_AS(ctor0.invoke(1), std::logic_error);
|
|
|
|
CHECK(ctor0.invoke_r<const clazz&>().v1 == 1);
|
|
CHECK(ctor0.invoke_r<const clazz&>().v2 == 2);
|
|
CHECK_THROWS_AS(ctor0.invoke_r<const clazz&>(1), std::logic_error);
|
|
}
|
|
|
|
SUBCASE("invoke1") {
|
|
CHECK(ctor1(42).cast<const clazz&>().v1 == 42);
|
|
CHECK(ctor1(42).cast<const clazz&>().v2 == 42);
|
|
CHECK_THROWS_AS(ctor1(), std::logic_error);
|
|
CHECK_THROWS_AS(ctor1(1,1), std::logic_error);
|
|
|
|
CHECK(ctor1.invoke(42).cast<const clazz&>().v1 == 42);
|
|
CHECK(ctor1.invoke(42).cast<const clazz&>().v2 == 42);
|
|
CHECK_THROWS_AS(ctor1.invoke(), std::logic_error);
|
|
CHECK_THROWS_AS(ctor1.invoke(1,1), std::logic_error);
|
|
|
|
CHECK(ctor1.invoke_r<const clazz&>(42).v1 == 42);
|
|
CHECK(ctor1.invoke_r<const clazz&>(42).v2 == 42);
|
|
CHECK_THROWS_AS(ctor1.invoke_r<const clazz&>(), std::logic_error);
|
|
CHECK_THROWS_AS(ctor1.invoke_r<const clazz&>(1,1), std::logic_error);
|
|
}
|
|
|
|
SUBCASE("invoke2") {
|
|
CHECK(ctor2(21,42).cast<const clazz&>().v1 == 21);
|
|
CHECK(ctor2(21,42).cast<const clazz&>().v2 == 42);
|
|
CHECK_THROWS_AS(ctor2(), std::logic_error);
|
|
CHECK_THROWS_AS(ctor2(1), std::logic_error);
|
|
CHECK_THROWS_AS(ctor2(1,1,1), std::logic_error);
|
|
|
|
CHECK(ctor2.invoke(21,42).cast<const clazz&>().v1 == 21);
|
|
CHECK(ctor2.invoke(21,42).cast<const clazz&>().v2 == 42);
|
|
CHECK_THROWS_AS(ctor2.invoke(), std::logic_error);
|
|
CHECK_THROWS_AS(ctor2.invoke(1), std::logic_error);
|
|
CHECK_THROWS_AS(ctor2.invoke(1,1,1), std::logic_error);
|
|
|
|
CHECK(ctor2.invoke_r<const clazz&>(21,42).v1 == 21);
|
|
CHECK(ctor2.invoke_r<const clazz&>(21,42).v2 == 42);
|
|
CHECK_THROWS_AS(ctor2.invoke_r<const clazz&>(), std::logic_error);
|
|
CHECK_THROWS_AS(ctor2.invoke_r<const clazz&>(1), std::logic_error);
|
|
CHECK_THROWS_AS(ctor2.invoke_r<const clazz&>(1,1,1), std::logic_error);
|
|
}
|
|
|
|
SUBCASE("is_invocable") {
|
|
CHECK(ctor0.is_invocable<>());
|
|
CHECK_FALSE(ctor0.is_invocable<int>());
|
|
|
|
CHECK(ctor1.is_invocable<int>());
|
|
CHECK_FALSE(ctor1.is_invocable<float>());
|
|
CHECK_FALSE(ctor1.is_invocable<>());
|
|
CHECK_FALSE(ctor1.is_invocable<int, int>());
|
|
|
|
CHECK(ctor2.is_invocable<int, int>());
|
|
CHECK_FALSE(ctor2.is_invocable<int, float>());
|
|
CHECK_FALSE(ctor2.is_invocable<>());
|
|
CHECK_FALSE(ctor2.is_invocable<int>());
|
|
}
|
|
}
|
|
|
|
TEST_CASE("meta/ctor/class") {
|
|
namespace meta = meta_hpp;
|
|
|
|
const meta::class_info clazz_info = meta::class_<clazz>("clazz")(
|
|
meta::ctor_<>(),
|
|
meta::ctor_<int>(),
|
|
meta::ctor_<int, int>()
|
|
).make_info();
|
|
|
|
CHECK(clazz_info.get_ctor<>());
|
|
CHECK(clazz_info.get_ctor<int>());
|
|
CHECK(clazz_info.get_ctor<int, int>());
|
|
|
|
CHECK_FALSE(clazz_info.get_ctor<float>());
|
|
CHECK_FALSE(clazz_info.get_ctor<int, float>());
|
|
CHECK_FALSE(clazz_info.get_ctor<int, int, int>());
|
|
}
|