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 |