C++98 用 std::function もどき
- #pragma once
- #include <algorithm>
- #include <stdexcept>
- class FunctionCallException : public std::logic_error
- {
- public:
- FunctionCallException() : logic_error("FunctionCallException")
- {
- }
- };
- template<typename T>
- class Function;
- #define DEFINE_FUNC \
- template<typename TRet TYPENAMES_DECL_C TYPENAMES_DECL> \
- class Function<TRet(TYPES)> \
- { \
- class ICallable \
- { \
- public: \
- virtual ~ICallable() \
- { \
- } \
- \
- virtual TRet operator()(ARGS_DECL) const = 0; \
- virtual ICallable* Clone() const = 0; \
- }; \
- \
- template<typename TObject> \
- class CallableImpl : public ICallable \
- { \
- public: \
- explicit CallableImpl(TObject obj) : m_Object(obj) \
- { \
- } \
- \
- virtual TRet operator()(ARGS_DECL) const \
- { \
- return m_Object(ARGS); \
- } \
- \
- virtual ICallable* Clone() const \
- { \
- return new CallableImpl<TObject>(m_Object); \
- } \
- \
- private: \
- TObject m_Object; \
- }; \
- \
- public: \
- Function() : m_pCallable(NULL) \
- { \
- } \
- \
- template<typename TObject> \
- Function(TObject obj) : m_pCallable(new CallableImpl<TObject>(obj)) \
- { \
- } \
- \
- Function(const Function& rhs) : m_pCallable(rhs.m_pCallable ? rhs.m_pCallable->Clone() : NULL) \
- { \
- } \
- \
- Function& operator=(const Function& rhs) \
- { \
- Function(rhs).Swap(*this); \
- return *this; \
- } \
- \
- void Swap(Function& rhs) \
- { \
- using std::swap; \
- swap(m_pCallable, rhs.m_pCallable); \
- } \
- \
- TRet operator()(ARGS_DECL) const \
- { \
- if (!m_pCallable) \
- { \
- throw FunctionCallException(); \
- } \
- \
- return (*m_pCallable)(ARGS); \
- } \
- \
- private: \
- ICallable* m_pCallable; \
- }; \
- \
- template<TYPENAMES_DECL> \
- class Function<void(TYPES)> \
- { \
- class ICallable \
- { \
- public: \
- virtual ~ICallable() \
- { \
- } \
- \
- virtual void operator()(ARGS_DECL) const = 0; \
- virtual ICallable* Clone() const = 0; \
- }; \
- \
- template<typename TObject> \
- class CallableImpl : public ICallable \
- { \
- public: \
- explicit CallableImpl(TObject obj) : m_Object(obj) \
- { \
- } \
- \
- virtual void operator()(ARGS_DECL) const \
- { \
- m_Object(ARGS); \
- } \
- \
- virtual ICallable* Clone() const \
- { \
- return new CallableImpl<TObject>(m_Object); \
- } \
- \
- private: \
- TObject m_Object; \
- }; \
- \
- public: \
- Function() : m_pCallable(NULL) \
- { \
- } \
- \
- template<typename TObject> \
- Function(TObject obj) : m_pCallable(new CallableImpl<TObject>(obj)) \
- { \
- } \
- \
- Function(const Function& rhs) : m_pCallable(rhs.m_pCallable ? rhs.m_pCallable->Clone() : NULL) \
- { \
- } \
- \
- Function& operator=(const Function& rhs) \
- { \
- Function(rhs).Swap(*this); \
- return *this; \
- } \
- \
- void Swap(Function& rhs) \
- { \
- using std::swap; \
- swap(m_pCallable, rhs.m_pCallable); \
- } \
- \
- void operator()(ARGS_DECL) const \
- { \
- if (!m_pCallable) \
- { \
- throw FunctionCallException(); \
- } \
- \
- (*m_pCallable)(ARGS); \
- } \
- \
- private: \
- ICallable* m_pCallable; \
- };
- // 0
- #define TYPENAMES_DECL_C
- #define TYPENAMES_DECL
- #define TYPES
- #define ARGS_DECL
- #define ARGS
- DEFINE_FUNC
- #undef TYPENAMES_DECL_C
- #undef TYPENAMES_DECL
- #undef TYPES
- #undef ARGS_DECL
- #undef ARGS
- // ---
- #define TYPENAMES_DECL_C ,
- // 1
- #define TYPENAMES_DECL typename TArg1
- #define TYPES TArg1
- #define ARGS_DECL TArg1 arg1
- #define ARGS arg1
- DEFINE_FUNC
- #undef TYPENAMES_DECL
- #undef TYPES
- #undef ARGS_DECL
- #undef ARGS
- // 2
- #define TYPENAMES_DECL typename TArg1, typename TArg2
- #define TYPES TArg1, TArg2
- #define ARGS_DECL TArg1 arg1, TArg2 arg2
- #define ARGS arg1, arg2
- DEFINE_FUNC
- #undef TYPENAMES_DECL
- #undef TYPES
- #undef ARGS_DECL
- #undef ARGS
- // 3
- #define TYPENAMES_DECL typename TArg1, typename TArg2, typename TArg3
- #define TYPES TArg1, TArg2, TArg3
- #define ARGS_DECL TArg1 arg1, TArg2 arg2, TArg3 arg3
- #define ARGS arg1, arg2, arg3
- DEFINE_FUNC
- #undef TYPENAMES_DECL
- #undef TYPES
- #undef ARGS_DECL
- #undef ARGS
- // 4
- #define TYPENAMES_DECL typename TArg1, typename TArg2, typename TArg3, typename TArg4
- #define TYPES TArg1, TArg2, TArg3, TArg4
- #define ARGS_DECL TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4
- #define ARGS arg1, arg2, arg3, arg4
- DEFINE_FUNC
- #undef TYPENAMES_DECL
- #undef TYPES
- #undef ARGS_DECL
- #undef ARGS
- // ---
- #undef TYPENAMES_DECL_C
- template<typename T>
- void swap(Function<T>& lhs, Function<T>& rhs)
- {
- lhs.Swap(rhs);
- }