LocARNA-2.0.0
zip.hh
1 #ifndef LOCARNA_ZIP_HH
2 #define LOCARNA_ZIP_HH
3 
4 #ifdef HAVE_CONFIG_H
5 #include <config.h>
6 #endif
7 
8 #include <type_traits>
9 #include <utility>
10 #include <memory>
11 
12 #include "aux.hh"
13 
14 namespace LocARNA {
15 
16  template <class T1, class T2>
17  class Zip : std::pair<T1 &, T2 &> {
18  public:
19  using iterator1_t = std::conditional_t<std::is_const<T1>::value,
20  typename T1::const_iterator,
21  typename T1::iterator>;
22  using iterator2_t = std::conditional_t<std::is_const<T2>::value,
23  typename T2::const_iterator,
24  typename T2::iterator>;
25 
26  using iparent_t = std::pair<iterator1_t, iterator2_t>;
27 
28  using value_type1 = std::conditional_t<std::is_const<T1>::value,
29  const typename T1::value_type &,
30  typename T1::value_type &>;
31 
32  using value_type2 = std::conditional_t<std::is_const<T2>::value,
33  const typename T2::value_type &,
34  typename T2::value_type &>;
35 
36  using value_pair_t = std::pair<value_type1, value_type2>;
37 
38  class iterator : public iparent_t {
39  public:
40  iterator(iterator1_t c1, iterator2_t c2) : iparent_t(c1, c2) {}
41 
42  auto operator*() {
43  return value_pair_t(*this->first, *this->second);
44  }
45 
46  auto operator-> () const {
47  auto x = std::make_unique<value_pair_t>(*this->first,
48  *this->second);
49  return x;
50  }
51 
52  auto &operator++() {
53  ++(this->first);
54  ++(this->second);
55  return *this;
56  }
57 
58  auto &
59  operator+=(int x) {
60  this->first += x;
61  this->second += x;
62  return *this;
63  }
64 
65  auto &
66  operator-=(int x) {
67  this->first -= x;
68  this->second -= x;
69  return *this;
70  }
71 
72  auto
73  operator+(int x) const {
74  return iterator(this->first + x, this->second + x);
75  }
76 
77  auto
78  operator-(int x) const {
79  return iterator(this->first - x, this->second - x);
80  }
81 
82  bool
83  operator==(const iterator &x) const {
84  return static_cast<iparent_t>(x).first == this->first ||
85  static_cast<iparent_t>(x).second == this->second;
86  }
87 
88  bool
89  operator!=(const iterator &x) const {
90  return static_cast<iparent_t>(x).first != this->first &&
91  static_cast<iparent_t>(x).second != this->second;
92  }
93 
94  };
95 
96  using parent_t = std::pair<T1 &, T2 &>;
97  Zip(T1 &c1, T2 &c2) : parent_t(c1, c2) {}
98 
99  auto
100  begin() {
101  return iterator(this->first.begin(), this->second.begin());
102  }
103 
104  auto
105  end() {
106  return iterator(this->first.end(), this->second.end());
107  }
108  };
109 
110  template <typename T = size_t>
112  public:
113  using value_type = T;
114 
115  ConstIterableSequence(value_type start)
116  : start_(start){};
117 
119  public:
120  const_iterator(const value_type &idx) : idx_(idx) {}
121 
122  const auto &
123  operator *() const {
124  return idx_;
125  }
126 
127  const auto *
128  operator ->() const {
129  return &idx_;
130  }
131 
132  auto &operator++() {
133  idx_++;
134  return *this;
135  }
136 
137  auto &
138  operator+=(int x) {
139  idx_ += x;
140  return *this;
141  }
142 
143  auto &
144  operator-=(int x) {
145  idx_ -= x;
146  return *this;
147  }
148 
149  auto
150  operator+(int x) const {
151  return const_iterator(idx_ + x);
152  }
153 
154  auto
155  operator-(int x) const {
156  return const_iterator(idx_ - x);
157  }
158 
159  bool
160  operator==(const const_iterator &) const {
161  return false;
162  }
163 
164  bool
165  operator!=(const const_iterator &) const {
166  return true;
167  }
168 
169  private:
170  value_type idx_;
171  };
172 
173  using iterator = const_iterator;
174 
175  auto
176  begin() const {
177  return const_iterator(start_);
178  }
179  auto
180  end() const {
181  return const_iterator(0);
182  }
183  auto
184  cbegin() const {
185  return begin();
186  }
187  auto
188  cend() const {
189  return end();
190  }
191  private:
192  value_type start_;
193  };
194 
195  template <class T>
196  class Enumerate : public Zip<const ConstIterableSequence<>,T> {
197  public:
198  Enumerate(T &c) : Zip<const ConstIterableSequence<>,T>(cis_, c), cis_(0) {}
199 
200  private:
202  };
203 
204  template <class T>
205  auto
206  enumerate(T &c) {
207  return Enumerate<T>(c);
208  }
209 
210  template <class T1, class T2>
211  auto
212  zip(T1 &c1, T2 &c2) {
213  return Zip<T1, T2>(c1, c2);
214  }
215 
216 }
217 
218 #endif // LOCARNA_ZIP_HH
Definition: zip.hh:111
Definition: zip.hh:196
Definition: zip.hh:38
Definition: zip.hh:17
Definition: aligner.cc:15