Avoid to_remove vector in select helper function

Remove the need to allocate anything when removing selections.
This commit is contained in:
Maxime Coste 2020-05-29 11:59:59 +10:00
parent 94f33bb638
commit 63371da8aa
3 changed files with 20 additions and 7 deletions

View File

@ -92,14 +92,16 @@ void select(Context& context, T func)
} }
else else
{ {
Vector<int> to_remove; auto main_index = selections.main_index();
for (int i = 0; i < (int)selections.size(); ++i) auto new_end = selections.begin();
for (size_t i = 0; i < selections.size(); ++i)
{ {
auto& sel = selections[i]; auto& sel = selections[i];
auto res = func(context, sel); auto res = func(context, sel);
if (not res) if (not res)
{ {
to_remove.push_back(i); if (i <= main_index and main_index != 0)
--main_index;
continue; continue;
} }
@ -112,12 +114,13 @@ void select(Context& context, T func)
} }
if (not res->captures().empty()) if (not res->captures().empty())
sel.captures() = std::move(res->captures()); sel.captures() = std::move(res->captures());
*new_end++ = std::move(sel);
} }
if (new_end == selections.begin())
if (to_remove.size() == selections.size())
throw no_selections_remaining{}; throw no_selections_remaining{};
for (auto& i : to_remove | reverse())
selections.remove(i); selections.set_main_index(main_index);
selections.remove_from(new_end - selections.begin());
} }
selections.sort_and_merge_overlapping(); selections.sort_and_merge_overlapping();

View File

@ -33,6 +33,15 @@ void SelectionList::remove(size_t index)
if (index < m_main or m_main == m_selections.size()) if (index < m_main or m_main == m_selections.size())
--m_main; --m_main;
} }
void SelectionList::remove_from(size_t index)
{
kak_assert(index > 0);
m_selections.erase(begin() + index, end());
if (index <= m_main)
m_main = m_selections.size() - 1;
}
void SelectionList::set(Vector<Selection> list, size_t main) void SelectionList::set(Vector<Selection> list, size_t main)
{ {
kak_assert(main < list.size()); kak_assert(main < list.size());

View File

@ -125,6 +125,7 @@ struct SelectionList
const_iterator end() const { return m_selections.end(); } const_iterator end() const { return m_selections.end(); }
void remove(size_t index); void remove(size_t index);
void remove_from(size_t index);
const Selection* data() const { return m_selections.data(); } const Selection* data() const { return m_selections.data(); }
size_t size() const { return m_selections.size(); } size_t size() const { return m_selections.size(); }