Loading...
Searching...
No Matches
python.h
Go to the documentation of this file.
1#if defined(BBM_PYTHON) && !defined(_BBM_NATIVE_PYTHON_H_)
2#define _BBM_NATIVE_PYTHON_H_
3
4#include <iostream>
5
6#include <pybind11/numpy.h>
7#include "backbone/array.h"
8
9namespace pybind11 {
10 namespace detail {
11
12 template<typename ARR>
13 struct type_caster<ARR, std::enable_if_t<backbone::is_array_v<ARR>>>
14 {
15 using array_type = std::decay_t<ARR>;
16 using value_type = typename array_type::value_type;
17 public:
18
19 bool load(handle src, bool convert)
20 {
21 // check if py object == none
22 if(src.is_none())
23 {
24 is_none = true;
25 return true;
26 }
27
28 // if not convert, check type matches
29 if(!isinstance<array_t<array_type>>(src) && !convert) return false;
30
31 // setup interpretation of the array
32 array arr = reinterpret_borrow<array>(src);
33 arr = array_t<value_type, array::c_style>::ensure(arr);
34 if(!arr) return false;
35
36 // check shape of array
37 if(arr.ndim() != 1 && convert) return false;
38 if(arr.shape()[0] != value.size()) return false;
39
40 // copy data
41 const value_type* buf = static_cast<const value_type*>(arr.data());
42 for(size_t i=0; i < value.size(); ++i)
43 value[i] = buf[i];
44
45 return true;
46 }
47
48 static handle cast(const array_type* src, return_value_policy policy, handle parent)
49 {
50 if(!src) return pybind11::none();
51 return cast(*src, policy, parent);
52 }
53
54 static handle cast(const array_type& src, return_value_policy /*policy*/, handle /*parent*/)
55 {
56 std::array<size_t, 1> shape{src.size()};
57 std::array<size_t, 1> stride{sizeof(value_type)};
58
59 array arr(pybind11::dtype::of<value_type>(),
60 std::vector<ssize_t>(shape.begin(), shape.end()),
61 std::vector<ssize_t>(stride.begin(), stride.end()));
62
63 value_type* buf = static_cast<value_type*>(arr.mutable_data());
64 for(size_t i=0; i < src.size(); ++i)
65 buf[i] = src[i];
66
67 return arr.release();
68 }
69
70 template<typename T> using cast_op_type = pybind11::detail::cast_op_type<T>;
71
72 static constexpr auto name = _("numpy.ndarray[dtype=") + npy_format_descriptor<value_type>::name + _("], shape=(") + _<backbone::array_size<array_type>>() + _(")");
73
74 operator array_type*() { if (is_none) return nullptr; else return &value; }
75 operator array_type&() { if (is_none) throw pybind11::cast_error("Cannot cast None or nullptr to an backbone::array."); return value; }
76
77 private:
78 array_type value;
79 bool is_none = false;
80 };
81
82 } // end detail namespace
83} // end pybind11 namespace
84
85
86#endif /* _BBM_NATIVE_PYTHON_H_ */
NEWTYPE cast(OLDTYPE &&val)
cast
Definition: control.h:27
decltype(auto) value(T &&t)
return the value of an attribute, or if not an attribute the object
Definition: attribute_value.h:20
Definition: named.h:325