def_abstract_functor.h

00001 /*
00002     PyEO
00003     
00004     Copyright (C) 2003 Maarten Keijzer
00005 
00006     This program is free software; you can redistribute it and/or modify
00007     it under the terms of the GNU General Public License as published by
00008     the Free Software Foundation; either version 2 of the License, or
00009     (at your option) any later version.
00010 
00011     This program is distributed in the hope that it will be useful,
00012     but WITHOUT ANY WARRANTY; without even the implied warranty of
00013     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014     GNU General Public License for more details.
00015 
00016     You should have received a copy of the GNU General Public License
00017     along with this program; if not, write to the Free Software
00018     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019 */
00020 
00021 #ifndef MAKE_ABSTRACT_FUNCTOR_H
00022 #define MAKE_ABSTRACT_FUNCTOR_H
00023 
00024 #include <eoFunctor.h>
00025 
00026 // DEFINES for call 
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 }// namespace eoutils
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

Generated on Thu Oct 19 05:06:34 2006 for EO by  doxygen 1.3.9.1