Merge branch 'feature/ctor_infos' into dev

This commit is contained in:
BlackMATov
2021-07-14 00:33:11 +07:00
19 changed files with 690 additions and 69 deletions

View File

@@ -17,6 +17,9 @@
#include "meta_class.hpp"
#include "meta_class_info.hpp"
#include "meta_ctor.hpp"
#include "meta_ctor_info.hpp"
#include "meta_data.hpp"
#include "meta_data_info.hpp"

View File

@@ -8,6 +8,7 @@
#include "meta_fwd.hpp"
#include "meta_ctor.hpp"
#include "meta_data.hpp"
#include "meta_field.hpp"
#include "meta_function.hpp"
@@ -40,6 +41,12 @@ namespace meta_hpp
detail::merge_with(info_.classes_, info.id(), info, &class_info::merge);
}
template < typename... Args >
void add_(ctor_<Args...> internal) {
ctor_info info = std::move(internal).template make_info<Class>();
detail::merge_with(info_.ctors_, info.family(), info, &ctor_info::merge);
}
void add_(data_ internal) {
data_info info = std::move(internal).make_info();
detail::merge_with(info_.datas_, info.id(), info, &data_info::merge);

View File

@@ -9,6 +9,7 @@
#include "meta_fwd.hpp"
#include "meta_value.hpp"
#include "meta_ctor_info.hpp"
#include "meta_data_info.hpp"
#include "meta_field_info.hpp"
#include "meta_function_info.hpp"
@@ -42,6 +43,13 @@ namespace meta_hpp
}
}
template < typename F >
void each_ctor(F&& f) const {
for ( auto&& family_info : ctors_ ) {
std::invoke(f, family_info.second);
}
}
template < typename F >
void each_data(F&& f) const {
for ( auto&& id_info : datas_ ) {
@@ -80,6 +88,7 @@ namespace meta_hpp
template < typename F >
void visit(F&& f) const {
each_class(f);
each_ctor(f);
each_data(f);
each_field(f);
each_function(f);
@@ -91,6 +100,16 @@ namespace meta_hpp
return detail::find_opt(classes_, id);
}
template < typename... Args >
std::optional<ctor_info> get_ctor() const {
for ( auto&& family_info : ctors_ ) {
if ( family_info.second.is_invocable<Args...>() ) {
return family_info.second;
}
}
return std::nullopt;
}
std::optional<data_info> get_data(std::string_view id) const {
return detail::find_opt(datas_, id);
}
@@ -116,6 +135,7 @@ namespace meta_hpp
throw std::logic_error("class_info::merge failed");
}
detail::merge_with(classes_, other.classes_, &class_info::merge);
detail::merge_with(ctors_, other.ctors_, &ctor_info::merge);
detail::merge_with(datas_, other.datas_, &data_info::merge);
detail::merge_with(fields_, other.fields_, &field_info::merge);
detail::merge_with(functions_, other.functions_, &function_info::merge);
@@ -134,6 +154,7 @@ namespace meta_hpp
std::string id_;
family_id family_;
std::map<std::string, class_info, std::less<>> classes_;
std::map<family_id, ctor_info, std::less<>> ctors_;
std::map<std::string, data_info, std::less<>> datas_;
std::map<std::string, field_info, std::less<>> fields_;
std::map<std::string, function_info, std::less<>> functions_;

View File

@@ -0,0 +1,43 @@
/*******************************************************************************
* 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)
******************************************************************************/
#pragma once
#include "meta_fwd.hpp"
#include "meta_data.hpp"
#include "meta_ctor_info.hpp"
namespace meta_hpp
{
template < typename... Args >
class ctor_ {
public:
ctor_() = default;
template < typename Class >
ctor_info make_info() const {
static_assert(std::is_constructible_v<Class, Args...>);
ctor_info info{detail::typename_arg<Class>, detail::typename_args<Args...>};
detail::merge_with(info.datas_, datas_, &data_info::merge);
return info;
}
template < typename... Internals >
ctor_& operator()(Internals&&...internals) {
(add_(std::forward<Internals>(internals)), ...);
return *this;
}
private:
void add_(data_ internal) {
data_info info = std::move(internal).make_info();
detail::merge_with(datas_, info.id(), info, &data_info::merge);
}
private:
std::map<std::string, data_info, std::less<>> datas_;
};
}

View File

@@ -0,0 +1,188 @@
/*******************************************************************************
* 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)
******************************************************************************/
#pragma once
#include "meta_fwd.hpp"
#include "meta_value.hpp"
#include "meta_data_info.hpp"
namespace meta_hpp::ctor_detail
{
template < typename Class, typename... Args, std::size_t... Is >
value raw_invoke_impl(
value* args,
std::index_sequence<Is...>)
{
using ct = detail::ctor_traits<Class, Args...>;
using return_type = typename ct::return_type;
using argument_types = typename ct::argument_types;
[[maybe_unused]] auto typed_arguments = std::make_tuple(
(args + Is)->try_cast<std::tuple_element_t<Is, argument_types>>()...);
if ( !(std::get<Is>(typed_arguments) && ...) ) {
throw std::logic_error("an attempt to call a ctor with incorrect argument types");
}
return_type return_value{std::move(*std::get<Is>(typed_arguments))...};
return value{std::move(return_value)};
}
template < typename Class, typename... Args >
value raw_invoke(
value* args,
std::size_t arg_count)
{
using ct = detail::ctor_traits<Class, Args...>;
if ( arg_count != ct::arity ) {
throw std::logic_error("an attempt to call a ctor with an incorrect arity");
}
return raw_invoke_impl<Class, Args...>(args, std::make_index_sequence<ct::arity>());
}
using ctor_invoke = std::function<value(value*, std::size_t)>;
template < typename Class, typename... Args >
ctor_invoke make_invoke() {
using namespace std::placeholders;
return std::bind(&raw_invoke<Class, Args...>, _1, _2);
}
template < typename Class, typename... Args >
family_id make_return_type() {
using ct = detail::ctor_traits<Class, Args...>;
using return_type = typename ct::return_type;
return get_family_id<return_type>();
}
template < typename Class, typename... Args, std::size_t... Is >
std::vector<family_id> make_argument_types_impl(std::index_sequence<Is...>) {
using ct = detail::ctor_traits<Class, Args...>;
using argument_types = typename ct::argument_types;
return { get_family_id<std::tuple_element_t<Is, argument_types>>()... };
}
template < typename Class, typename... Args >
std::vector<family_id> make_argument_types() {
using ct = detail::ctor_traits<Class, Args...>;
return make_argument_types_impl<Class, Args...>(std::make_index_sequence<ct::arity>());
}
template < typename... Args, std::size_t... Is >
bool parameters_equal(const std::vector<family_id>& parameters, std::index_sequence<Is...>) {
if ( parameters.size() != sizeof...(Args) ) {
return false;
}
return ((get_family_id<std::tuple_element_t<Is, std::tuple<Args...>>>() == parameters[Is]) && ... );
}
template < typename... Args >
bool parameters_equal(const std::vector<family_id>& parameters) {
return parameters_equal<Args...>(parameters, std::make_index_sequence<sizeof...(Args)>());
}
}
namespace meta_hpp
{
class ctor_info {
public:
ctor_info() = delete;
ctor_info(ctor_info&&) = default;
ctor_info(const ctor_info&) = default;
ctor_info& operator=(ctor_info&&) = default;
ctor_info& operator=(const ctor_info&) = default;
public:
family_id family() const noexcept {
return family_;
}
std::size_t arity() const noexcept {
return argument_types_.size();
}
family_id return_type() const noexcept {
return return_type_;
}
std::optional<family_id> argument_type(std::size_t index) const noexcept {
if ( index < argument_types_.size() ) {
return argument_types_[index];
}
return std::nullopt;
}
template < typename... Args >
value invoke(Args&&... args) const {
if constexpr ( sizeof...(Args) > 0u ) {
std::array<value, sizeof...(Args)> vargs{std::forward<Args>(args)...};
return invoke_(vargs.data(), vargs.size());
} else {
return invoke_(nullptr, 0u);
}
}
template < typename R, typename Rp = std::decay_t<R>, typename... Args >
Rp invoke_r(Args&&... args) const {
return invoke(std::forward<Args>(args)...).template cast<Rp>();
}
template < typename... Args >
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_);
}
template < typename F >
void each_data(F&& f) const {
for ( auto&& id_info : datas_ ) {
std::invoke(f, id_info.second);
}
}
template < typename F >
void visit(F&& f) const {
each_data(f);
}
std::optional<data_info> get_data(std::string_view id) const {
return detail::find_opt(datas_, id);
}
void merge(const ctor_info& other) {
if ( family() != other.family() ) {
throw std::logic_error("ctor_info::merge failed");
}
detail::merge_with(datas_, other.datas_, &data_info::merge);
}
private:
template < typename... Args >
friend class ctor_;
template < typename Class, typename... Args >
ctor_info(detail::typename_arg_t<Class>, detail::typename_args_t<Args...>)
: family_{get_family_id<detail::ctor_traits<Class, Args...>>()}
, return_type_{ctor_detail::make_return_type<Class, Args...>()}
, argument_types_{ctor_detail::make_argument_types<Class, Args...>()}
, invoke_{ctor_detail::make_invoke<Class, Args...>()} {}
private:
family_id family_;
family_id return_type_;
std::vector<family_id> argument_types_;
ctor_detail::ctor_invoke invoke_;
std::map<std::string, data_info, std::less<>> datas_;
};
}

