remove "auto Function"

This commit is contained in:
BlackMATov
2021-07-07 03:01:39 +07:00
parent 60674de7da
commit 4e829bc7b7
9 changed files with 49 additions and 33 deletions

View File

@@ -14,13 +14,13 @@
namespace meta_hpp
{
template < auto Function >
template < typename FunctionType >
class function_ {
public:
static_assert(std::is_function_v<std::remove_pointer_t<decltype(Function)>>);
static_assert(std::is_function_v<std::remove_pointer_t<FunctionType>>);
explicit function_(std::string id)
: info_{detail::auto_arg<META_HPP_AUTO_T(Function)>, std::move(id)} {}
explicit function_(std::string id, FunctionType function)
: info_{std::move(id), function} {}
operator const function_info&() const noexcept {
return info_;

View File

@@ -14,8 +14,12 @@
namespace meta_hpp::function_detail
{
template < typename FunctionType, FunctionType Function, std::size_t... Is >
std::optional<value> invoke(value* args, std::index_sequence<Is...>) {
template < typename FunctionType, std::size_t... Is >
std::optional<value> raw_invoke_impl(
FunctionType function,
value* args,
std::index_sequence<Is...>)
{
using ft = detail::function_traits<FunctionType>;
using return_type = typename ft::return_type;
using argument_types = typename ft::argument_types;
@@ -28,23 +32,35 @@ namespace meta_hpp::function_detail
}
if constexpr ( std::is_void_v<return_type> ) {
std::invoke(Function, std::move(*std::get<Is>(typed_arguments))...);
std::invoke(function, std::move(*std::get<Is>(typed_arguments))...);
return std::nullopt;
} else {
return_type return_value{std::invoke(Function, std::move(*std::get<Is>(typed_arguments))...)};
return_type return_value{std::invoke(function, std::move(*std::get<Is>(typed_arguments))...)};
return value{std::move(return_value)};
}
}
template < typename FunctionType, FunctionType Function >
std::optional<value> invoke(value* args, std::size_t arg_count) {
template < typename FunctionType >
std::optional<value> raw_invoke(
FunctionType function,
value* args,
std::size_t arg_count)
{
using ft = detail::function_traits<FunctionType>;
if ( arg_count != ft::arity ) {
throw std::logic_error("an attempt to call a function with an incorrect arity");
}
return invoke<FunctionType, Function>(args, std::make_index_sequence<ft::arity>());
return raw_invoke_impl<FunctionType>(function, args, std::make_index_sequence<ft::arity>());
}
using function_invoke = std::function<std::optional<value>(value*, std::size_t)>;
template < typename FunctionType >
function_invoke make_invoke(FunctionType function) {
using namespace std::placeholders;
return std::bind(&raw_invoke<FunctionType>, function, _1, _2);
}
}
@@ -97,16 +113,16 @@ namespace meta_hpp
detail::merge_with(datas_, other.datas_, &data_info::merge);
}
private:
template < auto Function >
template < typename FunctionType >
friend class function_;
template < typename FunctionType, FunctionType Function >
function_info(detail::auto_arg_t<FunctionType, Function>, std::string id)
template < typename FunctionType >
function_info(std::string id, FunctionType function)
: id_{std::move(id)}
, invoke_{&function_detail::invoke<FunctionType, Function>} {}
, invoke_{function_detail::make_invoke(function)} {}
private:
std::string id_;
std::optional<value>(*invoke_)(value*, std::size_t);
function_detail::function_invoke invoke_;
std::map<std::string, data_info, std::less<>> datas_;
};
}