
John Torjo wrote:
Dear boosters,
Did a lightweight replacement for boost::function (compile-wise). Focus was on making it very fast to compile.
Forgot to remove some namespaces, etc. ;) Here it is again. -- John Torjo Freelancer -- john@torjo.com Contributing editor, C/C++ Users Journal -- "Win32 GUI Generics" -- generics & GUI do mix, after all -- http://www.torjo.com/win32gui/ -- v1.3beta released - check out splitter/simple_viewer, a File Explorer/Viewer all in about 200 lines of code! Professional Logging Solution for FREE -- http://www.torjo.com/code/logging.zip (logging - C++) -- http://www.torjo.com/logview/ (viewing/filtering - Win32) -- http://www.torjo.com/logbreak/ (debugging - Win32) #ifndef JOHN_TORJO_WIN32GUI_function #define JOHN_TORJO_WIN32GUI_function #if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif // function.hpp // // Copyright (C) 2004 John Torjo (john@torjo.com) // // Permission to copy, use, sell and distribute this software is granted // provided this copyright notice appears in all copies. // Permission to modify the code and to distribute modified code is granted // provided this copyright notice appears in all copies, and a notice // that the code was modified is included with the copyright notice. // // This software is provided "as is" without express or implied warranty, // and with no claim as to its suitability for any purpose. // #include <assert.h> #include <stdexcept> // #include <win32gui/.hpp> namespace detail { struct no_param {}; template<class func, class base> struct func_exec : base { typedef typename base::result res; typedef typename base::arg1 arg1; typedef typename base::arg2 arg2; typedef typename base::arg3 arg3; typedef typename base::arg4 arg4; typedef typename base::arg5 arg5; func_exec(func f) : f(f) {} // note: one of these is defined virtual in class base res operator()() { return f(); } res operator()(const arg1 & a1) { return f(a1); } res operator()(const arg1 & a1, const arg2 & a2) { return f(a1,a2); } res operator()(const arg1 & a1, const arg2 & a2, const arg3 & a3) { return f(a1,a2,a3); } res operator()(const arg1 & a1, const arg2 & a2, const arg3 & a3, const arg4 & a4) { return f(a1,a2,a3,a4); } res operator()(const arg1 & a1, const arg2 & a2, const arg3 & a3, const arg4 & a4, const arg5 & a5) { return f(a1,a2,a3,a4,a5); } // overrides the base' class base * clone() const { return new func_exec<func,base>(*this); } private: func f; }; template<class res> struct func_keeper0 { typedef func_keeper0<res> self; typedef res result; typedef no_param arg1; typedef no_param arg2; typedef no_param arg3; typedef no_param arg4; typedef no_param arg5; virtual res operator()() = 0; virtual self * clone() const = 0; }; template<class res, class a1> struct func_keeper1 { typedef func_keeper1<res,a1> self; typedef res result; typedef a1 arg1; typedef no_param arg2; typedef no_param arg3; typedef no_param arg4; typedef no_param arg5; virtual res operator()(const arg1&) = 0; virtual self * clone() const = 0; }; template<class res, class a1, class a2> struct func_keeper2 { typedef func_keeper2<res,a1,a2> self; typedef res result; typedef a1 arg1; typedef a2 arg2; typedef no_param arg3; typedef no_param arg4; typedef no_param arg5; virtual res operator()(const arg1&,const arg2&) = 0; virtual self * clone() const = 0; }; template<class res, class a1, class a2, class a3> struct func_keeper3 { typedef func_keeper3<res,a1,a2,a3> self; typedef res result; typedef a1 arg1; typedef a2 arg2; typedef a3 arg3; typedef no_param arg4; typedef no_param arg5; virtual res operator()(const arg1&,const arg2&, const arg3&) = 0; virtual self * clone() const = 0; }; template<class res, class a1, class a2, class a3, class a4> struct func_keeper4 { typedef func_keeper4<res,a1,a2,a3,a4> self; typedef res result; typedef a1 arg1; typedef a2 arg2; typedef a3 arg3; typedef a4 arg4; typedef no_param arg5; virtual res operator()(const arg1&,const arg2&, const arg3&, const arg4&) = 0; virtual self * clone() const = 0; }; } template<class res> struct func_wrapper0 { typedef res result; typedef detail::no_param arg1; typedef detail::no_param arg2; typedef detail::no_param arg3; typedef detail::no_param arg4; typedef detail::no_param arg5; typedef detail::func_keeper0<res> func_keeper; typedef func_wrapper0<res> self_type; func_wrapper0() : m_f(0) {} template<class func> func_wrapper0(func f) : m_f(new detail::func_exec<func,func_keeper>(f)) {} typedef res (*raw_func)(); func_wrapper0(raw_func f) : m_f(new detail::func_exec<raw_func,func_keeper>(f)){} func_wrapper0(const self_type & other) : m_f(other.m_f ? other.m_f->clone() : 0) {} res operator()() { if ( m_f) return (*m_f)(); else throw std::runtime_error("null function"); } self_type& operator=(const self_type & other) { func_keeper * old = m_f; m_f = other.m_f ? other.m_f->clone() : 0; delete old; return *this; } private: func_keeper * m_f; }; template<class res,class arg1_type> struct func_wrapper1 { typedef res result; typedef arg1_type arg1; typedef detail::no_param arg2; typedef detail::no_param arg3; typedef detail::no_param arg4; typedef detail::no_param arg5; typedef detail::func_keeper1<res,arg1> func_keeper; typedef func_wrapper1<res,arg1> self_type; typedef res (*raw_func)(const arg1&); func_wrapper1() : m_f(0) {} template<class func> func_wrapper1(func f) : m_f(new detail::func_exec<func,func_keeper>(f)) {} func_wrapper1(raw_func f) : m_f(new detail::func_exec<raw_func,func_keeper>(f)){} func_wrapper1(const self_type & other) : m_f(other.m_f ? other.m_f->clone() : 0) {} res operator()(const arg1 &a1) { if ( m_f) return (*m_f)(a1); else throw std::runtime_error("null function"); } self_type& operator=(const self_type & other) { func_keeper * old = m_f; m_f = other.m_f ? other.m_f->clone() : 0; delete old; return *this; } private: func_keeper * m_f; }; template<class res,class arg1_type,class arg2_type> struct func_wrapper2 { typedef res result; typedef arg1_type arg1; typedef arg2_type arg2; typedef detail::no_param arg3; typedef detail::no_param arg4; typedef detail::no_param arg5; typedef detail::func_keeper2<res,arg1,arg2> func_keeper; typedef func_wrapper2<res,arg1,arg2> self_type; typedef res (*raw_func)(const arg1&,const arg2&); func_wrapper2() : m_f(0) {} template<class func> func_wrapper2(func f) : m_f(new detail::func_exec<func,func_keeper>(f)) {} func_wrapper2(raw_func f) : m_f(new detail::func_exec<raw_func,func_keeper>(f)){} func_wrapper2(const self_type & other) : m_f(other.m_f ? other.m_f->clone() : 0) {} res operator()(const arg1 &a1, const arg2 &a2) { if ( m_f) return (*m_f)(a1,a2); else throw std::runtime_error("null function"); } self_type& operator=(const self_type & other) { func_keeper * old = m_f; m_f = other.m_f ? other.m_f->clone() : 0; delete old; return *this; } private: func_keeper * m_f; }; template<class res,class arg1_type,class arg2_type,class arg3_type> struct func_wrapper3 { typedef res result; typedef arg1_type arg1; typedef arg2_type arg2; typedef arg3_type arg3; typedef detail::no_param arg4; typedef detail::no_param arg5; typedef detail::func_keeper3<res,arg1,arg2,arg3> func_keeper; typedef func_wrapper3<res,arg1,arg2,arg3> self_type; typedef res (*raw_func)(const arg1&,const arg2&,const arg3&); func_wrapper3() : m_f(0) {} template<class func> func_wrapper3(func f) : m_f(new detail::func_exec<func,func_keeper>(f)) {} func_wrapper3(raw_func f) : m_f(new detail::func_exec<raw_func,func_keeper>(f)){} func_wrapper3(const self_type & other) : m_f(other.m_f ? other.m_f->clone() : 0) {} res operator()(const arg1 &a1, const arg2 &a2, const arg3 &a3) { if ( m_f) return (*m_f)(a1,a2,a3); else throw std::runtime_error("null function"); } self_type& operator=(const self_type & other) { func_keeper * old = m_f; m_f = other.m_f ? other.m_f->clone() : 0; delete old; return *this; } private: func_keeper * m_f; }; template<class res,class arg1_type,class arg2_type,class arg3_type,class arg4_type> struct func_wrapper4 { typedef res result; typedef arg1_type arg1; typedef arg2_type arg2; typedef arg3_type arg3; typedef arg4_type arg4; typedef detail::no_param arg5; typedef detail::func_keeper4<res,arg1,arg2,arg3,arg4> func_keeper; typedef func_wrapper4<res,arg1,arg2,arg3,arg4> self_type; typedef res (*raw_func)(const arg1&,const arg2&,const arg3&,const arg4&); func_wrapper4() : m_f(0) {} template<class func> func_wrapper4(func f) : m_f(new detail::func_exec<func,func_keeper>(f)) {} func_wrapper4(raw_func f) : m_f(new detail::func_exec<raw_func,func_keeper>(f)){} func_wrapper4(const self_type & other) : m_f(other.m_f ? other.m_f->clone() : 0) {} res operator()(const arg1 &a1, const arg2 &a2, const arg3 &a3, const arg4 &a4) { if ( m_f) return (*m_f)(a1,a2,a3,a4); else throw std::runtime_error("null function"); } self_type& operator=(const self_type & other) { func_keeper * old = m_f; m_f = other.m_f ? other.m_f->clone() : 0; delete old; return *this; } private: func_keeper * m_f; }; /* void f() { std::cout << "f" << std::endl; } void f1(int i) { std::cout << "f1(" << i << ")" << std::endl; } bool f2(int i, char c) { std::cout << "f2(" << i << "," << c << ")" << std::endl; return true; } int f3(int i, char c, char d) { std::cout << "f3(" << i << "," << c << d << ")" << std::endl; return 2; } int f4(int i, char c, char d, char e) { std::cout << "f4(" << i << "," << c << d << e << ")" << std::endl; return 3; } struct titi { titi() : idx(0) {} void operator()() { std::cout << "titi" << idx++ << std::endl; } int idx; }; int main() { func_wrapper0<void> test(&f); test(); titi t; func_wrapper0<void> test2( t ); test2(); func_wrapper0<void> test3( test2 ); test2(); test2(); test3(); func_wrapper0<void> test4; test4 = test3; test4(); test4 = test; test4(); func_wrapper1<void,long> func1(f1); func1(0); func1(2); func_wrapper2<int,long,int> func2(f2); int i = func2(10,97); assert(i == 1); func_wrapper3<int,long,int,char> func3(f3); i = func3(11,97,'b'); assert(i == 2); func_wrapper4<int,long,int,char,char> func4(f4); i = func4(12,97,'b','c'); assert(i == 3); std::cin.get(); return 0; } */ #endif // JOHN_TORJO_WIN32GUI_function