View File

@@ -122,9 +122,23 @@ namespace meta_hpp
return getter_(instance);
}
template < typename R, typename Rp = std::decay_t<R> >
Rp get_r(cinstance instance) const {
return get(instance).template cast<Rp>();
}
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 Rp = std::decay_t<R>, typename... Args >
std::optional<Rp> invoke_r(Args&&... args) const {
if ( std::optional<value> r = invoke(std::forward<Args>(args)...) ) {
return std::move(r)->template cast<Rp>();
}
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

@@ -105,8 +105,15 @@ namespace meta_hpp::detail
struct typename_arg_t {
};
template < typename... Args >
struct typename_args_t {
};
template < typename Arg >
inline typename_arg_t<Arg> typename_arg;
template < typename... Args >
inline typename_args_t<Args...> typename_args;
}
namespace meta_hpp::detail
@@ -136,6 +143,16 @@ namespace meta_hpp::detail
}
}
namespace meta_hpp::detail
{
template < typename Class, typename... Args >
struct ctor_traits {
static constexpr std::size_t arity = sizeof...(Args);
using return_type = std::decay_t<Class>;
using argument_types = std::tuple<std::decay_t<Args>...>;
};
}
namespace meta_hpp::detail
{
template < typename Field >

View File

@@ -56,7 +56,7 @@ namespace meta_hpp
std::add_pointer_t<T>
try_cast() noexcept {
static_assert(!std::is_reference_v<T>);
return fid() == get_family_id<T>()
return fid_ == get_family_id<T>()
? static_cast<std::add_pointer_t<T>>(data_)
: nullptr;
}
@@ -65,7 +65,7 @@ namespace meta_hpp
std::add_pointer_t<std::add_const_t<T>>
try_cast() const noexcept {
static_assert(!std::is_reference_v<T>);
return fid() == get_family_id<T>()
return fid_ == get_family_id<T>()
? static_cast<std::add_pointer_t<std::add_const_t<T>>>(data_)
: nullptr;
}
@@ -91,8 +91,8 @@ namespace meta_hpp
, typename = std::enable_if_t<!std::is_same_v<T, value>>
, typename = std::enable_if_t<!std::is_same_v<T, instance>>
, typename = std::enable_if_t<!std::is_same_v<T, cinstance>> >
cinstance(const T& data)
: data_{std::addressof(data)}
cinstance(const T& v)
: data_{std::addressof(v)}
, fid_{get_family_id<T>()} {}
cinstance(const value& v)
@@ -115,7 +115,7 @@ namespace meta_hpp
std::add_pointer_t<std::add_const_t<T>>
try_cast() const noexcept {
static_assert(!std::is_reference_v<T>);
return fid() == get_family_id<T>()
return fid_ == get_family_id<T>()
? static_cast<std::add_pointer_t<std::add_const_t<T>>>(data_)
: nullptr;
}

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)...};
return invoke_(inst, vargs.data(), vargs.size());
if constexpr ( std::is_const_v<T> ) {
return cinvoke_(inst, vargs.data(), vargs.size());
} else {
return invoke_(inst, vargs.data(), vargs.size());
}
} else {
return invoke_(inst, nullptr, 0u);
if constexpr ( std::is_const_v<T> ) {
return cinvoke_(inst, nullptr, 0u);
} else {
return invoke_(inst, nullptr, 0u);
}
}
}
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);
template < typename R, typename Rp = std::decay_t<R>, typename T, typename... Args >
std::optional<Rp> invoke_r(T& inst, Args&&... args) const {
if ( std::optional<value> r = invoke(inst, std::forward<Args>(args)...) ) {
return std::move(r)->template cast<Rp>();
}
return std::nullopt;
}
template < typename T, typename... Args >
std::optional<value> operator()(T& inst, Args&&... args) const {
return invoke(inst, std::forward<Args>(args)...);
}
template < typename F >

