FairMQ: Support Apple Compiler 8.0

In fact, this commit will workaround a bug with template alias compilation
from Clang 3.4 to Clang 3.8.
This commit is contained in:
Dennis Klein 2017-10-09 18:52:15 +02:00 committed by Mohammad Al-Turany
parent b63e2ee153
commit b7d97f6306
3 changed files with 17 additions and 14 deletions

View File

@ -32,7 +32,7 @@ namespace mq
template<typename K> template<typename K>
struct Event struct Event
{ {
using KeyType = const K; using KeyType = K;
}; };
/** /**
@ -53,16 +53,19 @@ struct Event
class EventManager class EventManager
{ {
public: public:
template<typename E, typename ...Args> // Clang 3.4-3.8 has a bug and cannot properly deal with the following template alias.
using Callback = std::function<void(typename E::KeyType, Args...)>; // Therefore, we leave them here commented out for now.
// template<typename E, typename ...Args>
// using Callback = std::function<void(typename E::KeyType, Args...)>;
template<typename E, typename ...Args> template<typename E, typename ...Args>
using Signal = boost::signals2::signal<void(typename E::KeyType, Args...)>; using Signal = boost::signals2::signal<void(typename E::KeyType, Args...)>;
template<typename E, typename ...Args> template<typename E, typename ...Args>
auto Subscribe(const std::string& subscriber, Callback<E, Args...> callback) -> void auto Subscribe(const std::string& subscriber, std::function<void(typename E::KeyType, Args...)> callback) -> void
{ {
const std::type_index event_type_index{typeid(E)}; const std::type_index event_type_index{typeid(E)};
const std::type_index callback_type_index{typeid(Callback<E, Args...>)}; const std::type_index callback_type_index{typeid(std::function<void(typename E::KeyType, Args...)>)};
const auto signalsKey = std::make_pair(event_type_index, callback_type_index); const auto signalsKey = std::make_pair(event_type_index, callback_type_index);
const auto connectionsKey = std::make_pair(subscriber, signalsKey); const auto connectionsKey = std::make_pair(subscriber, signalsKey);
@ -84,7 +87,7 @@ class EventManager
auto Unsubscribe(const std::string& subscriber) -> void auto Unsubscribe(const std::string& subscriber) -> void
{ {
const std::type_index event_type_index{typeid(E)}; const std::type_index event_type_index{typeid(E)};
const std::type_index callback_type_index{typeid(Callback<E, Args...>)}; const std::type_index callback_type_index{typeid(std::function<void(typename E::KeyType, Args...)>)};
const auto signalsKey = std::make_pair(event_type_index, callback_type_index); const auto signalsKey = std::make_pair(event_type_index, callback_type_index);
const auto connectionsKey = std::make_pair(subscriber, signalsKey); const auto connectionsKey = std::make_pair(subscriber, signalsKey);
@ -95,10 +98,10 @@ class EventManager
} }
template<typename E, typename ...Args> template<typename E, typename ...Args>
auto Emit(typename E::KeyType& key, Args... args) const -> void auto Emit(typename E::KeyType key, Args... args) const -> void
{ {
const std::type_index event_type_index{typeid(E)}; const std::type_index event_type_index{typeid(E)};
const std::type_index callback_type_index{typeid(Callback<E, Args...>)}; const std::type_index callback_type_index{typeid(std::function<void(typename E::KeyType, Args...)>)};
const auto signalsKey = std::make_pair(event_type_index, callback_type_index); const auto signalsKey = std::make_pair(event_type_index, callback_type_index);
(*GetSignal<E, Args...>(signalsKey))(key, std::forward<Args>(args)...); (*GetSignal<E, Args...>(signalsKey))(key, std::forward<Args>(args)...);

View File

@ -95,7 +95,7 @@ class StateMachine
struct StateQueued : Event<State> {}; struct StateQueued : Event<State> {};
auto SubscribeToStateChange(const std::string& subscriber, std::function<void(typename StateChange::KeyType newState, State lastState)> callback) -> void { fCallbacks.Subscribe<StateChange, State>(subscriber, callback); } auto SubscribeToStateChange(const std::string& subscriber, std::function<void(typename StateChange::KeyType newState, State lastState)> callback) -> void { fCallbacks.Subscribe<StateChange, State>(subscriber, callback); }
auto UnsubscribeFromStateChange(const std::string& subscriber) -> void { fCallbacks.Unsubscribe<StateChange, State>(subscriber); } auto UnsubscribeFromStateChange(const std::string& subscriber) -> void { fCallbacks.Unsubscribe<StateChange, State>(subscriber); }
auto SubscribeToStateQueued(const std::string& subscriber, std::function<void(typename StateChange::KeyType newState, State lastState)> callback) -> void { fCallbacks.Subscribe<StateQueued, State>(subscriber, callback); } auto SubscribeToStateQueued(const std::string& subscriber, std::function<void(typename StateQueued::KeyType newState, State lastState)> callback) -> void { fCallbacks.Subscribe<StateQueued, State>(subscriber, callback); }
auto UnsubscribeFromStateQueued(const std::string& subscriber) -> void { fCallbacks.Unsubscribe<StateQueued, State>(subscriber); } auto UnsubscribeFromStateQueued(const std::string& subscriber) -> void { fCallbacks.Unsubscribe<StateQueued, State>(subscriber); }
auto GetCurrentState() const -> State { std::lock_guard<std::mutex> lock{fMutex}; return fState; } auto GetCurrentState() const -> State { std::lock_guard<std::mutex> lock{fMutex}; return fState; }

View File

@ -16,7 +16,7 @@ namespace
using namespace std; using namespace std;
using namespace fair::mq; using namespace fair::mq;
struct TestEvent : fair::mq::Event<std::string> {}; struct TestEvent : fair::mq::Event<const std::string&> {};
TEST(EventManager, Basics) TEST(EventManager, Basics)
{ {
@ -26,14 +26,14 @@ TEST(EventManager, Basics)
int value = 0; int value = 0;
string value2; string value2;
EventManager::Callback<TestEvent, int> callback{ std::function<void(typename TestEvent::KeyType, int)> callback{
[&](TestEvent::KeyType& key, int newValue){ [&](TestEvent::KeyType key, int newValue){
++call_counter; ++call_counter;
if (key == "test") value = newValue; if (key == "test") value = newValue;
} }
}; };
EventManager::Callback<TestEvent, string> callback2{ std::function<void(typename TestEvent::KeyType, string)> callback2{
[&](TestEvent::KeyType& key, string newValue){ [&](TestEvent::KeyType key, string newValue){
++call_counter2; ++call_counter2;
if (key == "test") value2 = newValue; if (key == "test") value2 = newValue;
} }