diff --git a/src/util/DereferenceIterator.hxx b/src/util/DereferenceIterator.hxx
index 709df6ac4..4d21cd998 100644
--- a/src/util/DereferenceIterator.hxx
+++ b/src/util/DereferenceIterator.hxx
@@ -89,3 +89,53 @@ public:
 		return original == other.original;
 	}
 };
+
+/**
+ * A container wrapper that wraps the iterators in a
+ * DereferenceIterator.
+ */
+template<typename CT,
+	 typename VT=std::remove_pointer_t<typename std::remove_reference_t<CT>::value_type>>
+class DereferenceContainerAdapter {
+	CT original;
+
+	/* these aliases allow the underlying container to return a
+	   different type for begin() and end() */
+	using const_end_iterator = DereferenceIterator<decltype(std::declval<CT>().cend()), const VT>;
+	using end_iterator = DereferenceIterator<decltype(std::declval<CT>().end()), VT>;
+
+public:
+	using value_type = VT;
+	using pointer = VT *;
+	using reference = VT &;
+
+	using const_iterator = DereferenceIterator<decltype(std::declval<CT>().cbegin()), const VT>;
+	using iterator = DereferenceIterator<decltype(std::declval<CT>().begin()), VT>;
+
+	explicit constexpr DereferenceContainerAdapter(CT &&_original) noexcept
+		:original(std::move(_original)) {}
+
+	constexpr iterator begin() noexcept {
+		return original.begin();
+	}
+
+	constexpr const_iterator begin() const noexcept {
+		return original.cbegin();
+	}
+
+	constexpr const_iterator cbegin() const noexcept {
+		return original.cbegin();
+	}
+
+	constexpr end_iterator end() noexcept {
+		return original.end();
+	}
+
+	constexpr const_end_iterator end() const noexcept {
+		return original.cend();
+	}
+
+	constexpr const_end_iterator cend() const noexcept {
+		return original.cend();
+	}
+};