1
Fork 0
mirror of https://github.com/Jaxan/hybrid-ads.git synced 2025-04-27 23:17:44 +02:00
hybrid-ads/lib/partition.hpp
2015-04-14 11:54:51 +02:00

37 lines
860 B
C++

#pragma once
#include <cassert>
#include <list>
#include <numeric>
#include <stdexcept>
#include <type_traits>
#include <vector>
template <typename Iterator, typename Fun>
std::list<std::list<typename Iterator::value_type>>
partition_(Iterator b, Iterator e, Fun&& function, size_t output_size) {
using namespace std;
using T = typename decay<decltype(*b)>::type;
list<T> elements(b, e);
list<list<T>> blocks;
using ref = typename list<list<T>>::iterator;
vector<ref> A(output_size);
auto it = begin(elements);
auto ed = end(elements);
while (it != ed) {
const auto current = it++;
const auto y = function(*current);
if (y >= output_size) throw runtime_error("Output is too big");
auto& ar = A[y];
if (ar == ref{}) {
ar = blocks.insert(blocks.end(), list<T>{});
}
ar->splice(ar->end(), elements, current);
}
return blocks;
}