• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2015 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef ART_LIBARTBASE_BASE_STRIDE_ITERATOR_H_
18 #define ART_LIBARTBASE_BASE_STRIDE_ITERATOR_H_
19 
20 #include <iterator>
21 
22 #include <android-base/logging.h>
23 
24 namespace art {
25 
26 template <typename T>
27 class StrideIterator {
28  public:
29   using iterator_category = std::random_access_iterator_tag;
30   using value_type = T;
31   using difference_type = ptrdiff_t;
32   using pointer = value_type*;
33   using reference = value_type&;
34 
35   StrideIterator(const StrideIterator&) = default;
36   StrideIterator(StrideIterator&&) noexcept = default;
37   StrideIterator& operator=(const StrideIterator&) = default;
38   StrideIterator& operator=(StrideIterator&&) noexcept = default;
39 
StrideIterator(T * ptr,size_t stride)40   StrideIterator(T* ptr, size_t stride)
41       : ptr_(reinterpret_cast<uintptr_t>(ptr)),
42         stride_(stride) {}
43 
44   bool operator==(const StrideIterator& other) const {
45     DCHECK_EQ(stride_, other.stride_);
46     return ptr_ == other.ptr_;
47   }
48 
49   bool operator!=(const StrideIterator& other) const {
50     return !(*this == other);
51   }
52 
53   StrideIterator& operator++() {  // Value after modification.
54     ptr_ += stride_;
55     return *this;
56   }
57 
58   StrideIterator operator++(int) {
59     StrideIterator<T> temp = *this;
60     ++*this;
61     return temp;
62   }
63 
64   StrideIterator& operator--() {  // Value after modification.
65     ptr_ -= stride_;
66     return *this;
67   }
68 
69   StrideIterator operator--(int) {
70     StrideIterator<T> temp = *this;
71     --*this;
72     return temp;
73   }
74 
75   StrideIterator& operator+=(difference_type delta) {
76     ptr_ += static_cast<ssize_t>(stride_) * delta;
77     return *this;
78   }
79 
80   StrideIterator operator+(difference_type delta) const {
81     StrideIterator<T> temp = *this;
82     temp += delta;
83     return temp;
84   }
85 
86   StrideIterator& operator-=(difference_type delta) {
87     ptr_ -= static_cast<ssize_t>(stride_) * delta;
88     return *this;
89   }
90 
91   StrideIterator operator-(difference_type delta) const {
92     StrideIterator<T> temp = *this;
93     temp -= delta;
94     return temp;
95   }
96 
97   difference_type operator-(const StrideIterator& rhs) {
98     DCHECK_EQ(stride_, rhs.stride_);
99     DCHECK_EQ((ptr_ - rhs.ptr_) % stride_, 0u);
100     return (ptr_ - rhs.ptr_) / stride_;
101   }
102 
103   T& operator*() const {
104     return *reinterpret_cast<T*>(ptr_);
105   }
106 
107   T* operator->() const {
108     return &**this;
109   }
110 
111   T& operator[](difference_type n) {
112     return *(*this + n);
113   }
114 
115  private:
116   uintptr_t ptr_;
117   // Not const for operator=.
118   size_t stride_;
119 
120   template <typename U>
121   friend bool operator<(const StrideIterator<U>& lhs, const StrideIterator<U>& rhs);
122 };
123 
124 template <typename T>
125 StrideIterator<T> operator+(typename StrideIterator<T>::difference_type dist,
126                             const StrideIterator<T>& it) {
127   return it + dist;
128 }
129 
130 template <typename T>
131 bool operator<(const StrideIterator<T>& lhs, const StrideIterator<T>& rhs) {
132   DCHECK_EQ(lhs.stride_, rhs.stride_);
133   return lhs.ptr_ < rhs.ptr_;
134 }
135 
136 template <typename T>
137 bool operator>(const StrideIterator<T>& lhs, const StrideIterator<T>& rhs) {
138   return rhs < lhs;
139 }
140 
141 template <typename T>
142 bool operator<=(const StrideIterator<T>& lhs, const StrideIterator<T>& rhs) {
143   return !(rhs < lhs);
144 }
145 
146 template <typename T>
147 bool operator>=(const StrideIterator<T>& lhs, const StrideIterator<T>& rhs) {
148   return !(lhs < rhs);
149 }
150 
151 }  // namespace art
152 
153 #endif  // ART_LIBARTBASE_BASE_STRIDE_ITERATOR_H_
154