From cb4d8a8dff461596dc6deab98cf2cac7a08dc3d1 Mon Sep 17 00:00:00 2001
From: Charles Dang <exodia339@gmail.com>
Date: Fri, 25 Oct 2024 02:55:53 -0400
Subject: [PATCH] Deploy utils::erase_if

---
 src/addon/manager.cpp                             |  4 ++--
 src/ai/default/ca_move_to_targets.cpp             |  2 +-
 src/config.cpp                                    | 10 +++-------
 src/display.cpp                                   | 11 +++--------
 src/filesystem_common.cpp                         |  9 +++------
 src/game_events/manager_impl.cpp                  |  7 ++-----
 src/game_initialization/flg_manager.cpp           |  7 ++-----
 src/gui/auxiliary/tips.cpp                        |  6 ++----
 src/gui/core/canvas.cpp                           |  5 +----
 src/gui/dialogs/multiplayer/mp_create_game.cpp    |  5 ++---
 src/gui/dialogs/multiplayer/mp_options_helper.cpp |  4 +---
 src/log.cpp                                       |  3 ++-
 src/recall_list_manager.cpp                       |  9 +++------
 src/save_index.cpp                                |  7 +++----
 src/saved_game.cpp                                |  3 ++-
 src/serialization/schema_validator.cpp            |  7 ++++---
 src/serialization/schema_validator.hpp            |  4 ++--
 src/server/wesnothd/game.cpp                      |  2 +-
 src/tod_manager.cpp                               |  3 ++-
 src/units/unit.cpp                                |  6 +-----
 20 files changed, 42 insertions(+), 72 deletions(-)

diff --git a/src/addon/manager.cpp b/src/addon/manager.cpp
index 7fd06ebd01c..9da51cca5b8 100644
--- a/src/addon/manager.cpp
+++ b/src/addon/manager.cpp
@@ -20,6 +20,7 @@
 #include "log.hpp"
 #include "serialization/parser.hpp"
 #include "serialization/schema_validator.hpp"
+#include "utils/general.hpp"
 #include "game_version.hpp"
 #include "wml_exception.hpp"
 
@@ -231,8 +232,7 @@ static std::string strip_cr(std::string str, bool strip)
 {
 	if(!strip)
 		return str;
-	std::string::iterator new_end = std::remove_if(str.begin(), str.end(), IsCR);
-	str.erase(new_end, str.end());
+	utils::erase_if(str, IsCR);
 	return str;
 }
 
diff --git a/src/ai/default/ca_move_to_targets.cpp b/src/ai/default/ca_move_to_targets.cpp
index 79203695868..de60cb93505 100644
--- a/src/ai/default/ca_move_to_targets.cpp
+++ b/src/ai/default/ca_move_to_targets.cpp
@@ -144,7 +144,7 @@ void move_to_targets_phase::execute()
 			}
 		}
 
-		targets.erase( std::remove_if(targets.begin(),targets.end(),remove_wrong_targets(*this)), targets.end() );
+		utils::erase_if(targets, remove_wrong_targets{*this});
 
 		if(targets.empty()) {
 			break;
diff --git a/src/config.cpp b/src/config.cpp
index bbb9848073c..1b1b518ba17 100644
--- a/src/config.cpp
+++ b/src/config.cpp
@@ -27,6 +27,7 @@
 #include "deprecation.hpp"
 #include "game_version.hpp"
 #include "serialization/string_utils.hpp"
+#include "utils/general.hpp"
 
 #include <algorithm>
 #include <cstring>
@@ -573,10 +574,7 @@ void config::clear_children_impl(config_key_type key)
 	if(i == children_.end())
 		return;
 
-	ordered_children.erase(
-		std::remove_if(ordered_children.begin(), ordered_children.end(), remove_ordered(i)),
-		ordered_children.end());
-
+	utils::erase_if(ordered_children, remove_ordered{i});
 	children_.erase(i);
 }
 
