#include <iostream>
#include <string>
#include <tuple>
#include <vector>

#define USE_MEDIATOR

using namespace std;

template<class T>
void show(T tup)
{
    cout << "-----------------" << endl;
    cout << get<0>(tup) << endl;
    cout << get<1>(tup) << endl;
    cout << get<2>(tup) << endl;
    cout << "-----------------" << endl;
}

template <class T>
class NotifyParam
{
public:
    NotifyParam(T body)
        :body(body)
    {}
    T body;
};

#ifdef USE_MEDIATOR

class MediatorBase
{
public:
    virtual void doCommand(NotifyParam notifyParam) = 0;
};

class MediatorA : public MediatorBase
{
public:
    virtual void doCommand(NotifyParam notifyParam)
    {
        cout << "-----------------" << endl;
        cout << "----MediatorA----" << endl;
        show(notifyParam.body);
    }
};

class MediatorB : public MediatorBase
{
public:
    virtual void doCommand(NotifyParam notifyParam)
    {
        cout << "-----------------" << endl;
        cout << "----MediatorB----" << endl;
        show(notifyParam.body);
    }
};

#endif

int main ()
{
    auto tup1 = make_tuple("A", 1, 0.3);
    NotifyParam<decltype(tup1)> pp1(tup1);
    show(pp1.body);

    auto tup2 = make_tuple("B", "cc", 1);
    NotifyParam<decltype(tup2)> pp2(tup2);
    show(pp2.body);

 #ifdef USE_MEDIATOR

    vector<MediatorBase*> vt = {new MediatorA, new MediatorB};

    for(auto it : vt)
    {
        it->doCommand(pp1.body);
        it->doCommand(pp2.body);
    }

#endif

    return 0;
}
