AK: Make quick_sort() a little more ergonomic

Now it actually defaults to "a < b" comparison, instead of forcing you
to provide a trivial less-than comparator. Also you can pass in any
collection type that has .begin() and .end() and we'll sort it for you.
This commit is contained in:
Andreas Kling 2020-03-03 16:01:37 +01:00
parent 058cd1241e
commit 686ade6b5a
14 changed files with 35 additions and 23 deletions

View file

@ -30,14 +30,8 @@
namespace AK {
template<typename T>
bool is_less_than(const T& a, const T& b)
{
return a < b;
}
template<typename Iterator, typename LessThan>
void quick_sort(Iterator start, Iterator end, LessThan less_than = is_less_than)
void quick_sort(Iterator start, Iterator end, LessThan less_than)
{
int size = end - start;
if (size <= 1)
@ -62,6 +56,24 @@ void quick_sort(Iterator start, Iterator end, LessThan less_than = is_less_than)
quick_sort(start + i, end, less_than);
}
template<typename Iterator>
void quick_sort(Iterator start, Iterator end)
{
quick_sort(start, end, [](auto& a, auto& b) { return a < b; });
}
template<typename Collection, typename LessThan>
void quick_sort(Collection& collection, LessThan less_than)
{
quick_sort(collection.begin(), collection.end(), move(less_than));
}
template<typename Collection>
void quick_sort(Collection& collection)
{
quick_sort(collection.begin(), collection.end());
}
}
using AK::quick_sort;

View file

@ -542,7 +542,7 @@ void IRCClient::handle_rpl_namreply(const Message& msg)
auto& channel = ensure_channel(channel_name);
auto members = msg.arguments[3].split(' ');
quick_sort(members.begin(), members.end(), [](auto& a, auto& b) {
quick_sort(members, [](auto& a, auto& b) {
return strcasecmp(a.characters(), b.characters()) < 0;
});

View file

@ -123,7 +123,7 @@ NonnullRefPtr<GUI::Menu> build_system_menu()
Vector<String> sorted_app_categories;
for (auto& category : seen_app_categories)
sorted_app_categories.append(category);
quick_sort(sorted_app_categories.begin(), sorted_app_categories.end(), [](auto& a, auto& b) { return a < b; });
quick_sort(sorted_app_categories);
u8 system_menu_name[] = { 0xc3, 0xb8, 0 };
auto system_menu = GUI::Menu::construct(String((const char*)system_menu_name));
@ -175,7 +175,7 @@ NonnullRefPtr<GUI::Menu> build_system_menu()
auto theme_path = String::format("/res/themes/%s", theme_name.characters());
g_themes.append({ FileSystemPath(theme_name).title(), theme_path });
}
quick_sort(g_themes.begin(), g_themes.end(), [](auto& a, auto& b) { return a.name < b.name; });
quick_sort(g_themes, [](auto& a, auto& b) { return a.name < b.name; });
}
{

View file

@ -60,7 +60,7 @@ struct Project::ProjectTreeNode : public RefCounted<ProjectTreeNode> {
{
if (type == Type::File)
return;
quick_sort(children.begin(), children.end(), [](auto& a, auto& b) {
quick_sort(children, [](auto& a, auto& b) {
return a->name < b->name;
});
for (auto& child : children)

View file

@ -401,7 +401,7 @@ bool Scheduler::pick_next()
sorted_runnables.append(&thread);
return IterationDecision::Continue;
});
quick_sort(sorted_runnables.begin(), sorted_runnables.end(), [](auto& a, auto& b) { return a->effective_priority() >= b->effective_priority(); });
quick_sort(sorted_runnables, [](auto& a, auto& b) { return a->effective_priority() >= b->effective_priority(); });
Thread* thread_to_schedule = nullptr;

View file

@ -179,7 +179,7 @@ String ELFLoader::symbolicate(u32 address, u32* out_offset) const
m_sorted_symbols.append({ symbol.value(), symbol.name() });
return IterationDecision::Continue;
});
quick_sort(m_sorted_symbols.begin(), m_sorted_symbols.end(), [](auto& a, auto& b) {
quick_sort(m_sorted_symbols, [](auto& a, auto& b) {
return a.address < b.address;
});
}

View file

@ -71,7 +71,7 @@ void GFontDatabase::for_each_font(Function<void(const StringView&)> callback)
names.ensure_capacity(m_name_to_metadata.size());
for (auto& it : m_name_to_metadata)
names.append(it.key);
quick_sort(names.begin(), names.end(), AK::is_less_than<String>);
quick_sort(names);
for (auto& name : names)
callback(name);
}
@ -84,7 +84,7 @@ void GFontDatabase::for_each_fixed_width_font(Function<void(const StringView&)>
if (it.value.is_fixed_width)
names.append(it.key);
}
quick_sort(names.begin(), names.end(), AK::is_less_than<String>);
quick_sort(names);
for (auto& name : names)
callback(name);
}

