10 #include <tracking/trackFindingCDC/utilities/Range.h>
21 namespace TrackFindingCDC {
27 template <
class Ts,
class ACategoryFunction,
class ACategory>
28 ACategory common(
const Ts& items,
const ACategoryFunction& catFunc,
const ACategory defaultCat)
30 auto it = std::begin(items);
31 auto itEnd = std::end(items);
32 return common(it, itEnd, catFunc, defaultCat);
39 template <
class It,
class ACategoryFunction,
class ACategory>
40 ACategory common(It itBegin, It itEnd,
const ACategoryFunction& catFunc,
const ACategory defaultCat)
42 if (itBegin == itEnd)
return defaultCat;
43 const ACategory cat = catFunc(*itBegin);
44 for (It it = itBegin; it != itEnd; ++it) {
45 if (cat != catFunc(*it)) {
55 template <
class Ts,
class APredicate>
56 void erase_remove_if(Ts& ts,
const APredicate& predicate)
58 ts.erase(std::remove_if(std::begin(ts), std::end(ts), predicate), std::end(ts));
62 void only_best_N(Ts& ts,
const size_t N)
64 auto newEnd = std::next(ts.begin(), std::min(N, ts.size()));
65 ts.erase(newEnd, ts.end());
72 void erase_unique(Ts& ts)
74 ts.erase(std::unique(std::begin(ts), std::end(ts)), std::end(ts));
80 template <
class Ts,
class AEqual>
81 void erase_unique(Ts& ts,
const AEqual& equal)
83 ts.erase(std::unique(std::begin(ts), std::end(ts), equal), std::end(ts));
90 std::vector<std::pair<It, int> > unique_count(It itBegin, It itEnd)
92 std::vector<std::pair<It, int> > result;
93 if (itBegin == itEnd)
return result;
95 result.emplace_back(it, 1);
97 for (; it != itEnd; ++it) {
98 if (*it == *result.back().first) {
99 ++result.back().second;
101 result.emplace_back(it, 1);
110 template <
class It,
class AEqual>
111 std::vector<std::pair<It, int> > unique_count(It itBegin, It itEnd,
const AEqual& equal)
113 std::vector<std::pair<It, int> > result;
114 if (itBegin == itEnd)
return result;
116 result.emplace_back(it, 1);
118 for (; it != itEnd; ++it) {
119 if (
equal(*it, *result.back().first)) {
120 ++result.back().second;
122 result.emplace_back(it, 1);
132 std::vector<Range<It> > unique_ranges(It itBegin, It itEnd)
134 std::vector<std::pair<It, It> > result;
135 if (itBegin == itEnd)
return result;
137 It it2 = itBegin + 1;
138 result.emplace_back(it1, it2);
139 for (; it2 != itEnd; ++it1, ++it2) {
140 if (not(*it1 == *it2)) {
141 result.emplace_back(it2, it2);
143 ++result.back().second;
151 template <
class It,
class AEqual>
152 std::vector<Range<It> > unique_ranges(It itBegin, It itEnd,
const AEqual& equal)
154 std::vector<Range<It> > result;
155 if (itBegin == itEnd)
return result;
157 It it2 = itBegin + 1;
158 result.emplace_back(it1, it2);
159 for (; it2 != itEnd; ++it1, ++it2) {
160 if (not
equal(*it1, *it2)) {
161 result.emplace_back(it2, it2);
163 ++result.back().second;
171 template <
class It,
class ACategoryFunction>
172 std::vector<Range<It>> adjacent_groupby(It itBegin, It itEnd,
const ACategoryFunction& catFunc)
174 std::vector<Range<It>> result;
175 if (itBegin == itEnd)
return result;
177 It itFirstOfGroup = itBegin;
178 auto catOfGroup = catFunc(*itBegin);
180 for (It it = itBegin; it != itEnd; ++it) {
181 auto cat = catFunc(*it);
182 if (catOfGroup != cat) {
183 result.emplace_back(itFirstOfGroup, it);
188 result.emplace_back(itFirstOfGroup, itEnd);
196 template <
class AInputIterator,
class AOutputIterator,
class ABinaryOperation>
197 AOutputIterator transform_adjacent_pairs(AInputIterator itBegin,
198 AInputIterator itEnd,
199 AOutputIterator result,
200 const ABinaryOperation& map)
202 if (itBegin == itEnd)
return result;
204 AInputIterator second = itBegin;
206 while (second != itEnd) {
207 *result = map(*itBegin, *second);
219 template <
class AInputIterator,
class AOutputIterator,
class ATrinaryOperation>
220 AOutputIterator transform_adjacent_triples(AInputIterator itBegin,
221 AInputIterator itEnd,
222 AOutputIterator result,
223 const ATrinaryOperation& map)
225 if (not(itBegin != itEnd))
return result;
227 AInputIterator second = itBegin;
229 if (not(second != itEnd))
return result;
231 AInputIterator third = second;
233 while (third != itEnd) {
234 *result = map(*itBegin, *second, *third);
247 template <
class Ts,
class TCopyIfPredicate>
248 Ts copy_if(Ts
const& inputContainer, TCopyIfPredicate pred)
253 std::copy_if(inputContainer.begin(), inputContainer.end(), std::back_inserter(outputContainer), pred);
254 return outputContainer;
261 template <
class Ts,
class AUnaryPredicate>
262 bool any(
const Ts& ts,
const AUnaryPredicate& comparator)
264 return std::any_of(std::begin(ts), std::end(ts), comparator);
270 template <
class Ts,
class AItem>
271 bool is_in(
const AItem& item,
const Ts& ts)
273 return std::find(std::begin(ts), std::end(ts), item) != std::end(ts);
279 template <
class T,
class Ts>
280 std::vector<T*> as_pointers(Ts& ts)
284 std::size_t vsize = end(ts) - begin(ts);
285 std::vector<T*> result(vsize,
nullptr);
286 std::transform(begin(ts), end(ts), result.begin(), [](T & t) { return std::addressof<T>(t);});
Abstract base class for different kinds of events.