| // -*-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. */ |
| #ifndef cm_iterator |
| #define cm_iterator |
| |
| #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 |
| |
| #endif |