iterator 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. // -*-c++-*-
  2. // vim: set ft=cpp:
  3. /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
  4. file Copyright.txt or https://cmake.org/licensing for details. */
  5. #pragma once
  6. #include <iterator> // IWYU pragma: export
  7. namespace cm {
  8. #if __cplusplus >= 201402L || defined(_MSVC_LANG) && _MSVC_LANG >= 201402L
  9. using std::make_reverse_iterator;
  10. using std::cbegin;
  11. using std::cend;
  12. using std::rbegin;
  13. using std::rend;
  14. using std::crbegin;
  15. using std::crend;
  16. #else
  17. template <class Iter>
  18. std::reverse_iterator<Iter> make_reverse_iterator(Iter it)
  19. {
  20. return std::reverse_iterator<Iter>(it);
  21. }
  22. // std::c{begin,end} backport from C++14
  23. template <class C>
  24. # if defined(_MSC_VER) && _MSC_VER < 1900
  25. auto cbegin(C const& c)
  26. # else
  27. constexpr auto cbegin(C const& c) noexcept(noexcept(std::begin(c)))
  28. # endif
  29. -> decltype(std::begin(c))
  30. {
  31. return std::begin(c);
  32. }
  33. template <class C>
  34. # if defined(_MSC_VER) && _MSC_VER < 1900
  35. auto cend(C const& c)
  36. # else
  37. constexpr auto cend(C const& c) noexcept(noexcept(std::end(c)))
  38. # endif
  39. -> decltype(std::end(c))
  40. {
  41. return std::end(c);
  42. }
  43. // std::r{begin,end} backport from C++14
  44. template <class C>
  45. # if !defined(_MSC_VER) || _MSC_VER >= 1900
  46. constexpr
  47. # endif
  48. auto
  49. rbegin(C& c) -> decltype(c.rbegin())
  50. {
  51. return c.rbegin();
  52. }
  53. template <class C>
  54. # if !defined(_MSC_VER) || _MSC_VER >= 1900
  55. constexpr
  56. # endif
  57. auto
  58. rbegin(C const& c) -> decltype(c.rbegin())
  59. {
  60. return c.rbegin();
  61. }
  62. template <typename T, size_t N>
  63. # if !defined(_MSC_VER) || _MSC_VER >= 1900
  64. constexpr
  65. # endif
  66. std::reverse_iterator<T*>
  67. rbegin(T (&arr)[N])
  68. {
  69. return std::reverse_iterator<T*>(arr + N);
  70. }
  71. template <class C>
  72. # if !defined(_MSC_VER) || _MSC_VER >= 1900
  73. constexpr
  74. # endif
  75. auto
  76. rend(C& c) -> decltype(c.rend())
  77. {
  78. return c.rend();
  79. }
  80. template <class C>
  81. # if !defined(_MSC_VER) || _MSC_VER >= 1900
  82. constexpr
  83. # endif
  84. auto
  85. rend(C const& c) -> decltype(c.rend())
  86. {
  87. return c.rend();
  88. }
  89. template <typename T, size_t N>
  90. # if !defined(_MSC_VER) || _MSC_VER >= 1900
  91. constexpr
  92. # endif
  93. std::reverse_iterator<T*>
  94. rend(T (&arr)[N])
  95. {
  96. return std::reverse_iterator<T*>(arr);
  97. }
  98. // std::cr{begin,end} backport from C++14
  99. template <class C>
  100. # if !defined(_MSC_VER) || _MSC_VER >= 1900
  101. constexpr
  102. # endif
  103. auto
  104. crbegin(C const& c) -> decltype(cm::rbegin(c))
  105. {
  106. return cm::rbegin(c);
  107. }
  108. template <class C>
  109. # if !defined(_MSC_VER) || _MSC_VER >= 1900
  110. constexpr
  111. # endif
  112. auto
  113. crend(C const& c) -> decltype(cm::rend(c))
  114. {
  115. return cm::rend(c);
  116. }
  117. #endif
  118. #if __cplusplus >= 201703L || defined(_MSVC_LANG) && _MSVC_LANG >= 201703L
  119. using std::size;
  120. using std::empty;
  121. using std::data;
  122. #else
  123. // std::size backport from C++17.
  124. template <class C>
  125. # if !defined(_MSC_VER) || _MSC_VER >= 1900
  126. constexpr
  127. # endif
  128. auto
  129. size(C const& c) -> decltype(c.size())
  130. {
  131. return c.size();
  132. }
  133. template <typename T, size_t N>
  134. # if !defined(_MSC_VER) || _MSC_VER >= 1900
  135. constexpr
  136. # endif
  137. std::size_t
  138. size(const T (&)[N]) throw()
  139. {
  140. return N;
  141. }
  142. // std::empty backport from C++17.
  143. template <class C>
  144. # if defined(_MSC_VER) && _MSC_VER < 1900
  145. auto empty(C const& c)
  146. # else
  147. constexpr auto empty(C const& c) noexcept(noexcept(c.empty()))
  148. # endif
  149. -> decltype(c.empty())
  150. {
  151. return c.empty();
  152. }
  153. template <typename T, size_t N>
  154. # if defined(_MSC_VER) && _MSC_VER < 1900
  155. bool empty(const T (&)[N])
  156. # else
  157. constexpr bool empty(const T (&)[N]) noexcept
  158. # endif
  159. {
  160. return false;
  161. }
  162. // std::data backport from C++17.
  163. template <class C>
  164. # if defined(_MSC_VER) && _MSC_VER < 1900
  165. auto data(C const& c)
  166. # else
  167. constexpr auto data(C const& c) noexcept(noexcept(c.data()))
  168. # endif
  169. -> decltype(c.data())
  170. {
  171. return c.data();
  172. }
  173. template <class C>
  174. # if defined(_MSC_VER) && _MSC_VER < 1900
  175. auto data(C& c)
  176. # else
  177. constexpr auto data(C& c) noexcept(noexcept(c.data()))
  178. # endif
  179. -> decltype(c.data())
  180. {
  181. return c.data();
  182. }
  183. template <typename T, size_t N>
  184. # if defined(_MSC_VER) && _MSC_VER < 1900
  185. T* data(T (&)[N])
  186. # else
  187. constexpr T* data(T (&arr)[N]) noexcept
  188. # endif
  189. {
  190. return arr;
  191. }
  192. #endif
  193. } // namespace cm