| 270 | |
| 271 | template <typename C> |
| 272 | static handle cast_impl(C *src, return_value_policy policy, handle parent) { |
| 273 | object parent_object; |
| 274 | bool writeable = false; |
| 275 | switch (policy) { |
| 276 | case return_value_policy::move: |
| 277 | if (std::is_const<C>::value) { |
| 278 | pybind11_fail("Cannot move from a constant reference"); |
| 279 | } |
| 280 | |
| 281 | src = Helper::alloc(std::move(*src)); |
| 282 | |
| 283 | parent_object |
| 284 | = capsule(src, [](void *ptr) { Helper::free(reinterpret_cast<Type *>(ptr)); }); |
| 285 | writeable = true; |
| 286 | break; |
| 287 | |
| 288 | case return_value_policy::take_ownership: |
| 289 | if (std::is_const<C>::value) { |
| 290 | // This cast is ugly, and might be UB in some cases, but we don't have an |
| 291 | // alternative here as we must free that memory |
| 292 | Helper::free(const_cast<Type *>(src)); |
| 293 | pybind11_fail("Cannot take ownership of a const reference"); |
| 294 | } |
| 295 | |
| 296 | parent_object |
| 297 | = capsule(src, [](void *ptr) { Helper::free(reinterpret_cast<Type *>(ptr)); }); |
| 298 | writeable = true; |
| 299 | break; |
| 300 | |
| 301 | case return_value_policy::copy: |
| 302 | writeable = true; |
| 303 | break; |
| 304 | |
| 305 | case return_value_policy::reference: |
| 306 | parent_object = none(); |
| 307 | writeable = !std::is_const<C>::value; |
| 308 | break; |
| 309 | |
| 310 | case return_value_policy::reference_internal: |
| 311 | // Default should do the right thing |
| 312 | if (!parent) { |
| 313 | pybind11_fail("Cannot use reference internal when there is no parent"); |
| 314 | } |
| 315 | parent_object = reinterpret_borrow<object>(parent); |
| 316 | writeable = !std::is_const<C>::value; |
| 317 | break; |
| 318 | |
| 319 | default: |
| 320 | pybind11_fail("pybind11 bug in eigen.h, please file a bug report"); |
| 321 | } |
| 322 | |
| 323 | auto result = array_t<typename Type::Scalar, compute_array_flag_from_tensor<Type>()>( |
| 324 | convert_dsizes_to_vector(Helper::get_shape(*src)), src->data(), parent_object); |
| 325 | |
| 326 | if (!writeable) { |
| 327 | array_proxy(result.ptr())->flags &= ~detail::npy_api::NPY_ARRAY_WRITEABLE_; |
| 328 | } |
| 329 | |