Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rtt_roscomm: fixed compilation of service plugins with Clang #133

Merged
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 37 additions & 30 deletions rtt_roscomm/include/rtt_roscomm/rtt_rosservice_proxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
#include <rtt/internal/GlobalEngine.hpp>
#include <rtt/plugin/ServicePlugin.hpp>

#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_void.hpp>

//! Abstract ROS Service Proxy
class ROSServiceProxyBase
{
Expand Down Expand Up @@ -46,7 +49,9 @@ class ROSServiceServerOperationCallerBase {
};

template<class ROS_SERVICE_T, int variant = 0>
struct ROSServiceServerOperationCallerWrapper;
struct ROSServiceServerOperationCallerWrapper {
typedef void ProxyOperationCallerType;
};

// Default implementation of an OperationCaller that fowards ROS service calls to Orocos operations
// that have the default bool(Request&, Response&) signature. You can add more variants of this class
Expand All @@ -66,7 +71,7 @@ struct ROSServiceServerOperationCallerWrapper<ROS_SERVICE_T,0> {
template<class ROS_SERVICE_T, int variant = 0>
class ROSServiceServerOperationCaller : public ROSServiceServerOperationCallerBase<ROS_SERVICE_T> {
public:
using typename ROSServiceServerOperationCallerBase<ROS_SERVICE_T>::Ptr;
typedef typename ROSServiceServerOperationCallerBase<ROS_SERVICE_T>::Ptr Ptr;

//! The wrapper type for this variant
typedef ROSServiceServerOperationCallerWrapper<ROS_SERVICE_T, variant> Wrapper;
Expand All @@ -75,14 +80,7 @@ class ROSServiceServerOperationCaller : public ROSServiceServerOperationCallerBa
typedef typename Wrapper::ProxyOperationCallerType ProxyOperationCallerType;
typedef boost::shared_ptr<ProxyOperationCallerType> ProxyOperationCallerTypePtr;

static Ptr connect(RTT::OperationInterfacePart* operation) {
ProxyOperationCallerTypePtr proxy_operation_caller
= boost::make_shared<ProxyOperationCallerType>(operation->getLocalOperation(), RTT::internal::GlobalEngine::Instance());
if (proxy_operation_caller->ready()) {
return Ptr(new ROSServiceServerOperationCaller<ROS_SERVICE_T, variant>(proxy_operation_caller));
}
return NextVariant<void>::connect(operation);
}
static Ptr connect(RTT::OperationInterfacePart* operation);

virtual bool call(typename ROS_SERVICE_T::Request& request, typename ROS_SERVICE_T::Response& response) const {
// Check if the operation caller is ready, and then call it.
Expand All @@ -91,32 +89,41 @@ class ROSServiceServerOperationCaller : public ROSServiceServerOperationCallerBa
}

private:
template<typename Dummy> struct Void { typedef void type; };
ROSServiceServerOperationCaller(const boost::shared_ptr<ProxyOperationCallerType>& impl)
: proxy_operation_caller_(impl) {}

template<typename R = void, typename Enabled = void> struct EnableIfHasNextVariant { };
ProxyOperationCallerTypePtr proxy_operation_caller_;
};

template<typename R> struct EnableIfHasNextVariant<R,
typename Void<typename ROSServiceServerOperationCallerWrapper<ROS_SERVICE_T, variant + 1>::ProxyOperationCallerType>::type> {
typedef R type;
};
namespace {

template<typename R = void, typename Enabled = void>
struct NextVariant {
static Ptr connect(RTT::OperationInterfacePart*) { return Ptr(); }
};
template<class ROS_SERVICE_T, int variant, typename Enabled = void>
struct ROSServiceServerOperationCallerWrapperNextVariant {
typedef typename ROSServiceServerOperationCallerBase<ROS_SERVICE_T>::Ptr Ptr;
static Ptr connect(RTT::OperationInterfacePart*) { return Ptr(); }
};

template<typename R>
struct NextVariant<R, typename EnableIfHasNextVariant<R>::type> {
static Ptr connect(RTT::OperationInterfacePart* operation) {
return ROSServiceServerOperationCaller<ROS_SERVICE_T, variant + 1>::connect(operation);
}
};
template<class ROS_SERVICE_T, int variant>
struct ROSServiceServerOperationCallerWrapperNextVariant<ROS_SERVICE_T, variant,
typename boost::disable_if<boost::is_void<typename ROSServiceServerOperationCallerWrapper<ROS_SERVICE_T, variant + 1>::ProxyOperationCallerType> >::type> {
typedef typename ROSServiceServerOperationCallerBase<ROS_SERVICE_T>::Ptr Ptr;
static Ptr connect(RTT::OperationInterfacePart* operation) {
return ROSServiceServerOperationCaller<ROS_SERVICE_T, variant + 1>::connect(operation);
}
};

ROSServiceServerOperationCaller(const boost::shared_ptr<ProxyOperationCallerType>& impl)
: proxy_operation_caller_(impl) {}
}

ProxyOperationCallerTypePtr proxy_operation_caller_;
};
template<class ROS_SERVICE_T, int variant>
typename ROSServiceServerOperationCaller<ROS_SERVICE_T, variant>::Ptr
ROSServiceServerOperationCaller<ROS_SERVICE_T, variant>::connect(RTT::OperationInterfacePart* operation) {
ProxyOperationCallerTypePtr proxy_operation_caller
= boost::make_shared<ProxyOperationCallerType>(operation->getLocalOperation(), RTT::internal::GlobalEngine::Instance());
if (proxy_operation_caller->ready()) {
return Ptr(new ROSServiceServerOperationCaller<ROS_SERVICE_T, variant>(proxy_operation_caller));
}
return ROSServiceServerOperationCallerWrapperNextVariant<ROS_SERVICE_T, variant>::connect(operation);
}

template<class ROS_SERVICE_T>
class ROSServiceServerProxy : public ROSServiceServerProxyBase
Expand Down