return and argument types for method and function infos

This commit is contained in:
BlackMATov
2021-07-07 05:55:18 +07:00
parent 997687d219
commit 3336d8cc67
5 changed files with 115 additions and 6 deletions

View File

@@ -62,6 +62,31 @@ namespace meta_hpp::function_detail
using namespace std::placeholders;
return std::bind(&raw_invoke<FunctionType>, function, _1, _2);
}
template < typename FunctionType >
std::optional<family_id> make_return_type() {
using ft = detail::function_traits<FunctionType>;
using return_type = typename ft::return_type;
if constexpr ( !std::is_void_v<return_type> ) {
return get_family_id<return_type>();
} else {
return std::nullopt;
}
}
template < typename FunctionType, std::size_t... Is >
std::vector<family_id> make_argument_types_impl(std::index_sequence<Is...>) {
using ft = detail::function_traits<FunctionType>;
using argument_types = typename ft::argument_types;
return { get_family_id<std::tuple_element_t<Is, argument_types>>()... };
}
template < typename FunctionType >
std::vector<family_id> make_argument_types() {
using ft = detail::function_traits<FunctionType>;
return make_argument_types_impl<FunctionType>(std::make_index_sequence<ft::arity>());
}
}
namespace meta_hpp
@@ -81,7 +106,18 @@ namespace meta_hpp
}
std::size_t arity() const noexcept {
return arity_;
return argument_types_.size();
}
std::optional<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 >
@@ -123,11 +159,13 @@ namespace meta_hpp
template < typename FunctionType >
function_info(std::string id, FunctionType function_ptr)
: id_{std::move(id)}
, arity_{detail::function_traits<FunctionType>::arity}
, return_type_{function_detail::make_return_type<FunctionType>()}
, argument_types_{function_detail::make_argument_types<FunctionType>()}
, invoke_{function_detail::make_invoke(function_ptr)} {}
private:
std::string id_;
std::size_t arity_;
std::optional<family_id> return_type_;
std::vector<family_id> argument_types_;
function_detail::function_invoke invoke_;
std::map<std::string, data_info, std::less<>> datas_;
};

View File

@@ -22,6 +22,7 @@
#include <type_traits>
#include <utility>
#include <variant>
#include <vector>
#define META_HPP_AUTO_T(V) decltype(V), V

View File

@@ -131,6 +131,31 @@ namespace meta_hpp::method_detail
using namespace std::placeholders;
return std::bind(&raw_cinvoke<MethodType>, method, _1, _2, _3);
}
template < typename MethodType >
std::optional<family_id> make_return_type() {
using ft = detail::method_traits<MethodType>;
using return_type = typename ft::return_type;
if constexpr ( !std::is_void_v<return_type> ) {
return get_family_id<return_type>();
} else {
return std::nullopt;
}
}
template < typename MethodType, std::size_t... Is >
std::vector<family_id> make_argument_types_impl(std::index_sequence<Is...>) {
using ft = detail::method_traits<MethodType>;
using argument_types = typename ft::argument_types;
return { get_family_id<std::tuple_element_t<Is, argument_types>>()... };
}
template < typename MethodType >
std::vector<family_id> make_argument_types() {
using ft = detail::method_traits<MethodType>;
return make_argument_types_impl<MethodType>(std::make_index_sequence<ft::arity>());
}
}
namespace meta_hpp
@@ -150,7 +175,18 @@ namespace meta_hpp
}
std::size_t arity() const noexcept {
return arity_;
return argument_types_.size();
}
std::optional<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 T, typename... Args >
@@ -202,12 +238,14 @@ namespace meta_hpp
template < typename MethodType >
method_info(std::string id, MethodType method_ptr)
: id_{std::move(id)}
, arity_{detail::method_traits<MethodType>::arity}
, return_type_{method_detail::make_return_type<MethodType>()}
, argument_types_{method_detail::make_argument_types<MethodType>()}
, invoke_{method_detail::make_invoke(method_ptr)}
, cinvoke_{method_detail::make_cinvoke(method_ptr)} {}
private:
std::string id_;
std::size_t arity_;
std::optional<family_id> return_type_;
std::vector<family_id> argument_types_;
method_detail::method_invoke invoke_;
method_detail::method_cinvoke cinvoke_;
std::map<std::string, data_info, std::less<>> datas_;

View File

@@ -47,6 +47,22 @@ TEST_CASE("meta/function") {
CHECK(int_f_int2_info.arity() == 2);
}
SUBCASE("return_type") {
CHECK_FALSE(void_f_void_info.return_type());
CHECK(int_f_void_info.return_type() == meta::get_family_id<int>());
}
SUBCASE("argument_types") {
CHECK_FALSE(void_f_void_info.argument_type(0u));
CHECK(int_f_int_info.argument_type(0u) == meta::get_family_id<int>());
CHECK_FALSE(int_f_int_info.argument_type(1u));
CHECK(int_f_int2_info.argument_type(0u) == meta::get_family_id<int>());
CHECK(int_f_int2_info.argument_type(1u) == meta::get_family_id<int>());
CHECK_FALSE(int_f_int2_info.argument_type(2u));
}
SUBCASE("void_return") {
CHECK_NOTHROW(void_f_void_info.invoke());
CHECK_THROWS_AS(void_f_void_info.invoke(1), std::logic_error);

View File

@@ -60,6 +60,22 @@ TEST_CASE("meta/non_const_method") {
CHECK(int_f_int2_info.arity() == 2);
}
SUBCASE("return_type") {
CHECK_FALSE(void_f_void_info.return_type());
CHECK(int_f_void_info.return_type() == meta::get_family_id<int>());
}
SUBCASE("argument_types") {
CHECK_FALSE(void_f_void_info.argument_type(0u));
CHECK(int_f_int_info.argument_type(0u) == meta::get_family_id<int>());
CHECK_FALSE(int_f_int_info.argument_type(1u));
CHECK(int_f_int2_info.argument_type(0u) == meta::get_family_id<int>());
CHECK(int_f_int2_info.argument_type(1u) == meta::get_family_id<int>());
CHECK_FALSE(int_f_int2_info.argument_type(2u));
}
SUBCASE("another_instance") {
clazz2 instance;
CHECK_THROWS_AS(void_f_void_info.invoke(instance), std::logic_error);