View File

@@ -11,6 +11,8 @@
#include "meta_type.hpp"
#include "meta_class.hpp"
#include "meta_ctor.hpp"
#include "meta_data.hpp"
#include "meta_field.hpp"
#include "meta_function.hpp"
#include "meta_method.hpp"
@@ -150,6 +152,7 @@ namespace meta_hpp
detail::merge_with(classes_, name, info, &class_info::merge);
info.visit(overloaded {
[](const ctor_info&) {},
[](const data_info&) {},
[this, &name](const auto& internal){
add_(name, internal);

View File

@@ -53,33 +53,36 @@ namespace meta_hpp
value& operator=(value&&) = default;
value& operator=(const value&) = default;
template < typename T
, typename U = std::decay_t<T>
, typename = std::enable_if_t<!std::is_same_v<U, value>> >
template < typename T, typename Tp = std::decay_t<T>
, typename = std::enable_if_t<!std::is_same_v<Tp, value>> >
value(T&& val)
: raw_{std::forward<T>(val)}
, fid_{get_family_id<U>()}
, traits_{value_detail::get_traits<U>()} {}
, fid_{get_family_id<Tp>()}
, traits_{value_detail::get_traits<Tp>()} {}
template < typename T
, typename U = std::decay_t<T>
, typename = std::enable_if_t<!std::is_same_v<U, value>> >
template < typename T, typename Tp = std::decay_t<T>
, typename = std::enable_if_t<!std::is_same_v<Tp, value>> >
value& operator=(T&& val) {
value{std::forward<T>(val)}.swap(*this);
return *this;
}
template < typename T, typename... Args >
template < typename T, typename Tp = std::decay_t<T>, typename... Args >
explicit value(std::in_place_type_t<T>, Args&&... args)
: raw_{std::in_place_type<T>, std::forward<Args>(args)...}
, fid_{get_family_id<T>()}
, traits_{value_detail::get_traits<T>()} {}
: raw_{std::in_place_type<Tp>, std::forward<Args>(args)...}
, fid_{get_family_id<Tp>()}
, traits_{value_detail::get_traits<Tp>()} {}
template < typename T, typename U, typename... Args >
explicit value(std::in_place_type_t<T>, std::initializer_list<U> ilist, Args&&... args)
: raw_{std::in_place_type<T>, ilist, std::forward<Args>(args)...}
, fid_{get_family_id<T>()}
, traits_{value_detail::get_traits<T>()} {}
template < typename T, typename Tp = std::decay_t<T>, typename I, typename... Args >
explicit value(std::in_place_type_t<T>, std::initializer_list<I> ilist, Args&&... args)
: raw_{std::in_place_type<Tp>, ilist, std::forward<Args>(args)...}
, fid_{get_family_id<Tp>()}
, traits_{value_detail::get_traits<Tp>()} {}
template < typename T >
bool has_type() const noexcept {
return fid_ == get_family_id<T>();
}
template < typename T >
T cast() && {
@@ -129,12 +132,11 @@ namespace meta_hpp
swap(traits_, other.traits_);
}
template < typename T
, typename U = std::decay_t<T>
, typename = std::enable_if_t<!std::is_same_v<U, value>> >
template < typename T, typename Tp = std::decay_t<T>
, typename = std::enable_if_t<!std::is_same_v<Tp, value>> >
bool equals(T&& other) const {
return fid() == get_family_id<U>()
&& std::equal_to<>{}(*try_cast<U>(), std::forward<T>(other));
return fid_ == get_family_id<Tp>()
&& std::equal_to<>{}(*try_cast<Tp>(), std::forward<T>(other));
}
bool equals(const value& other) const {
@@ -146,7 +148,7 @@ namespace meta_hpp
unsigned to_uint() const { return cast<unsigned>(); }
float to_float() const { return cast<float>(); }
double to_double() const { return cast<double>(); }
std::string to_string() const { return cast<std::string>(); }
const std::string& to_string() const { return cast<const std::string&>(); }
std::int8_t to_int8() const { return cast<std::int8_t>(); }
std::int16_t to_int16() const { return cast<std::int16_t>(); }
@@ -162,26 +164,26 @@ namespace meta_hpp
std::size_t to_size_t() const { return cast<std::size_t>(); }
std::uintptr_t to_uintptr_t() const { return cast<std::uintptr_t>(); }
public:
bool is_bool() const noexcept { return !!try_cast<bool>(); }
bool is_int() const noexcept { return !!try_cast<int>(); }
bool is_uint() const noexcept { return !!try_cast<unsigned>(); }
bool is_float() const noexcept { return !!try_cast<float>(); }
bool is_double() const noexcept { return !!try_cast<double>(); }
bool is_string() const noexcept { return !!try_cast<std::string>(); }
bool is_bool() const noexcept { return has_type<bool>(); }
bool is_int() const noexcept { return has_type<int>(); }
bool is_uint() const noexcept { return has_type<unsigned>(); }
bool is_float() const noexcept { return has_type<float>(); }
bool is_double() const noexcept { return has_type<double>(); }
bool is_string() const noexcept { return has_type<std::string>(); }
bool is_int8() const noexcept { return !!try_cast<std::int8_t>(); }
bool is_int16() const noexcept { return !!try_cast<std::int16_t>(); }
bool is_int32() const noexcept { return !!try_cast<std::int32_t>(); }
bool is_int64() const noexcept { return !!try_cast<std::int64_t>(); }
bool is_ptrdiff_t() const noexcept { return !!try_cast<std::ptrdiff_t>(); }
bool is_intptr_t() const noexcept { return !!try_cast<std::intptr_t>(); }
bool is_int8() const noexcept { return has_type<std::int8_t>(); }
bool is_int16() const noexcept { return has_type<std::int16_t>(); }
bool is_int32() const noexcept { return has_type<std::int32_t>(); }
bool is_int64() const noexcept { return has_type<std::int64_t>(); }
bool is_ptrdiff_t() const noexcept { return has_type<std::ptrdiff_t>(); }
bool is_intptr_t() const noexcept { return has_type<std::intptr_t>(); }
bool is_uint8() const noexcept { return !!try_cast<std::uint8_t>(); }
bool is_uint16() const noexcept { return !!try_cast<std::uint16_t>(); }
bool is_uint32() const noexcept { return !!try_cast<std::uint32_t>(); }
bool is_uint64() const noexcept { return !!try_cast<std::uint64_t>(); }
bool is_size_t() const noexcept { return !!try_cast<std::size_t>(); }
bool is_uintptr_t() const noexcept { return !!try_cast<std::uintptr_t>(); }
bool is_uint8() const noexcept { return has_type<std::uint8_t>(); }
bool is_uint16() const noexcept { return has_type<std::uint16_t>(); }
bool is_uint32() const noexcept { return has_type<std::uint32_t>(); }
bool is_uint64() const noexcept { return has_type<std::uint64_t>(); }
bool is_size_t() const noexcept { return has_type<std::size_t>(); }
bool is_uintptr_t() const noexcept { return has_type<std::uintptr_t>(); }
private:
std::any raw_;
family_id fid_;
@@ -213,7 +215,7 @@ namespace meta_hpp::value_detail
if constexpr ( std::is_invocable_v<std::equal_to<>, T, T> ) {
return std::equal_to<>{}(*l.try_cast<T>(), *r.try_cast<T>());
} else {
return std::addressof(l) == std::addressof(r);
return value_cdata<T>(l) == value_cdata<T>(r);
}
}
}

View File

@@ -96,11 +96,25 @@ namespace meta_hpp
return getter_();
}
template < typename R, typename Rp = std::decay_t<R> >
Rp get_r() const {
return get().template cast<Rp>();
}
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_ ) {

138
untests/meta_ctor_tests.cpp Normal file
View File

@@ -0,0 +1,138 @@
/*******************************************************************************
* 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>());
}

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

@@ -69,14 +69,25 @@ TEST_CASE("meta/value") {
CHECK(meta::value{std::in_place_type<std::uint64_t>, std::uint64_t{1}}.is_uint64());
CHECK(meta::value{std::in_place_type<std::size_t>, std::size_t{1}}.is_size_t());
CHECK(meta::value{std::in_place_type<std::uintptr_t>, std::uintptr_t{1}}.is_uintptr_t());
SUBCASE("in_place") {
CHECK(meta::value{std::in_place_type<std::uint8_t>, std::uint8_t{1}}.is_uint8());
CHECK(meta::value{std::in_place_type<std::uint8_t&>, std::uint8_t{1}}.is_uint8());
CHECK(meta::value{std::in_place_type<const std::uint8_t>, std::uint8_t{1}}.is_uint8());
CHECK(meta::value{std::in_place_type<const std::uint8_t&>, std::uint8_t{1}}.is_uint8());
}
}
TEST_CASE("meta/value/fid") {
namespace meta = meta_hpp;
using namespace std::string_literals;
CHECK(meta::value{clazz{}}.has_type<clazz>());
CHECK(meta::value{clazz{}}.fid() == meta::get_family_id<clazz>());
CHECK(meta::value{clazz2{}}.has_type<clazz2>());
CHECK(meta::value{clazz2{}}.fid() == meta::get_family_id<clazz2>());
CHECK(meta::value{clazz{}}.fid() != meta::value{clazz2{}}.fid());
{

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);
}
}
}