3 #if !defined(CPPLINQ_LINQ_GROUPBY_HPP)
4 #define CPPLINQ_LINQ_GROUPBY_HPP
10 template <
class Iter,
class Key>
57 template <
class Collection,
class KeyFn,
class Compare = default_less>
60 typedef typename Collection::cursor
63 typedef typename util::result_of<KeyFn(
typename inner_cursor::element_type)>::type
66 typedef std::list<typename inner_cursor::element_type>
72 typedef std::list<group_type>
82 element_list_type elements;
83 std::list<group_type> groups;
84 std::map<key_type, group_type*, Compare> groupIndex;
91 impl_t(inner_cursor cur,
93 Compare comp = Compare())
94 : keySelector(keySelector)
98 insert_all(std::move(cur));
101 void insert_all(inner_cursor cur)
103 while(!cur.empty()) {
108 void insert(
typename inner_cursor::reference_type element)
110 key_type key = keySelector(element);
111 auto groupPos = groupIndex.find(key);
112 if(groupPos == groupIndex.end()) {
114 bool firstGroup = groups.empty();
116 elements.push_back(element);
126 groupIndex.insert( std::make_pair(key, &newGroup) );
128 newGroup.
fin = elements.end();
132 elements.insert(groupPos->second->end(), element);
150 Compare comp = Compare())
152 impl.reset(
new impl_t(cur, keyFn, comp));
153 inner = impl->groups.begin();
154 fin = impl->groups.end();
163 throw std::logic_error(
"attempt to iterate past end of range");
172 std::shared_ptr<impl_t> impl;
173 typename std::list<group_type>::iterator inner;
174 typename std::list<group_type>::iterator fin;
179 Compare comp = Compare())
180 : c(c), keyFn(keyFn), comp(comp)
194 #endif // !defined(CPPLINQ_LINQ_GROUPBY_HPP)