| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091 |
- #pragma once
- #include "../detail/arrow_proxy.h"
- #include "base.hpp"
- #include "traits.hpp"
- namespace iterator::recursive {
- /**
- * @class flatten_iterator_layer
- * @brief A single layer for recursing down a nested collection. Represents
- * associative containers.
- *
- * @copydoc recursive_iterator_layer
- */
- template <typename Iterator, typename Next>
- class flatten_layer : public base<Iterator>, public Next {
- protected:
- using recursive_category = continue_layer_tag_t;
- public:
- flatten_layer() = default;
- explicit flatten_layer(base<Iterator> v) : flatten_layer() {
- assign(v);
- update();
- }
- template <typename OIter, typename Rec>
- flatten_layer(flatten_layer<OIter, Rec> const & other)
- : base<Iterator>(static_cast<base<OIter> const &>(other)),
- Next(static_cast<Rec const &>(other)) {}
- /**
- * @brief Concatenate the key in this layer, with the dereferenced data from
- * the next.
- *
- * Due to the use of the next_layer_type metaprogramming, a type such as
- * std::map<K, std::vector<std::tuple<T1, T2, T3>>> would return a reference
- * of type std::tuple<K const &, std::tuple<T1, T2, T3>&>, preserving
- * sub-aggregates of pair/tuple type. Similarly, forward_as_tuple means
- * even a key-type of pair/tuple will not be unwrapped.
- */
- decltype(auto) operator*() const {
- using next_t =
- typename next_layer_type<decltype(Next::get()),
- typename Next::recursive_category>::type;
- return std::tuple_cat(
- std::forward_as_tuple(std::get<0>(base<Iterator>::get())),
- next_t(Next::get()));
- }
- /**
- * Unimplemented because we return an inline constructed type, and tuple
- * can only be accessed through std::get anyway.
- */
- // auto operator->() const { return detail::arrow_proxy(**this); }
- void operator->() const;
- bool operator==(flatten_layer const & other) const {
- return (static_cast<base<Iterator> const &>(*this) == other) &&
- (static_cast<Next const &>(*this) == other);
- }
- protected:
- decltype(auto) get() const { return **this; }
- /**
- * @copydoc recursive_iterator_layer::next
- */
- void next() {
- Next::next();
- update();
- }
- void update() {
- base<Iterator> & self = static_cast<base<Iterator> &>(*this);
- while (Next::at_end() && !(++self).at_end()) {
- Next::assign(make_end_aware_iterator(self->second));
- }
- }
- /**
- * @copydoc recursive_iterator_layer::assign
- */
- void assign(base<Iterator> v) {
- static_cast<base<Iterator> &>(*this) = v;
- if (!v.at_end()) { Next::assign(make_end_aware_iterator(v->second)); }
- }
- using base<Iterator>::at_end;
- };
- }
|