Where Online Learning is simpler!
The C and C++ Include Header Files
cat -n /usr/include/c++/15/bits/valarray_array.h
1 // The template and inlines for the -*- C++ -*- internal _Array helper class. 2 3 // Copyright (C) 1997-2025 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/valarray_array.h 26 * This is an internal header file, included by other library headers. 27 * Do not attempt to use it directly. @headername{valarray} 28 */ 29 30 // Written by Gabriel Dos Reis <Gabriel.Dos-Reis@DPTMaths.ENS-Cachan.Fr> 31 32 #ifndef _VALARRAY_ARRAY_H 33 #define _VALARRAY_ARRAY_H 1 34 35 #ifdef _GLIBCXX_SYSHDR 36 #pragma GCC system_header 37 #endif 38 39 #include <bits/c++config.h> 40 #include <bits/cpp_type_traits.h> 41 #include <cstdlib> 42 #include <new> 43 44 namespace std _GLIBCXX_VISIBILITY(default) 45 { 46 _GLIBCXX_BEGIN_NAMESPACE_VERSION 47 48 // 49 // Helper functions on raw pointers 50 // 51 52 // We get memory the old fashioned way 53 template<typename _Tp> 54 _Tp* 55 __valarray_get_storage(size_t) __attribute__((__malloc__)); 56 57 template<typename _Tp> 58 inline _Tp* 59 __valarray_get_storage(size_t __n) 60 { return static_cast<_Tp*>(operator new(__n * sizeof(_Tp))); } 61 62 // Return memory to the system 63 inline void 64 __valarray_release_memory(void* __p) 65 { operator delete(__p); } 66 67 // Turn raw-memory into an array of _Tp filled with _Tp(). 68 // This is used in `valarray<T> v(n);` and in `valarray<T>::shift(n)`. 69 template<typename _Tp> 70 inline void 71 __valarray_default_construct(_Tp* __b, _Tp* __e) 72 { 73 if _GLIBCXX17_CONSTEXPR (__is_trivial(_Tp)) 74 __builtin_memset(__b, 0, (__e - __b) * sizeof(_Tp)); 75 else 76 while (__b != __e) 77 ::new(static_cast<void*>(__b++)) _Tp(); 78 } 79 80 // Turn a raw-memory into an array of _Tp filled with __t 81 // This is the required in valarray<T> v(n, t). Also 82 // used in valarray<>::resize(). 83 template<typename _Tp> 84 inline void 85 __valarray_fill_construct(_Tp* __b, _Tp* __e, const _Tp __t) 86 { 87 while (__b != __e) 88 ::new(static_cast<void*>(__b++)) _Tp(__t); 89 } 90 91 // copy-construct raw array [__o, *) from plain array [__b, __e) 92 template<typename _Tp> 93 inline void 94 __valarray_copy_construct(const _Tp* __b, const _Tp* __e, 95 _Tp* __restrict__ __o) 96 { 97 if _GLIBCXX17_CONSTEXPR (__is_trivial(_Tp)) 98 { 99 if (__b) 100 __builtin_memcpy(__o, __b, (__e - __b) * sizeof(_Tp)); 101 } 102 else 103 while (__b != __e) 104 ::new(static_cast<void*>(__o++)) _Tp(*__b++); 105 } 106 107 // copy-construct raw array [__o, *) from strided array __a[<__n : __s>] 108 template<typename _Tp> 109 inline void 110 __valarray_copy_construct (const _Tp* __restrict__ __a, size_t __n, 111 size_t __s, _Tp* __restrict__ __o) 112 { 113 if _GLIBCXX17_CONSTEXPR (__is_trivial(_Tp)) 114 while (__n--) 115 { 116 *__o++ = *__a; 117 __a += __s; 118 } 119 else 120 while (__n--) 121 { 122 new(__o++) _Tp(*__a); 123 __a += __s; 124 } 125 } 126 127 // copy-construct raw array [__o, *) from indexed array __a[__i[<__n>]] 128 template<typename _Tp> 129 inline void 130 __valarray_copy_construct (const _Tp* __restrict__ __a, 131 const size_t* __restrict__ __i, 132 _Tp* __restrict__ __o, size_t __n) 133 { 134 if (__is_trivial(_Tp)) 135 while (__n--) 136 *__o++ = __a[*__i++]; 137 else 138 while (__n--) 139 new (__o++) _Tp(__a[*__i++]); 140 } 141 142 // Do the necessary cleanup when we're done with arrays. 143 template<typename _Tp> 144 inline void 145 __valarray_destroy_elements(_Tp* __b, _Tp* __e) 146 { 147 if (!__is_trivial(_Tp)) 148 while (__b != __e) 149 { 150 __b->~_Tp(); 151 ++__b; 152 } 153 } 154 155 // Fill a plain array __a[<__n>] with __t 156 template<typename _Tp> 157 inline void 158 __valarray_fill(_Tp* __restrict__ __a, size_t __n, const _Tp& __t) 159 { 160 while (__n--) 161 *__a++ = __t; 162 } 163 164 // fill strided array __a[<__n-1 : __s>] with __t 165 template<typename _Tp> 166 inline void 167 __valarray_fill(_Tp* __restrict__ __a, size_t __n, 168 size_t __s, const _Tp& __t) 169 { 170 for (size_t __i = 0; __i < __n; ++__i, __a += __s) 171 *__a = __t; 172 } 173 174 // fill indirect array __a[__i[<__n>]] with __i 175 template<typename _Tp> 176 inline void 177 __valarray_fill(_Tp* __restrict__ __a, const size_t* __restrict__ __i, 178 size_t __n, const _Tp& __t) 179 { 180 for (size_t __j = 0; __j < __n; ++__j, ++__i) 181 __a[*__i] = __t; 182 } 183 184 // copy plain array __a[<__n>] in __b[<__n>] 185 // For non-fundamental types, it is wrong to say 'memcpy()' 186 template<typename _Tp, bool> 187 struct _Array_copier 188 { 189 inline static void 190 _S_do_it(const _Tp* __restrict__ __a, size_t __n, _Tp* __restrict__ __b) 191 { 192 while(__n--) 193 *__b++ = *__a++; 194 } 195 }; 196 197 template<typename _Tp> 198 struct _Array_copier<_Tp, true> 199 { 200 inline static void 201 _S_do_it(const _Tp* __restrict__ __a, size_t __n, _Tp* __restrict__ __b) 202 { 203 if (__n != 0) 204 __builtin_memcpy(__b, __a, __n * sizeof (_Tp)); 205 } 206 }; 207 208 // Copy a plain array __a[<__n>] into a play array __b[<>] 209 template<typename _Tp> 210 inline void 211 __valarray_copy(const _Tp* __restrict__ __a, size_t __n, 212 _Tp* __restrict__ __b) 213 { 214 _Array_copier<_Tp, __is_trivial(_Tp)>::_S_do_it(__a, __n, __b); 215 } 216 217 // Copy strided array __a[<__n : __s>] in plain __b[<__n>] 218 template<typename _Tp> 219 inline void 220 __valarray_copy(const _Tp* __restrict__ __a, size_t __n, size_t __s, 221 _Tp* __restrict__ __b) 222 { 223 for (size_t __i = 0; __i < __n; ++__i, ++__b, __a += __s) 224 *__b = *__a; 225 } 226 227 // Copy a plain array __a[<__n>] into a strided array __b[<__n : __s>] 228 template<typename _Tp> 229 inline void 230 __valarray_copy(const _Tp* __restrict__ __a, _Tp* __restrict__ __b, 231 size_t __n, size_t __s) 232 { 233 for (size_t __i = 0; __i < __n; ++__i, ++__a, __b += __s) 234 *__b = *__a; 235 } 236 237 // Copy strided array __src[<__n : __s1>] into another 238 // strided array __dst[< : __s2>]. Their sizes must match. 239 template<typename _Tp> 240 inline void 241 __valarray_copy(const _Tp* __restrict__ __src, size_t __n, size_t __s1, 242 _Tp* __restrict__ __dst, size_t __s2) 243 { 244 for (size_t __i = 0; __i < __n; ++__i) 245 __dst[__i * __s2] = __src[__i * __s1]; 246 } 247 248 // Copy an indexed array __a[__i[<__n>]] in plain array __b[<__n>] 249 template<typename _Tp> 250 inline void 251 __valarray_copy(const _Tp* __restrict__ __a, 252 const size_t* __restrict__ __i, 253 _Tp* __restrict__ __b, size_t __n) 254 { 255 for (size_t __j = 0; __j < __n; ++__j, ++__b, ++__i) 256 *__b = __a[*__i]; 257 } 258 259 // Copy a plain array __a[<__n>] in an indexed array __b[__i[<__n>]] 260 template<typename _Tp> 261 inline void 262 __valarray_copy(const _Tp* __restrict__ __a, size_t __n, 263 _Tp* __restrict__ __b, const size_t* __restrict__ __i) 264 { 265 for (size_t __j = 0; __j < __n; ++__j, ++__a, ++__i) 266 __b[*__i] = *__a; 267 } 268 269 // Copy the __n first elements of an indexed array __src[<__i>] into 270 // another indexed array __dst[<__j>]. 271 template<typename _Tp> 272 inline void 273 __valarray_copy(const _Tp* __restrict__ __src, size_t __n, 274 const size_t* __restrict__ __i, 275 _Tp* __restrict__ __dst, const size_t* __restrict__ __j) 276 { 277 for (size_t __k = 0; __k < __n; ++__k) 278 __dst[*__j++] = __src[*__i++]; 279 } 280 281 // 282 // Compute the sum of elements in range [__f, __l) which must not be empty. 283 // This is a naive algorithm. It suffers from cancelling. 284 // In the future try to specialize for _Tp = float, double, long double 285 // using a more accurate algorithm. 286 // 287 template<typename _Tp> 288 inline _Tp 289 __valarray_sum(const _Tp* __f, const _Tp* __l) 290 { 291 _Tp __r = *__f++; 292 while (__f != __l) 293 __r += *__f++; 294 return __r; 295 } 296 297 // Compute the min/max of an array-expression 298 template<typename _Ta> 299 inline typename _Ta::value_type 300 __valarray_min(const _Ta& __a) 301 { 302 size_t __s = __a.size(); 303 typedef typename _Ta::value_type _Value_type; 304 _Value_type __r = __s == 0 ? _Value_type() : __a[0]; 305 for (size_t __i = 1; __i < __s; ++__i) 306 { 307 _Value_type __t = __a[__i]; 308 if (__t < __r) 309 __r = __t; 310 } 311 return __r; 312 } 313 314 template<typename _Ta> 315 inline typename _Ta::value_type 316 __valarray_max(const _Ta& __a) 317 { 318 size_t __s = __a.size(); 319 typedef typename _Ta::value_type _Value_type; 320 _Value_type __r = __s == 0 ? _Value_type() : __a[0]; 321 for (size_t __i = 1; __i < __s; ++__i) 322 { 323 _Value_type __t = __a[__i]; 324 if (__t > __r) 325 __r = __t; 326 } 327 return __r; 328 } 329 330 // 331 // Helper class _Array, first layer of valarray abstraction. 332 // All operations on valarray should be forwarded to this class 333 // whenever possible. -- gdr 334 // 335 336 template<typename _Tp> 337 struct _Array 338 { 339 explicit _Array(_Tp* const __restrict__); 340 explicit _Array(const valarray<_Tp>&); 341 _Array(const _Tp* __restrict__, size_t); 342 343 _Tp* begin() const; 344 345 _Tp* const __restrict__ _M_data; 346 }; 347 348 349 // Copy-construct plain array __b[<__n>] from indexed array __a[__i[<__n>]] 350 template<typename _Tp> 351 inline void 352 __valarray_copy_construct(_Array<_Tp> __a, _Array<size_t> __i, 353 _Array<_Tp> __b, size_t __n) 354 { std::__valarray_copy_construct(__a._M_data, __i._M_data, 355 __b._M_data, __n); } 356 357 // Copy-construct plain array __b[<__n>] from strided array __a[<__n : __s>] 358 template<typename _Tp> 359 inline void 360 __valarray_copy_construct(_Array<_Tp> __a, size_t __n, size_t __s, 361 _Array<_Tp> __b) 362 { std::__valarray_copy_construct(__a._M_data, __n, __s, __b._M_data); } 363 364 template<typename _Tp> 365 inline void 366 __valarray_fill (_Array<_Tp> __a, size_t __n, const _Tp& __t) 367 { std::__valarray_fill(__a._M_data, __n, __t); } 368 369 template<typename _Tp> 370 inline void 371 __valarray_fill(_Array<_Tp> __a, size_t __n, size_t __s, const _Tp& __t) 372 { std::__valarray_fill(__a._M_data, __n, __s, __t); } 373 374 template<typename _Tp> 375 inline void 376 __valarray_fill(_Array<_Tp> __a, _Array<size_t> __i, 377 size_t __n, const _Tp& __t) 378 { std::__valarray_fill(__a._M_data, __i._M_data, __n, __t); } 379 380 // Copy a plain array __a[<__n>] into a play array __b[<>] 381 template<typename _Tp> 382 inline void 383 __valarray_copy(_Array<_Tp> __a, size_t __n, _Array<_Tp> __b) 384 { std::__valarray_copy(__a._M_data, __n, __b._M_data); } 385 386 // Copy strided array __a[<__n : __s>] in plain __b[<__n>] 387 template<typename _Tp> 388 inline void 389 __valarray_copy(_Array<_Tp> __a, size_t __n, size_t __s, _Array<_Tp> __b) 390 { std::__valarray_copy(__a._M_data, __n, __s, __b._M_data); } 391 392 // Copy a plain array __a[<__n>] into a strided array __b[<__n : __s>] 393 template<typename _Tp> 394 inline void 395 __valarray_copy(_Array<_Tp> __a, _Array<_Tp> __b, size_t __n, size_t __s) 396 { __valarray_copy(__a._M_data, __b._M_data, __n, __s); } 397 398 // Copy strided array __src[<__n : __s1>] into another 399 // strided array __dst[< : __s2>]. Their sizes must match. 400 template<typename _Tp> 401 inline void 402 __valarray_copy(_Array<_Tp> __a, size_t __n, size_t __s1, 403 _Array<_Tp> __b, size_t __s2) 404 { std::__valarray_copy(__a._M_data, __n, __s1, __b._M_data, __s2); } 405 406 // Copy an indexed array __a[__i[<__n>]] in plain array __b[<__n>] 407 template<typename _Tp> 408 inline void 409 __valarray_copy(_Array<_Tp> __a, _Array<size_t> __i, 410 _Array<_Tp> __b, size_t __n) 411 { std::__valarray_copy(__a._M_data, __i._M_data, __b._M_data, __n); } 412 413 // Copy a plain array __a[<__n>] in an indexed array __b[__i[<__n>]] 414 template<typename _Tp> 415 inline void 416 __valarray_copy(_Array<_Tp> __a, size_t __n, _Array<_Tp> __b, 417 _Array<size_t> __i) 418 { std::__valarray_copy(__a._M_data, __n, __b._M_data, __i._M_data); } 419 420 // Copy the __n first elements of an indexed array __src[<__i>] into 421 // another indexed array __dst[<__j>]. 422 template<typename _Tp> 423 inline void 424 __valarray_copy(_Array<_Tp> __src, size_t __n, _Array<size_t> __i, 425 _Array<_Tp> __dst, _Array<size_t> __j) 426 { 427 std::__valarray_copy(__src._M_data, __n, __i._M_data, 428 __dst._M_data, __j._M_data); 429 } 430 431 template<typename _Tp> 432 inline 433 _Array<_Tp>::_Array(_Tp* const __restrict__ __p) 434 : _M_data (__p) {} 435 436 template<typename _Tp> 437 inline 438 _Array<_Tp>::_Array(const valarray<_Tp>& __v) 439 : _M_data (__v._M_data) {} 440 441 template<typename _Tp> 442 inline 443 _Array<_Tp>::_Array(const _Tp* __restrict__ __b, size_t __s) 444 : _M_data(__valarray_get_storage<_Tp>(__s)) 445 { std::__valarray_copy_construct(__b, __s, _M_data); } 446 447 template<typename _Tp> 448 inline _Tp* 449 _Array<_Tp>::begin () const 450 { return _M_data; } 451 452 #define _DEFINE_ARRAY_FUNCTION(_Op, _Name) \ 453 template<typename _Tp> \ 454 inline void \ 455 _Array_augmented_##_Name(_Array<_Tp> __a, size_t __n, const _Tp& __t) \ 456 { \ 457 for (_Tp* __p = __a._M_data; __p < __a._M_data + __n; ++__p) \ 458 *__p _Op##= __t; \ 459 } \ 460 \ 461 template<typename _Tp> \ 462 inline void \ 463 _Array_augmented_##_Name(_Array<_Tp> __a, size_t __n, _Array<_Tp> __b) \ 464 { \ 465 _Tp* __p = __a._M_data; \ 466 for (_Tp* __q = __b._M_data; __q < __b._M_data + __n; ++__p, ++__q) \ 467 *__p _Op##= *__q; \ 468 } \ 469 \ 470 template<typename _Tp, class _Dom> \ 471 void \ 472 _Array_augmented_##_Name(_Array<_Tp> __a, \ 473 const _Expr<_Dom, _Tp>& __e, size_t __n) \ 474 { \ 475 _Tp* __p(__a._M_data); \ 476 for (size_t __i = 0; __i < __n; ++__i, ++__p) \ 477 *__p _Op##= __e[__i]; \ 478 } \ 479 \ 480 template<typename _Tp> \ 481 inline void \ 482 _Array_augmented_##_Name(_Array<_Tp> __a, size_t __n, size_t __s, \ 483 _Array<_Tp> __b) \ 484 { \ 485 _Tp* __q(__b._M_data); \ 486 for (_Tp* __p = __a._M_data; __p < __a._M_data + __s * __n; \ 487 __p += __s, ++__q) \ 488 *__p _Op##= *__q; \ 489 } \ 490 \ 491 template<typename _Tp> \ 492 inline void \ 493 _Array_augmented_##_Name(_Array<_Tp> __a, _Array<_Tp> __b, \ 494 size_t __n, size_t __s) \ 495 { \ 496 _Tp* __q(__b._M_data); \ 497 for (_Tp* __p = __a._M_data; __p < __a._M_data + __n; \ 498 ++__p, __q += __s) \ 499 *__p _Op##= *__q; \ 500 } \ 501 \ 502 template<typename _Tp, class _Dom> \ 503 void \ 504 _Array_augmented_##_Name(_Array<_Tp> __a, size_t __s, \ 505 const _Expr<_Dom, _Tp>& __e, size_t __n) \ 506 { \ 507 _Tp* __p(__a._M_data); \ 508 for (size_t __i = 0; __i < __n; ++__i, __p += __s) \ 509 *__p _Op##= __e[__i]; \ 510 } \ 511 \ 512 template<typename _Tp> \ 513 inline void \ 514 _Array_augmented_##_Name(_Array<_Tp> __a, _Array<size_t> __i, \ 515 _Array<_Tp> __b, size_t __n) \ 516 { \ 517 _Tp* __q(__b._M_data); \ 518 for (size_t* __j = __i._M_data; __j < __i._M_data + __n; \ 519 ++__j, ++__q) \ 520 __a._M_data[*__j] _Op##= *__q; \ 521 } \ 522 \ 523 template<typename _Tp> \ 524 inline void \ 525 _Array_augmented_##_Name(_Array<_Tp> __a, size_t __n, \ 526 _Array<_Tp> __b, _Array<size_t> __i) \ 527 { \ 528 _Tp* __p(__a._M_data); \ 529 for (size_t* __j = __i._M_data; __j<__i._M_data + __n; \ 530 ++__j, ++__p) \ 531 *__p _Op##= __b._M_data[*__j]; \ 532 } \ 533 \ 534 template<typename _Tp, class _Dom> \ 535 void \ 536 _Array_augmented_##_Name(_Array<_Tp> __a, _Array<size_t> __i, \ 537 const _Expr<_Dom, _Tp>& __e, size_t __n) \ 538 { \ 539 size_t* __j(__i._M_data); \ 540 for (size_t __k = 0; __k<__n; ++__k, ++__j) \ 541 __a._M_data[*__j] _Op##= __e[__k]; \ 542 } \ 543 \ 544 template<typename _Tp> \ 545 void \ 546 _Array_augmented_##_Name(_Array<_Tp> __a, _Array<bool> __m, \ 547 _Array<_Tp> __b, size_t __n) \ 548 { \ 549 bool* __ok(__m._M_data); \ 550 _Tp* __p(__a._M_data); \ 551 for (_Tp* __q = __b._M_data; __q < __b._M_data + __n; \ 552 ++__q, ++__ok, ++__p) \ 553 { \ 554 while (! *__ok) \ 555 { \ 556 ++__ok; \ 557 ++__p; \ 558 } \ 559 *__p _Op##= *__q; \ 560 } \ 561 } \ 562 \ 563 template<typename _Tp> \ 564 void \ 565 _Array_augmented_##_Name(_Array<_Tp> __a, size_t __n, \ 566 _Array<_Tp> __b, _Array<bool> __m) \ 567 { \ 568 bool* __ok(__m._M_data); \ 569 _Tp* __q(__b._M_data); \ 570 for (_Tp* __p = __a._M_data; __p < __a._M_data + __n; \ 571 ++__p, ++__ok, ++__q) \ 572 { \ 573 while (! *__ok) \ 574 { \ 575 ++__ok; \ 576 ++__q; \ 577 } \ 578 *__p _Op##= *__q; \ 579 } \ 580 } \ 581 \ 582 template<typename _Tp, class _Dom> \ 583 void \ 584 _Array_augmented_##_Name(_Array<_Tp> __a, _Array<bool> __m, \ 585 const _Expr<_Dom, _Tp>& __e, size_t __n) \ 586 { \ 587 bool* __ok(__m._M_data); \ 588 _Tp* __p(__a._M_data); \ 589 for (size_t __i = 0; __i < __n; ++__i, ++__ok, ++__p) \ 590 { \ 591 while (! *__ok) \ 592 { \ 593 ++__ok; \ 594 ++__p; \ 595 } \ 596 *__p _Op##= __e[__i]; \ 597 } \ 598 } 599 600 _DEFINE_ARRAY_FUNCTION(+, __plus) 601 _DEFINE_ARRAY_FUNCTION(-, __minus) 602 _DEFINE_ARRAY_FUNCTION(*, __multiplies) 603 _DEFINE_ARRAY_FUNCTION(/, __divides) 604 _DEFINE_ARRAY_FUNCTION(%, __modulus) 605 _DEFINE_ARRAY_FUNCTION(^, __bitwise_xor) 606 _DEFINE_ARRAY_FUNCTION(|, __bitwise_or) 607 _DEFINE_ARRAY_FUNCTION(&, __bitwise_and) 608 _DEFINE_ARRAY_FUNCTION(<<, __shift_left) 609 _DEFINE_ARRAY_FUNCTION(>>, __shift_right) 610 611 #undef _DEFINE_ARRAY_FUNCTION 612 613 _GLIBCXX_END_NAMESPACE_VERSION 614 } // namespace 615 616 # include <bits/valarray_array.tcc> 617 618 #endif /* _ARRAY_H */