invoke syntactic sugar

This commit is contained in:
BlackMATov
2021-07-13 13:19:09 +07:00
parent 2ea9a01f32
commit 6677514faf
11 changed files with 263 additions and 35 deletions

View File

@@ -103,7 +103,7 @@ namespace meta_hpp
template < typename... Args >
std::optional<ctor_info> get_ctor() const {
for ( auto&& family_info : ctors_ ) {
if ( family_info.second.is_invocable_with<Args...>() ) {
if ( family_info.second.is_invocable<Args...>() ) {
return family_info.second;
}
}

View File

@@ -131,8 +131,18 @@ namespace meta_hpp
}
}
template < typename R, typename... Args >
R invoke_r(Args&&... args) const {
return invoke(std::forward<Args>(args)...).template cast<R>();
}
template < typename... Args >
bool is_invocable_with() const noexcept {
value operator()(Args&&... args) const {
return invoke(std::forward<Args>(args)...);
}
template < typename... Args >
bool is_invocable() const noexcept {
return ctor_detail::parameters_equal<Args...>(argument_types_);
}

View File

@@ -122,9 +122,23 @@ namespace meta_hpp
return getter_(instance);
}
template < typename R >
R get_r(cinstance instance) const {
return get(instance).cast<R>();
}
template < typename Value >
void set(instance instance, Value&& value) const {
return setter_(instance, std::forward<Value>(value));
setter_(instance, std::forward<Value>(value));
}
value operator()(cinstance instance) const {
return get(instance);
}
template < typename Value >
void operator()(instance instance, Value&& value) const {
set(instance, std::forward<Value>(value));
}
template < typename F >

View File

