FunctionWrap.cxx
Go to the documentation of this file.
1 
12 // include first to avoid _POSIX_C_SOURCE warning.
13 #include <boost/python.hpp>
14 
15 #ifdef HAVE_CONFIG_H
16 // for boost defect
17 #include "config.h"
18 #endif
19 
20 
21 #include "FunctionWrap.h"
22 #ifndef BOOST_DEFECT
23 
24 #include <stdexcept>
25 
26 using std::string;
27 using std::vector;
28 
29 using namespace boost::python;
30 
31 namespace hippodraw {
32  namespace Python {
33  void
35  {
36  class_ < FunctionWrap, std::auto_ptr < FunctionWrap> >
37  ( "FunctionBase",
38  "The base class for raw functions. FunctionBase objects need to\n"
39  "wrapped with Function objects to be displayed. FunctionBase\n"
40  "can be derived from and cloned so they can be added to the\n"
41  "FunctionFactory.",
42  init < const FunctionBase & >
43  ( "FunctionBase () -> FunctionBase\n"
44  "FunctionBase ( FunctionBase ) -> FunctionBase\n"
45  "\n"
46  "Constructors of the FunctionBase object.\n" ) )
47 
48  .def ( init <> () )
49 
50  .def ( init < const FunctionWrap & > () )
51 
52  .def ( "initialize", &FunctionWrap::initialize,
53  "initialize () -> None\n"
54  "\n"
55  "Initializes the function parameter values and the names.\n"
56  "The number of parameters is taken from the number of names." )
57 
58  .def ( "name", &FunctionBase::name,
59  return_value_policy < copy_const_reference > (),
60  "name () -> string\n"
61  "\n"
62  "Returns the name of the function." )
63 
64  .def ( "setName", &FunctionWrap::setName,
65  "setName ( string ) -> None\n"
66  "\n"
67  "Sets the name of the function." )
68 
69  .def ( "parmNames",
70  &FunctionBase::parmNames,
71  return_value_policy < copy_const_reference > (),
72  "parmNames () -> sequence\n"
73  "\n"
74  "Returns the names of the parameters" )
75 
76  .def ( "setParmNames",
77  &FunctionWrap::setParmNames,
78  "setParmNames ( sequence ) -> None\n"
79  "\n"
80  "Sets the parameter names and re-sizes the parameters" )
81 
82  .def ( "setParameters",
83  ( void ( FunctionBase::* ) // function pointer cast
84  ( const std::vector < double > & ) ) // function signature
85  &FunctionBase::setParameters,
86  "setParameters ( sequence ) -> None\n"
87  "\n"
88  "Sets the values of the parameters." )
89 
90  .def ( "getParameters", &FunctionBase::getParameters,
91  return_value_policy < copy_const_reference > (),
92  "getParameters () -> sequence\n"
93  "\n"
94  "Returns the current function parameter values." )
95 
96  ;
97  }
98  } // namespace Python
99 } // namespace hippodraw
100 
101 using namespace hippodraw;
102 
103 FunctionWrap::
104 FunctionWrap ( )
105  : FunctionBase ()
106 {
107 }
108 
110 FunctionWrap ( const FunctionBase & base )
111  : FunctionBase ( base )//,
112 {
113 }
114 
116 FunctionWrap ( const FunctionWrap & wrap )
117  : FunctionBase ( wrap )
118 {
119 }
120 
123 {
124 #ifndef HAVE_OLD_PYTHON
125  PyGILState_STATE state = PyGILState_Ensure ();
126 
127  extract<std::auto_ptr<FunctionWrap>&> x(get_owner(this));
128  if ( x.check() ) x().release();
129 
130  PyGILState_Release ( state );
131 #endif
132 }
133 
134 template <class T>
135 object
137 get_owner(T* ) const // me
138 {
139  // Use secret interface to get the Python object
140  // that owns *this. I guess I will have to make that
141  // interface public. -- Dave Abrahams
142  return
143 object ( handle<> ( borrowed ( detail::wrapper_base_::get_owner(*this))));
144 }
145 
146 unsigned int
148 dimensions () const
149 {
150  unsigned int dims = 0;
151 #ifndef HAVE_OLD_PYTHON
152  PyGILState_STATE state = PyGILState_Ensure ();
153 
154  if ( override member = this -> get_override ( "dimensions" ) ) {
155  FunctionWrap * fw = const_cast < FunctionWrap * > ( this );
156  object self = get_owner ( fw );
157  dims = call_method < unsigned int > ( self.ptr(), "dimensions" );
158  }
159  else { // didn't override it
160  dims = FunctionBase::dimensions ();
161  }
162  PyGILState_Release ( state );
163 #endif
164 
165  return dims;
166 }
167 
168 bool
171 {
172  bool yes = false;
173 
174  if ( override member = this -> get_override ( "derivByParm" ) ) {
175  yes = true;
176  }
177 
178  return yes;
179 }
180 
181 FunctionBase *
183 clone () const
184 {
185 #ifndef HAVE_OLD_PYTHON
186  PyGILState_STATE state = PyGILState_Ensure ();
187 
188  object py_result;
189 
190  if (override clone = this->get_override("clone")) {
191  try {
192  // The Python class author overrode clone; do
193  // whatever she says
194  py_result ( clone() );
195  } catch ( error_already_set & ) {
196  PyErr_Print ();
197  handle_exception ();
198  PyGILState_Release ( state );
199  return 0;
200  }
201  } else {
202  FunctionWrap * t = const_cast < FunctionWrap * > ( this );
203  try {
204  object self = get_owner ( t );
205  // Find its most-derived Python class
206  object my_class = self.attr("__class__");
207  // call the default constructor
208  py_result = my_class ( );
209  } catch ( error_already_set & ) {
210  PyErr_Print ();
211  handle_exception ();
212  PyGILState_Release ( state );
213  return 0;
214  }
215  }
216 
217  FunctionWrap* result = extract<FunctionWrap*>(py_result);
218 
219  // Make the C++ result control the destiny of the Python result.
220  result->invert_ownership = py_result;
221  PyGILState_Release ( state );
222 
223  return result;
224 
225 #else // old Python
226  return 0;
227 #endif
228 }
229 
234 void
236 setName ( const std::string & name )
237 {
238  FunctionBase::setName ( name.c_str() );
239 }
240 
241 void
243 setParmNames ( const std::vector < std::string > & names )
244 {
245  m_parm_names = names;
246  resize ();
247 }
248 
253 double
255 derivByParm ( int i , double x ) const
256 {
257 #ifndef HAVE_OLD_PYTHON
258  double value = 0.;
259  PyGILState_STATE state = PyGILState_Ensure ();
260 
261  FunctionWrap * t = const_cast < FunctionWrap * > ( this );
262  object self = get_owner ( t );
263 
264  try {
265  value = call_method < double, int, double >
266  ( self.ptr(), "derivByParm", i, x );
267  } catch ( ... ) {
268  value = 0.;
269  }
270 
271  PyGILState_Release ( state );
272 
273  return value;
274 #else // old Python
275  return 0;
276 #endif
277 }
278 
281 void
284 {
285 #ifndef HAVE_OLD_PYTHON
286  PyGILState_STATE state = PyGILState_Ensure ();
287 
288  FunctionWrap * t = const_cast < FunctionWrap * > ( this );
289  object self = get_owner ( t );
290  call_method < void > ( self.ptr(), "initialize" );
291  resize ();
292 
293  PyGILState_Release ( state );
294 #endif
295 }
296 
301 double
303 operator () ( double x ) const
304 {
305  double value = 0;
306 
307 #ifndef HAVE_OLD_PYTHON
308  PyGILState_STATE state = PyGILState_Ensure ();
309  FunctionWrap * t = const_cast < FunctionWrap * > ( this );
310  object self = get_owner ( t );
311 
312  try {
313  value = call_method < double, double > ( self.ptr(), "valueAt", x );
314  PyGILState_Release ( state );
315  }
316  catch ( const error_already_set & ) {
317  PyGILState_Release ( state );
318 // handle_exception ();
319  }
320 #endif
321 
322  return value;
323 }
324 
327 double
329 operator () ( const std::vector < double > & x ) const
330 {
331  double value = 0;
332 
333 #ifndef HAVE_OLD_PYTHON
334  PyGILState_STATE state = PyGILState_Ensure ();
335  FunctionWrap * t = const_cast < FunctionWrap * > ( this );
336  object self = get_owner ( t );
337  unsigned int size = x.size();
338 
339  switch ( size ) {
340  case 2 :
341  value = call_method < double, double, double >
342  ( self.ptr(), "valueAt", x[0], x[1] );
343  break;
344  case 3 :
345  value = call_method < double, double, double, double >
346  ( self.ptr(), "valueAt", x[0], x[1], x[2] );
347  break;
348  default:
349  break;
350  }
351  PyGILState_Release ( state );
352 #endif
353 
354  return value;
355 }
356 
357 void
360 {
361 }
362 
363 #endif // BOOST_DEFECT

Generated for HippoDraw Class Library by doxygen