欢迎光临散文网 会员登陆 & 注册

北大同学黄雨松制作的北太天元插件代码阅读后,我想到可以用c++17 的 if c

2023-05-15 09:59 作者:卢朓  | 我要投稿

/**

 * 北太天元的插件开发示例,这个还不是完整的,我这几天的视频的想法是

 * 每次介绍很少的几个知识点,面向的对象是对c++11之后的特性不熟悉的同学。

 * 这是和前一个视频相比增加了if constexpr 实现编译期计算的功能。

 */


#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++){

               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;

         }


         void return_to_bxArray(R result, int nlhs, bxArray *plhs[]){

            if(nlhs <= 0 ) return;

            if constexpr (std::is_same<char, R>::value){

               char tmp[2] ={result, '\0'};

               plhs[0] = bxCreateString(tmp);   

            }   

            else if constexpr (std::is_same<int32_t,R>::value){

               plhs[0] = bxCreateInt32Scalar(result);

            }

            else if constexpr (std::is_same<double,R>::value){

               plhs[0] = bxCreateDoubleMatrix(1,1,bxREAL);

               double * ptr = bxGetDoubles(plhs[0]);

               *ptr = result;

            }   

            else if constexpr (std::is_same<std::string,R>::value){

               plhs[0] = bxCreateString(result.c_str());

            }

         }


      };

}



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();

   q.return_to_bxArray(result, nlhs, plhs);


}



static bexfun_info_t flist[] = {

 {"cmdd_h", cmd_h, nullptr},

 {"", nullptr, nullptr},

};


bexfun_info_t *bxPluginFunctions() {

 return flist;

}



北大同学黄雨松制作的北太天元插件代码阅读后,我想到可以用c++17 的 if c的评论 (共 条)

分享到微博请遵守国家法律