| // -*-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: 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) | |
| { | |
| 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 |