개발관련/C&C++

Functional 이용한 델리게이트

Diademata 2018. 4. 26. 11:41
반응형

C++용 소켓 서버/클라이언트 콜백 메소드를 담기위해 만듦.


모든 델리게이터는 MulticastDelegate로만 생성 하거나 상속


NS.h


#pragma once

#ifndef COMMON_H

#define COMMON_H

#define NS_COMMON_BEGIN namespace Util { namespace Common {

#define NS_COMMON_END } }

#define USING_COMMON using namespace Util::Common;

#endif


Delegate.h


#pragma once

#include "NS.h"

#include <functional>

#include <vector>

NS_COMMON_BEGIN

template<typename R, typename T1, typename T2, typename T3, typename T4, typename T5>

class MulticastDelegate;


template<typename R, typename ...Types>

class Delegate

{

private:

template<typename R, typename T1, typename T2, typename T3, typename T4, typename T5>

friend class MulticastDelegate;

protected:

std::vector<std::function<R(Types...)>> _methods;

private:

Delegate();

public:

virtual ~Delegate();

public:

R operator() (Types...);

bool operator != (const Delegate& d) const;

bool operator != (nullptr_t) const;

bool operator == (const Delegate& d) const;

bool operator == (nullptr_t) const;

Delegate& operator = (const nullptr_t);

Delegate& operator = (const std::function<R(Types...)>&);

Delegate& operator += (const std::function<R(Types...)>&);

public:

virtual Delegate& Combine(const Delegate&);

virtual Delegate& operator + (const Delegate&);

};

template<typename R, typename ...Types>

inline Delegate<R, Types...>::Delegate()

{

_methods.clear();

}

template<typename R, typename ...Types>

inline Delegate<R, Types...>::~Delegate()

{

_methods.clear();

}


template<typename R, typename ...Types>

inline Delegate<R, Types...>& Delegate<R, Types...>::Combine(const Delegate<R, Types...>& other)

{

for (auto m : other._methods)

{

_methods.push_back(m);

}

return *this;

}

template<typename R, typename ...Types>

inline Delegate<R, Types...>& Delegate<R, Types...>::operator += (const std::function<R(Types...)>& method)

{

if (method == nullptr)

return;

_methods.push_back(method);

return *this;

}

template<typename R, typename ...Types>

inline Delegate<R, Types...>& Delegate<R, Types...>::operator + (const Delegate<R, Types...>& other)

{

return Combine(other);

}

template<typename R, typename ...Types>

inline Delegate<R, Types...>& Delegate<R, Types...>::operator = (const std::function<R(Types...)>& method)

{

if (method == nullptr)

return *this;

_methods.clear();

_methods.push_back(method);

return *this;

}


template<>

inline void Delegate<void>::operator() ()

{

for (auto m : _methods)

{

m();

}

}

template<typename R, typename ...Types>

inline R Delegate<R, Types...>::operator() (Types... params)

{

for (size_t i = 0; i < _methods.size() - 1; i++)

{

_methods[i](std::forward<Types>(params)...);

}

return _methods.back()(std::forward<Types>(params)...);

}

template<typename R, typename ...Types>

inline bool Delegate<R, Types...>::operator != (nullptr_t) const

{

return _methods.size() != 0;

}


template<typename R, typename ...Types>

inline bool Delegate<R, Types...>::operator != (const Delegate<R, Types...>& del) const

{

return this != &del;

}


template<typename R, typename ...Types>

inline bool Delegate<R, Types...>::operator == (nullptr_t) const

{

return _methods.size() == 0;

}


template<typename R, typename ...Types>

inline bool Delegate<R, Types...>::operator == (const Delegate<R, Types...>& del) const

{

return this == &del;

}


template<typename R, typename ...Types>

inline Delegate<R, Types...>& Delegate<R, Types...>::operator = (const nullptr_t)

{

_methods.clear();

return *this;

}


NS_COMMON_END



MulticastDelegate.h


#pragma once

#include "NS.h"

#include "Delegate.h"

NS_COMMON_BEGIN

template<typename R, typename T1 = void, typename T2 = void, typename T3 = void, typename T4 = void, typename T5 = void>

class MulticastDelegate : public Delegate<R, T1, T2, T3, T4, T5>

