@@ -75,21 +75,183 @@ namespace pybind11
7575namespace xt
7676{
7777
78+ /* *************************
79+ * pybackstrides_iterator *
80+ **************************/
81+
82+ template <class B >
83+ class pybackstrides_iterator
84+ {
85+ public:
86+
87+ using self_type = pybackstrides_iterator<B>;
88+
89+ using value_type = typename B::value_type;
90+ using pointer = const value_type*;
91+ using reference = value_type;
92+ using difference_type = std::ptrdiff_t ;
93+ using iterator_category = std::random_access_iterator_tag;
94+
95+ inline pybackstrides_iterator (const B* b, std::size_t offset)
96+ : p_b(b), m_offset(offset)
97+ {
98+ }
99+
100+ inline reference operator *() const
101+ {
102+ return p_b->operator [](m_offset);
103+ }
104+
105+ inline pointer operator ->() const
106+ {
107+ // Returning the address of a temporary
108+ value_type res = p_b->operator [](m_offset);
109+ return &res;
110+ }
111+
112+ inline reference operator [](difference_type n) const
113+ {
114+ return p_b->operator [](m_offset + n);
115+ }
116+
117+ inline self_type& operator ++()
118+ {
119+ ++m_offset;
120+ return *this ;
121+ }
122+
123+ inline self_type& operator --()
124+ {
125+ --m_offset;
126+ return *this ;
127+ }
128+
129+ inline self_type operator ++(int )
130+ {
131+ self_type tmp (*this );
132+ ++m_offset;
133+ return tmp;
134+ }
135+
136+ inline self_type operator --(int )
137+ {
138+ self_type tmp (*this );
139+ --m_offset;
140+ return tmp;
141+ }
142+
143+ inline self_type& operator +=(difference_type n)
144+ {
145+ m_offset += n;
146+ return *this ;
147+ }
148+
149+ inline self_type& operator -=(difference_type n)
150+ {
151+ m_offset -= n;
152+ return *this ;
153+ }
154+
155+ inline self_type operator +(difference_type n) const
156+ {
157+ return self_type (p_b, m_offset + n);
158+ }
159+
160+ inline self_type operator -(difference_type n) const
161+ {
162+ return self_type (p_b, m_offset - n);
163+ }
164+
165+ inline self_type operator -(const self_type& rhs) const
166+ {
167+ self_type tmp (*this );
168+ tmp -= (m_offset - rhs.m_offset );
169+ return tmp;
170+ }
171+
172+ inline std::size_t offset () const
173+ {
174+ return m_offset;
175+ }
176+
177+ private:
178+
179+ const B* p_b;
180+ std::size_t m_offset;
181+ };
182+
183+ template <class B >
184+ inline bool operator ==(const pybackstrides_iterator<B>& lhs,
185+ const pybackstrides_iterator<B>& rhs)
186+ {
187+ return lhs.offset () == rhs.offset ();
188+ }
189+
190+ template <class B >
191+ inline bool operator !=(const pybackstrides_iterator<B>& lhs,
192+ const pybackstrides_iterator<B>& rhs)
193+ {
194+ return !(lhs == rhs);
195+ }
196+
197+ template <class B >
198+ inline bool operator <(const pybackstrides_iterator<B>& lhs,
199+ const pybackstrides_iterator<B>& rhs)
200+ {
201+ return lhs.offset () < rhs.offset ();
202+ }
203+
204+ template <class B >
205+ inline bool operator <=(const pybackstrides_iterator<B>& lhs,
206+ const pybackstrides_iterator<B>& rhs)
207+ {
208+ return (lhs < rhs) || (lhs == rhs);
209+ }
210+
211+ template <class B >
212+ inline bool operator >(const pybackstrides_iterator<B>& lhs,
213+ const pybackstrides_iterator<B>& rhs)
214+ {
215+ return !(lhs <= rhs);
216+ }
217+
218+ template <class B >
219+ inline bool operator >=(const pybackstrides_iterator<B>& lhs,
220+ const pybackstrides_iterator<B>& rhs)
221+ {
222+ return !(lhs < rhs);
223+ }
224+
78225 template <class A >
79226 class pyarray_backstrides
80227 {
81228 public:
82229
230+ using self_type = pyarray_backstrides<A>;
83231 using array_type = A;
84232 using value_type = typename array_type::size_type;
233+ using const_reference = value_type;
234+ using const_pointer = const value_type*;
85235 using size_type = typename array_type::size_type;
236+ using difference_type = typename array_type::difference_type;
237+
238+ using const_iterator = pybackstrides_iterator<self_type>;
86239
87240 pyarray_backstrides () = default ;
88241 pyarray_backstrides (const array_type& a);
89242
243+ bool empty () const ;
244+ size_type size () const ;
245+
90246 value_type operator [](size_type i) const ;
91247
92- size_type size () const ;
248+ const_reference front () const ;
249+ const_reference back () const ;
250+
251+ const_iterator begin () const ;
252+ const_iterator end () const ;
253+ const_iterator cbegin () const ;
254+ const_iterator cend () const ;
93255
94256 private:
95257
@@ -213,6 +375,12 @@ namespace xt
213375 {
214376 }
215377
378+ template <class A >
379+ inline bool pyarray_backstrides<A>::empty() const
380+ {
381+ return p_a->dimension () == 0 ;
382+ }
383+
216384 template <class A >
217385 inline auto pyarray_backstrides<A>::size() const -> size_type
218386 {
@@ -227,6 +395,47 @@ namespace xt
227395 return res;
228396 }
229397
398+ template <class A >
399+ inline auto pyarray_backstrides<A>::front() const -> const_reference
400+ {
401+ value_type sh = p_a->shape ()[0 ];
402+ value_type res = sh == 1 ? 0 : (sh - 1 ) * p_a->strides ()[0 ];
403+ return res;
404+ }
405+
406+ template <class A >
407+ inline auto pyarray_backstrides<A>::back() const -> const_reference
408+ {
409+ auto index = p_a->size () - 1 ;
410+ value_type sh = p_a->shape ()[index];
411+ value_type res = sh == 1 ? 0 : (sh - 1 ) * p_a->strides ()[index];
412+ return res;
413+ }
414+
415+ template <class A >
416+ inline auto pyarray_backstrides<A>::begin() const -> const_iterator
417+ {
418+ return cbegin ();
419+ }
420+
421+ template <class A >
422+ inline auto pyarray_backstrides<A>::end() const -> const_iterator
423+ {
424+ return cend ();
425+ }
426+
427+ template <class A >
428+ inline auto pyarray_backstrides<A>::cbegin() const -> const_iterator
429+ {
430+ const_iterator (this , 0 );
431+ }
432+
433+ template <class A >
434+ inline auto pyarray_backstrides<A>::cend() const -> const_iterator
435+ {
436+ const_iterator (this , size ());
437+ }
438+
230439 /* *************************
231440 * pyarray implementation *
232441 **************************/
0 commit comments