4#include "pybind11/numpy.h"
22 template<
typename TARGET>
26 static inline TARGET
cast(T&& t)
30 if constexpr (
requires(T&& t) {{py::cast<TARGET>(std::forward<T>(t))};})
return py::cast<TARGET>(std::forward<T>(t));
31 else throw std::runtime_error(
"BBM: casting error");
35 throw std::runtime_error(std::string(
"BBM: do not know how to cast to ") + std::string(bbm::typestring<TARGET>) +
".");
47 static inline TARGET
cast(T&& t)
57 struct py_cast<TARGET>
63 static void from_const(T& result,
const scalar_t<TARGET>& val)
65 if constexpr (std::same_as<value_t<T>, std::decay_t<T>>) result = val;
66 else for(
auto& r : result) from_const(r, val);
70 template<
typename T,
typename... Idx>
71 static void from_py_array(T& result,
const py::array_t<scalar_t<TARGET>>& parr, Idx... idx)
74 if constexpr (std::same_as<value_t<T>, std::decay_t<T>>)
77 if((
sizeof...(Idx) == parr.ndim()))
return from_const(result, parr.at(idx...));
80 size_t size = parr.shape()[
sizeof...(Idx)];
81 if(
sizeof...(Idx)+1 == parr.ndim() &&
size == 1)
return from_const(result, parr.at(idx..., 0));
94 size_t size = parr.shape()[
sizeof...(Idx)];
98 for(
size_t current_idx = 0; current_idx !=
bbm::size(result); ++current_idx)
101 if(parr.ndim() ==
sizeof...(Idx)+1) from_const(
value(*std::next(
bbm::begin(result), current_idx)), parr.at(idx..., current_idx));
104 else from_py_array(
value(*std::next(
bbm::begin(result), current_idx)), parr, idx..., current_idx);
113 static inline TARGET
cast(T&& t)
118 return py::cast<TARGET>(std::forward<T>(t));
123 if constexpr (std::constructible_from<TARGET, scalar_t<TARGET>>)
124 return TARGET(
py_cast<scalar_t<TARGET>>::cast(std::forward<T>(t)) );
128 auto parr = py::cast<py::array_t<scalar_t<TARGET>>>(std::forward<T>(t));
130 from_py_array(result, parr);
Helper methods for extracting the value of an attribute (according to concepts::attribute).
attribute concept
Definition: attribute.h:39
#define bbm_size_error
Definition: error.h:45
Definition: aggregatebsdf.h:29
size_t size(T &&t)
Definition: iterator_util.h:22
auto begin(T &&t)
Definition: iterator_util.h:29
decltype(auto) value(T &&t)
return the value of an attribute, or if not an attribute the object
Definition: attribute_value.h:20
static void from_const(T &result, const scalar_t< TARGET > &val)
copy constant values (val) in 'result'
Definition: py_cast.h:63
static TARGET cast(T &&t)
Definition: py_cast.h:47
static void from_py_array(T &result, const py::array_t< scalar_t< TARGET > > &parr, Idx... idx)
recusively copy values from the sub-array at partial indices [idx...] to result
Definition: py_cast.h:71
Default casting.
Definition: py_cast.h:24
static TARGET cast(T &&t)
Definition: py_cast.h:26
produce stringview of type name of a type. Avoids using typeid for GCC, MSVC, and CLANG....