19 #include <type_traits>
27 template <
typename T2>
29 test_comparable(decltype(std::declval<const T2 &>() == std::declval<const T2 &>()) *);
30 template <
typename T2>
32 template <
typename T2>
33 static std::true_type
test_value(
typename T2::value_type *);
34 template <
typename T2>
36 template <
typename T2>
37 static std::true_type
test_pair(
typename T2::first_type *,
typename T2::second_type *);
38 template <
typename T2>
42 = std::is_same<std::true_type, decltype(test_comparable<T>(
nullptr))>::
value;
43 static constexpr
const bool is_pair
44 = std::is_same<std::true_type, decltype(test_pair<T>(
nullptr,
nullptr))>::
value;
46 = std::is_same<std::true_type, decltype(test_value<T>(
nullptr))>::
value;
51 template <
typename T,
typename SFINAE =
void>
65 :
is_comparable<typename recursive_container_traits<T>::type_to_check_recursively> {};
78 template <
typename,
typename,
typename... Args>
80 template <
typename,
typename,
typename... Args>
82 template <
typename,
typename,
typename... Args>
84 template <
typename,
typename,
typename... Args>
87 template <
typename Vector,
typename Class_>
92 template <
typename Vector,
typename Class_>
94 using T =
typename Vector::value_type;
101 [](
const Vector &
v,
const T &
x) {
return std::count(
v.begin(),
v.end(),
x); },
103 "Return the number of times ``x`` appears in the list");
108 auto p = std::find(
v.begin(),
v.end(),
x);
116 "Remove the first item from the list whose value is x. "
117 "It is an error if there is no such item.");
121 [](
const Vector &
v,
const T &
x) {
return std::find(
v.begin(),
v.end(),
x) !=
v.end(); },
123 "Return true the container contains ``x``");
129 template <
typename Vector,
typename Class_>
132 using T =
typename Vector::value_type;
133 using SizeType =
typename Vector::size_type;
134 using DiffType =
typename Vector::difference_type;
136 auto wrap_i = [](DiffType
i, SizeType
n) {
140 if (
i < 0 || (SizeType)
i >=
n) {
150 "Add an item to the end of the list");
153 auto v = std::unique_ptr<Vector>(
new Vector());
156 v->push_back(
h.cast<
T>());
162 "clear", [](
Vector &
v) {
v.clear(); },
"Clear the contents");
166 [](
Vector &
v,
const Vector &src) {
v.insert(
v.end(), src.begin(), src.end()); },
168 "Extend the list by appending all the items in the given list");
173 const size_t old_size =
v.size();
177 v.push_back(
h.cast<
T>());
179 }
catch (
const cast_error &) {
180 v.erase(
v.begin() +
static_cast<typename Vector::difference_type
>(old_size),
184 }
catch (
const std::exception &) {
191 "Extend the list by appending all the items in the given list");
200 if (
i < 0 || (SizeType)
i >
v.size()) {
203 v.insert(
v.begin() +
i,
x);
207 "Insert an item at a given position.");
215 T t = std::move(
v.back());
219 "Remove and return the last item");
224 i = wrap_i(
i,
v.size());
225 T t = std::move(
v[(SizeType)
i]);
226 v.erase(std::next(
v.begin(),
i));
230 "Remove and return the item at index ``i``");
232 cl.def(
"__setitem__", [wrap_i](
Vector &
v, DiffType
i,
const T &
t) {
233 i = wrap_i(
i,
v.size());
241 size_t start = 0, stop = 0,
step = 0, slicelength = 0;
248 seq->reserve((
size_t) slicelength);
250 for (
size_t i = 0;
i < slicelength; ++
i) {
251 seq->push_back(
v[start]);
257 "Retrieve list elements using a slice object");
262 size_t start = 0, stop = 0,
step = 0, slicelength = 0;
267 if (slicelength !=
value.size()) {
268 throw std::runtime_error(
269 "Left and right hand size of slice assignment have different sizes!");
272 for (
size_t i = 0;
i < slicelength; ++
i) {
277 "Assign list elements using a slice object");
282 i = wrap_i(
i,
v.size());
283 v.erase(
v.begin() +
i);
285 "Delete the list elements at index ``i``");
290 size_t start = 0, stop = 0,
step = 0, slicelength = 0;
296 if (
step == 1 &&
false) {
297 v.erase(
v.begin() + (DiffType) start,
v.begin() + DiffType(start + slicelength));
299 for (
size_t i = 0;
i < slicelength; ++
i) {
300 v.erase(
v.begin() + DiffType(start));
305 "Delete list elements using a slice object");
310 template <
typename Vector>
313 typename Vector::value_type &>>;
316 template <
typename Vector,
typename Class_>
318 using T =
typename Vector::value_type;
319 using SizeType =
typename Vector::size_type;
320 using DiffType =
typename Vector::difference_type;
321 using ItType =
typename Vector::iterator;
323 auto wrap_i = [](DiffType
i, SizeType
n) {
327 if (
i < 0 || (SizeType)
i >=
n) {
336 i = wrap_i(
i,
v.size());
337 return v[(SizeType)
i];
345 return make_iterator<return_value_policy::reference_internal, ItType, ItType, T &>(
353 template <
typename Vector,
typename Class_>
355 using T =
typename Vector::value_type;
356 using SizeType =
typename Vector::size_type;
357 using DiffType =
typename Vector::difference_type;
358 using ItType =
typename Vector::iterator;
359 cl.def(
"__getitem__", [](
const Vector &
v, DiffType
i) ->
T {
366 auto i_st =
static_cast<SizeType
>(
i);
367 if (i_st >=
v.size()) {
376 return make_iterator<return_value_policy::copy, ItType, ItType, T>(
v.begin(),
v.end());
382 template <
typename Vector,
typename Class_>
384 -> decltype(std::declval<std::ostream &>() << std::declval<typename Vector::value_type>(),
386 using size_type =
typename Vector::size_type;
391 std::ostringstream
s;
393 for (size_type
i = 0;
i <
v.size(); ++
i) {
395 if (
i !=
v.size() - 1) {
402 "Return the canonical string representation of this list.");
408 template <
typename Vector,
typename =
void>
410 template <
typename Vector>
413 enable_if_t<
std::is_same<decltype(format_descriptor<typename Vector::value_type>::format(),
414 std::declval<Vector>().data()),
415 typename Vector::value_type *>
::value>> : std::true_type {};
420 template <
typename... Args>
422 return detail::any_of<std::is_same<Args, buffer_protocol>...>
::value;
429 template <
typename Vector,
typename Class_,
typename... Args>
431 using T =
typename Vector::value_type;
434 "There is not an appropriate format descriptor for this vector");
452 throw type_error(
"Only valid 1D buffers can be copied to a vector");
456 throw type_error(
"Format mismatch (Python: " + info.format
457 +
" C++: " + format_descriptor<T>::format() +
")");
460 T *
p =
static_cast<T *
>(
info.ptr);
467 vec.reserve((
size_t)
info.shape[0]);
477 template <
typename Vector,
typename Class_,
typename... Args>
480 template <
typename Vector,
typename Class_,
typename... Args>
483 cl, detail::any_of<std::is_same<Args, buffer_protocol>...>{});
491 template <
typename Vector,
typename holder_type = std::unique_ptr<Vector>,
typename... Args>
497 using vtype =
typename Vector::value_type;
499 bool local = !vtype_info || vtype_info->module_local;
501 Class_
cl(
scope,
name.c_str(), pybind11::module_local(local), std::forward<Args>(
args)...);
509 detail::vector_if_copy_constructible<Vector, Class_>(
cl);
512 detail::vector_if_equal_operator<Vector, Class_>(
cl);
515 detail::vector_if_insertion_operator<Vector, Class_>(
cl,
name);
518 detail::vector_modifiers<Vector, Class_>(
cl);
521 detail::vector_accessor<Vector, Class_>(
cl);
525 [](
const Vector &
v) ->
bool {
return !
v.empty(); },
526 "Check whether the list is nonempty");
536 "changes the number of elements stored");
542 v.erase(
v.begin() +
i);
543 },
"erases element at index ``i``");
545 cl.def(
"empty", &Vector::empty,
"checks whether the container is empty");
547 cl.def(
"push_back", (
void (
Vector::*)(
const T&)) &Vector::push_back,
"adds an element to the end");
548 cl.def(
"pop_back", &Vector::pop_back,
"removes the last element");
550 cl.def(
"max_size", &Vector::max_size,
"returns the maximum possible number of elements");
551 cl.def(
"reserve", &Vector::reserve,
"reserves storage");
552 cl.def(
"capacity", &Vector::capacity,
"returns the number of elements that can be held in currently allocated storage");
553 cl.def(
"shrink_to_fit", &Vector::shrink_to_fit,
"reduces memory usage by freeing unused memory");
555 cl.def(
"clear", &Vector::clear,
"clears the contents");
559 if (
v.size())
return v.front();
560 else throw index_error();
561 },
"access the first element");
564 if (
v.size())
return v.back();
565 else throw index_error();
566 },
"access the last element ");
580 template <
typename,
typename,
typename... Args>
582 template <
typename,
typename,
typename... Args>
586 template <
typename Map,
typename Class_>
589 using KeyType =
typename Map::key_type;
590 using MappedType =
typename Map::mapped_type;
592 cl.def(
"__setitem__", [](Map &
m,
const KeyType &k,
const MappedType &
v) {
604 template <
typename Map,
typename Class_>
608 using KeyType =
typename Map::key_type;
609 using MappedType =
typename Map::mapped_type;
611 cl.def(
"__setitem__", [](Map &
m,
const KeyType &k,
const MappedType &
v) {
613 auto r =
m.emplace(k,
v);
623 template <
typename Map,
typename Class_>
625 -> decltype(std::declval<std::ostream &>() << std::declval<typename Map::key_type>()
626 << std::declval<typename Map::mapped_type>(),
632 std::ostringstream
s;
635 for (
auto const &kv :
m) {
639 s << kv.first <<
": " << kv.second;
645 "Return the canonical string representation of this map.");
648 template <
typename KeyType>
650 virtual size_t len() = 0;
652 virtual bool contains(
const KeyType &k) = 0;
653 virtual bool contains(
const object &k) = 0;
657 template <
typename MappedType>
659 virtual size_t len() = 0;
664 template <
typename KeyType,
typename MappedType>
666 virtual size_t len() = 0;
671 template <
typename Map,
typename KeysView>
674 size_t len()
override {
return map.size(); }
676 bool contains(
const typename Map::key_type &k)
override {
return map.find(k) !=
map.end(); }
677 bool contains(
const object &)
override {
return false; }
681 template <
typename Map,
typename ValuesView>
684 size_t len()
override {
return map.size(); }
689 template <
typename Map,
typename ItemsView>
692 size_t len()
override {
return map.size(); }
699 template <
typename Map,
typename holder_type = std::unique_ptr<Map>,
typename... Args>
701 using KeyType =
typename Map::key_type;
702 using MappedType =
typename Map::mapped_type;
703 using StrippedKeyType = detail::remove_cvref_t<KeyType>;
704 using StrippedMappedType = detail::remove_cvref_t<MappedType>;
705 using KeysView = detail::keys_view<StrippedKeyType>;
706 using ValuesView = detail::values_view<StrippedMappedType>;
707 using ItemsView = detail::items_view<StrippedKeyType, StrippedMappedType>;
714 bool local = !tinfo || tinfo->module_local;
717 local = !tinfo || tinfo->module_local;
720 Class_
cl(
scope,
name.c_str(), pybind11::module_local(local), std::forward<Args>(
args)...);
723 std::string key_type_name(key_type_descr.text), mapped_type_name(mapped_type_descr.text);
726 if (key_type_name ==
"%") {
730 if (mapped_type_name ==
"%") {
737 scope, (
"KeysView[" + key_type_name +
"]").
c_str(), pybind11::module_local(local));
744 static_cast<bool (KeysView::*)(
const KeyType &)
>(&KeysView::contains));
747 static_cast<bool (KeysView::*)(
const object &)
>(&KeysView::contains));
752 (
"ValuesView[" + mapped_type_name +
"]").
c_str(),
753 pybind11::module_local(local));
764 (
"ItemsView[" + key_type_name +
", ").append(mapped_type_name +
"]").
c_str(),
765 pybind11::module_local(local));
776 detail::map_if_insertion_operator<Map, Class_>(
cl,
name);
780 [](
const Map &
m) ->
bool {
return !
m.empty(); },
781 "Check whether the map is nonempty");
792 return std::unique_ptr<KeysView>(
new detail::KeysViewImpl<Map, KeysView>(
m));
800 return std::unique_ptr<ValuesView>(
new detail::ValuesViewImpl<Map, ValuesView>(
m));
808 return std::unique_ptr<ItemsView>(
new detail::ItemsViewImpl<Map, ItemsView>(
m));
815 [](Map &
m,
const KeyType &k) -> MappedType & {
825 cl.def(
"__contains__", [](Map &
m,
const KeyType &k) ->
bool {
833 cl.def(
"__contains__", [](Map &,
const object &) ->
bool {
return false; });
836 detail::map_assignment<Map, Class_>(
cl);
838 cl.def(
"__delitem__", [](Map &
m,
const KeyType &k) {