test_stl_binders.cpp
Go to the documentation of this file.
1 /*
2  tests/test_stl_binders.cpp -- Usage of stl_binders functions
3 
4  Copyright (c) 2016 Sergey Lyskov
5 
6  All rights reserved. Use of this source code is governed by a
7  BSD-style license that can be found in the LICENSE file.
8 */
9 
10 #include <pybind11/numpy.h>
11 #include <pybind11/stl_bind.h>
12 
13 #include "pybind11_tests.h"
14 
15 #include <deque>
16 #include <map>
17 #include <unordered_map>
18 #include <vector>
19 
20 class El {
21 public:
22  El() = delete;
23  explicit El(int v) : a(v) {}
24 
25  int a;
26 };
27 
28 std::ostream &operator<<(std::ostream &s, El const &v) {
29  s << "El{" << v.a << '}';
30  return s;
31 }
32 
34 class E_nc {
35 public:
36  explicit E_nc(int i) : value{i} {}
37  E_nc(const E_nc &) = delete;
38  E_nc &operator=(const E_nc &) = delete;
39  E_nc(E_nc &&) = default;
40  E_nc &operator=(E_nc &&) = default;
41 
42  int value;
43 };
44 
45 template <class Container>
46 Container *one_to_n(int n) {
47  auto *v = new Container();
48  for (int i = 1; i <= n; i++) {
49  v->emplace_back(i);
50  }
51  return v;
52 }
53 
54 template <class Map>
55 Map *times_ten(int n) {
56  auto *m = new Map();
57  for (int i = 1; i <= n; i++) {
58  m->emplace(int(i), E_nc(10 * i));
59  }
60  return m;
61 }
62 
63 template <class NestMap>
64 NestMap *times_hundred(int n) {
65  auto *m = new NestMap();
66  for (int i = 1; i <= n; i++) {
67  for (int j = 1; j <= n; j++) {
68  (*m)[i].emplace(int(j * 10), E_nc(100 * j));
69  }
70  }
71  return m;
72 }
73 
74 /*
75  * Recursive data structures as test for issue #4623
76  */
77 struct RecursiveVector : std::vector<RecursiveVector> {
78  using Parent = std::vector<RecursiveVector>;
79  using Parent::Parent;
80 };
81 
82 struct RecursiveMap : std::map<int, RecursiveMap> {
83  using Parent = std::map<int, RecursiveMap>;
84  using Parent::Parent;
85 };
86 
87 class UserVectorLike : private std::vector<int> {
88 public:
89  // This is only a subset of the member functions, as needed at the time.
90  using Base = std::vector<int>;
91  using typename Base::const_iterator;
92  using typename Base::difference_type;
93  using typename Base::iterator;
94  using typename Base::size_type;
95  using typename Base::value_type;
96 
97  using Base::at;
98  using Base::back;
99  using Base::Base;
100  using Base::begin;
101  using Base::cbegin;
102  using Base::cend;
103  using Base::clear;
104  using Base::empty;
105  using Base::end;
106  using Base::erase;
107  using Base::front;
108  using Base::insert;
109  using Base::pop_back;
110  using Base::push_back;
111  using Base::reserve;
112  using Base::shrink_to_fit;
113  using Base::swap;
114  using Base::operator[];
115  using Base::capacity;
116  using Base::size;
117 };
118 
119 bool operator==(UserVectorLike const &, UserVectorLike const &) { return true; }
120 bool operator!=(UserVectorLike const &, UserVectorLike const &) { return false; }
121 
122 class UserMapLike : private std::map<int, int> {
123 public:
124  // This is only a subset of the member functions, as needed at the time.
125  using Base = std::map<int, int>;
126  using typename Base::const_iterator;
127  using typename Base::iterator;
128  using typename Base::key_type;
129  using typename Base::mapped_type;
130  using typename Base::size_type;
131  using typename Base::value_type;
132 
133  using Base::at;
134  using Base::Base;
135  using Base::begin;
136  using Base::cbegin;
137  using Base::cend;
138  using Base::clear;
139  using Base::emplace;
140  using Base::emplace_hint;
141  using Base::empty;
142  using Base::end;
143  using Base::erase;
144  using Base::find;
145  using Base::insert;
146  using Base::max_size;
147  using Base::swap;
148  using Base::operator[];
149  using Base::size;
150 };
151 
152 /*
153  * Pybind11 does not catch more complicated recursion schemes, such as mutual
154  * recursion.
155  * In that case custom recursive_container_traits specializations need to be added,
156  * thus manually telling pybind11 about the recursion.
157  */
160 
161 struct MutuallyRecursiveContainerPairMV : std::map<int, MutuallyRecursiveContainerPairVM> {};
162 struct MutuallyRecursiveContainerPairVM : std::vector<MutuallyRecursiveContainerPairMV> {};
163 
164 namespace pybind11 {
165 namespace detail {
166 template <typename SFINAE>
169 };
170 template <typename SFINAE>
173 };
174 } // namespace detail
175 } // namespace pybind11
176 
177 TEST_SUBMODULE(stl_binders, m) {
178  // test_vector_int
179  py::bind_vector<std::vector<unsigned int>>(m, "VectorInt", py::buffer_protocol());
180 
181  // test_vector_custom
182  py::class_<El>(m, "El").def(py::init<int>());
183  py::bind_vector<std::vector<El>>(m, "VectorEl");
184  py::bind_vector<std::vector<std::vector<El>>>(m, "VectorVectorEl");
185 
186  // test_map_string_double
187  py::bind_map<std::map<std::string, double>>(m, "MapStringDouble");
188  py::bind_map<std::unordered_map<std::string, double>>(m, "UnorderedMapStringDouble");
189 
190  // test_map_string_double_const
191  py::bind_map<std::map<std::string, double const>>(m, "MapStringDoubleConst");
192  py::bind_map<std::unordered_map<std::string, double const>>(m,
193  "UnorderedMapStringDoubleConst");
194 
195  // test_map_view_types
196  py::bind_map<std::map<std::string, float>>(m, "MapStringFloat");
197  py::bind_map<std::unordered_map<std::string, float>>(m, "UnorderedMapStringFloat");
198 
199  py::bind_map<std::map<std::pair<double, int>, int32_t>>(m, "MapPairDoubleIntInt32");
200  py::bind_map<std::map<std::pair<double, int>, int64_t>>(m, "MapPairDoubleIntInt64");
201 
202  py::bind_map<std::map<int, py::object>>(m, "MapIntObject");
203  py::bind_map<std::map<std::string, py::object>>(m, "MapStringObject");
204 
205  py::class_<E_nc>(m, "ENC").def(py::init<int>()).def_readwrite("value", &E_nc::value);
206 
207  // test_noncopyable_containers
208  py::bind_vector<std::vector<E_nc>>(m, "VectorENC");
209  m.def("get_vnc", &one_to_n<std::vector<E_nc>>);
210  py::bind_vector<std::deque<E_nc>>(m, "DequeENC");
211  m.def("get_dnc", &one_to_n<std::deque<E_nc>>);
212  py::bind_map<std::map<int, E_nc>>(m, "MapENC");
213  m.def("get_mnc", &times_ten<std::map<int, E_nc>>);
214  py::bind_map<std::unordered_map<int, E_nc>>(m, "UmapENC");
215  m.def("get_umnc", &times_ten<std::unordered_map<int, E_nc>>);
216  // Issue #1885: binding nested std::map<X, Container<E>> with E non-copyable
217  py::bind_map<std::map<int, std::vector<E_nc>>>(m, "MapVecENC");
218  m.def("get_nvnc", [](int n) {
219  auto *m = new std::map<int, std::vector<E_nc>>();
220  for (int i = 1; i <= n; i++) {
221  for (int j = 1; j <= n; j++) {
222  (*m)[i].emplace_back(j);
223  }
224  }
225  return m;
226  });
227  py::bind_map<std::map<int, std::map<int, E_nc>>>(m, "MapMapENC");
228  m.def("get_nmnc", &times_hundred<std::map<int, std::map<int, E_nc>>>);
229  py::bind_map<std::unordered_map<int, std::unordered_map<int, E_nc>>>(m, "UmapUmapENC");
230  m.def("get_numnc", &times_hundred<std::unordered_map<int, std::unordered_map<int, E_nc>>>);
231 
232  // test_vector_buffer
233  py::bind_vector<std::vector<unsigned char>>(m, "VectorUChar", py::buffer_protocol());
234  // no dtype declared for this version:
235  struct VUndeclStruct {
236  bool w;
237  uint32_t x;
238  double y;
239  bool z;
240  };
241  m.def("create_undeclstruct", [m]() mutable {
242  py::bind_vector<std::vector<VUndeclStruct>>(
243  m, "VectorUndeclStruct", py::buffer_protocol());
244  });
245 
246  // Bind recursive container types
247  py::bind_vector<RecursiveVector>(m, "RecursiveVector");
248  py::bind_map<RecursiveMap>(m, "RecursiveMap");
249  py::bind_map<MutuallyRecursiveContainerPairMV>(m, "MutuallyRecursiveContainerPairMV");
250  py::bind_vector<MutuallyRecursiveContainerPairVM>(m, "MutuallyRecursiveContainerPairVM");
251 
252  // Bind with private inheritance + `using` directives.
253  py::bind_vector<UserVectorLike>(m, "UserVectorLike");
254  py::bind_map<UserMapLike>(m, "UserMapLike");
255 
256  // The rest depends on numpy:
257  try {
258  py::module_::import("numpy");
259  } catch (...) {
260  return;
261  }
262 
263  // test_vector_buffer_numpy
264  struct VStruct {
265  bool w;
266  uint32_t x;
267  double y;
268  bool z;
269  };
270  PYBIND11_NUMPY_DTYPE(VStruct, w, x, y, z);
271  py::class_<VStruct>(m, "VStruct").def_readwrite("x", &VStruct::x);
272  py::bind_vector<std::vector<VStruct>>(m, "VectorStruct", py::buffer_protocol());
273  m.def("get_vectorstruct",
274  [] { return std::vector<VStruct>{{false, 5, 3.0, true}, {true, 30, -1e4, false}}; });
275 }
w
RowVector3d w
Definition: Matrix_resize_int.cpp:3
E_nc::value
int value
Definition: test_stl_binders.cpp:42
s
RealScalar s
Definition: level1_cplx_impl.h:126
MutuallyRecursiveContainerPairVM
Definition: test_stl_binders.cpp:162
uint32_t
unsigned int uint32_t
Definition: ms_stdint.h:85
E_nc::operator=
E_nc & operator=(const E_nc &)=delete
x
set noclip points set clip one set noclip two set bar set border lt lw set xdata set ydata set zdata set x2data set y2data set boxwidth set dummy x
Definition: gnuplot_common_settings.hh:12
El::a
int a
Definition: test_stl_binders.cpp:25
detail
Definition: testSerializationNonlinear.cpp:70
RecursiveMap::Parent
std::map< int, RecursiveMap > Parent
Definition: test_stl_binders.cpp:83
Eigen::DenseBase::operator<<
std::ostream & operator<<(std::ostream &s, const DenseBase< Derived > &m)
Definition: IO.h:250
El
Definition: test_stl_binders.cpp:20
times_hundred
NestMap * times_hundred(int n)
Definition: test_stl_binders.cpp:64
El::El
El()=delete
RecursiveVector::Parent
std::vector< RecursiveVector > Parent
Definition: test_stl_binders.cpp:78
size
Scalar Scalar int size
Definition: benchVecAdd.cpp:17
UserMapLike
Definition: test_stl_binders.cpp:122
n
int n
Definition: BiCGSTAB_simple.cpp:1
UserVectorLike
Definition: test_stl_binders.cpp:87
recursive_container_traits
Definition: type_caster_base.h:1002
j
std::ptrdiff_t j
Definition: tut_arithmetic_redux_minmax.cpp:2
int64_t
signed __int64 int64_t
Definition: ms_stdint.h:94
PYBIND11_NUMPY_DTYPE
#define PYBIND11_NUMPY_DTYPE(Type,...)
Definition: numpy.h:1652
RecursiveMap
Definition: test_copy_move.cpp:527
MutuallyRecursiveContainerPairMV
Definition: test_stl_binders.cpp:161
one_to_n
Container * one_to_n(int n)
Definition: test_stl_binders.cpp:46
El::El
El(int v)
Definition: test_stl_binders.cpp:23
numpy.h
pybind_wrapper_test_script.z
z
Definition: pybind_wrapper_test_script.py:61
m
Matrix3f m
Definition: AngleAxis_mimic_euler.cpp:1
RecursiveVector
Definition: test_copy_move.cpp:508
y
Scalar * y
Definition: level1_cplx_impl.h:124
operator!=
bool operator!=(UserVectorLike const &, UserVectorLike const &)
Definition: test_stl_binders.cpp:120
operator==
bool operator==(UserVectorLike const &, UserVectorLike const &)
Definition: test_stl_binders.cpp:119
E_nc
Issue #487: binding std::vector<E> with E non-copyable.
Definition: test_stl_binders.cpp:34
times_ten
Map * times_ten(int n)
Definition: test_stl_binders.cpp:55
pybind11_tests.h
Base::Base
Base()=default
v
Array< int, Dynamic, 1 > v
Definition: Array_initializer_list_vector_cxx11.cpp:1
pybind11
Definition: wrap/pybind11/pybind11/__init__.py:1
int32_t
signed int int32_t
Definition: ms_stdint.h:82
recursive_bottom
Definition: type_caster_base.h:914
Eigen::placeholders::end
static const EIGEN_DEPRECATED end_t end
Definition: IndexedViewHelper.h:181
Base
Definition: test_virtual_functions.cpp:156
insert
A insert(1, 2)=0
swap
int EIGEN_BLAS_FUNC() swap(int *n, RealScalar *px, int *incx, RealScalar *py, int *incy)
Definition: level1_impl.h:130
TEST_SUBMODULE
TEST_SUBMODULE(stl_binders, m)
Definition: test_stl_binders.cpp:177
stl_bind.h
i
int i
Definition: BiCGSTAB_step_by_step.cpp:9
E_nc::E_nc
E_nc(int i)
Definition: test_stl_binders.cpp:36


gtsam
Author(s):
autogenerated on Fri Nov 1 2024 03:39:32