14#include <lagrange/python/binding.h>
18NAMESPACE_BEGIN(NB_NAMESPACE)
20template <
typename Vector, rv_policy Policy = rv_policy::automatic_reference,
typename...
Args>
21class_<Vector> bind_safe_vector(handle scope,
const char* name,
Args&&... args)
23 using ValueRef =
typename detail::iterator_access<typename Vector::iterator>::result_type;
24 using Value = std::decay_t<ValueRef>;
25 using ValueType =
typename Value::element_type;
28 std::is_same_v<std::shared_ptr<ValueType>,
Value>,
29 "bind_safe_vector(): Value type must be a std::shared_ptr<>");
32 !detail::is_base_caster_v<detail::make_caster<Value>> ||
33 detail::is_copy_constructible_v<Value> ||
34 (Policy != rv_policy::automatic_reference && Policy != rv_policy::copy),
35 "bind_safe_vector(): the generated __getitem__ would copy elements, so the "
36 "element type must be copy-constructible");
38 handle cl_cur = type<Vector>();
39 if (cl_cur.is_valid()) {
41 return borrow<class_<Vector>>(cl_cur);
44 auto cl = class_<Vector>(scope, name, std::forward<Args>(args)...)
45 .def(init<>(),
"Default constructor")
47 .def(
"__len__", [](
const Vector& v) {
return v.size(); })
51 [](
const Vector& v) {
return !v.empty(); },
52 "Check whether the vector is nonempty")
56 [](handle_t<Vector> h) {
return steal<str>(detail::repr_list(h.ptr())); })
61 return make_iterator<Policy>(
64 v.Vector::Super::begin(),
65 v.Vector::Super::end());
71 [](Vector& v, Py_ssize_t i) -> ValueRef {
72 return v.Vector::Super::operator[](detail::wrap(i, v.size()));
76 .def(
"clear", [](Vector& v) { v.clear(); },
"Remove all items from list.");
78 if constexpr (detail::is_copy_constructible_v<Value>) {
79 cl.def(init<const Vector&>(),
"Copy constructor");
83 [](Vector* v, typed<iterable, Value> seq) {
85 v->reserve(len_hint(seq));
86 for (handle h : seq) v->Vector::Super::push_back(cast<Value>(h));
88 "Construct from an iterable object");
90 implicitly_convertible<iterable, Vector>();
94 [](Vector& v,
const Value& value) { v.Vector::Super::push_back(value); },
95 "Append `arg` to the end of the list.")
99 [](Vector& v, Py_ssize_t i,
const Value& x) {
100 if (i < 0) i += (Py_ssize_t)v.size();
101 if (i < 0 || (
size_t)i > v.size())
throw index_error();
102 v.insert(v.Vector::Super::begin() + i, x);
104 "Insert object `arg1` before index `arg0`.")
108 [](Vector& v, Py_ssize_t i) {
109 size_t index = detail::wrap(i, v.size());
110 Value result = std::move(v.Vector::Super::operator[](index));
111 v.erase(v.Vector::Super::begin() + index);
115 "Remove and return item at `index` (default last).")
119 [](Vector& v,
const Vector& src) {
121 v.Vector::Super::end(),
122 src.Vector::Super::begin(),
123 src.Vector::Super::end());
125 "Extend `self` by appending elements from `arg`.")
129 [](Vector& v, Py_ssize_t i,
const Value& value) {
130 v.Vector::Super::operator[](detail::wrap(i, v.size())) = value;
135 [](Vector& v, Py_ssize_t i) {
136 v.erase(v.Vector::Super::begin() + detail::wrap(i, v.size()));
141 [](
const Vector& v,
const slice& slice) -> Vector* {
142 auto [start, stop, step, length] = slice.compute(v.size());
144 seq->reserve(length);
146 for (
size_t i = 0; i < length; ++i) {
147 seq->Vector::Super::push_back(v.Vector::Super::operator[](start));
156 [](Vector& v,
const slice& slice,
const Vector& value) {
157 auto [start, stop, step, length] = slice.compute(v.size());
159 if (length != value.size())
161 "The left and right hand side of the slice "
162 "assignment have mismatched sizes!");
164 for (
size_t i = 0; i < length; ++i) {
165 v.Vector::Super::operator[](start) = value.Vector::Super::operator[](i);
170 .def(
"__delitem__", [](Vector& v,
const slice& slice) {
171 auto [start, stop, step, length] = slice.compute(v.size());
172 if (length == 0)
return;
174 stop = start + (length - 1) * step;
176 std::swap(start, stop);
181 v.erase(v.Vector::Super::begin() + start, v.Vector::Super::begin() + stop + 1);
183 for (
size_t i = 0; i < length; ++i) {
184 v.erase(v.Vector::Super::begin() + stop);
191 if constexpr (detail::is_equality_comparable_v<Value>) {
192 cl.def(self == self, sig(
"def __eq__(self, arg: object, /) -> bool"))
193 .def(self != self, sig(
"def __ne__(self, arg: object, /) -> bool"))
197 [](
const Vector& v,
const Value& x) {
198 return std::find(v.Vector::Super::begin(), v.Vector::Super::end(), x) !=
199 v.Vector::Super::end();
204 [](
const Vector&, handle) {
return false; })
208 [](
const Vector& v,
const Value& x) {
209 return std::count(v.Vector::Super::begin(), v.Vector::Super::end(), x);
211 "Return number of occurrences of `arg`.")
215 [](Vector& v,
const Value& x) {
216 auto p = std::find(v.Vector::Super::begin(), v.Vector::Super::end(), x);
217 if (p != v.Vector::Super::end())
222 "Remove first occurrence of `arg`.");
228NAMESPACE_END(NB_NAMESPACE)
@ Value
Values that are not attached to a specific element.
Definition AttributeFwd.h:42
Eigen::Matrix< Scalar, Eigen::Dynamic, 1 > Vector
Type alias for one-dimensional column Eigen vectors.
Definition views.h:79
Definition project.cpp:27