{

private :

typedef const std::function<R(T1, T2, T3, T4, T5)> DelegateType;

public:

MulticastDelegate()

{

}

MulticastDelegate(DelegateType& method)

{

this->operator= (method);

}

virtual ~MulticastDelegate() {}

public:

MulticastDelegate& operator = (DelegateType& method);

};

template<typename R, typename T1, typename T2, typename T3, typename T4, typename T5>

inline MulticastDelegate<R, T1, T2, T3, T4, T5>& MulticastDelegate<R, T1, T2, T3, T4, T5>::operator = (DelegateType& method)

{

Delegate<R, T1, T2, T3, T4, T5>::operator = (method);

return *this;

}


template<typename R, typename T1, typename T2, typename T3, typename T4>

class MulticastDelegate<R, T1, T2, T3, T4, void> : public Delegate<R, T1, T2, T3, T4>

{

private:

typedef const std::function<R(T1, T2, T3, T4)> DelegateType;

public:

MulticastDelegate()

{

}

MulticastDelegate(DelegateType method)

{

this->operator= (method);

}

virtual ~MulticastDelegate() {}

public:

MulticastDelegate& operator = (DelegateType& method);

};

template<typename R, typename T1, typename T2, typename T3, typename T4>

inline MulticastDelegate<R, T1, T2, T3, T4>& MulticastDelegate<R, T1, T2, T3, T4>::operator = (DelegateType& method)

{

Delegate<R, T1, T2, T3, T4>::operator = (method);

return *this;

}


template<typename R, typename T1, typename T2, typename T3>

class MulticastDelegate<R, T1, T2, T3, void, void> : public Delegate<R, T1, T2, T3>

{

private:

typedef const std::function<R(T1, T2, T3)> DelegateType;

public:

MulticastDelegate()

{

}

MulticastDelegate(DelegateType& method)

{

this->operator= (method);

}

virtual ~MulticastDelegate() {}

public:

MulticastDelegate& operator = (DelegateType& method);

};

template<typename R, typename T1, typename T2, typename T3>

inline MulticastDelegate<R, T1, T2, T3>& MulticastDelegate<R, T1, T2, T3>::operator = (DelegateType& method)

{

Delegate<R, T1, T2, T3>::operator = (method);

return *this;

}


template<typename R, typename T1, typename T2>

class MulticastDelegate<R, T1, T2, void, void, void> : public Delegate<R, T1, T2>

{

private:

typedef const std::function<R(T1, T2)> DelegateType;

public:

MulticastDelegate()

{

}

MulticastDelegate(DelegateType& method)

{

this->operator= (method);

}

virtual ~MulticastDelegate() {}

public:

MulticastDelegate& operator = (DelegateType& method);

};

template<typename R, typename T1, typename T2>

inline MulticastDelegate<R, T1, T2>& MulticastDelegate<R, T1, T2>::operator = (DelegateType& method)

{

Delegate<R, T1, T2>::operator = (method);

return *this;

}


template<typename R, typename T>

class MulticastDelegate<R, T, void, void, void, void> : public Delegate<R, T>

{

private:

typedef const std::function<R(T)> DelegateType;

public:

MulticastDelegate()

{

}

MulticastDelegate(DelegateType& method)

{

this->operator= (method);

}

virtual ~MulticastDelegate() {}

public:

MulticastDelegate& operator = (DelegateType&);

};

template<typename R, typename T>

inline MulticastDelegate<R, T>& MulticastDelegate<R, T>::operator = (DelegateType& method)

{

Delegate<R, T>::operator = (method);

return *this;

}


template<typename R>

class MulticastDelegate<R, void, void, void, void, void> : public Delegate<R>

{

private:

typedef const std::function<R()> DelegateType;

public:

MulticastDelegate()

{

}

MulticastDelegate(DelegateType& method)

{

this->operator= (method);

}

virtual ~MulticastDelegate() {}

public:

MulticastDelegate& operator = (DelegateType& method);

};


template<typename R>

inline MulticastDelegate<R>& MulticastDelegate<R>::operator = (DelegateType& method)

{

Delegate<R>::operator = (method);

return *this;

}

NS_COMMON_END

반응형

'개발관련 > C&C++' 카테고리의 다른 글

HttpClient  (0) 2018.05.25
MSMQ(MS MessageQueue)  (0) 2018.05.15
IOCP Socket Server 구현  (0) 2018.04.16
StringFormat  (0) 2018.03.20
라이브러리 빌드 전/후 이벤트 명령어  (0) 2018.03.16