Vcsn  2.0
Be Rational
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
cross.hh
Go to the documentation of this file.
1 #ifndef VCSN_MISC_CROSS_HH
2 # define VCSN_MISC_CROSS_HH
3 
4 # include <boost/iterator/iterator_facade.hpp>
5 
6 # include <vcsn/misc/raise.hh> // pass
7 # include <vcsn/misc/tuple.hh>
8 
9 namespace vcsn
10 {
11 
12  template <typename... Sequences>
14  {
16  using sequences_t = std::tuple<Sequences...>;
17 
19  template <std::size_t... I>
21 
23  static constexpr size_t size = sizeof...(Sequences);
24 
26  using indices_t = vcsn::detail::make_index_sequence<sizeof...(Sequences)>;
27 
29  template <typename Seq>
30  using seq_t = typename std::remove_reference<Seq>::type;
31 
33  using value_type
34  = std::tuple<typename seq_t<Sequences>::value_type...>;
35 
36  cross_sequences(const sequences_t& sequences)
37  : sequences_(sequences)
38  {}
39 
40  cross_sequences(Sequences... sequences)
41  : sequences_(sequences...)
42  {}
43 
45  using const_iterators_t
46  = std::tuple<typename seq_t<Sequences>::const_iterator...>;
47 
49  using iterators_t
50  = std::tuple<typename seq_t<Sequences>::iterator...>;
51 
53  template <typename ValueType,
54  typename IteratorsType>
56  : public boost::iterator_facade<
57  cross_iterator<ValueType, IteratorsType>
58  , ValueType
59  , boost::forward_traversal_tag
60  >
61  {
63  using iterators_type = IteratorsType;
64 
66  : is_{is}
67  , begins_{is}
68  , ends_{ends}
69  {}
70 
71  template <typename OtherValue, typename OtherIterators>
73  : is_{that.is_}
74  , begins_{that.begins_}
75  , ends_{that.ends_}
76  {}
77 
84 
87  {
88  if (next_() == -1)
89  done_();
90  return *this;
91  }
92 
93  bool operator!=(const cross_iterator& that) const
94  {
95  return not_equal_(that, indices_t{});
96  }
97 
99  {
100  return dereference_(indices_t{});
101  }
102 
103  private:
105 
107  void done_()
108  {
109  is_ = ends_;
110  }
111 
114  int next_()
115  {
116  auto res = next_(indices_t{});
117  // Reset all the iterators that are before the first one that could
118  // advance.
119  if (res != -1)
120  reset_up_to_(res);
121  return res;
122  }
123 
124  template <std::size_t... I>
126  {
127  int res = -1;
128  using swallow = int[];
129  (void) swallow
130  {
131  (res == -1
132  && std::get<size-1-I>(is_) != std::get<size-1-I>(ends_)
133  && std::next(std::get<size-1-I>(is_)) != std::get<size-1-I>(ends_))
134  ? ++std::get<size-1-I>(is_), res = size-1-I
135  : 0
136  ...
137  };
138  return res;
139  }
140 
142  void reset_up_to_(int n)
143  {
144  reset_up_to_(n, indices_t{});
145  }
146 
147  template <std::size_t... I>
148  void reset_up_to_(size_t n, seq<I...>)
149  {
150  using swallow = int[];
151  (void) swallow
152  {
153  (n < I
154  && ((std::get<I>(is_) = std::get<I>(begins_)), true))...
155  };
156  }
157 
158  template <std::size_t... I>
159  bool not_equal_(const cross_iterator& that, seq<I...>) const
160  {
161  for (auto n: {(std::get<I>(is_) != std::get<I>(that.is_))...})
162  if (n)
163  return true;
164  return false;
165  }
166 
168  template <std::size_t... I>
170  {
171  return value_type{(*std::get<I>(is_))...};
172  }
173  };
174 
177 
180 
182  {
183  auto res = cbegin_(indices_t{});
184  return res;
185  }
186 
188  {
189  return cend_(indices_t{});
190  }
191 
193  {
194  return cbegin();
195  }
196 
198  {
199  return cend();
200  }
201 
203  {
204  auto res = begin_(indices_t{});
205  return res;
206  }
207 
209  {
210  return end_(indices_t{});
211  }
212 
213  private:
214  template <std::size_t... I>
216  {
217  return {const_iterators_t{std::get<I>(sequences_).cbegin()...},
218  const_iterators_t{std::get<I>(sequences_).cend()...}};
219  }
220 
221  template <std::size_t... I>
223  {
224  return {const_iterators_t{std::get<I>(sequences_).cend()...},
225  const_iterators_t{std::get<I>(sequences_).cend()...}};
226  }
227 
228  template <std::size_t... I>
230  {
231  return {iterators_t{std::get<I>(sequences_).begin()...},
232  iterators_t{std::get<I>(sequences_).end()...}};
233  }
234 
235  template <std::size_t... I>
237  {
238  return {iterators_t{std::get<I>(sequences_).end()...},
239  iterators_t{std::get<I>(sequences_).end()...}};
240  }
241 
244  };
245 
246  template <typename... Sequences>
247  cross_sequences<Sequences...>
248  cross(Sequences&&... seqs)
249  {
250  return {std::forward<Sequences>(seqs)...};
251  }
252 
253  template <typename... Sequences>
254  cross_sequences<Sequences...>
255  cross_tuple(const std::tuple<Sequences...>& seqs)
256  {
257  return {seqs};
258  }
259 }
260 
261 #endif // !VCSN_MISC_CROSS_HH
cross_iterator(const iterators_type &is, const iterators_type &ends)
Definition: cross.hh:65
iterator end_(seq< I...>)
Definition: cross.hh:236
cross_sequences(const sequences_t &sequences)
Definition: cross.hh:36
std::tuple< typename seq_t< Sequences >::value_type...> value_type
The type of the members.
Definition: cross.hh:34
static constexpr size_t size
Number of sequences.
Definition: cross.hh:23
void reset_up_to_(size_t n, seq< I...>)
Definition: cross.hh:148
std::tuple< typename seq_t< Sequences >::const_iterator...> const_iterators_t
Tuple of const_iterators.
Definition: cross.hh:46
const_iterator cend() const
Definition: cross.hh:187
value_type dereference_(seq< I...>) const
Tuple of values.
Definition: cross.hh:169
typename std::remove_reference< Seq >::type seq_t
The type of the underlying sequences, without reference.
Definition: cross.hh:30
iterators_type is_
The current position.
Definition: cross.hh:79
std::tuple< Sequences...> sequences_t
Type of the tuple of all the maps.
Definition: cross.hh:16
sequences_t sequences_
The sequences we iterate upon.
Definition: cross.hh:243
value_type operator*() const
Definition: cross.hh:98
iterator begin_(seq< I...>)
Definition: cross.hh:229
iterator begin()
Definition: cross.hh:202
int next_()
Move to the next position.
Definition: cross.hh:114
cross_sequences< Sequences...> cross_tuple(const std::tuple< Sequences...> &seqs)
Definition: cross.hh:255
iterator end()
Definition: cross.hh:208
cross_iterator(cross_iterator< OtherValue, OtherIterators > const &that)
Definition: cross.hh:72
bool not_equal_(const cross_iterator &that, seq< I...>) const
Definition: cross.hh:159
const_iterator cbegin() const
Definition: cross.hh:181
cross_sequences(Sequences...sequences)
Definition: cross.hh:40
void done_()
We have reached the end, move all the cursors to this end.
Definition: cross.hh:107
const_iterator cbegin_(seq< I...>) const
Definition: cross.hh:215
const_iterator cend_(seq< I...>) const
Definition: cross.hh:222
std::istringstream is
The input stream: the specification to translate.
Definition: translate.cc:329
const_iterator end() const
Definition: cross.hh:197
cross_sequences< Sequences...> cross(Sequences &&...seqs)
Definition: cross.hh:248
void reset_up_to_(int n)
Move beginning of ranges to their end, and align.
Definition: cross.hh:142
friend class boost::iterator_core_access
Definition: cross.hh:104
bool operator!=(const cross_iterator &that) const
Definition: cross.hh:93
const_iterator begin() const
Definition: cross.hh:192
IteratorsType iterators_type
Underlying iterators.
Definition: cross.hh:63
std::tuple< typename seq_t< Sequences >::iterator...> iterators_t
Tuple of iterators.
Definition: cross.hh:50
iterators_type ends_
The ends.
Definition: cross.hh:83
iterators_type begins_
The begins.
Definition: cross.hh:81
cross_iterator & operator++()
Advance to next position.
Definition: cross.hh:86
Composite iterator.
Definition: cross.hh:55