diff options
author | Marc Chevrier <marc.chevrier@gmail.com> | 2022-05-04 09:21:41 (GMT) |
---|---|---|
committer | Marc Chevrier <marc.chevrier@gmail.com> | 2022-05-07 09:04:06 (GMT) |
commit | 95a1b2c7b8cda5593a0a369b88b6b41669f44712 (patch) | |
tree | 9940b030ea206935fa68a12491d0d32f2a0bd482 /Utilities/std | |
parent | 30f91596677b0b93f22b5123d27fb76f494d0864 (diff) | |
download | CMake-95a1b2c7b8cda5593a0a369b88b6b41669f44712.zip CMake-95a1b2c7b8cda5593a0a369b88b6b41669f44712.tar.gz CMake-95a1b2c7b8cda5593a0a369b88b6b41669f44712.tar.bz2 |
stl containers: enhance compatibility with C++14, C++17 and C++20
* Ensure various functions working with containers are available through
all headers as specified by the standard.
* Add C++20 std::ssize() function.
Diffstat (limited to 'Utilities/std')
-rw-r--r-- | Utilities/std/cm/array | 10 | ||||
-rw-r--r-- | Utilities/std/cm/bits/container_helpers.hxx | 302 | ||||
-rw-r--r-- | Utilities/std/cm/deque | 2 | ||||
-rw-r--r-- | Utilities/std/cm/forward_list | 10 | ||||
-rw-r--r-- | Utilities/std/cm/iterator | 191 | ||||
-rw-r--r-- | Utilities/std/cm/list | 2 | ||||
-rw-r--r-- | Utilities/std/cm/map | 1 | ||||
-rw-r--r-- | Utilities/std/cm/set | 1 | ||||
-rw-r--r-- | Utilities/std/cm/string | 2 | ||||
-rw-r--r-- | Utilities/std/cm/string_view | 2 | ||||
-rw-r--r-- | Utilities/std/cm/unordered_map | 1 | ||||
-rw-r--r-- | Utilities/std/cm/unordered_set | 1 | ||||
-rw-r--r-- | Utilities/std/cm/vector | 2 |
13 files changed, 338 insertions, 189 deletions
diff --git a/Utilities/std/cm/array b/Utilities/std/cm/array new file mode 100644 index 0000000..f344ee7 --- /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 0000000..abcdacb --- /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 b7b6959..df5f8df 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 0000000..3397a09 --- /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 3b38cc7..3bfd947 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 380bff8..bd02e86 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 1794cd7..4270d78 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 9fd24d3..70e2c49 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 30b1b85..d3d899f 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 9542bac..35cf5d9 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 d21c37e..0b085f3 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 2545ff6..0593051 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 33d9365..efd4404 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 |