xref: /oneTBB/test/common/iterator.h (revision 478de5b1)
151c0b2f7Stbbdev /*
2b15aabb3Stbbdev     Copyright (c) 2005-2021 Intel Corporation
351c0b2f7Stbbdev 
451c0b2f7Stbbdev     Licensed under the Apache License, Version 2.0 (the "License");
551c0b2f7Stbbdev     you may not use this file except in compliance with the License.
651c0b2f7Stbbdev     You may obtain a copy of the License at
751c0b2f7Stbbdev 
851c0b2f7Stbbdev         http://www.apache.org/licenses/LICENSE-2.0
951c0b2f7Stbbdev 
1051c0b2f7Stbbdev     Unless required by applicable law or agreed to in writing, software
1151c0b2f7Stbbdev     distributed under the License is distributed on an "AS IS" BASIS,
1251c0b2f7Stbbdev     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1351c0b2f7Stbbdev     See the License for the specific language governing permissions and
1451c0b2f7Stbbdev     limitations under the License.
1551c0b2f7Stbbdev */
1651c0b2f7Stbbdev 
1751c0b2f7Stbbdev #ifndef __TBB_test_common_iterator_H
1851c0b2f7Stbbdev #define __TBB_test_common_iterator_H
1951c0b2f7Stbbdev 
20*478de5b1Stbbdev #include "config.h"
21*478de5b1Stbbdev 
2251c0b2f7Stbbdev #include <iterator>
2351c0b2f7Stbbdev #include <memory>
2451c0b2f7Stbbdev #include <atomic>
2551c0b2f7Stbbdev #include "utils_assert.h"
2651c0b2f7Stbbdev 
2751c0b2f7Stbbdev namespace utils {
2851c0b2f7Stbbdev 
2951c0b2f7Stbbdev template <typename T>
3051c0b2f7Stbbdev class InputIterator {
31*478de5b1Stbbdev     typedef std::allocator<T> allocator_type;
32*478de5b1Stbbdev     typedef std::allocator_traits<allocator_type> allocator_traits_type;
3351c0b2f7Stbbdev public:
3451c0b2f7Stbbdev     typedef std::input_iterator_tag iterator_category;
3551c0b2f7Stbbdev     typedef T value_type;
36*478de5b1Stbbdev     typedef typename allocator_traits_type::difference_type difference_type;
37*478de5b1Stbbdev     typedef typename allocator_traits_type::pointer pointer;
38*478de5b1Stbbdev     typedef typename allocator_traits_type::value_type& reference;
3951c0b2f7Stbbdev 
InputIterator()40*478de5b1Stbbdev     InputIterator() : my_ptr(nullptr) {}
InputIterator(T * ptr)4151c0b2f7Stbbdev     explicit InputIterator ( T * ptr ) : my_ptr(ptr), my_shared_epoch(new Epoch), my_current_epoch(0) {}
4251c0b2f7Stbbdev 
InputIterator(const InputIterator & it)4351c0b2f7Stbbdev     InputIterator( const InputIterator& it ) {
4451c0b2f7Stbbdev         REQUIRE_MESSAGE(it.my_current_epoch == it.my_shared_epoch->epoch, "Copying an invalidated iterator");
4551c0b2f7Stbbdev         my_ptr = it.my_ptr;
4651c0b2f7Stbbdev         my_shared_epoch = it.my_shared_epoch;
4751c0b2f7Stbbdev         my_current_epoch = it.my_current_epoch;
4851c0b2f7Stbbdev         ++my_shared_epoch->refcounter;
4951c0b2f7Stbbdev     }
5051c0b2f7Stbbdev 
5151c0b2f7Stbbdev     InputIterator& operator= ( const InputIterator& it ) {
5251c0b2f7Stbbdev         REQUIRE_MESSAGE(it.my_current_epoch == it.my_shared_epoch->epoch, "Assigning an invalidated iterator");
5351c0b2f7Stbbdev         my_ptr = it.my_ptr;
5451c0b2f7Stbbdev         my_current_epoch = it.my_current_epoch;
5551c0b2f7Stbbdev         if(my_shared_epoch == it.my_shared_epoch)
5651c0b2f7Stbbdev             return *this;
5751c0b2f7Stbbdev         destroy();
5851c0b2f7Stbbdev         my_shared_epoch = it.my_shared_epoch;
5951c0b2f7Stbbdev         ++my_shared_epoch->refcounter;
6051c0b2f7Stbbdev         return *this;
6151c0b2f7Stbbdev     }
6251c0b2f7Stbbdev 
6351c0b2f7Stbbdev     T& operator* () const {
6451c0b2f7Stbbdev         REQUIRE_MESSAGE(my_shared_epoch->epoch == my_current_epoch, "Dereferencing an invalidated input iterator");
6551c0b2f7Stbbdev         return *my_ptr;
6651c0b2f7Stbbdev     }
6751c0b2f7Stbbdev 
6851c0b2f7Stbbdev     InputIterator& operator++ () {
6951c0b2f7Stbbdev         REQUIRE_MESSAGE(my_shared_epoch->epoch == my_current_epoch, "Incrementing an invalidated input iterator");
7051c0b2f7Stbbdev         ++my_ptr;
7151c0b2f7Stbbdev         ++my_current_epoch;
7251c0b2f7Stbbdev         ++my_shared_epoch->epoch;
7351c0b2f7Stbbdev         return *this;
7451c0b2f7Stbbdev     }
7551c0b2f7Stbbdev 
76*478de5b1Stbbdev     InputIterator operator++( int ) {
77*478de5b1Stbbdev         InputIterator it = *this;
78*478de5b1Stbbdev         ++*this;
79*478de5b1Stbbdev         return it;
80*478de5b1Stbbdev     }
81*478de5b1Stbbdev 
8251c0b2f7Stbbdev     bool operator== ( const InputIterator& it ) const {
8351c0b2f7Stbbdev         REQUIRE_MESSAGE(my_shared_epoch->epoch == my_current_epoch, "Comparing an invalidated input iterator");
8451c0b2f7Stbbdev         REQUIRE_MESSAGE(it.my_shared_epoch->epoch == it.my_current_epoch, "Comparing with an invalidated input iterator");
8551c0b2f7Stbbdev         return my_ptr == it.my_ptr;
8651c0b2f7Stbbdev     }
8751c0b2f7Stbbdev 
~InputIterator()8851c0b2f7Stbbdev     ~InputIterator() {
8951c0b2f7Stbbdev         destroy();
9051c0b2f7Stbbdev     }
9151c0b2f7Stbbdev private:
destroy()9251c0b2f7Stbbdev     void destroy() {
9351c0b2f7Stbbdev         if(0 == --my_shared_epoch->refcounter) {
9451c0b2f7Stbbdev             delete my_shared_epoch;
9551c0b2f7Stbbdev         }
9651c0b2f7Stbbdev     }
9751c0b2f7Stbbdev     struct Epoch {
9851c0b2f7Stbbdev         typedef std::atomic<size_t> Counter;
EpochEpoch9951c0b2f7Stbbdev         Epoch() { epoch = 0; refcounter = 1; }
10051c0b2f7Stbbdev         Counter epoch;
10151c0b2f7Stbbdev         Counter refcounter;
10251c0b2f7Stbbdev     };
10351c0b2f7Stbbdev 
10451c0b2f7Stbbdev     T * my_ptr;
10551c0b2f7Stbbdev     Epoch *my_shared_epoch;
10651c0b2f7Stbbdev     size_t my_current_epoch;
10751c0b2f7Stbbdev };
10851c0b2f7Stbbdev 
10951c0b2f7Stbbdev template <typename T>
11051c0b2f7Stbbdev class ForwardIterator {
11151c0b2f7Stbbdev     T * my_ptr;
112*478de5b1Stbbdev     typedef std::allocator<T> allocator_type;
113*478de5b1Stbbdev     typedef std::allocator_traits<allocator_type> allocator_traits_type;
11451c0b2f7Stbbdev public:
11551c0b2f7Stbbdev     typedef std::forward_iterator_tag iterator_category;
11651c0b2f7Stbbdev     typedef T value_type;
117*478de5b1Stbbdev     typedef typename allocator_traits_type::difference_type difference_type;
118*478de5b1Stbbdev     typedef typename allocator_traits_type::pointer pointer;
119*478de5b1Stbbdev     typedef typename allocator_traits_type::value_type& reference;
12051c0b2f7Stbbdev 
ForwardIterator()121*478de5b1Stbbdev     ForwardIterator() : my_ptr(nullptr) {}
ForwardIterator(T * ptr)12251c0b2f7Stbbdev     explicit ForwardIterator ( T * ptr ) : my_ptr(ptr){}
12351c0b2f7Stbbdev 
ForwardIterator(const ForwardIterator & r)12451c0b2f7Stbbdev     ForwardIterator ( const ForwardIterator& r ) : my_ptr(r.my_ptr){}
12551c0b2f7Stbbdev     T& operator* () const { return *my_ptr; }
12651c0b2f7Stbbdev     ForwardIterator& operator++ () { ++my_ptr; return *this; }
127*478de5b1Stbbdev     ForwardIterator operator++(int) {
128*478de5b1Stbbdev         ForwardIterator result = *this;
129*478de5b1Stbbdev         ++*this;
130*478de5b1Stbbdev         return result;
131*478de5b1Stbbdev     }
132*478de5b1Stbbdev 
13351c0b2f7Stbbdev     bool operator== ( const ForwardIterator& r ) const { return my_ptr == r.my_ptr; }
13451c0b2f7Stbbdev };
13551c0b2f7Stbbdev 
13651c0b2f7Stbbdev template <typename T>
13751c0b2f7Stbbdev class RandomIterator {
13851c0b2f7Stbbdev     T * my_ptr;
139*478de5b1Stbbdev     typedef std::allocator<T> allocator_type;
140*478de5b1Stbbdev     typedef std::allocator_traits<allocator_type> allocator_traits_type;
14151c0b2f7Stbbdev public:
14251c0b2f7Stbbdev     typedef std::random_access_iterator_tag iterator_category;
14351c0b2f7Stbbdev     typedef T value_type;
144*478de5b1Stbbdev     typedef typename allocator_traits_type::pointer pointer;
145*478de5b1Stbbdev     typedef typename allocator_traits_type::value_type& reference;
146*478de5b1Stbbdev     typedef typename allocator_traits_type::difference_type difference_type;
14751c0b2f7Stbbdev 
RandomIterator()148*478de5b1Stbbdev     RandomIterator() : my_ptr(nullptr) {}
RandomIterator(T * ptr)14951c0b2f7Stbbdev     explicit RandomIterator ( T * ptr ) : my_ptr(ptr){}
RandomIterator(const RandomIterator & r)15051c0b2f7Stbbdev     RandomIterator ( const RandomIterator& r ) : my_ptr(r.my_ptr){}
15151c0b2f7Stbbdev     T& operator* () const { return *my_ptr; }
15251c0b2f7Stbbdev     RandomIterator& operator++ () { ++my_ptr; return *this; }
153*478de5b1Stbbdev     RandomIterator operator++(int) {
154*478de5b1Stbbdev         RandomIterator result = *this;
155*478de5b1Stbbdev         ++*this;
156*478de5b1Stbbdev         return result;
157*478de5b1Stbbdev     }
158*478de5b1Stbbdev     RandomIterator& operator--() { --my_ptr; return *this; }
159*478de5b1Stbbdev     RandomIterator operator--(int) {
160*478de5b1Stbbdev         RandomIterator result = *this;
161*478de5b1Stbbdev         --*this;
162*478de5b1Stbbdev         return result;
163*478de5b1Stbbdev     }
164*478de5b1Stbbdev 
16551c0b2f7Stbbdev     bool operator== ( const RandomIterator& r ) const { return my_ptr == r.my_ptr; }
16651c0b2f7Stbbdev     bool operator!= ( const RandomIterator& r ) const { return my_ptr != r.my_ptr; }
16751c0b2f7Stbbdev     difference_type operator- (const RandomIterator &r) const {return my_ptr - r.my_ptr;}
16851c0b2f7Stbbdev     RandomIterator operator+ (difference_type n) const {return RandomIterator(my_ptr + n);}
16951c0b2f7Stbbdev     bool operator< (const RandomIterator &r) const {return my_ptr < r.my_ptr;}
170*478de5b1Stbbdev     bool operator> (const RandomIterator &r) const {return my_ptr > r.my_ptr;}
171*478de5b1Stbbdev     bool operator<=(const RandomIterator &r) const {return my_ptr <= r.my_ptr;}
172*478de5b1Stbbdev     bool operator>=(const RandomIterator &r) const {return my_ptr >= r.my_ptr;}
173*478de5b1Stbbdev 
174*478de5b1Stbbdev     RandomIterator& operator+=( difference_type n ) {
175*478de5b1Stbbdev         my_ptr += n;
176*478de5b1Stbbdev         return *this;
177*478de5b1Stbbdev     }
178*478de5b1Stbbdev     RandomIterator& operator-=( difference_type n ) {
179*478de5b1Stbbdev         my_ptr -= n;
180*478de5b1Stbbdev         return *this;
181*478de5b1Stbbdev     }
182*478de5b1Stbbdev 
183*478de5b1Stbbdev     friend RandomIterator operator+( difference_type n, RandomIterator it ) {
184*478de5b1Stbbdev         return RandomIterator(it.my_ptr + n);
185*478de5b1Stbbdev     }
186*478de5b1Stbbdev     RandomIterator operator-( difference_type n ) const {
187*478de5b1Stbbdev         return RandomIterator(my_ptr - n);
188*478de5b1Stbbdev     }
189*478de5b1Stbbdev     reference operator[]( difference_type n ) const {
190*478de5b1Stbbdev         return my_ptr[n];
191*478de5b1Stbbdev     }
19251c0b2f7Stbbdev };
19351c0b2f7Stbbdev 
19451c0b2f7Stbbdev template <typename T>
19551c0b2f7Stbbdev class ConstRandomIterator {
19651c0b2f7Stbbdev     const T * my_ptr;
197*478de5b1Stbbdev     typedef std::allocator<T> allocator_type;
198*478de5b1Stbbdev     typedef std::allocator_traits<allocator_type> allocator_traits_type;
19951c0b2f7Stbbdev public:
20051c0b2f7Stbbdev     typedef std::random_access_iterator_tag iterator_category;
20151c0b2f7Stbbdev     typedef const T value_type;
202*478de5b1Stbbdev     typedef typename allocator_traits_type::const_pointer pointer;
203*478de5b1Stbbdev     typedef const typename allocator_traits_type::value_type& reference;
204*478de5b1Stbbdev     typedef typename allocator_traits_type::difference_type difference_type;
20551c0b2f7Stbbdev 
ConstRandomIterator()206*478de5b1Stbbdev     ConstRandomIterator() : my_ptr(nullptr) {}
ConstRandomIterator(const T * ptr)20751c0b2f7Stbbdev     explicit ConstRandomIterator ( const T * ptr ) : my_ptr(ptr){}
ConstRandomIterator(const ConstRandomIterator & r)20851c0b2f7Stbbdev     ConstRandomIterator ( const ConstRandomIterator& r ) : my_ptr(r.my_ptr){}
20951c0b2f7Stbbdev     const T& operator* () const { return *my_ptr; }
21051c0b2f7Stbbdev     ConstRandomIterator& operator++ () { ++my_ptr; return *this; }
211*478de5b1Stbbdev     ConstRandomIterator operator++(int) {
212*478de5b1Stbbdev         ConstRandomIterator result = *this;
213*478de5b1Stbbdev         ++*this;
214*478de5b1Stbbdev         return result;
215*478de5b1Stbbdev     }
216*478de5b1Stbbdev     ConstRandomIterator& operator--() { --my_ptr; return *this; }
217*478de5b1Stbbdev     ConstRandomIterator operator--(int) {
218*478de5b1Stbbdev         ConstRandomIterator result = *this;
219*478de5b1Stbbdev         --*this;
220*478de5b1Stbbdev         return result;
221*478de5b1Stbbdev     }
222*478de5b1Stbbdev 
22351c0b2f7Stbbdev     bool operator== ( const ConstRandomIterator& r ) const { return my_ptr == r.my_ptr; }
22451c0b2f7Stbbdev     bool operator!= ( const ConstRandomIterator& r ) const { return my_ptr != r.my_ptr; }
22551c0b2f7Stbbdev     difference_type operator- (const ConstRandomIterator &r) const {return my_ptr - r.my_ptr;}
22651c0b2f7Stbbdev     ConstRandomIterator operator+ (difference_type n) const {return ConstRandomIterator(my_ptr + n);}
22751c0b2f7Stbbdev     bool operator< (const ConstRandomIterator &r) const {return my_ptr < r.my_ptr;}
228*478de5b1Stbbdev     bool operator> (const ConstRandomIterator &r) const {return my_ptr > r.my_ptr;}
229*478de5b1Stbbdev     bool operator<=(const ConstRandomIterator &r) const {return my_ptr <= r.my_ptr;}
230*478de5b1Stbbdev     bool operator>=(const ConstRandomIterator &r) const {return my_ptr >= r.my_ptr;}
231*478de5b1Stbbdev 
232*478de5b1Stbbdev 
233*478de5b1Stbbdev     ConstRandomIterator& operator+=( difference_type n ) {
234*478de5b1Stbbdev         my_ptr += n;
235*478de5b1Stbbdev         return *this;
236*478de5b1Stbbdev     }
237*478de5b1Stbbdev     ConstRandomIterator& operator-=( difference_type n ) {
238*478de5b1Stbbdev         my_ptr -= n;
239*478de5b1Stbbdev         return *this;
240*478de5b1Stbbdev     }
241*478de5b1Stbbdev 
242*478de5b1Stbbdev     friend ConstRandomIterator operator+( difference_type n, ConstRandomIterator it ) {
243*478de5b1Stbbdev         return ConstRandomIterator(it.my_ptr + n);
244*478de5b1Stbbdev     }
245*478de5b1Stbbdev     ConstRandomIterator operator-( difference_type n ) const {
246*478de5b1Stbbdev         return ConstRandomIterator(my_ptr - n);
247*478de5b1Stbbdev     }
248*478de5b1Stbbdev     reference operator[]( difference_type n ) const {
249*478de5b1Stbbdev         return my_ptr[n];
250*478de5b1Stbbdev     }
25151c0b2f7Stbbdev };
25251c0b2f7Stbbdev 
25351c0b2f7Stbbdev } // namespace utils
25451c0b2f7Stbbdev 
25551c0b2f7Stbbdev #endif // __TBB_test_common_iterator_H
256