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;
}
c++模板偏特化及function_traits检测模板函数返回值和参数合法性
于 2024-10-14 16:12:12 首次发布