diff --git a/source.list b/source.list
index 6849fb0ff4..4eb2265107 100644
--- a/source.list
+++ b/source.list
@@ -450,6 +450,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;
+ });
+}
diff --git a/src/viewport.cpp b/src/viewport.cpp
index 0184438691..2ddbee3365 100644
--- a/src/viewport.cpp
+++ b/src/viewport.cpp
@@ -99,6 +99,7 @@
#include "depot_base.h"
#include "tunnelbridge_map.h"
#include "gui.h"
+#include "core/container_func.hpp"
#include