IPSDK  4_1_0_2
IPSDK : Image Processing Software Development Kit
PythonStdVectorUtils.h
Go to the documentation of this file.
1 // PythonStdVectorUtils.h:
3 // -----------------------
4 //
14 
15 #ifndef __PYIPSDKBASE_PYTHONSTDVECTORUTILS_H__
16 #define __PYIPSDKBASE_PYTHONSTDVECTORUTILS_H__
17 
18 #include <vector>
19 #include <boost/python/iterator.hpp>
20 #include <boost/python/self.hpp>
21 #include <boost/python/operators.hpp>
22 #include <boost/python/suite/indexing/vector_indexing_suite.hpp>
23 
24 namespace ipsdk {
25 namespace python {
26 
29 
30 // from http://stackoverflow.com/questions/15842126/feeding-a-python-list-into-a-function-taking-in-a-vector-with-boost-python
31 template <typename Container>
33 {
34  // @brief Check if PyObject is iterable.
35  static void* convertible(PyObject* object)
36  {
37  return PyObject_GetIter(object) ? object : NULL;
38  }
39 
40  // @brief Convert iterable PyObject to C++ container type.
41  //
42  // Container Concept requirements:
43  //
44  // * Container::value_type is CopyConstructable.
45  // * Container can be constructed and populated with two iterators.
46  // I.e. Container(begin, end)
47  static void construct(
48  PyObject* object,
49  boost::python::converter::rvalue_from_python_stage1_data* data)
50  {
51  namespace python = boost::python;
52  // Object is a borrowed reference, so create a handle indicting it is
53  // borrowed for proper reference counting.
54  python::handle<> handle(python::borrowed(object));
55 
56  // Obtain a handle to the memory block that the converter has allocated
57  // for the C++ type.
58  typedef python::converter::rvalue_from_python_storage<Container>
59  storage_type;
60  void* storage = reinterpret_cast<storage_type*>(data)->storage.bytes;
61 
62  typedef python::stl_input_iterator<typename Container::value_type>
63  iterator;
64 
65  // Allocate the C++ type into the converter's memory block, and assign
66  // its handle to the converter's convertible variable. The C++
67  // container is populated by passing the begin and end iterators of
68  // the python object to the container's constructor.
69  new (storage)Container(
70  iterator(python::object(handle)), // begin
71  iterator()); // end
72  data->convertible = storage;
73  }
74 
75  // create string associated to object
76  static std::string to_string(const Container& cl)
77  {
78  std::stringstream ss;
79  ss << "[";
80  bool first = true;
81  for (typename Container::const_iterator
82  i = cl.begin(), e = cl.end(); i != e; ++i) {
83  if (first) {
84  first = false;
85  }
86  else {
87  ss << ", ";
88  }
89  ss << (*i);
90  }
91  ss << "]";
92  return ss.str();
93  }
94 };
95 
96 // export vector
97 template<class Container> void
98 export_vector_no_proxy(const char* py_name)
99 {
100  boost::python::type_info info = boost::python::type_id<Container>();
101  const boost::python::converter::registration* reg = boost::python::converter::registry::query(info);
102  if (reg == 0 || reg->m_to_python == 0) {
103 
104  boost::python::class_<Container>(py_name)
105  .def(boost::python::vector_indexing_suite<Container, true>())
106  .def("__str__", &VectorConverter<Container>::to_string);
107  boost::python::converter::registry::push_back(
110  boost::python::type_id<Container>());
111  }
112 }
113 
114 // export vector
115 template<class Container> void
116 export_vector(const char* py_name)
117 {
118  boost::python::type_info info = boost::python::type_id<Container>();
119  const boost::python::converter::registration* reg = boost::python::converter::registry::query(info);
120  if (reg == 0 || reg->m_to_python == 0) {
121 
122  boost::python::class_<Container>(py_name)
123  .def(boost::python::vector_indexing_suite<Container>())
124  .def("__str__", &VectorConverter<Container>::to_string);
125  boost::python::converter::registry::push_back(
126  &VectorConverter<Container>::convertible,
127  &VectorConverter<Container>::construct,
128  boost::python::type_id<Container>());
129  }
130 }
131 
132 // export vector
133 template<class Container> void
134 export_vector_no_str(const char* py_name)
135 {
136  boost::python::type_info info = boost::python::type_id<Container>();
137  const boost::python::converter::registration* reg = boost::python::converter::registry::query(info);
138  if (reg == 0 || reg->m_to_python == 0) {
139 
140  boost::python::class_<Container>(py_name)
141  .def(boost::python::vector_indexing_suite<Container>());
142  boost::python::converter::registry::push_back(
143  &VectorConverter<Container>::convertible,
144  &VectorConverter<Container>::construct,
145  boost::python::type_id<Container>());
146  }
147 }
148 
149 // export vector
150 template<class Container> void
151 export_vector_no_str_no_proxy(const char* py_name)
152 {
153  boost::python::type_info info = boost::python::type_id<Container>();
154  const boost::python::converter::registration* reg = boost::python::converter::registry::query(info);
155  if (reg == 0 || reg->m_to_python == 0) {
156 
157  boost::python::class_<Container>(py_name)
158  .def(boost::python::vector_indexing_suite<Container, true>());
159  boost::python::converter::registry::push_back(
160  &VectorConverter<Container>::convertible,
161  &VectorConverter<Container>::construct,
162  boost::python::type_id<Container>());
163  }
164 }
165 
168 
169 } // end of namespace python
170 } // end of namespace ipsdk
171 
172 #endif // __PYIPSDKBASE_PYTHONSTDVECTORUTILS_H__
Main namespace for IPSDK library.
Definition: AlgorithmFunctionEfficiency.h:22
Definition: PythonStdVectorUtils.h:32