15#include "Tracking/Sim/Range.h"
17namespace acts_examples {
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&;
61 : m_group_by_(groupBy),
62 m_group_begin_(groupBegin),
67 std::swap(m_group_begin_, m_group_end_);
80 const Key key = (m_group_begin_ != m_group_end_)
81 ? m_group_by_.m_key_getter_(*m_group_begin_)
83 return {key, makeRange(m_group_begin_, m_group_end_)};
88 Iterator m_group_begin_;
89 Iterator m_group_end_;
93 return lhs.m_group_begin_ == 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_key_getter_(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_key_getter_;
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_key_getter_(x_) == m_key_getter_(*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 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.
constexpr GroupIterator & operator++()
Pre-increment operator to advance to the next group.
Proxy for iterating over groups of elements within a container.
std::decay_t< decltype(KeyGetter()(*Iterator()))> Key
The key type that identifies elements within a group.
std::pair< Key, Range< Iterator > > Group
A Group is an iterator range with the associated key.
Iterator GroupEndIterator
Iterator type representing the end of the groups.
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.