@@ -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