codepad
[
create a new paste
]
login
|
about
Language:
C
C++
D
Haskell
Lua
OCaml
PHP
Perl
Plain Text
Python
Ruby
Scheme
Tcl
#include <iostream> #include <string> #include <boost/type_traits.hpp> #include <boost/mpl/if.hpp> union any_pointer { void (*func_ptr)(); void *obj_ptr; }; template <class FuncPtr, class R> struct function_ptr_manager { static R invoke(any_pointer func_ptr) { FuncPtr func = reinterpret_cast<FuncPtr>(func_ptr.func_ptr); return func(); } }; template <class FuncObj, class R> struct function_obj_manager { static R invoke(any_pointer func_obj) { FuncObj* func = reinterpret_cast<FuncObj*>(func_obj.obj_ptr); return (*func)(); } }; struct function_ptr_tag {}; struct function_obj_tag {}; template <class FuncType> struct get_function_tag { private: typedef typename boost::mpl::if_<boost::is_pointer<FuncType>, function_ptr_tag, FuncType>::type func_ptr_tag; typedef typename boost::mpl::if_<boost::is_same<func_ptr_tag, FuncType>, function_obj_tag, function_ptr_tag>::type ret_type; public: typedef ret_type type; }; template <class R> class function { R (*invoke_)(any_pointer); any_pointer functor_; public: template <class FuncType> function& operator=(FuncType func) { typedef typename get_function_tag<FuncType>::type func_tag; assign_to(func, func_tag()); return *this; } R operator()() { return invoke_(functor_); } private: template <class FuncPtr> void assign_to(FuncPtr func_ptr, function_ptr_tag) { invoke_ = &function_ptr_manager<FuncPtr, R>::invoke; functor_.func_ptr = reinterpret_cast<void(*)()>(func_ptr); } template <class FuncObj> void assign_to(FuncObj func_obj, function_obj_tag) { invoke_ = &function_obj_manager<FuncObj, R>::invoke; functor_.obj_ptr = reinterpret_cast<void*>(new FuncObj(func_obj)); } }; std::string func() { return "func"; } struct func_obj { std::string operator()() { return "func_obj"; } }; int main() { function<std::string> f; f = &func; std::cout << f() << std::endl; f = func_obj(); std::cout << f() << std::endl; return 0; }
Private
[
?
]
Run code
Submit