stl_bind.h
Go to the documentation of this file.
1 /*
2  pybind11/std_bind.h: Binding generators for STL data types
3 
4  Copyright (c) 2016 Sergey Lyskov and Wenzel Jakob
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 #pragma once
11 
12 #include "detail/common.h"
13 #include "operators.h"
14 
15 #include <algorithm>
16 #include <sstream>
17 
20 
21 /* SFINAE helper class used by 'is_comparable */
22 template <typename T>
24  template <typename T2>
25  static std::true_type
26  test_comparable(decltype(std::declval<const T2 &>() == std::declval<const T2 &>()) *);
27  template <typename T2>
28  static std::false_type test_comparable(...);
29  template <typename T2>
30  static std::true_type test_value(typename T2::value_type *);
31  template <typename T2>
32  static std::false_type test_value(...);
33  template <typename T2>
34  static std::true_type test_pair(typename T2::first_type *, typename T2::second_type *);
35  template <typename T2>
36  static std::false_type test_pair(...);
37 
38  static constexpr const bool is_comparable
39  = std::is_same<std::true_type, decltype(test_comparable<T>(nullptr))>::value;
40  static constexpr const bool is_pair
41  = std::is_same<std::true_type, decltype(test_pair<T>(nullptr, nullptr))>::value;
42  static constexpr const bool is_vector
43  = std::is_same<std::true_type, decltype(test_value<T>(nullptr))>::value;
44  static constexpr const bool is_element = !is_pair && !is_vector;
45 };
46 
47 /* Default: is_comparable -> std::false_type */
48 template <typename T, typename SFINAE = void>
49 struct is_comparable : std::false_type {};
50 
51 /* For non-map data structures, check whether operator== can be instantiated */
52 template <typename T>
54  T,
56  : std::true_type {};
57 
58 /* For a vector/map data structure, recursively check the value type
59  (which is std::pair for maps) */
60 template <typename T>
62  static constexpr const bool value = is_comparable<typename T::value_type>::value;
63 };
64 
65 /* For pairs, recursively check the two data types */
66 template <typename T>
70 };
71 
72 /* Fallback functions */
73 template <typename, typename, typename... Args>
74 void vector_if_copy_constructible(const Args &...) {}
75 template <typename, typename, typename... Args>
76 void vector_if_equal_operator(const Args &...) {}
77 template <typename, typename, typename... Args>
78 void vector_if_insertion_operator(const Args &...) {}
79 template <typename, typename, typename... Args>
80 void vector_modifiers(const Args &...) {}
81 
82 template <typename Vector, typename Class_>
84  cl.def(init<const Vector &>(), "Copy constructor");
85 }
86 
87 template <typename Vector, typename Class_>
89  using T = typename Vector::value_type;
90 
91  cl.def(self == self);
92  cl.def(self != self);
93 
94  cl.def(
95  "count",
96  [](const Vector &v, const T &x) { return std::count(v.begin(), v.end(), x); },
97  arg("x"),
98  "Return the number of times ``x`` appears in the list");
99 
100  cl.def(
101  "remove",
102  [](Vector &v, const T &x) {
103  auto p = std::find(v.begin(), v.end(), x);
104  if (p != v.end()) {
105  v.erase(p);
106  } else {
107  throw value_error();
108  }
109  },
110  arg("x"),
111  "Remove the first item from the list whose value is x. "
112  "It is an error if there is no such item.");
113 
114  cl.def(
115  "__contains__",
116  [](const Vector &v, const T &x) { return std::find(v.begin(), v.end(), x) != v.end(); },
117  arg("x"),
118  "Return true the container contains ``x``");
119 }
120 
121 // Vector modifiers -- requires a copyable vector_type:
122 // (Technically, some of these (pop and __delitem__) don't actually require copyability, but it
123 // seems silly to allow deletion but not insertion, so include them here too.)
124 template <typename Vector, typename Class_>
127  using T = typename Vector::value_type;
128  using SizeType = typename Vector::size_type;
129  using DiffType = typename Vector::difference_type;
130 
131  auto wrap_i = [](DiffType i, SizeType n) {
132  if (i < 0) {
133  i += n;
134  }
135  if (i < 0 || (SizeType) i >= n) {
136  throw index_error();
137  }
138  return i;
139  };
140 
141  cl.def(
142  "append",
143  [](Vector &v, const T &value) { v.push_back(value); },
144  arg("x"),
145  "Add an item to the end of the list");
146 
147  cl.def(init([](const iterable &it) {
148  auto v = std::unique_ptr<Vector>(new Vector());
149  v->reserve(len_hint(it));
150  for (handle h : it) {
151  v->push_back(h.cast<T>());
152  }
153  return v.release();
154  }));
155 
156  cl.def(
157  "clear", [](Vector &v) { v.clear(); }, "Clear the contents");
158 
159  cl.def(
160  "extend",
161  [](Vector &v, const Vector &src) { v.insert(v.end(), src.begin(), src.end()); },
162  arg("L"),
163  "Extend the list by appending all the items in the given list");
164 
165  cl.def(
166  "extend",
167  [](Vector &v, const iterable &it) {
168  const size_t old_size = v.size();
169  v.reserve(old_size + len_hint(it));
170  try {
171  for (handle h : it) {
172  v.push_back(h.cast<T>());
173  }
174  } catch (const cast_error &) {
175  v.erase(v.begin() + static_cast<typename Vector::difference_type>(old_size),
176  v.end());
177  try {
178  v.shrink_to_fit();
179  } catch (const std::exception &) {
180  // Do nothing
181  }
182  throw;
183  }
184  },
185  arg("L"),
186  "Extend the list by appending all the items in the given list");
187 
188  cl.def(
189  "insert",
190  [](Vector &v, DiffType i, const T &x) {
191  // Can't use wrap_i; i == v.size() is OK
192  if (i < 0) {
193  i += v.size();
194  }
195  if (i < 0 || (SizeType) i > v.size()) {
196  throw index_error();
197  }
198  v.insert(v.begin() + i, x);
199  },
200  arg("i"),
201  arg("x"),
202  "Insert an item at a given position.");
203 
204  cl.def(
205  "pop",
206  [](Vector &v) {
207  if (v.empty()) {
208  throw index_error();
209  }
210  T t = std::move(v.back());
211  v.pop_back();
212  return t;
213  },
214  "Remove and return the last item");
215 
216  cl.def(
217  "pop",
218  [wrap_i](Vector &v, DiffType i) {
219  i = wrap_i(i, v.size());
220  T t = std::move(v[(SizeType) i]);
221  v.erase(std::next(v.begin(), i));
222  return t;
223  },
224  arg("i"),
225  "Remove and return the item at index ``i``");
226 
227  cl.def("__setitem__", [wrap_i](Vector &v, DiffType i, const T &t) {
228  i = wrap_i(i, v.size());
229  v[(SizeType) i] = t;
230  });
231 
233  cl.def(
234  "__getitem__",
235  [](const Vector &v, const slice &slice) -> Vector * {
236  size_t start = 0, stop = 0, step = 0, slicelength = 0;
237 
238  if (!slice.compute(v.size(), &start, &stop, &step, &slicelength)) {
239  throw error_already_set();
240  }
241 
242  auto *seq = new Vector();
243  seq->reserve((size_t) slicelength);
244 
245  for (size_t i = 0; i < slicelength; ++i) {
246  seq->push_back(v[start]);
247  start += step;
248  }
249  return seq;
250  },
251  arg("s"),
252  "Retrieve list elements using a slice object");
253 
254  cl.def(
255  "__setitem__",
256  [](Vector &v, const slice &slice, const Vector &value) {
257  size_t start = 0, stop = 0, step = 0, slicelength = 0;
258  if (!slice.compute(v.size(), &start, &stop, &step, &slicelength)) {
259  throw error_already_set();
260  }
261 
262  if (slicelength != value.size()) {
263  throw std::runtime_error(
264  "Left and right hand size of slice assignment have different sizes!");
265  }
266 
267  for (size_t i = 0; i < slicelength; ++i) {
268  v[start] = value[i];
269  start += step;
270  }
271  },
272  "Assign list elements using a slice object");
273 
274  cl.def(
275  "__delitem__",
276  [wrap_i](Vector &v, DiffType i) {
277  i = wrap_i(i, v.size());
278  v.erase(v.begin() + i);
279  },
280  "Delete the list elements at index ``i``");
281 
282  cl.def(
283  "__delitem__",
284  [](Vector &v, const slice &slice) {
285  size_t start = 0, stop = 0, step = 0, slicelength = 0;
286 
287  if (!slice.compute(v.size(), &start, &stop, &step, &slicelength)) {
288  throw error_already_set();
289  }
290 
291  if (step == 1 && false) {
292  v.erase(v.begin() + (DiffType) start, v.begin() + DiffType(start + slicelength));
293  } else {
294  for (size_t i = 0; i < slicelength; ++i) {
295  v.erase(v.begin() + DiffType(start));
296  start += step - 1;
297  }
298  }
299  },
300  "Delete list elements using a slice object");
301 }
302 
303 // If the type has an operator[] that doesn't return a reference (most notably std::vector<bool>),
304 // we have to access by copying; otherwise we return by reference.
305 template <typename Vector>
306 using vector_needs_copy
307  = negation<std::is_same<decltype(std::declval<Vector>()[typename Vector::size_type()]),
308  typename Vector::value_type &>>;
309 
310 // The usual case: access and iterate by reference
311 template <typename Vector, typename Class_>
313  using T = typename Vector::value_type;
314  using SizeType = typename Vector::size_type;
315  using DiffType = typename Vector::difference_type;
316  using ItType = typename Vector::iterator;
317 
318  auto wrap_i = [](DiffType i, SizeType n) {
319  if (i < 0) {
320  i += n;
321  }
322  if (i < 0 || (SizeType) i >= n) {
323  throw index_error();
324  }
325  return i;
326  };
327 
328  cl.def(
329  "__getitem__",
330  [wrap_i](Vector &v, DiffType i) -> T & {
331  i = wrap_i(i, v.size());
332  return v[(SizeType) i];
333  },
334  return_value_policy::reference_internal // ref + keepalive
335  );
336 
337  cl.def(
338  "__iter__",
339  [](Vector &v) {
340  return make_iterator<return_value_policy::reference_internal, ItType, ItType, T &>(
341  v.begin(), v.end());
342  },
343  keep_alive<0, 1>() /* Essential: keep list alive while iterator exists */
344  );
345 }
346 
347 // The case for special objects, like std::vector<bool>, that have to be returned-by-copy:
348 template <typename Vector, typename Class_>
350  using T = typename Vector::value_type;
351  using SizeType = typename Vector::size_type;
352  using DiffType = typename Vector::difference_type;
353  using ItType = typename Vector::iterator;
354  cl.def("__getitem__", [](const Vector &v, DiffType i) -> T {
355  if (i < 0 && (i += v.size()) < 0) {
356  throw index_error();
357  }
358  if ((SizeType) i >= v.size()) {
359  throw index_error();
360  }
361  return v[(SizeType) i];
362  });
363 
364  cl.def(
365  "__iter__",
366  [](Vector &v) {
367  return make_iterator<return_value_policy::copy, ItType, ItType, T>(v.begin(), v.end());
368  },
369  keep_alive<0, 1>() /* Essential: keep list alive while iterator exists */
370  );
371 }
372 
373 template <typename Vector, typename Class_>
374 auto vector_if_insertion_operator(Class_ &cl, std::string const &name)
375  -> decltype(std::declval<std::ostream &>() << std::declval<typename Vector::value_type>(),
376  void()) {
377  using size_type = typename Vector::size_type;
378 
379  cl.def(
380  "__repr__",
381  [name](Vector &v) {
382  std::ostringstream s;
383  s << name << '[';
384  for (size_type i = 0; i < v.size(); ++i) {
385  s << v[i];
386  if (i != v.size() - 1) {
387  s << ", ";
388  }
389  }
390  s << ']';
391  return s.str();
392  },
393  "Return the canonical string representation of this list.");
394 }
395 
396 // Provide the buffer interface for vectors if we have data() and we have a format for it
397 // GCC seems to have "void std::vector<bool>::data()" - doing SFINAE on the existence of data()
398 // is insufficient, we need to check it returns an appropriate pointer
399 template <typename Vector, typename = void>
400 struct vector_has_data_and_format : std::false_type {};
401 template <typename Vector>
403  Vector,
404  enable_if_t<std::is_same<decltype(format_descriptor<typename Vector::value_type>::format(),
405  std::declval<Vector>().data()),
406  typename Vector::value_type *>::value>> : std::true_type {};
407 
408 // [workaround(intel)] Separate function required here
409 // Workaround as the Intel compiler does not compile the enable_if_t part below
410 // (tested with icc (ICC) 2021.1 Beta 20200827)
411 template <typename... Args>
412 constexpr bool args_any_are_buffer() {
413  return detail::any_of<std::is_same<Args, buffer_protocol>...>::value;
414 }
415 
416 // [workaround(intel)] Separate function required here
417 // [workaround(msvc)] Can't use constexpr bool in return type
418 
419 // Add the buffer interface to a vector
420 template <typename Vector, typename Class_, typename... Args>
421 void vector_buffer_impl(Class_ &cl, std::true_type) {
422  using T = typename Vector::value_type;
423 
425  "There is not an appropriate format descriptor for this vector");
426 
427  // numpy.h declares this for arbitrary types, but it may raise an exception and crash hard
428  // at runtime if PYBIND11_NUMPY_DTYPE hasn't been called, so check here
430 
431  cl.def_buffer([](Vector &v) -> buffer_info {
432  return buffer_info(v.data(),
433  static_cast<ssize_t>(sizeof(T)),
435  1,
436  {v.size()},
437  {sizeof(T)});
438  });
439 
440  cl.def(init([](const buffer &buf) {
441  auto info = buf.request();
442  if (info.ndim != 1 || info.strides[0] % static_cast<ssize_t>(sizeof(T))) {
443  throw type_error("Only valid 1D buffers can be copied to a vector");
444  }
446  || (ssize_t) sizeof(T) != info.itemsize) {
447  throw type_error("Format mismatch (Python: " + info.format
448  + " C++: " + format_descriptor<T>::format() + ")");
449  }
450 
451  T *p = static_cast<T *>(info.ptr);
452  ssize_t step = info.strides[0] / static_cast<ssize_t>(sizeof(T));
453  T *end = p + info.shape[0] * step;
454  if (step == 1) {
455  return Vector(p, end);
456  }
457  Vector vec;
458  vec.reserve((size_t) info.shape[0]);
459  for (; p != end; p += step) {
460  vec.push_back(*p);
461  }
462  return vec;
463  }));
464 
465  return;
466 }
467 
468 template <typename Vector, typename Class_, typename... Args>
469 void vector_buffer_impl(Class_ &, std::false_type) {}
470 
471 template <typename Vector, typename Class_, typename... Args>
472 void vector_buffer(Class_ &cl) {
473  vector_buffer_impl<Vector, Class_, Args...>(
474  cl, detail::any_of<std::is_same<Args, buffer_protocol>...>{});
475 }
476 
478 
479 //
480 // std::vector
481 //
482 template <typename Vector, typename holder_type = std::unique_ptr<Vector>, typename... Args>
483 class_<Vector, holder_type> bind_vector(handle scope, std::string const &name, Args &&...args) {
484  using Class_ = class_<Vector, holder_type>;
485 
486  // If the value_type is unregistered (e.g. a converting type) or is itself registered
487  // module-local then make the vector binding module-local as well:
488  using vtype = typename Vector::value_type;
489  auto *vtype_info = detail::get_type_info(typeid(vtype));
490  bool local = !vtype_info || vtype_info->module_local;
491 
492  Class_ cl(scope, name.c_str(), pybind11::module_local(local), std::forward<Args>(args)...);
493 
494  // Declare the buffer interface if a buffer_protocol() is passed in
495  detail::vector_buffer<Vector, Class_, Args...>(cl);
496 
497  cl.def(init<>());
498 
499  // Register copy constructor (if possible)
500  detail::vector_if_copy_constructible<Vector, Class_>(cl);
501 
502  // Register comparison-related operators and functions (if possible)
503  detail::vector_if_equal_operator<Vector, Class_>(cl);
504 
505  // Register stream insertion operator (if possible)
506  detail::vector_if_insertion_operator<Vector, Class_>(cl, name);
507 
508  // Modifiers require copyable vector value type
509  detail::vector_modifiers<Vector, Class_>(cl);
510 
511  // Accessor and iterator; return by value if copyable, otherwise we return by ref + keep-alive
512  detail::vector_accessor<Vector, Class_>(cl);
513 
514  cl.def(
515  "__bool__",
516  [](const Vector &v) -> bool { return !v.empty(); },
517  "Check whether the list is nonempty");
518 
519  cl.def("__len__", &Vector::size);
520 
521 #if 0
522  // C++ style functions deprecated, leaving it here as an example
523  cl.def(init<size_type>());
524 
525  cl.def("resize",
526  (void (Vector::*) (size_type count)) & Vector::resize,
527  "changes the number of elements stored");
528 
529  cl.def("erase",
530  [](Vector &v, SizeType i) {
531  if (i >= v.size())
532  throw index_error();
533  v.erase(v.begin() + i);
534  }, "erases element at index ``i``");
535 
536  cl.def("empty", &Vector::empty, "checks whether the container is empty");
537  cl.def("size", &Vector::size, "returns the number of elements");
538  cl.def("push_back", (void (Vector::*)(const T&)) &Vector::push_back, "adds an element to the end");
539  cl.def("pop_back", &Vector::pop_back, "removes the last element");
540 
541  cl.def("max_size", &Vector::max_size, "returns the maximum possible number of elements");
542  cl.def("reserve", &Vector::reserve, "reserves storage");
543  cl.def("capacity", &Vector::capacity, "returns the number of elements that can be held in currently allocated storage");
544  cl.def("shrink_to_fit", &Vector::shrink_to_fit, "reduces memory usage by freeing unused memory");
545 
546  cl.def("clear", &Vector::clear, "clears the contents");
547  cl.def("swap", &Vector::swap, "swaps the contents");
548 
549  cl.def("front", [](Vector &v) {
550  if (v.size()) return v.front();
551  else throw index_error();
552  }, "access the first element");
553 
554  cl.def("back", [](Vector &v) {
555  if (v.size()) return v.back();
556  else throw index_error();
557  }, "access the last element ");
558 
559 #endif
560 
561  return cl;
562 }
563 
564 //
565 // std::map, std::unordered_map
566 //
567 
569 
570 /* Fallback functions */
571 template <typename, typename, typename... Args>
572 void map_if_insertion_operator(const Args &...) {}
573 template <typename, typename, typename... Args>
574 void map_assignment(const Args &...) {}
575 
576 // Map assignment when copy-assignable: just copy the value
577 template <typename Map, typename Class_>
580  using KeyType = typename Map::key_type;
581  using MappedType = typename Map::mapped_type;
582 
583  cl.def("__setitem__", [](Map &m, const KeyType &k, const MappedType &v) {
584  auto it = m.find(k);
585  if (it != m.end()) {
586  it->second = v;
587  } else {
588  m.emplace(k, v);
589  }
590  });
591 }
592 
593 // Not copy-assignable, but still copy-constructible: we can update the value by erasing and
594 // reinserting
595 template <typename Map, typename Class_>
598  Class_> &cl) {
599  using KeyType = typename Map::key_type;
600  using MappedType = typename Map::mapped_type;
601 
602  cl.def("__setitem__", [](Map &m, const KeyType &k, const MappedType &v) {
603  // We can't use m[k] = v; because value type might not be default constructable
604  auto r = m.emplace(k, v);
605  if (!r.second) {
606  // value type is not copy assignable so the only way to insert it is to erase it
607  // first...
608  m.erase(r.first);
609  m.emplace(k, v);
610  }
611  });
612 }
613 
614 template <typename Map, typename Class_>
615 auto map_if_insertion_operator(Class_ &cl, std::string const &name)
616  -> decltype(std::declval<std::ostream &>() << std::declval<typename Map::key_type>()
617  << std::declval<typename Map::mapped_type>(),
618  void()) {
619 
620  cl.def(
621  "__repr__",
622  [name](Map &m) {
623  std::ostringstream s;
624  s << name << '{';
625  bool f = false;
626  for (auto const &kv : m) {
627  if (f) {
628  s << ", ";
629  }
630  s << kv.first << ": " << kv.second;
631  f = true;
632  }
633  s << '}';
634  return s.str();
635  },
636  "Return the canonical string representation of this map.");
637 }
638 
639 template <typename Map>
640 struct keys_view {
641  Map &map;
642 };
643 
644 template <typename Map>
645 struct values_view {
646  Map &map;
647 };
648 
649 template <typename Map>
650 struct items_view {
651  Map &map;
652 };
653 
655 
656 template <typename Map, typename holder_type = std::unique_ptr<Map>, typename... Args>
657 class_<Map, holder_type> bind_map(handle scope, const std::string &name, Args &&...args) {
658  using KeyType = typename Map::key_type;
659  using MappedType = typename Map::mapped_type;
660  using KeysView = detail::keys_view<Map>;
661  using ValuesView = detail::values_view<Map>;
662  using ItemsView = detail::items_view<Map>;
663  using Class_ = class_<Map, holder_type>;
664 
665  // If either type is a non-module-local bound type then make the map binding non-local as well;
666  // otherwise (e.g. both types are either module-local or converting) the map will be
667  // module-local.
668  auto *tinfo = detail::get_type_info(typeid(MappedType));
669  bool local = !tinfo || tinfo->module_local;
670  if (local) {
671  tinfo = detail::get_type_info(typeid(KeyType));
672  local = !tinfo || tinfo->module_local;
673  }
674 
675  Class_ cl(scope, name.c_str(), pybind11::module_local(local), std::forward<Args>(args)...);
677  scope, ("KeysView[" + name + "]").c_str(), pybind11::module_local(local));
679  scope, ("ValuesView[" + name + "]").c_str(), pybind11::module_local(local));
681  scope, ("ItemsView[" + name + "]").c_str(), pybind11::module_local(local));
682 
683  cl.def(init<>());
684 
685  // Register stream insertion operator (if possible)
686  detail::map_if_insertion_operator<Map, Class_>(cl, name);
687 
688  cl.def(
689  "__bool__",
690  [](const Map &m) -> bool { return !m.empty(); },
691  "Check whether the map is nonempty");
692 
693  cl.def(
694  "__iter__",
695  [](Map &m) { return make_key_iterator(m.begin(), m.end()); },
696  keep_alive<0, 1>() /* Essential: keep map alive while iterator exists */
697  );
698 
699  cl.def(
700  "keys",
701  [](Map &m) { return KeysView{m}; },
702  keep_alive<0, 1>() /* Essential: keep map alive while view exists */
703  );
704 
705  cl.def(
706  "values",
707  [](Map &m) { return ValuesView{m}; },
708  keep_alive<0, 1>() /* Essential: keep map alive while view exists */
709  );
710 
711  cl.def(
712  "items",
713  [](Map &m) { return ItemsView{m}; },
714  keep_alive<0, 1>() /* Essential: keep map alive while view exists */
715  );
716 
717  cl.def(
718  "__getitem__",
719  [](Map &m, const KeyType &k) -> MappedType & {
720  auto it = m.find(k);
721  if (it == m.end()) {
722  throw key_error();
723  }
724  return it->second;
725  },
726  return_value_policy::reference_internal // ref + keepalive
727  );
728 
729  cl.def("__contains__", [](Map &m, const KeyType &k) -> bool {
730  auto it = m.find(k);
731  if (it == m.end()) {
732  return false;
733  }
734  return true;
735  });
736  // Fallback for when the object is not of the key type
737  cl.def("__contains__", [](Map &, const object &) -> bool { return false; });
738 
739  // Assignment provided only if the type is copyable
740  detail::map_assignment<Map, Class_>(cl);
741 
742  cl.def("__delitem__", [](Map &m, const KeyType &k) {
743  auto it = m.find(k);
744  if (it == m.end()) {
745  throw key_error();
746  }
747  m.erase(it);
748  });
749 
750  cl.def("__len__", &Map::size);
751 
752  keys_view.def("__len__", [](KeysView &view) { return view.map.size(); });
753  keys_view.def(
754  "__iter__",
755  [](KeysView &view) { return make_key_iterator(view.map.begin(), view.map.end()); },
756  keep_alive<0, 1>() /* Essential: keep view alive while iterator exists */
757  );
758  keys_view.def("__contains__", [](KeysView &view, const KeyType &k) -> bool {
759  auto it = view.map.find(k);
760  if (it == view.map.end()) {
761  return false;
762  }
763  return true;
764  });
765  // Fallback for when the object is not of the key type
766  keys_view.def("__contains__", [](KeysView &, const object &) -> bool { return false; });
767 
768  values_view.def("__len__", [](ValuesView &view) { return view.map.size(); });
769  values_view.def(
770  "__iter__",
771  [](ValuesView &view) { return make_value_iterator(view.map.begin(), view.map.end()); },
772  keep_alive<0, 1>() /* Essential: keep view alive while iterator exists */
773  );
774 
775  items_view.def("__len__", [](ItemsView &view) { return view.map.size(); });
776  items_view.def(
777  "__iter__",
778  [](ItemsView &view) { return make_iterator(view.map.begin(), view.map.end()); },
779  keep_alive<0, 1>() /* Essential: keep view alive while iterator exists */
780  );
781 
782  return cl;
783 }
784 
PYBIND11_NOINLINE detail::type_info * get_type_info(PyTypeObject *type)
Matrix3f m
def step(data, isam, result, truth, currPoseIndex)
Definition: visual_isam.py:82
Annotation for parent scope.
Definition: attr.h:36
bool compare
static constexpr const bool is_element
Definition: stl_bind.h:44
Keep patient alive while nurse lives.
Definition: attr.h:70
void vector_modifiers(const Args &...)
Definition: stl_bind.h:80
Map & map
Definition: stl_bind.h:651
Definition: pytypes.h:2012
int n
void vector_if_copy_constructible(const Args &...)
Definition: stl_bind.h:74
constexpr bool args_any_are_buffer()
Definition: stl_bind.h:412
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 y set format x g set format y g set format x2 g set format y2 g set format z g set angles radians set nogrid set key title set key left top Right noreverse box linetype linewidth samplen spacing width set nolabel set noarrow set nologscale set logscale x set set pointsize set encoding default set nopolar set noparametric set view
buffer_info request(bool writable=false) const
Definition: pytypes.h:2072
class_ & def(const char *name_, Func &&f, const Extra &...extra)
Definition: pybind11.h:1557
Map & map
Definition: stl_bind.h:646
Definition: BFloat16.h:88
void vector_buffer(Class_ &cl)
Definition: stl_bind.h:472
void vector_if_equal_operator(const Args &...)
Definition: stl_bind.h:76
const char * c_str(Args &&...args)
Definition: internals.h:524
else if n * info
Scalar Scalar int size
Definition: benchVecAdd.cpp:17
int EIGEN_BLAS_FUNC() swap(int *n, RealScalar *px, int *incx, RealScalar *py, int *incy)
Definition: level1_impl.h:130
void vector_if_insertion_operator(const Args &...)
Definition: stl_bind.h:78
class_< Map, holder_type > bind_map(handle scope, const std::string &name, Args &&...args)
Definition: stl_bind.h:657
Map & map
Definition: stl_bind.h:641
bool compute(size_t length, size_t *start, size_t *stop, size_t *step, size_t *slicelength) const
Definition: pytypes.h:1756
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const ArgReturnType arg() const
Array< int, Dynamic, 1 > v
Eigen::Triplet< double > T
Point2(* f)(const Point3 &, OptionalJacobian< 2, 3 >)
void map_if_insertion_operator(const Args &...)
Definition: stl_bind.h:572
RealScalar s
static constexpr const bool is_vector
Definition: stl_bind.h:43
internal::enable_if<!(symbolic::is_symbolic< FirstType >::value||symbolic::is_symbolic< LastType >::value), ArithmeticSequence< typename internal::cleanup_index_type< FirstType >::type, Index > >::type seq(FirstType f, LastType l)
const double h
void map_assignment(const Args &...)
Definition: stl_bind.h:574
class_< Vector, holder_type > bind_vector(handle scope, std::string const &name, Args &&...args)
Definition: stl_bind.h:483
void vector_buffer_impl(Class_ &cl, std::true_type)
Definition: stl_bind.h:421
detail::initimpl::constructor< Args... > init()
Binds an existing constructor taking arguments Args...
Definition: pybind11.h:1882
static EIGEN_DEPRECATED const end_t end
std::string format(const std::string &str, const std::vector< std::string > &find, const std::vector< std::string > &replace)
static std::true_type test_comparable(decltype(std::declval< const T2 &>()==std::declval< const T2 &>()) *)
float * p
size_t len_hint(handle h)
Definition: pytypes.h:2254
void vector_accessor(enable_if_t<!vector_needs_copy< Vector >::value, Class_ > &cl)
Definition: stl_bind.h:312
iterator make_key_iterator(Iterator &&first, Sentinel &&last, Extra &&...extra)
Definition: pybind11.h:2391
typename std::enable_if< B, T >::type enable_if_t
from cpp_future import (convenient aliases from C++14/17)
iterator make_iterator(Iterator &&first, Sentinel &&last, Extra &&...extra)
Makes a python iterator from a first and past-the-end C++ InputIterator.
Definition: pybind11.h:2373
iterator make_value_iterator(Iterator &&first, Sentinel &&last, Extra &&...extra)
Definition: pybind11.h:2409
Annotation for function names.
Definition: attr.h:48
Information record describing a Python buffer object.
Definition: buffer_info.h:43
static std::true_type test_value(typename T2::value_type *)
static constexpr const bool is_pair
Definition: stl_bind.h:41
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
v resize(3)
Eigen::Matrix< double, Eigen::Dynamic, 1 > Vector
static std::true_type test_pair(typename T2::first_type *, typename T2::second_type *)
#define PYBIND11_NAMESPACE_END(name)
Point2 t(10, 10)
#define PYBIND11_NAMESPACE_BEGIN(name)


gtsam
Author(s):
autogenerated on Tue Jul 4 2023 02:36:20