Skip to content

Commit b86826d

Browse files
committed
strides adaptor
1 parent c9aca87 commit b86826d

File tree

1 file changed

+193
-0
lines changed

1 file changed

+193
-0
lines changed

include/xtensor-python/pybuffer_adaptor.hpp

Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,45 @@ namespace xt
6060
size_type m_size;
6161
};
6262

63+
template <std::size_t N>
64+
class pystrides_iterator;
65+
66+
template <std::size_t N>
67+
class pystrides_adaptor
68+
{
69+
70+
public:
71+
72+
using value_type = std::size_t;
73+
using const_reference = value_type;
74+
using const_pointer = const value_type*;
75+
using size_type = std::size_t;
76+
using difference_type = std::ptrdiff_t;
77+
78+
using const_iterator = pystrides_iterator<N>;
79+
80+
pystrides_adaptor() = default;
81+
pystrides_adaptor(const_pointer data, size_type size);
82+
83+
bool empty() const noexcept;
84+
size_type size() const noexcept;
85+
86+
const_reference operator[](size_type i) const;
87+
88+
const_reference front() const;
89+
const_reference back() const;
90+
91+
const_iterator begin() const;
92+
const_iterator end() const;
93+
const_iterator cbegin() const;
94+
const_iterator cend() const;
95+
96+
private:
97+
98+
const_pointer p_data;
99+
size_type m_size;
100+
};
101+
63102
/***********************************
64103
* pybuffer_adaptor implementation *
65104
***********************************/
@@ -153,6 +192,160 @@ namespace xt
153192
{
154193
return end();
155194
}
195+
196+
/*************************************
197+
* pystrides_iterator implementation *
198+
*************************************/
199+
200+
template <std::size_t N>
201+
class pystrides_iterator
202+
{
203+
204+
public:
205+
206+
using self_type = pystrides_adaptor<N>;
207+
208+
using value_type = typename pystrides_adaptor<N>::value_type;
209+
using pointer = typename pystrides_adaptor<N>::const_pointer;
210+
using reference = typename pystrides_adaptor<N>::const_reference;
211+
using difference_type = typename pystrides_adaptor<N>::difference_type;
212+
using iterator_category = std::random_access_iterator;
213+
214+
inline pystrides_iterator(pointer current)
215+
: p_current(current)
216+
{
217+
}
218+
219+
inline reference operator*() const { return *p_current / N; }
220+
inline pointer operator->() const { return p_current; }
221+
222+
inline reference operator[](difference_type n) { return *(p_current + n) / N; }
223+
224+
inline self_type& operator++() { ++p_current; return *this; }
225+
inline self_type& operator--() { --p_current; return *this; }
226+
227+
inline self_type operator++(int) { self_type tmp(*this); ++p_current; return tmp; }
228+
inline self_type operator--(int) { self_type tmp(*this); --p_current; return tmp; }
229+
230+
inline self_type& operator+=(difference_type n) { p_current += n; return *this; }
231+
inline self_type& operator-=(difference_type n) { p_current -= n; return *this; }
232+
233+
inline self_type operator+(difference_type n) const { return self_type(p_current + n); }
234+
inline self_type operator-(difference_type n) const { return self_type(p_current - n); }
235+
236+
pointer get_pointer() const { return p_current; }
237+
238+
private:
239+
240+
pointer p_current;
241+
};
242+
243+
template <std::size_t N>
244+
inline bool operator==(const pystrides_iterator<N>& lhs,
245+
const pystrides_iterator<N>& rhs)
246+
{
247+
return lhs.get_pointer() == rhs.get_pointer();
248+
}
249+
250+
template <std::size_t N>
251+
inline bool operator!=(const pystrides_iterator<N>& lhs,
252+
const pystrides_iterator<N>& rhs)
253+
{
254+
return !(lhs == rhs);
255+
}
256+
257+
template <std::size_t N>
258+
inline bool operator<(const pystrides_iterator<N>& lhs,
259+
const pystrides_iterator<N>& rhs)
260+
{
261+
return lhs.get_pointer() < rhs.get_pointer();
262+
}
263+
264+
template <std::size_t N>
265+
inline bool operator<=(const pystrides_iterator<N>& lhs,
266+
const pystrides_iterator<N>& rhs)
267+
{
268+
return (lhs < rhs) || (lhs == rhs);
269+
}
270+
271+
template <std::size_t N>
272+
inline bool operator>(const pystrides_iterator<N>& lhs,
273+
const pystrides_iterator<N>& rhs)
274+
{
275+
return !(lhs <= rhs);
276+
}
277+
278+
template <std::size_t N>
279+
inline bool operator>=(const pystrides_iterator<N>& lhs,
280+
const pystrides_iterator<N>& rhs)
281+
{
282+
return !(lhs < rhs);
283+
}
284+
285+
/************************************
286+
* pystrides_adaptor implementation *
287+
************************************/
288+
289+
template <std::size_t N>
290+
inline pystrides_adaptor<N>::pystrides_adaptor(const_pointer data, size_type size)
291+
: p_data(data), m_size(size)
292+
{
293+
}
294+
295+
template <std::size_t N>
296+
inline bool pystrides_adaptor<N>::empty() const noexcept
297+
{
298+
return m_size == 0;
299+
}
300+
301+
template <std::size_t N>
302+
inline auto pystrides_adaptor<N>::size() const noexcept -> size_type
303+
{
304+
return m_size;
305+
}
306+
307+
template <std::size_t N>
308+
inline auto pystrides_adaptor<N>::operator[](size_type i) const -> const_reference
309+
{
310+
return p_data[i] / N;
311+
}
312+
313+
template <std::size_t N>
314+
inline auto pystrides_adaptor<N>::front() const -> const_reference
315+
{
316+
return p_data[0] / N;
317+
}
318+
319+
template <std::size_t N>
320+
inline auto pystrides_adaptor<N>::back() const -> const_reference
321+
{
322+
return p_data[m_size - 1] / N;
323+
}
324+
325+
template <std::size_t N>
326+
inline auto pystrides_adaptor<N>::begin() const -> const_iterator
327+
{
328+
return const_iterator(p_data);
329+
}
330+
331+
template <std::size_t N>
332+
inline auto pystrides_adaptor<N>::end() const -> const_iterator
333+
{
334+
return const_iterator(p_data + m_size);
335+
}
336+
337+
template <std::size_t N>
338+
inline auto pystrides_adaptor<N>::cbegin() const -> const_iterator
339+
{
340+
return begin();
341+
}
342+
343+
template <std::size_t N>
344+
inline auto pystrides_adaptor<N>::cend() const -> const_iterator
345+
{
346+
return end();
347+
}
348+
156349
}
157350

158351
#endif

0 commit comments

Comments
 (0)