casacore
PycBasicData.h
Go to the documentation of this file.
1 //# PycBasicData.h: Convert casa data types to/from python
2 //# Copyright (C) 2006
3 //# Associated Universities, Inc. Washington DC, USA.
4 //#
5 //# This library is free software; you can redistribute it and/or modify it
6 //# under the terms of the GNU Library General Public License as published by
7 //# the Free Software Foundation; either version 2 of the License, or (at your
8 //# option) any later version.
9 //#
10 //# This library is distributed in the hope that it will be useful, but WITHOUT
11 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
13 //# License for more details.
14 //#
15 //# You should have received a copy of the GNU Library General Public License
16 //# along with this library; if not, write to the Free Software Foundation,
17 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
18 //#
19 //# Correspondence concerning AIPS++ should be addressed as follows:
20 //# Internet email: aips2-request@nrao.edu.
21 //# Postal address: AIPS++ Project Office
22 //# National Radio Astronomy Observatory
23 //# 520 Edgemont Road
24 //# Charlottesville, VA 22903-2475 USA
25 //#
26 //# $Id: PycBasicData.h,v 1.5 2006/10/25 01:42:13 gvandiep Exp $
27 
28 #ifndef PYRAP_PYCBASICDATA_H
29 #define PYRAP_PYCBASICDATA_H
30 
31 // include python first to avoid _POSIX_C_SOURCE redefined warnings
32 #include <boost/python.hpp>
33 #include <boost/python/object.hpp>
34 #include <casacore/python/Converters/PycArray.h>
35 #include <casacore/casa/BasicSL/String.h>
36 #include <casacore/casa/Arrays/IPosition.h>
37 #include <casacore/casa/Arrays/Vector.h>
38 #include <casacore/casa/Utilities/Assert.h>
39 #include <casacore/casa/Exceptions/Error.h>
40 #include <vector>
41 #include <map>
42 
43 #if PY_MAJOR_VERSION >= 3
44 #define IS_PY3K
45 #endif
46 
47 // Define classes and functions to convert the basic data types and
48 // containers to and from Python.
49 
50 namespace casacore { namespace python {
51 
52  // Prevent a converter from being registered multiple times.
53  class pyregistry
54  {
55  public:
56  static bool get (const std::string& name);
57  static void set (const std::string& name);
58  private:
59  static std::map<std::string,bool> _registry;
60  };
61 
62  // Check if the given object is a sequence object.
63  // If so, return true.
64  // py_obj gets changed if the given object was a scalar numpy/numarray.
65  // In that case it is flattened.
66  bool getSeqObject (boost::python::object& py_obj);
67 
68  // Convert a String object to python.
70  {
71  static boost::python::object makeobject(String const& s)
72  { return boost::python::object((const std::string&)s); }
73  static PyObject* convert(String const& s)
74  { return boost::python::incref(makeobject(s).ptr()); }
75  };
76 
77  // Convert a String object from python.
79  {
81  {
82  boost::python::converter::registry::push_back(
83  &convertible,
84  &construct,
85  boost::python::type_id<String>());
86  }
87 
88  static void* convertible(PyObject* obj_ptr)
89  {
90 #ifdef IS_PY3K
91  if (!PyUnicode_Check(obj_ptr)) return 0;
92 #else
93  if (!PyString_Check(obj_ptr) && !PyUnicode_Check(obj_ptr)) return 0;
94 #endif
95  return obj_ptr;
96  }
97 
98  static void construct(
99  PyObject* obj_ptr,
100  boost::python::converter::rvalue_from_python_stage1_data* data)
101  {
102  char* value = NULL;
103  boost::python::object temp_bytes_obj;
104  if (PyUnicode_Check(obj_ptr)) {
105  PyObject * temp_bytes = PyUnicode_AsEncodedString(obj_ptr, "UTF-8", "strict"); // Owned reference
106 
107  if (temp_bytes != NULL) {
108  // Take over lifetime management of temp_bytes
109  temp_bytes_obj = boost::python::object(boost::python::handle<>(temp_bytes));
110  value = PyBytes_AS_STRING(temp_bytes);
111  } else {
112  boost::python::throw_error_already_set();
113  }
114 #ifndef IS_PY3K
115  } else if (PyString_Check(obj_ptr)) {
116  value = PyString_AsString(obj_ptr);
117 #endif
118  } else {
119  boost::python::throw_error_already_set();
120  }
121  if (value == 0) boost::python::throw_error_already_set();
122  void* storage = (
123  (boost::python::converter::rvalue_from_python_storage<String>*)
124  data)->storage.bytes;
125  new (storage) String(value);
126  data->convertible = storage;
127  }
128  };
129 
130 
131  // Default operations on all containers for conversion from Python
132  // container to C++ one.
133 
134  // Copied from
135  // scitbx/include/scitbx/boost_python/container_conversions.h that is
136  // described in the <a
137  // href="http://www.boost.org/libs/python/doc/v2/faq.html">
138  // Boost.Python FAQ. </a>
139 
140  // @author Ralf W. Grosse-Kunstleve <rwgk@yahoo.com> of
141  // <a href="http://www.lbl.gov/">Lawrence Berkeley National Laboratory</a>
143  {
144  static bool check_convertibility_per_element() { return true; }
145 
146  template <typename ContainerType>
147  static bool check_size(boost::type<ContainerType>, std::size_t)
148  {
149  return true;
150  }
151 
152  template <typename ContainerType>
153  static void assert_size(boost::type<ContainerType>, std::size_t)
154  {}
155 
156  template <typename ContainerType>
157  static void reserve(ContainerType&, std::size_t)
158  {}
159  };
160 
161  // Operations on containers that have variable capacity for
162  // conversion from Python container to C++ one.
163 
164  // Copied from
165  // scitbx/include/scitbx/boost_python/container_conversions.h that is
166  // described in the <a
167  // href="http://www.boost.org/libs/python/doc/v2/faq.html">
168  // Boost.Python FAQ. </a>
169 
170  // @author Ralf W. Grosse-Kunstleve <rwgk@yahoo.com> of
171  // <a href="http://www.lbl.gov/">Lawrence Berkeley National Laboratory</a>
173  {
174  template <typename ContainerType>
175  static void reserve(ContainerType& a, std::size_t sz)
176  {
177  a.reserve(sz);
178  }
179 
180  template <typename ContainerType, typename ValueType>
181  static void set_value(ContainerType& a, std::size_t i, ValueType const& v)
182  {
183  AlwaysAssert(a.size() == i, AipsError);
184  a.push_back(v);
185  }
186  };
187 
189  {
190  template <typename ContainerType>
191  static void reserve(ContainerType& a, std::size_t sz)
192  {
193  a.resize(sz);
194  }
195 
196  template <typename ContainerType, typename ValueType>
197  static void set_value(ContainerType& a, std::size_t i, ValueType const& v)
198  {
199  assert(a.size() > i);
200  a[i] = v;
201  }
202  };
203 
205  {
206  template <typename ContainerType>
207  static void reserve(ContainerType& a, std::size_t sz)
208  {
209  a.resize(sz);
210  }
211 
212  template <typename ContainerType, typename ValueType>
213  static void set_value(ContainerType& a, std::size_t i, ValueType const& v)
214  {
215  assert(a.size() > i);
216  a[a.size() - i - 1] = v;
217  }
218  };
219 
220 
221  // A wrapper of a conversion function to convert a STL vector to a
222  // Python list. This class satisfies the requirements of the
223  // boost::python::to_python_converter conversion template argument.
224 
225  // Copied from
226  // scitbx/include/scitbx/boost_python/container_conversions.h that is
227  // described in the <a
228  // href="http://www.boost.org/libs/python/doc/v2/faq.html">
229  // Boost.Python FAQ. </a>
230 
231  // @author Ralf W. Grosse-Kunstleve <rwgk@yahoo.com> of
232  // <a href="http://www.lbl.gov/">Lawrence Berkeley National Laboratory</a>
233  template < typename ContainerType >
234  struct to_list
235  {
236  // Creates and returns a Python list from the elements copied
237  // from a STL container. The ContainerType must be a container
238  // with STL iterators defined on it.
239  // It may contain any type of object supported by the
240  // boost::python::object constructor.
241  static boost::python::object makeobject (ContainerType const& c)
242  {
243  boost::python::list result;
244  typename ContainerType::const_iterator i = c.begin();
245  typename ContainerType::const_iterator iEnd = c.end();
246  for( ; i != iEnd; ++i) {
247  result.append(*i);
248  }
249  return result;
250  }
251  static PyObject* convert (ContainerType const& c)
252  {
253  return boost::python::incref(makeobject(c).ptr());
254  }
255  };
256  //# Make specialisations for various types.
257  template <>
259  {
261  static boost::python::list makeobject (ContainerType const& c)
262  {
263  // Reverse IPosition values.
264  boost::python::list result;
265  for (int i=c.size()-1; i>=0; --i) {
266  result.append(c[i]);
267  }
268  return result;
269  }
270  static PyObject* convert (ContainerType const& c)
271  {
272  return boost::python::incref(makeobject(c).ptr());
273  }
274  };
275  //# This specialisation is needed because on OS-X 10.9 clang-3.5 with
276  //# Boost-Python 1.57 gives a compile error
277  //# /opt/casa/01/include/boost/python/converter/arg_to_python.hpp:209:9:
278  //# error: no matching constructor for initialization of
279  //# 'boost::python::converter::detail::arg_to_python_base'
280  //# : arg_to_python_base(&x, registered<T>::converters)
281  template <>
282  struct to_list <std::vector <bool> >
283  {
284  typedef std::vector <bool> ContainerType;
285  static boost::python::list makeobject (ContainerType const& c)
286  {
287  boost::python::list result;
288  ContainerType::const_iterator i = c.begin();
289  ContainerType::const_iterator iEnd = c.end();
290  for( ; i != iEnd; ++i) {
291  bool b = *i;
292  result.append(b);
293  }
294  return result;
295  }
296  static PyObject* convert (ContainerType const& c)
297  {
298  return boost::python::incref(makeobject(c).ptr());
299  }
300  };
301  template <>
302  struct to_list <std::vector <casacore::String> >
303  {
304  typedef std::vector <casacore::String> ContainerType;
305  static boost::python::list makeobject (ContainerType const& c)
306  {
307  boost::python::list result;
308  ContainerType::const_iterator i = c.begin();
309  ContainerType::const_iterator iEnd = c.end();
310  for( ; i != iEnd; ++i) {
311  result.append((std::string const&)(*i));
312  }
313  return result;
314  }
315  static PyObject* convert (ContainerType const& c)
316  {
317  return boost::python::incref(makeobject(c).ptr());
318  }
319  };
320  template <>
321  struct to_list <casacore::Array <casacore::String> >
322  {
324  static boost::python::object makeobject (ContainerType const& c)
325  {
326  boost::python::list result;
327  ContainerType::const_iterator i = c.begin();
328  ContainerType::const_iterator iEnd = c.end();
329  for( ; i != iEnd; ++i) {
330  result.append((std::string const&)(*i));
331  }
332  return result;
333  }
334  static PyObject* convert (ContainerType const& c)
335  {
336  return boost::python::incref(makeobject(c).ptr());
337  }
338  };
339  template <>
340  struct to_list <casacore::Vector <casacore::String> >
341  {
343  static boost::python::object makeobject (ContainerType const& c)
344  {
345  boost::python::list result;
346  ContainerType::const_iterator i = c.begin();
347  ContainerType::const_iterator iEnd = c.end();
348  for( ; i != iEnd; ++i) {
349  result.append((std::string const&)(*i));
350  }
351  return result;
352  }
353  static PyObject* convert (ContainerType const& c)
354  {
355  return boost::python::incref(makeobject(c).ptr());
356  }
357  };
358 
359  // Converts an STL vector or casa Array of T objects to Python list.
360  // Copied from
361  // scitbx/include/scitbx/boost_python/container_conversions.h that is
362  // described in the <a
363  // href="http://www.boost.org/libs/python/doc/v2/faq.html">
364  // Boost.Python FAQ. </a>
365  // @author Ralf W. Grosse-Kunstleve <rwgk@yahoo.com> of
366  // <a href="http://www.lbl.gov/">Lawrence Berkeley National Laboratory</a>
367  template < typename T >
369  {
371  {
372  boost::python::to_python_converter < std::vector < T >,
374  }
375  };
376  template < typename T >
378  {
380  {
381  boost::python::to_python_converter < casacore::Array < T >,
383  }
384  };
385  template < typename T >
387  {
389  {
390  boost::python::to_python_converter < casacore::Vector < T >,
392  }
393  };
395  {
397  {
398  boost::python::to_python_converter < casacore::IPosition,
400  }
401  };
402 
403 
404  // Conversion of Python sequence to C++ container.
405 
406  // Copied from
407  // scitbx/include/scitbx/boost_python/container_conversions.h that is
408  // described in the <a
409  // href="http://www.boost.org/libs/python/doc/v2/faq.html">
410  // Boost.Python FAQ. </a>
411  // @author Ralf W. Grosse-Kunstleve <rwgk@yahoo.com> of
412  // <a href="http://www.lbl.gov/">Lawrence Berkeley National Laboratory</a>
413  template <typename ContainerType, typename ConversionPolicy>
415  {
416  typedef typename ContainerType::value_type container_element_type;
417 
419  {
420  boost::python::converter::registry::push_back(
421  &convertible,
422  &construct,
423  boost::python::type_id<ContainerType>());
424  }
425 
426  // Appears to return @a obj_ptr if it is type of Python sequence
427  // that can be convertible to C++ container.
428  static void* convertible(PyObject* obj_ptr)
429  {
430  using namespace boost::python;
431  handle<> py_hdl(obj_ptr);
432  if (PyErr_Occurred()) {
433  PyErr_Clear();
434  return 0;
435  }
436  object py_obj(py_hdl);
437  incref(obj_ptr); // incr refcount, because ~object decrements it
438  // Accept single values.
439  if (PyBool_Check(obj_ptr)
440  || PyLong_Check(obj_ptr)
441  || PyFloat_Check(obj_ptr)
442  || PyComplex_Check(obj_ptr)
443 #ifndef IS_PY3K
444  || PyInt_Check(obj_ptr)
445  || PyString_Check(obj_ptr)
446 #endif
447  || PyUnicode_Check(obj_ptr)) {
448  extract<container_element_type> elem_proxy(py_obj);
449  if (!elem_proxy.check()) return 0;
450  return obj_ptr;
451  }
452  // An array scalar is accepted.
453  if (PycArrayScalarCheck(obj_ptr)) {
454  return obj_ptr;
455  }
456  // Get the sequence object.
457  // It can be a numarray/numpy scalar in which case
458  // it fills py_obj with a flattened array.
459  if (! getSeqObject (py_obj)) {
460  return 0;
461  }
462  // Check the sequence.
463  // It must be convertible to an iterator.
464  handle<> obj_iter(allow_null(PyObject_GetIter(py_obj.ptr())));
465  if (!obj_iter.get()) {
466  PyErr_Clear();
467  return 0;
468  }
469  if (!check_convertibility (py_obj.ptr())) {
470  return 0;
471  }
472  return obj_ptr;
473  }
474 
475  // Constructs a C++ container from a Python sequence.
476  static void construct(
477  PyObject* obj_ptr,
478  boost::python::converter::rvalue_from_python_stage1_data* data)
479  {
480  using namespace boost::python;
481  using boost::python::converter::rvalue_from_python_storage;
482  void* storage = (
483  (rvalue_from_python_storage<ContainerType>*)
484  data)->storage.bytes;
485  new (storage) ContainerType();
486  data->convertible = storage;
487  ContainerType& result = *((ContainerType*)storage);
488  if (PyBool_Check(obj_ptr)
489  || PyLong_Check(obj_ptr)
490  || PyFloat_Check(obj_ptr)
491  || PyComplex_Check(obj_ptr)
492  || PyUnicode_Check(obj_ptr)
493 #ifndef IS_PY3K
494  || PyString_Check(obj_ptr)
495  || PyInt_Check(obj_ptr)
496 #endif
497  || PycArrayScalarCheck(obj_ptr)) {
498  extract<container_element_type> elem_proxy(obj_ptr);
499  ConversionPolicy::reserve(result, 1);
500  ConversionPolicy::set_value(result, 0, elem_proxy());
501  return;
502  }
503  handle<> py_hdl(obj_ptr);
504  object py_obj = object(py_hdl);
505  incref(obj_ptr); // incr refcount, because ~object decrements it
506  assert (getSeqObject (py_obj));
507  fill_container (result, py_obj.ptr());
508  // ConversionPolicy::reserve(result, 1);
509  // ConversionPolicy::set_value(result, 0,
510  // extract<container_element_type>(py_flat.attr("__getitem__")(0)));
511  }
512 
513  // Constructs a C++ container from a Python sequence.
514  static ContainerType make_container(PyObject* obj_ptr)
515  {
516  ContainerType result;
517  fill_container (result, obj_ptr);
518  return result;
519  }
520 
521  private:
522  static void fill_container (ContainerType& result, PyObject* obj_ptr)
523  {
524  using namespace boost::python;
525  int obj_size = PyObject_Length(obj_ptr);
526  handle<> obj_iter(PyObject_GetIter(obj_ptr));
527  ConversionPolicy::reserve(result, obj_size);
528  std::size_t i=0;
529  for(;;i++) {
530  handle<> py_elem_hdl(allow_null(PyIter_Next(obj_iter.get())));
531  if (PyErr_Occurred()) throw_error_already_set();
532  if (!py_elem_hdl.get()) break; // end of iteration
533  object py_elem_obj(py_elem_hdl);
534  extract<container_element_type> elem_proxy(py_elem_obj);
535  ConversionPolicy::set_value(result, i, elem_proxy());
536  }
537  ConversionPolicy::assert_size(boost::type<ContainerType>(), i);
538  }
539 
540  static bool check_convertibility(PyObject* obj_ptr)
541  {
542  using namespace boost::python;
543  handle<> obj_iter(allow_null(PyObject_GetIter(obj_ptr)));
544  if (!obj_iter.get()) { // must be convertible to an iterator
545  PyErr_Clear();
546  return false;
547  }
548  int obj_size = PyObject_Length(obj_ptr);
549  if (obj_size < 0) { // must be a measurable sequence
550  PyErr_Clear();
551  return false;
552  }
553  if (ConversionPolicy::check_convertibility_per_element()) {
554  if (!ConversionPolicy::check_size(
555  boost::type<ContainerType>(), obj_size)) return false;
556  // All elements in a range and array have the same type, so
557  // need to check the first element only.
558  bool is_same = PyRange_Check(obj_ptr) ||
559  (PySequence_Check(obj_ptr)
560  && !PyTuple_Check(obj_ptr) && !PyList_Check(obj_ptr));
561  int i = 0;
562  for (;;i++) {
563  handle<> py_elem_hdl(allow_null(PyIter_Next(obj_iter.get())));
564  if (PyErr_Occurred()) {
565  PyErr_Clear();
566  return false;
567  }
568  if (!py_elem_hdl.get()) break; // end of iteration
569  object py_elem_obj(py_elem_hdl);
570  extract<container_element_type> elem_proxy(py_elem_obj);
571  if (!elem_proxy.check()) return false;
572  if (is_same) break; // all elements are of the same type
573  }
574  if (!is_same) assert(i == obj_size );
575  }
576  return true;
577  }
578  };
579 
580  // Register the String conversion.
582  {
583  static void reg();
584  };
587 
588  // Register the IPosition conversion.
590  {
591  static void reg();
592  };
595 
596  // Register the std::vector conversions.
597  template < typename T >
599  {
600  static void reg()
601  {
602  std::string tname(typeid(std::vector<T>).name());
603  if (! pyregistry::get (tname)) {
604  pyregistry::set (tname);
608  }
609  }
610  };
611  template < typename T >
614 
615  // Register the casacore::Vector conversions.
616  template < typename T >
618  {
619  static void reg()
620  {
621  std::string tname(typeid(casacore::Vector<T>).name());
622  if (! pyregistry::get (tname)) {
623  pyregistry::set (tname);
628  }
629  }
630  };
631  template < typename T >
634 
635 
636  // Register all standard basic conversions.
637  // These are String, IPosition, Vector<String>, Vector<Int>,
638  // Vector<Double>, Vector<DComplex>.
640 }}
641 
642 #endif
#define AlwaysAssert(expr, exception)
These marcos are provided for use instead of simply using the constructors of assert_ to allow additi...
Definition: Assert.h:157
ConstIteratorSTL const_iterator
Definition: Array.h:853
String: the storage and methods of handling collections of characters.
Definition: String.h:225
Prevent a converter from being registered multiple times.
Definition: PycBasicData.h:54
static bool get(const std::string &name)
static std::map< std::string, bool > _registry
Definition: PycBasicData.h:59
static void set(const std::string &name)
const Double c
Fundamental physical constants (SI units):
void register_convert_casa_string()
Definition: PycBasicData.h:585
void register_convert_basicdata()
Register all standard basic conversions.
Bool PycArrayScalarCheck(PyObject *obj_ptr)
Check if the PyObject is an array scalar object.
void register_convert_casa_iposition()
Definition: PycBasicData.h:593
void register_convert_casa_vector()
Definition: PycBasicData.h:632
bool getSeqObject(boost::python::object &py_obj)
Check if the given object is a sequence object.
void register_convert_std_vector()
Definition: PycBasicData.h:612
this file contains all the compiler specific defines
Definition: mainpage.dox:28
LatticeExprNode value(const LatticeExprNode &expr)
This function returns the value of the expression without a mask.
Define real & complex conjugation for non-complex types and put comparisons into std namespace.
Definition: Complex.h:352
static void set_value(ContainerType &a, std::size_t i, ValueType const &v)
Definition: PycBasicData.h:213
static void reserve(ContainerType &a, std::size_t sz)
Definition: PycBasicData.h:207
Convert a String object from python.
Definition: PycBasicData.h:79
static void * convertible(PyObject *obj_ptr)
Definition: PycBasicData.h:88
static void construct(PyObject *obj_ptr, boost::python::converter::rvalue_from_python_stage1_data *data)
Definition: PycBasicData.h:98
Convert a String object to python.
Definition: PycBasicData.h:70
static boost::python::object makeobject(String const &s)
Definition: PycBasicData.h:71
static PyObject * convert(String const &s)
Definition: PycBasicData.h:73
static void reserve(ContainerType &a, std::size_t sz)
Definition: PycBasicData.h:191
static void set_value(ContainerType &a, std::size_t i, ValueType const &v)
Definition: PycBasicData.h:197
Register the IPosition conversion.
Definition: PycBasicData.h:590
Register the String conversion.
Definition: PycBasicData.h:582
Register the casacore::Vector conversions.
Definition: PycBasicData.h:618
Register the std::vector conversions.
Definition: PycBasicData.h:599
Default operations on all containers for conversion from Python container to C++ one.
Definition: PycBasicData.h:143
static void assert_size(boost::type< ContainerType >, std::size_t)
Definition: PycBasicData.h:153
static bool check_size(boost::type< ContainerType >, std::size_t)
Definition: PycBasicData.h:147
static bool check_convertibility_per_element()
Definition: PycBasicData.h:144
static void reserve(ContainerType &, std::size_t)
Definition: PycBasicData.h:157
Conversion of Python sequence to C++ container.
Definition: PycBasicData.h:415
static void construct(PyObject *obj_ptr, boost::python::converter::rvalue_from_python_stage1_data *data)
Constructs a C++ container from a Python sequence.
Definition: PycBasicData.h:476
static ContainerType make_container(PyObject *obj_ptr)
Constructs a C++ container from a Python sequence.
Definition: PycBasicData.h:514
static void * convertible(PyObject *obj_ptr)
Appears to return obj_ptr if it is type of Python sequence that can be convertible to C++ container.
Definition: PycBasicData.h:428
static void fill_container(ContainerType &result, PyObject *obj_ptr)
Definition: PycBasicData.h:522
static bool check_convertibility(PyObject *obj_ptr)
Definition: PycBasicData.h:540
ContainerType::value_type container_element_type
Definition: PycBasicData.h:416
Converts an STL vector or casa Array of T objects to Python list.
Definition: PycBasicData.h:369
Operations on containers that have variable capacity for conversion from Python container to C++ one.
Definition: PycBasicData.h:173
static void reserve(ContainerType &a, std::size_t sz)
Definition: PycBasicData.h:175
static void set_value(ContainerType &a, std::size_t i, ValueType const &v)
Definition: PycBasicData.h:181
static boost::python::object makeobject(ContainerType const &c)
Definition: PycBasicData.h:324
static PyObject * convert(ContainerType const &c)
Definition: PycBasicData.h:334
static PyObject * convert(ContainerType const &c)
Definition: PycBasicData.h:270
static boost::python::list makeobject(ContainerType const &c)
Definition: PycBasicData.h:261
static boost::python::object makeobject(ContainerType const &c)
Definition: PycBasicData.h:343
static PyObject * convert(ContainerType const &c)
Definition: PycBasicData.h:296
static boost::python::list makeobject(ContainerType const &c)
Definition: PycBasicData.h:285
static boost::python::list makeobject(ContainerType const &c)
Definition: PycBasicData.h:305
static PyObject * convert(ContainerType const &c)
Definition: PycBasicData.h:315
A wrapper of a conversion function to convert a STL vector to a Python list.
Definition: PycBasicData.h:235
static PyObject * convert(ContainerType const &c)
Definition: PycBasicData.h:251
static boost::python::object makeobject(ContainerType const &c)
Creates and returns a Python list from the elements copied from a STL container.
Definition: PycBasicData.h:241