c++模板偏特化及function_traits检测模板函数返回值和参数合法性

template <typename MessageT, typename  std::enable_if<std::is_trivial<MessageT>::value &&
                                                                    std::is_standard_layout<MessageT>::value,MessageT>::type* = nullptr>
    std::shared_ptr<Subscriber> CreateSubscriber(const std::string &topic_name, SubCbFuncType<MessageT> callback) {
       // char *topic_type =  abi::__cxa_demangle(typeid(MessageT).name(), 0, 0, 0);
        char topic_type[32];
        snprintf(topic_type,32,"t%d",(int)sizeof(MessageT));
        topic_type[31] = 0;
        
        if ((0 == topic_name.length()) || (0 == strlen(topic_type))) {
            cpp_fatal("Error: Topic name or type string length is zero!!!\n");
            return nullptr;
        }
        if ((topic_name.npos != topic_name.find(" ")) || (topic_name.npos != topic_name.find(" "))) {
            cpp_fatal("Error: Topic name or type string can not use space char!!!\n");
            return nullptr;
        }
        std::shared_ptr<Subscriber> suber = _CreateSub(topic_name, topic_type);

        int32_t ret = __RegSub(topic_name.c_str(), topic_type, UsualCbkImpl<SubCbFuncType<MessageT>, MessageT>,
                               reinterpret_cast<void *>(callback));

        if (kDdsRetOK != ret) {
         //   free(topic_type);
            return nullptr;
        }
      //  free(topic_type);
        return suber;
    }
    
    std::shared_ptr<Subscriber> _CreateSub(std::string topic, char *topic_type);
    
#if PROTOBUF_ENABLE == 1
    template <typename MessageT, typename  std::enable_if<
                                     (std::is_trivial<MessageT>::value && std::is_standard_layout<MessageT>::value) ||
                                     std::is_base_of<google::protobuf::Message, MessageT>::value ||
                                     std::is_base_of<google::protobuf::MessageLite, MessageT>::value||
                                     std::is_base_of<CustomizeMsg,MessageT>::value,MessageT>::type* = nullptr>
#else
    template <typename MessageT, typename  std::enable_if<(std::is_trivial<MessageT>::value &&
                                                                     std::is_standard_layout<MessageT>::value)||
                                                                     std::is_base_of<CustomizeMsg,MessageT>::value,MessageT>::type* = nullptr>
#endif
    std::shared_ptr<Subscriber> CreateSubscriber(const std::string &topic_name,
                                                  SubCbFuncTypeShare<MessageT> callback) {
     //   char *topic_type = nullptr;
      //  topic_type = abi::__cxa_demangle(typeid(MessageT).name(), 0, 0, 0);
        char topic_type[32];
        snprintf(topic_type,32,"t%d",(int)sizeof(MessageT));
        topic_type[31] = 0;
       
        if ((0 == topic_name.length()) || (0 == strlen(topic_type))) {
            cpp_fatal("Error: Topic name or type string length is zero!!!\n");
            return nullptr;
        }
        if ((topic_name.npos != topic_name.find(" ")) || (topic_name.npos != topic_name.find(" "))) {
            cpp_fatal("Error: Topic name or type string can not use space char!!!\n");
            return nullptr;
        }

        std::shared_ptr<Subscriber> suber = _CreateSub(topic_name, topic_type);
        int32_t ret = __RegSub(topic_name.c_str(), topic_type, CbkImpl<SubCbFuncTypeShare<MessageT>, MessageT>,
                               reinterpret_cast<void *>(callback));

        if (kDdsRetOK != ret) {
         //   free(topic_type);
            return nullptr;
        }
     //   free(topic_type);
        return suber;
    }

#if PROTOBUF_ENABLE == 1
    template <typename MessageT, typename  std::enable_if<
                                     (std::is_trivial<MessageT>::value && std::is_standard_layout<MessageT>::value) ||
                                     std::is_base_of<google::protobuf::Message, MessageT>::value ||
                                     std::is_base_of<google::protobuf::MessageLite, MessageT>::value||
                                     std::is_base_of<CustomizeMsg,MessageT>::value,MessageT>::type* = nullptr>
#else
    template <typename MessageT, typename  std::enable_if<(std::is_trivial<MessageT>::value &&
                                                                     std::is_standard_layout<MessageT>::value)||
                                                                     std::is_base_of<CustomizeMsg,MessageT>::value,MessageT>::type* = nullptr>
