#pragma once #include #include #include namespace gp { namespace __details { template void selection_sort(it_t first, it_t last, pred predicate = pred{}) { while(first != last) { it_t traveler = first; it_t it = first; it++; for(;it!=last;it++) { if(predicate(*it, *traveler)) traveler = it; } gp::swap(*first, *traveler); first++; } } template bool sort2(auto it0, auto it1, pred predicate = pred{}){ if(it0 != it1 && predicate(*it1, *it0)) { gp::swap(*it0, *it1); return true; } return false; }; template void quick_sort(it_t first, it_t last, pred predicate = pred{}) { using __details::sort2; if(last - first <= 2) { auto nit = first + (size_t)(last == first + 1); __details::sort2(first, nit, predicate); return; } auto pivot_v = *(first + (last - first)/2); auto pivot = gp::partition(first, last, [&](auto& a) -> bool{ return predicate(a, pivot_v); }); gp::__details::quick_sort(first, pivot, predicate); gp::__details::quick_sort(pivot, last, predicate); } template void bubble_sort(it_t first, it_t last, pred predicate = pred{}) { if(last - first <= 2) { auto nit = first + (size_t)(last == first + 1); __details::sort2(first, nit, predicate); return; } size_t swaps; do { swaps = 0; auto it = first; auto nit = it + 1; for(;;) { swaps += __details::sort2(it, nit, predicate); ++it; ++nit; if(nit == last) break; } } while(swaps); } } template void sort(it_t first, it_t last, pred predicate = pred{}) { return gp::__details::bubble_sort(first, last, predicate); } }