diff --git a/source.list b/source.list
index 59b2824ad0..b2c2f4d495 100644
--- a/source.list
+++ b/source.list
@@ -423,6 +423,7 @@ core/alloc_type.hpp
core/backup_type.hpp
core/bitmath_func.cpp
core/bitmath_func.hpp
+core/container_func.hpp
core/endian_func.hpp
core/endian_type.hpp
core/enum_type.hpp
diff --git a/src/core/container_func.hpp b/src/core/container_func.hpp
new file mode 100644
index 0000000000..1b8e8ad847
--- /dev/null
+++ b/src/core/container_func.hpp
@@ -0,0 +1,35 @@
+/* $Id$ */
+
+/*
+ * This file is part of OpenTTD.
+ * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
+ * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see .
+ */
+
+/** @file container_func.hpp Functions related to use of containers. */
+
+template unsigned int container_unordered_remove_if (C &container, UP predicate) {
+ unsigned int removecount = 0;
+ for (auto it = container.begin(); it != container.end();) {
+ if (predicate(*it)) {
+ removecount++;
+ if (std::next(it) != container.end()) {
+ *it = std::move(container.back());
+ container.pop_back();
+ } else {
+ container.pop_back();
+ break;
+ }
+ } else {
+ ++it;
+ }
+ }
+ return removecount;
+}
+
+template unsigned int container_unordered_remove(C &container, const V &value) {
+ return container_unordered_remove_if (container, [&](const typename C::value_type &v) {
+ return v == value;
+ });
+}