[ create a new paste ] login | about

Link: http://codepad.org/KxacU5UC    [ raw code | output | fork ]

hecomi - C++, pasted on Feb 9:
#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;
}       


Output:
1
2
func
func_obj


Create a new paste based on this one


Comments: