北大黄雨松同学为北太天元开发插件的知识点-typeid的使用

/**
* 北太天元的插件开发示例,这个还不是完整的,我这几天的视频的想法是
* 每次介绍很少的几个知识点。 这是和前一个视频相比增加了
* 类型检查。
*/
#include <cstdlib>
#include <iostream>
#include <typeinfo>
#include <utility>
#include <array>
#include <map>
#include <vector>
#include "bex/bex.hpp"
namespace ParseParams {
template <class _T>
class FunTrait;
template <typename R, typename... Args>
class FunTrait<R(Args...)>{
public:
static constexpr size_t n_args = sizeof...(Args);
static constexpr const std::array<const std::type_info *, n_args> infos = {&typeid(Args)...};
public:
int required_params;
std::array<void *, n_args> passed_args_ptr;
//变量类型函数句柄, 变量名是decorated_func
R(*decorated_func)
(Args...);
public:
FunTrait(R (*func)(Args...), int num_required = 0){
decorated_func = func;
required_params = num_required;
}
template <size_t... I>
R eval_impl(std::index_sequence<I...>){
std::cout<<"必须的参数个数是 = " << required_params << std::endl;
return decorated_func((Args)passed_args_ptr[I]...);
}
R eval(){
return eval_impl(std::make_index_sequence<n_args>());
}
int check_in_args_type(int nrhs, const bxArray * prhs[]){
for(size_t i= 0; i< n_args; i++){
std::cout<<"类型"<<i<<std::endl;
std::cout<<infos[i]->name() <<std::endl;
std::cout<<"const double *的类型名称:"<<typeid(const double *).name() <<std::endl;
std::cout<<"double *的类型名称:" <<typeid(double *).name() <<std::endl;
std::cout<<typeid(const int32_t *).name() <<std::endl;
std::cout<<typeid(int32_t *).name() <<std::endl;
std::cout<<typeid(const int64_t *).name() <<std::endl;
std::cout<<typeid(int64_t *).name() <<std::endl;
std::cout<<typeid(const std::string *).name() <<std::endl;
std::cout<<typeid(std::string *).name() <<std::endl;
if(infos[i]->name() == typeid(const double *).name()){
if(!bxIsDouble(prhs[i])){
bxPrintf("第%d输入参数必须是double类型",i);
return 1;
}
passed_args_ptr[i] = (void *)(bxGetDoubles(prhs[i]));
}
else if(infos[i]->name() == typeid(const int32_t *).name()){
if(!bxIsInt32(prhs[i])){
bxPrintf("第%d输入参数必须是int32类型",i);
return 1;
}
passed_args_ptr[i] = (void *)(bxGetInt32s(prhs[i]));
}
else if(infos[i]->name() == typeid(const int64_t *).name()){
if(!bxIsInt64(prhs[i])){
bxPrintf("第%d输入参数必须是int64类型",i);
return 1;
}
passed_args_ptr[i] = (void *)(bxGetInt64s(prhs[i]));
}
else if(infos[i]->name() == typeid(const std::string *).name()){
if(!bxIsString(prhs[i])){
bxPrintf("第%d输入参数必须是string类型",i);
return 1;
}
passed_args_ptr[i] = (void *)(new std::string(bxGetStringDataPr(prhs[i])));
/**
* 这儿new 的东西,没有delete,会有内存泄漏
*/
}
else {
bxPrintf("第%d输入参数类型不对",i);
return 1;
}
}
return 0;
}
};
}
char h(const int *j , const std::string *str ){
std::cout<<" *j = "<<*j << std::endl;
std::cout<<" *str = "<<*str << std::endl;
std::cout<<" (*str)[*j] = "<<(*str)[*j]<< std::endl;
return (*str)[*j];
}
void cmd_h(int nlhs, bxArray *plhs[], int nrhs, const bxArray *prhs[]) {
ParseParams::FunTrait<decltype(h)> q(h,0);
if(nrhs < q.n_args ){
bxPrintf("输入参数%d < %d", nrhs, q.n_args);
return;
}
if(0 != q.check_in_args_type(nrhs, prhs)){
bxPrintf("输入参数赋值出错\n");
return;
}
auto result = q.eval();
}
static bexfun_info_t flist[] = {
{"cmd_h", cmd_h, nullptr},
{"", nullptr, nullptr},
};
bexfun_info_t *bxPluginFunctions() {
return flist;
}