Awali
Another Weighted Automata library
cross.hh
Go to the documentation of this file.
1 // This file is part of Awali.
2 // Copyright 2016-2022 Sylvain Lombardy, Victor Marsault, Jacques Sakarovitch
3 //
4 // Awali is a free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
16 
17 #ifndef AWALI_MISC_CROSS_HH
18 # define AWALI_MISC_CROSS_HH
19 
20 #include <awali/sttc/misc/raise.hh> // pass
21 #include <awali/common/tuple.hh>
22 # include <iterator>
23 
24 namespace awali {
25  namespace sttc {
26  namespace internal {
27  template <typename... Sequences>
29  {
31  using sequences_t = std::tuple<Sequences...>;
32 
34  template <std::size_t... I>
36 
38  static constexpr size_t size = sizeof...(Sequences);
39 
41  using indices_t = awali::internal::make_index_sequence<sizeof...(Sequences)>;
42 
44  template <typename Seq>
45  using seq_t = typename std::remove_reference<Seq>::type;
46 
48  using value_type
49  = std::tuple<typename seq_t<Sequences>::value_type...>;
50 
51  cross_sequences(const sequences_t& sequences)
52  : sequences_(sequences)
53  {}
54 
55  cross_sequences(Sequences... sequences)
56  : sequences_(sequences...)
57  {}
58 
61  = std::tuple<typename seq_t<Sequences>::const_iterator...>;
62 
65  = std::tuple<typename seq_t<Sequences>::iterator...>;
66 
68  template <typename ValueType,
69  typename IteratorsType>
71  {
73  using iterators_type = IteratorsType;
74 
76  : is_{is}
77  , begins_{is}
78  , ends_{ends}
79  {}
80 
81  template <typename OtherValue, typename OtherIterators>
83  : is_{that.is_}
84  , begins_{that.begins_}
85  , ends_{that.ends_}
86  {}
87 
94 
97  {
98  if (next_() == -1)
99  done_();
100  return *this;
101  }
102 
103  bool operator!=(const cross_iterator& that) const
104  {
105  return not_equal_(that, indices_t{});
106  }
107 
109  {
110  return dereference_(indices_t{});
111  }
112 
113  private:
114 
116  void done_()
117  {
118  is_ = ends_;
119  }
120 
123  int next_()
124  {
125  auto res = next_(indices_t{});
126  // Reset all the iterators that are before the first one that could
127  // advance.
128  if (res != -1)
129  reset_up_to_(res);
130  return res;
131  }
132 
133  template <std::size_t... I>
134  int next_(seq<I...>)
135  {
136  int res = -1;
137  using swallow = int[];
138  (void) swallow
139  {
140  (res == -1
141  && std::get<size-1-I>(is_) != std::get<size-1-I>(ends_)
142  && std::next(std::get<size-1-I>(is_)) != std::get<size-1-I>(ends_))
143  ? ++std::get<size-1-I>(is_), res = size-1-I
144  : 0
145  ...
146  };
147  return res;
148  }
149 
151  void reset_up_to_(int n)
152  {
153  reset_up_to_(n, indices_t{});
154  }
155 
156  template <std::size_t... I>
157  void reset_up_to_(size_t n, seq<I...>)
158  {
159  using swallow = int[];
160  (void) swallow
161  {
162  (n < I
163  && ((std::get<I>(is_) = std::get<I>(begins_)), true))...
164  };
165  }
166 
167  template <std::size_t... I>
168  bool not_equal_(const cross_iterator& that, seq<I...>) const
169  {
170  for (auto n: {(std::get<I>(is_) != std::get<I>(that.is_))...})
171  if (n)
172  return true;
173  return false;
174  }
175 
177  template <std::size_t... I>
178  value_type dereference_(seq<I...>) const
179  {
180  return value_type{(*std::get<I>(is_))...};
181  }
182  };
183 
186 
189 
191  {
192  auto res = cbegin_(indices_t{});
193  return res;
194  }
195 
197  {
198  return cend_(indices_t{});
199  }
200 
202  {
203  return cbegin();
204  }
205 
207  {
208  return cend();
209  }
210 
212  {
213  auto res = begin_(indices_t{});
214  return res;
215  }
216 
218  {
219  return end_(indices_t{});
220  }
221 
222  private:
223  template <std::size_t... I>
224  const_iterator cbegin_(seq<I...>) const
225  {
226  return {const_iterators_t{std::get<I>(sequences_).cbegin()...},
227  const_iterators_t{std::get<I>(sequences_).cend()...}};
228  }
229 
230  template <std::size_t... I>
231  const_iterator cend_(seq<I...>) const
232  {
233  return {const_iterators_t{std::get<I>(sequences_).cend()...},
234  const_iterators_t{std::get<I>(sequences_).cend()...}};
235  }
236 
237  template <std::size_t... I>
238  iterator begin_(seq<I...>)
239  {
240  return {iterators_t{std::get<I>(sequences_).begin()...},
241  iterators_t{std::get<I>(sequences_).end()...}};
242  }
243 
244  template <std::size_t... I>
245  iterator end_(seq<I...>)
246  {
247  return {iterators_t{std::get<I>(sequences_).end()...},
248  iterators_t{std::get<I>(sequences_).end()...}};
249  }
250 
252  sequences_t sequences_;
253  };
254 
255  template <typename... Sequences>
256  cross_sequences<Sequences...>
257  cross(Sequences&&... seqs)
258  {
259  return {std::forward<Sequences>(seqs)...};
260  }
261 
262  template <typename... Sequences>
263  cross_sequences<Sequences...>
264  cross_tuple(const std::tuple<Sequences...>& seqs)
265  {
266  return {seqs};
267  }
268  }
269  }
270 }//end of ns awali::stc
271 
272 #endif // !AWALI_MISC_CROSS_HH
Definition: tuple.hh:43
cross_sequences< Sequences... > cross_tuple(const std::tuple< Sequences... > &seqs)
Definition: cross.hh:264
cross_sequences< Sequences... > cross(Sequences &&... seqs)
Definition: cross.hh:257
Main namespace of Awali.
Definition: ato.hh:22
Composite iterator.
Definition: cross.hh:71
cross_iterator(cross_iterator< OtherValue, OtherIterators > const &that)
Definition: cross.hh:82
IteratorsType iterators_type
Underlying iterators.
Definition: cross.hh:73
iterators_type is_
The current position.
Definition: cross.hh:89
iterators_type begins_
The begins.
Definition: cross.hh:91
value_type operator*() const
Definition: cross.hh:108
iterators_type ends_
The ends.
Definition: cross.hh:93
cross_iterator(const iterators_type &is, const iterators_type &ends)
Definition: cross.hh:75
bool operator!=(const cross_iterator &that) const
Definition: cross.hh:103
cross_iterator & operator++()
Advance to next position.
Definition: cross.hh:96
const_iterator begin() const
Definition: cross.hh:201
std::tuple< Sequences... > sequences_t
Type of the tuple of all the maps.
Definition: cross.hh:31
iterator end()
Definition: cross.hh:217
cross_sequences(const sequences_t &sequences)
Definition: cross.hh:51
cross_sequences(Sequences... sequences)
Definition: cross.hh:55
static constexpr size_t size
Number of sequences.
Definition: cross.hh:38
awali::internal::make_index_sequence< sizeof...(Sequences)> indices_t
Index sequence for our sequences.
Definition: cross.hh:41
const_iterator cbegin() const
Definition: cross.hh:190
cross_iterator< value_type, iterators_t > iterator
Mutable iterator.
Definition: cross.hh:185
typename std::remove_reference< Seq >::type seq_t
The type of the underlying sequences, without reference.
Definition: cross.hh:45
iterator begin()
Definition: cross.hh:211
cross_iterator< const value_type, const_iterators_t > const_iterator
Const iterator.
Definition: cross.hh:188
const_iterator end() const
Definition: cross.hh:206
const_iterator cend() const
Definition: cross.hh:196
std::tuple< typename seq_t< Sequences >::value_type... > value_type
The type of the members.
Definition: cross.hh:49
std::tuple< typename seq_t< Sequences >::const_iterator... > const_iterators_t
Tuple of const_iterators.
Definition: cross.hh:61
std::tuple< typename seq_t< Sequences >::iterator... > iterators_t
Tuple of iterators.
Definition: cross.hh:65