#endif
    std::shared_ptr<Subscriber> CreateSubscriber(const std::string &topic_name, const SubCbFuncTypeUnif<MessageT> &callback) {
   static_assert(std::is_same<typename FuncTraits<typename std::decay<decltype(callback)>::type>::template args<0>::type,
        std::shared_ptr<MessageT const>&>::value, 
                "second arg invalid type");  
#if PROTOBUF_ENABLE == 1
        static_assert((std::is_trivial<MessageT>::value && std::is_standard_layout<MessageT>::value) ||
                          std::is_base_of<google::protobuf::Message, MessageT>::value ||
                          std::is_base_of<google::protobuf::MessageLite, MessageT>::value||
                                                  std::is_base_of<CustomizeMsg,MessageT>::value,
                      "Lambda func's args type is NOT POD or protobuf!");
#else
        static_assert((std::is_trivial<MessageT>::value && std::is_standard_layout<MessageT>::value)||
                                                  std::is_base_of<CustomizeMsg,MessageT>::value,
                      "Lambda func's args type is NOT POD!");
#endif
      //  char *topic_type = nullptr;
     //   topic_type = abi::__cxa_demangle(typeid(MessageT).name(), 0, 0, 0);
        char topic_type[32];
        snprintf(topic_type,32,"t%d",(int)sizeof(MessageT));
        topic_type[31] = 0;
        
        if ((0 == topic_name.length()) || (0 == strlen(topic_type))) {
            cpp_fatal("Error: Topic name or type string length is zero!!!\n");
            return nullptr;
        }
        if ((topic_name.npos != topic_name.find(" ")) || (topic_name.npos != topic_name.find(" "))) {
            cpp_fatal("Error: Topic name or type string can not use space char!!!\n");
            return nullptr;
        }

        std::shared_ptr<Subscriber> suber = _CreateSub(topic_name, topic_type);

        std::shared_ptr<SubCbFuncTypeUnif<MessageT>> cb_func = std::make_shared<SubCbFuncTypeUnif<MessageT>>(callback);
        int32_t ret = __RegSub(topic_name.c_str(), topic_type, CbkImpl<SubCbFuncTypeUnif<MessageT> *, MessageT>,
                               reinterpret_cast<void *>(const_cast<SubCbFuncTypeUnif<MessageT> *>(cb_func.get())));

        if (kDdsRetOK != ret) {
         //   free(topic_type);`
            return nullptr;
        }
        // cpp_fatal("bos cb ref cnt %d!!!\n", cb_func.use_count());
        RegFuncList([cb_func]() {
        });
        // cpp_fatal("bos cb ref cnt %d!!!\n", cb_func.use_count());
     //   free(topic_type);
        return suber;
    }
    #if PROTOBUF_ENABLE == 1
    template <typename MessageT, typename  std::enable_if<
                                     (std::is_trivial<MessageT>::value && std::is_standard_layout<MessageT>::value) ||
                                     std::is_base_of<google::protobuf::Message, MessageT>::value ||
                                     std::is_base_of<google::protobuf::MessageLite, MessageT>::value||
                                     std::is_base_of<CustomizeMsg,MessageT>::value,MessageT>::type* = nullptr>
#else
    template <typename MessageT, typename  std::enable_if<(std::is_trivial<MessageT>::value &&
                                                                     std::is_standard_layout<MessageT>::value)||
                                                                     std::is_base_of<CustomizeMsg,MessageT>::value,MessageT>::type* = nullptr>
