stl_bind.h 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785
  1. /*
  2. pybind11/std_bind.h: Binding generators for STL data types
  3. Copyright (c) 2016 Sergey Lyskov and Wenzel Jakob
  4. All rights reserved. Use of this source code is governed by a
  5. BSD-style license that can be found in the LICENSE file.
  6. */
  7. #pragma once
  8. #include "detail/common.h"
  9. #include "operators.h"
  10. #include <algorithm>
  11. #include <sstream>
  12. PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
  13. PYBIND11_NAMESPACE_BEGIN(detail)
  14. /* SFINAE helper class used by 'is_comparable */
  15. template <typename T>
  16. struct container_traits {
  17. template <typename T2>
  18. static std::true_type
  19. test_comparable(decltype(std::declval<const T2 &>() == std::declval<const T2 &>()) *);
  20. template <typename T2>
  21. static std::false_type test_comparable(...);
  22. template <typename T2>
  23. static std::true_type test_value(typename T2::value_type *);
  24. template <typename T2>
  25. static std::false_type test_value(...);
  26. template <typename T2>
  27. static std::true_type test_pair(typename T2::first_type *, typename T2::second_type *);
  28. template <typename T2>
  29. static std::false_type test_pair(...);
  30. static constexpr const bool is_comparable
  31. = std::is_same<std::true_type, decltype(test_comparable<T>(nullptr))>::value;
  32. static constexpr const bool is_pair
  33. = std::is_same<std::true_type, decltype(test_pair<T>(nullptr, nullptr))>::value;
  34. static constexpr const bool is_vector
  35. = std::is_same<std::true_type, decltype(test_value<T>(nullptr))>::value;
  36. static constexpr const bool is_element = !is_pair && !is_vector;
  37. };
  38. /* Default: is_comparable -> std::false_type */
  39. template <typename T, typename SFINAE = void>
  40. struct is_comparable : std::false_type {};
  41. /* For non-map data structures, check whether operator== can be instantiated */
  42. template <typename T>
  43. struct is_comparable<
  44. T,
  45. enable_if_t<container_traits<T>::is_element && container_traits<T>::is_comparable>>
  46. : std::true_type {};
  47. /* For a vector/map data structure, recursively check the value type
  48. (which is std::pair for maps) */
  49. template <typename T>
  50. struct is_comparable<T, enable_if_t<container_traits<T>::is_vector>> {
  51. static constexpr const bool value = is_comparable<typename T::value_type>::value;
  52. };
  53. /* For pairs, recursively check the two data types */
  54. template <typename T>
  55. struct is_comparable<T, enable_if_t<container_traits<T>::is_pair>> {
  56. static constexpr const bool value = is_comparable<typename T::first_type>::value
  57. && is_comparable<typename T::second_type>::value;
  58. };
  59. /* Fallback functions */
  60. template <typename, typename, typename... Args>
  61. void vector_if_copy_constructible(const Args &...) {}
  62. template <typename, typename, typename... Args>
  63. void vector_if_equal_operator(const Args &...) {}
  64. template <typename, typename, typename... Args>
  65. void vector_if_insertion_operator(const Args &...) {}
  66. template <typename, typename, typename... Args>
  67. void vector_modifiers(const Args &...) {}
  68. template <typename Vector, typename Class_>
  69. void vector_if_copy_constructible(enable_if_t<is_copy_constructible<Vector>::value, Class_> &cl) {
  70. cl.def(init<const Vector &>(), "Copy constructor");
  71. }
  72. template <typename Vector, typename Class_>
  73. void vector_if_equal_operator(enable_if_t<is_comparable<Vector>::value, Class_> &cl) {
  74. using T = typename Vector::value_type;
  75. cl.def(self == self);
  76. cl.def(self != self);
  77. cl.def(
  78. "count",
  79. [](const Vector &v, const T &x) { return std::count(v.begin(), v.end(), x); },
  80. arg("x"),
  81. "Return the number of times ``x`` appears in the list");
  82. cl.def(
  83. "remove",
  84. [](Vector &v, const T &x) {
  85. auto p = std::find(v.begin(), v.end(), x);
  86. if (p != v.end()) {
  87. v.erase(p);
  88. } else {
  89. throw value_error();
  90. }
  91. },
  92. arg("x"),
  93. "Remove the first item from the list whose value is x. "
  94. "It is an error if there is no such item.");
  95. cl.def(
  96. "__contains__",
  97. [](const Vector &v, const T &x) { return std::find(v.begin(), v.end(), x) != v.end(); },
  98. arg("x"),
  99. "Return true the container contains ``x``");
  100. }
  101. // Vector modifiers -- requires a copyable vector_type:
  102. // (Technically, some of these (pop and __delitem__) don't actually require copyability, but it
  103. // seems silly to allow deletion but not insertion, so include them here too.)
  104. template <typename Vector, typename Class_>
  105. void vector_modifiers(
  106. enable_if_t<is_copy_constructible<typename Vector::value_type>::value, Class_> &cl) {
  107. using T = typename Vector::value_type;
  108. using SizeType = typename Vector::size_type;
  109. using DiffType = typename Vector::difference_type;
  110. auto wrap_i = [](DiffType i, SizeType n) {
  111. if (i < 0) {
  112. i += n;
  113. }
  114. if (i < 0 || (SizeType) i >= n) {
  115. throw index_error();
  116. }
  117. return i;
  118. };
  119. cl.def(
  120. "append",
  121. [](Vector &v, const T &value) { v.push_back(value); },
  122. arg("x"),
  123. "Add an item to the end of the list");
  124. cl.def(init([](const iterable &it) {
  125. auto v = std::unique_ptr<Vector>(new Vector());
  126. v->reserve(len_hint(it));
  127. for (handle h : it) {
  128. v->push_back(h.cast<T>());
  129. }
  130. return v.release();
  131. }));
  132. cl.def(
  133. "clear", [](Vector &v) { v.clear(); }, "Clear the contents");
  134. cl.def(
  135. "extend",
  136. [](Vector &v, const Vector &src) { v.insert(v.end(), src.begin(), src.end()); },
  137. arg("L"),
  138. "Extend the list by appending all the items in the given list");
  139. cl.def(
  140. "extend",
  141. [](Vector &v, const iterable &it) {
  142. const size_t old_size = v.size();
  143. v.reserve(old_size + len_hint(it));
  144. try {
  145. for (handle h : it) {
  146. v.push_back(h.cast<T>());
  147. }
  148. } catch (const cast_error &) {
  149. v.erase(v.begin() + static_cast<typename Vector::difference_type>(old_size),
  150. v.end());
  151. try {
  152. v.shrink_to_fit();
  153. } catch (const std::exception &) {
  154. // Do nothing
  155. }
  156. throw;
  157. }
  158. },
  159. arg("L"),
  160. "Extend the list by appending all the items in the given list");
  161. cl.def(
  162. "insert",
  163. [](Vector &v, DiffType i, const T &x) {
  164. // Can't use wrap_i; i == v.size() is OK
  165. if (i < 0) {
  166. i += v.size();
  167. }
  168. if (i < 0 || (SizeType) i > v.size()) {
  169. throw index_error();
  170. }
  171. v.insert(v.begin() + i, x);
  172. },
  173. arg("i"),
  174. arg("x"),
  175. "Insert an item at a given position.");
  176. cl.def(
  177. "pop",
  178. [](Vector &v) {
  179. if (v.empty()) {
  180. throw index_error();
  181. }
  182. T t = std::move(v.back());
  183. v.pop_back();
  184. return t;
  185. },
  186. "Remove and return the last item");
  187. cl.def(
  188. "pop",
  189. [wrap_i](Vector &v, DiffType i) {
  190. i = wrap_i(i, v.size());
  191. T t = std::move(v[(SizeType) i]);
  192. v.erase(std::next(v.begin(), i));
  193. return t;
  194. },
  195. arg("i"),
  196. "Remove and return the item at index ``i``");
  197. cl.def("__setitem__", [wrap_i](Vector &v, DiffType i, const T &t) {
  198. i = wrap_i(i, v.size());
  199. v[(SizeType) i] = t;
  200. });
  201. /// Slicing protocol
  202. cl.def(
  203. "__getitem__",
  204. [](const Vector &v, const slice &slice) -> Vector * {
  205. size_t start = 0, stop = 0, step = 0, slicelength = 0;
  206. if (!slice.compute(v.size(), &start, &stop, &step, &slicelength)) {
  207. throw error_already_set();
  208. }
  209. auto *seq = new Vector();
  210. seq->reserve((size_t) slicelength);
  211. for (size_t i = 0; i < slicelength; ++i) {
  212. seq->push_back(v[start]);
  213. start += step;
  214. }
  215. return seq;
  216. },
  217. arg("s"),
  218. "Retrieve list elements using a slice object");
  219. cl.def(
  220. "__setitem__",
  221. [](Vector &v, const slice &slice, const Vector &value) {
  222. size_t start = 0, stop = 0, step = 0, slicelength = 0;
  223. if (!slice.compute(v.size(), &start, &stop, &step, &slicelength)) {
  224. throw error_already_set();
  225. }
  226. if (slicelength != value.size()) {
  227. throw std::runtime_error(
  228. "Left and right hand size of slice assignment have different sizes!");
  229. }
  230. for (size_t i = 0; i < slicelength; ++i) {
  231. v[start] = value[i];
  232. start += step;
  233. }
  234. },
  235. "Assign list elements using a slice object");
  236. cl.def(
  237. "__delitem__",
  238. [wrap_i](Vector &v, DiffType i) {
  239. i = wrap_i(i, v.size());
  240. v.erase(v.begin() + i);
  241. },
  242. "Delete the list elements at index ``i``");
  243. cl.def(
  244. "__delitem__",
  245. [](Vector &v, const slice &slice) {
  246. size_t start = 0, stop = 0, step = 0, slicelength = 0;
  247. if (!slice.compute(v.size(), &start, &stop, &step, &slicelength)) {
  248. throw error_already_set();
  249. }
  250. if (step == 1 && false) {
  251. v.erase(v.begin() + (DiffType) start, v.begin() + DiffType(start + slicelength));
  252. } else {
  253. for (size_t i = 0; i < slicelength; ++i) {
  254. v.erase(v.begin() + DiffType(start));
  255. start += step - 1;
  256. }
  257. }
  258. },
  259. "Delete list elements using a slice object");
  260. }
  261. // If the type has an operator[] that doesn't return a reference (most notably std::vector<bool>),
  262. // we have to access by copying; otherwise we return by reference.
  263. template <typename Vector>
  264. using vector_needs_copy
  265. = negation<std::is_same<decltype(std::declval<Vector>()[typename Vector::size_type()]),
  266. typename Vector::value_type &>>;
  267. // The usual case: access and iterate by reference
  268. template <typename Vector, typename Class_>
  269. void vector_accessor(enable_if_t<!vector_needs_copy<Vector>::value, Class_> &cl) {
  270. using T = typename Vector::value_type;
  271. using SizeType = typename Vector::size_type;
  272. using DiffType = typename Vector::difference_type;
  273. using ItType = typename Vector::iterator;
  274. auto wrap_i = [](DiffType i, SizeType n) {
  275. if (i < 0) {
  276. i += n;
  277. }
  278. if (i < 0 || (SizeType) i >= n) {
  279. throw index_error();
  280. }
  281. return i;
  282. };
  283. cl.def(
  284. "__getitem__",
  285. [wrap_i](Vector &v, DiffType i) -> T & {
  286. i = wrap_i(i, v.size());
  287. return v[(SizeType) i];
  288. },
  289. return_value_policy::reference_internal // ref + keepalive
  290. );
  291. cl.def(
  292. "__iter__",
  293. [](Vector &v) {
  294. return make_iterator<return_value_policy::reference_internal, ItType, ItType, T &>(
  295. v.begin(), v.end());
  296. },
  297. keep_alive<0, 1>() /* Essential: keep list alive while iterator exists */
  298. );
  299. }
  300. // The case for special objects, like std::vector<bool>, that have to be returned-by-copy:
  301. template <typename Vector, typename Class_>
  302. void vector_accessor(enable_if_t<vector_needs_copy<Vector>::value, Class_> &cl) {
  303. using T = typename Vector::value_type;
  304. using SizeType = typename Vector::size_type;
  305. using DiffType = typename Vector::difference_type;
  306. using ItType = typename Vector::iterator;
  307. cl.def("__getitem__", [](const Vector &v, DiffType i) -> T {
  308. if (i < 0 && (i += v.size()) < 0) {
  309. throw index_error();
  310. }
  311. if ((SizeType) i >= v.size()) {
  312. throw index_error();
  313. }
  314. return v[(SizeType) i];
  315. });
  316. cl.def(
  317. "__iter__",
  318. [](Vector &v) {
  319. return make_iterator<return_value_policy::copy, ItType, ItType, T>(v.begin(), v.end());
  320. },
  321. keep_alive<0, 1>() /* Essential: keep list alive while iterator exists */
  322. );
  323. }
  324. template <typename Vector, typename Class_>
  325. auto vector_if_insertion_operator(Class_ &cl, std::string const &name)
  326. -> decltype(std::declval<std::ostream &>() << std::declval<typename Vector::value_type>(),
  327. void()) {
  328. using size_type = typename Vector::size_type;
  329. cl.def(
  330. "__repr__",
  331. [name](Vector &v) {
  332. std::ostringstream s;
  333. s << name << '[';
  334. for (size_type i = 0; i < v.size(); ++i) {
  335. s << v[i];
  336. if (i != v.size() - 1) {
  337. s << ", ";
  338. }
  339. }
  340. s << ']';
  341. return s.str();
  342. },
  343. "Return the canonical string representation of this list.");
  344. }
  345. // Provide the buffer interface for vectors if we have data() and we have a format for it
  346. // GCC seems to have "void std::vector<bool>::data()" - doing SFINAE on the existence of data()
  347. // is insufficient, we need to check it returns an appropriate pointer
  348. template <typename Vector, typename = void>
  349. struct vector_has_data_and_format : std::false_type {};
  350. template <typename Vector>
  351. struct vector_has_data_and_format<
  352. Vector,
  353. enable_if_t<std::is_same<decltype(format_descriptor<typename Vector::value_type>::format(),
  354. std::declval<Vector>().data()),
  355. typename Vector::value_type *>::value>> : std::true_type {};
  356. // [workaround(intel)] Separate function required here
  357. // Workaround as the Intel compiler does not compile the enable_if_t part below
  358. // (tested with icc (ICC) 2021.1 Beta 20200827)
  359. template <typename... Args>
  360. constexpr bool args_any_are_buffer() {
  361. return detail::any_of<std::is_same<Args, buffer_protocol>...>::value;
  362. }
  363. // [workaround(intel)] Separate function required here
  364. // [workaround(msvc)] Can't use constexpr bool in return type
  365. // Add the buffer interface to a vector
  366. template <typename Vector, typename Class_, typename... Args>
  367. void vector_buffer_impl(Class_ &cl, std::true_type) {
  368. using T = typename Vector::value_type;
  369. static_assert(vector_has_data_and_format<Vector>::value,
  370. "There is not an appropriate format descriptor for this vector");
  371. // numpy.h declares this for arbitrary types, but it may raise an exception and crash hard
  372. // at runtime if PYBIND11_NUMPY_DTYPE hasn't been called, so check here
  373. format_descriptor<T>::format();
  374. cl.def_buffer([](Vector &v) -> buffer_info {
  375. return buffer_info(v.data(),
  376. static_cast<ssize_t>(sizeof(T)),
  377. format_descriptor<T>::format(),
  378. 1,
  379. {v.size()},
  380. {sizeof(T)});
  381. });
  382. cl.def(init([](const buffer &buf) {
  383. auto info = buf.request();
  384. if (info.ndim != 1 || info.strides[0] % static_cast<ssize_t>(sizeof(T))) {
  385. throw type_error("Only valid 1D buffers can be copied to a vector");
  386. }
  387. if (!detail::compare_buffer_info<T>::compare(info)
  388. || (ssize_t) sizeof(T) != info.itemsize) {
  389. throw type_error("Format mismatch (Python: " + info.format
  390. + " C++: " + format_descriptor<T>::format() + ")");
  391. }
  392. T *p = static_cast<T *>(info.ptr);
  393. ssize_t step = info.strides[0] / static_cast<ssize_t>(sizeof(T));
  394. T *end = p + info.shape[0] * step;
  395. if (step == 1) {
  396. return Vector(p, end);
  397. }
  398. Vector vec;
  399. vec.reserve((size_t) info.shape[0]);
  400. for (; p != end; p += step) {
  401. vec.push_back(*p);
  402. }
  403. return vec;
  404. }));
  405. return;
  406. }
  407. template <typename Vector, typename Class_, typename... Args>
  408. void vector_buffer_impl(Class_ &, std::false_type) {}
  409. template <typename Vector, typename Class_, typename... Args>
  410. void vector_buffer(Class_ &cl) {
  411. vector_buffer_impl<Vector, Class_, Args...>(
  412. cl, detail::any_of<std::is_same<Args, buffer_protocol>...>{});
  413. }
  414. PYBIND11_NAMESPACE_END(detail)
  415. //
  416. // std::vector
  417. //
  418. template <typename Vector, typename holder_type = std::unique_ptr<Vector>, typename... Args>
  419. class_<Vector, holder_type> bind_vector(handle scope, std::string const &name, Args &&...args) {
  420. using Class_ = class_<Vector, holder_type>;
  421. // If the value_type is unregistered (e.g. a converting type) or is itself registered
  422. // module-local then make the vector binding module-local as well:
  423. using vtype = typename Vector::value_type;
  424. auto *vtype_info = detail::get_type_info(typeid(vtype));
  425. bool local = !vtype_info || vtype_info->module_local;
  426. Class_ cl(scope, name.c_str(), pybind11::module_local(local), std::forward<Args>(args)...);
  427. // Declare the buffer interface if a buffer_protocol() is passed in
  428. detail::vector_buffer<Vector, Class_, Args...>(cl);
  429. cl.def(init<>());
  430. // Register copy constructor (if possible)
  431. detail::vector_if_copy_constructible<Vector, Class_>(cl);
  432. // Register comparison-related operators and functions (if possible)
  433. detail::vector_if_equal_operator<Vector, Class_>(cl);
  434. // Register stream insertion operator (if possible)
  435. detail::vector_if_insertion_operator<Vector, Class_>(cl, name);
  436. // Modifiers require copyable vector value type
  437. detail::vector_modifiers<Vector, Class_>(cl);
  438. // Accessor and iterator; return by value if copyable, otherwise we return by ref + keep-alive
  439. detail::vector_accessor<Vector, Class_>(cl);
  440. cl.def(
  441. "__bool__",
  442. [](const Vector &v) -> bool { return !v.empty(); },
  443. "Check whether the list is nonempty");
  444. cl.def("__len__", &Vector::size);
  445. #if 0
  446. // C++ style functions deprecated, leaving it here as an example
  447. cl.def(init<size_type>());
  448. cl.def("resize",
  449. (void (Vector::*) (size_type count)) & Vector::resize,
  450. "changes the number of elements stored");
  451. cl.def("erase",
  452. [](Vector &v, SizeType i) {
  453. if (i >= v.size())
  454. throw index_error();
  455. v.erase(v.begin() + i);
  456. }, "erases element at index ``i``");
  457. cl.def("empty", &Vector::empty, "checks whether the container is empty");
  458. cl.def("size", &Vector::size, "returns the number of elements");
  459. cl.def("push_back", (void (Vector::*)(const T&)) &Vector::push_back, "adds an element to the end");
  460. cl.def("pop_back", &Vector::pop_back, "removes the last element");
  461. cl.def("max_size", &Vector::max_size, "returns the maximum possible number of elements");
  462. cl.def("reserve", &Vector::reserve, "reserves storage");
  463. cl.def("capacity", &Vector::capacity, "returns the number of elements that can be held in currently allocated storage");
  464. cl.def("shrink_to_fit", &Vector::shrink_to_fit, "reduces memory usage by freeing unused memory");
  465. cl.def("clear", &Vector::clear, "clears the contents");
  466. cl.def("swap", &Vector::swap, "swaps the contents");
  467. cl.def("front", [](Vector &v) {
  468. if (v.size()) return v.front();
  469. else throw index_error();
  470. }, "access the first element");
  471. cl.def("back", [](Vector &v) {
  472. if (v.size()) return v.back();
  473. else throw index_error();
  474. }, "access the last element ");
  475. #endif
  476. return cl;
  477. }
  478. //
  479. // std::map, std::unordered_map
  480. //
  481. PYBIND11_NAMESPACE_BEGIN(detail)
  482. /* Fallback functions */
  483. template <typename, typename, typename... Args>
  484. void map_if_insertion_operator(const Args &...) {}
  485. template <typename, typename, typename... Args>
  486. void map_assignment(const Args &...) {}
  487. // Map assignment when copy-assignable: just copy the value
  488. template <typename Map, typename Class_>
  489. void map_assignment(
  490. enable_if_t<is_copy_assignable<typename Map::mapped_type>::value, Class_> &cl) {
  491. using KeyType = typename Map::key_type;
  492. using MappedType = typename Map::mapped_type;
  493. cl.def("__setitem__", [](Map &m, const KeyType &k, const MappedType &v) {
  494. auto it = m.find(k);
  495. if (it != m.end()) {
  496. it->second = v;
  497. } else {
  498. m.emplace(k, v);
  499. }
  500. });
  501. }
  502. // Not copy-assignable, but still copy-constructible: we can update the value by erasing and
  503. // reinserting
  504. template <typename Map, typename Class_>
  505. void map_assignment(enable_if_t<!is_copy_assignable<typename Map::mapped_type>::value
  506. && is_copy_constructible<typename Map::mapped_type>::value,
  507. Class_> &cl) {
  508. using KeyType = typename Map::key_type;
  509. using MappedType = typename Map::mapped_type;
  510. cl.def("__setitem__", [](Map &m, const KeyType &k, const MappedType &v) {
  511. // We can't use m[k] = v; because value type might not be default constructable
  512. auto r = m.emplace(k, v);
  513. if (!r.second) {
  514. // value type is not copy assignable so the only way to insert it is to erase it
  515. // first...
  516. m.erase(r.first);
  517. m.emplace(k, v);
  518. }
  519. });
  520. }
  521. template <typename Map, typename Class_>
  522. auto map_if_insertion_operator(Class_ &cl, std::string const &name)
  523. -> decltype(std::declval<std::ostream &>() << std::declval<typename Map::key_type>()
  524. << std::declval<typename Map::mapped_type>(),
  525. void()) {
  526. cl.def(
  527. "__repr__",
  528. [name](Map &m) {
  529. std::ostringstream s;
  530. s << name << '{';
  531. bool f = false;
  532. for (auto const &kv : m) {
  533. if (f) {
  534. s << ", ";
  535. }
  536. s << kv.first << ": " << kv.second;
  537. f = true;
  538. }
  539. s << '}';
  540. return s.str();
  541. },
  542. "Return the canonical string representation of this map.");
  543. }
  544. template <typename Map>
  545. struct keys_view {
  546. Map &map;
  547. };
  548. template <typename Map>
  549. struct values_view {
  550. Map &map;
  551. };
  552. template <typename Map>
  553. struct items_view {
  554. Map &map;
  555. };
  556. PYBIND11_NAMESPACE_END(detail)
  557. template <typename Map, typename holder_type = std::unique_ptr<Map>, typename... Args>
  558. class_<Map, holder_type> bind_map(handle scope, const std::string &name, Args &&...args) {
  559. using KeyType = typename Map::key_type;
  560. using MappedType = typename Map::mapped_type;
  561. using KeysView = detail::keys_view<Map>;
  562. using ValuesView = detail::values_view<Map>;
  563. using ItemsView = detail::items_view<Map>;
  564. using Class_ = class_<Map, holder_type>;
  565. // If either type is a non-module-local bound type then make the map binding non-local as well;
  566. // otherwise (e.g. both types are either module-local or converting) the map will be
  567. // module-local.
  568. auto *tinfo = detail::get_type_info(typeid(MappedType));
  569. bool local = !tinfo || tinfo->module_local;
  570. if (local) {
  571. tinfo = detail::get_type_info(typeid(KeyType));
  572. local = !tinfo || tinfo->module_local;
  573. }
  574. Class_ cl(scope, name.c_str(), pybind11::module_local(local), std::forward<Args>(args)...);
  575. class_<KeysView> keys_view(
  576. scope, ("KeysView[" + name + "]").c_str(), pybind11::module_local(local));
  577. class_<ValuesView> values_view(
  578. scope, ("ValuesView[" + name + "]").c_str(), pybind11::module_local(local));
  579. class_<ItemsView> items_view(
  580. scope, ("ItemsView[" + name + "]").c_str(), pybind11::module_local(local));
  581. cl.def(init<>());
  582. // Register stream insertion operator (if possible)
  583. detail::map_if_insertion_operator<Map, Class_>(cl, name);
  584. cl.def(
  585. "__bool__",
  586. [](const Map &m) -> bool { return !m.empty(); },
  587. "Check whether the map is nonempty");
  588. cl.def(
  589. "__iter__",
  590. [](Map &m) { return make_key_iterator(m.begin(), m.end()); },
  591. keep_alive<0, 1>() /* Essential: keep map alive while iterator exists */
  592. );
  593. cl.def(
  594. "keys",
  595. [](Map &m) { return KeysView{m}; },
  596. keep_alive<0, 1>() /* Essential: keep map alive while view exists */
  597. );
  598. cl.def(
  599. "values",
  600. [](Map &m) { return ValuesView{m}; },
  601. keep_alive<0, 1>() /* Essential: keep map alive while view exists */
  602. );
  603. cl.def(
  604. "items",
  605. [](Map &m) { return ItemsView{m}; },
  606. keep_alive<0, 1>() /* Essential: keep map alive while view exists */
  607. );
  608. cl.def(
  609. "__getitem__",
  610. [](Map &m, const KeyType &k) -> MappedType & {
  611. auto it = m.find(k);
  612. if (it == m.end()) {
  613. throw key_error();
  614. }
  615. return it->second;
  616. },
  617. return_value_policy::reference_internal // ref + keepalive
  618. );
  619. cl.def("__contains__", [](Map &m, const KeyType &k) -> bool {
  620. auto it = m.find(k);
  621. if (it == m.end()) {
  622. return false;
  623. }
  624. return true;
  625. });
  626. // Fallback for when the object is not of the key type
  627. cl.def("__contains__", [](Map &, const object &) -> bool { return false; });
  628. // Assignment provided only if the type is copyable
  629. detail::map_assignment<Map, Class_>(cl);
  630. cl.def("__delitem__", [](Map &m, const KeyType &k) {
  631. auto it = m.find(k);
  632. if (it == m.end()) {
  633. throw key_error();
  634. }
  635. m.erase(it);
  636. });
  637. cl.def("__len__", &Map::size);
  638. keys_view.def("__len__", [](KeysView &view) { return view.map.size(); });
  639. keys_view.def(
  640. "__iter__",
  641. [](KeysView &view) { return make_key_iterator(view.map.begin(), view.map.end()); },
  642. keep_alive<0, 1>() /* Essential: keep view alive while iterator exists */
  643. );
  644. keys_view.def("__contains__", [](KeysView &view, const KeyType &k) -> bool {
  645. auto it = view.map.find(k);
  646. if (it == view.map.end()) {
  647. return false;
  648. }
  649. return true;
  650. });
  651. // Fallback for when the object is not of the key type
  652. keys_view.def("__contains__", [](KeysView &, const object &) -> bool { return false; });
  653. values_view.def("__len__", [](ValuesView &view) { return view.map.size(); });
  654. values_view.def(
  655. "__iter__",
  656. [](ValuesView &view) { return make_value_iterator(view.map.begin(), view.map.end()); },
  657. keep_alive<0, 1>() /* Essential: keep view alive while iterator exists */
  658. );
  659. items_view.def("__len__", [](ItemsView &view) { return view.map.size(); });
  660. items_view.def(
  661. "__iter__",
  662. [](ItemsView &view) { return make_iterator(view.map.begin(), view.map.end()); },
  663. keep_alive<0, 1>() /* Essential: keep view alive while iterator exists */
  664. );
  665. return cl;
  666. }
  667. PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)