AIToolbox
A library that offers tools for AI problem solving.
Utils.hpp
Go to the documentation of this file.
1 #ifndef AI_TOOLBOX_PYTHON_UTILS_HEADER_FILE
2 #define AI_TOOLBOX_PYTHON_UTILS_HEADER_FILE
3 
4 #include <cstddef>
5 #include <vector>
6 #include <tuple>
7 
8 #include <boost/python.hpp>
9 
10 // C++ to Python
11 
12 template <typename T>
13 struct TupleToPython {
15  boost::python::to_python_converter<T, TupleToPython<T>>();
16  }
17 
18  template<int...>
19  struct sequence {};
20 
21  template<int N, int... S>
22  struct generator : generator<N-1, N-1, S...> { };
23 
24  template<int... S>
25  struct generator<0, S...> {
26  using type = sequence<S...>;
27  };
28 
29  template <int... I>
30  static boost::python::tuple boostConvertImpl(const T& t, sequence<I...>) {
31  return boost::python::make_tuple(std::get<I>(t)...);
32  }
33 
34  static boost::python::tuple boostConvert(const T & t) {
35  return boostConvertImpl(t, typename generator<std::tuple_size_v<T>>::type());
36  }
37 
38  static PyObject* convert(const T& t) {
39  return boost::python::incref(boostConvert(t).ptr());
40  }
41 };
42 
43 template <typename T>
44 struct PairToPython {
46  boost::python::to_python_converter<T, PairToPython<T>>();
47  }
48 
49  static PyObject* convert(const T& t) {
50  return boost::python::incref(boost::python::make_tuple(t.first, t.second).ptr());
51  }
52 };
53 
54 // Python to C++
55 
56 template <typename T>
59  boost::python::converter::registry::push_back(&TupleFromPython::convertible, &TupleFromPython::construct, boost::python::type_id<T>());
60  }
61 
62  static void* convertible(PyObject* obj_ptr) {
63  if (!PyTuple_CheckExact(obj_ptr)) return 0;
64  return obj_ptr;
65  }
66 
67  template <size_t Id, bool = true>
69  void operator()(T & t, PyObject * tuple) {
70  std::get<Id>(t) = boost::python::extract<std::tuple_element_t<Id, T>>(PyTuple_GetItem(tuple, Id));
71  ExtractPythonTuple<Id - 1>()(t, tuple);
72  }
73  };
74 
75  template <bool dummyForSpecialization>
76  struct ExtractPythonTuple<0, dummyForSpecialization> {
77  void operator()(T & t, PyObject * tuple) {
78  std::get<0>(t) = boost::python::extract<std::tuple_element_t<0, T>>(PyTuple_GetItem(tuple, 0));
79  }
80  };
81 
82  static void construct(PyObject* tuple, boost::python::converter::rvalue_from_python_stage1_data* data) {
83  // Grab pointer to memory into which to construct the new tuple
84  void* storage = ((boost::python::converter::rvalue_from_python_storage<T>*)data)->storage.bytes;
85 
86  T& t = *(new (storage) T());
87 
88  // Copy item by item the tuple
90 
91  // Stash the memory chunk pointer for later use by boost.python
92  data->convertible = storage;
93  }
94 };
95 
96 template <typename T>
99  boost::python::converter::registry::push_back(&PairFromPython::convertible, &PairFromPython::construct, boost::python::type_id<T>());
100  }
101 
102  static void* convertible(PyObject* obj_ptr) {
103  if (!PyTuple_CheckExact(obj_ptr)) return 0;
104  return obj_ptr;
105  }
106 
107  static void construct(PyObject* tuple, boost::python::converter::rvalue_from_python_stage1_data* data) {
108  // Grab pointer to memory into which to construct the new tuple
109  void* storage = ((boost::python::converter::rvalue_from_python_storage<T>*)data)->storage.bytes;
110 
111  T& t = *(new (storage) T());
112 
113  // Copy the pair in
114  t.first = boost::python::extract<std::tuple_element_t<0, T>>(PyTuple_GetItem(tuple, 0));
115  t.second = boost::python::extract<std::tuple_element_t<1, T>>(PyTuple_GetItem(tuple, 1));
116 
117  // Stash the memory chunk pointer for later use by boost.python
118  data->convertible = storage;
119  }
120 };
121 
124 
125  static void* convertible(PyObject* obj_ptr);
126  static void construct(PyObject* list, boost::python::converter::rvalue_from_python_stage1_data* data);
127 };
128 
129 template<typename T>
132  boost::python::converter::registry::push_back(&VectorFromPython<T>::convertible, &VectorFromPython<T>::construct, boost::python::type_id<std::vector<T>>());
133  }
134 
135  static void* convertible(PyObject* obj_ptr) {
136  if (!PyList_Check(obj_ptr)) return 0;
137  return obj_ptr;
138  }
139 
140  static void construct(PyObject* list, boost::python::converter::rvalue_from_python_stage1_data* data) {
141  // Grab pointer to memory into which to construct the new std::vector<T>
142  void* storage = ((boost::python::converter::rvalue_from_python_storage<std::vector<T>>*)data)->storage.bytes;
143 
144  std::vector<T>& v = *(new (storage) std::vector<T>());
145 
146  // Copy item by item the list
147  auto size = PyList_Size(list);
148  v.resize(size);
149  for(decltype(size) i = 0; i < size; ++i)
150  v[i] = boost::python::extract<T>(PyList_GetItem(list, i));
151 
152  // Stash the memory chunk pointer for later use by boost.python
153  data->convertible = storage;
154  }
155 };
156 
157 template <typename T>
159  using V2D = std::vector<std::vector<T>>;
160 
162  boost::python::converter::registry::push_back(&Vector2DFromPython<T>::convertible, &Vector2DFromPython<T>::construct, boost::python::type_id<V2D>());
163  }
164 
165  static void* convertible(PyObject* obj_ptr) {
166  if (!PyList_Check(obj_ptr) ||
167  !PyList_Check(PyList_GetItem(obj_ptr,0))) return 0;
168  return obj_ptr;
169  }
170 
171  static void construct(PyObject* list, boost::python::converter::rvalue_from_python_stage1_data* data) {
172  // Grab pointer to memory into which to construct the new std::vector<T>
173  void* storage = ((boost::python::converter::rvalue_from_python_storage<V2D>*)data)->storage.bytes;
174 
175  V2D& v = *(new (storage) V2D());
176 
177  // Copy item by item the list
178  auto size2 = PyList_Size(list);
179  v.resize(size2);
180  for(decltype(size2) i = 0; i < size2; ++i) {
181  auto size1 = PyList_Size(PyList_GetItem(list,0));
182  v[i].resize(size1);
183  for(decltype(size1) j = 0; j < size1; ++j) {
184  v[i][j] = boost::python::extract<T>(PyList_GetItem(PyList_GetItem(list, i), j));
185  }
186  }
187 
188  // Stash the memory chunk pointer for later use by boost.python
189  data->convertible = storage;
190  }
191 };
192 
193 template <typename T>
195  using V3D = std::vector<std::vector<std::vector<T>>>;
196 
198  boost::python::converter::registry::push_back(&Vector3DFromPython<T>::convertible, &Vector3DFromPython<T>::construct, boost::python::type_id<V3D>());
199  }
200 
201  static void* convertible(PyObject* obj_ptr) {
202  if (!PyList_Check(obj_ptr) ||
203  !PyList_Check(PyList_GetItem(obj_ptr,0)) ||
204  !PyList_Check(PyList_GetItem(PyList_GetItem(obj_ptr,0),0))) return 0;
205  return obj_ptr;
206  }
207 
208  static void construct(PyObject* list, boost::python::converter::rvalue_from_python_stage1_data* data) {
209  // Grab pointer to memory into which to construct the new std::vector<T>
210  void* storage = ((boost::python::converter::rvalue_from_python_storage<V3D>*)data)->storage.bytes;
211 
212  V3D& v = *(new (storage) V3D());
213 
214  // Copy item by item the list
215  auto size3 = PyList_Size(list);
216  v.resize(size3);
217  for(decltype(size3) i = 0; i < size3; ++i) {
218  auto size2 = PyList_Size(PyList_GetItem(list,0));
219  v[i].resize(size2);
220  for(decltype(size2) j = 0; j < size2; ++j) {
221  auto size1 = PyList_Size(PyList_GetItem(PyList_GetItem(list,0),0));
222  v[i][j].resize(size1);
223  for(decltype(size1) k = 0; k < size1; ++k)
224  v[i][j][k] = boost::python::extract<T>(PyList_GetItem(PyList_GetItem(PyList_GetItem(list, i), j), k));
225  }
226  }
227 
228  // Stash the memory chunk pointer for later use by boost.python
229  data->convertible = storage;
230  }
231 };
232 
233 #endif
TupleFromPython::TupleFromPython
TupleFromPython()
Definition: Utils.hpp:58
VectorFromPython::convertible
static void * convertible(PyObject *obj_ptr)
Definition: Utils.hpp:135
TupleFromPython
Definition: Utils.hpp:57
PairToPython
Definition: Utils.hpp:44
TupleFromPython::ExtractPythonTuple
Definition: Utils.hpp:68
Vector2DFromPython::construct
static void construct(PyObject *list, boost::python::converter::rvalue_from_python_stage1_data *data)
Definition: Utils.hpp:171
Vector3DFromPython::convertible
static void * convertible(PyObject *obj_ptr)
Definition: Utils.hpp:201
PairFromPython::construct
static void construct(PyObject *tuple, boost::python::converter::rvalue_from_python_stage1_data *data)
Definition: Utils.hpp:107
Vector3DFromPython
Definition: Utils.hpp:194
TupleToPython
Definition: Utils.hpp:13
Vector3DFromPython::Vector3DFromPython
Vector3DFromPython()
Definition: Utils.hpp:197
TupleToPython::convert
static PyObject * convert(const T &t)
Definition: Utils.hpp:38
TupleFromPython::construct
static void construct(PyObject *tuple, boost::python::converter::rvalue_from_python_stage1_data *data)
Definition: Utils.hpp:82
Vector2DFromPython
Definition: Utils.hpp:158
VectorFromPython::VectorFromPython
VectorFromPython()
Definition: Utils.hpp:131
VectorFromPython
Definition: Utils.hpp:130
PairFromPython::PairFromPython
PairFromPython()
Definition: Utils.hpp:98
TupleToPython::generator
Definition: Utils.hpp:22
Vector2DFromPython::V2D
std::vector< std::vector< T > > V2D
Definition: Utils.hpp:159
EigenVectorFromPython::convertible
static void * convertible(PyObject *obj_ptr)
PairFromPython
Definition: Utils.hpp:97
Vector3DFromPython::V3D
std::vector< std::vector< std::vector< T > >> V3D
Definition: Utils.hpp:195
Vector3DFromPython::construct
static void construct(PyObject *list, boost::python::converter::rvalue_from_python_stage1_data *data)
Definition: Utils.hpp:208
PairToPython::convert
static PyObject * convert(const T &t)
Definition: Utils.hpp:49
TupleToPython::TupleToPython
TupleToPython()
Definition: Utils.hpp:14
EigenVectorFromPython::EigenVectorFromPython
EigenVectorFromPython()
Vector2DFromPython::Vector2DFromPython
Vector2DFromPython()
Definition: Utils.hpp:161
TupleToPython::boostConvertImpl
static boost::python::tuple boostConvertImpl(const T &t, sequence< I... >)
Definition: Utils.hpp:30
TupleToPython::sequence
Definition: Utils.hpp:19
VectorFromPython::construct
static void construct(PyObject *list, boost::python::converter::rvalue_from_python_stage1_data *data)
Definition: Utils.hpp:140
PairFromPython::convertible
static void * convertible(PyObject *obj_ptr)
Definition: Utils.hpp:102
EigenVectorFromPython::construct
static void construct(PyObject *list, boost::python::converter::rvalue_from_python_stage1_data *data)
TupleFromPython::convertible
static void * convertible(PyObject *obj_ptr)
Definition: Utils.hpp:62
TupleToPython::boostConvert
static boost::python::tuple boostConvert(const T &t)
Definition: Utils.hpp:34
PairToPython::PairToPython
PairToPython()
Definition: Utils.hpp:45
TupleFromPython::ExtractPythonTuple::operator()
void operator()(T &t, PyObject *tuple)
Definition: Utils.hpp:69
EigenVectorFromPython
Definition: Utils.hpp:122
TupleFromPython::ExtractPythonTuple< 0, dummyForSpecialization >::operator()
void operator()(T &t, PyObject *tuple)
Definition: Utils.hpp:77
Vector2DFromPython::convertible
static void * convertible(PyObject *obj_ptr)
Definition: Utils.hpp:165