Metall  v0.28
A persistent memory allocator for data-centric analytics
container_of_containers_iterator_adaptor.hpp
Go to the documentation of this file.
1 // Copyright 2020 Lawrence Livermore National Security, LLC and other Metall
2 // Project Developers. See the top-level COPYRIGHT file for details.
3 //
4 // SPDX-License-Identifier: (Apache-2.0 OR MIT)
5 
6 #ifndef METALL_UTILITY_CONTAINER_OF_CONTAINERS_ITERATOR_ADAPTOR_HPP
7 #define METALL_UTILITY_CONTAINER_OF_CONTAINERS_ITERATOR_ADAPTOR_HPP
8 
9 #include <iterator>
10 
13 namespace metall::utility {
14 
19 template <typename outer_iterator_type, typename inner_iterator_type>
21  public:
23  typename std::iterator_traits<inner_iterator_type>::difference_type;
24  using value_type =
25  typename std::iterator_traits<inner_iterator_type>::value_type;
26  using pointer = typename std::iterator_traits<inner_iterator_type>::pointer;
27  using reference =
28  typename std::iterator_traits<inner_iterator_type>::reference;
30  std::forward_iterator_tag; // TODO: expand to bidirectional_iterator_tag
31 
32  container_of_containers_iterator_adaptor(outer_iterator_type outer_begin,
33  outer_iterator_type outer_end)
34  : m_outer_iterator(outer_begin),
35  m_outer_end(outer_end),
36  m_inner_iterator(),
37  m_inner_end() {
38  if (m_outer_iterator != m_outer_end) {
39  m_inner_iterator = std::begin(*m_outer_iterator);
40  m_inner_end = std::end(*m_outer_iterator);
41  if (m_inner_iterator == m_inner_end) {
42  next();
43  }
44  }
45  }
46 
47  container_of_containers_iterator_adaptor(outer_iterator_type outer_begin,
48  inner_iterator_type inner_iterator,
49  outer_iterator_type outer_end)
50  : m_outer_iterator(outer_begin),
51  m_outer_end(outer_end),
52  m_inner_iterator(inner_iterator),
53  m_inner_end() {
54  if (m_outer_iterator != m_outer_end) {
55  m_inner_end = std::end(*m_outer_iterator);
56  if (m_inner_iterator == m_inner_end) {
57  next();
58  }
59  }
60  }
61 
63  next();
64  return *m_inner_iterator;
65  }
66 
69  operator++();
70  return tmp;
71  }
72 
73  pointer operator->() { return &(*m_inner_iterator); }
74 
75  reference operator*() { return (*m_inner_iterator); }
76 
78  return (m_outer_iterator == m_outer_end &&
79  other.m_outer_iterator == other.m_outer_end) ||
80  (m_outer_iterator == other.m_outer_iterator &&
81  m_inner_iterator == other.m_inner_iterator);
82  }
83 
84  private:
85  void next() {
86  if (m_outer_iterator == m_outer_end) {
87  return; // already at the outer end
88  }
89 
90  if (m_inner_iterator != m_inner_end) {
91  m_inner_iterator = std::next(m_inner_iterator);
92  if (m_inner_iterator != m_inner_end) {
93  return; // found the next one
94  }
95  }
96 
97  // iterate until find the next valid element
98  while (true) {
99  m_outer_iterator =
100  std::next(m_outer_iterator); // move to the next container
101  if (m_outer_iterator == m_outer_end) {
102  return; // reach the outer end
103  }
104 
105  // Check if the current container is empty
106  m_inner_iterator = std::begin(*m_outer_iterator);
107  m_inner_end = std::end(*m_outer_iterator);
108  if (m_inner_iterator != m_inner_end) {
109  return; // found the next one
110  }
111  }
112  }
113 
114  outer_iterator_type m_outer_iterator;
115  outer_iterator_type m_outer_end;
116  inner_iterator_type m_inner_iterator;
117  inner_iterator_type m_inner_end;
118 };
119 
120 template <typename outer_iterator_type, typename inner_iterator_type>
121 inline bool operator==(
122  const container_of_containers_iterator_adaptor<outer_iterator_type,
123  inner_iterator_type> &lhs,
124  const container_of_containers_iterator_adaptor<outer_iterator_type,
125  inner_iterator_type> &rhs) {
126  return lhs.equal(rhs);
127 }
128 
129 template <typename outer_iterator_type, typename inner_iterator_type>
130 inline bool operator!=(
131  const container_of_containers_iterator_adaptor<outer_iterator_type,
132  inner_iterator_type> &lhs,
133  const container_of_containers_iterator_adaptor<outer_iterator_type,
134  inner_iterator_type> &rhs) {
135  return !(lhs == rhs);
136 }
137 
138 } // namespace metall::utility
139 
140 #endif // METALL_UTILITY_CONTAINER_OF_CONTAINERS_ITERATOR_ADAPTOR_HPP
Utility class that provides an iterator for a container of containers, e.g., map of vectors This is a...
Definition: container_of_containers_iterator_adaptor.hpp:20
std::forward_iterator_tag iterator_category
Definition: container_of_containers_iterator_adaptor.hpp:30
typename std::iterator_traits< inner_iterator_type >::difference_type difference_type
Definition: container_of_containers_iterator_adaptor.hpp:23
reference operator++()
Definition: container_of_containers_iterator_adaptor.hpp:62
typename std::iterator_traits< inner_iterator_type >::pointer pointer
Definition: container_of_containers_iterator_adaptor.hpp:26
container_of_containers_iterator_adaptor operator++(int)
Definition: container_of_containers_iterator_adaptor.hpp:67
pointer operator->()
Definition: container_of_containers_iterator_adaptor.hpp:73
container_of_containers_iterator_adaptor(outer_iterator_type outer_begin, outer_iterator_type outer_end)
Definition: container_of_containers_iterator_adaptor.hpp:32
bool equal(const container_of_containers_iterator_adaptor &other) const
Definition: container_of_containers_iterator_adaptor.hpp:77
typename std::iterator_traits< inner_iterator_type >::value_type value_type
Definition: container_of_containers_iterator_adaptor.hpp:25
typename std::iterator_traits< inner_iterator_type >::reference reference
Definition: container_of_containers_iterator_adaptor.hpp:28
reference operator*()
Definition: container_of_containers_iterator_adaptor.hpp:75
container_of_containers_iterator_adaptor(outer_iterator_type outer_begin, inner_iterator_type inner_iterator, outer_iterator_type outer_end)
Definition: container_of_containers_iterator_adaptor.hpp:47
Namespace for utility items.
bool operator==(const container_of_containers_iterator_adaptor< outer_iterator_type, inner_iterator_type > &lhs, const container_of_containers_iterator_adaptor< outer_iterator_type, inner_iterator_type > &rhs)
Definition: container_of_containers_iterator_adaptor.hpp:121
bool operator!=(const container_of_containers_iterator_adaptor< outer_iterator_type, inner_iterator_type > &lhs, const container_of_containers_iterator_adaptor< outer_iterator_type, inner_iterator_type > &rhs)
Definition: container_of_containers_iterator_adaptor.hpp:130