// -*-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 // IWYU pragma: keep #if __cplusplus < 201402L || defined(_MSVC_LANG) && _MSVC_LANG < 201402L # include #endif #if __cplusplus < 202002L || defined(_MSVC_LANG) && _MSVC_LANG < 202002L # include # include #endif namespace cm { using std::begin; using std::end; #if __cplusplus < 201402L || defined(_MSVC_LANG) && _MSVC_LANG < 201402L template # 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 # 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 # 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 # 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 # if defined(_MSC_VER) && _MSC_VER < 1900 inline std::reverse_iterator rbegin(T (&array)[N]) # else inline constexpr std::reverse_iterator rbegin(T (&array)[N]) noexcept # endif { return std::reverse_iterator(array + N); } template # if defined(_MSC_VER) && _MSC_VER < 1900 inline std::reverse_iterator rbegin(std::initializer_list il) # else inline constexpr std::reverse_iterator rbegin( std::initializer_list il) noexcept # endif { return std::reverse_iterator(il.end()); } template # 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 # 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 # if defined(_MSC_VER) && _MSC_VER < 1900 inline std::reverse_iterator rend(T (&array)[N]) # else inline constexpr std::reverse_iterator rend(T (&array)[N]) noexcept # endif { return std::reverse_iterator(array); } template # if defined(_MSC_VER) && _MSC_VER < 1900 inline std::reverse_iterator rend(std::initializer_list il) # else inline constexpr std::reverse_iterator rend( std::initializer_list il) noexcept # endif { return std::reverse_iterator(il.begin()); } template # 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 # 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 # 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 # 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 # 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 # 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 # if defined(_MSC_VER) && _MSC_VER < 1900 inline bool empty(std::initializer_list il) # else inline constexpr bool empty(std::initializer_list il) noexcept # endif { return il.size() == 0; } template # 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 # 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 # 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 # if defined(_MSC_VER) && _MSC_VER < 1900 inline const E* data(std::initializer_list il) # else inline constexpr const E* data(std::initializer_list 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 # 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::type>::type { using signed_type = typename std::make_signed::type; using result_type = typename std::common_type::type; return static_cast(c.size()); } template # 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