16 template <
typename Dereference =
as_tuple,
typename... Maps>
23 template <std::size_t... I>
41 using iterator_t =
typename std::remove_reference_t<T>::const_iterator;
45 using value_t =
typename std::remove_reference_t<T>::value_type;
58 = std::remove_const_t<typename tuple_element_t<0, values_t>::first_type>;
61 = std::tuple<const typename std::remove_reference_t<Maps>::mapped_type&...>;
102 return {dereference_first_(), dereference_second_(
indices_t{})};
111 auto operator*() -> decltype(this->dereference_(Dereference()))
113 return dereference_(Dereference());
130 if (std::get<0>(is_) == std::get<0>(ends_))
134 key_t k = std::get<0>(is_)->first;
138 if (is_done_ || k == k2)
148 template <std::size_t... I>
151 using swallow =
int[];
152 (
void) swallow{ (!is_done_ && (k = align_<I>(k),
false))... };
158 template <std::
size_t I>
162 auto& first = std::get<I>(is_);
166 while (first != std::get<I>(ends_)
167 && std::get<I>(zip_.
maps_).key_comp()(first->first, k))
169 if (first == std::get<I>(ends_))
178 template <std::size_t... I>
181 for (
auto n: {(std::get<I>(is_) != std::get<I>(that.
is_))...})
190 return std::get<0>(is_)->first;
194 template <std::size_t... I>
199 return mapped_t{(std::get<I>(is_)->second)...};
203 template <std::size_t... I>
229 template <std::size_t... I>
233 std::get<I>(maps_).begin()...,
234 std::get<I>(maps_).end()...);
237 template <std::size_t... I>
241 std::get<I>(maps_).end()...,
242 std::get<I>(maps_).end()...);
248 template <
typename Dereference =
as_pair,
typename... Maps>
252 return {std::forward<Maps>(maps)...};
255 template <
typename Dereference =
as_pair,
typename... Maps>
key_t align_(key_t k)
Given the current candidate key, try to find the proper range for I.
std::tuple< value_t< Maps >... > values_t
auto dereference_(as_pair) -> std::pair< key_t, mapped_t >
Return as <k1, <v1, v2...>>.
std::tuple< range_t< Maps >... > ranges_t
std::tuple< iterator_t< Maps >... > iterators_t
auto dereference_(as_tuple) -> references_t
Return as <<k1, v1>, <k1, v2>, ...>.
bool operator!=(const iterator &that) const
zipped_maps< Dereference, Maps... > zip_maps(Maps &&... maps)
iterator begin_(seq< I... >)
void done_()
We have reached the end, move all the cursors to this end.
bool not_equal_(const iterator &that, seq< I... >) const
zipped_maps & zip_
The maps etc.
bool is_done_
Whether we reached the end.
std::pair< iterator_t< T >, iterator_t< T > > range_t
typename std::remove_reference_t< T >::value_type value_t
void align_()
Align all iterators on the first common key.
key_t align_(key_t k, seq< I... >)
Try to align all the ranges to support key k.
auto tuple(const Auts &... as)
Build the (accessible part of the) tuple.
zipped_maps(const maps_t &maps)
mapped_t dereference_second_(seq< I... >) const
The associated tuple of values.
iterator end_(seq< I... >)
Build the static sequence of size_t [0, N[.
key_t dereference_first_() const
The common key.
zipped_maps(Maps... maps)
auto operator*() -> decltype(this->dereference_(Dereference()))
std::tuple< Maps... > maps_t
Type of the tuple of all the maps.
references_t dereference_(seq< I... >) const
Tuple of pairs.
iterators_t ends_
The genuine ends.
typename std::remove_reference_t< T >::const_iterator iterator_t
std::tuple< const typename std::remove_reference_t< Maps >::mapped_type &... > mapped_t
Tuple of mapped types.
iterator & operator++()
Advance to next position.
std::remove_const_t< typename tuple_element_t< 0, values_t >::first_type > key_t
Common key type.
iterators_t is_
The current position.
std::tuple< const value_t< Maps > &... > references_t
zip_sequences< Sequences... > zip(Sequences &&... seqs)
zipped_maps< Dereference, Maps... > zip_map_tuple(const std::tuple< Maps... > &maps)
iterator(zipped_maps &zip, iterator_t< Maps >... is, iterator_t< Maps >... ends)