File indexing completed on 2025-02-16 05:12:19

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 "detail/common.h"
0013 #include "pybind11.h"
0014 #include <set>
0015 #include <unordered_set>
0016 #include <map>
0017 #include <unordered_map>
0018 #include <iostream>
0019 #include <list>
0020 #include <deque>
0021 #include <valarray>
0022 
0023 // See `detail/common.h` for implementation of these guards.
0024 #if defined(PYBIND11_HAS_OPTIONAL)
0025 #  include <optional>
0026 #elif defined(PYBIND11_HAS_EXP_OPTIONAL)
0027 #  include <experimental/optional>
0028 #endif
0029 
0030 #if defined(PYBIND11_HAS_VARIANT)
0031 #  include <variant>
0032 #endif
0033 
0034 PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
0035 PYBIND11_NAMESPACE_BEGIN(detail)
0036 
0037 /// Extracts an const lvalue reference or rvalue reference for U based on the type of T (e.g. for
0038 /// forwarding a container element).  Typically used indirect via forwarded_type(), below.
0039 template <typename T, typename U>
0040 using forwarded_type = conditional_t<
0041     std::is_lvalue_reference<T>::value, remove_reference_t<U> &, remove_reference_t<U> &&>;
0042 
0043 /// Forwards a value U as rvalue or lvalue according to whether T is rvalue or lvalue; typically
0044 /// used for forwarding a container's elements.
0045 template <typename T, typename U>
0046 forwarded_type<T, U> forward_like(U &&u) {
0047     return std::forward<detail::forwarded_type<T, U>>(std::forward<U>(u));
0048 }
0049 
0050 template <typename Type, typename Key> struct set_caster {
0051     using type = Type;
0052     using key_conv = make_caster<Key>;
0053 
0054     bool load(handle src, bool convert) {
0055         if (!isinstance<pybind11::set>(src))
0056             return false;
0057         auto s = reinterpret_borrow<pybind11::set>(src);
0058         value.clear();
0059         for (auto entry : s) {
0060             key_conv conv;
0061             if (!conv.load(entry, convert))
0062                 return false;
0063             value.insert(cast_op<Key &&>(std::move(conv)));
0064         }
0065         return true;
0066     }
0067 
0068     template <typename T>
0069     static handle cast(T &&src, return_value_policy policy, handle parent) {
0070         if (!std::is_lvalue_reference<T>::value)
0071             policy = return_value_policy_override<Key>::policy(policy);
0072         pybind11::set s;
0073         for (auto &&value : src) {
0074             auto value_ = reinterpret_steal<object>(key_conv::cast(forward_like<T>(value), policy, parent));
0075             if (!value_ || !s.add(value_))
0076                 return handle();
0077         }
0078         return s.release();
0079     }
0080 
0081     PYBIND11_TYPE_CASTER(type, const_name("Set[") + key_conv::name + const_name("]"));
0082 };
0083 
0084 template <typename Type, typename Key, typename Value> struct map_caster {
0085     using key_conv   = make_caster<Key>;
0086     using value_conv = make_caster<Value>;
0087 
0088     bool load(handle src, bool convert) {
0089         if (!isinstance<dict>(src))
0090             return false;
0091         auto d = reinterpret_borrow<dict>(src);
0092         value.clear();
0093         for (auto it : d) {
0094             key_conv kconv;
0095             value_conv vconv;
0096             if (!kconv.load(it.first.ptr(), convert) ||
0097                 !vconv.load(it.second.ptr(), convert))
0098                 return false;
0099             value.emplace(cast_op<Key &&>(std::move(kconv)), cast_op<Value &&>(std::move(vconv)));
0100         }
0101         return true;
0102     }
0103 
0104     template <typename T>
0105     static handle cast(T &&src, return_value_policy policy, handle parent) {
0106         dict d;
0107         return_value_policy policy_key = policy;
0108         return_value_policy policy_value = policy;
0109         if (!std::is_lvalue_reference<T>::value) {
0110             policy_key = return_value_policy_override<Key>::policy(policy_key);
0111             policy_value = return_value_policy_override<Value>::policy(policy_value);
0112         }
0113         for (auto &&kv : src) {
0114             auto key = reinterpret_steal<object>(key_conv::cast(forward_like<T>(kv.first), policy_key, parent));
0115             auto value = reinterpret_steal<object>(value_conv::cast(forward_like<T>(kv.second), policy_value, parent));
0116             if (!key || !value)
0117                 return handle();
0118             d[key] = value;
0119         }
0120         return d.release();
0121     }
0122 
0123     PYBIND11_TYPE_CASTER(Type, const_name("Dict[") + key_conv::name + const_name(", ") + value_conv::name + const_name("]"));
0124 };
0125 
0126 template <typename Type, typename Value> struct list_caster {
0127     using value_conv = make_caster<Value>;
0128 
0129     bool load(handle src, bool convert) {
0130         if (!isinstance<sequence>(src) || isinstance<bytes>(src) || isinstance<str>(src))
0131             return false;
0132         auto s = reinterpret_borrow<sequence>(src);
0133         value.clear();
0134         reserve_maybe(s, &value);
0135         for (auto it : s) {
0136             value_conv conv;
0137             if (!conv.load(it, convert))
0138                 return false;
0139             value.push_back(cast_op<Value &&>(std::move(conv)));
0140         }
0141         return true;
0142     }
0143 
0144 private:
0145     template <
0146         typename T                                                                          = Type,
0147         enable_if_t<std::is_same<decltype(std::declval<T>().reserve(0)), void>::value, int> = 0>
0148     void reserve_maybe(const sequence &s, Type *) {
0149         value.reserve(s.size());
0150     }
0151     void reserve_maybe(const sequence &, void *) {}
0152 
0153 public:
0154     template <typename T>
0155     static handle cast(T &&src, return_value_policy policy, handle parent) {
0156         if (!std::is_lvalue_reference<T>::value)
0157             policy = return_value_policy_override<Value>::policy(policy);
0158         list l(src.size());
0159         ssize_t index = 0;
0160         for (auto &&value : src) {
0161             auto value_ = reinterpret_steal<object>(value_conv::cast(forward_like<T>(value), policy, parent));
0162             if (!value_)
0163                 return handle();
0164             PyList_SET_ITEM(l.ptr(), index++, value_.release().ptr()); // steals a reference
0165         }
0166         return l.release();
0167     }
0168 
0169     PYBIND11_TYPE_CASTER(Type, const_name("List[") + value_conv::name + const_name("]"));
0170 };
0171 
0172 template <typename Type, typename Alloc> struct type_caster<std::vector<Type, Alloc>>
0173  : list_caster<std::vector<Type, Alloc>, Type> { };
0174 
0175 template <typename Type, typename Alloc> struct type_caster<std::deque<Type, Alloc>>
0176  : list_caster<std::deque<Type, Alloc>, Type> { };
0177 
0178 template <typename Type, typename Alloc> struct type_caster<std::list<Type, Alloc>>
0179  : list_caster<std::list<Type, Alloc>, Type> { };
0180 
0181 template <typename ArrayType, typename Value, bool Resizable, size_t Size = 0> struct array_caster {
0182     using value_conv = make_caster<Value>;
0183 
0184 private:
0185     template <bool R = Resizable>
0186     bool require_size(enable_if_t<R, size_t> size) {
0187         if (value.size() != size)
0188             value.resize(size);
0189         return true;
0190     }
0191     template <bool R = Resizable>
0192     bool require_size(enable_if_t<!R, size_t> size) {
0193         return size == Size;
0194     }
0195 
0196 public:
0197     bool load(handle src, bool convert) {
0198         if (!isinstance<sequence>(src))
0199             return false;
0200         auto l = reinterpret_borrow<sequence>(src);
0201         if (!require_size(l.size()))
0202             return false;
0203         size_t ctr = 0;
0204         for (auto it : l) {
0205             value_conv conv;
0206             if (!conv.load(it, convert))
0207                 return false;
0208             value[ctr++] = cast_op<Value &&>(std::move(conv));
0209         }
0210         return true;
0211     }
0212 
0213     template <typename T>
0214     static handle cast(T &&src, return_value_policy policy, handle parent) {
0215         list l(src.size());
0216         ssize_t index = 0;
0217         for (auto &&value : src) {
0218             auto value_ = reinterpret_steal<object>(value_conv::cast(forward_like<T>(value), policy, parent));
0219             if (!value_)
0220                 return handle();
0221             PyList_SET_ITEM(l.ptr(), index++, value_.release().ptr()); // steals a reference
0222         }
0223         return l.release();
0224     }
0225 
0226     PYBIND11_TYPE_CASTER(ArrayType, const_name("List[") + value_conv::name + const_name<Resizable>(const_name(""), const_name("[") + const_name<Size>() + const_name("]")) + const_name("]"));
0227 };
0228 
0229 template <typename Type, size_t Size> struct type_caster<std::array<Type, Size>>
0230  : array_caster<std::array<Type, Size>, Type, false, Size> { };
0231 
0232 template <typename Type> struct type_caster<std::valarray<Type>>
0233  : array_caster<std::valarray<Type>, Type, true> { };
0234 
0235 template <typename Key, typename Compare, typename Alloc> struct type_caster<std::set<Key, Compare, Alloc>>
0236   : set_caster<std::set<Key, Compare, Alloc>, Key> { };
0237 
0238 template <typename Key, typename Hash, typename Equal, typename Alloc> struct type_caster<std::unordered_set<Key, Hash, Equal, Alloc>>
0239   : set_caster<std::unordered_set<Key, Hash, Equal, Alloc>, Key> { };
0240 
0241 template <typename Key, typename Value, typename Compare, typename Alloc> struct type_caster<std::map<Key, Value, Compare, Alloc>>
0242   : map_caster<std::map<Key, Value, Compare, Alloc>, Key, Value> { };
0243 
0244 template <typename Key, typename Value, typename Hash, typename Equal, typename Alloc> struct type_caster<std::unordered_map<Key, Value, Hash, Equal, Alloc>>
0245   : map_caster<std::unordered_map<Key, Value, Hash, Equal, Alloc>, Key, Value> { };
0246 
0247 // This type caster is intended to be used for std::optional and std::experimental::optional
0248 template<typename Type, typename Value = typename Type::value_type> struct optional_caster {
0249     using value_conv = make_caster<Value>;
0250 
0251     template <typename T>
0252     static handle cast(T &&src, return_value_policy policy, handle parent) {
0253         if (!src)
0254             return none().inc_ref();
0255         if (!std::is_lvalue_reference<T>::value) {
0256             policy = return_value_policy_override<Value>::policy(policy);
0257         }
0258         return value_conv::cast(*std::forward<T>(src), policy, parent);
0259     }
0260 
0261     bool load(handle src, bool convert) {
0262         if (!src) {
0263             return false;
0264         }
0265         if (src.is_none()) {
0266             return true;  // default-constructed value is already empty
0267         }
0268         value_conv inner_caster;
0269         if (!inner_caster.load(src, convert))
0270             return false;
0271 
0272         value.emplace(cast_op<Value &&>(std::move(inner_caster)));
0273         return true;
0274     }
0275 
0276     PYBIND11_TYPE_CASTER(Type, const_name("Optional[") + value_conv::name + const_name("]"));
0277 };
0278 
0279 #if defined(PYBIND11_HAS_OPTIONAL)
0280 template<typename T> struct type_caster<std::optional<T>>
0281     : public optional_caster<std::optional<T>> {};
0282 
0283 template<> struct type_caster<std::nullopt_t>
0284     : public void_caster<std::nullopt_t> {};
0285 #endif
0286 
0287 #if defined(PYBIND11_HAS_EXP_OPTIONAL)
0288 template<typename T> struct type_caster<std::experimental::optional<T>>
0289     : public optional_caster<std::experimental::optional<T>> {};
0290 
0291 template<> struct type_caster<std::experimental::nullopt_t>
0292     : public void_caster<std::experimental::nullopt_t> {};
0293 #endif
0294 
0295 /// Visit a variant and cast any found type to Python
0296 struct variant_caster_visitor {
0297     return_value_policy policy;
0298     handle parent;
0299 
0300     using result_type = handle; // required by boost::variant in C++11
0301 
0302     template <typename T>
0303     result_type operator()(T &&src) const {
0304         return make_caster<T>::cast(std::forward<T>(src), policy, parent);
0305     }
0306 };
0307 
0308 /// Helper class which abstracts away variant's `visit` function. `std::variant` and similar
0309 /// `namespace::variant` types which provide a `namespace::visit()` function are handled here
0310 /// automatically using argument-dependent lookup. Users can provide specializations for other
0311 /// variant-like classes, e.g. `boost::variant` and `boost::apply_visitor`.
0312 template <template<typename...> class Variant>
0313 struct visit_helper {
0314     template <typename... Args>
0315     static auto call(Args &&...args) -> decltype(visit(std::forward<Args>(args)...)) {
0316         return visit(std::forward<Args>(args)...);
0317     }
0318 };
0319 
0320 /// Generic variant caster
0321 template <typename Variant> struct variant_caster;
0322 
0323 template <template<typename...> class V, typename... Ts>
0324 struct variant_caster<V<Ts...>> {
0325     static_assert(sizeof...(Ts) > 0, "Variant must consist of at least one alternative.");
0326 
0327     template <typename U, typename... Us>
0328     bool load_alternative(handle src, bool convert, type_list<U, Us...>) {
0329         auto caster = make_caster<U>();
0330         if (caster.load(src, convert)) {
0331             value = cast_op<U>(caster);
0332             return true;
0333         }
0334         return load_alternative(src, convert, type_list<Us...>{});
0335     }
0336 
0337     bool load_alternative(handle, bool, type_list<>) { return false; }
0338 
0339     bool load(handle src, bool convert) {
0340         // Do a first pass without conversions to improve constructor resolution.
0341         // E.g. `py::int_(1).cast<variant<double, int>>()` needs to fill the `int`
0342         // slot of the variant. Without two-pass loading `double` would be filled
0343         // because it appears first and a conversion is possible.
0344         if (convert && load_alternative(src, false, type_list<Ts...>{}))
0345             return true;
0346         return load_alternative(src, convert, type_list<Ts...>{});
0347     }
0348 
0349     template <typename Variant>
0350     static handle cast(Variant &&src, return_value_policy policy, handle parent) {
0351         return visit_helper<V>::call(variant_caster_visitor{policy, parent},
0352                                      std::forward<Variant>(src));
0353     }
0354 
0355     using Type = V<Ts...>;
0356     PYBIND11_TYPE_CASTER(Type, const_name("Union[") + detail::concat(make_caster<Ts>::name...) + const_name("]"));
0357 };
0358 
0359 #if defined(PYBIND11_HAS_VARIANT)
0360 template <typename... Ts>
0361 struct type_caster<std::variant<Ts...>> : variant_caster<std::variant<Ts...>> { };
0362 #endif
0363 
0364 PYBIND11_NAMESPACE_END(detail)
0365 
0366 inline std::ostream &operator<<(std::ostream &os, const handle &obj) {
0367 #ifdef PYBIND11_HAS_STRING_VIEW
0368     os << str(obj).cast<std::string_view>();
0369 #else
0370     os << (std::string) str(obj);
0371 #endif
0372     return os;
0373 }
0374 
0375 PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)