stl_bind.h 29 KB

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