EvolvingObjects
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
 All Classes Namespaces Files Functions Variables Typedefs Friends