From 924f30840bdde1b18602b3db8b63e2efb3517c21 Mon Sep 17 00:00:00 2001 From: Maxime Coste Date: Sat, 16 Feb 2019 22:58:00 +1100 Subject: [PATCH] Fix uses of std::remove_if std::remove_if is not std::partition, it makes no guarantees on the state of the objects past the new end (they usually are in a moved-from state). --- src/client_manager.cc | 22 +++++++++++++--------- src/hook_manager.cc | 15 ++++++++------- 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/src/client_manager.cc b/src/client_manager.cc index d90526a7..2f2a9e84 100644 --- a/src/client_manager.cc +++ b/src/client_manager.cc @@ -153,18 +153,22 @@ void ClientManager::ensure_no_client_uses_buffer(Buffer& buffer) Buffer* last = client->last_buffer(); context.change_buffer(last ? *last : BufferManager::instance().get_first_buffer()); } - auto end = std::remove_if(m_free_windows.begin(), m_free_windows.end(), - [&buffer](const WindowAndSelections& ws) - { return &ws.window->buffer() == &buffer; }); + Vector> removed_windows; + m_free_windows.erase(std::remove_if(m_free_windows.begin(), m_free_windows.end(), + [&buffer, &removed_windows](WindowAndSelections& ws) { + if (&ws.window->buffer() != &buffer) + return false; + removed_windows.push_back(std::move(ws.window)); + return true; + }), + m_free_windows.end()); - for (auto it = end; it != m_free_windows.end(); ++it) + for (auto&& removed_window : removed_windows) { - auto& win = it->window; - win->run_hook_in_own_context(Hook::WinClose, win->buffer().name()); - m_window_trash.push_back(std::move(win)); + removed_window->run_hook_in_own_context(Hook::WinClose, + removed_window->buffer().name()); + m_window_trash.push_back(std::move(removed_window)); } - - m_free_windows.erase(end, m_free_windows.end()); } void ClientManager::clear_window_trash() diff --git a/src/hook_manager.cc b/src/hook_manager.cc index c5698c18..82f14512 100644 --- a/src/hook_manager.cc +++ b/src/hook_manager.cc @@ -36,13 +36,14 @@ void HookManager::remove_hooks(const Regex& regex) { for (auto& list : m_hooks) { - auto it = std::remove_if(list.begin(), list.end(), - [&](const std::unique_ptr& h) - { return regex_match(h->group.begin(), h->group.end(), regex); }); - if (not m_running_hooks.empty()) // we are running some hooks, defer deletion - m_hooks_trash.insert(m_hooks_trash.end(), std::make_move_iterator(it), - std::make_move_iterator(list.end())); - list.erase(it, list.end()); + list.erase(std::remove_if(list.begin(), list.end(), + [this, ®ex](std::unique_ptr& h) { + if (not regex_match(h->group.begin(), h->group.end(), regex)) + return false; + m_hooks_trash.push_back(std::move(h)); + return true; + }), + list.end()); } }