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 <set> 14#include <unordered_set> 15#include <map> 16#include <unordered_map> 17#include <iostream> 18#include <list> 19#include <deque> 20#include <valarray> 21 22#if defined(_MSC_VER) 23#pragma warning(push) 24#pragma warning(disable: 4127) // warning C4127: Conditional expression is constant 25#endif 26 27#ifdef __has_include 28// std::optional (but including it in c++14 mode isn't allowed) 29# if defined(PYBIND11_CPP17) && __has_include(<optional>) 30# include <optional> 31# define PYBIND11_HAS_OPTIONAL 1 32# endif 33// std::experimental::optional (but not allowed in c++11 mode) 34# if defined(PYBIND11_CPP14) && (__has_include(<experimental/optional>) && \ 35 !__has_include(<optional>)) 36# include <experimental/optional> 37# define PYBIND11_HAS_EXP_OPTIONAL 1 38# endif 39// std::variant 40# if defined(PYBIND11_CPP17) && __has_include(<variant>) 41# include <variant> 42# define PYBIND11_HAS_VARIANT 1 43# endif 44#elif defined(_MSC_VER) && defined(PYBIND11_CPP17) 45# include <optional> 46# include <variant> 47# define PYBIND11_HAS_OPTIONAL 1 48# define PYBIND11_HAS_VARIANT 1 49#endif 50 51NAMESPACE_BEGIN(PYBIND11_NAMESPACE) 52NAMESPACE_BEGIN(detail) 53 54/// Extracts an const lvalue reference or rvalue reference for U based on the type of T (e.g. for 55/// forwarding a container element). Typically used indirect via forwarded_type(), below. 56template <typename T, typename U> 57using forwarded_type = conditional_t< 58 std::is_lvalue_reference<T>::value, remove_reference_t<U> &, remove_reference_t<U> &&>; 59 60/// Forwards a value U as rvalue or lvalue according to whether T is rvalue or lvalue; typically 61/// used for forwarding a container's elements. 62template <typename T, typename U> 63forwarded_type<T, U> forward_like(U &&u) { 64 return std::forward<detail::forwarded_type<T, U>>(std::forward<U>(u)); 65} 66 67template <typename Type, typename Key> struct set_caster { 68 using type = Type; 69 using key_conv = make_caster<Key>; 70 71 bool load(handle src, bool convert) { 72 if (!isinstance<pybind11::set>(src)) 73 return false; 74 auto s = reinterpret_borrow<pybind11::set>(src); 75 value.clear(); 76 for (auto entry : s) { 77 key_conv conv; 78 if (!conv.load(entry, convert)) 79 return false; 80 value.insert(cast_op<Key &&>(std::move(conv))); 81 } 82 return true; 83 } 84 85 template <typename T> 86 static handle cast(T &&src, return_value_policy policy, handle parent) { 87 if (!std::is_lvalue_reference<T>::value) 88 policy = return_value_policy_override<Key>::policy(policy); 89 pybind11::set s; 90 for (auto &&value : src) { 91 auto value_ = reinterpret_steal<object>(key_conv::cast(forward_like<T>(value), policy, parent)); 92 if (!value_ || !s.add(value_)) 93 return handle(); 94 } 95 return s.release(); 96 } 97 98 PYBIND11_TYPE_CASTER(type, _("Set[") + key_conv::name + _("]")); 99}; 100 101template <typename Type, typename Key, typename Value> struct map_caster { 102 using key_conv = make_caster<Key>; 103 using value_conv = make_caster<Value>; 104 105 bool load(handle src, bool convert) { 106 if (!isinstance<dict>(src)) 107 return false; 108 auto d = reinterpret_borrow<dict>(src); 109 value.clear(); 110 for (auto it : d) { 111 key_conv kconv; 112 value_conv vconv; 113 if (!kconv.load(it.first.ptr(), convert) || 114 !vconv.load(it.second.ptr(), convert)) 115 return false; 116 value.emplace(cast_op<Key &&>(std::move(kconv)), cast_op<Value &&>(std::move(vconv))); 117 } 118 return true; 119 } 120 121 template <typename T> 122 static handle cast(T &&src, return_value_policy policy, handle parent) { 123 dict d; 124 return_value_policy policy_key = policy; 125 return_value_policy policy_value = policy; 126 if (!std::is_lvalue_reference<T>::value) { 127 policy_key = return_value_policy_override<Key>::policy(policy_key); 128 policy_value = return_value_policy_override<Value>::policy(policy_value); 129 } 130 for (auto &&kv : src) { 131 auto key = reinterpret_steal<object>(key_conv::cast(forward_like<T>(kv.first), policy_key, parent)); 132 auto value = reinterpret_steal<object>(value_conv::cast(forward_like<T>(kv.second), policy_value, parent)); 133 if (!key || !value) 134 return handle(); 135 d[key] = value; 136 } 137 return d.release(); 138 } 139 140 PYBIND11_TYPE_CASTER(Type, _("Dict[") + key_conv::name + _(", ") + value_conv::name + _("]")); 141}; 142 143template <typename Type, typename Value> struct list_caster { 144 using value_conv = make_caster<Value>; 145 146 bool load(handle src, bool convert) { 147 if (!isinstance<sequence>(src) || isinstance<str>(src)) 148 return false; 149 auto s = reinterpret_borrow<sequence>(src); 150 value.clear(); 151 reserve_maybe(s, &value); 152 for (auto it : s) { 153 value_conv conv; 154 if (!conv.load(it, convert)) 155 return false; 156 value.push_back(cast_op<Value &&>(std::move(conv))); 157 } 158 return true; 159 } 160 161private: 162 template <typename T = Type, 163 enable_if_t<std::is_same<decltype(std::declval<T>().reserve(0)), void>::value, int> = 0> 164 void reserve_maybe(sequence s, Type *) { value.reserve(s.size()); } 165 void reserve_maybe(sequence, void *) { } 166 167public: 168 template <typename T> 169 static handle cast(T &&src, return_value_policy policy, handle parent) { 170 if (!std::is_lvalue_reference<T>::value) 171 policy = return_value_policy_override<Value>::policy(policy); 172 list l(src.size()); 173 size_t index = 0; 174 for (auto &&value : src) { 175 auto value_ = reinterpret_steal<object>(value_conv::cast(forward_like<T>(value), policy, parent)); 176 if (!value_) 177 return handle(); 178 PyList_SET_ITEM(l.ptr(), (ssize_t) index++, value_.release().ptr()); // steals a reference 179 } 180 return l.release(); 181 } 182 183 PYBIND11_TYPE_CASTER(Type, _("List[") + value_conv::name + _("]")); 184}; 185 186template <typename Type, typename Alloc> struct type_caster<std::vector<Type, Alloc>> 187 : list_caster<std::vector<Type, Alloc>, Type> { }; 188 189template <typename Type, typename Alloc> struct type_caster<std::deque<Type, Alloc>> 190 : list_caster<std::deque<Type, Alloc>, Type> { }; 191 192template <typename Type, typename Alloc> struct type_caster<std::list<Type, Alloc>> 193 : list_caster<std::list<Type, Alloc>, Type> { }; 194 195template <typename ArrayType, typename Value, bool Resizable, size_t Size = 0> struct array_caster { 196 using value_conv = make_caster<Value>; 197 198private: 199 template <bool R = Resizable> 200 bool require_size(enable_if_t<R, size_t> size) { 201 if (value.size() != size) 202 value.resize(size); 203 return true; 204 } 205 template <bool R = Resizable> 206 bool require_size(enable_if_t<!R, size_t> size) { 207 return size == Size; 208 } 209 210public: 211 bool load(handle src, bool convert) { 212 if (!isinstance<sequence>(src)) 213 return false; 214 auto l = reinterpret_borrow<sequence>(src); 215 if (!require_size(l.size())) 216 return false; 217 size_t ctr = 0; 218 for (auto it : l) { 219 value_conv conv; 220 if (!conv.load(it, convert)) 221 return false; 222 value[ctr++] = cast_op<Value &&>(std::move(conv)); 223 } 224 return true; 225 } 226 227 template <typename T> 228 static handle cast(T &&src, return_value_policy policy, handle parent) { 229 list l(src.size()); 230 size_t index = 0; 231 for (auto &&value : src) { 232 auto value_ = reinterpret_steal<object>(value_conv::cast(forward_like<T>(value), policy, parent)); 233 if (!value_) 234 return handle(); 235 PyList_SET_ITEM(l.ptr(), (ssize_t) index++, value_.release().ptr()); // steals a reference 236 } 237 return l.release(); 238 } 239 240 PYBIND11_TYPE_CASTER(ArrayType, _("List[") + value_conv::name + _<Resizable>(_(""), _("[") + _<Size>() + _("]")) + _("]")); 241}; 242 243template <typename Type, size_t Size> struct type_caster<std::array<Type, Size>> 244 : array_caster<std::array<Type, Size>, Type, false, Size> { }; 245 246template <typename Type> struct type_caster<std::valarray<Type>> 247 : array_caster<std::valarray<Type>, Type, true> { }; 248 249template <typename Key, typename Compare, typename Alloc> struct type_caster<std::set<Key, Compare, Alloc>> 250 : set_caster<std::set<Key, Compare, Alloc>, Key> { }; 251 252template <typename Key, typename Hash, typename Equal, typename Alloc> struct type_caster<std::unordered_set<Key, Hash, Equal, Alloc>> 253 : set_caster<std::unordered_set<Key, Hash, Equal, Alloc>, Key> { }; 254 255template <typename Key, typename Value, typename Compare, typename Alloc> struct type_caster<std::map<Key, Value, Compare, Alloc>> 256 : map_caster<std::map<Key, Value, Compare, Alloc>, Key, Value> { }; 257 258template <typename Key, typename Value, typename Hash, typename Equal, typename Alloc> struct type_caster<std::unordered_map<Key, Value, Hash, Equal, Alloc>> 259 : map_caster<std::unordered_map<Key, Value, Hash, Equal, Alloc>, Key, Value> { }; 260 261// This type caster is intended to be used for std::optional and std::experimental::optional 262template<typename T> struct optional_caster { 263 using value_conv = make_caster<typename T::value_type>; 264 265 template <typename T_> 266 static handle cast(T_ &&src, return_value_policy policy, handle parent) { 267 if (!src) 268 return none().inc_ref(); 269 policy = return_value_policy_override<typename T::value_type>::policy(policy); 270 return value_conv::cast(*std::forward<T_>(src), policy, parent); 271 } 272 273 bool load(handle src, bool convert) { 274 if (!src) { 275 return false; 276 } else if (src.is_none()) { 277 return true; // default-constructed value is already empty 278 } 279 value_conv inner_caster; 280 if (!inner_caster.load(src, convert)) 281 return false; 282 283 value.emplace(cast_op<typename T::value_type &&>(std::move(inner_caster))); 284 return true; 285 } 286 287 PYBIND11_TYPE_CASTER(T, _("Optional[") + value_conv::name + _("]")); 288}; 289 290#ifdef PYBIND11_HAS_OPTIONAL 291template<typename T> struct type_caster<std::optional<T>> 292 : public optional_caster<std::optional<T>> {}; 293 294template<> struct type_caster<std::nullopt_t> 295 : public void_caster<std::nullopt_t> {}; 296#endif 297 298#ifdef PYBIND11_HAS_EXP_OPTIONAL 299template<typename T> struct type_caster<std::experimental::optional<T>> 300 : public optional_caster<std::experimental::optional<T>> {}; 301 302template<> struct type_caster<std::experimental::nullopt_t> 303 : public void_caster<std::experimental::nullopt_t> {}; 304#endif 305 306/// Visit a variant and cast any found type to Python 307struct variant_caster_visitor { 308 return_value_policy policy; 309 handle parent; 310 311 using result_type = handle; // required by boost::variant in C++11 312 313 template <typename T> 314 result_type operator()(T &&src) const { 315 return make_caster<T>::cast(std::forward<T>(src), policy, parent); 316 } 317}; 318 319/// Helper class which abstracts away variant's `visit` function. `std::variant` and similar 320/// `namespace::variant` types which provide a `namespace::visit()` function are handled here 321/// automatically using argument-dependent lookup. Users can provide specializations for other 322/// variant-like classes, e.g. `boost::variant` and `boost::apply_visitor`. 323template <template<typename...> class Variant> 324struct visit_helper { 325 template <typename... Args> 326 static auto call(Args &&...args) -> decltype(visit(std::forward<Args>(args)...)) { 327 return visit(std::forward<Args>(args)...); 328 } 329}; 330 331/// Generic variant caster 332template <typename Variant> struct variant_caster; 333 334template <template<typename...> class V, typename... Ts> 335struct variant_caster<V<Ts...>> { 336 static_assert(sizeof...(Ts) > 0, "Variant must consist of at least one alternative."); 337 338 template <typename U, typename... Us> 339 bool load_alternative(handle src, bool convert, type_list<U, Us...>) { 340 auto caster = make_caster<U>(); 341 if (caster.load(src, convert)) { 342 value = cast_op<U>(caster); 343 return true; 344 } 345 return load_alternative(src, convert, type_list<Us...>{}); 346 } 347 348 bool load_alternative(handle, bool, type_list<>) { return false; } 349 350 bool load(handle src, bool convert) { 351 // Do a first pass without conversions to improve constructor resolution. 352 // E.g. `py::int_(1).cast<variant<double, int>>()` needs to fill the `int` 353 // slot of the variant. Without two-pass loading `double` would be filled 354 // because it appears first and a conversion is possible. 355 if (convert && load_alternative(src, false, type_list<Ts...>{})) 356 return true; 357 return load_alternative(src, convert, type_list<Ts...>{}); 358 } 359 360 template <typename Variant> 361 static handle cast(Variant &&src, return_value_policy policy, handle parent) { 362 return visit_helper<V>::call(variant_caster_visitor{policy, parent}, 363 std::forward<Variant>(src)); 364 } 365 366 using Type = V<Ts...>; 367 PYBIND11_TYPE_CASTER(Type, _("Union[") + detail::concat(make_caster<Ts>::name...) + _("]")); 368}; 369 370#ifdef PYBIND11_HAS_VARIANT 371template <typename... Ts> 372struct type_caster<std::variant<Ts...>> : variant_caster<std::variant<Ts...>> { }; 373#endif 374 375NAMESPACE_END(detail) 376 377inline std::ostream &operator<<(std::ostream &os, const handle &obj) { 378 os << (std::string) str(obj); 379 return os; 380} 381 382NAMESPACE_END(PYBIND11_NAMESPACE) 383 384#if defined(_MSC_VER) 385#pragma warning(pop) 386#endif 387