Embedded Multicore Building Blocks V1.0.0
zip_iterator.h
1 /*
2  * Copyright (c) 2014-2017, Siemens AG. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  * 1. Redistributions of source code must retain the above copyright notice,
8  * this list of conditions and the following disclaimer.
9  *
10  * 2. Redistributions in binary form must reproduce the above copyright notice,
11  * this list of conditions and the following disclaimer in the documentation
12  * and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
18  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24  * POSSIBILITY OF SUCH DAMAGE.
25  */
26 
27 #ifndef EMBB_ALGORITHMS_ZIP_ITERATOR_H_
28 #define EMBB_ALGORITHMS_ZIP_ITERATOR_H_
29 
30 #include<iterator>
31 #include <utility>
32 #include <cassert>
33 
34 namespace embb {
35 namespace algorithms {
52 template<typename TypeA, typename TypeB>
53 class ZipPair {
54  public:
59  TypeA first,
61  TypeB second
63  )
64  :first_(first), second_(second) {}
65 
70  const ZipPair& other
72  )
73  :first_(other.first_), second_(other.second_) {}
74 
80  TypeA First() {
81  return first_;
82  }
83 
89  TypeB Second() {
90  return second_;
91  }
92 
98  const TypeA First() const {
99  return first_;
100  }
101 
107  const TypeB Second() const {
108  return second_;
109  }
110 
111  private:
112  TypeA first_;
113  TypeB second_;
114 
118  ZipPair &operator=(const ZipPair&);
119 };
120 
138 template<typename IteratorA, typename IteratorB>
140  public:
146  typedef std::random_access_iterator_tag iterator_category;
147  typedef typename std::iterator_traits<IteratorA>::difference_type
148  difference_type;
149  typedef typename std::iterator_traits<IteratorA>::reference RefA;
150  typedef typename std::iterator_traits<IteratorB>::reference RefB;
151  typedef typename std::iterator_traits<IteratorA>::value_type ValueA;
152  typedef typename std::iterator_traits<IteratorB>::value_type ValueB;
164  IteratorA iter_a,
166  IteratorB iter_b
168  )
169  :iter_a_(iter_a), iter_b_(iter_b) {}
170 
177  const ZipIterator &other
179  ) const {
180  return iter_a_ == other.iter_a_ && iter_b_ == other.iter_b_;
181  }
182 
189  const ZipIterator &other
191  ) const {
192  return iter_a_ != other.iter_a_ || iter_b_ != other.iter_b_;
193  }
194 
198  void operator++() {
199  ++iter_a_;
200  ++iter_b_;
201  }
202 
206  void operator--() {
207  --iter_a_;
208  --iter_b_;
209  }
210 
218  difference_type distance
220  ) const {
221  ZipIterator<IteratorA, IteratorB> new_iterator(*this);
222  new_iterator.iter_a_ += distance;
223  new_iterator.iter_b_ += distance;
224 
225  return new_iterator;
226  }
227 
235  difference_type distance
237  ) const {
238  ZipIterator<IteratorA, IteratorB> new_iterator(*this);
239  new_iterator.iter_a_ -= distance;
240  new_iterator.iter_b_ -= distance;
241 
242  return new_iterator;
243  }
244 
251  difference_type distance
253  ) {
254  iter_a_ += distance;
255  iter_b_ += distance;
256  return *this;
257  }
258 
265  difference_type distance
267  ) {
268  iter_a_ -= distance;
269  iter_b_ -= distance;
270  return *this;
271  }
272 
279  difference_type operator-(
280  const ZipIterator<IteratorA,
281  IteratorB> &other
283  ) const {
284  assert(iter_a_ - other.iter_a_ == iter_b_ - other.iter_b_);
285  return iter_a_ - other.iter_a_;
286  }
287 
293  reference operator*() const {
294  return ZipPair<RefA, RefB>(*iter_a_, *iter_b_);
295  }
296 
297  private:
298  IteratorA iter_a_;
299  IteratorB iter_b_;
300 };
301 
311 template<typename IteratorA, typename IteratorB>
313  IteratorA iter_a,
315  IteratorB iter_b
317  ) {
318  return ZipIterator<IteratorA, IteratorB>(iter_a, iter_b);
319 }
320 
324 } // namespace algorithms
325 } // namespace embb
326 
327 #endif // EMBB_ALGORITHMS_ZIP_ITERATOR_H_
Definition: lock_free_mpmc_queue.h:40
const TypeA First() const
Returns the first value of the pair.
Definition: zip_iterator.h:98
bool operator!=(const ZipIterator &other) const
Compares two zip iterators for inequality.
Definition: zip_iterator.h:188
const TypeB Second() const
Returns the second value of the pair.
Definition: zip_iterator.h:107
ZipPair(TypeA first, TypeB second)
Constructs a pair from two values.
Definition: zip_iterator.h:58
Container for the values of two dereferenced iterators.
Definition: zip_iterator.h:53
ZipIterator< IteratorA, IteratorB > & operator+=(difference_type distance)
Advances both iterators by the specified distance.
Definition: zip_iterator.h:250
difference_type operator-(const ZipIterator< IteratorA, IteratorB > &other) const
Computes the distance between two zip iterators.
Definition: zip_iterator.h:279
ZipIterator< IteratorA, IteratorB > & operator-=(difference_type distance)
Regresses both iterators by the specified distance.
Definition: zip_iterator.h:264
Zip container for two iterators.
Definition: zip_iterator.h:139
ZipPair(const ZipPair &other)
Copies a pair.
Definition: zip_iterator.h:69
ZipIterator(IteratorA iter_a, IteratorB iter_b)
Constructs a zip iterator from two iterators of any type.
Definition: zip_iterator.h:163
ZipIterator< IteratorA, IteratorB > operator-(difference_type distance) const
Returns an instance of a zip iterator where both iterators have been regressed by the specified dista...
Definition: zip_iterator.h:234
TypeA First()
Returns the first value of the pair.
Definition: zip_iterator.h:80
reference operator*() const
Dereferences the zip iterator.
Definition: zip_iterator.h:293
ZipIterator< IteratorA, IteratorB > operator+(difference_type distance) const
Returns an instance of a zip iterator where both iterators have been advanced by the specified distan...
Definition: zip_iterator.h:217
bool operator==(const ZipIterator &other) const
Compares two zip iterators for equality.
Definition: zip_iterator.h:176
ZipIterator< IteratorA, IteratorB > Zip(IteratorA iter_a, IteratorB iter_b)
Creates a zip iterator from two iterators.
Definition: zip_iterator.h:312
void operator--()
Applies prefix decrement on both iterators.
Definition: zip_iterator.h:206
TypeB Second()
Returns the second value of the pair.
Definition: zip_iterator.h:89
void operator++()
Applies prefix increment on both iterators.
Definition: zip_iterator.h:198