range_access.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345
  1. // Range access functions for containers -*- C++ -*-
  2. // Copyright (C) 2010-2021 Free Software Foundation, Inc.
  3. //
  4. // This file is part of the GNU ISO C++ Library. This library is free
  5. // software; you can redistribute it and/or modify it under the
  6. // terms of the GNU General Public License as published by the
  7. // Free Software Foundation; either version 3, or (at your option)
  8. // any later version.
  9. // This library is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. // Under Section 7 of GPL version 3, you are granted additional
  14. // permissions described in the GCC Runtime Library Exception, version
  15. // 3.1, as published by the Free Software Foundation.
  16. // You should have received a copy of the GNU General Public License and
  17. // a copy of the GCC Runtime Library Exception along with this program;
  18. // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
  19. // <http://www.gnu.org/licenses/>.
  20. /** @file bits/range_access.h
  21. * This is an internal header file, included by other library headers.
  22. * Do not attempt to use it directly. @headername{iterator}
  23. */
  24. #ifndef _GLIBCXX_RANGE_ACCESS_H
  25. #define _GLIBCXX_RANGE_ACCESS_H 1
  26. #pragma GCC system_header
  27. #if __cplusplus >= 201103L
  28. #include <initializer_list>
  29. #include <type_traits> // common_type_t, make_signed_t
  30. #include <bits/stl_iterator.h> // reverse_iterator
  31. namespace std _GLIBCXX_VISIBILITY(default)
  32. {
  33. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  34. /**
  35. * @brief Return an iterator pointing to the first element of
  36. * the container.
  37. * @param __cont Container.
  38. */
  39. template<typename _Container>
  40. inline _GLIBCXX17_CONSTEXPR auto
  41. begin(_Container& __cont) -> decltype(__cont.begin())
  42. { return __cont.begin(); }
  43. /**
  44. * @brief Return an iterator pointing to the first element of
  45. * the const container.
  46. * @param __cont Container.
  47. */
  48. template<typename _Container>
  49. inline _GLIBCXX17_CONSTEXPR auto
  50. begin(const _Container& __cont) -> decltype(__cont.begin())
  51. { return __cont.begin(); }
  52. /**
  53. * @brief Return an iterator pointing to one past the last element of
  54. * the container.
  55. * @param __cont Container.
  56. */
  57. template<typename _Container>
  58. inline _GLIBCXX17_CONSTEXPR auto
  59. end(_Container& __cont) -> decltype(__cont.end())
  60. { return __cont.end(); }
  61. /**
  62. * @brief Return an iterator pointing to one past the last element of
  63. * the const container.
  64. * @param __cont Container.
  65. */
  66. template<typename _Container>
  67. inline _GLIBCXX17_CONSTEXPR auto
  68. end(const _Container& __cont) -> decltype(__cont.end())
  69. { return __cont.end(); }
  70. /**
  71. * @brief Return an iterator pointing to the first element of the array.
  72. * @param __arr Array.
  73. */
  74. template<typename _Tp, size_t _Nm>
  75. inline _GLIBCXX14_CONSTEXPR _Tp*
  76. begin(_Tp (&__arr)[_Nm]) noexcept
  77. { return __arr; }
  78. /**
  79. * @brief Return an iterator pointing to one past the last element
  80. * of the array.
  81. * @param __arr Array.
  82. */
  83. template<typename _Tp, size_t _Nm>
  84. inline _GLIBCXX14_CONSTEXPR _Tp*
  85. end(_Tp (&__arr)[_Nm]) noexcept
  86. { return __arr + _Nm; }
  87. #if __cplusplus >= 201402L
  88. template<typename _Tp> class valarray;
  89. // These overloads must be declared for cbegin and cend to use them.
  90. template<typename _Tp> _Tp* begin(valarray<_Tp>&);
  91. template<typename _Tp> const _Tp* begin(const valarray<_Tp>&);
  92. template<typename _Tp> _Tp* end(valarray<_Tp>&);
  93. template<typename _Tp> const _Tp* end(const valarray<_Tp>&);
  94. /**
  95. * @brief Return an iterator pointing to the first element of
  96. * the const container.
  97. * @param __cont Container.
  98. */
  99. template<typename _Container>
  100. inline constexpr auto
  101. cbegin(const _Container& __cont) noexcept(noexcept(std::begin(__cont)))
  102. -> decltype(std::begin(__cont))
  103. { return std::begin(__cont); }
  104. /**
  105. * @brief Return an iterator pointing to one past the last element of
  106. * the const container.
  107. * @param __cont Container.
  108. */
  109. template<typename _Container>
  110. inline constexpr auto
  111. cend(const _Container& __cont) noexcept(noexcept(std::end(__cont)))
  112. -> decltype(std::end(__cont))
  113. { return std::end(__cont); }
  114. /**
  115. * @brief Return a reverse iterator pointing to the last element of
  116. * the container.
  117. * @param __cont Container.
  118. */
  119. template<typename _Container>
  120. inline _GLIBCXX17_CONSTEXPR auto
  121. rbegin(_Container& __cont) -> decltype(__cont.rbegin())
  122. { return __cont.rbegin(); }
  123. /**
  124. * @brief Return a reverse iterator pointing to the last element of
  125. * the const container.
  126. * @param __cont Container.
  127. */
  128. template<typename _Container>
  129. inline _GLIBCXX17_CONSTEXPR auto
  130. rbegin(const _Container& __cont) -> decltype(__cont.rbegin())
  131. { return __cont.rbegin(); }
  132. /**
  133. * @brief Return a reverse iterator pointing one past the first element of
  134. * the container.
  135. * @param __cont Container.
  136. */
  137. template<typename _Container>
  138. inline _GLIBCXX17_CONSTEXPR auto
  139. rend(_Container& __cont) -> decltype(__cont.rend())
  140. { return __cont.rend(); }
  141. /**
  142. * @brief Return a reverse iterator pointing one past the first element of
  143. * the const container.
  144. * @param __cont Container.
  145. */
  146. template<typename _Container>
  147. inline _GLIBCXX17_CONSTEXPR auto
  148. rend(const _Container& __cont) -> decltype(__cont.rend())
  149. { return __cont.rend(); }
  150. /**
  151. * @brief Return a reverse iterator pointing to the last element of
  152. * the array.
  153. * @param __arr Array.
  154. */
  155. template<typename _Tp, size_t _Nm>
  156. inline _GLIBCXX17_CONSTEXPR reverse_iterator<_Tp*>
  157. rbegin(_Tp (&__arr)[_Nm]) noexcept
  158. { return reverse_iterator<_Tp*>(__arr + _Nm); }
  159. /**
  160. * @brief Return a reverse iterator pointing one past the first element of
  161. * the array.
  162. * @param __arr Array.
  163. */
  164. template<typename _Tp, size_t _Nm>
  165. inline _GLIBCXX17_CONSTEXPR reverse_iterator<_Tp*>
  166. rend(_Tp (&__arr)[_Nm]) noexcept
  167. { return reverse_iterator<_Tp*>(__arr); }
  168. /**
  169. * @brief Return a reverse iterator pointing to the last element of
  170. * the initializer_list.
  171. * @param __il initializer_list.
  172. */
  173. template<typename _Tp>
  174. inline _GLIBCXX17_CONSTEXPR reverse_iterator<const _Tp*>
  175. rbegin(initializer_list<_Tp> __il) noexcept
  176. { return reverse_iterator<const _Tp*>(__il.end()); }
  177. /**
  178. * @brief Return a reverse iterator pointing one past the first element of
  179. * the initializer_list.
  180. * @param __il initializer_list.
  181. */
  182. template<typename _Tp>
  183. inline _GLIBCXX17_CONSTEXPR reverse_iterator<const _Tp*>
  184. rend(initializer_list<_Tp> __il) noexcept
  185. { return reverse_iterator<const _Tp*>(__il.begin()); }
  186. /**
  187. * @brief Return a reverse iterator pointing to the last element of
  188. * the const container.
  189. * @param __cont Container.
  190. */
  191. template<typename _Container>
  192. inline _GLIBCXX17_CONSTEXPR auto
  193. crbegin(const _Container& __cont) -> decltype(std::rbegin(__cont))
  194. { return std::rbegin(__cont); }
  195. /**
  196. * @brief Return a reverse iterator pointing one past the first element of
  197. * the const container.
  198. * @param __cont Container.
  199. */
  200. template<typename _Container>
  201. inline _GLIBCXX17_CONSTEXPR auto
  202. crend(const _Container& __cont) -> decltype(std::rend(__cont))
  203. { return std::rend(__cont); }
  204. #endif // C++14
  205. #if __cplusplus >= 201703L
  206. #define __cpp_lib_nonmember_container_access 201411
  207. /**
  208. * @brief Return the size of a container.
  209. * @param __cont Container.
  210. */
  211. template <typename _Container>
  212. constexpr auto
  213. size(const _Container& __cont) noexcept(noexcept(__cont.size()))
  214. -> decltype(__cont.size())
  215. { return __cont.size(); }
  216. /**
  217. * @brief Return the size of an array.
  218. */
  219. template <typename _Tp, size_t _Nm>
  220. constexpr size_t
  221. size(const _Tp (&)[_Nm]) noexcept
  222. { return _Nm; }
  223. /**
  224. * @brief Return whether a container is empty.
  225. * @param __cont Container.
  226. */
  227. template <typename _Container>
  228. [[nodiscard]] constexpr auto
  229. empty(const _Container& __cont) noexcept(noexcept(__cont.empty()))
  230. -> decltype(__cont.empty())
  231. { return __cont.empty(); }
  232. /**
  233. * @brief Return whether an array is empty (always false).
  234. */
  235. template <typename _Tp, size_t _Nm>
  236. [[nodiscard]] constexpr bool
  237. empty(const _Tp (&)[_Nm]) noexcept
  238. { return false; }
  239. /**
  240. * @brief Return whether an initializer_list is empty.
  241. * @param __il Initializer list.
  242. */
  243. template <typename _Tp>
  244. [[nodiscard]] constexpr bool
  245. empty(initializer_list<_Tp> __il) noexcept
  246. { return __il.size() == 0;}
  247. /**
  248. * @brief Return the data pointer of a container.
  249. * @param __cont Container.
  250. */
  251. template <typename _Container>
  252. constexpr auto
  253. data(_Container& __cont) noexcept(noexcept(__cont.data()))
  254. -> decltype(__cont.data())
  255. { return __cont.data(); }
  256. /**
  257. * @brief Return the data pointer of a const container.
  258. * @param __cont Container.
  259. */
  260. template <typename _Container>
  261. constexpr auto
  262. data(const _Container& __cont) noexcept(noexcept(__cont.data()))
  263. -> decltype(__cont.data())
  264. { return __cont.data(); }
  265. /**
  266. * @brief Return the data pointer of an array.
  267. * @param __array Array.
  268. */
  269. template <typename _Tp, size_t _Nm>
  270. constexpr _Tp*
  271. data(_Tp (&__array)[_Nm]) noexcept
  272. { return __array; }
  273. /**
  274. * @brief Return the data pointer of an initializer list.
  275. * @param __il Initializer list.
  276. */
  277. template <typename _Tp>
  278. constexpr const _Tp*
  279. data(initializer_list<_Tp> __il) noexcept
  280. { return __il.begin(); }
  281. #if __cplusplus > 201703L
  282. #define __cpp_lib_ssize 201902L
  283. template<typename _Container>
  284. constexpr auto
  285. ssize(const _Container& __cont)
  286. noexcept(noexcept(__cont.size()))
  287. -> common_type_t<ptrdiff_t, make_signed_t<decltype(__cont.size())>>
  288. {
  289. using type = make_signed_t<decltype(__cont.size())>;
  290. return static_cast<common_type_t<ptrdiff_t, type>>(__cont.size());
  291. }
  292. template<typename _Tp, ptrdiff_t _Num>
  293. constexpr ptrdiff_t
  294. ssize(const _Tp (&)[_Num]) noexcept
  295. { return _Num; }
  296. #endif // C++20
  297. #endif // C++17
  298. _GLIBCXX_END_NAMESPACE_VERSION
  299. } // namespace
  300. #endif // C++11
  301. #endif // _GLIBCXX_RANGE_ACCESS_H