LCOV - code coverage report
Current view: top level - python - element_array_view.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 50 54 92.6 %
Date: 2024-11-17 01:47:58 Functions: 48 178 27.0 %

          Line data    Source code
       1             : // SPDX-License-Identifier: BSD-3-Clause
       2             : // Copyright (c) 2023 Scipp contributors (https://github.com/scipp)
       3             : /// @file
       4             : /// @author Simon Heybrock
       5             : #include "scipp/core/element_array_view.h"
       6             : #include "scipp/core/array_to_string.h"
       7             : #include "scipp/core/dtype.h"
       8             : #include "scipp/core/eigen.h"
       9             : #include "scipp/core/except.h"
      10             : #include "scipp/dataset/dataset.h"
      11             : #include "scipp/dataset/except.h"
      12             : 
      13             : #include "pybind11.h"
      14             : 
      15             : #include "py_object.h"
      16             : 
      17             : using namespace scipp;
      18             : using namespace scipp::core;
      19             : 
      20             : namespace py = pybind11;
      21             : 
      22             : namespace {
      23             : template <class T> struct is_bins : std::false_type {};
      24             : template <class T> struct is_bins<core::bin<T>> : std::true_type {};
      25             : 
      26          78 : template <typename T> decltype(auto) to_python_object(T &&val) {
      27             :   if constexpr (std::is_same_v<std::remove_const_t<std::remove_reference_t<T>>,
      28             :                                scipp::python::PyObject>) {
      29           5 :     return std::forward<T>(val).to_pybind();
      30             :   } else {
      31          73 :     return std::forward<T>(val);
      32             :   }
      33             : }
      34             : } // namespace
      35             : 
      36             : template <class T>
      37          90 : void declare_ElementArrayView(py::module &m, const std::string &suffix) {
      38         180 :   py::class_<ElementArrayView<T>> view(
      39         180 :       m, (std::string("ElementArrayView_") + suffix).c_str());
      40          90 :   view.def(
      41             :           "__repr__",
      42           1 :           [](const ElementArrayView<T> &self) { return array_to_string(self); })
      43           0 :       .def(
      44             :           "__getitem__",
      45          78 :           [](const ElementArrayView<T> &self, const scipp::index i) {
      46          78 :             return to_python_object(self[i]);
      47             :           },
      48          90 :           py::return_value_policy::reference)
      49          90 :       .def("__len__", &ElementArrayView<T>::size)
      50         110 :       .def("__iter__", [](const ElementArrayView<T> &self) {
      51          20 :         return py::make_iterator(self.begin(), self.end());
      52             :       });
      53             :   if constexpr (std::is_same_v<std::remove_const_t<std::remove_reference_t<T>>,
      54             :                                scipp::python::PyObject>) {
      55           6 :     view.def("__setitem__", [](ElementArrayView<T> &self,
      56             :                                [[maybe_unused]] const scipp::index i,
      57             :                                [[maybe_unused]] const py::object &value) {
      58             :       if constexpr (is_bins<T>::value || std::is_const_v<T>)
      59           0 :         throw std::invalid_argument("assignment destination is read-only");
      60             :       else
      61           0 :         to_python_object(self[i]) = value;
      62             :     });
      63             :   } else {
      64         114 :     view.def("__setitem__", [](ElementArrayView<T> &self,
      65             :                                [[maybe_unused]] const scipp::index i,
      66             :                                [[maybe_unused]] const T &value) {
      67             :       if constexpr (is_bins<T>::value || std::is_const_v<T>)
      68           0 :         throw std::invalid_argument("assignment destination is read-only");
      69             :       else
      70          15 :         self[i] = value;
      71             :     });
      72             :   }
      73          90 : }
      74             : 
      75           3 : void init_element_array_view(py::module &m) {
      76           3 :   declare_ElementArrayView<double>(m, "double");
      77           3 :   declare_ElementArrayView<float>(m, "float");
      78           3 :   declare_ElementArrayView<int64_t>(m, "int64");
      79           3 :   declare_ElementArrayView<int32_t>(m, "int32");
      80           3 :   declare_ElementArrayView<std::string>(m, "string");
      81           3 :   declare_ElementArrayView<bool>(m, "bool");
      82           3 :   declare_ElementArrayView<Variable>(m, "Variable");
      83           3 :   declare_ElementArrayView<DataArray>(m, "DataArray");
      84           3 :   declare_ElementArrayView<Dataset>(m, "Dataset");
      85           3 :   declare_ElementArrayView<Eigen::Vector3d>(m, "Eigen_Vector3d");
      86           3 :   declare_ElementArrayView<Eigen::Matrix3d>(m, "Eigen_Matrix3d");
      87           3 :   declare_ElementArrayView<bucket<Variable>>(m, "bin_Variable");
      88           3 :   declare_ElementArrayView<bucket<DataArray>>(m, "bin_DataArray");
      89           3 :   declare_ElementArrayView<bucket<Dataset>>(m, "bin_Dataset");
      90           3 :   declare_ElementArrayView<scipp::python::PyObject>(m, "PyObject");
      91             : 
      92           3 :   declare_ElementArrayView<const double>(m, "double_const");
      93           3 :   declare_ElementArrayView<const float>(m, "float_const");
      94           3 :   declare_ElementArrayView<const int64_t>(m, "int64_const");
      95           3 :   declare_ElementArrayView<const int32_t>(m, "int32_const");
      96           3 :   declare_ElementArrayView<const std::string>(m, "string_const");
      97           3 :   declare_ElementArrayView<const bool>(m, "bool_const");
      98           3 :   declare_ElementArrayView<const Variable>(m, "Variable_const");
      99           3 :   declare_ElementArrayView<const DataArray>(m, "DataArray_const");
     100           3 :   declare_ElementArrayView<const Dataset>(m, "Dataset_const");
     101           3 :   declare_ElementArrayView<const Eigen::Vector3d>(m, "Eigen_Vector3d_const");
     102           3 :   declare_ElementArrayView<const Eigen::Matrix3d>(m, "Eigen_Matrix3d_const");
     103           3 :   declare_ElementArrayView<const bucket<Variable>>(m, "bin_Variable_const");
     104           3 :   declare_ElementArrayView<const bucket<DataArray>>(m, "bin_DataArray_const");
     105           3 :   declare_ElementArrayView<const bucket<Dataset>>(m, "bin_Dataset_const");
     106           3 :   declare_ElementArrayView<const scipp::python::PyObject>(m, "PyObject_const");
     107           3 : }

Generated by: LCOV version 1.14