xref: /aosp_15_r20/external/mesa3d/src/gallium/frontends/clover/util/adaptor.hpp (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 //
2 // Copyright 2013 Francisco Jerez
3 //
4 // Permission is hereby granted, free of charge, to any person obtaining a
5 // copy of this software and associated documentation files (the "Software"),
6 // to deal in the Software without restriction, including without limitation
7 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 // and/or sell copies of the Software, and to permit persons to whom the
9 // Software is furnished to do so, subject to the following conditions:
10 //
11 // The above copyright notice and this permission notice shall be included in
12 // all copies or substantial portions of the Software.
13 //
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 // OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 // OTHER DEALINGS IN THE SOFTWARE.
21 //
22 
23 #ifndef CLOVER_UTIL_ADAPTOR_HPP
24 #define CLOVER_UTIL_ADAPTOR_HPP
25 
26 #include <iterator>
27 
28 #include "util/compat.hpp"
29 #include "util/tuple.hpp"
30 #include "util/pointer.hpp"
31 #include "util/functional.hpp"
32 
33 namespace clover {
34    namespace detail {
35       ///
36       /// Implementation of the iterator concept that transforms the
37       /// value of the source iterators \a Is on dereference by use of
38       /// a functor \a F.
39       ///
40       /// The exact category of the resulting iterator should be the
41       /// least common denominator of the source iterator categories.
42       ///
43       template<typename F, typename... Is>
44       class iterator_adaptor {
45       public:
46          typedef std::forward_iterator_tag iterator_category;
47          typedef typename invoke_result<
48                F, typename std::iterator_traits<Is>::reference...
49             >::type reference;
50          typedef typename std::remove_reference<reference>::type value_type;
51          typedef pseudo_ptr<value_type> pointer;
52          typedef std::ptrdiff_t difference_type;
53 
iterator_adaptor()54          iterator_adaptor() {
55          }
56 
iterator_adaptor(F f,std::tuple<Is...> && its)57          iterator_adaptor(F f, std::tuple<Is...> &&its) :
58             f(f), its(std::move(its)) {
59          }
60 
61          reference
operator *() const62          operator*() const {
63             return tuple::apply(f, tuple::map(derefs(), its));
64          }
65 
66          iterator_adaptor &
operator ++()67          operator++() {
68             tuple::map(preincs(), its);
69             return *this;
70          }
71 
72          iterator_adaptor
operator ++(int)73          operator++(int) {
74             auto jt = *this;
75             ++*this;
76             return jt;
77          }
78 
79          bool
operator ==(const iterator_adaptor & jt) const80          operator==(const iterator_adaptor &jt) const {
81             return its == jt.its;
82          }
83 
84          bool
operator !=(const iterator_adaptor & jt) const85          operator!=(const iterator_adaptor &jt) const {
86             return its != jt.its;
87          }
88 
89          pointer
operator ->() const90          operator->() const {
91             return { **this };
92          }
93 
94          iterator_adaptor &
operator --()95          operator--() {
96             tuple::map(predecs(), its);
97             return *this;
98          }
99 
100          iterator_adaptor
operator --(int)101          operator--(int) {
102             auto jt = *this;
103             --*this;
104             return jt;
105          }
106 
107          iterator_adaptor &
operator +=(difference_type n)108          operator+=(difference_type n) {
109             tuple::map(advances_by(n), its);
110             return *this;
111          }
112 
113          iterator_adaptor &
operator -=(difference_type n)114          operator-=(difference_type n) {
115             tuple::map(advances_by(-n), its);
116             return *this;
117          }
118 
119          iterator_adaptor
operator +(difference_type n) const120          operator+(difference_type n) const {
121             auto jt = *this;
122             jt += n;
123             return jt;
124          }
125 
126          iterator_adaptor
operator -(difference_type n) const127          operator-(difference_type n) const {
128             auto jt = *this;
129             jt -= n;
130             return jt;
131          }
132 
133          difference_type
operator -(const iterator_adaptor & jt) const134          operator-(const iterator_adaptor &jt) const {
135             return std::get<0>(its) - std::get<0>(jt.its);
136          }
137 
138          reference
operator [](difference_type n) const139          operator[](difference_type n) const {
140             return *(*this + n);
141          }
142 
143          bool
operator <(iterator_adaptor & jt) const144          operator<(iterator_adaptor &jt) const {
145             return *this - jt < 0;
146          }
147 
148          bool
operator >(iterator_adaptor & jt) const149          operator>(iterator_adaptor &jt) const {
150             return *this - jt > 0;
151          }
152 
153          bool
operator >=(iterator_adaptor & jt) const154          operator>=(iterator_adaptor &jt) const {
155             return !(*this < jt);
156          }
157 
158          bool
operator <=(iterator_adaptor & jt) const159          operator<=(iterator_adaptor &jt) const {
160             return !(*this > jt);
161          }
162 
163       protected:
164          F f;
165          std::tuple<Is...> its;
166       };
167 
168       template<typename F, typename... Is>
169       iterator_adaptor<F, Is...>
operator +(typename iterator_adaptor<F,Is...>::difference_type n,const iterator_adaptor<F,Is...> & jt)170       operator+(typename iterator_adaptor<F, Is...>::difference_type n,
171                 const iterator_adaptor<F, Is...> &jt) {
172          return (jt + n);
173       }
174 
175       template<typename F, typename... Is>
176       iterator_adaptor<F, Is...>
operator -(typename iterator_adaptor<F,Is...>::difference_type n,const iterator_adaptor<F,Is...> & jt)177       operator-(typename iterator_adaptor<F, Is...>::difference_type n,
178                 const iterator_adaptor<F, Is...> &jt) {
179          return (jt - n);
180       }
181    }
182 }
183 
184 #endif
185