stl.h
Go to the documentation of this file.
1 /*
2  pybind11/stl.h: Transparent conversion for STL data types
3 
4  Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
5 
6  All rights reserved. Use of this source code is governed by a
7  BSD-style license that can be found in the LICENSE file.
8 */
9 
10 #pragma once
11 
12 #include "pybind11.h"
13 #include "detail/common.h"
14 
15 #include <deque>
16 #include <list>
17 #include <map>
18 #include <ostream>
19 #include <set>
20 #include <unordered_map>
21 #include <unordered_set>
22 #include <valarray>
23 
24 // See `detail/common.h` for implementation of these guards.
25 #if defined(PYBIND11_HAS_OPTIONAL)
26 # include <optional>
27 #elif defined(PYBIND11_HAS_EXP_OPTIONAL)
28 # include <experimental/optional>
29 #endif
30 
31 #if defined(PYBIND11_HAS_VARIANT)
32 # include <variant>
33 #endif
34 
37 
38 template <typename T, typename U>
44 
47 template <typename T, typename U>
49  return std::forward<detail::forwarded_type<T, U>>(std::forward<U>(u));
50 }
51 
52 // Checks if a container has a STL style reserve method.
53 // This will only return true for a `reserve()` with a `void` return.
54 template <typename C>
55 using has_reserve_method = std::is_same<decltype(std::declval<C>().reserve(0)), void>;
56 
57 template <typename Type, typename Key>
58 struct set_caster {
59  using type = Type;
61 
62 private:
64  void reserve_maybe(const anyset &s, Type *) {
65  value.reserve(s.size());
66  }
67  void reserve_maybe(const anyset &, void *) {}
68 
69 public:
70  bool load(handle src, bool convert) {
71  if (!isinstance<anyset>(src)) {
72  return false;
73  }
74  auto s = reinterpret_borrow<anyset>(src);
75  value.clear();
77  for (auto entry : s) {
78  key_conv conv;
79  if (!conv.load(entry, convert)) {
80  return false;
81  }
82  value.insert(cast_op<Key &&>(std::move(conv)));
83  }
84  return true;
85  }
86 
87  template <typename T>
88  static handle cast(T &&src, return_value_policy policy, handle parent) {
91  }
93  for (auto &&value : src) {
94  auto value_ = reinterpret_steal<object>(
95  key_conv::cast(detail::forward_like<T>(value), policy, parent));
96  if (!value_ || !s.add(std::move(value_))) {
97  return handle();
98  }
99  }
100  return s.release();
101  }
102 
104 };
105 
106 template <typename Type, typename Key, typename Value>
107 struct map_caster {
110 
111 private:
113  void reserve_maybe(const dict &d, Type *) {
114  value.reserve(d.size());
115  }
116  void reserve_maybe(const dict &, void *) {}
117 
118 public:
119  bool load(handle src, bool convert) {
120  if (!isinstance<dict>(src)) {
121  return false;
122  }
123  auto d = reinterpret_borrow<dict>(src);
124  value.clear();
125  reserve_maybe(d, &value);
126  for (auto it : d) {
127  key_conv kconv;
128  value_conv vconv;
129  if (!kconv.load(it.first.ptr(), convert) || !vconv.load(it.second.ptr(), convert)) {
130  return false;
131  }
132  value.emplace(cast_op<Key &&>(std::move(kconv)), cast_op<Value &&>(std::move(vconv)));
133  }
134  return true;
135  }
136 
137  template <typename T>
138  static handle cast(T &&src, return_value_policy policy, handle parent) {
139  dict d;
140  return_value_policy policy_key = policy;
141  return_value_policy policy_value = policy;
143  policy_key = return_value_policy_override<Key>::policy(policy_key);
144  policy_value = return_value_policy_override<Value>::policy(policy_value);
145  }
146  for (auto &&kv : src) {
147  auto key = reinterpret_steal<object>(
148  key_conv::cast(detail::forward_like<T>(kv.first), policy_key, parent));
149  auto value = reinterpret_steal<object>(
150  value_conv::cast(detail::forward_like<T>(kv.second), policy_value, parent));
151  if (!key || !value) {
152  return handle();
153  }
154  d[std::move(key)] = std::move(value);
155  }
156  return d.release();
157  }
158 
161  + const_name("]"));
162 };
163 
164 template <typename Type, typename Value>
165 struct list_caster {
167 
168  bool load(handle src, bool convert) {
169  if (!isinstance<sequence>(src) || isinstance<bytes>(src) || isinstance<str>(src)) {
170  return false;
171  }
172  auto s = reinterpret_borrow<sequence>(src);
173  value.clear();
174  reserve_maybe(s, &value);
175  for (auto it : s) {
177  if (!conv.load(it, convert)) {
178  return false;
179  }
180  value.push_back(cast_op<Value &&>(std::move(conv)));
181  }
182  return true;
183  }
184 
185 private:
187  void reserve_maybe(const sequence &s, Type *) {
188  value.reserve(s.size());
189  }
190  void reserve_maybe(const sequence &, void *) {}
191 
192 public:
193  template <typename T>
194  static handle cast(T &&src, return_value_policy policy, handle parent) {
197  }
198  list l(src.size());
199  ssize_t index = 0;
200  for (auto &&value : src) {
201  auto value_ = reinterpret_steal<object>(
202  value_conv::cast(detail::forward_like<T>(value), policy, parent));
203  if (!value_) {
204  return handle();
205  }
206  PyList_SET_ITEM(l.ptr(), index++, value_.release().ptr()); // steals a reference
207  }
208  return l.release();
209  }
210 
212 };
213 
214 template <typename Type, typename Alloc>
215 struct type_caster<std::vector<Type, Alloc>> : list_caster<std::vector<Type, Alloc>, Type> {};
216 
217 template <typename Type, typename Alloc>
218 struct type_caster<std::deque<Type, Alloc>> : list_caster<std::deque<Type, Alloc>, Type> {};
219 
220 template <typename Type, typename Alloc>
221 struct type_caster<std::list<Type, Alloc>> : list_caster<std::list<Type, Alloc>, Type> {};
222 
223 template <typename ArrayType, typename Value, bool Resizable, size_t Size = 0>
224 struct array_caster {
226 
227 private:
228  template <bool R = Resizable>
230  if (value.size() != size) {
231  value.resize(size);
232  }
233  return true;
234  }
235  template <bool R = Resizable>
237  return size == Size;
238  }
239 
240 public:
241  bool load(handle src, bool convert) {
242  if (!isinstance<sequence>(src)) {
243  return false;
244  }
245  auto l = reinterpret_borrow<sequence>(src);
246  if (!require_size(l.size())) {
247  return false;
248  }
249  size_t ctr = 0;
250  for (auto it : l) {
252  if (!conv.load(it, convert)) {
253  return false;
254  }
255  value[ctr++] = cast_op<Value &&>(std::move(conv));
256  }
257  return true;
258  }
259 
260  template <typename T>
261  static handle cast(T &&src, return_value_policy policy, handle parent) {
262  list l(src.size());
263  ssize_t index = 0;
264  for (auto &&value : src) {
265  auto value_ = reinterpret_steal<object>(
266  value_conv::cast(detail::forward_like<T>(value), policy, parent));
267  if (!value_) {
268  return handle();
269  }
270  PyList_SET_ITEM(l.ptr(), index++, value_.release().ptr()); // steals a reference
271  }
272  return l.release();
273  }
274 
275  PYBIND11_TYPE_CASTER(ArrayType,
276  const_name<Resizable>(const_name(""), const_name("Annotated["))
277  + const_name("List[") + value_conv::name + const_name("]")
278  + const_name<Resizable>(const_name(""),
279  const_name(", FixedSize(")
280  + const_name<Size>() + const_name(")]")));
281 };
282 
283 template <typename Type, size_t Size>
284 struct type_caster<std::array<Type, Size>>
285  : array_caster<std::array<Type, Size>, Type, false, Size> {};
286 
287 template <typename Type>
288 struct type_caster<std::valarray<Type>> : array_caster<std::valarray<Type>, Type, true> {};
289 
290 template <typename Key, typename Compare, typename Alloc>
291 struct type_caster<std::set<Key, Compare, Alloc>>
292  : set_caster<std::set<Key, Compare, Alloc>, Key> {};
293 
294 template <typename Key, typename Hash, typename Equal, typename Alloc>
295 struct type_caster<std::unordered_set<Key, Hash, Equal, Alloc>>
296  : set_caster<std::unordered_set<Key, Hash, Equal, Alloc>, Key> {};
297 
298 template <typename Key, typename Value, typename Compare, typename Alloc>
299 struct type_caster<std::map<Key, Value, Compare, Alloc>>
300  : map_caster<std::map<Key, Value, Compare, Alloc>, Key, Value> {};
301 
302 template <typename Key, typename Value, typename Hash, typename Equal, typename Alloc>
303 struct type_caster<std::unordered_map<Key, Value, Hash, Equal, Alloc>>
304  : map_caster<std::unordered_map<Key, Value, Hash, Equal, Alloc>, Key, Value> {};
305 
306 // This type caster is intended to be used for std::optional and std::experimental::optional
307 template <typename Type, typename Value = typename Type::value_type>
310 
311  template <typename T>
312  static handle cast(T &&src, return_value_policy policy, handle parent) {
313  if (!src) {
314  return none().release();
315  }
318  }
319  // NOLINTNEXTLINE(bugprone-unchecked-optional-access)
320  return value_conv::cast(*std::forward<T>(src), policy, parent);
321  }
322 
323  bool load(handle src, bool convert) {
324  if (!src) {
325  return false;
326  }
327  if (src.is_none()) {
328  return true; // default-constructed value is already empty
329  }
330  value_conv inner_caster;
331  if (!inner_caster.load(src, convert)) {
332  return false;
333  }
334 
335  value.emplace(cast_op<Value &&>(std::move(inner_caster)));
336  return true;
337  }
338 
340 };
341 
342 #if defined(PYBIND11_HAS_OPTIONAL)
343 template <typename T>
344 struct type_caster<std::optional<T>> : public optional_caster<std::optional<T>> {};
345 
346 template <>
347 struct type_caster<std::nullopt_t> : public void_caster<std::nullopt_t> {};
348 #endif
349 
350 #if defined(PYBIND11_HAS_EXP_OPTIONAL)
351 template <typename T>
352 struct type_caster<std::experimental::optional<T>>
353  : public optional_caster<std::experimental::optional<T>> {};
354 
355 template <>
356 struct type_caster<std::experimental::nullopt_t>
357  : public void_caster<std::experimental::nullopt_t> {};
358 #endif
359 
364 
365  using result_type = handle; // required by boost::variant in C++11
366 
367  template <typename T>
368  result_type operator()(T &&src) const {
369  return make_caster<T>::cast(std::forward<T>(src), policy, parent);
370  }
371 };
372 
377 template <template <typename...> class Variant>
378 struct visit_helper {
379  template <typename... Args>
380  static auto call(Args &&...args) -> decltype(visit(std::forward<Args>(args)...)) {
381  return visit(std::forward<Args>(args)...);
382  }
383 };
384 
386 template <typename Variant>
388 
389 template <template <typename...> class V, typename... Ts>
390 struct variant_caster<V<Ts...>> {
391  static_assert(sizeof...(Ts) > 0, "Variant must consist of at least one alternative.");
392 
393  template <typename U, typename... Us>
395  auto caster = make_caster<U>();
396  if (caster.load(src, convert)) {
397  value = cast_op<U>(std::move(caster));
398  return true;
399  }
400  return load_alternative(src, convert, type_list<Us...>{});
401  }
402 
403  bool load_alternative(handle, bool, type_list<>) { return false; }
404 
405  bool load(handle src, bool convert) {
406  // Do a first pass without conversions to improve constructor resolution.
407  // E.g. `py::int_(1).cast<variant<double, int>>()` needs to fill the `int`
408  // slot of the variant. Without two-pass loading `double` would be filled
409  // because it appears first and a conversion is possible.
410  if (convert && load_alternative(src, false, type_list<Ts...>{})) {
411  return true;
412  }
413  return load_alternative(src, convert, type_list<Ts...>{});
414  }
415 
416  template <typename Variant>
417  static handle cast(Variant &&src, return_value_policy policy, handle parent) {
418  return visit_helper<V>::call(variant_caster_visitor{policy, parent},
419  std::forward<Variant>(src));
420  }
421 
422  using Type = V<Ts...>;
425  + const_name("]"));
426 };
427 
428 #if defined(PYBIND11_HAS_VARIANT)
429 template <typename... Ts>
430 struct type_caster<std::variant<Ts...>> : variant_caster<std::variant<Ts...>> {};
431 
432 template <>
433 struct type_caster<std::monostate> : public void_caster<std::monostate> {};
434 #endif
435 
437 
438 inline std::ostream &operator<<(std::ostream &os, const handle &obj) {
439 #ifdef PYBIND11_HAS_STRING_VIEW
440  os << str(obj).cast<std::string_view>();
441 #else
442  os << (std::string) str(obj);
443 #endif
444  return os;
445 }
446 
variant_caster< V< Ts... > >::Type
V< Ts... > Type
Definition: stl.h:422
external::detail::conv
PyObject * conv(PyObject *o)
Definition: test_pytypes.cpp:18
list_caster::reserve_maybe
void reserve_maybe(const sequence &s, Type *)
Definition: stl.h:187
variant_caster< V< Ts... > >::load_alternative
bool load_alternative(handle, bool, type_list<>)
Definition: stl.h:403
has_reserve_method
std::is_same< decltype(std::declval< C >().reserve(0)), void > has_reserve_method
Definition: stl.h:55
array_caster
Definition: stl.h:224
map_caster::PYBIND11_TYPE_CASTER
PYBIND11_TYPE_CASTER(Type, const_name("Dict[")+key_conv::name+const_name(", ")+value_conv::name+const_name("]"))
set
Definition: pytypes.h:2185
list_caster
Definition: stl.h:165
ssize_t
Py_ssize_t ssize_t
Definition: wrap/pybind11/include/pybind11/detail/common.h:475
array_caster::load
bool load(handle src, bool convert)
Definition: stl.h:241
optional_caster
Definition: stl.h:308
s
RealScalar s
Definition: level1_cplx_impl.h:126
const_name
constexpr descr< N - 1 > const_name(char const (&text)[N])
Definition: descr.h:60
d
static const double d[K][N]
Definition: igam.h:11
array_caster::cast
static handle cast(T &&src, return_value_policy policy, handle parent)
Definition: stl.h:261
map_caster::reserve_maybe
void reserve_maybe(const dict &d, Type *)
Definition: stl.h:113
return_value_policy
return_value_policy
Approach used to cast a previously unknown C++ instance into a Python object.
Definition: wrap/pybind11/include/pybind11/detail/common.h:485
list
Definition: pytypes.h:2124
forward_like
constexpr forwarded_type< T, U > forward_like(U &&u)
Definition: stl.h:48
PYBIND11_NAMESPACE_END
#define PYBIND11_NAMESPACE_END(name)
Definition: wrap/pybind11/include/pybind11/detail/common.h:80
array_caster::PYBIND11_TYPE_CASTER
PYBIND11_TYPE_CASTER(ArrayType, const_name< Resizable >(const_name(""), const_name("Annotated["))+const_name("List[")+value_conv::name+const_name("]")+const_name< Resizable >(const_name(""), const_name(", FixedSize(")+const_name< Size >()+const_name(")]")))
void_caster
Definition: cast.h:246
type
Definition: pytypes.h:1491
detail
Definition: testSerializationNonlinear.cpp:70
set_caster::reserve_maybe
void reserve_maybe(const anyset &, void *)
Definition: stl.h:67
PYBIND11_NAMESPACE_BEGIN
#define PYBIND11_NAMESPACE_BEGIN(name)
Definition: wrap/pybind11/include/pybind11/detail/common.h:76
os
ofstream os("timeSchurFactors.csv")
map_caster::load
bool load(handle src, bool convert)
Definition: stl.h:119
list_caster::cast
static handle cast(T &&src, return_value_policy policy, handle parent)
Definition: stl.h:194
conditional_t
typename std::conditional< B, T, F >::type conditional_t
Definition: wrap/pybind11/include/pybind11/detail/common.h:642
type_list
Helper template which holds a list of types.
Definition: wrap/pybind11/include/pybind11/detail/common.h:805
variant_caster< V< Ts... > >::load_alternative
bool load_alternative(handle src, bool convert, type_list< U, Us... >)
Definition: stl.h:394
size
Scalar Scalar int size
Definition: benchVecAdd.cpp:17
type_caster_base::cast
static handle cast(const itype &src, return_value_policy policy, handle parent)
Definition: type_caster_base.h:1072
dict
Definition: pytypes.h:2065
optional_caster::cast
static handle cast(T &&src, return_value_policy policy, handle parent)
Definition: stl.h:312
map_caster
Definition: stl.h:107
handle
Definition: pytypes.h:217
type_caster
Definition: cast.h:38
sequence
Definition: pytypes.h:2104
set_caster
Definition: stl.h:58
variant_caster
Generic variant caster.
Definition: stl.h:387
return_value_policy_override::policy
static return_value_policy policy(return_value_policy p)
Definition: cast.h:999
object::release
handle release()
Definition: pytypes.h:368
set_caster::reserve_maybe
void reserve_maybe(const anyset &s, Type *)
Definition: stl.h:64
list_caster::PYBIND11_TYPE_CASTER
PYBIND11_TYPE_CASTER(Type, const_name("List[")+value_conv::name+const_name("]"))
Eigen::Architecture::Type
Type
Definition: Constants.h:471
l
static const Line3 l(Rot3(), 1, 1)
array_caster::require_size
bool require_size(enable_if_t< R, size_t > size)
Definition: stl.h:229
map_caster::cast
static handle cast(T &&src, return_value_policy policy, handle parent)
Definition: stl.h:138
list_caster::reserve_maybe
void reserve_maybe(const sequence &, void *)
Definition: stl.h:190
variant_caster_visitor::parent
handle parent
Definition: stl.h:363
PYBIND11_NAMESPACE
Definition: test_custom_type_casters.cpp:24
Eigen::Triplet< double >
concat
constexpr descr< 0 > concat()
Definition: descr.h:139
common.h
visit_helper
Definition: stl.h:378
variant_caster_visitor::operator()
result_type operator()(T &&src) const
Definition: stl.h:368
key
const gtsam::Symbol key('X', 0)
set
void set(Container &c, Position position, const Value &value)
Definition: stdlist_overload.cpp:37
PYBIND11_TYPE_CASTER
#define PYBIND11_TYPE_CASTER(type, py_name)
Definition: cast.h:85
pybind11.h
forwarded_type
conditional_t< std::is_lvalue_reference< T >::value, remove_reference_t< U > &, remove_reference_t< U > && > forwarded_type
Definition: stl.h:43
array
Definition: numpy.h:684
map_caster::reserve_maybe
void reserve_maybe(const dict &, void *)
Definition: stl.h:116
list_caster::load
bool load(handle src, bool convert)
Definition: stl.h:168
variant_caster_visitor::policy
return_value_policy policy
Definition: stl.h:362
array_caster::require_size
bool require_size(enable_if_t<!R, size_t > size)
Definition: stl.h:236
std
Definition: BFloat16.h:88
args
Definition: pytypes.h:2163
visit_helper::call
static auto call(Args &&...args) -> decltype(visit(std::forward< Args >(args)...))
Definition: stl.h:380
U
@ U
Definition: testDecisionTree.cpp:296
optional_caster::load
bool load(handle src, bool convert)
Definition: stl.h:323
V
MatrixXcd V
Definition: EigenSolver_EigenSolver_MatrixType.cpp:15
type_caster_generic::load
bool load(handle src, bool convert)
Definition: type_caster_base.h:506
none
Definition: pytypes.h:1744
set_caster::cast
static handle cast(T &&src, return_value_policy policy, handle parent)
Definition: stl.h:88
set_caster::load
bool load(handle src, bool convert)
Definition: stl.h:70
gtsam::convert
static BinaryMeasurement< Rot3 > convert(const BetweenFactor< Pose3 >::shared_ptr &f)
Definition: ShonanAveraging.cpp:998
gtsam.examples.ShonanAveragingCLI.str
str
Definition: ShonanAveragingCLI.py:115
type_caster_base::name
static constexpr auto name
Definition: type_caster_base.h:1067
enable_if_t
typename std::enable_if< B, T >::type enable_if_t
from cpp_future import (convenient aliases from C++14/17)
Definition: wrap/pybind11/include/pybind11/detail/common.h:640
variant_caster< V< Ts... > >::cast
static handle cast(Variant &&src, return_value_policy policy, handle parent)
Definition: stl.h:417
variant_caster_visitor
Visit a variant and cast any found type to Python.
Definition: stl.h:361
test_callbacks.value
value
Definition: test_callbacks.py:158
set_caster::PYBIND11_TYPE_CASTER
PYBIND11_TYPE_CASTER(type, const_name("Set[")+key_conv::name+const_name("]"))
remove_reference_t
typename std::remove_reference< T >::type remove_reference_t
Definition: wrap/pybind11/include/pybind11/detail/common.h:646
variant_caster< V< Ts... > >::load
bool load(handle src, bool convert)
Definition: stl.h:405
optional_caster::PYBIND11_TYPE_CASTER
PYBIND11_TYPE_CASTER(Type, const_name("Optional[")+value_conv::name+const_name("]"))
anyset
Definition: pytypes.h:2170


gtsam
Author(s):
autogenerated on Sat Jun 1 2024 03:04:09