@@ -134,6 +134,19 @@ namespace meta_hpp
}
}
template < typename R, typename... Args >
std::optional<R> invoke_r(Args&&... args) const {
if ( std::optional<value> r = invoke(std::forward<Args>(args)...) ) {
return std::move(r)->template cast<R>();
}
return std::nullopt;
}
template < typename... Args >
std::optional<value> operator()(Args&&... args) const {
return invoke(std::forward<Args>(args)...);
}
template < typename F >
void each_data(F&& f) const {
for ( auto&& id_info : datas_ ) {

View File

@@ -208,20 +208,31 @@ namespace meta_hpp
std::optional<value> invoke(T& inst, Args&&... args) const {
if constexpr ( sizeof...(Args) > 0u ) {
std::array<value, sizeof...(Args)> vargs{std::forward<Args>(args)...};
if constexpr ( std::is_const_v<T> ) {
return cinvoke_(inst, vargs.data(), vargs.size());
} else {
return invoke_(inst, vargs.data(), vargs.size());
}
} else {
if constexpr ( std::is_const_v<T> ) {
return cinvoke_(inst, nullptr, 0u);
} else {
return invoke_(inst, nullptr, 0u);
}
}
}
template < typename R, typename T, typename... Args >
std::optional<R> invoke_r(T& inst, Args&&... args) const {
if ( std::optional<value> r = invoke(inst, std::forward<Args>(args)...) ) {
return std::move(r)->template cast<R>();
}
return std::nullopt;
}
template < typename T, typename... Args >
std::optional<value> invoke(const T& inst, Args&&... args) const {
if constexpr ( sizeof...(Args) > 0u ) {
std::array<value, sizeof...(Args)> vargs{std::forward<Args>(args)...};
return cinvoke_(inst, vargs.data(), vargs.size());
} else {
return cinvoke_(inst, nullptr, 0u);
}
std::optional<value> operator()(T& inst, Args&&... args) const {
return invoke(inst, std::forward<Args>(args)...);
}
template < typename F >

View File

@@ -96,11 +96,25 @@ namespace meta_hpp
return getter_();
}
template < typename R >
R get_r() const {
return get().cast<R>();
}
template < typename Value >
void set(Value&& value) const {
return setter_(std::forward<Value>(value));
}
value operator()() const {
return get();
}
template < typename Value >
void operator()(Value&& value) const {
return set(std::forward<Value>(value));
}
template < typename F >
void each_data(F&& f) const {
for ( auto&& id_info : datas_ ) {

View File

@@ -53,39 +53,69 @@ TEST_CASE("meta/ctor") {
}
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_with") {
CHECK(ctor0.is_invocable_with<>());
CHECK_FALSE(ctor0.is_invocable_with<int>());
SUBCASE("is_invocable") {
CHECK(ctor0.is_invocable<>());
CHECK_FALSE(ctor0.is_invocable<int>());
CHECK(ctor1.is_invocable_with<int>());
CHECK_FALSE(ctor1.is_invocable_with<float>());
CHECK_FALSE(ctor1.is_invocable_with<>());
CHECK_FALSE(ctor1.is_invocable_with<int, 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_with<int, int>());
CHECK_FALSE(ctor2.is_invocable_with<int, float>());
CHECK_FALSE(ctor2.is_invocable_with<>());
CHECK_FALSE(ctor2.is_invocable_with<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>());
}
}

View File

@@ -37,14 +37,24 @@ TEST_CASE("meta/field") {
clazz instance;
CHECK(instance.field == 1);
CHECK(field_info.get_r<int>(instance) == 1);
CHECK(field_info(instance).cast<int>() == 1);
CHECK(field_info.get(instance).cast<int>() == 1);
CHECK(field_info.get_r<int>(std::as_const(instance)) == 1);
CHECK(field_info(std::as_const(instance)).cast<int>() == 1);
CHECK(field_info.get(std::as_const(instance)).cast<int>() == 1);
CHECK_NOTHROW(field_info(instance, 3));
CHECK_NOTHROW(field_info.set(instance, 3));
CHECK_THROWS_AS(field_info(instance, 4.f), std::logic_error);
CHECK_THROWS_AS(field_info.set(instance, 4.f), std::logic_error);
CHECK(instance.field == 3);
CHECK(field_info.get_r<int>(instance) == 3);
CHECK(field_info(instance).cast<int>() == 3);
CHECK(field_info.get(instance).cast<int>() == 3);
CHECK(field_info.get_r<int>(std::as_const(instance)) == 3);
CHECK(field_info(std::as_const(instance)).cast<int>() == 3);
CHECK(field_info.get(std::as_const(instance)).cast<int>() == 3);
}
@@ -52,13 +62,22 @@ TEST_CASE("meta/field") {
clazz instance;
CHECK(instance.cfield == 2);
CHECK(cfield_info.get_r<int>(instance) == 2);
CHECK(cfield_info(instance).cast<int>() == 2);
CHECK(cfield_info.get(instance).cast<int>() == 2);
CHECK(cfield_info.get_r<int>(std::as_const(instance)) == 2);
CHECK(cfield_info(std::as_const(instance)).cast<int>() == 2);
CHECK(cfield_info.get(std::as_const(instance)).cast<int>() == 2);
CHECK_THROWS_AS(cfield_info(instance, 4), std::logic_error);
CHECK_THROWS_AS(cfield_info.set(instance, 4), std::logic_error);
CHECK(instance.cfield == 2);
CHECK(cfield_info.get_r<int>(instance) == 2);
CHECK(cfield_info(instance).cast<int>() == 2);
CHECK(cfield_info.get(instance).cast<int>() == 2);
CHECK(cfield_info.get_r<int>(std::as_const(instance)) == 2);
CHECK(cfield_info(std::as_const(instance)).cast<int>() == 2);
CHECK(cfield_info.get(std::as_const(instance)).cast<int>() == 2);
}
@@ -66,7 +85,11 @@ TEST_CASE("meta/field") {
clazz instance;
instance.field = 5;
CHECK(field_info.get_r<int>(instance) == 5);
CHECK(field_info(instance).cast<int>() == 5);
CHECK(field_info.get(instance).cast<int>() == 5);
CHECK(field_info.get_r<int>(std::as_const(instance)) == 5);
CHECK(field_info(std::as_const(instance)).cast<int>() == 5);
CHECK(field_info.get(std::as_const(instance)).cast<int>() == 5);
}
}

View File

@@ -64,33 +64,52 @@ TEST_CASE("meta/function") {
}
SUBCASE("void_return") {
CHECK_NOTHROW(void_f_void_info.invoke());
CHECK_FALSE(void_f_void_info());
CHECK_FALSE(void_f_void_info.invoke());
CHECK_FALSE(void_f_void_info.invoke_r<int>());
CHECK_THROWS_AS(void_f_void_info(1), std::logic_error);
CHECK_THROWS_AS(void_f_void_info.invoke(1), std::logic_error);
CHECK_THROWS_AS(void_f_int_info(), std::logic_error);
CHECK_THROWS_AS(void_f_int_info.invoke(), std::logic_error);
CHECK_NOTHROW(void_f_int_info.invoke(1));
CHECK_FALSE(void_f_int_info(1));
CHECK_FALSE(void_f_int_info.invoke(1));
CHECK_FALSE(void_f_int_info.invoke_r<int>(1));
CHECK_THROWS_AS(void_f_int_info(1.f), std::logic_error);
CHECK_THROWS_AS(void_f_int_info.invoke(1.f), std::logic_error);
CHECK_THROWS_AS(void_f_int_info(1, 2), std::logic_error);
CHECK_THROWS_AS(void_f_int_info.invoke(1, 2), std::logic_error);
CHECK_THROWS_AS(void_f_int2_info(), std::logic_error);
CHECK_THROWS_AS(void_f_int2_info.invoke(), std::logic_error);
CHECK_THROWS_AS(void_f_int2_info(1), std::logic_error);
CHECK_THROWS_AS(void_f_int2_info.invoke(1), std::logic_error);
CHECK_NOTHROW(void_f_int2_info.invoke(1, 2));
CHECK_FALSE(void_f_int2_info(1, 2));
CHECK_FALSE(void_f_int2_info.invoke(1, 2));
CHECK_FALSE(void_f_int2_info.invoke_r<int>(1, 2));
CHECK_THROWS_AS(void_f_int2_info(1.f, 2), std::logic_error);
CHECK_THROWS_AS(void_f_int2_info.invoke(1.f, 2), std::logic_error);
CHECK_THROWS_AS(void_f_int2_info(1, 2.f), std::logic_error);
CHECK_THROWS_AS(void_f_int2_info.invoke(1, 2.f), std::logic_error);
CHECK_THROWS_AS(void_f_int2_info(1, 2, 3), std::logic_error);
CHECK_THROWS_AS(void_f_int2_info.invoke(1, 2, 3), std::logic_error);
}
SUBCASE("int_return") {
CHECK(int_f_void_info.invoke_r<int>() == 1);
CHECK(int_f_void_info.invoke()->cast<int>() == 1);
CHECK_THROWS_AS(int_f_void_info.invoke(1), std::logic_error);
CHECK_THROWS_AS(int_f_void_info.invoke_r<int>(1), std::logic_error);
CHECK_THROWS_AS(int_f_int_info.invoke(), std::logic_error);
CHECK(int_f_int_info.invoke_r<int>(1) == 1);
CHECK(int_f_int_info.invoke(1)->cast<int>() == 1);
CHECK_THROWS_AS(int_f_int_info.invoke(1.f), std::logic_error);
CHECK_THROWS_AS(int_f_int_info.invoke(1, 2), std::logic_error);
CHECK_THROWS_AS(int_f_int2_info.invoke(), std::logic_error);
CHECK_THROWS_AS(int_f_int2_info.invoke(1), std::logic_error);
CHECK(int_f_int2_info.invoke_r<int>(1, 2) == 3);
CHECK(int_f_int2_info.invoke(1, 2)->cast<int>() == 3);
CHECK_THROWS_AS(int_f_int2_info.invoke(1.f, 2), std::logic_error);
CHECK_THROWS_AS(int_f_int2_info.invoke(1, 2.f), std::logic_error);

View File

@@ -83,64 +83,106 @@ TEST_CASE("meta/non_const_method") {
SUBCASE("another_instance") {
clazz2 instance;
CHECK_THROWS_AS(void_f_void_info(instance), std::logic_error);
CHECK_THROWS_AS(void_f_void_info.invoke(instance), std::logic_error);
CHECK_THROWS_AS(void_f_void_info.invoke_r<int>(instance), std::logic_error);
CHECK_THROWS_AS(void_f_int_info(instance, 1), std::logic_error);
CHECK_THROWS_AS(void_f_int_info.invoke(instance, 1), std::logic_error);
CHECK_THROWS_AS(void_f_int_info.invoke_r<int>(instance, 1), std::logic_error);
CHECK_THROWS_AS(void_f_int2_info(instance, 1, 2), std::logic_error);
CHECK_THROWS_AS(void_f_int2_info.invoke(instance, 1, 2), std::logic_error);
CHECK_THROWS_AS(void_f_int2_info.invoke_r<int>(instance, 1, 2), std::logic_error);
}
SUBCASE("void_return") {
clazz instance;
CHECK_NOTHROW(void_f_void_info.invoke(instance));
CHECK_FALSE(void_f_void_info(instance));
CHECK_FALSE(void_f_void_info.invoke(instance));
CHECK_FALSE(void_f_void_info.invoke_r<int>(instance));
CHECK_THROWS_AS(void_f_void_info(instance, 1), std::logic_error);
CHECK_THROWS_AS(void_f_void_info.invoke(instance, 1), std::logic_error);
CHECK_THROWS_AS(void_f_void_info.invoke_r<int>(instance, 1), std::logic_error);
CHECK_THROWS_AS(void_f_int_info.invoke(instance), std::logic_error);
CHECK_NOTHROW(void_f_int_info.invoke(instance, 1));
CHECK_FALSE(void_f_int_info(instance, 1));
CHECK_FALSE(void_f_int_info.invoke(instance, 1));
CHECK_FALSE(void_f_int_info.invoke_r<int>(instance, 1));
CHECK_THROWS_AS(void_f_int_info.invoke(instance, 1.f), std::logic_error);
CHECK_THROWS_AS(void_f_int_info.invoke(instance, 1, 2), std::logic_error);
CHECK_THROWS_AS(void_f_int2_info.invoke(instance), std::logic_error);
CHECK_THROWS_AS(void_f_int2_info.invoke(instance, 1), std::logic_error);
CHECK_NOTHROW(void_f_int2_info.invoke(instance, 1, 2));
CHECK_FALSE(void_f_int2_info(instance, 1, 2));
CHECK_FALSE(void_f_int2_info.invoke(instance, 1, 2));
CHECK_FALSE(void_f_int2_info.invoke_r<int>(instance, 1, 2));
CHECK_THROWS_AS(void_f_int2_info.invoke(instance, 1.f, 2), std::logic_error);
CHECK_THROWS_AS(void_f_int2_info.invoke(instance, 1, 2.f), std::logic_error);
CHECK_THROWS_AS(void_f_int2_info.invoke(instance, 1, 2, 3), std::logic_error);
const clazz& cinstance = instance;
CHECK_THROWS_AS(void_f_void_info(cinstance), std::logic_error);
CHECK_THROWS_AS(void_f_void_info.invoke(cinstance), std::logic_error);
CHECK_THROWS_AS(void_f_void_info.invoke_r<int>(cinstance), std::logic_error);
CHECK_THROWS_AS(void_f_int_info(cinstance, 1), std::logic_error);
CHECK_THROWS_AS(void_f_int_info.invoke(cinstance, 1), std::logic_error);
CHECK_THROWS_AS(void_f_int_info.invoke_r<int>(cinstance, 1), std::logic_error);
CHECK_THROWS_AS(void_f_int2_info(cinstance, 1, 2), std::logic_error);
CHECK_THROWS_AS(void_f_int2_info.invoke(cinstance, 1, 2), std::logic_error);
CHECK_THROWS_AS(void_f_int2_info.invoke_r<int>(cinstance, 1, 2), std::logic_error);
}
SUBCASE("int_return") {
clazz instance;
CHECK(int_f_void_info(instance)->cast<int>() == 1);
CHECK(int_f_void_info.invoke(instance)->cast<int>() == 1);
CHECK(int_f_void_info.invoke_r<int>(instance) == 1);
CHECK_THROWS_AS(int_f_void_info(instance, 1), std::logic_error);
CHECK_THROWS_AS(int_f_void_info.invoke(instance, 1), std::logic_error);
CHECK_THROWS_AS(int_f_void_info.invoke_r<int>(instance, 1), std::logic_error);
CHECK_THROWS_AS(int_f_int_info.invoke(instance), std::logic_error);
CHECK(int_f_int_info(instance, 1)->cast<int>() == 1);
CHECK(int_f_int_info.invoke(instance, 1)->cast<int>() == 1);
CHECK(int_f_int_info.invoke_r<int>(instance, 1) == 1);
CHECK_THROWS_AS(int_f_int_info.invoke(instance, 1.f), std::logic_error);
CHECK_THROWS_AS(int_f_int_info.invoke(instance, 1, 2), std::logic_error);
CHECK_THROWS_AS(int_f_int2_info.invoke(instance), std::logic_error);
CHECK_THROWS_AS(int_f_int2_info.invoke(instance, 1), std::logic_error);
CHECK(int_f_int2_info(instance, 1, 2)->cast<int>() == 3);
CHECK(int_f_int2_info.invoke(instance, 1, 2)->cast<int>() == 3);
CHECK(int_f_int2_info.invoke_r<int>(instance, 1, 2) == 3);
CHECK_THROWS_AS(int_f_int2_info.invoke(instance, 1.f, 2), std::logic_error);
CHECK_THROWS_AS(int_f_int2_info.invoke(instance, 1, 2.f), std::logic_error);
CHECK_THROWS_AS(int_f_int2_info.invoke(instance, 1, 2, 3), std::logic_error);
const clazz& cinstance = instance;
CHECK_THROWS_AS(int_f_void_info(cinstance), std::logic_error);
CHECK_THROWS_AS(int_f_void_info.invoke(cinstance), std::logic_error);
CHECK_THROWS_AS(int_f_void_info.invoke_r<int>(cinstance), std::logic_error);
CHECK_THROWS_AS(int_f_int_info(cinstance, 1), std::logic_error);
CHECK_THROWS_AS(int_f_int_info.invoke(cinstance, 1), std::logic_error);
CHECK_THROWS_AS(int_f_int_info.invoke_r<int>(cinstance, 1), std::logic_error);
CHECK_THROWS_AS(int_f_int2_info(cinstance, 1, 2), std::logic_error);
CHECK_THROWS_AS(int_f_int2_info.invoke(cinstance, 1, 2), std::logic_error);
CHECK_THROWS_AS(int_f_int2_info.invoke_r<int>(cinstance, 1, 2), std::logic_error);
}
SUBCASE("int_return_by_value") {
meta::value instance{clazz{}};
CHECK(int_f_void_info(instance)->cast<int>() == 1);
CHECK(int_f_void_info.invoke(instance)->cast<int>() == 1);
CHECK(int_f_void_info.invoke_r<int>(instance) == 1);
CHECK(int_f_int_info(instance, 1)->cast<int>() == 1);
CHECK(int_f_int_info.invoke(instance, 1)->cast<int>() == 1);
CHECK(int_f_int_info.invoke_r<int>(instance, 1) == 1);
CHECK(int_f_int2_info(instance, 1, 2)->cast<int>() == 3);
CHECK(int_f_int2_info.invoke(instance, 1, 2)->cast<int>() == 3);
CHECK(int_f_int2_info.invoke_r<int>(instance, 1, 2) == 3);
}
}
@@ -186,63 +228,90 @@ TEST_CASE("meta/const_method") {
SUBCASE("another_instance") {
const clazz2 instance;
CHECK_THROWS_AS(void_f_void_info(instance), std::logic_error);
CHECK_THROWS_AS(void_f_void_info.invoke(instance), std::logic_error);
CHECK_THROWS_AS(void_f_int_info(instance, 1), std::logic_error);
CHECK_THROWS_AS(void_f_int_info.invoke(instance, 1), std::logic_error);
CHECK_THROWS_AS(void_f_int2_info(instance, 1, 2), std::logic_error);
CHECK_THROWS_AS(void_f_int2_info.invoke(instance, 1, 2), std::logic_error);
}
SUBCASE("void_return") {
clazz instance;
CHECK_NOTHROW(void_f_void_info.invoke(instance));
CHECK_FALSE(void_f_void_info(instance));
CHECK_FALSE(void_f_void_info.invoke(instance));
CHECK_THROWS_AS(void_f_void_info.invoke(instance, 1), std::logic_error);
CHECK_THROWS_AS(void_f_int_info.invoke(instance), std::logic_error);
CHECK_NOTHROW(void_f_int_info.invoke(instance, 1));
CHECK_FALSE(void_f_int_info(instance, 1));
CHECK_FALSE(void_f_int_info.invoke(instance, 1));
CHECK_THROWS_AS(void_f_int_info.invoke(instance, 1.f), std::logic_error);
CHECK_THROWS_AS(void_f_int_info.invoke(instance, 1, 2), std::logic_error);
CHECK_THROWS_AS(void_f_int2_info.invoke(instance), std::logic_error);
CHECK_THROWS_AS(void_f_int2_info.invoke(instance, 1), std::logic_error);
CHECK_NOTHROW(void_f_int2_info.invoke(instance, 1, 2));
CHECK_FALSE(void_f_int2_info(instance, 1, 2));
CHECK_FALSE(void_f_int2_info.invoke(instance, 1, 2));
CHECK_THROWS_AS(void_f_int2_info.invoke(instance, 1.f, 2), std::logic_error);
CHECK_THROWS_AS(void_f_int2_info.invoke(instance, 1, 2.f), std::logic_error);
CHECK_THROWS_AS(void_f_int2_info.invoke(instance, 1, 2, 3), std::logic_error);
const clazz& cinstance = instance;
CHECK_NOTHROW(void_f_void_info.invoke(cinstance));
CHECK_NOTHROW(void_f_int_info.invoke(cinstance, 1));
CHECK_NOTHROW(void_f_int2_info.invoke(cinstance, 1, 2));
CHECK_FALSE(void_f_void_info(cinstance));
CHECK_FALSE(void_f_void_info.invoke(cinstance));
CHECK_FALSE(void_f_int_info(cinstance, 1));
CHECK_FALSE(void_f_int_info.invoke(cinstance, 1));
CHECK_FALSE(void_f_int2_info(cinstance, 1, 2));
CHECK_FALSE(void_f_int2_info.invoke(cinstance, 1, 2));
}
SUBCASE("int_return") {
clazz instance;
CHECK(int_f_void_info(instance)->cast<int>() == 1);
CHECK(int_f_void_info.invoke(instance)->cast<int>() == 1);
CHECK(int_f_void_info.invoke_r<int>(instance) == 1);
CHECK_THROWS_AS(int_f_void_info.invoke(instance, 1), std::logic_error);
CHECK_THROWS_AS(int_f_int_info.invoke(instance), std::logic_error);
CHECK(int_f_int_info(instance, 1)->cast<int>() == 1);
CHECK(int_f_int_info.invoke(instance, 1)->cast<int>() == 1);
CHECK(int_f_int_info.invoke_r<int>(instance, 1) == 1);
CHECK_THROWS_AS(int_f_int_info.invoke(instance, 1.f), std::logic_error);
CHECK_THROWS_AS(int_f_int_info.invoke(instance, 1, 2), std::logic_error);
CHECK_THROWS_AS(int_f_int2_info.invoke(instance), std::logic_error);
CHECK_THROWS_AS(int_f_int2_info.invoke(instance, 1), std::logic_error);
CHECK(int_f_int2_info(instance, 1, 2)->cast<int>() == 3);
CHECK(int_f_int2_info.invoke(instance, 1, 2)->cast<int>() == 3);
CHECK(int_f_int2_info.invoke_r<int>(instance, 1, 2) == 3);
CHECK_THROWS_AS(int_f_int2_info.invoke(instance, 1.f, 2), std::logic_error);
CHECK_THROWS_AS(int_f_int2_info.invoke(instance, 1, 2.f), std::logic_error);
CHECK_THROWS_AS(int_f_int2_info.invoke(instance, 1, 2, 3), std::logic_error);
const clazz& cinstance = instance;
CHECK(int_f_void_info(cinstance)->cast<int>() == 1);
CHECK(int_f_void_info.invoke(cinstance)->cast<int>() == 1);
CHECK(int_f_void_info.invoke_r<int>(cinstance) == 1);
CHECK(int_f_int_info(cinstance, 1)->cast<int>() == 1);
CHECK(int_f_int_info.invoke(cinstance, 1)->cast<int>() == 1);
CHECK(int_f_int_info.invoke_r<int>(cinstance, 1) == 1);
CHECK(int_f_int2_info(cinstance, 1, 2)->cast<int>() == 3);
CHECK(int_f_int2_info.invoke(cinstance, 1, 2)->cast<int>() == 3);
CHECK(int_f_int2_info.invoke_r<int>(cinstance, 1, 2) == 3);
}
SUBCASE("int_return_by_value") {
meta::value instance{clazz{}};
CHECK(int_f_void_info(instance)->cast<int>() == 1);
CHECK(int_f_void_info.invoke(instance)->cast<int>() == 1);
CHECK(int_f_void_info.invoke_r<int>(instance) == 1);
CHECK(int_f_int_info(instance, 1)->cast<int>() == 1);
CHECK(int_f_int_info.invoke(instance, 1)->cast<int>() == 1);
CHECK(int_f_int_info.invoke_r<int>(instance, 1) == 1);
CHECK(int_f_int2_info(instance, 1, 2)->cast<int>() == 3);
CHECK(int_f_int2_info.invoke(instance, 1, 2)->cast<int>() == 3);
CHECK(int_f_int2_info.invoke_r<int>(instance, 1, 2) == 3);
}
}

View File

@@ -39,28 +39,41 @@ TEST_CASE("meta/variable") {
{
CHECK(variable == 1);
CHECK(variable_info().cast<int>() == 1);
CHECK(variable_info.get().cast<int>() == 1);
CHECK(variable_info.get_r<int>() == 1);
CHECK_NOTHROW(variable_info(3));
CHECK_NOTHROW(variable_info.set(3));
CHECK_THROWS_AS(variable_info(4.f), std::logic_error);
CHECK_THROWS_AS(variable_info.set(4.f), std::logic_error);
CHECK(variable == 3);
CHECK(variable_info().cast<int>() == 3);
CHECK(variable_info.get().cast<int>() == 3);
CHECK(variable_info.get_r<int>() == 3);
}
{
CHECK(cvariable == 2);
CHECK(cvariable_info().cast<int>() == 2);
CHECK(cvariable_info.get().cast<int>() == 2);
CHECK(cvariable_info.get_r<int>() == 2);
CHECK_THROWS_AS(cvariable_info(4), std::logic_error);
CHECK_THROWS_AS(cvariable_info.set(4), std::logic_error);
CHECK(cvariable == 2);
CHECK(cvariable_info().cast<int>() == 2);
CHECK(cvariable_info.get().cast<int>() == 2);
CHECK(cvariable_info.get_r<int>() == 2);
}
{
variable = 5;
CHECK(variable_info().cast<int>() == 5);
CHECK(variable_info.get().cast<int>() == 5);
CHECK(variable_info.get_r<int>() == 5);
}
}
@@ -78,27 +91,39 @@ TEST_CASE("meta/variable") {
{
CHECK(clazz::variable == 1);
CHECK(variable_info().cast<int>() == 1);
CHECK(variable_info.get().cast<int>() == 1);
CHECK(variable_info.get_r<int>() == 1);
CHECK_NOTHROW(variable_info(3));
CHECK_NOTHROW(variable_info.set(3));
CHECK(clazz::variable == 3);
CHECK(variable_info().cast<int>() == 3);
CHECK(variable_info.get().cast<int>() == 3);
CHECK(variable_info.get_r<int>() == 3);
}
{
CHECK(clazz::cvariable == 2);
CHECK(cvariable_info().cast<int>() == 2);
CHECK(cvariable_info.get().cast<int>() == 2);
CHECK(cvariable_info.get_r<int>() == 2);
CHECK_THROWS_AS(cvariable_info(4), std::logic_error);
CHECK_THROWS_AS(cvariable_info.set(4), std::logic_error);
CHECK(clazz::cvariable == 2);
CHECK(cvariable_info().cast<int>() == 2);
CHECK(cvariable_info.get().cast<int>() == 2);
CHECK(cvariable_info.get_r<int>() == 2);
}
{
clazz::variable = 5;
CHECK(variable_info().cast<int>() == 5);
CHECK(variable_info.get().cast<int>() == 5);
CHECK(variable_info.get_r<int>() == 5);
}
}
}