21 #ifdef PYBIND11_HAS_OPTIONAL
23 #endif // PYBIND11_HAS_OPTIONAL
38 const
T &operator*()
const {
return *
ptr_; }
47 template <
typename A,
typename B>
49 return !(*it).first || !(*it).second;
92 template <
typename PythonType>
95 throw py::value_error(
"Please provide at least 5 elements for testing.");
98 auto checks = py::list();
100 auto result = PyObject_RichCompareBool(
a.ptr(),
b.ptr(), Py_EQ);
102 throw py::error_already_set();
104 checks.append(
result != 0);
129 checks.append(
static_cast<std::size_t>(
x.end() -
x.begin()) ==
x.size());
130 checks.append((
x.begin() +
static_cast<std::ptrdiff_t
>(
x.size())) ==
x.end());
131 checks.append(
x.begin() <
x.end());
140 explicit Sliceable(
int n) :
size(
n) {}
141 int start, stop,
step;
144 py::class_<Sliceable>(
m,
"Sliceable")
145 .def(py::init<int>())
146 .def(
"__getitem__", [](
const Sliceable &
s,
const py::slice &
slice) {
149 throw py::error_already_set();
151 int istart =
static_cast<int>(start);
152 int istop =
static_cast<int>(stop);
153 int istep =
static_cast<int>(
step);
157 m.def(
"make_forward_slice_size_t", []() {
return py::slice(0, -1, 1); });
158 m.def(
"make_reversed_slice_object",
159 []() {
return py::slice(py::none(), py::none(), py::int_(-1)); });
160 #ifdef PYBIND11_HAS_OPTIONAL
161 m.attr(
"has_optional") =
true;
162 m.def(
"make_reversed_slice_size_t_optional_verbose",
163 []() {
return py::slice(std::nullopt, std::nullopt, -1); });
166 m.def(
"make_reversed_slice_size_t_optional", []() {
return py::slice({}, {}, -1); });
168 m.attr(
"has_optional") =
false;
177 m_data =
new float[
size];
178 memset(m_data, 0,
sizeof(
float) *
size);
183 m_data =
new float[m_size];
184 memcpy(m_data, &
value[0],
sizeof(
float) * m_size);
189 m_data =
new float[m_size];
190 memcpy(m_data,
s.m_data,
sizeof(
float) * m_size);
207 m_data =
new float[m_size];
208 memcpy(m_data,
s.m_data,
sizeof(
float) * m_size);
227 if (m_size !=
s.size()) {
230 for (
size_t i = 0;
i < m_size; ++
i) {
231 if (m_data[
i] !=
s[
i]) {
239 float operator[](
size_t index)
const {
return m_data[index]; }
240 float &operator[](
size_t index) {
return m_data[index]; }
242 bool contains(
float v)
const {
243 for (
size_t i = 0;
i < m_size; ++
i) {
244 if (
v == m_data[
i]) {
253 for (
size_t i = 0;
i < m_size; ++
i) {
259 size_t size()
const {
return m_size; }
261 const float *begin()
const {
return m_data; }
262 const float *
end()
const {
return m_data + m_size; }
268 py::class_<Sequence>(
m,
"Sequence")
269 .def(py::init<size_t>())
270 .def(
py::init<
const std::vector<float> &>())
275 throw py::index_error();
282 throw py::index_error();
291 py::keep_alive<0, 1>() )
292 .def(
"__contains__", [](
const Sequence &
s,
float v) {
return s.contains(
v); })
297 size_t start = 0, stop = 0,
step = 0, slicelength = 0;
299 throw py::error_already_set();
302 for (
size_t i = 0;
i < slicelength; ++
i) {
303 (*seq)[
i] =
s[start];
310 size_t start = 0, stop = 0,
step = 0, slicelength = 0;
312 throw py::error_already_set();
314 if (slicelength !=
value.size()) {
315 throw std::runtime_error(
316 "Left and right hand size of slice assignment have different sizes!");
318 for (
size_t i = 0;
i < slicelength; ++
i) {
334 StringMap() =
default;
335 explicit StringMap(std::unordered_map<std::string, std::string>
init)
336 : map(std::move(
init)) {}
338 void set(
const std::string &
key, std::string val) { map[
key] = std::move(val); }
339 std::string
get(
const std::string &
key)
const {
return map.at(
key); }
340 size_t size()
const {
return map.size(); }
343 std::unordered_map<std::string, std::string> map;
346 decltype(map.cbegin()) begin()
const {
return map.cbegin(); }
347 decltype(map.cend())
end()
const {
return map.cend(); }
349 py::class_<StringMap>(
m,
"StringMap")
351 .def(
py::init<std::unordered_map<std::string, std::string>>())
353 [](
const StringMap &map,
const std::string &
key) {
356 }
catch (
const std::out_of_range &) {
357 throw py::key_error(
"key '" +
key +
"' does not exist");
365 py::keep_alive<0, 1>())
369 py::keep_alive<0, 1>())
373 py::keep_alive<0, 1>());
378 explicit IntPairs(std::vector<std::pair<int, int>>
data) : data_(std::move(
data)) {}
379 const std::pair<int, int> *begin()
const {
return data_.data(); }
381 const std::pair<int, int> *
end()
const {
return data_.data() + data_.size(); }
384 std::vector<std::pair<int, int>> data_;
397 py::class_<IntPairs>(
m,
"IntPairs")
398 .def(
py::init<std::vector<std::pair<int, int>>>())
401 [](
const IntPairs &
s) {
405 py::keep_alive<0, 1>())
408 [](
const IntPairs &
s) {
412 py::keep_alive<0, 1>())
415 [](
const IntPairs &
s) {
419 py::keep_alive<0, 1>())
424 [](
const IntPairs &
s) {
428 py::keep_alive<0, 1>())
431 [](
const IntPairs &
s) {
435 py::keep_alive<0, 1>())
438 [](
const IntPairs &
s) {
442 py::keep_alive<0, 1>())
448 py::keep_alive<0, 1>())
452 py::keep_alive<0, 1>())
456 py::keep_alive<0, 1>())
462 "_make_iterator_extras",
464 py::keep_alive<0, 1>())
468 py::keep_alive<0, 1>())
470 "_make_value_extras",
472 py::keep_alive<0, 1>());
475 py::class_<NonCopyableInt>(
m,
"NonCopyableInt")
476 .def(py::init<int>())
479 py::class_<std::vector<NonCopyableInt>>(
m,
"VectorNonCopyableInt")
482 [](std::vector<NonCopyableInt> &vec,
int value) { vec.emplace_back(
value); })
483 .def(
"__iter__", [](std::vector<NonCopyableInt> &vec) {
486 py::class_<std::vector<NonCopyableIntPair>>(
m,
"VectorNonCopyableIntPair")
489 [](std::vector<NonCopyableIntPair> &vec,
const std::pair<int, int> &
value) {
493 [](std::vector<NonCopyableIntPair> &vec) {
496 .def(
"values", [](std::vector<NonCopyableIntPair> &vec) {
505 struct PySequenceIterator {
509 if (index ==
seq.size())
510 throw py::stop_iteration();
519 py::class_<PySequenceIterator>(
seq,
"Iterator")
520 .def(
"__iter__", [](PySequenceIterator &it) -> PySequenceIterator& {
return it; })
521 .def(
"__next__", &PySequenceIterator::next);
524 .def(
"__iter__", [](py::object
s) {
return PySequenceIterator(
s.cast<
const Sequence &>(),
s); })
528 m.def(
"object_to_list", [](
const py::object &o) {
530 for (
auto item : o) {
536 m.def(
"iterator_to_list", [](py::iterator it) {
538 while (it != py::iterator::sentinel()) {
546 m.def(
"sequence_length", [](
const py::sequence &
seq) {
return seq.size(); });
549 m.def(
"count_none", [](
const py::object &o) {
550 return std::count_if(o.begin(), o.end(), [](py::handle
h) { return h.is_none(); });
553 m.def(
"find_none", [](
const py::object &o) {
554 auto it = std::find_if(o.begin(), o.end(), [](py::handle
h) { return h.is_none(); });
555 return it->is_none();
558 m.def(
"count_nonzeros", [](
const py::dict &
d) {
559 return std::count_if(
d.begin(),
d.end(), [](std::pair<py::handle, py::handle>
p) {
560 return p.second.cast<int>() != 0;
564 m.def(
"tuple_iterator", &test_random_access_iterator<py::tuple>);
565 m.def(
"list_iterator", &test_random_access_iterator<py::list>);
566 m.def(
"sequence_iterator", &test_random_access_iterator<py::sequence>);
570 m.def(
"iterator_passthrough", [](py::iterator
s) -> py::iterator {
576 static std::vector<int> list = {1, 2, 3};
577 m.def(
"make_iterator_1",
578 []() {
return py::make_iterator<py::return_value_policy::copy>(list); });
579 m.def(
"make_iterator_2",
580 []() {
return py::make_iterator<py::return_value_policy::automatic>(list); });
586 CArrayHolder(
double x,
double y,
double z) {
594 py::class_<CArrayHolder>(
m,
"CArrayHolder")
595 .def(py::init<double, double, double>())
599 py::keep_alive<0, 1>());