summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Help/dev/source.rst104
-rw-r--r--Utilities/std/cm/array10
-rw-r--r--Utilities/std/cm/bits/container_helpers.hxx302
-rw-r--r--Utilities/std/cm/deque2
-rw-r--r--Utilities/std/cm/forward_list10
-rw-r--r--Utilities/std/cm/iterator191
-rw-r--r--Utilities/std/cm/list2
-rw-r--r--Utilities/std/cm/map1
-rw-r--r--Utilities/std/cm/set1
-rw-r--r--Utilities/std/cm/string2
-rw-r--r--Utilities/std/cm/string_view2
-rw-r--r--Utilities/std/cm/unordered_map1
-rw-r--r--Utilities/std/cm/unordered_set1
-rw-r--r--Utilities/std/cm/vector2
14 files changed, 433 insertions, 198 deletions
diff --git a/Help/dev/source.rst b/Help/dev/source.rst
index 0ee104fea0..f488b3e1af 100644
--- a/Help/dev/source.rst
+++ b/Help/dev/source.rst
@@ -35,6 +35,18 @@ Available features are:
* From ``C++14``:
+ * ``<cm/array>``:
+ ``cm::cbegin``, ``cm::cend``, ``cm::rbegin``, ``cm::rend``,
+ ``cm::crbegin``, ``cm::crend``
+
+ * ``<cm/deque>``:
+ ``cm::cbegin``, ``cm::cend``, ``cm::rbegin``, ``cm::rend``,
+ ``cm::crbegin``, ``cm::crend``
+
+ * ``<cm/forward_list>``:
+ ``cm::cbegin``, ``cm::cend``, ``cm::rbegin``, ``cm::rend``,
+ ``cm::crbegin``, ``cm::crend``
+
* ``<cm/iomanip>``:
``cm::quoted``
@@ -42,68 +54,142 @@ Available features are:
``cm::make_reverse_iterator``, ``cm::cbegin``, ``cm::cend``,
``cm::rbegin``, ``cm::rend``, ``cm::crbegin``, ``cm::crend``
+ * ``<cm/list>``:
+ ``cm::cbegin``, ``cm::cend``, ``cm::rbegin``, ``cm::rend``,
+ ``cm::crbegin``, ``cm::crend``
+
+ * ``<cm/map>``:
+ ``cm::cbegin``, ``cm::cend``, ``cm::rbegin``, ``cm::rend``,
+ ``cm::crbegin``, ``cm::crend``
+
* ``<cm/memory>``:
``cm::make_unique``
+ * ``<cm/set>``:
+ ``cm::cbegin``, ``cm::cend``, ``cm::rbegin``, ``cm::rend``,
+ ``cm::crbegin``, ``cm::crend``
+
+ * ``<cm/string>``:
+ ``cm::cbegin``, ``cm::cend``, ``cm::rbegin``, ``cm::rend``,
+ ``cm::crbegin``, ``cm::crend``
+
+ * ``<cm/string_view>``:
+ ``cm::cbegin``, ``cm::cend``, ``cm::rbegin``, ``cm::rend``,
+ ``cm::crbegin``, ``cm::crend``
+
* ``<cm/shared_mutex>``:
``cm::shared_lock``
* ``<cm/type_traits>``:
``cm::enable_if_t``
+ * ``<cm/unordered_map>``:
+ ``cm::cbegin``, ``cm::cend``, ``cm::rbegin``, ``cm::rend``,
+ ``cm::crbegin``, ``cm::crend``
+
+ * ``<cm/unordered_set>``:
+ ``cm::cbegin``, ``cm::cend``, ``cm::rbegin``, ``cm::rend``,
+ ``cm::crbegin``, ``cm::crend``
+
+ * ``<cm/vector>``:
+ ``cm::cbegin``, ``cm::cend``, ``cm::rbegin``, ``cm::rend``,
+ ``cm::crbegin``, ``cm::crend``
+
* From ``C++17``:
* ``<cm/algorithm>``:
``cm::clamp``
+ * ``<cm/array>``:
+ ``cm::size``, ``cm::empty``, ``cm::data``
+
+ * ``<cm/deque>``:
+ ``cm::size``, ``cm::empty``, ``cm::data``
+
* ``cm/filesystem>``:
``cm::filesystem::path``
+ * ``<cm/forward_list>``:
+ ``cm::size``, ``cm::empty``, ``cm::data``
+
* ``<cm/iterator>``:
``cm::size``, ``cm::empty``, ``cm::data``
+ * ``<cm/list>``:
+ ``cm::size``, ``cm::empty``, ``cm::data``
+
+ * ``<cm/map>``:
+ ``cm::size``, ``cm::empty``, ``cm::data``
+
* ``<cm/optional>``:
``cm::nullopt_t``, ``cm::nullopt``, ``cm::optional``,
``cm::make_optional``, ``cm::bad_optional_access``
+ * ``<cm/set>``:
+ ``cm::size``, ``cm::empty``, ``cm::data``
+
* ``<cm/shared_mutex>``:
``cm::shared_mutex``
+ * ``<cm/string>``:
+ ``cm::size``, ``cm::empty``, ``cm::data``
+
* ``<cm/string_view>``:
- ``cm::string_view``
+ ``cm::string_view``, ``cm::size``, ``cm::empty``, ``cm::data``
* ``<cm/type_traits>``:
``cm::bool_constant``, ``cm::invoke_result_t``, ``cm::invoke_result``,
``cm::void_t``
+ * ``<cm/unordered_map>``:
+ ``cm::size``, ``cm::empty``, ``cm::data``
+
+ * ``<cm/unordered_set>``:
+ ``cm::size``, ``cm::empty``, ``cm::data``
+
* ``<cm/utility>``:
``cm::in_place_t``, ``cm::in_place``
+ * ``<cm/vector>``:
+ ``cm::size``, ``cm::empty``, ``cm::data``
+
* From ``C++20``:
+ * ``<cm/array>``:
+ ``cm::ssize``
+
* ``<cm/deque>``:
- ``cm::erase``, ``cm::erase_if``
+ ``cm::erase``, ``cm::erase_if``, ``cm::ssize``
+
+ * ``<cm/forward_list>``:
+ ``cm::ssize``
+
+ * ``<cm/iterator>``:
+ ``cm::ssize``
* ``<cm/list>``:
- ``cm::erase``, ``cm::erase_if``
+ ``cm::erase``, ``cm::erase_if``, ``cm::ssize``
* ``<cm/map>`` :
- ``cm::erase_if``
+ ``cm::erase_if``, ``cm::ssize``
* ``<cm/set>`` :
- ``cm::erase_if``
+ ``cm::erase_if``, ``cm::ssize``
+
+ * ``<cm/string_view>``:
+ ``cm::ssize``
* ``<cm/string>``:
- ``cm::erase``, ``cm::erase_if``
+ ``cm::erase``, ``cm::erase_if``, ``cm::ssize``
* ``<cm/unordered_map>``:
- ``cm::erase_if``
+ ``cm::erase_if``, ``cm::ssize``
* ``<cm/unordered_set>``:
- ``cm::erase_if``
+ ``cm::erase_if``, ``cm::ssize``
* ``<cm/vector>``:
- ``cm::erase``, ``cm::erase_if``
+ ``cm::erase``, ``cm::erase_if``, ``cm::ssize``
Additionally, some useful non-standard extensions to the C++ standard library
are available in headers under the directory ``cmext/`` in namespace ``cm``.
diff --git a/Utilities/std/cm/array b/Utilities/std/cm/array
new file mode 100644
index 0000000000..f344ee7312
--- /dev/null
+++ b/Utilities/std/cm/array
@@ -0,0 +1,10 @@
+// -*-c++-*-
+// vim: set ft=cpp:
+
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#pragma once
+
+#include <array> // IWYU pragma: export
+
+#include <cm/bits/container_helpers.hxx> // IWYU pragma: export
diff --git a/Utilities/std/cm/bits/container_helpers.hxx b/Utilities/std/cm/bits/container_helpers.hxx
new file mode 100644
index 0000000000..abcdacbfe6
--- /dev/null
+++ b/Utilities/std/cm/bits/container_helpers.hxx
@@ -0,0 +1,302 @@
+// -*-c++-*-
+// vim: set ft=cpp:
+
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+
+#pragma once
+
+#include <iterator> // IWYU pragma: keep
+
+#if __cplusplus < 201402L || defined(_MSVC_LANG) && _MSVC_LANG < 201402L
+# include <initializer_list>
+#endif
+#if __cplusplus < 202002L || defined(_MSVC_LANG) && _MSVC_LANG < 202002L
+# include <cstddef>
+# include <type_traits>
+#endif
+
+namespace cm {
+
+using std::begin;
+using std::end;
+
+#if __cplusplus < 201402L || defined(_MSVC_LANG) && _MSVC_LANG < 201402L
+
+template <typename C>
+# if defined(_MSC_VER) && _MSC_VER < 1900
+inline auto cbegin(const C& c)
+# else
+inline constexpr auto cbegin(const C& c) noexcept(noexcept(std::begin(c)))
+# endif
+ -> decltype(std::begin(c))
+{
+ return std::begin(c);
+}
+
+template <typename C>
+# if defined(_MSC_VER) && _MSC_VER < 1900
+inline auto cend(const C& c)
+# else
+inline constexpr auto cend(const C& c) noexcept(noexcept(std::end(c)))
+# endif
+ -> decltype(std::end(c))
+{
+ return std::end(c);
+}
+
+template <typename C>
+# if defined(_MSC_VER) && _MSC_VER < 1900
+inline auto rbegin(C& c)
+# else
+inline constexpr auto rbegin(C& c)
+# endif
+ -> decltype(c.rbegin())
+{
+ return c.rbegin();
+}
+template <typename C>
+# if defined(_MSC_VER) && _MSC_VER < 1900
+inline auto rbegin(const C& c)
+# else
+inline constexpr auto rbegin(const C& c)
+# endif
+ -> decltype(c.rbegin())
+{
+ return c.rbegin();
+}
+template <typename T, std::size_t N>
+# if defined(_MSC_VER) && _MSC_VER < 1900
+inline std::reverse_iterator<T*> rbegin(T (&array)[N])
+# else
+inline constexpr std::reverse_iterator<T*> rbegin(T (&array)[N]) noexcept
+# endif
+{
+ return std::reverse_iterator<T*>(array + N);
+}
+template <typename T>
+# if defined(_MSC_VER) && _MSC_VER < 1900
+inline std::reverse_iterator<const T*> rbegin(std::initializer_list<T> il)
+# else
+inline constexpr std::reverse_iterator<const T*> rbegin(
+ std::initializer_list<T> il) noexcept
+# endif
+{
+ return std::reverse_iterator<const T*>(il.end());
+}
+
+template <typename C>
+# if defined(_MSC_VER) && _MSC_VER < 1900
+inline auto rend(C& c)
+# else
+inline constexpr auto rend(C& c)
+# endif
+ -> decltype(c.rend())
+
+{
+ return c.rend();
+}
+template <typename C>
+# if defined(_MSC_VER) && _MSC_VER < 1900
+inline auto rend(const C& c)
+# else
+inline constexpr auto rend(const C& c)
+# endif
+ -> decltype(c.rend())
+{
+ return c.rend();
+}
+template <typename T, std::size_t N>
+# if defined(_MSC_VER) && _MSC_VER < 1900
+inline std::reverse_iterator<T*> rend(T (&array)[N])
+# else
+inline constexpr std::reverse_iterator<T*> rend(T (&array)[N]) noexcept
+# endif
+{
+ return std::reverse_iterator<T*>(array);
+}
+template <typename T>
+# if defined(_MSC_VER) && _MSC_VER < 1900
+inline std::reverse_iterator<const T*> rend(std::initializer_list<T> il)
+# else
+inline constexpr std::reverse_iterator<const T*> rend(
+ std::initializer_list<T> il) noexcept
+# endif
+{
+ return std::reverse_iterator<const T*>(il.begin());
+}
+
+template <typename C>
+# if defined(_MSC_VER) && _MSC_VER < 1900
+inline auto crbegin(const C& c)
+# else
+inline constexpr auto crbegin(const C& c)
+# endif
+ -> decltype(cm::rbegin(c))
+{
+ return cm::rbegin(c);
+}
+
+template <typename C>
+# if defined(_MSC_VER) && _MSC_VER < 1900
+inline auto crend(const C& c)
+# else
+inline constexpr auto crend(const C& c)
+# endif
+ -> decltype(cm::rend(c))
+{
+ return cm::rend(c);
+}
+
+#else
+
+using std::cbegin;
+using std::cend;
+
+using std::rbegin;
+using std::rend;
+
+using std::crbegin;
+using std::crend;
+
+#endif
+
+#if __cplusplus < 201703L || defined(_MSVC_LANG) && _MSVC_LANG < 201703L
+
+template <typename C>
+# if defined(_MSC_VER) && _MSC_VER < 1900
+inline auto size(const C& c)
+# else
+inline constexpr auto size(const C& c) noexcept(noexcept(c.size()))
+# endif
+ -> decltype(c.size())
+{
+ return c.size();
+}
+
+template <typename T, std::size_t N>
+# if defined(_MSC_VER) && _MSC_VER < 1900
+inline std::size_t size(const T (&)[N])
+# else
+inline constexpr std::size_t size(const T (&)[N]) noexcept
+# endif
+{
+ return N;
+}
+
+template <typename C>
+# if defined(_MSC_VER) && _MSC_VER < 1900
+inline auto empty(const C& c)
+# else
+inline constexpr auto empty(const C& c) noexcept(noexcept(c.empty()))
+# endif
+ -> decltype(c.empty())
+{
+ return c.empty();
+}
+
+template <typename T, std::size_t N>
+# if defined(_MSC_VER) && _MSC_VER < 1900
+inline bool empty(const T (&)[N])
+# else
+inline constexpr bool empty(const T (&)[N]) noexcept
+# endif
+{
+ return false;
+}
+
+template <typename E>
+# if defined(_MSC_VER) && _MSC_VER < 1900
+inline bool empty(std::initializer_list<E> il)
+# else
+inline constexpr bool empty(std::initializer_list<E> il) noexcept
+# endif
+{
+ return il.size() == 0;
+}
+
+template <typename C>
+# if defined(_MSC_VER) && _MSC_VER < 1900
+inline auto data(C& c) -> decltype(c.data())
+# else
+inline constexpr auto data(C& c) noexcept(noexcept(c.data()))
+# endif
+ -> decltype(c.data())
+{
+ return c.data();
+}
+
+template <typename C>
+# if defined(_MSC_VER) && _MSC_VER < 1900
+inline auto data(const C& c)
+# else
+inline constexpr auto data(const C& c) noexcept(noexcept(c.data()))
+# endif
+ -> decltype(c.data())
+{
+ return c.data();
+}
+
+template <typename T, std::size_t N>
+# if defined(_MSC_VER) && _MSC_VER < 1900
+inline T* data(T (&array)[N])
+# else
+inline constexpr T* data(T (&array)[N]) noexcept
+# endif
+{
+ return array;
+}
+
+template <typename E>
+# if defined(_MSC_VER) && _MSC_VER < 1900
+inline const E* data(std::initializer_list<E> il)
+# else
+inline constexpr const E* data(std::initializer_list<E> il) noexcept
+# endif
+{
+ return il.begin();
+}
+
+#else
+
+using std::size;
+using std::empty;
+using std::data;
+
+#endif
+
+#if __cplusplus < 202002L || defined(_MSVC_LANG) && _MSVC_LANG < 202002L
+
+template <typename C>
+# if defined(_MSC_VER) && _MSC_VER < 1900
+inline auto ssize(const C& c)
+# else
+inline constexpr auto ssize(const C& c)
+# endif
+ -> typename std::common_type<
+ std::ptrdiff_t, typename std::make_signed<decltype(c.size())>::type>::type
+{
+ using signed_type = typename std::make_signed<decltype(c.size())>::type;
+ using result_type =
+ typename std::common_type<std::ptrdiff_t, signed_type>::type;
+
+ return static_cast<result_type>(c.size());
+}
+
+template <typename T, std::ptrdiff_t N>
+# if defined(_MSC_VER) && _MSC_VER < 1900
+inline std::ptrdiff_t ssize(const T (&)[N])
+# else
+inline constexpr std::ptrdiff_t ssize(const T (&)[N]) noexcept
+# endif
+{
+ return N;
+}
+
+#else
+
+using std::ssize;
+
+#endif
+
+} // namespace cm
diff --git a/Utilities/std/cm/deque b/Utilities/std/cm/deque
index b7b6959da4..df5f8dffe8 100644
--- a/Utilities/std/cm/deque
+++ b/Utilities/std/cm/deque
@@ -8,6 +8,8 @@
#include <algorithm>
#include <deque> // IWYU pragma: export
+#include <cm/bits/container_helpers.hxx> // IWYU pragma: export
+
namespace cm {
// should be updated when C++20 is finalized
diff --git a/Utilities/std/cm/forward_list b/Utilities/std/cm/forward_list
new file mode 100644
index 0000000000..3397a09954
--- /dev/null
+++ b/Utilities/std/cm/forward_list
@@ -0,0 +1,10 @@
+// -*-c++-*-
+// vim: set ft=cpp:
+
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#pragma once
+
+#include <forward_list> // IWYU pragma: export
+
+#include <cm/bits/container_helpers.hxx> // IWYU pragma: export
diff --git a/Utilities/std/cm/iterator b/Utilities/std/cm/iterator
index 3b38cc7925..3bfd9474e2 100644
--- a/Utilities/std/cm/iterator
+++ b/Utilities/std/cm/iterator
@@ -7,18 +7,13 @@
#include <iterator> // IWYU pragma: export
+#include <cm/bits/container_helpers.hxx> // IWYU pragma: export
+
namespace cm {
#if __cplusplus >= 201402L || defined(_MSVC_LANG) && _MSVC_LANG >= 201402L
using std::make_reverse_iterator;
-using std::cbegin;
-using std::cend;
-
-using std::rbegin;
-using std::rend;
-using std::crbegin;
-using std::crend;
#else
template <class Iter>
std::reverse_iterator<Iter> make_reverse_iterator(Iter it)
@@ -26,188 +21,6 @@ std::reverse_iterator<Iter> make_reverse_iterator(Iter it)
return std::reverse_iterator<Iter>(it);
}
-// std::c{begin,end} backport from C++14
-template <class C>
-# if defined(_MSC_VER) && _MSC_VER < 1900
-auto cbegin(C const& c)
-# else
-constexpr auto cbegin(C const& c) noexcept(noexcept(std::begin(c)))
-# endif
- -> decltype(std::begin(c))
-{
- return std::begin(c);
-}
-
-template <class C>
-# if defined(_MSC_VER) && _MSC_VER < 1900
-auto cend(C const& c)
-# else
-constexpr auto cend(C const& c) noexcept(noexcept(std::end(c)))
-# endif
- -> decltype(std::end(c))
-{
- return std::end(c);
-}
-
-// std::r{begin,end} backport from C++14
-template <class C>
-# if !defined(_MSC_VER) || _MSC_VER >= 1900
-constexpr
-# endif
- auto
- rbegin(C& c) -> decltype(c.rbegin())
-{
- return c.rbegin();
-}
-template <class C>
-# if !defined(_MSC_VER) || _MSC_VER >= 1900
-constexpr
-# endif
- auto
- rbegin(C const& c) -> decltype(c.rbegin())
-{
- return c.rbegin();
-}
-template <typename T, size_t N>
-# if !defined(_MSC_VER) || _MSC_VER >= 1900
-constexpr
-# endif
- std::reverse_iterator<T*>
- rbegin(T (&arr)[N])
-{
- return std::reverse_iterator<T*>(arr + N);
-}
-
-template <class C>
-# if !defined(_MSC_VER) || _MSC_VER >= 1900
-constexpr
-# endif
- auto
- rend(C& c) -> decltype(c.rend())
-{
- return c.rend();
-}
-template <class C>
-# if !defined(_MSC_VER) || _MSC_VER >= 1900
-constexpr
-# endif
- auto
- rend(C const& c) -> decltype(c.rend())
-{
- return c.rend();
-}
-template <typename T, size_t N>
-# if !defined(_MSC_VER) || _MSC_VER >= 1900
-constexpr
-# endif
- std::reverse_iterator<T*>
- rend(T (&arr)[N])
-{
- return std::reverse_iterator<T*>(arr);
-}
-
-// std::cr{begin,end} backport from C++14
-template <class C>
-# if !defined(_MSC_VER) || _MSC_VER >= 1900
-constexpr
-# endif
- auto
- crbegin(C const& c) -> decltype(cm::rbegin(c))
-{
- return cm::rbegin(c);
-}
-
-template <class C>
-# if !defined(_MSC_VER) || _MSC_VER >= 1900
-constexpr
-# endif
- auto
- crend(C const& c) -> decltype(cm::rend(c))
-{
- return cm::rend(c);
-}
-#endif
-
-#if __cplusplus >= 201703L || defined(_MSVC_LANG) && _MSVC_LANG >= 201703L
-using std::size;
-
-using std::empty;
-using std::data;
-#else
-
-// std::size backport from C++17.
-template <class C>
-# if !defined(_MSC_VER) || _MSC_VER >= 1900
-constexpr
-# endif
- auto
- size(C const& c) -> decltype(c.size())
-{
- return c.size();
-}
-
-template <typename T, size_t N>
-# if !defined(_MSC_VER) || _MSC_VER >= 1900
-constexpr
-# endif
- std::size_t
- size(const T (&)[N]) throw()
-{
- return N;
-}
-
-// std::empty backport from C++17.
-template <class C>
-# if defined(_MSC_VER) && _MSC_VER < 1900
-auto empty(C const& c)
-# else
-constexpr auto empty(C const& c) noexcept(noexcept(c.empty()))
-# endif
- -> decltype(c.empty())
-{
- return c.empty();
-}
-template <typename T, size_t N>
-# if defined(_MSC_VER) && _MSC_VER < 1900
-bool empty(const T (&)[N])
-# else
-constexpr bool empty(const T (&)[N]) noexcept
-# endif
-{
- return false;
-}
-
-// std::data backport from C++17.
-template <class C>
-# if defined(_MSC_VER) && _MSC_VER < 1900
-auto data(C const& c)
-# else
-constexpr auto data(C const& c) noexcept(noexcept(c.data()))
-# endif
- -> decltype(c.data())
-{
- return c.data();
-}
-template <class C>
-# if defined(_MSC_VER) && _MSC_VER < 1900
-auto data(C& c)
-# else
-constexpr auto data(C& c) noexcept(noexcept(c.data()))
-# endif
- -> decltype(c.data())
-{
- return c.data();
-}
-template <typename T, size_t N>
-# if defined(_MSC_VER) && _MSC_VER < 1900
-T* data(T (&)[N])
-# else
-constexpr T* data(T (&arr)[N]) noexcept
-# endif
-{
- return arr;
-}
-
#endif
} // namespace cm
diff --git a/Utilities/std/cm/list b/Utilities/std/cm/list
index 380bff8d71..bd02e868bb 100644
--- a/Utilities/std/cm/list
+++ b/Utilities/std/cm/list
@@ -7,6 +7,8 @@
#include <list> // IWYU pragma: export
+#include <cm/bits/container_helpers.hxx> // IWYU pragma: export
+
namespace cm {
// should be updated when C++20 is finalized
diff --git a/Utilities/std/cm/map b/Utilities/std/cm/map
index 1794cd78db..4270d78961 100644
--- a/Utilities/std/cm/map
+++ b/Utilities/std/cm/map
@@ -7,6 +7,7 @@
#include <map> // IWYU pragma: export
+#include <cm/bits/container_helpers.hxx> // IWYU pragma: export
#include <cm/bits/erase_if.hxx>
namespace cm {
diff --git a/Utilities/std/cm/set b/Utilities/std/cm/set
index 9fd24d3d4f..70e2c49e95 100644
--- a/Utilities/std/cm/set
+++ b/Utilities/std/cm/set
@@ -7,6 +7,7 @@
#include <set> // IWYU pragma: export
+#include <cm/bits/container_helpers.hxx> // IWYU pragma: export
#include <cm/bits/erase_if.hxx>
namespace cm {
diff --git a/Utilities/std/cm/string b/Utilities/std/cm/string
index 30b1b8565f..d3d899fb71 100644
--- a/Utilities/std/cm/string
+++ b/Utilities/std/cm/string
@@ -8,6 +8,8 @@
#include <algorithm>
#include <string> // IWYU pragma: export
+#include <cm/bits/container_helpers.hxx> // IWYU pragma: export
+
namespace cm {
// should be updated when C++20 is finalized
diff --git a/Utilities/std/cm/string_view b/Utilities/std/cm/string_view
index 9542bac352..35cf5d97e2 100644
--- a/Utilities/std/cm/string_view
+++ b/Utilities/std/cm/string_view
@@ -9,6 +9,8 @@
# define CMake_HAVE_CXX_STRING_VIEW
#endif
+#include <cm/bits/container_helpers.hxx> // IWYU pragma: export
+
#ifdef CMake_HAVE_CXX_STRING_VIEW
# include <string_view> // IWYU pragma: export
namespace cm {
diff --git a/Utilities/std/cm/unordered_map b/Utilities/std/cm/unordered_map
index d21c37e2bf..0b085f3762 100644
--- a/Utilities/std/cm/unordered_map
+++ b/Utilities/std/cm/unordered_map
@@ -7,6 +7,7 @@
#include <unordered_map> // IWYU pragma: export
+#include <cm/bits/container_helpers.hxx> // IWYU pragma: export
#include <cm/bits/erase_if.hxx>
namespace cm {
diff --git a/Utilities/std/cm/unordered_set b/Utilities/std/cm/unordered_set
index 2545ff6896..05930510f2 100644
--- a/Utilities/std/cm/unordered_set
+++ b/Utilities/std/cm/unordered_set
@@ -7,6 +7,7 @@
#include <unordered_set> // IWYU pragma: export
+#include <cm/bits/container_helpers.hxx> // IWYU pragma: export
#include <cm/bits/erase_if.hxx>
namespace cm {
diff --git a/Utilities/std/cm/vector b/Utilities/std/cm/vector
index 33d9365a7d..efd44042ea 100644
--- a/Utilities/std/cm/vector
+++ b/Utilities/std/cm/vector
@@ -8,6 +8,8 @@
#include <algorithm>
#include <vector> // IWYU pragma: export
+#include <cm/bits/container_helpers.hxx> // IWYU pragma: export
+
namespace cm {
// should be updated when C++20 is finalized