#endif
    std::shared_ptr<Subscriber> CreateSubscriber(const std::string &topic_name, const SubCbFuncTypeRefUnif<MessageT> &callback) {
    static_assert(std::is_same<typename FuncTraits<typename std::decay<decltype(callback)>::type>::template args<0>::type,
        MessageT&>::value, 
                "second arg invalid type"); 
#if PROTOBUF_ENABLE == 1
        static_assert((std::is_trivial<MessageT>::value && std::is_standard_layout<MessageT>::value) ||
                          std::is_base_of<google::protobuf::Message, MessageT>::value ||
                          std::is_base_of<google::protobuf::MessageLite, MessageT>::value||
                                                  std::is_base_of<CustomizeMsg,MessageT>::value,
                      "Lambda func's args type is NOT POD or protobuf!");
#else
        static_assert((std::is_trivial<MessageT>::value && std::is_standard_layout<MessageT>::value)||
                                                  std::is_base_of<CustomizeMsg,MessageT>::value,
                      "Lambda func's args type is NOT POD!");
#endif


      
        std::shared_ptr<Subscriber> suber ;

        return suber;

}
template <typename CallbackT>
    std::shared_ptr<Subscriber> CreateSubscriber(const std::string &topic_name, const CallbackT &callback) {
        if (0 == topic_name.length()) {
            cpp_fatal("Error: Topic name or type is none!!!\n");
            return nullptr;
        }
         using CbArg0Type = typename FuncTraits<CallbackT>::template args<0>::type;
       //  static_assert(std::is_same<typename FuncTraits<CallbackT>::template args<0>::type,int>::value, 
           //     "second arg invalid type");
         static_assert((std::is_trivial<typename std::remove_reference<CbArg0Type>::type>::value &&
              std::is_standard_layout<typename std::remove_reference<CbArg0Type>::type>::value) ||
                 std::is_base_of<google::protobuf::Message,typename std::remove_reference<CbArg0Type>::type>::value||
                 std::is_base_of<google::protobuf::MessageLite, typename std::remove_reference<CbArg0Type>::type>::value,
             "Lambda func's args type is NOT POD or protobuf!");
         static_assert(std::is_lvalue_reference<
                           CbArg0Type>::value,
                       "Lambda func's args type is NOT left value reference!");
        using CbRetType = typename FuncTraits<CallbackT>::return_type;
        static_assert(false == FuncTraits<CallbackT>::is_member, "Lambda func should not be member-func");
        static_assert(2 == FuncTraits<CallbackT>::arity, "Lambda func's args should be 2!");
        static_assert(std::is_same<CbRetType, void>::value, "Lambda func's return type is not void!");
        static_assert(std::is_same<typename FuncTraits<CallbackT>::template args<1>::type,MsgMetaInterface*>::value, 
                "Lambda func's secode param type is not MsgMetaInterface!");
        using FuncType = typename FuncTraits<CallbackT>::stl_function_type;
        FuncType cb_func = std::bind(callback,  std::placeholders::_1,std::placeholders::_2);
        Subscriber::SharedPtr suber = CreateSubscriber(topic_name, cb_func);
       // delete cb_func;
        return suber;
    }
    template <typename CallbackT,typename MemberT>
    std::shared_ptr<Subscriber> CreateSubscriber(const std::string &topic_name, const CallbackT &callback,MemberT* mp) {
        if (0 == topic_name.length()) {
            cpp_fatal("Error: Topic name or type is none!!!\n");
            return nullptr;
        }
         using CbArg0Type = typename FuncTraits<CallbackT>::template args<0>::type;
         static_assert((std::is_trivial<typename std::remove_reference<CbArg0Type>::type>::value &&
              std::is_standard_layout<typename std::remove_reference<CbArg0Type>::type>::value) ||
                 std::is_base_of<google::protobuf::Message,typename std::remove_reference<CbArg0Type>::type>::value||
                 std::is_base_of<google::protobuf::MessageLite, typename std::remove_reference<CbArg0Type>::type>::value,
             "Lambda func's args type is NOT POD or protobuf!");
         static_assert(std::is_lvalue_reference<
                           CbArg0Type>::value,
                       "Lambda func's args type is NOT left value reference!");
        using CbRetType = typename FuncTraits<CallbackT>::return_type;
        static_assert(true == FuncTraits<CallbackT>::is_member, "Lambda func should  be member-func");
        static_assert(2 == FuncTraits<CallbackT>::arity, "Lambda func's args should be 2!");
        static_assert(std::is_same<CbRetType, void>::value, "Lambda func's return type is not void!");
        static_assert(std::is_same<typename FuncTraits<CallbackT>::template args<1>::type,MsgMetaInterface*>::value, 
                "Lambda func's secode param type is not MsgMetaInterface!");
        static_assert(std::is_same<MemberT, typename FuncTraits<CallbackT>::class_type>::value, "member type invalid!");
        using FuncType = typename FuncTraits<CallbackT>::stl_function_type;
        FuncType cb_func = std::bind(callback, mp, std::placeholders::_1,std::placeholders::_2);
        Subscriber::SharedPtr suber = CreateSubscriber(topic_name, cb_func);
    //    delete cb_func;
        return suber;
 }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

无v邪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值