15#include "Tracking/Sim/Range.h"
17namespace ActsExamples {
38template <
typename Iterator,
typename KeyGetter>
42 using Key = std::decay_t<
decltype(KeyGetter()(*Iterator()))>;
44 using Group = std::pair<Key, Range<Iterator>>;
54 using iterator_category = std::input_iterator_tag;
55 using value_type =
Group;
56 using difference_type = std::ptrdiff_t;
57 using pointer =
Group*;
58 using reference =
Group&;
62 m_groupBegin(groupBegin),
67 std::swap(m_groupBegin, m_groupEnd);
80 const Key key = (m_groupBegin != m_groupEnd)
81 ? m_groupBy.m_keyGetter(*m_groupBegin)
83 return {key, makeRange(m_groupBegin, m_groupEnd)};
88 Iterator m_groupBegin;
93 return lhs.m_groupBegin == rhs;
95 friend constexpr bool operator!=(
const GroupIterator& lhs,
97 return not(lhs == rhs);
102 constexpr GroupBy(Iterator begin, Iterator end,
103 KeyGetter keyGetter = KeyGetter())
104 : m_begin(begin), m_end(end), m_keyGetter(std::move(keyGetter)) {}
105 constexpr GroupIterator begin()
const {
106 return GroupIterator(*
this, m_begin);
109 constexpr bool empty()
const {
return m_begin == m_end; }
114 KeyGetter m_keyGetter;
123 if (start == m_end) {
127 return std::find_if_not(std::next(start), m_end,
128 [
this, start](
const auto& x) {
129 return m_keyGetter(x) == m_keyGetter(*start);
135template <
typename Container,
typename KeyGetter>
136auto makeGroupBy(
const Container& container, KeyGetter keyGetter)
137 -> GroupBy<
decltype(std::begin(container)), KeyGetter> {
138 return {std::begin(container), std::end(container), std::move(keyGetter)};
Iterator type representing a group of elements.
constexpr GroupIterator & operator++()
Pre-increment operator to advance to the next group.
constexpr Group operator*() const
Derefence operator that returns the pointed-to group of elements.
constexpr GroupIterator operator++(int)
Post-increment operator to advance to the next group.
Proxy for iterating over groups of elements within a container.
constexpr Iterator findEndOfGroup(Iterator start) const
Find the end of the group that starts at the given position.
constexpr GroupBy(Iterator begin, Iterator end, KeyGetter keyGetter=KeyGetter())
Construct the group-by proxy for an iterator range.
std::decay_t< decltype(KeyGetter()(*Iterator()))> Key
The key type that identifies elements within a group.
Iterator GroupEndIterator
Iterator type representing the end of the groups.
std::pair< Key, Range< Iterator > > Group
A Group is an iterator range with the associated key.