Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-03-31 08:26:39

0001 /*
0002     pybind11/stl.h: Transparent conversion for STL data types
0003 
0004     Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
0005 
0006     All rights reserved. Use of this source code is governed by a
0007     BSD-style license that can be found in the LICENSE file.
0008 */
0009 
0010 #pragma once
0011 
0012 #include "pybind11.h"
0013 #include "detail/common.h"
0014 #include "detail/descr.h"
0015 #include "detail/type_caster_base.h"
0016 
0017 #include <deque>
0018 #include <initializer_list>
0019 #include <list>
0020 #include <map>
0021 #include <memory>
0022 #include <ostream>
0023 #include <set>
0024 #include <unordered_map>
0025 #include <unordered_set>
0026 #include <valarray>
0027 
0028 // See `detail/common.h` for implementation of these guards.
0029 #if defined(PYBIND11_HAS_OPTIONAL)
0030 #    include <optional>
0031 #elif defined(PYBIND11_HAS_EXP_OPTIONAL)
0032 #    include <experimental/optional>
0033 #endif
0034 
0035 #if defined(PYBIND11_HAS_VARIANT)
0036 #    include <variant>
0037 #endif
0038 
0039 PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
0040 PYBIND11_NAMESPACE_BEGIN(detail)
0041 
0042 //
0043 // Begin: Equivalent of
0044 //        https://github.com/google/clif/blob/ae4eee1de07cdf115c0c9bf9fec9ff28efce6f6c/clif/python/runtime.cc#L388-L438
0045 /*
0046 The three `object_is_convertible_to_*()` functions below are
0047 the result of converging the behaviors of pybind11 and PyCLIF
0048 (http://github.com/google/clif).
0049 
0050 Originally PyCLIF was extremely far on the permissive side of the spectrum,
0051 while pybind11 was very far on the strict side. Originally PyCLIF accepted any
0052 Python iterable as input for a C++ `vector`/`set`/`map` argument, as long as
0053 the elements were convertible. The obvious (in hindsight) problem was that
0054 any empty Python iterable could be passed to any of these C++ types, e.g. `{}`
0055 was accepted for C++ `vector`/`set` arguments, or `[]` for C++ `map` arguments.
0056 
0057 The functions below strike a practical permissive-vs-strict compromise,
0058 informed by tens of thousands of use cases in the wild. A main objective is
0059 to prevent accidents and improve readability:
0060 
0061 - Python literals must match the C++ types.
0062 
0063 - For C++ `set`: The potentially reducing conversion from a Python sequence
0064   (e.g. Python `list` or `tuple`) to a C++ `set` must be explicit, by going
0065   through a Python `set`.
0066 
0067 - However, a Python `set` can still be passed to a C++ `vector`. The rationale
0068   is that this conversion is not reducing. Implicit conversions of this kind
0069   are also fairly commonly used, therefore enforcing explicit conversions
0070   would have an unfavorable cost : benefit ratio; more sloppily speaking,
0071   such an enforcement would be more annoying than helpful.
0072 
0073 Additional checks have been added to allow types derived from `collections.abc.Set` and
0074 `collections.abc.Mapping` (`collections.abc.Sequence` is already allowed by `PySequence_Check`).
0075 */
0076 
0077 inline bool object_is_instance_with_one_of_tp_names(PyObject *obj,
0078                                                     std::initializer_list<const char *> tp_names) {
0079     if (PyType_Check(obj)) {
0080         return false;
0081     }
0082     const char *obj_tp_name = Py_TYPE(obj)->tp_name;
0083     for (const auto *tp_name : tp_names) {
0084         if (std::strcmp(obj_tp_name, tp_name) == 0) {
0085             return true;
0086         }
0087     }
0088     return false;
0089 }
0090 
0091 inline bool object_is_convertible_to_std_vector(const handle &src) {
0092     // Allow sequence-like objects, but not (byte-)string-like objects.
0093     if (PySequence_Check(src.ptr()) != 0) {
0094         return !PyUnicode_Check(src.ptr()) && !PyBytes_Check(src.ptr());
0095     }
0096     // Allow generators, set/frozenset and several common iterable types.
0097     return (PyGen_Check(src.ptr()) != 0) || (PyAnySet_Check(src.ptr()) != 0)
0098            || object_is_instance_with_one_of_tp_names(
0099                src.ptr(), {"dict_keys", "dict_values", "dict_items", "map", "zip"});
0100 }
0101 
0102 inline bool object_is_convertible_to_std_set(const handle &src, bool convert) {
0103     // Allow set/frozenset and dict keys.
0104     // In convert mode: also allow types derived from collections.abc.Set.
0105     return ((PyAnySet_Check(src.ptr()) != 0)
0106             || object_is_instance_with_one_of_tp_names(src.ptr(), {"dict_keys"}))
0107            || (convert && isinstance(src, module_::import("collections.abc").attr("Set")));
0108 }
0109 
0110 inline bool object_is_convertible_to_std_map(const handle &src, bool convert) {
0111     // Allow dict.
0112     if (PyDict_Check(src.ptr())) {
0113         return true;
0114     }
0115     // Allow types conforming to Mapping Protocol.
0116     // According to https://docs.python.org/3/c-api/mapping.html, `PyMappingCheck()` checks for
0117     // `__getitem__()` without checking the type of keys. In order to restrict the allowed types
0118     // closer to actual Mapping-like types, we also check for the `items()` method.
0119     if (PyMapping_Check(src.ptr()) != 0) {
0120         PyObject *items = PyObject_GetAttrString(src.ptr(), "items");
0121         if (items != nullptr) {
0122             bool is_convertible = (PyCallable_Check(items) != 0);
0123             Py_DECREF(items);
0124             if (is_convertible) {
0125                 return true;
0126             }
0127         } else {
0128             PyErr_Clear();
0129         }
0130     }
0131     // In convert mode: Allow types derived from collections.abc.Mapping
0132     return convert && isinstance(src, module_::import("collections.abc").attr("Mapping"));
0133 }
0134 
0135 //
0136 // End: Equivalent of clif/python/runtime.cc
0137 //
0138 
0139 /// Extracts an const lvalue reference or rvalue reference for U based on the type of T (e.g. for
0140 /// forwarding a container element).  Typically used indirect via forwarded_type(), below.
0141 template <typename T, typename U>
0142 using forwarded_type = conditional_t<std::is_lvalue_reference<T>::value,
0143                                      remove_reference_t<U> &,
0144                                      remove_reference_t<U> &&>;
0145 
0146 /// Forwards a value U as rvalue or lvalue according to whether T is rvalue or lvalue; typically
0147 /// used for forwarding a container's elements.
0148 template <typename T, typename U>
0149 constexpr forwarded_type<T, U> forward_like(U &&u) {
0150     return std::forward<detail::forwarded_type<T, U>>(std::forward<U>(u));
0151 }
0152 
0153 // Checks if a container has a STL style reserve method.
0154 // This will only return true for a `reserve()` with a `void` return.
0155 template <typename C>
0156 using has_reserve_method = std::is_same<decltype(std::declval<C>().reserve(0)), void>;
0157 
0158 template <typename Type, typename Key>
0159 struct set_caster {
0160     using type = Type;
0161     using key_conv = make_caster<Key>;
0162 
0163 private:
0164     template <typename T = Type, enable_if_t<has_reserve_method<T>::value, int> = 0>
0165     void reserve_maybe(const anyset &s, Type *) {
0166         value.reserve(s.size());
0167     }
0168     void reserve_maybe(const anyset &, void *) {}
0169 
0170     bool convert_iterable(const iterable &itbl, bool convert) {
0171         for (const auto &it : itbl) {
0172             key_conv conv;
0173             if (!conv.load(it, convert)) {
0174                 return false;
0175             }
0176             value.insert(cast_op<Key &&>(std::move(conv)));
0177         }
0178         return true;
0179     }
0180 
0181     bool convert_anyset(const anyset &s, bool convert) {
0182         value.clear();
0183         reserve_maybe(s, &value);
0184         return convert_iterable(s, convert);
0185     }
0186 
0187 public:
0188     bool load(handle src, bool convert) {
0189         if (!object_is_convertible_to_std_set(src, convert)) {
0190             return false;
0191         }
0192         if (isinstance<anyset>(src)) {
0193             value.clear();
0194             return convert_anyset(reinterpret_borrow<anyset>(src), convert);
0195         }
0196         if (!convert) {
0197             return false;
0198         }
0199         assert(isinstance<iterable>(src));
0200         value.clear();
0201         return convert_iterable(reinterpret_borrow<iterable>(src), convert);
0202     }
0203 
0204     template <typename T>
0205     static handle cast(T &&src, return_value_policy policy, handle parent) {
0206         if (!std::is_lvalue_reference<T>::value) {
0207             policy = return_value_policy_override<Key>::policy(policy);
0208         }
0209         pybind11::set s;
0210         for (auto &&value : src) {
0211             auto value_ = reinterpret_steal<object>(
0212                 key_conv::cast(detail::forward_like<T>(value), policy, parent));
0213             if (!value_ || !s.add(std::move(value_))) {
0214                 return handle();
0215             }
0216         }
0217         return s.release();
0218     }
0219 
0220     PYBIND11_TYPE_CASTER(type,
0221                          io_name("collections.abc.Set", "set") + const_name("[") + key_conv::name
0222                              + const_name("]"));
0223 };
0224 
0225 template <typename Type, typename Key, typename Value>
0226 struct map_caster {
0227     using key_conv = make_caster<Key>;
0228     using value_conv = make_caster<Value>;
0229 
0230 private:
0231     template <typename T = Type, enable_if_t<has_reserve_method<T>::value, int> = 0>
0232     void reserve_maybe(const dict &d, Type *) {
0233         value.reserve(d.size());
0234     }
0235     void reserve_maybe(const dict &, void *) {}
0236 
0237     bool convert_elements(const dict &d, bool convert) {
0238         value.clear();
0239         reserve_maybe(d, &value);
0240         for (const auto &it : d) {
0241             key_conv kconv;
0242             value_conv vconv;
0243             if (!kconv.load(it.first.ptr(), convert) || !vconv.load(it.second.ptr(), convert)) {
0244                 return false;
0245             }
0246             value.emplace(cast_op<Key &&>(std::move(kconv)), cast_op<Value &&>(std::move(vconv)));
0247         }
0248         return true;
0249     }
0250 
0251 public:
0252     bool load(handle src, bool convert) {
0253         if (!object_is_convertible_to_std_map(src, convert)) {
0254             return false;
0255         }
0256         if (isinstance<dict>(src)) {
0257             return convert_elements(reinterpret_borrow<dict>(src), convert);
0258         }
0259         if (!convert) {
0260             return false;
0261         }
0262         auto items = reinterpret_steal<object>(PyMapping_Items(src.ptr()));
0263         if (!items) {
0264             throw error_already_set();
0265         }
0266         assert(isinstance<iterable>(items));
0267         return convert_elements(dict(reinterpret_borrow<iterable>(items)), convert);
0268     }
0269 
0270     template <typename T>
0271     static handle cast(T &&src, return_value_policy policy, handle parent) {
0272         dict d;
0273         return_value_policy policy_key = policy;
0274         return_value_policy policy_value = policy;
0275         if (!std::is_lvalue_reference<T>::value) {
0276             policy_key = return_value_policy_override<Key>::policy(policy_key);
0277             policy_value = return_value_policy_override<Value>::policy(policy_value);
0278         }
0279         for (auto &&kv : src) {
0280             auto key = reinterpret_steal<object>(
0281                 key_conv::cast(detail::forward_like<T>(kv.first), policy_key, parent));
0282             auto value = reinterpret_steal<object>(
0283                 value_conv::cast(detail::forward_like<T>(kv.second), policy_value, parent));
0284             if (!key || !value) {
0285                 return handle();
0286             }
0287             d[std::move(key)] = std::move(value);
0288         }
0289         return d.release();
0290     }
0291 
0292     PYBIND11_TYPE_CASTER(Type,
0293                          io_name("collections.abc.Mapping", "dict") + const_name("[")
0294                              + key_conv::name + const_name(", ") + value_conv::name
0295                              + const_name("]"));
0296 };
0297 
0298 template <typename Type, typename Value>
0299 struct list_caster {
0300     using value_conv = make_caster<Value>;
0301 
0302     bool load(handle src, bool convert) {
0303         if (!object_is_convertible_to_std_vector(src)) {
0304             return false;
0305         }
0306         if (isinstance<sequence>(src)) {
0307             return convert_elements(src, convert);
0308         }
0309         if (!convert) {
0310             return false;
0311         }
0312         // Designed to be behavior-equivalent to passing tuple(src) from Python:
0313         // The conversion to a tuple will first exhaust the generator object, to ensure that
0314         // the generator is not left in an unpredictable (to the caller) partially-consumed
0315         // state.
0316         assert(isinstance<iterable>(src));
0317         return convert_elements(tuple(reinterpret_borrow<iterable>(src)), convert);
0318     }
0319 
0320 private:
0321     template <typename T = Type, enable_if_t<has_reserve_method<T>::value, int> = 0>
0322     void reserve_maybe(const sequence &s, Type *) {
0323         value.reserve(s.size());
0324     }
0325     void reserve_maybe(const sequence &, void *) {}
0326 
0327     bool convert_elements(handle seq, bool convert) {
0328         auto s = reinterpret_borrow<sequence>(seq);
0329         value.clear();
0330         reserve_maybe(s, &value);
0331         for (const auto &it : seq) {
0332             value_conv conv;
0333             if (!conv.load(it, convert)) {
0334                 return false;
0335             }
0336             value.push_back(cast_op<Value &&>(std::move(conv)));
0337         }
0338         return true;
0339     }
0340 
0341 public:
0342     template <typename T>
0343     static handle cast(T &&src, return_value_policy policy, handle parent) {
0344         if (!std::is_lvalue_reference<T>::value) {
0345             policy = return_value_policy_override<Value>::policy(policy);
0346         }
0347         list l(src.size());
0348         ssize_t index = 0;
0349         for (auto &&value : src) {
0350             auto value_ = reinterpret_steal<object>(
0351                 value_conv::cast(detail::forward_like<T>(value), policy, parent));
0352             if (!value_) {
0353                 return handle();
0354             }
0355             PyList_SET_ITEM(l.ptr(), index++, value_.release().ptr()); // steals a reference
0356         }
0357         return l.release();
0358     }
0359 
0360     PYBIND11_TYPE_CASTER(Type,
0361                          io_name("collections.abc.Sequence", "list") + const_name("[")
0362                              + value_conv::name + const_name("]"));
0363 };
0364 
0365 template <typename Type, typename Alloc>
0366 struct type_caster<std::vector<Type, Alloc>> : list_caster<std::vector<Type, Alloc>, Type> {};
0367 
0368 template <typename Type, typename Alloc>
0369 struct type_caster<std::deque<Type, Alloc>> : list_caster<std::deque<Type, Alloc>, Type> {};
0370 
0371 template <typename Type, typename Alloc>
0372 struct type_caster<std::list<Type, Alloc>> : list_caster<std::list<Type, Alloc>, Type> {};
0373 
0374 template <typename ArrayType, typename V, size_t... I>
0375 ArrayType vector_to_array_impl(V &&v, index_sequence<I...>) {
0376     return {{std::move(v[I])...}};
0377 }
0378 
0379 // Based on https://en.cppreference.com/w/cpp/container/array/to_array
0380 template <typename ArrayType, size_t N, typename V>
0381 ArrayType vector_to_array(V &&v) {
0382     return vector_to_array_impl<ArrayType, V>(std::forward<V>(v), make_index_sequence<N>{});
0383 }
0384 
0385 template <typename ArrayType, typename Value, bool Resizable, size_t Size = 0>
0386 struct array_caster {
0387     using value_conv = make_caster<Value>;
0388 
0389 private:
0390     std::unique_ptr<ArrayType> value;
0391 
0392     template <bool R = Resizable, enable_if_t<R, int> = 0>
0393     bool convert_elements(handle seq, bool convert) {
0394         auto l = reinterpret_borrow<sequence>(seq);
0395         value.reset(new ArrayType{});
0396         // Using `resize` to preserve the behavior exactly as it was before PR #5305
0397         // For the `resize` to work, `Value` must be default constructible.
0398         // For `std::valarray`, this is a requirement:
0399         // https://en.cppreference.com/w/cpp/named_req/NumericType
0400         value->resize(l.size());
0401         size_t ctr = 0;
0402         for (const auto &it : l) {
0403             value_conv conv;
0404             if (!conv.load(it, convert)) {
0405                 return false;
0406             }
0407             (*value)[ctr++] = cast_op<Value &&>(std::move(conv));
0408         }
0409         return true;
0410     }
0411 
0412     template <bool R = Resizable, enable_if_t<!R, int> = 0>
0413     bool convert_elements(handle seq, bool convert) {
0414         auto l = reinterpret_borrow<sequence>(seq);
0415         if (l.size() != Size) {
0416             return false;
0417         }
0418         // The `temp` storage is needed to support `Value` types that are not
0419         // default-constructible.
0420         // Deliberate choice: no template specializations, for simplicity, and
0421         // because the compile time overhead for the specializations is deemed
0422         // more significant than the runtime overhead for the `temp` storage.
0423         std::vector<Value> temp;
0424         temp.reserve(l.size());
0425         for (auto it : l) {
0426             value_conv conv;
0427             if (!conv.load(it, convert)) {
0428                 return false;
0429             }
0430             temp.emplace_back(cast_op<Value &&>(std::move(conv)));
0431         }
0432         value.reset(new ArrayType(vector_to_array<ArrayType, Size>(std::move(temp))));
0433         return true;
0434     }
0435 
0436 public:
0437     bool load(handle src, bool convert) {
0438         if (!object_is_convertible_to_std_vector(src)) {
0439             return false;
0440         }
0441         if (isinstance<sequence>(src)) {
0442             return convert_elements(src, convert);
0443         }
0444         if (!convert) {
0445             return false;
0446         }
0447         // Designed to be behavior-equivalent to passing tuple(src) from Python:
0448         // The conversion to a tuple will first exhaust the generator object, to ensure that
0449         // the generator is not left in an unpredictable (to the caller) partially-consumed
0450         // state.
0451         assert(isinstance<iterable>(src));
0452         return convert_elements(tuple(reinterpret_borrow<iterable>(src)), convert);
0453     }
0454 
0455     template <typename T>
0456     static handle cast(T &&src, return_value_policy policy, handle parent) {
0457         list l(src.size());
0458         ssize_t index = 0;
0459         for (auto &&value : src) {
0460             auto value_ = reinterpret_steal<object>(
0461                 value_conv::cast(detail::forward_like<T>(value), policy, parent));
0462             if (!value_) {
0463                 return handle();
0464             }
0465             PyList_SET_ITEM(l.ptr(), index++, value_.release().ptr()); // steals a reference
0466         }
0467         return l.release();
0468     }
0469 
0470     // Code copied from PYBIND11_TYPE_CASTER macro.
0471     // Intentionally preserving the behavior exactly as it was before PR #5305
0472     template <typename T_, enable_if_t<std::is_same<ArrayType, remove_cv_t<T_>>::value, int> = 0>
0473     static handle cast(T_ *src, return_value_policy policy, handle parent) {
0474         if (!src) {
0475             return none().release();
0476         }
0477         if (policy == return_value_policy::take_ownership) {
0478             auto h = cast(std::move(*src), policy, parent);
0479             delete src; // WARNING: Assumes `src` was allocated with `new`.
0480             return h;
0481         }
0482         return cast(*src, policy, parent);
0483     }
0484 
0485     // NOLINTNEXTLINE(google-explicit-constructor)
0486     operator ArrayType *() { return &(*value); }
0487     // NOLINTNEXTLINE(google-explicit-constructor)
0488     operator ArrayType &() { return *value; }
0489     // NOLINTNEXTLINE(google-explicit-constructor)
0490     operator ArrayType &&() && { return std::move(*value); }
0491 
0492     template <typename T_>
0493     using cast_op_type = movable_cast_op_type<T_>;
0494 
0495     static constexpr auto name
0496         = const_name<Resizable>(const_name(""), const_name("typing.Annotated["))
0497           + io_name("collections.abc.Sequence", "list") + const_name("[") + value_conv::name
0498           + const_name("]")
0499           + const_name<Resizable>(const_name(""),
0500                                   const_name(", \"FixedSize(") + const_name<Size>()
0501                                       + const_name(")\"]"));
0502 };
0503 
0504 template <typename Type, size_t Size>
0505 struct type_caster<std::array<Type, Size>>
0506     : array_caster<std::array<Type, Size>, Type, false, Size> {};
0507 
0508 template <typename Type>
0509 struct type_caster<std::valarray<Type>> : array_caster<std::valarray<Type>, Type, true> {};
0510 
0511 template <typename Key, typename Compare, typename Alloc>
0512 struct type_caster<std::set<Key, Compare, Alloc>>
0513     : set_caster<std::set<Key, Compare, Alloc>, Key> {};
0514 
0515 template <typename Key, typename Hash, typename Equal, typename Alloc>
0516 struct type_caster<std::unordered_set<Key, Hash, Equal, Alloc>>
0517     : set_caster<std::unordered_set<Key, Hash, Equal, Alloc>, Key> {};
0518 
0519 template <typename Key, typename Value, typename Compare, typename Alloc>
0520 struct type_caster<std::map<Key, Value, Compare, Alloc>>
0521     : map_caster<std::map<Key, Value, Compare, Alloc>, Key, Value> {};
0522 
0523 template <typename Key, typename Value, typename Hash, typename Equal, typename Alloc>
0524 struct type_caster<std::unordered_map<Key, Value, Hash, Equal, Alloc>>
0525     : map_caster<std::unordered_map<Key, Value, Hash, Equal, Alloc>, Key, Value> {};
0526 
0527 // This type caster is intended to be used for std::optional and std::experimental::optional
0528 template <typename Type, typename Value = typename Type::value_type>
0529 struct optional_caster {
0530     using value_conv = make_caster<Value>;
0531 
0532     template <typename T>
0533     static handle cast(T &&src, return_value_policy policy, handle parent) {
0534         if (!src) {
0535             return none().release();
0536         }
0537         if (!std::is_lvalue_reference<T>::value) {
0538             policy = return_value_policy_override<Value>::policy(policy);
0539         }
0540         // NOLINTNEXTLINE(bugprone-unchecked-optional-access)
0541         return value_conv::cast(*std::forward<T>(src), policy, parent);
0542     }
0543 
0544     bool load(handle src, bool convert) {
0545         if (!src) {
0546             return false;
0547         }
0548         if (src.is_none()) {
0549             return true; // default-constructed value is already empty
0550         }
0551         value_conv inner_caster;
0552         if (!inner_caster.load(src, convert)) {
0553             return false;
0554         }
0555 
0556         value.emplace(cast_op<Value &&>(std::move(inner_caster)));
0557         return true;
0558     }
0559 
0560     PYBIND11_TYPE_CASTER(Type, value_conv::name | make_caster<none>::name);
0561 };
0562 
0563 #if defined(PYBIND11_HAS_OPTIONAL)
0564 template <typename T>
0565 struct type_caster<std::optional<T>> : public optional_caster<std::optional<T>> {};
0566 
0567 template <>
0568 struct type_caster<std::nullopt_t> : public void_caster<std::nullopt_t> {};
0569 #endif
0570 
0571 #if defined(PYBIND11_HAS_EXP_OPTIONAL)
0572 template <typename T>
0573 struct type_caster<std::experimental::optional<T>>
0574     : public optional_caster<std::experimental::optional<T>> {};
0575 
0576 template <>
0577 struct type_caster<std::experimental::nullopt_t>
0578     : public void_caster<std::experimental::nullopt_t> {};
0579 #endif
0580 
0581 /// Visit a variant and cast any found type to Python
0582 struct variant_caster_visitor {
0583     return_value_policy policy;
0584     handle parent;
0585 
0586     using result_type = handle; // required by boost::variant in C++11
0587 
0588     template <typename T>
0589     result_type operator()(T &&src) const {
0590         return make_caster<T>::cast(std::forward<T>(src), policy, parent);
0591     }
0592 };
0593 
0594 /// Helper class which abstracts away variant's `visit` function. `std::variant` and similar
0595 /// `namespace::variant` types which provide a `namespace::visit()` function are handled here
0596 /// automatically using argument-dependent lookup. Users can provide specializations for other
0597 /// variant-like classes, e.g. `boost::variant` and `boost::apply_visitor`.
0598 template <template <typename...> class Variant>
0599 struct visit_helper {
0600     template <typename... Args>
0601     static auto call(Args &&...args) -> decltype(visit(std::forward<Args>(args)...)) {
0602         return visit(std::forward<Args>(args)...);
0603     }
0604 };
0605 
0606 /// Generic variant caster
0607 template <typename Variant>
0608 struct variant_caster;
0609 
0610 template <template <typename...> class V, typename... Ts>
0611 struct variant_caster<V<Ts...>> {
0612     static_assert(sizeof...(Ts) > 0, "Variant must consist of at least one alternative.");
0613 
0614     template <typename U, typename... Us>
0615     bool load_alternative(handle src, bool convert, type_list<U, Us...>) {
0616         auto caster = make_caster<U>();
0617         if (caster.load(src, convert)) {
0618             value = cast_op<U>(std::move(caster));
0619             return true;
0620         }
0621         return load_alternative(src, convert, type_list<Us...>{});
0622     }
0623 
0624     bool load_alternative(handle, bool, type_list<>) { return false; }
0625 
0626     bool load(handle src, bool convert) {
0627         // Do a first pass without conversions to improve constructor resolution.
0628         // E.g. `py::int_(1).cast<variant<double, int>>()` needs to fill the `int`
0629         // slot of the variant. Without two-pass loading `double` would be filled
0630         // because it appears first and a conversion is possible.
0631         if (convert && load_alternative(src, false, type_list<Ts...>{})) {
0632             return true;
0633         }
0634         return load_alternative(src, convert, type_list<Ts...>{});
0635     }
0636 
0637     template <typename Variant>
0638     static handle cast(Variant &&src, return_value_policy policy, handle parent) {
0639         return visit_helper<V>::call(variant_caster_visitor{policy, parent},
0640                                      std::forward<Variant>(src));
0641     }
0642 
0643     using Type = V<Ts...>;
0644     PYBIND11_TYPE_CASTER(Type, ::pybind11::detail::union_concat(make_caster<Ts>::name...));
0645 };
0646 
0647 #if defined(PYBIND11_HAS_VARIANT)
0648 template <typename... Ts>
0649 struct type_caster<std::variant<Ts...>> : variant_caster<std::variant<Ts...>> {};
0650 
0651 template <>
0652 struct type_caster<std::monostate> : public void_caster<std::monostate> {};
0653 #endif
0654 
0655 PYBIND11_NAMESPACE_END(detail)
0656 
0657 inline std::ostream &operator<<(std::ostream &os, const handle &obj) {
0658 #ifdef PYBIND11_HAS_STRING_VIEW
0659     os << str(obj).cast<std::string_view>();
0660 #else
0661     os << (std::string) str(obj);
0662 #endif
0663     return os;
0664 }
0665 
0666 PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)