Skip to content

Instantly share code, notes, and snippets.

@TABETA
Created March 28, 2016 21:11
Show Gist options
  • Save TABETA/7418918c3182606624a5 to your computer and use it in GitHub Desktop.
Save TABETA/7418918c3182606624a5 to your computer and use it in GitHub Desktop.
メンバ関数ポインタへのコールバックをtemplateで ref: http://qiita.com/abedominal/items/9cca99e10cf4eac1708f
#pragma once
#include "Singleton.hpp"
using namespace std;
struct Listner
{
public:
Listner() {}
virtual ~Listner(){}
virtual void execute() = 0;
};
enum ListnerName
{
Listner_start = -1,
Listner1_event1 = 0,
Listner1_event2,
Listner_end,
};
class Caster
{
public:
Caster()
{
}
bool initialize()
{
return initialize<Listner_start>();
}
void run()
{
for (int i = 0; i < Listner_end; ++i)
{
listners_[i]->execute();
}
}
~Caster()
{
for (int i = 0; i < Listner_end; ++i)
{
delete listners_[i];
}
}
private:
template<ListnerName N>
bool initialize();
template<>
bool initialize<Listner_start>()
{
const ListnerName next = static_cast<ListnerName>(Listner_start + 1);
return initialize<next>();
}
template<>
bool initialize<Listner_end>()
{
return true;
}
template <typename T>
class ConcreteListner : public Listner
{
public:
ConcreteListner(void(T::*func)())
: func_(func) {}
~ConcreteListner(){}
void execute() { (T::getInstance()->*func_)(); }
private:
void (T::*func_)();
};
Listner* listners_[Listner_end];
};
template<ListnerName N> struct listner_traits;
template<ListnerName N>
bool Caster::initialize()
{
if ((listners_[N] = new(std::nothrow) ConcreteListner<listner_traits<N>::object_t>(listner_traits<N>::cb)) == 0)
{
return false;
}
return initialize<static_cast<ListnerName>(N+1)>();
}
#pragma once
#include <iostream>
#include "Singleton.hpp"
using namespace std;
class Listner1 : public Singleton<Listner1>
{
public:
void event1()
{
cout << "event1" << endl;
}
void event2()
{
cout << "event2" << endl;
}
};
template<>
struct listner_traits<Listner1_event1>
{
typedef Listner1 object_t;
typedef void(Listner1::*callBack)();
static const callBack cb;
};
const listner_traits<Listner1_event1>::callBack listner_traits<Listner1_event1>::cb = &Listner1::event1;
template<>
struct listner_traits<Listner1_event2>
{
typedef Listner1 object_t;
typedef void(Listner1::*callBack)();
static const callBack cb;
};
const listner_traits<Listner1_event2>::callBack listner_traits<Listner1_event2>::cb = &Listner1::event2;
#include "Singleton.hpp"
#include "Caster.hpp"
#include "Listner1.hpp"
using namespace std;
int main(int argv, char* argc[])
{
Caster caster;
caster.initialize();
caster.run();
return 0;
}
#pragma once
template <typename T>
class Singleton
{
protected:
Singleton(){}
Singleton(Singleton const&);
~Singleton(){}
Singleton& operator=(Singleton const&);
public:
static T* getInstance()
{
static T i;
return &i;
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment