range_access.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371
  1. // Range access functions for containers -*- C++ -*-
  2. // Copyright (C) 2010-2022 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. [[__nodiscard__]]
  41. inline _GLIBCXX17_CONSTEXPR auto
  42. begin(_Container& __cont) -> decltype(__cont.begin())
  43. { return __cont.begin(); }
  44. /**
  45. * @brief Return an iterator pointing to the first element of
  46. * the const container.
  47. * @param __cont Container.
  48. */
  49. template<typename _Container>
  50. [[__nodiscard__]]
  51. inline _GLIBCXX17_CONSTEXPR auto
  52. begin(const _Container& __cont) -> decltype(__cont.begin())
  53. { return __cont.begin(); }
  54. /**
  55. * @brief Return an iterator pointing to one past the last element of
  56. * the container.
  57. * @param __cont Container.
  58. */
  59. template<typename _Container>
  60. [[__nodiscard__]]
  61. inline _GLIBCXX17_CONSTEXPR auto
  62. end(_Container& __cont) -> decltype(__cont.end())
  63. { return __cont.end(); }
  64. /**
  65. * @brief Return an iterator pointing to one past the last element of
  66. * the const container.
  67. * @param __cont Container.
  68. */
  69. template<typename _Container>
  70. [[__nodiscard__]]
  71. inline _GLIBCXX17_CONSTEXPR auto
  72. end(const _Container& __cont) -> decltype(__cont.end())
  73. { return __cont.end(); }
  74. /**
  75. * @brief Return an iterator pointing to the first element of the array.
  76. * @param __arr Array.
  77. */
  78. template<typename _Tp, size_t _Nm>
  79. [[__nodiscard__]]
  80. inline _GLIBCXX14_CONSTEXPR _Tp*
  81. begin(_Tp (&__arr)[_Nm]) noexcept
  82. { return __arr; }
  83. /**
  84. * @brief Return an iterator pointing to one past the last element
  85. * of the array.
  86. * @param __arr Array.
  87. */
  88. template<typename _Tp, size_t _Nm>
  89. [[__nodiscard__]]
  90. inline _GLIBCXX14_CONSTEXPR _Tp*
  91. end(_Tp (&__arr)[_Nm]) noexcept
  92. { return __arr + _Nm; }
  93. #if __cplusplus >= 201402L
  94. template<typename _Tp> class valarray;
  95. // These overloads must be declared for cbegin and cend to use them.
  96. template<typename _Tp> _Tp* begin(valarray<_Tp>&) noexcept;
  97. template<typename _Tp> const _Tp* begin(const valarray<_Tp>&) noexcept;
  98. template<typename _Tp> _Tp* end(valarray<_Tp>&) noexcept;
  99. template<typename _Tp> const _Tp* end(const valarray<_Tp>&) noexcept;
  100. /**
  101. * @brief Return an iterator pointing to the first element of
  102. * the const container.
  103. * @param __cont Container.
  104. */
  105. template<typename _Container>
  106. [[__nodiscard__]]
  107. constexpr auto
  108. cbegin(const _Container& __cont) noexcept(noexcept(std::begin(__cont)))
  109. -> decltype(std::begin(__cont))
  110. { return std::begin(__cont); }
  111. /**
  112. * @brief Return an iterator pointing to one past the last element of
  113. * the const container.
  114. * @param __cont Container.
  115. */
  116. template<typename _Container>
  117. [[__nodiscard__]]
  118. constexpr auto
  119. cend(const _Container& __cont) noexcept(noexcept(std::end(__cont)))
  120. -> decltype(std::end(__cont))
  121. { return std::end(__cont); }
  122. /**
  123. * @brief Return a reverse iterator pointing to the last element of
  124. * the container.
  125. * @param __cont Container.
  126. */
  127. template<typename _Container>
  128. [[__nodiscard__]]
  129. inline _GLIBCXX17_CONSTEXPR auto
  130. rbegin(_Container& __cont) -> decltype(__cont.rbegin())
  131. { return __cont.rbegin(); }
  132. /**
  133. * @brief Return a reverse iterator pointing to the last element of
  134. * the const container.
  135. * @param __cont Container.
  136. */
  137. template<typename _Container>
  138. [[__nodiscard__]]
  139. inline _GLIBCXX17_CONSTEXPR auto
  140. rbegin(const _Container& __cont) -> decltype(__cont.rbegin())
  141. { return __cont.rbegin(); }
  142. /**
  143. * @brief Return a reverse iterator pointing one past the first element of
  144. * the container.
  145. * @param __cont Container.
  146. */
  147. template<typename _Container>
  148. [[__nodiscard__]]
  149. inline _GLIBCXX17_CONSTEXPR auto
  150. rend(_Container& __cont) -> decltype(__cont.rend())
  151. { return __cont.rend(); }
  152. /**
  153. * @brief Return a reverse iterator pointing one past the first element of
  154. * the const container.
  155. * @param __cont Container.
  156. */
  157. template<typename _Container>
  158. [[__nodiscard__]]
  159. inline _GLIBCXX17_CONSTEXPR auto
  160. rend(const _Container& __cont) -> decltype(__cont.rend())
  161. { return __cont.rend(); }
  162. /**
  163. * @brief Return a reverse iterator pointing to the last element of
  164. * the array.
  165. * @param __arr Array.
  166. */
  167. template<typename _Tp, size_t _Nm>
  168. [[__nodiscard__]]
  169. inline _GLIBCXX17_CONSTEXPR reverse_iterator<_Tp*>
  170. rbegin(_Tp (&__arr)[_Nm]) noexcept
  171. { return reverse_iterator<_Tp*>(__arr + _Nm); }
  172. /**
  173. * @brief Return a reverse iterator pointing one past the first element of
  174. * the array.
  175. * @param __arr Array.
  176. */
  177. template<typename _Tp, size_t _Nm>
  178. [[__nodiscard__]]
  179. inline _GLIBCXX17_CONSTEXPR reverse_iterator<_Tp*>
  180. rend(_Tp (&__arr)[_Nm]) noexcept
  181. { return reverse_iterator<_Tp*>(__arr); }
  182. /**
  183. * @brief Return a reverse iterator pointing to the last element of
  184. * the initializer_list.
  185. * @param __il initializer_list.
  186. */
  187. template<typename _Tp>
  188. [[__nodiscard__]]
  189. inline _GLIBCXX17_CONSTEXPR reverse_iterator<const _Tp*>
  190. rbegin(initializer_list<_Tp> __il) noexcept
  191. { return reverse_iterator<const _Tp*>(__il.end()); }
  192. /**
  193. * @brief Return a reverse iterator pointing one past the first element of
  194. * the initializer_list.
  195. * @param __il initializer_list.
  196. */
  197. template<typename _Tp>
  198. [[__nodiscard__]]
  199. inline _GLIBCXX17_CONSTEXPR reverse_iterator<const _Tp*>
  200. rend(initializer_list<_Tp> __il) noexcept
  201. { return reverse_iterator<const _Tp*>(__il.begin()); }
  202. /**
  203. * @brief Return a reverse iterator pointing to the last element of
  204. * the const container.
  205. * @param __cont Container.
  206. */
  207. template<typename _Container>
  208. [[__nodiscard__]]
  209. inline _GLIBCXX17_CONSTEXPR auto
  210. crbegin(const _Container& __cont) -> decltype(std::rbegin(__cont))
  211. { return std::rbegin(__cont); }
  212. /**
  213. * @brief Return a reverse iterator pointing one past the first element of
  214. * the const container.
  215. * @param __cont Container.
  216. */
  217. template<typename _Container>
  218. [[__nodiscard__]]
  219. inline _GLIBCXX17_CONSTEXPR auto
  220. crend(const _Container& __cont) -> decltype(std::rend(__cont))
  221. { return std::rend(__cont); }
  222. #endif // C++14
  223. #if __cplusplus >= 201703L
  224. #define __cpp_lib_nonmember_container_access 201411L
  225. /**
  226. * @brief Return the size of a container.
  227. * @param __cont Container.
  228. */
  229. template <typename _Container>
  230. [[nodiscard]]
  231. constexpr auto
  232. size(const _Container& __cont) noexcept(noexcept(__cont.size()))
  233. -> decltype(__cont.size())
  234. { return __cont.size(); }
  235. /**
  236. * @brief Return the size of an array.
  237. */
  238. template <typename _Tp, size_t _Nm>
  239. [[nodiscard]]
  240. constexpr size_t
  241. size(const _Tp (&)[_Nm]) noexcept
  242. { return _Nm; }
  243. /**
  244. * @brief Return whether a container is empty.
  245. * @param __cont Container.
  246. */
  247. template <typename _Container>
  248. [[nodiscard]] constexpr auto
  249. empty(const _Container& __cont) noexcept(noexcept(__cont.empty()))
  250. -> decltype(__cont.empty())
  251. { return __cont.empty(); }
  252. /**
  253. * @brief Return whether an array is empty (always false).
  254. */
  255. template <typename _Tp, size_t _Nm>
  256. [[nodiscard]] constexpr bool
  257. empty(const _Tp (&)[_Nm]) noexcept
  258. { return false; }
  259. /**
  260. * @brief Return whether an initializer_list is empty.
  261. * @param __il Initializer list.
  262. */
  263. template <typename _Tp>
  264. [[nodiscard]] constexpr bool
  265. empty(initializer_list<_Tp> __il) noexcept
  266. { return __il.size() == 0;}
  267. /**
  268. * @brief Return the data pointer of a container.
  269. * @param __cont Container.
  270. */
  271. template <typename _Container>
  272. [[nodiscard]]
  273. constexpr auto
  274. data(_Container& __cont) noexcept(noexcept(__cont.data()))
  275. -> decltype(__cont.data())
  276. { return __cont.data(); }
  277. /**
  278. * @brief Return the data pointer of a const container.
  279. * @param __cont Container.
  280. */
  281. template <typename _Container>
  282. [[nodiscard]]
  283. constexpr auto
  284. data(const _Container& __cont) noexcept(noexcept(__cont.data()))
  285. -> decltype(__cont.data())
  286. { return __cont.data(); }
  287. /**
  288. * @brief Return the data pointer of an array.
  289. * @param __array Array.
  290. */
  291. template <typename _Tp, size_t _Nm>
  292. [[nodiscard]]
  293. constexpr _Tp*
  294. data(_Tp (&__array)[_Nm]) noexcept
  295. { return __array; }
  296. /**
  297. * @brief Return the data pointer of an initializer list.
  298. * @param __il Initializer list.
  299. */
  300. template <typename _Tp>
  301. [[nodiscard]]
  302. constexpr const _Tp*
  303. data(initializer_list<_Tp> __il) noexcept
  304. { return __il.begin(); }
  305. #if __cplusplus > 201703L
  306. #define __cpp_lib_ssize 201902L
  307. template<typename _Container>
  308. [[nodiscard]]
  309. constexpr auto
  310. ssize(const _Container& __cont)
  311. noexcept(noexcept(__cont.size()))
  312. -> common_type_t<ptrdiff_t, make_signed_t<decltype(__cont.size())>>
  313. {
  314. using type = make_signed_t<decltype(__cont.size())>;
  315. return static_cast<common_type_t<ptrdiff_t, type>>(__cont.size());
  316. }
  317. template<typename _Tp, ptrdiff_t _Num>
  318. [[nodiscard]]
  319. constexpr ptrdiff_t
  320. ssize(const _Tp (&)[_Num]) noexcept
  321. { return _Num; }
  322. #endif // C++20
  323. #endif // C++17
  324. _GLIBCXX_END_NAMESPACE_VERSION
  325. } // namespace
  326. #endif // C++11
  327. #endif // _GLIBCXX_RANGE_ACCESS_H