#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( int  which, void *  notifyParam)  =  0 ; 
} ; 
 
template < class  T1, class  T2> 
class  MediatorA :  public  MediatorBase
{ 
public : 
    virtual  void  doCommand( int  which, void *  notifyParam) 
    { 
        cout  <<  "-----------------"  <<  endl; 
        cout  <<  "----MediatorA----"  <<  endl; 
        switch  ( which) 
        { 
        case  1 : 
        	show( * static_cast < T1* > ( notifyParam) ) ; 
        	break ; 
        case  2 : 
        	show( * static_cast < T2* > ( notifyParam) ) ; 
        	break ; 
        } 
    } 
} ; 
 
template < class  T1, class  T2> 
class  MediatorB :  public  MediatorBase
{ 
public : 
    virtual  void  doCommand( int  which, void *  notifyParam) 
    { 
        cout  <<  "-----------------"  <<  endl; 
        cout  <<  "----MediatorB----"  <<  endl; 
        switch  ( which) 
        { 
        case  1 : 
        	show( * static_cast < T1* > ( notifyParam) ) ; 
        	break ; 
        case  2 : 
        	show( * static_cast < T2* > ( notifyParam) ) ; 
        	break ; 
        } 
    } 
} ; 
 
#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< decltype( tup1) , decltype( tup2) > , new  MediatorB< decltype( tup1) , decltype( tup2) > } ; 
 
    for ( auto  it :  vt) 
    { 
        it- > doCommand( 1 , & pp1.body ) ; 
        it- > doCommand( 2 , & pp2.body ) ; 
    } 
 
#endif 
 
    return  0 ; 
} 
 
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8c3RyaW5nPgojaW5jbHVkZSA8dHVwbGU+CiNpbmNsdWRlIDx2ZWN0b3I+CgojZGVmaW5lIFVTRV9NRURJQVRPUgoKdXNpbmcgbmFtZXNwYWNlIHN0ZDsKCnRlbXBsYXRlPGNsYXNzIFQ+CnZvaWQgc2hvdyhUIHR1cCkKewogICAgY291dCA8PCAiLS0tLS0tLS0tLS0tLS0tLS0iIDw8IGVuZGw7CiAgICBjb3V0IDw8IGdldDwwPih0dXApIDw8IGVuZGw7CiAgICBjb3V0IDw8IGdldDwxPih0dXApIDw8IGVuZGw7CiAgICBjb3V0IDw8IGdldDwyPih0dXApIDw8IGVuZGw7CiAgICBjb3V0IDw8ICItLS0tLS0tLS0tLS0tLS0tLSIgPDwgZW5kbDsKfQoKdGVtcGxhdGUgPGNsYXNzIFQ+CmNsYXNzIE5vdGlmeVBhcmFtCnsKcHVibGljOgogICAgTm90aWZ5UGFyYW0oVCBib2R5KQogICAgICAgIDpib2R5KGJvZHkpCiAgICB7fQogICAgVCBib2R5Owp9OwoKI2lmZGVmIFVTRV9NRURJQVRPUgoKY2xhc3MgTWVkaWF0b3JCYXNlCnsKcHVibGljOgogICAgdmlydHVhbCB2b2lkIGRvQ29tbWFuZChpbnQgd2hpY2gsIHZvaWQqIG5vdGlmeVBhcmFtKSA9IDA7Cn07Cgp0ZW1wbGF0ZTxjbGFzcyBUMSwgY2xhc3MgVDI+CmNsYXNzIE1lZGlhdG9yQSA6IHB1YmxpYyBNZWRpYXRvckJhc2UKewpwdWJsaWM6CiAgICB2aXJ0dWFsIHZvaWQgZG9Db21tYW5kKGludCB3aGljaCwgdm9pZCogbm90aWZ5UGFyYW0pCiAgICB7CiAgICAgICAgY291dCA8PCAiLS0tLS0tLS0tLS0tLS0tLS0iIDw8IGVuZGw7CiAgICAgICAgY291dCA8PCAiLS0tLU1lZGlhdG9yQS0tLS0iIDw8IGVuZGw7CiAgICAgICAgc3dpdGNoICh3aGljaCkKICAgICAgICB7CiAgICAgICAgY2FzZSAxOgogICAgICAgIAlzaG93KCpzdGF0aWNfY2FzdDxUMSo+KG5vdGlmeVBhcmFtKSk7CiAgICAgICAgCWJyZWFrOwogICAgICAgIGNhc2UgMjoKICAgICAgICAJc2hvdygqc3RhdGljX2Nhc3Q8VDIqPihub3RpZnlQYXJhbSkpOwogICAgICAgIAlicmVhazsKICAgICAgICB9CiAgICB9Cn07Cgp0ZW1wbGF0ZTxjbGFzcyBUMSwgY2xhc3MgVDI+CmNsYXNzIE1lZGlhdG9yQiA6IHB1YmxpYyBNZWRpYXRvckJhc2UKewpwdWJsaWM6CiAgICB2aXJ0dWFsIHZvaWQgZG9Db21tYW5kKGludCB3aGljaCwgdm9pZCogbm90aWZ5UGFyYW0pCiAgICB7CiAgICAgICAgY291dCA8PCAiLS0tLS0tLS0tLS0tLS0tLS0iIDw8IGVuZGw7CiAgICAgICAgY291dCA8PCAiLS0tLU1lZGlhdG9yQi0tLS0iIDw8IGVuZGw7CiAgICAgICAgc3dpdGNoICh3aGljaCkKICAgICAgICB7CiAgICAgICAgY2FzZSAxOgogICAgICAgIAlzaG93KCpzdGF0aWNfY2FzdDxUMSo+KG5vdGlmeVBhcmFtKSk7CiAgICAgICAgCWJyZWFrOwogICAgICAgIGNhc2UgMjoKICAgICAgICAJc2hvdygqc3RhdGljX2Nhc3Q8VDIqPihub3RpZnlQYXJhbSkpOwogICAgICAgIAlicmVhazsKICAgICAgICB9CiAgICB9Cn07CgojZW5kaWYKCmludCBtYWluICgpCnsKICAgIGF1dG8gdHVwMSA9IG1ha2VfdHVwbGUoIkEiLCAxLCAwLjMpOwogICAgTm90aWZ5UGFyYW08ZGVjbHR5cGUodHVwMSk+IHBwMSh0dXAxKTsKICAgIHNob3cocHAxLmJvZHkpOwoKICAgIGF1dG8gdHVwMiA9IG1ha2VfdHVwbGUoIkIiLCAiY2MiLCAxKTsKICAgIE5vdGlmeVBhcmFtPGRlY2x0eXBlKHR1cDIpPiBwcDIodHVwMik7CiAgICBzaG93KHBwMi5ib2R5KTsKCiAjaWZkZWYgVVNFX01FRElBVE9SCgogICAgdmVjdG9yPE1lZGlhdG9yQmFzZSo+IHZ0ID0ge25ldyBNZWRpYXRvckE8ZGVjbHR5cGUodHVwMSksIGRlY2x0eXBlKHR1cDIpPiwgbmV3IE1lZGlhdG9yQjxkZWNsdHlwZSh0dXAxKSwgZGVjbHR5cGUodHVwMik+fTsKCiAgICBmb3IoYXV0byBpdCA6IHZ0KQogICAgewogICAgICAgIGl0LT5kb0NvbW1hbmQoMSwgJnBwMS5ib2R5KTsKICAgICAgICBpdC0+ZG9Db21tYW5kKDIsICZwcDIuYm9keSk7CiAgICB9CgojZW5kaWYKCiAgICByZXR1cm4gMDsKfQo=