flatten_iterator_layer.hpp 3.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. #pragma once
  2. #include "arrow_proxy.h"
  3. #include "recursive_iterator_base.hpp"
  4. #include "recursive_iterator_traits.hpp"
  5. namespace iterator { namespace detail {
  6. /**
  7. * @class flatten_iterator_layer
  8. * @brief A single layer for recursing down a nested collection. Represents
  9. * associative containers.
  10. *
  11. * @copydoc recursive_iterator_layer
  12. */
  13. template <typename Iterator, typename RecursiveIterator_NextLayer>
  14. class flatten_iterator_layer : public recursive_iterator_base<Iterator>,
  15. public RecursiveIterator_NextLayer {
  16. public:
  17. using super = RecursiveIterator_NextLayer;
  18. using layer = recursive_iterator_base<Iterator>;
  19. using key_type =
  20. typename std::tuple_element<0, typename layer::value_type>::type;
  21. protected:
  22. using recursive_category = continue_layer_tag_t;
  23. public:
  24. flatten_iterator_layer() = default;
  25. explicit flatten_iterator_layer(layer v) : flatten_iterator_layer() {
  26. assign(v);
  27. update();
  28. }
  29. template <typename OIter, typename Rec>
  30. flatten_iterator_layer(flatten_iterator_layer<OIter, Rec> const & other)
  31. : layer(static_cast<recursive_iterator_base<OIter> const &>(other)),
  32. super(static_cast<Rec const &>(other)) {}
  33. /**
  34. * @brief Concatenate the key in this layer, with the dereferenced data from
  35. * the next.
  36. *
  37. * Due to the use of the next_layer_type metaprogramming, a type such as
  38. * std::map<K, std::vector<std::tuple<T1, T2, T3>>> would return a reference
  39. * of type std::tuple<K const &, std::tuple<T1, T2, T3>&>, preserving
  40. * sub-aggregates of pair/tuple type. Similarly, forward_as_tuple means
  41. * even a key-type of pair/tuple will not be unwrapped.
  42. */
  43. decltype(auto) operator*() const {
  44. using next_t =
  45. typename next_layer_type<decltype(super::get()),
  46. typename super::recursive_category>::type;
  47. return std::tuple_cat(std::forward_as_tuple(std::get<0>(layer::get())),
  48. next_t(super::get()));
  49. }
  50. /**
  51. * Unimplemented because we return an inline constructed type, and tuple
  52. * can only be accessed through std::get anyway.
  53. */
  54. // auto operator->() const { return detail::arrow_proxy(**this); }
  55. void operator->() const;
  56. bool operator==(flatten_iterator_layer const & other) const {
  57. return (static_cast<layer const &>(*this) == other) &&
  58. (static_cast<super const &>(*this) == other);
  59. }
  60. protected:
  61. decltype(auto) get() const { return **this; }
  62. /**
  63. * @copydoc recursive_iterator_layer::next
  64. */
  65. void next() {
  66. super::next();
  67. update();
  68. }
  69. void update() {
  70. layer & self = static_cast<layer &>(*this);
  71. while (super::at_end() && !(++self).at_end()) {
  72. super::assign(make_end_aware_iterator(self->second));
  73. }
  74. }
  75. /**
  76. * @copydoc recursive_iterator_layer::assign
  77. */
  78. void assign(layer v) {
  79. static_cast<layer &>(*this) = v;
  80. if (!v.at_end()) { super::assign(make_end_aware_iterator(v->second)); }
  81. }
  82. using layer::at_end;
  83. };
  84. }}