GCC Code Coverage Report | |||||||||||||||||||||
|
|||||||||||||||||||||
Line | Branch | Exec | Source |
1 |
/// |
||
2 |
/// Copyright (c) 2023-2024 CNRS INRIA |
||
3 |
/// |
||
4 |
|||
5 |
#ifndef __eigenpy_utils_std_array_hpp__ |
||
6 |
#define __eigenpy_utils_std_array_hpp__ |
||
7 |
|||
8 |
#include <boost/python/suite/indexing/indexing_suite.hpp> |
||
9 |
#include "eigenpy/std-vector.hpp" |
||
10 |
|||
11 |
#include <array> |
||
12 |
|||
13 |
namespace eigenpy { |
||
14 |
|||
15 |
template <typename Container, bool NoProxy, class SliceAllocator, |
||
16 |
class DerivedPolicies> |
||
17 |
class array_indexing_suite; |
||
18 |
namespace details { |
||
19 |
|||
20 |
template <typename Container, bool NoProxy, class SliceAllocator> |
||
21 |
class final_array_derived_policies |
||
22 |
: public array_indexing_suite< |
||
23 |
Container, NoProxy, SliceAllocator, |
||
24 |
final_array_derived_policies<Container, NoProxy, SliceAllocator> > {}; |
||
25 |
} // namespace details |
||
26 |
|||
27 |
template <typename Container, bool NoProxy = false, |
||
28 |
class SliceAllocator = std::allocator<typename Container::value_type>, |
||
29 |
class DerivedPolicies = details::final_array_derived_policies< |
||
30 |
Container, NoProxy, SliceAllocator> > |
||
31 |
class array_indexing_suite |
||
32 |
: public bp::vector_indexing_suite<Container, NoProxy, DerivedPolicies> { |
||
33 |
public: |
||
34 |
typedef typename Container::value_type data_type; |
||
35 |
typedef typename Container::value_type key_type; |
||
36 |
typedef typename Container::size_type index_type; |
||
37 |
typedef typename Container::size_type size_type; |
||
38 |
typedef typename Container::difference_type difference_type; |
||
39 |
typedef std::vector<data_type, SliceAllocator> slice_vector_type; |
||
40 |
static constexpr std::size_t Size = std::tuple_size<Container>{}; |
||
41 |
|||
42 |
template <class Class> |
||
43 |
12 |
static void extension_def(Class &) {} |
|
44 |
|||
45 |
// throws exception |
||
46 |
2 |
static void delete_item(Container &, index_type) { |
|
47 |
2 |
PyErr_SetString(PyExc_NotImplementedError, |
|
48 |
"Cannot delete item from std::array type."); |
||
49 |
2 |
bp::throw_error_already_set(); |
|
50 |
} |
||
51 |
|||
52 |
// throws exception |
||
53 |
4 |
static void delete_slice(Container &, index_type, index_type) { |
|
54 |
4 |
PyErr_SetString(PyExc_NotImplementedError, |
|
55 |
"Cannot delete slice from std::array type."); |
||
56 |
4 |
bp::throw_error_already_set(); |
|
57 |
} |
||
58 |
|||
59 |
2 |
static void set_slice(Container &container, index_type from, index_type to, |
|
60 |
data_type const &v) { |
||
61 |
✗✓ | 2 |
if (from >= to) { |
62 |
PyErr_SetString(PyExc_NotImplementedError, |
||
63 |
"Setting this slice would insert into an std::array, " |
||
64 |
"which is not supported."); |
||
65 |
bp::throw_error_already_set(); |
||
66 |
} else { |
||
67 |
2 |
std::fill(container.begin() + from, container.begin() + to, v); |
|
68 |
} |
||
69 |
} |
||
70 |
|||
71 |
template <class Iter> |
||
72 |
12 |
static void set_slice(Container &container, index_type from, index_type to, |
|
73 |
Iter first, Iter last) { |
||
74 |
✓✓ | 12 |
if (from >= to) { |
75 |
6 |
PyErr_SetString(PyExc_NotImplementedError, |
|
76 |
"Setting this slice would insert into an std::array, " |
||
77 |
"which is not supported."); |
||
78 |
6 |
bp::throw_error_already_set(); |
|
79 |
} else { |
||
80 |
✓✓ | 6 |
if (long(to - from) == std::distance(first, last)) { |
81 |
2 |
std::copy(first, last, container.begin() + from); |
|
82 |
} else { |
||
83 |
4 |
PyErr_SetString(PyExc_NotImplementedError, |
|
84 |
"Size of std::array slice and size of right-hand side " |
||
85 |
"iterator are incompatible."); |
||
86 |
4 |
bp::throw_error_already_set(); |
|
87 |
} |
||
88 |
} |
||
89 |
} |
||
90 |
|||
91 |
6 |
static bp::object get_slice(Container &container, index_type from, |
|
92 |
index_type to) { |
||
93 |
✗✓✗✗ ✗✗✗ |
6 |
if (from > to) return bp::object(slice_vector_type()); |
94 |
✗✗ | 12 |
slice_vector_type out; |
95 |
✓✓ | 22 |
for (size_t i = from; i < to; i++) { |
96 |
✓✗ | 16 |
out.push_back(container[i]); |
97 |
} |
||
98 |
✓✗ | 6 |
return bp::object(std::move(out)); |
99 |
} |
||
100 |
}; |
||
101 |
|||
102 |
/// \brief Expose an std::array (a C++11 fixed-size array) from a given type |
||
103 |
/// \tparam array_type std::array type to expose |
||
104 |
/// \tparam NoProxy When set to false, the elements will be copied when |
||
105 |
/// returned to Python. |
||
106 |
/// \tparam SliceAllocator Allocator type to use for slices of std::array type |
||
107 |
/// accessed using e.g. __getitem__[0:4] in Python. These slices are returned as |
||
108 |
/// std::vector (dynamic size). |
||
109 |
template <typename array_type, bool NoProxy = false, |
||
110 |
class SliceAllocator = |
||
111 |
std::allocator<typename array_type::value_type> > |
||
112 |
struct StdArrayPythonVisitor { |
||
113 |
typedef typename array_type::value_type value_type; |
||
114 |
|||
115 |
4 |
static ::boost::python::list tolist(array_type &self, const bool deep_copy) { |
|
116 |
4 |
return details::build_list<array_type, NoProxy>::run(self, deep_copy); |
|
117 |
} |
||
118 |
|||
119 |
2 |
static void expose(const std::string &class_name, |
|
120 |
const std::string &doc_string = "") { |
||
121 |
✓✗ | 2 |
expose(class_name, doc_string, EmptyPythonVisitor()); |
122 |
2 |
} |
|
123 |
|||
124 |
template <typename DerivedVisitor> |
||
125 |
8 |
static void expose(const std::string &class_name, |
|
126 |
const bp::def_visitor<DerivedVisitor> &visitor) { |
||
127 |
✓✗✓✗ |
8 |
expose(class_name, "", visitor); |
128 |
8 |
} |
|
129 |
|||
130 |
template <typename DerivedVisitor> |
||
131 |
12 |
static void expose(const std::string &class_name, |
|
132 |
const std::string &doc_string, |
||
133 |
const bp::def_visitor<DerivedVisitor> &visitor) { |
||
134 |
✓✗ | 12 |
if (!register_symbolic_link_to_registered_type<array_type>()) { |
135 |
✓✗ | 12 |
bp::class_<array_type> cl(class_name.c_str(), doc_string.c_str()); |
136 |
✓✗✓✗ ✓✗ |
12 |
cl.def(bp::init<const array_type &>(bp::args("self", "other"), |
137 |
"Copy constructor")); |
||
138 |
|||
139 |
array_indexing_suite<array_type, NoProxy, SliceAllocator> indexing_suite; |
||
140 |
✓✗ | 24 |
cl.def(indexing_suite) |
141 |
✓✗ | 12 |
.def(visitor) |
142 |
✓✗✓✗ |
12 |
.def("tolist", tolist, |
143 |
✓✗✓✗ ✓✗ |
24 |
(bp::arg("self"), bp::arg("deep_copy") = false), |
144 |
"Returns the std::array as a Python list."); |
||
145 |
} |
||
146 |
12 |
} |
|
147 |
}; |
||
148 |
|||
149 |
/// Exposes std::array<MatrixType, Size> |
||
150 |
template <typename MatrixType, std::size_t Size> |
||
151 |
8 |
void exposeStdArrayEigenSpecificType(const char *name) { |
|
152 |
✓✗ | 8 |
std::ostringstream oss; |
153 |
✓✗ | 8 |
oss << "StdArr"; |
154 |
✓✗✓✗ ✓✗ |
8 |
oss << Size << "_" << name; |
155 |
typedef std::array<MatrixType, Size> array_type; |
||
156 |
StdArrayPythonVisitor<array_type, false, |
||
157 |
Eigen::aligned_allocator<MatrixType> >:: |
||
158 |
✓✗✓✗ |
8 |
expose(oss.str(), |
159 |
details::overload_base_get_item_for_std_vector<array_type>()); |
||
160 |
8 |
} |
|
161 |
|||
162 |
} // namespace eigenpy |
||
163 |
|||
164 |
#endif // ifndef __eigenpy_utils_std_array_hpp__ |
Generated by: GCOVR (Version 4.2) |