View file

@ -121,7 +121,7 @@ void SortingProxyModel::resort()
did_update();
return;
}
quick_sort(m_row_mappings.begin(), m_row_mappings.end(), [&](auto row1, auto row2) -> bool {
quick_sort(m_row_mappings, [&](auto row1, auto row2) -> bool {
auto data1 = target().data(target().index(row1, m_key_column), Model::Role::Sort);
auto data2 = target().data(target().index(row2, m_key_column), Model::Role::Sort);
if (data1 == data2)

View file

@ -71,7 +71,7 @@ void AppletManager::add_applet(Window& applet)
{
m_applets.append(applet.make_weak_ptr());
quick_sort(m_applets.begin(), m_applets.end(), [](auto& a, auto& b) {
quick_sort(m_applets, [](auto& a, auto& b) {
auto index_a = order_vector.find_first_index(a->title());
auto index_b = order_vector.find_first_index(b->title());
ASSERT(index_a.has_value());

View file

@ -127,7 +127,7 @@ void LineEditor::cache_path()
}
}
quick_sort(m_path.begin(), m_path.end(), AK::is_less_than<String>);
quick_sort(m_path);
}
void LineEditor::cut_mismatching_chars(String& completion, const String& other, size_t start_compare)

View file

@ -221,7 +221,7 @@ int main(int argc, char** argv)
Vector<Index> byte_vector;
expand_list(tokens, byte_vector);
quick_sort(byte_vector.begin(), byte_vector.end(), [](auto& a, auto& b) { return a.m_from < b.m_from; });
quick_sort(byte_vector, [](auto& a, auto& b) { return a.m_from < b.m_from; });
/* Process each file */
for (auto& file : files) {
cut_file(file, byte_vector);

View file

@ -326,7 +326,7 @@ int do_file_system_object_long(const char* path)
files.append(move(metadata));
}
quick_sort(files.begin(), files.end(), [](auto& a, auto& b) {
quick_sort(files, [](auto& a, auto& b) {
if (flag_sort_by_timestamp) {
if (flag_reverse_sort)
return a.stat.st_mtime > b.stat.st_mtime;
@ -382,7 +382,7 @@ int do_file_system_object_short(const char* path)
if (names.last().length() > longest_name)
longest_name = name.length();
}
quick_sort(names.begin(), names.end(), [](auto& a, auto& b) { return a < b; });
quick_sort(names);
size_t printed_on_row = 0;
size_t nprinted = 0;

View file

@ -50,7 +50,7 @@ int main(int argc, char** argv)
lines.append(buffer);
}
quick_sort(lines.begin(), lines.end(), [](auto& a, auto& b) {
quick_sort(lines, [](auto& a, auto& b) {
return strcmp(a.characters(), b.characters()) < 0;
});

View file

@ -184,7 +184,7 @@ int main(int, char**)
threads.append(&it.value);
}
quick_sort(threads.begin(), threads.end(), [](auto* p1, auto* p2) {
quick_sort(threads, [](auto* p1, auto* p2) {
return p2->times_scheduled_since_prev < p1->times_scheduled_since_prev;
});