00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef MAKE_ABSTRACT_FUNCTOR_H
00022 #define MAKE_ABSTRACT_FUNCTOR_H
00023
00024 #include <eoFunctor.h>
00025
00026
00027 #define WC1 boost::python::with_custodian_and_ward<1,2>()
00028 #define WC2 boost::python::with_custodian_and_ward<1,2, with_custodian_and_ward<1,3> >()
00029
00030 namespace eoutils {
00031
00032 using namespace boost::python;
00033
00034 template <class Proc>
00035 class ProcWrapper : public Proc
00036 {
00037 public:
00038 PyObject* self;
00039 ProcWrapper(PyObject* s) : self(s) {}
00040
00041 typename Proc::result_type operator()(void)
00042 {
00043 return boost::python::call_method<typename Proc::result_type>(self, "__call__");
00044 }
00045 };
00046
00047 template <class Proc>
00048 void make_abstract_functor(std::string name, typename eoFunctorBase::procedure_tag)
00049 {
00050 typedef ProcWrapper<Proc> Wrapper;
00051 boost::python::class_<Proc, Wrapper,boost::noncopyable>(name.c_str(), boost::python::init<>() )
00052 .def("__call__", &Wrapper::operator());
00053 }
00054
00055 template <class Proc>
00056 void make_abstract_functor_ref(std::string name, typename eoFunctorBase::procedure_tag)
00057 {
00058 typedef ProcWrapper<Proc> Wrapper;
00059 boost::python::class_<Proc, Wrapper,boost::noncopyable>(name.c_str(), boost::python::init<>() )
00060 .def("__call__", &Wrapper::operator(), boost::python::return_internal_reference<>());
00061 }
00062
00063 template <class Unary>
00064 class UnaryWrapper : public Unary
00065 {
00066 public:
00067 PyObject* self;
00068 UnaryWrapper(PyObject* s) : self(s) {}
00069
00070 typename Unary::result_type operator()(typename Unary::argument_type a)
00071 {
00072 return boost::python::call_method<typename Unary::result_type>(self, "__call__", boost::ref(a) );
00073 }
00074 };
00075
00076 template <class Unary>
00077 void make_abstract_functor(std::string name, typename eoFunctorBase::unary_function_tag)
00078 {
00079 typedef UnaryWrapper<Unary> Wrapper;
00080
00081 boost::python::class_<Unary, Wrapper, boost::noncopyable>(name.c_str(), boost::python::init<>() )
00082 .def("__call__", &Wrapper::operator())
00083 ;
00084 }
00085
00086 template <class Unary>
00087 void make_abstract_functor_ref(std::string name, typename eoFunctorBase::unary_function_tag)
00088 {
00089 typedef UnaryWrapper<Unary> Wrapper;
00090
00091 boost::python::class_<Unary, Wrapper, boost::noncopyable>(name.c_str(), boost::python::init<>() )
00092 .def("__call__", &Wrapper::operator(), boost::python::return_internal_reference<>() )
00093 ;
00094 }
00095
00096 template <class Binary>
00097 class BinaryWrapper : public Binary
00098 {
00099 public:
00100 PyObject* self;
00101 BinaryWrapper(PyObject* s) : self(s) {}
00102 typename Binary::result_type operator()(typename Binary::first_argument_type a1, typename Binary::second_argument_type a2)
00103 {
00104 return boost::python::call_method<
00105 typename Binary::result_type>(self, "__call__", boost::ref(a1), boost::ref(a2) );
00106 }
00107 };
00108
00109 template <class Binary>
00110 void make_abstract_functor(std::string name, typename eoFunctorBase::binary_function_tag)
00111 {
00112 typedef BinaryWrapper<Binary> Wrapper;
00113 boost::python::class_<Binary, Wrapper, boost::noncopyable>(name.c_str(), boost::python::init<>() )
00114 .def("__call__", &Wrapper::operator());
00115 }
00116
00117 template <class Binary>
00118 void make_abstract_functor_ref(std::string name, typename eoFunctorBase::binary_function_tag)
00119 {
00120 typedef BinaryWrapper<Binary> Wrapper;
00121 boost::python::class_<Binary, Wrapper, boost::noncopyable>(name.c_str(), boost::python::init<>() )
00122 .def("__call__", &Wrapper::operator(), boost::python::return_internal_reference<>() );
00123 }
00124
00125 }
00126
00127 template <class Functor>
00128 void def_abstract_functor(std::string name)
00129 {
00130 eoutils::make_abstract_functor<Functor>(name, Functor::functor_category());
00131 }
00132
00133 template <class Functor>
00134 void def_abstract_functor_ref(std::string name)
00135 {
00136 eoutils::make_abstract_functor_ref<Functor>(name, Functor::functor_category());
00137 }
00138
00139 #endif