12 #include "detail/common.h"
13 #include "operators.h"
18 PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
19 PYBIND11_NAMESPACE_BEGIN(detail)
23 template <
typename T2>
static std::true_type test_comparable(decltype(std::declval<const T2 &>() == std::declval<const T2 &>())*);
24 template <
typename T2>
static std::false_type test_comparable(...);
25 template <
typename T2>
static std::true_type test_value(
typename T2::value_type *);
26 template <
typename T2>
static std::false_type test_value(...);
27 template <
typename T2>
static std::true_type test_pair(
typename T2::first_type *,
typename T2::second_type *);
28 template <
typename T2>
static std::false_type test_pair(...);
30 static constexpr
const bool is_comparable = std::is_same<std::true_type, decltype(test_comparable<T>(
nullptr))>::value;
31 static constexpr
const bool is_pair = std::is_same<std::true_type, decltype(test_pair<T>(
nullptr,
nullptr))>::value;
32 static constexpr
const bool is_vector = std::is_same<std::true_type, decltype(test_value<T>(
nullptr))>::value;
33 static constexpr
const bool is_element = !is_pair && !is_vector;
37 template <
typename T,
typename SFINAE =
void>
50 static constexpr
const bool value =
57 static constexpr
const bool value =
63 template <
typename,
typename,
typename... Args>
void vector_if_copy_constructible(
const Args &...) { }
64 template <
typename,
typename,
typename... Args>
void vector_if_equal_operator(
const Args &...) { }
65 template <
typename,
typename,
typename... Args>
void vector_if_insertion_operator(
const Args &...) { }
66 template <
typename,
typename,
typename... Args>
void vector_modifiers(
const Args &...) { }
68 template<
typename Vector,
typename Class_>
70 cl.def(init<const Vector &>(),
"Copy constructor");
73 template<
typename Vector,
typename Class_>
75 using T =
typename Vector::value_type;
81 [](
const Vector &v,
const T &x) {
82 return std::count(v.begin(), v.end(), x);
85 "Return the number of times ``x`` appears in the list"
88 cl.def(
"remove", [](Vector &v,
const T &x) {
89 auto p = std::find(v.begin(), v.end(), x);
96 "Remove the first item from the list whose value is x. "
97 "It is an error if there is no such item."
100 cl.def(
"__contains__",
101 [](
const Vector &v,
const T &x) {
102 return std::find(v.begin(), v.end(), x) != v.end();
105 "Return true the container contains ``x``"
112 template <
typename Vector,
typename Class_>
114 using T =
typename Vector::value_type;
115 using SizeType =
typename Vector::size_type;
116 using DiffType =
typename Vector::difference_type;
118 auto wrap_i = [](DiffType i, SizeType n) {
121 if (i < 0 || (SizeType)i >= n)
127 [](Vector &v,
const T &value) { v.push_back(value); },
129 "Add an item to the end of the list");
132 auto v = std::unique_ptr<Vector>(
new Vector());
135 v->push_back(h.cast<T>());
147 [](Vector &v,
const Vector &src) {
148 v.insert(v.end(), src.begin(), src.end());
151 "Extend the list by appending all the items in the given list"
156 const size_t old_size = v.size();
160 v.push_back(h.cast<T>());
162 }
catch (
const cast_error &) {
163 v.erase(v.begin() +
static_cast<typename Vector::difference_type
>(old_size), v.end());
166 }
catch (
const std::exception &) {
173 "Extend the list by appending all the items in the given list"
177 [](Vector &v, DiffType i,
const T &x) {
181 if (i < 0 || (SizeType)i > v.size())
183 v.insert(v.begin() + i, x);
186 "Insert an item at a given position."
197 "Remove and return the last item"
201 [wrap_i](Vector &v, DiffType i) {
202 i = wrap_i(i, v.size());
203 T t = v[(SizeType) i];
204 v.erase(v.begin() + i);
208 "Remove and return the item at index ``i``"
211 cl.def(
"__setitem__",
212 [wrap_i](Vector &v, DiffType i,
const T &t) {
213 i = wrap_i(i, v.size());
219 cl.def(
"__getitem__",
220 [](
const Vector &v,
slice slice) -> Vector * {
221 size_t start, stop, step, slicelength;
223 if (!slice.compute(v.size(), &start, &stop, &step, &slicelength))
226 auto *seq =
new Vector();
227 seq->reserve((
size_t) slicelength);
229 for (
size_t i=0; i<slicelength; ++i) {
230 seq->push_back(v[start]);
236 "Retrieve list elements using a slice object"
239 cl.def(
"__setitem__",
240 [](Vector &v, slice slice,
const Vector &value) {
241 size_t start, stop, step, slicelength;
242 if (!slice.compute(v.size(), &start, &stop, &step, &slicelength))
245 if (slicelength != value.size())
246 throw std::runtime_error(
"Left and right hand size of slice assignment have different sizes!");
248 for (
size_t i=0; i<slicelength; ++i) {
253 "Assign list elements using a slice object"
256 cl.def(
"__delitem__",
257 [wrap_i](Vector &v, DiffType i) {
258 i = wrap_i(i, v.size());
259 v.erase(v.begin() + i);
261 "Delete the list elements at index ``i``"
264 cl.def(
"__delitem__",
265 [](Vector &v, slice slice) {
266 size_t start, stop, step, slicelength;
268 if (!slice.compute(v.size(), &start, &stop, &step, &slicelength))
271 if (step == 1 &&
false) {
272 v.erase(v.begin() + (DiffType) start, v.begin() + DiffType(start + slicelength));
274 for (
size_t i = 0; i < slicelength; ++i) {
275 v.erase(v.begin() + DiffType(start));
280 "Delete list elements using a slice object"
288 std::is_same<decltype(std::declval<Vector>()[
typename Vector::size_type()]),
typename Vector::value_type &>>;
291 template <
typename Vector,
typename Class_>
293 using T =
typename Vector::value_type;
294 using SizeType =
typename Vector::size_type;
295 using DiffType =
typename Vector::difference_type;
296 using ItType =
typename Vector::iterator;
298 auto wrap_i = [](DiffType i, SizeType n) {
301 if (i < 0 || (SizeType)i >= n)
306 cl.def(
"__getitem__",
307 [wrap_i](Vector &v, DiffType i) -> T & {
308 i = wrap_i(i, v.size());
309 return v[(SizeType)i];
311 return_value_policy::reference_internal
316 return make_iterator<
317 return_value_policy::reference_internal, ItType, ItType, T&>(
325 template <
typename Vector,
typename Class_>
327 using T =
typename Vector::value_type;
328 using SizeType =
typename Vector::size_type;
329 using DiffType =
typename Vector::difference_type;
330 using ItType =
typename Vector::iterator;
331 cl.def(
"__getitem__",
332 [](
const Vector &v, DiffType i) -> T {
333 if (i < 0 && (i += v.size()) < 0)
335 if ((SizeType)i >= v.size())
337 return v[(SizeType)i];
343 return make_iterator<
344 return_value_policy::copy, ItType, ItType, T>(
351 template <
typename Vector,
typename Class_>
auto vector_if_insertion_operator(Class_ &cl, std::string
const &
name)
352 -> decltype(std::declval<std::ostream&>() << std::declval<typename Vector::value_type>(),
void()) {
353 using size_type =
typename Vector::size_type;
357 std::ostringstream s;
359 for (size_type i=0; i < v.size(); ++i) {
361 if (i != v.size() - 1)
367 "Return the canonical string representation of this list."
373 template <
typename Vector,
typename =
void>
375 template <
typename Vector>
376 struct vector_has_data_and_format<Vector, enable_if_t<std::is_same<decltype(format_descriptor<typename Vector::value_type>::format(), std::declval<Vector>().data()), typename Vector::value_type*>::value>> : std::true_type {};
379 template <
typename Vector,
typename Class_,
typename... Args>
380 enable_if_t<detail::any_of<std::is_same<Args, buffer_protocol>...>::value>
381 vector_buffer(Class_& cl) {
382 using T =
typename Vector::value_type;
393 cl.def(init([](
buffer buf) {
394 auto info = buf.request();
395 if (info.ndim != 1 || info.strides[0] % static_cast<ssize_t>(
sizeof(T)))
396 throw type_error(
"Only valid 1D buffers can be copied to a vector");
397 if (!detail::compare_buffer_info<T>::compare(info) || (ssize_t)
sizeof(T) != info.itemsize)
400 T *p =
static_cast<T*
>(info.ptr);
401 ssize_t step = info.strides[0] /
static_cast<ssize_t
>(
sizeof(T));
402 T *end = p + info.shape[0] * step;
404 return Vector(p, end);
408 vec.reserve((
size_t) info.shape[0]);
409 for (; p != end; p += step)
418 template <
typename Vector,
typename Class_,
typename... Args>
419 enable_if_t<!detail::any_of<std::is_same<Args, buffer_protocol>...>::value> vector_buffer(Class_&) {}
421 PYBIND11_NAMESPACE_END(detail)
426 template <typename Vector, typename holder_type = std::unique_ptr<Vector>, typename... Args>
432 using vtype =
typename Vector::value_type;
433 auto vtype_info = detail::get_type_info(
typeid(vtype));
434 bool local = !vtype_info || vtype_info->module_local;
436 Class_ cl(scope, name.c_str(), pybind11::module_local(local), std::forward<Args>(args)...);
439 detail::vector_buffer<Vector, Class_, Args...>(cl);
444 detail::vector_if_copy_constructible<Vector, Class_>(cl);
447 detail::vector_if_equal_operator<Vector, Class_>(cl);
450 detail::vector_if_insertion_operator<Vector, Class_>(cl, name);
453 detail::vector_modifiers<Vector, Class_>(cl);
456 detail::vector_accessor<Vector, Class_>(cl);
459 [](
const Vector &v) ->
bool {
462 "Check whether the list is nonempty"
465 cl.def(
"__len__", &Vector::size);
472 cl.def(init<size_type>());
475 (
void (Vector::*) (size_type count)) & Vector::resize,
476 "changes the number of elements stored");
479 [](Vector &v, SizeType i) {
482 v.erase(v.begin() + i);
483 },
"erases element at index ``i``");
485 cl.def(
"empty", &Vector::empty,
"checks whether the container is empty");
486 cl.def(
"size", &Vector::size,
"returns the number of elements");
487 cl.def(
"push_back", (
void (Vector::*)(
const T&)) &Vector::push_back,
"adds an element to the end");
488 cl.def(
"pop_back", &Vector::pop_back,
"removes the last element");
490 cl.def(
"max_size", &Vector::max_size,
"returns the maximum possible number of elements");
491 cl.def(
"reserve", &Vector::reserve,
"reserves storage");
492 cl.def(
"capacity", &Vector::capacity,
"returns the number of elements that can be held in currently allocated storage");
493 cl.def(
"shrink_to_fit", &Vector::shrink_to_fit,
"reduces memory usage by freeing unused memory");
495 cl.def(
"clear", &Vector::clear,
"clears the contents");
496 cl.def(
"swap", &Vector::swap,
"swaps the contents");
498 cl.def(
"front", [](Vector &v) {
499 if (v.size())
return v.front();
500 else throw index_error();
501 },
"access the first element");
503 cl.def(
"back", [](Vector &v) {
504 if (v.size())
return v.back();
505 else throw index_error();
506 },
"access the last element ");
519 PYBIND11_NAMESPACE_BEGIN(detail)
522 template <typename, typename, typename... Args>
void map_if_insertion_operator(const Args &...) { }
523 template <
typename,
typename,
typename... Args>
void map_assignment(
const Args &...) { }
526 template <
typename Map,
typename Class_>
528 using KeyType =
typename Map::key_type;
529 using MappedType =
typename Map::mapped_type;
531 cl.def(
"__setitem__",
532 [](Map &m,
const KeyType &k,
const MappedType &v) {
534 if (it != m.end()) it->second = v;
535 else m.emplace(k, v);
541 template<
typename Map,
typename Class_>
542 void map_assignment(enable_if_t<
546 using KeyType =
typename Map::key_type;
547 using MappedType =
typename Map::mapped_type;
549 cl.def(
"__setitem__",
550 [](Map &m,
const KeyType &k,
const MappedType &v) {
552 auto r = m.emplace(k, v);
563 template <
typename Map,
typename Class_>
auto map_if_insertion_operator(Class_ &cl, std::string
const &name)
564 -> decltype(std::declval<std::ostream&>() << std::declval<typename Map::key_type>() << std::declval<typename Map::mapped_type>(),
void()) {
568 std::ostringstream s;
571 for (
auto const &kv : m) {
574 s << kv.first <<
": " << kv.second;
580 "Return the canonical string representation of this map."
585 PYBIND11_NAMESPACE_END(detail)
587 template <typename Map, typename holder_type = std::unique_ptr<Map>, typename... Args>
588 class_<Map, holder_type> bind_map(
handle scope, const std::
string &name, Args&&... args) {
589 using KeyType =
typename Map::key_type;
590 using MappedType =
typename Map::mapped_type;
596 auto tinfo = detail::get_type_info(
typeid(MappedType));
597 bool local = !tinfo || tinfo->module_local;
599 tinfo = detail::get_type_info(
typeid(KeyType));
600 local = !tinfo || tinfo->module_local;
603 Class_ cl(scope, name.c_str(), pybind11::module_local(local), std::forward<Args>(args)...);
608 detail::map_if_insertion_operator<Map, Class_>(cl, name);
611 [](
const Map &m) ->
bool {
return !m.empty(); },
612 "Check whether the map is nonempty"
616 [](Map &m) {
return make_key_iterator(m.begin(), m.end()); },
621 [](Map &m) {
return make_iterator(m.begin(), m.end()); },
625 cl.def(
"__getitem__",
626 [](Map &m,
const KeyType &k) -> MappedType & {
632 return_value_policy::reference_internal
635 cl.def(
"__contains__",
636 [](Map &m,
const KeyType &k) ->
bool {
645 detail::map_assignment<Map, Class_>(cl);
647 cl.def(
"__delitem__",
648 [](Map &m,
const KeyType &k) {
656 cl.def(
"__len__", &Map::size);
661 PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
Annotation for parent scope.
Keep patient alive while nurse lives.
size_t len_hint(handle h)
Annotation for function names.
Information record describing a Python buffer object.