using namespace traits;
template typename T1, typename R1, typename ...Args1>
class any_fun_operator
{
//using U1 = fun_traits;
//using type0 = easy_traits;
public:
void call()
{
T1 xxx;
int x = 0;
}
/*
template
typename std::enable_if::value, void>::type
check_smart_pointer(const T& t)
{
std::cout << "is smart pointer" << std::endl;
}
template
typename std::enable_if::value, void>::type
check_smart_pointer(const T& t)
{
std::cout << "not smart pointer" << std::endl;
}*/
/*
typename U1::ret_type operator()(typename U1::args_types)
{
int x = 0;
}*/
};
/*
template
class any_fun_operator
{
using type0 = easy_traits;
public:
typename type0::return_type operator()(typename type0::arguments)
{
int x = 0;
}
};*/
template
class any_fun
//:public any_fun_operator
{
static const size_t type_count = sizeof...(Args); //类型个数
static_assert(type_count > 0, "此类需要一个或多个模板参数,如:etd::function");
template
using typelist = typename std::tuple_element>::type;
private:
constexpr static int ERR_NO_FIND = -1;
constexpr static int ERR_TYPE_RE = -2;
public:
template
any_fun(F&& val)
{
constexpr auto const_Index = find_type();
//没有匹配的函数类型
static_assert(!(const_Index == ERR_NO_FIND), "no match type");
if constexpr (const_Index == ERR_TYPE_RE)
{
constexpr auto const_Index2 = find_type();
//没有匹配的函数类型
static_assert(!(const_Index2 == ERR_NO_FIND), "no match type");
//该函数模板给出了重复类型
static_assert(!(const_Index2 == ERR_TYPE_RE), "retype!");
_data = (typelist)std::move(val);
} else {
_data = (typelist)std::move(val);
}
using fun_traits = easy_traits;
easy_traits::print();
print_lists();
int x = 0;
/*
auto sssss = sizeof(TTT);
auto testval = std::is_same_v;
auto test2 = std::is_convertible_v;
auto test3 = std::is_arithmetic_v;
double aaaaa = 1234567890;
//int bbb = 0;
//auto xxx = type_id>().name();
//using MY_T = myfun_traits>;
//auto a2 = get_fun_string>();
//std::cout << std::endl;
//std::cout << get_return_type>();
//get_return_type::arg_type<0>>();
//auto xxx = std::type_info(fun);
int bbccb = 0;*/
}
/*
template
RET_TYPE operator()(As&& ... args)
{
//函数1参数类型
if constexpr (!easy_traits>:: template is_args_match<0, As...>())
{
}
}*/
private:
//查找赋值时期的类型索引号
//返回值:ERR_NO_FIND 没有找到匹配
//返回值:ERR_TYPE_RE 找到多个匹配项
//is_absolute 使用类型绝对匹配, 不使用自动转换.在如果找到多个匹配项下设置此值重新查找一遍.
//Index:当前索引号
//find_count:匹配次数,仅is_absolute==false时有效
//find_index:找到的索引号
template
constexpr static int find_type()
{
if constexpr (Index >= type_count) //结尾了
{
if constexpr (find_count == 1)
{
return find_index; //OK 找到了
} else if (find_count == 0)
{
return ERR_NO_FIND; //没有找到
} else {
return ERR_TYPE_RE; //找到多个匹配项
}
} else {
if constexpr (!is_absolute)
{
if constexpr (std::is_convertible_v>)
{
return find_type();
} else {
return find_type();
}
} else {
//类型绝对匹配
if constexpr (easy_traits>:: template cmp_types_absolute())
{
return find_type();
} else {
return find_type();
}
}
}
}
//打印所有函数类型列表
template
void print_lists()
{
if constexpr (Index >= type_count)
{
std::cout << "*************************************************************************\n";
return;
} else {
if constexpr (Index == 0)
{
std::cout << "******************************函数类型列表*******************************\n";
}
using fun_traits = easy_traits>;
fun_traits::print();
print_lists();
}
}
private:
std::any _data;
};
}
//元编程类型
namespace easy {
template
constexpr void static_print()
{
static_assert(val & false, "@debug output...");
}
//判断变量类型
template
struct var_type
{
//退化类型
using BASE_TYPE = typename std::decay::type;
constexpr static bool is_bool() {
return is_type();
};
constexpr static bool is_int() {
return is_type();
};
constexpr static bool is_null_pointer() {
return is_type();
};
template
constexpr static bool is_type() {
//自动退化std::decay
return std::is_same_v;
};
};
//类型列表
template
struct type_list
{
//类型信息:types
template
using types = typename std::tuple_element>::type;
//类型
static const size_t count = sizeof...(Args);
//比较列表-参数为 type_list
template
constexpr static bool cmp_list()
{
if constexpr (T::count != count)
{
return false;
} else {
if constexpr (Index == count)
{
return true;
} else {
if constexpr (std::is_same_v, typename T:: template types>)
{
return cmp_list();
} else {
return false;
}
}
}
}
};
//函数
template
struct fun_type;
template
struct fun_type>
{
typedef R result_type; //返回值类型
using args = type_list; //参数信息
};
/*
//比较两组类型是否一致(两个args_traits类型)
template
constexpr static bool cmp_args_type()
{
if constexpr (T1::count != T2::count)
{
return false;
} else {
if constexpr (Index == T1::count)
{
return true;
} else {
if constexpr (std::is_same_v, typename T2:: template types>)
{
return cmp_args_type();
} else {
return false;
}
}
}
}
*/
//判断参数类型
//template
//struct param_type;
//通用函数类型
template
class eFun
{
public:
template
using types = typename std::tuple_element>::type;
//函数类型个数
static const size_t count = sizeof...(Args);
//构造函数
template
eFun(T&& fun)
{
static_assert(count > 0, "该类需要添加函数类型.");
//查找匹配的函数类型
constexpr int Index = find_convertible();
if constexpr (Index == -1)
{
static_assert(Index >= 0, "不支持的函数类型.");
return;
}
_data = std::move((types)fun);
}
//按照给定类型,查找类型能否转换
//能的话返回其Index,否则返回-1
//注意is_from变量
template
constexpr static int find_convertible()
{
if constexpr (Index >= count)
{
return -1;
} else if constexpr (is_from ? std::is_convertible_v> : std::is_convertible_v, T>)
{
return Index;
} else {
return find_convertible();
}
}
/*
//构造函数
template
eFun(T&& t)
{
if constexpr (std::is_convertible_v)
{
fun = std::move((F1&&)t);
} else if constexpr (std::is_convertible_v)
{
fun = std::move((F2&&)t);
} else
{
//不支持回调函数类型
static_assert(0, "easy error unknown callback type");
}
}
//调用函数
template
auto operator()(Args&& ... args)
{
//函数1参数类型
typedef fun_type::args fun1_args;
if constexpr (fun1_args::is_match())
{
int x = 0;
} else {
//参数类型错误.
#ifdef WIN32
static_assert(0, "param type error");
#else
static_assert(0, "参数类型错误");
#endif
}
//constexpr auto i = args_type::nargs;
//完全匹配函数
return;
}*/
private:
std::any _data;
//int16_t _fun_type = -1;
};
using myFun = eFun<
std::function
, std::function
>;
/*
template
struct function_traits
{
typedef decltype(((LAMBDA*)0)->operator()()) return_type;
//using return_type = RET;
};
template
struct function_traits
{
//typedef RET return_type;
using return_type = RET;
};
template
struct function_traits
{
using return_type = RET;
};
template < typename F >
void foo(F f) {
using X = function_traits::return_type;
X abc;
int x = 0;
//return f();
}*/
}
#ifndef V8PP_UTILITY_HPP_INCLUDED
#define V8PP_UTILITY_HPP_INCLUDED
//修改自v8pp项目
//项目地址:https://github.com/pmed/v8pp
#include
#include
#include
#include
#include
namespace traits {
template
struct tuple_tail;
template
struct tuple_tail>
{
using type = std::tuple;
};
struct none
{
};
/////////////////////////////////////////////////////////////////////////////
//
// is_string
//
template
struct is_string : std::false_type
{
};
template
struct is_string> : std::true_type
{
};
template
struct is_string> : std::true_type
{
};
template<>
struct is_string : std::true_type
{
};
template<>
struct is_string : std::true_type
{
};
template<>
struct is_string : std::true_type
{
};
template<>
struct is_string : std::true_type
{
};
/////////////////////////////////////////////////////////////////////////////
//
// is_mapping
//
template
struct is_mapping_impl : std::false_type
{
};
template
struct is_mapping_impl().begin()), decltype(std::declval().end())>> : std::true_type
{
};
template
using is_mapping = is_mapping_impl;
/////////////////////////////////////////////////////////////////////////////
//
// is_sequence
//
template
struct is_sequence_impl : std::false_type
{
};
template
struct is_sequence_impl().begin()), decltype(std::declval().end()),
decltype(std::declval().emplace_back(std::declval()))>> : std::negation>
{
};
template
using is_sequence = is_sequence_impl;
/////////////////////////////////////////////////////////////////////////////
//
// has_reserve
//
template
struct has_reserve_impl : std::false_type
{
};
template
struct has_reserve_impl().reserve(0))>> : std::true_type
{
};
template
using has_reserve = has_reserve_impl;
/////////////////////////////////////////////////////////////////////////////
//
// is_array
//
template
struct is_array : std::false_type
{
};
template
struct is_array> : std::true_type
{
static constexpr size_t length = N;
};
/////////////////////////////////////////////////////////////////////////////
//
// is_tuple
//
template
struct is_tuple : std::false_type
{
};
template
struct is_tuple> : std::true_type
{
};
/////////////////////////////////////////////////////////////////////////////
//
// is_shared_ptr
//
template
struct is_shared_ptr : std::false_type
{
};
template
struct is_shared_ptr> : std::true_type
{
};
/////////////////////////////////////////////////////////////////////////////
//
// Function traits
//
template
struct function_traits;
template<>
struct function_traits
{
using return_type = void;
using arguments = std::tuple<>;
template
using pointer_type = void;
};
template
struct function_traits
{
using return_type = R;
using arguments = std::tuple;
template
using pointer_type = R(*)(Args...);
};
// function pointer
template
struct function_traits
: function_traits
{
};
// member function pointer
template
struct function_traits
: function_traits
{
using class_type = C;
template
using pointer_type = R(D::*)(Args...);
};
// const member function pointer
template
struct function_traits
: function_traits
{
using class_type = C const;
template
using pointer_type = R(D::*)(Args...) const;
};
// volatile member function pointer
template
struct function_traits
: function_traits
{
using class_type = C volatile;
template
using pointer_type = R(D::*)(Args...) volatile;
};
// const volatile member function pointer
template
struct function_traits
: function_traits
{
using class_type = C const volatile;
template
using pointer_type = R(D::*)(Args...) const volatile;
};
// member object pointer
template
struct function_traits
: function_traits
{
using class_type = C;
template
using pointer_type = R(D::*);
};
// const member object pointer
template
struct function_traits
: function_traits
{
using class_type = C const;
template
using pointer_type = const R(D::*);
};
// volatile member object pointer
template
struct function_traits
: function_traits
{
using class_type = C volatile;
template
using pointer_type = volatile R(D::*);
};
// const volatile member object pointer
template
struct function_traits
: function_traits
{
using class_type = C const volatile;
template
using pointer_type = const volatile R(D::*);
};
// function object, std::function, lambda
template
struct function_traits
{
static_assert(!std::is_bind_expression::value,
"std::bind result is not supported yet");
private:
using callable_traits = function_traits;
public:
using return_type = typename callable_traits::return_type;
using arguments = typename tuple_tail::type;
template
using pointer_type = typename callable_traits::template pointer_type;
};
template
struct function_traits : function_traits
{
};
template
struct function_traits : function_traits
{
};
template
inline constexpr bool is_void_return = std::is_same_v::return_type>;
template
struct is_callable_impl
: std::is_function::type>
{
};
template
struct is_callable_impl
{
private:
struct fallback { void operator()(); };
struct derived : F, fallback {};
template
struct check;
template
static std::true_type test(...);
template
static std::false_type test(check*);
using type = decltype(test(0));
public:
static constexpr bool value = type::value;
};
template
using is_callable = std::integral_constant::value>::value>;
/// Type information for custom RTTI
class type_info
{
public:
constexpr std::string_view name() const { return name_; }
constexpr bool operator==(type_info const& other) const { return name_ == other.name_; }
constexpr bool operator!=(type_info const& other) const { return name_ != other.name_; }
private:
template constexpr friend type_info type_id();
constexpr explicit type_info(std::string_view name)
: name_(name)
{
}
std::string_view name_;
};
/// Get type information for type T
/// The idea is borrowed from https://github.com/Manu343726/ctti
template
constexpr type_info type_id()
{
#if defined(_MSC_VER) && !defined(__clang__)
std::string_view name = __FUNCSIG__;
const std::initializer_list all_prefixes{ "type_id<", "struct ", "class " };
const std::initializer_list any_suffixes{ ">" };
#elif defined(__clang__) || defined(__GNUC__)
std::string_view name = __PRETTY_FUNCTION__;
const std::initializer_list all_prefixes{ "T = " };
const std::initializer_list any_suffixes{ ";", "]" };
#else
#error "Unknown compiler"
#endif
for (auto&& prefix : all_prefixes)
{
const auto p = name.find(prefix);
if (p != name.npos)
{
name.remove_prefix(p + prefix.size());
}
}
for (auto&& suffix : any_suffixes)
{
const auto p = name.rfind(suffix);
if (p != name.npos)
{
name.remove_suffix(name.size() - p);
break;
}
}
return type_info(name);
}
template
struct easy_traits
{
private:
static constexpr size_t offset = Offset;
static constexpr bool is_mem_fun = std::is_member_function_pointer::value;
public:
using arguments = typename function_traits::arguments;
private:
template
struct tuple_element
{
using type = typename std::tuple_element::type;
};
template
struct tuple_element
{
using type = void;
};
public:
using return_type = typename function_traits::return_type;
static constexpr size_t arg_count = std::tuple_size::value - is_mem_fun - offset;
template
using arg_type = typename tuple_element < Index + is_mem_fun, Index<(arg_count + offset)>::type;
//判断类型转换比较
template
constexpr static bool is_conver()
{
if (std::is_same_v<_from, _to>) //完全匹配.
{
return true;
}
return false;
}
//赋值时的类型绝对匹配
template
constexpr static bool cmp_types_absolute()
{
if constexpr (Index >= (int)arg_count)
{
return true;
} else if constexpr (Index == -1) //-1时检测参数个数与返回值类型
{
//检查参数个数
if constexpr (arg_count != easy_traits::arg_count)
{
return false;
}
//检查返回值类型
if constexpr (!std::is_same_v::return_type, return_type>)
{
return false;
} else {
return cmp_types_absolute();
}
} else {
if constexpr (!std::is_same_v::template arg_type, arg_type>)
{
return false;
} else {
return cmp_types_absolute();
}
}
}
//判断按照指定类型能否调用该函数
template
constexpr static bool is_match_call()
{
return true;
}
//匹配参数列表
template
constexpr static bool is_args_match()
{
constexpr size_t cur_size = sizeof... (Args);
if constexpr (Index >= cur_size)
{
return true;
} else {
using cur_type = typename std::tuple_element>::type;
if constexpr (!std::is_convertible_v>)
{
return false;
} else {
return is_args_match();
}
}
}
//打印函数类型信息
static void print(const char* sign = nullptr)
{
if (sign)
{
std::cout << sign << ":\t";
}
std::cout << get_return_type_string() << "(";
print_args_string();
std::cout << ")" << std::endl;
}
//打印全部参数
template
static void print_args_string()
{
if constexpr (Index >= count)
{
return;
} else {
if constexpr (Index != 0)
{
std::cout << ",";
}
std::cout << get_args_type_string();
print_args_string();
}
}
//得到返回类型字符串
constexpr static auto get_return_type_string()
{
return type_id().name();
}
//得到指定位置参数类型字符串
template
constexpr static auto get_args_type_string()
{
return type_id>().name();
}
/*
template,
typename U = std::remove_pointer_t>
using arg_converter = typename std::conditional_t<
is_wrapped_class>::value,
std::conditional_t,
typename Traits::template convert_ptr,
typename Traits::template convert_ref>,
convert>>;
template
static decltype(auto) arg_from_v8(v8::FunctionCallbackInfo const& args)
{
// might be reference
auto result = (arg_converter, Traits>::from_v8(args.GetIsolate(), args[Index - offset]));
return result;
}*/
};
} // namespace traits
#endif // V8PP_UTILITY_HPP_INCLUDED
namespace detail {
//出自:https://zhuanlan.zhihu.com/p/102240099
template
struct __function_traits_base {
using fun_type = std::function;
using ret_type = R;
using args_types = std::tuple;
};
template
struct __function_traits;
template
struct __function_traits> : public __function_traits {};
template
struct __function_traits : public __function_traits_base {};
template
struct __function_traits : public __function_traits_base {};
template
struct __function_traits : public __function_traits_base {};
template
struct __function_traits : public __function_traits {};
}
template
struct fun_traits : public detail::__function_traits> {};
/*
template typename T1
, template typename T2>
auto test_1(std::function && ff)
{
R x;
return 1;
}*/