@@ -587,9 +585,7 @@ void config::splice_children(config& src, config_key_type key)
 		return;
 	}
 
-	src.ordered_children.erase(
-		std::remove_if(src.ordered_children.begin(), src.ordered_children.end(), remove_ordered(i_src)),
-		src.ordered_children.end());
+	utils::erase_if(src.ordered_children, remove_ordered{i_src});
 
 	auto i_dst = map_get(children_, key);
 	child_list& dst = i_dst->second;
diff --git a/src/display.cpp b/src/display.cpp
index 10a88bbe5f3..589a166f1a5 100644
--- a/src/display.cpp
+++ b/src/display.cpp
@@ -51,6 +51,7 @@
 #include "units/animation_component.hpp"
 #include "units/drawer.hpp"
 #include "units/orb_status.hpp"
+#include "utils/general.hpp"
 #include "video.hpp"
 #include "whiteboard/manager.hpp"
 
@@ -136,14 +137,8 @@ void display::remove_overlay(const map_location& loc)
 
 void display::remove_single_overlay(const map_location& loc, const std::string& toDelete)
 {
-	std::vector<overlay>& overlays = get_overlays()[loc];
-	overlays.erase(
-		std::remove_if(
-			overlays.begin(), overlays.end(),
-			[&toDelete](const overlay& ov) { return ov.image == toDelete || ov.halo == toDelete || ov.id == toDelete; }
-		),
-		overlays.end()
-	);
+	utils::erase_if(get_overlays()[loc],
+		[&toDelete](const overlay& ov) { return ov.image == toDelete || ov.halo == toDelete || ov.id == toDelete; });
 }
 
 display::display(const display_context* dc,
diff --git a/src/filesystem_common.cpp b/src/filesystem_common.cpp
index 566cc679f10..bb38e83b6b2 100644
--- a/src/filesystem_common.cpp
+++ b/src/filesystem_common.cpp
@@ -19,6 +19,7 @@
 #include "log.hpp"
 #include "serialization/string_utils.hpp"
 #include "serialization/unicode.hpp"
+#include "utils/general.hpp"
 
 #include <boost/algorithm/string.hpp>
 
@@ -102,12 +103,8 @@ bool is_legal_user_file_name(const std::string& name, bool allow_whitespace)
 
 void blacklist_pattern_list::remove_blacklisted_files_and_dirs(std::vector<std::string>& files, std::vector<std::string>& directories) const
 {
-	files.erase(
-		std::remove_if(files.begin(), files.end(), [this](const std::string& name) { return match_file(name); }),
-		files.end());
-	directories.erase(
-		std::remove_if(directories.begin(), directories.end(), [this](const std::string& name) { return match_dir(name); }),
-		directories.end());
+	utils::erase_if(files, [this](const std::string& name) { return match_file(name); });
+	utils::erase_if(directories, [this](const std::string& name) { return match_dir(name); });
 }
 
 bool blacklist_pattern_list::match_file(const std::string& name) const
diff --git a/src/game_events/manager_impl.cpp b/src/game_events/manager_impl.cpp
index df193b7fa98..816679adc22 100644
--- a/src/game_events/manager_impl.cpp
+++ b/src/game_events/manager_impl.cpp
@@ -19,6 +19,7 @@
 #include "formula/string_utils.hpp"
 #include "log.hpp"
 #include "serialization/string_utils.hpp"
+#include "utils/general.hpp"
 
 #include <boost/algorithm/string.hpp>
 
@@ -204,11 +205,7 @@ void event_handlers::remove_event_handler(const std::string& id)
 void event_handlers::clean_up_expired_handlers(const std::string& event_name)
 {
 	// First, remove all disabled handlers from the main list.
-	auto to_remove = std::remove_if(active_.begin(), active_.end(),
-		[](handler_ptr p) { return p->disabled(); }
-	);
-
-	active_.erase(to_remove, active_.end());
+	utils::erase_if(active_, [](const handler_ptr& p) { return p->disabled(); });
 
 	// Then remove any now-unlockable weak_ptrs from the by-name list.
 	// Might be more than one so we split.
diff --git a/src/game_initialization/flg_manager.cpp b/src/game_initialization/flg_manager.cpp
index 15a335eaf2f..40baa830a95 100644
--- a/src/game_initialization/flg_manager.cpp
+++ b/src/game_initialization/flg_manager.cpp
@@ -21,6 +21,7 @@
 #include "log.hpp"
 #include "mt_rng.hpp"
 #include "units/types.hpp"
+#include "utils/general.hpp"
 
 #include <algorithm>
 
@@ -318,11 +319,7 @@ void flg_manager::update_available_leaders()
 
 			// Remove duplicate leaders.
 			std::set<std::string> seen;
-			auto pos = std::remove_if(available_leaders_.begin(), available_leaders_.end(),
-				[&seen](const std::string& s) { return !seen.insert(s).second; }
-			);
-
-			available_leaders_.erase(pos, available_leaders_.end());
+			utils::erase_if(available_leaders_, [&seen](const std::string& s) { return !seen.insert(s).second; });
 
 			if(available_leaders_.size() > 1) {
 				available_leaders_.insert(available_leaders_.begin() + random_pos, "random");
diff --git a/src/gui/auxiliary/tips.cpp b/src/gui/auxiliary/tips.cpp
index b0bde658d82..2d9e702f62e 100644
--- a/src/gui/auxiliary/tips.cpp
+++ b/src/gui/auxiliary/tips.cpp
@@ -21,6 +21,7 @@
 #include "preferences/preferences.hpp"
 #include "random.hpp"
 #include "serialization/string_utils.hpp"
+#include "utils/general.hpp"
 
 namespace gui2
 {
@@ -50,7 +51,7 @@ std::vector<game_tip> shuffle(const std::vector<game_tip>& tips)
 	const std::set<std::string>& units = prefs::get().encountered_units();
 
 	// Remove entries whose filters do not match from the tips list.
-	const auto iter = std::remove_if(result.begin(), result.end(), [&units](const game_tip& tip) {
+	utils::erase_if(result, [&units](const game_tip& tip) {
 		const auto& filters = tip.unit_filter_;
 
 		// Filter passes there's no filter at all or if every unit specified has already been
@@ -64,9 +65,6 @@ std::vector<game_tip> shuffle(const std::vector<game_tip>& tips)
 		return !passes_filter;
 	});
 
-	// Prune invalid entries.
-	result.erase(iter, result.end());
-
 	// Shuffle the list.
 	std::shuffle(result.begin(), result.end(), randomness::rng::default_instance());
 	return result;
diff --git a/src/gui/core/canvas.cpp b/src/gui/core/canvas.cpp
index 699acf54deb..f0934cfcb02 100644
--- a/src/gui/core/canvas.cpp
+++ b/src/gui/core/canvas.cpp
@@ -718,10 +718,7 @@ void canvas::clear_shapes(const bool force)
 	if(force) {
 		shapes_.clear();
 	} else {
-		auto conditional = [](const std::unique_ptr<shape>& s)->bool { return !s->immutable(); };
-
-		auto iter = std::remove_if(shapes_.begin(), shapes_.end(), conditional);
-		shapes_.erase(iter, shapes_.end());
+		utils::erase_if(shapes_, [](const std::unique_ptr<shape>& s) { return !s->immutable(); });
 	}
 }
 
diff --git a/src/gui/dialogs/multiplayer/mp_create_game.cpp b/src/gui/dialogs/multiplayer/mp_create_game.cpp
index ebd15e5a1ff..e12efc0d4dc 100644
--- a/src/gui/dialogs/multiplayer/mp_create_game.cpp
+++ b/src/gui/dialogs/multiplayer/mp_create_game.cpp
@@ -127,10 +127,9 @@ mp_create_game::mp_create_game(saved_game& state, bool local_mode)
 		{level_type::type::random_map, _("Random Maps")},
 	};
 
-	level_types_.erase(std::remove_if(level_types_.begin(), level_types_.end(),
-		[this](level_type_info& type_info) {
+	utils::erase_if(level_types_, [this](level_type_info& type_info) {
 		return create_engine_.get_levels_by_type_unfiltered(type_info.first).empty();
-	}), level_types_.end());
+	});
 
 	set_show_even_without_video(true);
 
diff --git a/src/gui/dialogs/multiplayer/mp_options_helper.cpp b/src/gui/dialogs/multiplayer/mp_options_helper.cpp
index f07097bd6b6..1815c3c4df6 100644
--- a/src/gui/dialogs/multiplayer/mp_options_helper.cpp
+++ b/src/gui/dialogs/multiplayer/mp_options_helper.cpp
@@ -106,12 +106,10 @@ void mp_options_helper::update_mod_options()
 int mp_options_helper::remove_nodes_for_type(const std::string& type)
 {
 	// Remove all visible options of the specified source type
-	auto vo_iter = std::remove_if(visible_options_.begin(), visible_options_.end(), [&type](const option_source& source) {
+	utils::erase_if(visible_options_, [&type](const option_source& source) {
 		return source.level_type == type;
 	});
 
-	visible_options_.erase(vo_iter, visible_options_.end());
-
 	// Get the node data for this specific source type
 	type_node_data* data;
 
diff --git a/src/log.cpp b/src/log.cpp
index 5949f585cb0..9e407823a9e 100644
--- a/src/log.cpp
+++ b/src/log.cpp
@@ -23,6 +23,7 @@
 #include "log.hpp"
 #include "filesystem.hpp"
 #include "mt_rng.hpp"
+#include "utils/general.hpp"
 
 #include <boost/algorithm/string.hpp>
 
@@ -106,7 +107,7 @@ void rotate_logs(const std::string& log_dir)
 	std::vector<std::string> files;
 	filesystem::get_files_in_dir(log_dir, &files);
 
-	files.erase(std::remove_if(files.begin(), files.end(), is_not_log_file), files.end());
+	utils::erase_if(files, is_not_log_file);
 
 	if(files.size() <= lg::max_logs) {
 		return;
diff --git a/src/recall_list_manager.cpp b/src/recall_list_manager.cpp
index c38b06851e8..5baa1798eb9 100644
--- a/src/recall_list_manager.cpp
+++ b/src/recall_list_manager.cpp
@@ -16,6 +16,7 @@
 #include "recall_list_manager.hpp"
 #include "units/unit.hpp"
 #include "units/ptr.hpp"
+#include "utils/general.hpp"
 
 #include <algorithm>
 #include <string>
@@ -57,9 +58,7 @@ void recall_list_manager::erase_if_matches_id(const std::string &unit_id)
 {
 	// using unit_id as reference has potential to cause a crash if the underlying unit becomes invald
 	// https://github.com/wesnoth/wesnoth/issues/6603
-	recall_list_.erase(std::remove_if(recall_list_.begin(), recall_list_.end(),
-		[unit_id](const unit_ptr & ptr) { return ptr->id() == unit_id; }),
-	                       recall_list_.end());
+	utils::erase_if(recall_list_, [unit_id](const unit_ptr& ptr) { return ptr->id() == unit_id; });
 }
 
 void recall_list_manager::add(const unit_ptr & ptr, int pos)
@@ -120,9 +119,7 @@ unit_const_ptr recall_list_manager::find_if_matches_underlying_id(std::size_t ui
 
 void recall_list_manager::erase_by_underlying_id(std::size_t uid)
 {
-	recall_list_.erase(std::remove_if(recall_list_.begin(), recall_list_.end(),
-		[uid](const unit_ptr & ptr) { return ptr->underlying_id() == uid; }),
-	                       recall_list_.end());
+	utils::erase_if(recall_list_, [uid](const unit_ptr& ptr) { return ptr->underlying_id() == uid; });
 }
 
 unit_ptr recall_list_manager::extract_if_matches_underlying_id(std::size_t uid)
diff --git a/src/save_index.cpp b/src/save_index.cpp
index bdfc6143e8e..16def0a5942 100644
--- a/src/save_index.cpp
+++ b/src/save_index.cpp
@@ -24,6 +24,7 @@
 #include "preferences/preferences.hpp"
 #include "serialization/parser.hpp"
 #include "team.hpp"
+#include "utils/general.hpp"
 
 #include <boost/algorithm/string/replace.hpp>
 #include <boost/iostreams/filter/gzip.hpp>
@@ -219,7 +220,7 @@ std::vector<save_info> save_index_class::get_saves_list(const std::string* filte
 	std::vector<std::string> filenames;
 	filesystem::get_files_in_dir(dir(), &filenames);
 
-	const auto should_remove = [filter](const std::string& filename) {
+	utils::erase_if(filenames, [filter](const std::string& filename) {
 		// Steam documentation indicates games can ignore their auto-generated 'steam_autocloud.vdf'.
 		// Reference: https://partner.steamgames.com/doc/features/cloud (under Steam Auto-Cloud section as of September 2021)
 		static const std::vector<std::string> to_ignore {"steam_autocloud.vdf"};
@@ -231,9 +232,7 @@ std::vector<save_info> save_index_class::get_saves_list(const std::string* filte
 		}
 
 		return false;
-	};
-
-	filenames.erase(std::remove_if(filenames.begin(), filenames.end(), should_remove), filenames.end());
+	});
 
 	std::vector<save_info> result;
 	std::transform(filenames.begin(), filenames.end(), std::back_inserter(result), creator);
diff --git a/src/saved_game.cpp b/src/saved_game.cpp
index c4b03a3d5d0..4075835be38 100644
--- a/src/saved_game.cpp
+++ b/src/saved_game.cpp
@@ -73,6 +73,7 @@
 #include "random.hpp"
 #include "serialization/binary_or_text.hpp"
 #include "side_controller.hpp"
+#include "utils/general.hpp"
 #include "variable.hpp" // for config_variable_set
 #include "variable_info.hpp"
 
@@ -708,7 +709,7 @@ void saved_game::update_label()
 		label = classification().abbrev + "-" + starting_point_["name"];
 	}
 
-	label.erase(std::remove_if(label.begin(), label.end(), is_illegal_file_char), label.end());
+	utils::erase_if(label, is_illegal_file_char);
 	std::replace(label.begin(), label.end(), '_', ' ');
 }
 
diff --git a/src/serialization/schema_validator.cpp b/src/serialization/schema_validator.cpp
index 5d95be8a009..52f50179512 100644
--- a/src/serialization/schema_validator.cpp
+++ b/src/serialization/schema_validator.cpp
@@ -21,6 +21,7 @@
 #include "serialization/schema/type.hpp"
 #include "serialization/string_utils.hpp"
 #include "utils/back_edge_detector.hpp"
+#include "utils/general.hpp"
 #include "wml_exception.hpp"
 #include <boost/graph/adjacency_list.hpp>
 #include <tuple>
@@ -834,7 +835,7 @@ void schema_self_validator::validate(const config& cfg, const std::string& name,
 		using namespace std::placeholders;
 		std::vector<reference> missing_types = referenced_types_, missing_tags = referenced_tag_paths_;
 		// Remove all the known types
-		missing_types.erase(std::remove_if(missing_types.begin(), missing_types.end(), std::bind(&reference::match, std::placeholders::_1, std::cref(defined_types_))), missing_types.end());
+		utils::erase_if(missing_types, [this](const reference& ref) { return ref.match(defined_types_); });
 		// Remove all the known tags. This is more complicated since links behave similar to a symbolic link.
 		// In other words, the presence of links means there may be more than one way to refer to a given tag.
 		// But that's not all! It's possible to refer to a tag through a derived tag even if it's actually defined in the base tag.
@@ -946,12 +947,12 @@ bool schema_self_validator::reference::operator<(const reference& other) const
 	return std::tie(file_, line_) < std::tie(other.file_, other.line_);
 }
 
-bool schema_self_validator::reference::match(const std::set<std::string>& with)
+bool schema_self_validator::reference::match(const std::set<std::string>& with) const
 {
 	return with.count(value_) > 0;
 }
 
-bool schema_self_validator::reference::can_find(const wml_tag& root, const config& cfg)
+bool schema_self_validator::reference::can_find(const wml_tag& root, const config& cfg) const
 {
 	// The problem is that the schema being validated is that of the schema!!!
 	return root.find_tag(value_, root, cfg) != nullptr;
diff --git a/src/serialization/schema_validator.hpp b/src/serialization/schema_validator.hpp
index dcd382aec5a..372a9c1d4f9 100644
--- a/src/serialization/schema_validator.hpp
+++ b/src/serialization/schema_validator.hpp
@@ -231,8 +231,8 @@ private:
 		{}
 		std::string value_, file_, tag_;
 		int line_;
-		bool match(const std::set<std::string>& with);
-		bool can_find(const wml_tag& root, const config& cfg);
+		bool match(const std::set<std::string>& with) const;
+		bool can_find(const wml_tag& root, const config& cfg) const;
 		bool operator<(const reference& other) const;
 	};
 	std::string current_path() const;
diff --git a/src/server/wesnothd/game.cpp b/src/server/wesnothd/game.cpp
index dab2895d6f4..914432202ec 100644
--- a/src/server/wesnothd/game.cpp
+++ b/src/server/wesnothd/game.cpp
@@ -1786,7 +1786,7 @@ std::string game::get_replay_filename()
 	name << (*starting_pos(level_.root()))["name"] << " Turn " << current_turn() << " (" << db_id_ << ").bz2";
 	std::string filename(name.str());
 	std::replace(filename.begin(), filename.end(), ' ', '_');
-	filename.erase(std::remove_if(filename.begin(), filename.end(), is_invalid_filename_char), filename.end());
+	utils::erase_if(filename, is_invalid_filename_char);
 	return filename;
 }
 
diff --git a/src/tod_manager.cpp b/src/tod_manager.cpp
index 439dcf970f7..d8fda056d66 100644
--- a/src/tod_manager.cpp
+++ b/src/tod_manager.cpp
@@ -26,6 +26,7 @@
 #include "units/abilities.hpp"
 #include "units/unit.hpp"
 #include "units/unit_alignments.hpp"
+#include "utils/general.hpp"
 
 #include <algorithm>
 #include <iterator>
@@ -79,7 +80,7 @@ void tod_manager::resolve_random(randomness::rng& r)
 	}
 
 	// Remove non-positive times
-	output.erase(std::remove_if(output.begin(), output.end(), [](int time) { return time <= 0; }), output.end());
+	utils::erase_if(output, [](int time) { return time <= 0; });
 
 	if(!output.empty()) {
 		int chosen = output[r.next_random() % output.size()];
diff --git a/src/units/unit.cpp b/src/units/unit.cpp
index 88a7dcc341f..33823b65494 100644
--- a/src/units/unit.cpp
+++ b/src/units/unit.cpp
@@ -2079,11 +2079,7 @@ void unit::apply_builtin_effect(std::string apply_to, const config& effect)
 		}
 	} else if(apply_to == "remove_attacks") {
 		set_attr_changed(UA_ATTACKS);
-		auto iter = std::remove_if(attacks_.begin(), attacks_.end(), [&effect](attack_ptr a) {
-			return a->matches_filter(effect);
-		});
-
-		attacks_.erase(iter, attacks_.end());
+		utils::erase_if(attacks_, [&effect](attack_ptr a) { return a->matches_filter(effect); });
 	} else if(apply_to == "attack") {
 		set_attr_changed(UA_ATTACKS);
 		for(attack_ptr a : attacks_) {