LDMX Software
Classes | Public Types | Public Member Functions | Private Member Functions | Private Attributes | List of all members
ActsExamples::GroupBy< Iterator, KeyGetter > Class Template Reference

Proxy for iterating over groups of elements within a container. More...

#include <GroupBy.h>

Classes

class  GroupIterator
 Iterator type representing a group of elements. More...
 

Public Types

using Key = std::decay_t< decltype(KeyGetter()(*Iterator()))>
 The key type that identifies elements within a group.
 
using Group = std::pair< Key, Range< Iterator > >
 A Group is an iterator range with the associated key.
 
using GroupEndIterator = Iterator
 Iterator type representing the end of the groups.
 

Public Member Functions

constexpr GroupBy (Iterator begin, Iterator end, KeyGetter keyGetter=KeyGetter())
 Construct the group-by proxy for an iterator range.
 
constexpr GroupIterator begin () const
 
constexpr GroupEndIterator end () const
 
constexpr bool empty () const
 

Private Member Functions

constexpr Iterator findEndOfGroup (Iterator start) const
 Find the end of the group that starts at the given position.
 

Private Attributes

Iterator m_begin
 
Iterator m_end
 
KeyGetter m_keyGetter
 

Detailed Description

template<typename Iterator, typename KeyGetter>
class ActsExamples::GroupBy< Iterator, KeyGetter >

Proxy for iterating over groups of elements within a container.

Note
Each group will contain at least one element.

Consecutive elements with the same key (as defined by the KeyGetter) are placed in one group. The proxy should always be used as part of a range-based for loop. In combination with structured bindings to reduce the boilerplate, the group iteration can be written as

for (auto&& [key, elements] : GroupBy<...>(...)) {
    // do something with just the key
    ...

    // iterate over the group elements
    for (const auto& element : elements) {
        ...
    }
}

Definition at line 39 of file GroupBy.h.

Member Typedef Documentation

◆ Group

template<typename Iterator , typename KeyGetter >
using ActsExamples::GroupBy< Iterator, KeyGetter >::Group = std::pair<Key, Range<Iterator> >

A Group is an iterator range with the associated key.

Definition at line 44 of file GroupBy.h.

◆ GroupEndIterator

template<typename Iterator , typename KeyGetter >
using ActsExamples::GroupBy< Iterator, KeyGetter >::GroupEndIterator = Iterator

Iterator type representing the end of the groups.

The end iterator will not be dereferenced in C++17 range-based loops. It can thus be a simpler type without the overhead of the full group iterator below.

Definition at line 50 of file GroupBy.h.

◆ Key

template<typename Iterator , typename KeyGetter >
using ActsExamples::GroupBy< Iterator, KeyGetter >::Key = std::decay_t<decltype(KeyGetter()(*Iterator()))>

The key type that identifies elements within a group.

Definition at line 42 of file GroupBy.h.

Constructor & Destructor Documentation

◆ GroupBy()

template<typename Iterator , typename KeyGetter >
constexpr ActsExamples::GroupBy< Iterator, KeyGetter >::GroupBy ( Iterator  begin,
Iterator  end,
KeyGetter  keyGetter = KeyGetter() 
)
inlineconstexpr

Construct the group-by proxy for an iterator range.

Definition at line 102 of file GroupBy.h.

104 : m_begin(begin), m_end(end), m_keyGetter(std::move(keyGetter)) {}

Member Function Documentation

◆ begin()

template<typename Iterator , typename KeyGetter >
constexpr GroupIterator ActsExamples::GroupBy< Iterator, KeyGetter >::begin ( ) const
inlineconstexpr

Definition at line 105 of file GroupBy.h.

105 {
106 return GroupIterator(*this, m_begin);
107 }

◆ empty()

template<typename Iterator , typename KeyGetter >
constexpr bool ActsExamples::GroupBy< Iterator, KeyGetter >::empty ( ) const
inlineconstexpr

Definition at line 109 of file GroupBy.h.

109{ return m_begin == m_end; }

◆ end()

template<typename Iterator , typename KeyGetter >
constexpr GroupEndIterator ActsExamples::GroupBy< Iterator, KeyGetter >::end ( ) const
inlineconstexpr

Definition at line 108 of file GroupBy.h.

108{ return m_end; }

◆ findEndOfGroup()

template<typename Iterator , typename KeyGetter >
constexpr Iterator ActsExamples::GroupBy< Iterator, KeyGetter >::findEndOfGroup ( Iterator  start) const
inlineconstexprprivate

Find the end of the group that starts at the given position.

This uses a linear search from the start position and thus has linear complexity in the group size. It does not assume any ordering of the underlying container and is a cache-friendly access pattern.

Definition at line 121 of file GroupBy.h.

121 {
122 // check for end so we can safely dereference the start iterator.
123 if (start == m_end) {
124 return start;
125 }
126 // search the first element that does not share a key with the start.
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);
130 });
131 }

Referenced by ActsExamples::GroupBy< Iterator, KeyGetter >::GroupIterator::operator++().

Member Data Documentation

◆ m_begin

template<typename Iterator , typename KeyGetter >
Iterator ActsExamples::GroupBy< Iterator, KeyGetter >::m_begin
private

Definition at line 112 of file GroupBy.h.

◆ m_end

template<typename Iterator , typename KeyGetter >
Iterator ActsExamples::GroupBy< Iterator, KeyGetter >::m_end
private

Definition at line 113 of file GroupBy.h.

◆ m_keyGetter

template<typename Iterator , typename KeyGetter >
KeyGetter ActsExamples::GroupBy< Iterator, KeyGetter >::m_keyGetter
private

Definition at line 114 of file GroupBy.h.


The documentation for this class was generated from the following file: