Vcsn  2.1
Be Rational
cross.hh
Go to the documentation of this file.
1 #pragma once
2 
3 #include <boost/iterator/iterator_facade.hpp>
4 
5 #include <vcsn/misc/raise.hh> // pass
6 #include <vcsn/misc/tuple.hh>
7 
8 namespace vcsn
9 {
14  template <typename... Sequences>
16  {
18  using sequences_t = std::tuple<Sequences...>;
19 
21  template <std::size_t... I>
23 
25  static constexpr size_t size = sizeof...(Sequences);
26 
28  using indices_t = vcsn::detail::make_index_sequence<sizeof...(Sequences)>;
29 
31  template <typename Seq>
33 
35  using value_type
36  = std::tuple<typename seq_t<Sequences>::value_type...>;
37 
39  : sequences_(std::move(sequences))
40  {}
41 
42  cross_sequences(Sequences... sequences)
43  : sequences_(sequences...)
44  {}
45 
47  using const_iterators_t
48  = std::tuple<typename seq_t<Sequences>::const_iterator...>;
49 
51  using iterators_t
52  = std::tuple<typename seq_t<Sequences>::iterator...>;
53 
55  template <typename ValueType,
56  typename IteratorsType>
58  : public boost::iterator_facade<
59  cross_iterator<ValueType, IteratorsType>
60  , ValueType
61  , boost::forward_traversal_tag
62  , ValueType // Reference.
63  >
64  {
66  using iterators_type = IteratorsType;
67 
69  const iterators_type& begins, const iterators_type& ends)
70  : is_{is}
71  , begins_{begins}
72  , ends_{ends}
73  {
74  // If one of the ranges is empty, we are done already.
75  if (empty())
76  done_();
77  }
78 
80  : cross_iterator{is, is, ends}
81  {}
82 
83  template <typename OtherValue, typename OtherIterators>
85  : cross_iterator{that.is_, that.begins_, that.ends_}
86  {}
87 
94 
96  bool empty() const
97  {
98  return empty_(indices_t{});
99  }
100 
102  void increment()
103  {
104  if (increment_() == -1)
105  done_();
106  }
107 
108  bool equal(const cross_iterator& that) const
109  {
110  return equal_(that, indices_t{});
111  }
112 
114  {
115  return dereference_(indices_t{});
116  }
117 
118  private:
120 
121  template <std::size_t... I>
122  bool empty_(seq<I...>) const
123  {
124  for (auto n: {(std::get<I>(begins_) == std::get<I>(ends_))...})
125  if (n)
126  return true;
127  return false;
128  }
129 
131  void done_()
132  {
133  is_ = ends_;
134  }
135 
139  {
140  auto res = increment_(indices_t{});
141  // Reset all the iterators that are before the first one that could
142  // advance.
143  if (res != -1)
144  reset_up_to_(res);
145  return res;
146  }
147 
148  template <std::size_t... I>
150  {
151  int res = -1;
152  using swallow = int[];
153  (void) swallow
154  {
155  (res == -1
156  && std::get<size-1-I>(is_) != std::get<size-1-I>(ends_)
157  && ++std::get<size-1-I>(is_) != std::get<size-1-I>(ends_))
158  ? res = size-1-I
159  : 0
160  ...
161  };
162  return res;
163  }
164 
166  void reset_up_to_(int n)
167  {
168  reset_up_to_(n, indices_t{});
169  }
170 
171  template <std::size_t... I>
172  void reset_up_to_(size_t n, seq<I...>)
173  {
174  using swallow = int[];
175  (void) swallow
176  {
177  (n < I
178  && ((std::get<I>(is_) = std::get<I>(begins_)), true))...
179  };
180  }
181 
182  template <std::size_t... I>
183  bool equal_(const cross_iterator& that, seq<I...>) const
184  {
185  for (auto n: {(std::get<I>(is_) == std::get<I>(that.is_))...})
186  if (!n)
187  return false;
188  return true;
189  }
190 
192  template <std::size_t... I>
194  {
195  return value_type{(*std::get<I>(is_))...};
196  }
197  };
198 
201 
204 
206  {
207  auto res = cbegin_(indices_t{});
208  return res;
209  }
210 
212  {
213  return cend_(indices_t{});
214  }
215 
217  {
218  return cbegin();
219  }
220 
222  {
223  return cend();
224  }
225 
227  {
228  auto res = begin_(indices_t{});
229  return res;
230  }
231 
233  {
234  return end_(indices_t{});
235  }
236 
237  private:
238  template <std::size_t... I>
240  {
241  return {const_iterators_t{std::get<I>(sequences_).cbegin()...},
242  const_iterators_t{std::get<I>(sequences_).cend()...}};
243  }
244 
245  template <std::size_t... I>
247  {
248  return {const_iterators_t{std::get<I>(sequences_).cend()...},
249  const_iterators_t{std::get<I>(sequences_).cend()...}};
250  }
251 
252  template <std::size_t... I>
254  {
255  return {iterators_t{std::get<I>(sequences_).begin()...},
256  iterators_t{std::get<I>(sequences_).end()...}};
257  }
258 
259  template <std::size_t... I>
261  {
262  return {iterators_t{std::get<I>(sequences_).end()...},
263  iterators_t{std::get<I>(sequences_).end()...}};
264  }
265 
268  };
269 
270  template <typename... Sequences>
271  cross_sequences<Sequences...>
272  cross(Sequences&&... seqs)
273  {
274  return {std::forward<Sequences>(seqs)...};
275  }
276 
277  template <typename... Sequences>
278  cross_sequences<Sequences...>
279  cross_tuple(const std::tuple<Sequences...>& seqs)
280  {
281  return {seqs};
282  }
283 }
STL namespace.
bool equal(const cross_iterator &that) const
Definition: cross.hh:108
typename std::remove_reference< Seq >::type seq_t
The type of the underlying sequences, without reference.
Definition: cross.hh:32
iterators_type begins_
The begins.
Definition: cross.hh:91
iterator begin()
Definition: cross.hh:226
cross_iterator(cross_iterator< OtherValue, OtherIterators > const &that)
Definition: cross.hh:84
bool equal_(const cross_iterator &that, seq< I...>) const
Definition: cross.hh:183
std::tuple< typename seq_t< Sequences >::iterator...> iterators_t
Tuple of iterators.
Definition: cross.hh:52
friend class boost::iterator_core_access
Definition: cross.hh:119
Provide a range that allows to iterate over the cross product of the provided ranges.
Definition: cross.hh:15
cross_sequences(Sequences...sequences)
Definition: cross.hh:42
cross_sequences< Sequences...> cross(Sequences &&...seqs)
Definition: cross.hh:272
std::string type(const automaton &a)
The implementation type of a.
Definition: others.cc:197
std::istringstream is
The input stream: the specification to translate.
Definition: translate.cc:372
iterator end()
Definition: cross.hh:232
cross_sequences< Sequences...> cross_tuple(const std::tuple< Sequences...> &seqs)
Definition: cross.hh:279
iterator begin_(seq< I...>)
Definition: cross.hh:253
const_iterator end() const
Definition: cross.hh:221
const_iterator cbegin_(seq< I...>) const
Definition: cross.hh:239
const_iterator cend_(seq< I...>) const
Definition: cross.hh:246
IteratorsType iterators_type
Underlying iterators.
Definition: cross.hh:66
ValueSet::value_t tuple(const ValueSet &vs, const typename ValueSets::value_t &...v)
Definition: tuple.hh:28
int increment_()
Move to the next position.
Definition: cross.hh:138
iterators_type ends_
The ends.
Definition: cross.hh:93
std::tuple< typename seq_t< Sequences >::value_type...> value_type
The type of the members.
Definition: cross.hh:36
void reset_up_to_(int n)
Move beginning of ranges to their end, and align.
Definition: cross.hh:166
cross_iterator(const iterators_type &is, const iterators_type &ends)
Definition: cross.hh:79
bool empty() const
Whether some of the range is empty.
Definition: cross.hh:96
const_iterator begin() const
Definition: cross.hh:216
Composite iterator.
Definition: cross.hh:57
sequences_t sequences_
The sequences we iterate upon.
Definition: cross.hh:267
std::tuple< Sequences...> sequences_t
Type of the tuple of all the maps.
Definition: cross.hh:18
value_type dereference() const
Definition: cross.hh:113
const_iterator cend() const
Definition: cross.hh:211
bool empty_(seq< I...>) const
Definition: cross.hh:122
void reset_up_to_(size_t n, seq< I...>)
Definition: cross.hh:172
value_type dereference_(seq< I...>) const
Tuple of values.
Definition: cross.hh:193
const_iterator cbegin() const
Definition: cross.hh:205
iterators_type is_
The current position.
Definition: cross.hh:89
void done_()
We have reached the end, move all the cursors to this end.
Definition: cross.hh:131
std::tuple< typename seq_t< Sequences >::const_iterator...> const_iterators_t
Tuple of const_iterators.
Definition: cross.hh:48
cross_iterator(const iterators_type &is, const iterators_type &begins, const iterators_type &ends)
Definition: cross.hh:68
iterator end_(seq< I...>)
Definition: cross.hh:260
static constexpr size_t size
Number of sequences.
Definition: cross.hh:25
cross_sequences(sequences_t sequences)
Definition: cross.hh:38
void increment()
Advance to next position.
Definition: cross.hh:102