mirror of
https://github.com/BlackMATov/meta.hpp.git
synced 2025-12-15 03:45:30 +07:00
return and argument types for method and function infos
This commit is contained in:
@@ -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_;
|
||||
};
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <variant>
|
||||
#include <vector>
|
||||
|
||||
#define META_HPP_AUTO_T(V) decltype(V), V
|
||||
|
||||
|
||||
@@ -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_;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user