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