template struct sorter { struct chunk_to_sort { std::list data; std::promise> promise; }; thread_safe_stack chunks; std::vector threads; unsigned const max_thread_count; std::atomic end_of_data; sorter() : max_thread_count(std::thread::hardware_concurrency() - 1), end_of_data(false) { } ~sorter() { end_of_data = true; for (unsigned i = 0; i < threads.size(); ++i) { threads[i].join(); } } void try_sort_chunk() { boost::shared_ptr chunk = chunks.pop(); if (chunk) { sort_chunk(chunk); } } std::list do_sort(std::list& chunk_data) { if (chunk_data.empty()) { return chunk_data; } std::list result; result.splice(result.begin(), chunk_data, chunk_data.begin()); T const& partition_val = *result.begin(); typename std::list::iterator divide_point = std::partition(chunk_data.begin(), chunk_data.end(), [&](T const& val) { return val < partition_val; }); chunk_to_sort new_lower_chunk; new_lower_chunk.data.splice(new_lower_chunk.data.end(), chunk_data, chunk_data.begin(), divide_point); std::future> new_lower = new_lower_chunk.promise.get_future(); chunks.push(std::move(new_lower_chunk)); if (threads.size() < max_thread_count) { threads.push_back(std::thread(&sorter::sort_thread, this)); } std::list new_higher(do_sort(chunk_data)); result.splice(result.end(), new_higher); while (new_lower.wait_for(std::chrono::seconds(0)) != std::future_status::ready) { try_sort_chunk(); } result.splice(result.begin(), new_lower.get()); return result; } void sort_chunk(boost::shared_ptr const& chunk) { chunk->promise.set_value(do_sort(chunk->data)); } void sort_thread() { while (!end_of_data) { try_sort_chunk(); std::this_thread::yield(); } } }; template std::list parallel_quick_sort(std::list input) { if (input.empty()) { return input; } sorter s; return s.do_sort(input); }