Where Online Learning is simpler!
The C and C++ Include Header Files
/usr/include/c++/13/bits/ranges_algobase.h
$ cat -n /usr/include/c++/13/bits/ranges_algobase.h 1 // Core algorithmic facilities -*- C++ -*- 2 3 // Copyright (C) 2020-2023 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 //
. 24 25 /** @file bits/ranges_algobase.h 26 * This is an internal header file, included by other library headers. 27 * Do not attempt to use it directly. @headername{algorithm} 28 */ 29 30 #ifndef _RANGES_ALGOBASE_H 31 #define _RANGES_ALGOBASE_H 1 32 33 #if __cplusplus > 201703L 34 35 #include
36 #include
37 #include
38 #include
// ranges::begin, ranges::range etc. 39 #include
// __invoke 40 #include
// __is_byte 41 42 #if __cpp_lib_concepts 43 namespace std _GLIBCXX_VISIBILITY(default) 44 { 45 _GLIBCXX_BEGIN_NAMESPACE_VERSION 46 namespace ranges 47 { 48 namespace __detail 49 { 50 template
51 constexpr inline bool __is_normal_iterator = false; 52 53 template
54 constexpr inline bool 55 __is_normal_iterator<__gnu_cxx::__normal_iterator<_Iterator, 56 _Container>> = true; 57 58 template
59 constexpr inline bool __is_reverse_iterator = false; 60 61 template
62 constexpr inline bool 63 __is_reverse_iterator
> = true; 64 65 template
66 constexpr inline bool __is_move_iterator = false; 67 68 template
69 constexpr inline bool 70 __is_move_iterator
> = true; 71 } // namespace __detail 72 73 struct __equal_fn 74 { 75 template
_Sent1, 76 input_iterator _Iter2, sentinel_for<_Iter2> _Sent2, 77 typename _Pred = ranges::equal_to, 78 typename _Proj1 = identity, typename _Proj2 = identity> 79 requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2> 80 constexpr bool 81 operator()(_Iter1 __first1, _Sent1 __last1, 82 _Iter2 __first2, _Sent2 __last2, _Pred __pred = {}, 83 _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const 84 { 85 // TODO: implement more specializations to at least have parity with 86 // std::equal. 87 if constexpr (__detail::__is_normal_iterator<_Iter1> 88 && same_as<_Iter1, _Sent1>) 89 return (*this)(__first1.base(), __last1.base(), 90 std::move(__first2), std::move(__last2), 91 std::move(__pred), 92 std::move(__proj1), std::move(__proj2)); 93 else if constexpr (__detail::__is_normal_iterator<_Iter2> 94 && same_as<_Iter2, _Sent2>) 95 return (*this)(std::move(__first1), std::move(__last1), 96 __first2.base(), __last2.base(), 97 std::move(__pred), 98 std::move(__proj1), std::move(__proj2)); 99 else if constexpr (sized_sentinel_for<_Sent1, _Iter1> 100 && sized_sentinel_for<_Sent2, _Iter2>) 101 { 102 auto __d1 = ranges::distance(__first1, __last1); 103 auto __d2 = ranges::distance(__first2, __last2); 104 if (__d1 != __d2) 105 return false; 106 107 using _ValueType1 = iter_value_t<_Iter1>; 108 constexpr bool __use_memcmp 109 = ((is_integral_v<_ValueType1> || is_pointer_v<_ValueType1>) 110 && __memcmpable<_Iter1, _Iter2>::__value 111 && is_same_v<_Pred, ranges::equal_to> 112 && is_same_v<_Proj1, identity> 113 && is_same_v<_Proj2, identity>); 114 if constexpr (__use_memcmp) 115 { 116 if (const size_t __len = (__last1 - __first1)) 117 return !std::__memcmp(__first1, __first2, __len); 118 return true; 119 } 120 else 121 { 122 for (; __first1 != __last1; ++__first1, (void)++__first2) 123 if (!(bool)std::__invoke(__pred, 124 std::__invoke(__proj1, *__first1), 125 std::__invoke(__proj2, *__first2))) 126 return false; 127 return true; 128 } 129 } 130 else 131 { 132 for (; __first1 != __last1 && __first2 != __last2; 133 ++__first1, (void)++__first2) 134 if (!(bool)std::__invoke(__pred, 135 std::__invoke(__proj1, *__first1), 136 std::__invoke(__proj2, *__first2))) 137 return false; 138 return __first1 == __last1 && __first2 == __last2; 139 } 140 } 141 142 template
145 requires indirectly_comparable
, iterator_t<_Range2>, 146 _Pred, _Proj1, _Proj2> 147 constexpr bool 148 operator()(_Range1&& __r1, _Range2&& __r2, _Pred __pred = {}, 149 _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const 150 { 151 return (*this)(ranges::begin(__r1), ranges::end(__r1), 152 ranges::begin(__r2), ranges::end(__r2), 153 std::move(__pred), 154 std::move(__proj1), std::move(__proj2)); 155 } 156 }; 157 158 inline constexpr __equal_fn equal{}; 159 160 template
161 struct in_out_result 162 { 163 [[no_unique_address]] _Iter in; 164 [[no_unique_address]] _Out out; 165 166 template
167 requires convertible_to
168 && convertible_to
169 constexpr 170 operator in_out_result<_Iter2, _Out2>() const & 171 { return {in, out}; } 172 173 template
174 requires convertible_to<_Iter, _Iter2> 175 && convertible_to<_Out, _Out2> 176 constexpr 177 operator in_out_result<_Iter2, _Out2>() && 178 { return {std::move(in), std::move(out)}; } 179 }; 180 181 template
182 using copy_result = in_out_result<_Iter, _Out>; 183 184 template
185 using move_result = in_out_result<_Iter, _Out>; 186 187 template
188 using move_backward_result = in_out_result<_Iter1, _Iter2>; 189 190 template
191 using copy_backward_result = in_out_result<_Iter1, _Iter2>; 192 193 template
_Sent, 195 bidirectional_iterator _Out> 196 requires (_IsMove 197 ? indirectly_movable<_Iter, _Out> 198 : indirectly_copyable<_Iter, _Out>) 199 constexpr __conditional_t<_IsMove, 200 move_backward_result<_Iter, _Out>, 201 copy_backward_result<_Iter, _Out>> 202 __copy_or_move_backward(_Iter __first, _Sent __last, _Out __result); 203 204 template
_Sent, 206 weakly_incrementable _Out> 207 requires (_IsMove 208 ? indirectly_movable<_Iter, _Out> 209 : indirectly_copyable<_Iter, _Out>) 210 constexpr __conditional_t<_IsMove, 211 move_result<_Iter, _Out>, 212 copy_result<_Iter, _Out>> 213 __copy_or_move(_Iter __first, _Sent __last, _Out __result) 214 { 215 // TODO: implement more specializations to be at least on par with 216 // std::copy/std::move. 217 using __detail::__is_move_iterator; 218 using __detail::__is_reverse_iterator; 219 using __detail::__is_normal_iterator; 220 if constexpr (__is_move_iterator<_Iter> && same_as<_Iter, _Sent>) 221 { 222 auto [__in, __out] 223 = ranges::__copy_or_move
(std::move(__first).base(), 224 std::move(__last).base(), 225 std::move(__result)); 226 return {move_iterator{std::move(__in)}, std::move(__out)}; 227 } 228 else if constexpr (__is_reverse_iterator<_Iter> && same_as<_Iter, _Sent> 229 && __is_reverse_iterator<_Out>) 230 { 231 auto [__in,__out] 232 = ranges::__copy_or_move_backward<_IsMove>(std::move(__last).base(), 233 std::move(__first).base(), 234 std::move(__result).base()); 235 return {reverse_iterator{std::move(__in)}, 236 reverse_iterator{std::move(__out)}}; 237 } 238 else if constexpr (__is_normal_iterator<_Iter> && same_as<_Iter, _Sent>) 239 { 240 auto [__in,__out] 241 = ranges::__copy_or_move<_IsMove>(__first.base(), __last.base(), 242 std::move(__result)); 243 return {decltype(__first){__in}, std::move(__out)}; 244 } 245 else if constexpr (__is_normal_iterator<_Out>) 246 { 247 auto [__in,__out] 248 = ranges::__copy_or_move<_IsMove>(std::move(__first), __last, __result.base()); 249 return {std::move(__in), decltype(__result){__out}}; 250 } 251 else if constexpr (sized_sentinel_for<_Sent, _Iter>) 252 { 253 if (!std::__is_constant_evaluated()) 254 { 255 if constexpr (__memcpyable<_Iter, _Out>::__value) 256 { 257 using _ValueTypeI = iter_value_t<_Iter>; 258 static_assert(_IsMove 259 ? is_move_assignable_v<_ValueTypeI> 260 : is_copy_assignable_v<_ValueTypeI>); 261 auto __num = __last - __first; 262 if (__num) 263 __builtin_memmove(__result, __first, 264 sizeof(_ValueTypeI) * __num); 265 return {__first + __num, __result + __num}; 266 } 267 } 268 269 for (auto __n = __last - __first; __n > 0; --__n) 270 { 271 if constexpr (_IsMove) 272 *__result = std::move(*__first); 273 else 274 *__result = *__first; 275 ++__first; 276 ++__result; 277 } 278 return {std::move(__first), std::move(__result)}; 279 } 280 else 281 { 282 while (__first != __last) 283 { 284 if constexpr (_IsMove) 285 *__result = std::move(*__first); 286 else 287 *__result = *__first; 288 ++__first; 289 ++__result; 290 } 291 return {std::move(__first), std::move(__result)}; 292 } 293 } 294 295 struct __copy_fn 296 { 297 template
_Sent, 298 weakly_incrementable _Out> 299 requires indirectly_copyable<_Iter, _Out> 300 constexpr copy_result<_Iter, _Out> 301 operator()(_Iter __first, _Sent __last, _Out __result) const 302 { 303 return ranges::__copy_or_move
(std::move(__first), 304 std::move(__last), 305 std::move(__result)); 306 } 307 308 template
309 requires indirectly_copyable
, _Out> 310 constexpr copy_result
, _Out> 311 operator()(_Range&& __r, _Out __result) const 312 { 313 return (*this)(ranges::begin(__r), ranges::end(__r), 314 std::move(__result)); 315 } 316 }; 317 318 inline constexpr __copy_fn copy{}; 319 320 struct __move_fn 321 { 322 template
_Sent, 323 weakly_incrementable _Out> 324 requires indirectly_movable<_Iter, _Out> 325 constexpr move_result<_Iter, _Out> 326 operator()(_Iter __first, _Sent __last, _Out __result) const 327 { 328 return ranges::__copy_or_move
(std::move(__first), 329 std::move(__last), 330 std::move(__result)); 331 } 332 333 template
334 requires indirectly_movable
, _Out> 335 constexpr move_result
, _Out> 336 operator()(_Range&& __r, _Out __result) const 337 { 338 return (*this)(ranges::begin(__r), ranges::end(__r), 339 std::move(__result)); 340 } 341 }; 342 343 inline constexpr __move_fn move{}; 344 345 template
_Sent, 347 bidirectional_iterator _Out> 348 requires (_IsMove 349 ? indirectly_movable<_Iter, _Out> 350 : indirectly_copyable<_Iter, _Out>) 351 constexpr __conditional_t<_IsMove, 352 move_backward_result<_Iter, _Out>, 353 copy_backward_result<_Iter, _Out>> 354 __copy_or_move_backward(_Iter __first, _Sent __last, _Out __result) 355 { 356 // TODO: implement more specializations to be at least on par with 357 // std::copy_backward/std::move_backward. 358 using __detail::__is_reverse_iterator; 359 using __detail::__is_normal_iterator; 360 if constexpr (__is_reverse_iterator<_Iter> && same_as<_Iter, _Sent> 361 && __is_reverse_iterator<_Out>) 362 { 363 auto [__in,__out] 364 = ranges::__copy_or_move<_IsMove>(std::move(__last).base(), 365 std::move(__first).base(), 366 std::move(__result).base()); 367 return {reverse_iterator{std::move(__in)}, 368 reverse_iterator{std::move(__out)}}; 369 } 370 else if constexpr (__is_normal_iterator<_Iter> && same_as<_Iter, _Sent>) 371 { 372 auto [__in,__out] 373 = ranges::__copy_or_move_backward<_IsMove>(__first.base(), 374 __last.base(), 375 std::move(__result)); 376 return {decltype(__first){__in}, std::move(__out)}; 377 } 378 else if constexpr (__is_normal_iterator<_Out>) 379 { 380 auto [__in,__out] 381 = ranges::__copy_or_move_backward<_IsMove>(std::move(__first), 382 std::move(__last), 383 __result.base()); 384 return {std::move(__in), decltype(__result){__out}}; 385 } 386 else if constexpr (sized_sentinel_for<_Sent, _Iter>) 387 { 388 if (!std::__is_constant_evaluated()) 389 { 390 if constexpr (__memcpyable<_Out, _Iter>::__value) 391 { 392 using _ValueTypeI = iter_value_t<_Iter>; 393 static_assert(_IsMove 394 ? is_move_assignable_v<_ValueTypeI> 395 : is_copy_assignable_v<_ValueTypeI>); 396 auto __num = __last - __first; 397 if (__num) 398 __builtin_memmove(__result - __num, __first, 399 sizeof(_ValueTypeI) * __num); 400 return {__first + __num, __result - __num}; 401 } 402 } 403 404 auto __lasti = ranges::next(__first, __last); 405 auto __tail = __lasti; 406 407 for (auto __n = __last - __first; __n > 0; --__n) 408 { 409 --__tail; 410 --__result; 411 if constexpr (_IsMove) 412 *__result = std::move(*__tail); 413 else 414 *__result = *__tail; 415 } 416 return {std::move(__lasti), std::move(__result)}; 417 } 418 else 419 { 420 auto __lasti = ranges::next(__first, __last); 421 auto __tail = __lasti; 422 423 while (__first != __tail) 424 { 425 --__tail; 426 --__result; 427 if constexpr (_IsMove) 428 *__result = std::move(*__tail); 429 else 430 *__result = *__tail; 431 } 432 return {std::move(__lasti), std::move(__result)}; 433 } 434 } 435 436 struct __copy_backward_fn 437 { 438 template
_Sent1, 439 bidirectional_iterator _Iter2> 440 requires indirectly_copyable<_Iter1, _Iter2> 441 constexpr copy_backward_result<_Iter1, _Iter2> 442 operator()(_Iter1 __first, _Sent1 __last, _Iter2 __result) const 443 { 444 return ranges::__copy_or_move_backward
(std::move(__first), 445 std::move(__last), 446 std::move(__result)); 447 } 448 449 template
450 requires indirectly_copyable
, _Iter> 451 constexpr copy_backward_result
, _Iter> 452 operator()(_Range&& __r, _Iter __result) const 453 { 454 return (*this)(ranges::begin(__r), ranges::end(__r), 455 std::move(__result)); 456 } 457 }; 458 459 inline constexpr __copy_backward_fn copy_backward{}; 460 461 struct __move_backward_fn 462 { 463 template
_Sent1, 464 bidirectional_iterator _Iter2> 465 requires indirectly_movable<_Iter1, _Iter2> 466 constexpr move_backward_result<_Iter1, _Iter2> 467 operator()(_Iter1 __first, _Sent1 __last, _Iter2 __result) const 468 { 469 return ranges::__copy_or_move_backward
(std::move(__first), 470 std::move(__last), 471 std::move(__result)); 472 } 473 474 template
475 requires indirectly_movable
, _Iter> 476 constexpr move_backward_result
, _Iter> 477 operator()(_Range&& __r, _Iter __result) const 478 { 479 return (*this)(ranges::begin(__r), ranges::end(__r), 480 std::move(__result)); 481 } 482 }; 483 484 inline constexpr __move_backward_fn move_backward{}; 485 486 template
487 using copy_n_result = in_out_result<_Iter, _Out>; 488 489 struct __copy_n_fn 490 { 491 template
492 requires indirectly_copyable<_Iter, _Out> 493 constexpr copy_n_result<_Iter, _Out> 494 operator()(_Iter __first, iter_difference_t<_Iter> __n, 495 _Out __result) const 496 { 497 if constexpr (random_access_iterator<_Iter>) 498 { 499 if (__n > 0) 500 return ranges::copy(__first, __first + __n, std::move(__result)); 501 } 502 else 503 { 504 for (; __n > 0; --__n, (void)++__result, (void)++__first) 505 *__result = *__first; 506 } 507 return {std::move(__first), std::move(__result)}; 508 } 509 }; 510 511 inline constexpr __copy_n_fn copy_n{}; 512 513 struct __fill_n_fn 514 { 515 template
_Out> 516 constexpr _Out 517 operator()(_Out __first, iter_difference_t<_Out> __n, 518 const _Tp& __value) const 519 { 520 // TODO: implement more specializations to be at least on par with 521 // std::fill_n 522 if (__n <= 0) 523 return __first; 524 525 if constexpr (is_scalar_v<_Tp>) 526 { 527 // TODO: Generalize this optimization to contiguous iterators. 528 if constexpr (is_pointer_v<_Out> 529 // Note that __is_byte already implies !is_volatile. 530 && __is_byte
>::__value 531 && integral<_Tp>) 532 { 533 if (!std::__is_constant_evaluated()) 534 { 535 __builtin_memset(__first, 536 static_cast
(__value), 537 __n); 538 return __first + __n; 539 } 540 } 541 542 const auto __tmp = __value; 543 for (; __n > 0; --__n, (void)++__first) 544 *__first = __tmp; 545 return __first; 546 } 547 else 548 { 549 for (; __n > 0; --__n, (void)++__first) 550 *__first = __value; 551 return __first; 552 } 553 } 554 }; 555 556 inline constexpr __fill_n_fn fill_n{}; 557 558 struct __fill_fn 559 { 560 template
_Out, sentinel_for<_Out> _Sent> 562 constexpr _Out 563 operator()(_Out __first, _Sent __last, const _Tp& __value) const 564 { 565 // TODO: implement more specializations to be at least on par with 566 // std::fill 567 if constexpr (sized_sentinel_for<_Sent, _Out>) 568 { 569 const auto __len = __last - __first; 570 return ranges::fill_n(__first, __len, __value); 571 } 572 else if constexpr (is_scalar_v<_Tp>) 573 { 574 const auto __tmp = __value; 575 for (; __first != __last; ++__first) 576 *__first = __tmp; 577 return __first; 578 } 579 else 580 { 581 for (; __first != __last; ++__first) 582 *__first = __value; 583 return __first; 584 } 585 } 586 587 template
_Range> 588 constexpr borrowed_iterator_t<_Range> 589 operator()(_Range&& __r, const _Tp& __value) const 590 { 591 return (*this)(ranges::begin(__r), ranges::end(__r), __value); 592 } 593 }; 594 595 inline constexpr __fill_fn fill{}; 596 } 597 _GLIBCXX_END_NAMESPACE_VERSION 598 } // namespace std 599 #endif // concepts 600 #endif // C++20 601 #endif // _RANGES_ALGOBASE_H
Contact us
|
About us
|
Term of use
|
Copyright © 2000-2025 MyWebUniversity.com ™