# 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