mirror of
https://gitlab.kitware.com/cmake/cmake.git
synced 2026-09-28 04:09:35 +03:00
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.
This commit is contained in:
+95
-9
@@ -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``.
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
+2
-189
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user