EvolvingObjects
|
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