diff options
Diffstat (limited to 'Utilities/std/cm/bits/container_helpers.hxx')
-rw-r--r-- | Utilities/std/cm/bits/container_helpers.hxx | 302 |
1 files changed, 302 insertions, 0 deletions
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 |