The C and C++ Include Header Files
/usr/include/c++/11/ext/throw_allocator.h
$ cat -n /usr/include/c++/11/ext/throw_allocator.h 1 // -*- C++ -*- 2 3 // Copyright (C) 2005-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 terms 7 // of the GNU General Public License as published by the Free Software 8 // Foundation; either version 3, or (at your option) any later 9 // version. 10 11 // This library is distributed in the hope that it will be useful, but 12 // WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 // 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 // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. 26 27 // Permission to use, copy, modify, sell, and distribute this software 28 // is hereby granted without fee, provided that the above copyright 29 // notice appears in all copies, and that both that copyright notice 30 // and this permission notice appear in supporting documentation. None 31 // of the above authors, nor IBM Haifa Research Laboratories, make any 32 // representation about the suitability of this software for any 33 // purpose. It is provided "as is" without express or implied 34 // warranty. 35 36 /** @file ext/throw_allocator.h 37 * This file is a GNU extension to the Standard C++ Library. 38 * 39 * Contains two exception-generating types (throw_value, throw_allocator) 40 * intended to be used as value and allocator types while testing 41 * exception safety in templatized containers and algorithms. The 42 * allocator has additional log and debug features. The exception 43 * generated is of type forced_exception_error. 44 */ 45 46 #ifndef _THROW_ALLOCATOR_H 47 #define _THROW_ALLOCATOR_H 1 48 49 #include
50 #include
51 #include
52 #include
53 #include
54 #include
55 #include
56 #include
57 #include
58 #if __cplusplus >= 201103L 59 # include
60 # include
61 #else 62 # include
63 # include
64 #endif 65 #include
66 67 #if !__has_builtin(__builtin_sprintf) 68 # include
69 #endif 70 71 namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) 72 { 73 _GLIBCXX_BEGIN_NAMESPACE_VERSION 74 75 /** 76 * @brief Thrown by utilities for testing exception safety. 77 * @ingroup exceptions 78 */ 79 struct forced_error : public std::exception 80 { }; 81 82 // Substitute for forced_error object when -fno-exceptions. 83 inline void 84 __throw_forced_error() 85 { _GLIBCXX_THROW_OR_ABORT(forced_error()); } 86 87 /** 88 * @brief Base class for checking address and label information 89 * about allocations. Create a std::map between the allocated 90 * address (void*) and a datum for annotations, which are a pair of 91 * numbers corresponding to label and allocated size. 92 */ 93 struct annotate_base 94 { 95 private: 96 typedef std::pair
data_type; 97 typedef std::map
map_alloc_type; 98 typedef map_alloc_type::value_type entry_type; 99 typedef map_alloc_type::const_iterator const_iterator; 100 typedef map_alloc_type::const_reference const_reference; 101 #if __cplusplus >= 201103L 102 typedef std::map
map_construct_type; 103 #endif 104 105 public: 106 annotate_base() 107 { 108 label(); 109 map_alloc(); 110 } 111 112 static void 113 set_label(size_t l) 114 { label() = l; } 115 116 static size_t 117 get_label() 118 { return label(); } 119 120 void 121 insert(void* p, size_t size) 122 { 123 entry_type entry = make_entry(p, size); 124 if (!p) 125 { 126 std::string error("annotate_base::insert null insert!\n"); 127 log_to_string(error, entry); 128 std::__throw_logic_error(error.c_str()); 129 } 130 131 std::pair
inserted 132 = map_alloc().insert(entry); 133 if (!inserted.second) 134 { 135 std::string error("annotate_base::insert double insert!\n"); 136 log_to_string(error, entry); 137 log_to_string(error, *inserted.first); 138 std::__throw_logic_error(error.c_str()); 139 } 140 } 141 142 void 143 erase(void* p, size_t size) 144 { map_alloc().erase(check_allocated(p, size)); } 145 146 #if __cplusplus >= 201103L 147 void 148 insert_construct(void* p) 149 { 150 if (!p) 151 { 152 std::string error("annotate_base::insert_construct null!\n"); 153 std::__throw_logic_error(error.c_str()); 154 } 155 156 auto inserted = map_construct().insert(std::make_pair(p, get_label())); 157 if (!inserted.second) 158 { 159 std::string error("annotate_base::insert_construct double insert!\n"); 160 log_to_string(error, std::make_pair(p, get_label())); 161 log_to_string(error, *inserted.first); 162 std::__throw_logic_error(error.c_str()); 163 } 164 } 165 166 void 167 erase_construct(void* p) 168 { map_construct().erase(check_constructed(p)); } 169 #endif 170 171 // See if a particular address and allocation size has been saved. 172 inline map_alloc_type::iterator 173 check_allocated(void* p, size_t size) 174 { 175 map_alloc_type::iterator found = map_alloc().find(p); 176 if (found == map_alloc().end()) 177 { 178 std::string error("annotate_base::check_allocated by value " 179 "null erase!\n"); 180 log_to_string(error, make_entry(p, size)); 181 std::__throw_logic_error(error.c_str()); 182 } 183 184 if (found->second.second != size) 185 { 186 std::string error("annotate_base::check_allocated by value " 187 "wrong-size erase!\n"); 188 log_to_string(error, make_entry(p, size)); 189 log_to_string(error, *found); 190 std::__throw_logic_error(error.c_str()); 191 } 192 193 return found; 194 } 195 196 // See if a given label has been allocated. 197 inline void 198 check(size_t label) 199 { 200 std::string found; 201 { 202 const_iterator beg = map_alloc().begin(); 203 const_iterator end = map_alloc().end(); 204 while (beg != end) 205 { 206 if (beg->second.first == label) 207 log_to_string(found, *beg); 208 ++beg; 209 } 210 } 211 212 #if __cplusplus >= 201103L 213 { 214 auto beg = map_construct().begin(); 215 auto end = map_construct().end(); 216 while (beg != end) 217 { 218 if (beg->second == label) 219 log_to_string(found, *beg); 220 ++beg; 221 } 222 } 223 #endif 224 225 if (!found.empty()) 226 { 227 std::string error("annotate_base::check by label\n"); 228 error += found; 229 std::__throw_logic_error(error.c_str()); 230 } 231 } 232 233 // See if there is anything left allocated or constructed. 234 inline static void 235 check() 236 { 237 std::string found; 238 { 239 const_iterator beg = map_alloc().begin(); 240 const_iterator end = map_alloc().end(); 241 while (beg != end) 242 { 243 log_to_string(found, *beg); 244 ++beg; 245 } 246 } 247 248 #if __cplusplus >= 201103L 249 { 250 auto beg = map_construct().begin(); 251 auto end = map_construct().end(); 252 while (beg != end) 253 { 254 log_to_string(found, *beg); 255 ++beg; 256 } 257 } 258 #endif 259 260 if (!found.empty()) 261 { 262 std::string error("annotate_base::check \n"); 263 error += found; 264 std::__throw_logic_error(error.c_str()); 265 } 266 } 267 268 #if __cplusplus >= 201103L 269 inline map_construct_type::iterator 270 check_constructed(void* p) 271 { 272 auto found = map_construct().find(p); 273 if (found == map_construct().end()) 274 { 275 std::string error("annotate_base::check_constructed not " 276 "constructed!\n"); 277 log_to_string(error, std::make_pair(p, get_label())); 278 std::__throw_logic_error(error.c_str()); 279 } 280 281 return found; 282 } 283 284 inline void 285 check_constructed(size_t label) 286 { 287 auto beg = map_construct().begin(); 288 auto end = map_construct().end(); 289 std::string found; 290 while (beg != end) 291 { 292 if (beg->second == label) 293 log_to_string(found, *beg); 294 ++beg; 295 } 296 297 if (!found.empty()) 298 { 299 std::string error("annotate_base::check_constructed by label\n"); 300 error += found; 301 std::__throw_logic_error(error.c_str()); 302 } 303 } 304 #endif 305 306 private: 307 friend std::ostream& 308 operator<<(std::ostream&, const annotate_base&); 309 310 entry_type 311 make_entry(void* p, size_t size) 312 { return std::make_pair(p, data_type(get_label(), size)); } 313 314 static void 315 log_to_string(std::string& s, const_reference ref) 316 { 317 #if ! __has_builtin(__builtin_sprintf) 318 __typeof__(&std::sprintf) __builtin_sprintf = &std::sprintf; 319 #endif 320 321 char buf[40]; 322 const char tab('\t'); 323 s += "label: "; 324 unsigned long l = static_cast
(ref.second.first); 325 __builtin_sprintf(buf, "%lu", l); 326 s += buf; 327 s += tab; 328 s += "size: "; 329 l = static_cast
(ref.second.second); 330 __builtin_sprintf(buf, "%lu", l); 331 s += buf; 332 s += tab; 333 s += "address: "; 334 __builtin_sprintf(buf, "%p", ref.first); 335 s += buf; 336 s += '\n'; 337 } 338 339 #if __cplusplus >= 201103L 340 static void 341 log_to_string(std::string& s, const std::pair
& ref) 342 { 343 #if ! __has_builtin(__builtin_sprintf) 344 auto __builtin_sprintf = &std::sprintf; 345 #endif 346 347 char buf[40]; 348 const char tab('\t'); 349 s += "label: "; 350 unsigned long l = static_cast
(ref.second); 351 __builtin_sprintf(buf, "%lu", l); 352 s += buf; 353 s += tab; 354 s += "address: "; 355 __builtin_sprintf(buf, "%p", ref.first); 356 s += buf; 357 s += '\n'; 358 } 359 #endif 360 361 static size_t& 362 label() 363 { 364 static size_t _S_label(std::numeric_limits
::max()); 365 return _S_label; 366 } 367 368 static map_alloc_type& 369 map_alloc() 370 { 371 static map_alloc_type _S_map; 372 return _S_map; 373 } 374 375 #if __cplusplus >= 201103L 376 static map_construct_type& 377 map_construct() 378 { 379 static map_construct_type _S_map; 380 return _S_map; 381 } 382 #endif 383 }; 384 385 inline std::ostream& 386 operator<<(std::ostream& os, const annotate_base& __b) 387 { 388 std::string error; 389 typedef annotate_base base_type; 390 { 391 base_type::const_iterator beg = __b.map_alloc().begin(); 392 base_type::const_iterator end = __b.map_alloc().end(); 393 for (; beg != end; ++beg) 394 __b.log_to_string(error, *beg); 395 } 396 #if __cplusplus >= 201103L 397 { 398 auto beg = __b.map_construct().begin(); 399 auto end = __b.map_construct().end(); 400 for (; beg != end; ++beg) 401 __b.log_to_string(error, *beg); 402 } 403 #endif 404 return os << error; 405 } 406 407 408 /** 409 * @brief Base struct for condition policy. 410 * 411 * Requires a public member function with the signature 412 * void throw_conditionally() 413 */ 414 struct condition_base 415 { 416 #if __cplusplus >= 201103L 417 condition_base() = default; 418 condition_base(const condition_base&) = default; 419 condition_base& operator=(const condition_base&) = default; 420 #endif 421 virtual ~condition_base() { }; 422 }; 423 424 425 /** 426 * @brief Base class for incremental control and throw. 427 */ 428 struct limit_condition : public condition_base 429 { 430 // Scope-level adjustor objects: set limit for throw at the 431 // beginning of a scope block, and restores to previous limit when 432 // object is destroyed on exiting the block. 433 struct adjustor_base 434 { 435 private: 436 const size_t _M_orig; 437 438 public: 439 adjustor_base() : _M_orig(limit()) { } 440 441 virtual 442 ~adjustor_base() { set_limit(_M_orig); } 443 }; 444 445 /// Never enter the condition. 446 struct never_adjustor : public adjustor_base 447 { 448 never_adjustor() { set_limit(std::numeric_limits
::max()); } 449 }; 450 451 /// Always enter the condition. 452 struct always_adjustor : public adjustor_base 453 { 454 always_adjustor() { set_limit(count()); } 455 }; 456 457 /// Enter the nth condition. 458 struct limit_adjustor : public adjustor_base 459 { 460 limit_adjustor(const size_t __l) { set_limit(__l); } 461 }; 462 463 // Increment _S_count every time called. 464 // If _S_count matches the limit count, throw. 465 static void 466 throw_conditionally() 467 { 468 if (count() == limit()) 469 __throw_forced_error(); 470 ++count(); 471 } 472 473 static size_t& 474 count() 475 { 476 static size_t _S_count(0); 477 return _S_count; 478 } 479 480 static size_t& 481 limit() 482 { 483 static size_t _S_limit(std::numeric_limits
::max()); 484 return _S_limit; 485 } 486 487 // Zero the throw counter, set limit to argument. 488 static void 489 set_limit(const size_t __l) 490 { 491 limit() = __l; 492 count() = 0; 493 } 494 }; 495 496 #ifdef _GLIBCXX_USE_C99_STDINT_TR1 497 /** 498 * @brief Base class for random probability control and throw. 499 */ 500 struct random_condition : public condition_base 501 { 502 // Scope-level adjustor objects: set probability for throw at the 503 // beginning of a scope block, and restores to previous 504 // probability when object is destroyed on exiting the block. 505 struct adjustor_base 506 { 507 private: 508 const double _M_orig; 509 510 public: 511 adjustor_base() : _M_orig(probability()) { } 512 513 virtual ~adjustor_base() 514 { set_probability(_M_orig); } 515 }; 516 517 /// Group condition. 518 struct group_adjustor : public adjustor_base 519 { 520 group_adjustor(size_t size) 521 { set_probability(1 - std::pow(double(1 - probability()), 522 double(0.5 / (size + 1)))); 523 } 524 }; 525 526 /// Never enter the condition. 527 struct never_adjustor : public adjustor_base 528 { 529 never_adjustor() { set_probability(0); } 530 }; 531 532 /// Always enter the condition. 533 struct always_adjustor : public adjustor_base 534 { 535 always_adjustor() { set_probability(1); } 536 }; 537 538 random_condition() 539 { 540 probability(); 541 engine(); 542 } 543 544 static void 545 set_probability(double __p) 546 { probability() = __p; } 547 548 static void 549 throw_conditionally() 550 { 551 if (generate() < probability()) 552 __throw_forced_error(); 553 } 554 555 void 556 seed(unsigned long __s) 557 { engine().seed(__s); } 558 559 private: 560 #if __cplusplus >= 201103L 561 typedef std::uniform_real_distribution
distribution_type; 562 typedef std::mt19937 engine_type; 563 #else 564 typedef std::tr1::uniform_real
distribution_type; 565 typedef std::tr1::mt19937 engine_type; 566 #endif 567 568 static double 569 generate() 570 { 571 #if __cplusplus >= 201103L 572 const distribution_type distribution(0, 1); 573 static auto generator = std::bind(distribution, engine()); 574 #else 575 // Use variate_generator to get normalized results. 576 typedef std::tr1::variate_generator
gen_t; 577 distribution_type distribution(0, 1); 578 static gen_t generator(engine(), distribution); 579 #endif 580 581 #if ! __has_builtin(__builtin_sprintf) 582 __typeof__(&std::sprintf) __builtin_sprintf = &std::sprintf; 583 #endif 584 585 double random = generator(); 586 if (random < distribution.min() || random > distribution.max()) 587 { 588 std::string __s("random_condition::generate"); 589 __s += "\n"; 590 __s += "random number generated is: "; 591 char buf[40]; 592 __builtin_sprintf(buf, "%f", random); 593 __s += buf; 594 std::__throw_out_of_range(__s.c_str()); 595 } 596 597 return random; 598 } 599 600 static double& 601 probability() 602 { 603 static double _S_p; 604 return _S_p; 605 } 606 607 static engine_type& 608 engine() 609 { 610 static engine_type _S_e; 611 return _S_e; 612 } 613 }; 614 #endif // _GLIBCXX_USE_C99_STDINT_TR1 615 616 /** 617 * @brief Class with exception generation control. Intended to be 618 * used as a value_type in templatized code. 619 * 620 * Note: Destructor not allowed to throw. 621 */ 622 template
623 struct throw_value_base : public _Cond 624 { 625 typedef _Cond condition_type; 626 627 using condition_type::throw_conditionally; 628 629 std::size_t _M_i; 630 631 #ifndef _GLIBCXX_IS_AGGREGATE 632 throw_value_base() : _M_i(0) 633 { throw_conditionally(); } 634 635 throw_value_base(const throw_value_base& __v) : _M_i(__v._M_i) 636 { throw_conditionally(); } 637 638 #if __cplusplus >= 201103L 639 // Shall not throw. 640 throw_value_base(throw_value_base&&) = default; 641 #endif 642 643 explicit throw_value_base(const std::size_t __i) : _M_i(__i) 644 { throw_conditionally(); } 645 #endif 646 647 throw_value_base& 648 operator=(const throw_value_base& __v) 649 { 650 throw_conditionally(); 651 _M_i = __v._M_i; 652 return *this; 653 } 654 655 #if __cplusplus >= 201103L 656 // Shall not throw. 657 throw_value_base& 658 operator=(throw_value_base&&) = default; 659 #endif 660 661 throw_value_base& 662 operator++() 663 { 664 throw_conditionally(); 665 ++_M_i; 666 return *this; 667 } 668 }; 669 670 template
671 inline void 672 swap(throw_value_base<_Cond>& __a, throw_value_base<_Cond>& __b) 673 { 674 typedef throw_value_base<_Cond> throw_value; 675 throw_value::throw_conditionally(); 676 throw_value orig(__a); 677 __a = __b; 678 __b = orig; 679 } 680 681 // General instantiable types requirements. 682 template
683 inline bool 684 operator==(const throw_value_base<_Cond>& __a, 685 const throw_value_base<_Cond>& __b) 686 { 687 typedef throw_value_base<_Cond> throw_value; 688 throw_value::throw_conditionally(); 689 bool __ret = __a._M_i == __b._M_i; 690 return __ret; 691 } 692 693 template
694 inline bool 695 operator<(const throw_value_base<_Cond>& __a, 696 const throw_value_base<_Cond>& __b) 697 { 698 typedef throw_value_base<_Cond> throw_value; 699 throw_value::throw_conditionally(); 700 bool __ret = __a._M_i < __b._M_i; 701 return __ret; 702 } 703 704 // Numeric algorithms instantiable types requirements. 705 template
706 inline throw_value_base<_Cond> 707 operator+(const throw_value_base<_Cond>& __a, 708 const throw_value_base<_Cond>& __b) 709 { 710 typedef throw_value_base<_Cond> throw_value; 711 throw_value::throw_conditionally(); 712 throw_value __ret(__a._M_i + __b._M_i); 713 return __ret; 714 } 715 716 template
717 inline throw_value_base<_Cond> 718 operator-(const throw_value_base<_Cond>& __a, 719 const throw_value_base<_Cond>& __b) 720 { 721 typedef throw_value_base<_Cond> throw_value; 722 throw_value::throw_conditionally(); 723 throw_value __ret(__a._M_i - __b._M_i); 724 return __ret; 725 } 726 727 template
728 inline throw_value_base<_Cond> 729 operator*(const throw_value_base<_Cond>& __a, 730 const throw_value_base<_Cond>& __b) 731 { 732 typedef throw_value_base<_Cond> throw_value; 733 throw_value::throw_conditionally(); 734 throw_value __ret(__a._M_i * __b._M_i); 735 return __ret; 736 } 737 738 739 /// Type throwing via limit condition. 740 struct throw_value_limit : public throw_value_base
741 { 742 typedef throw_value_base
base_type; 743 744 #ifndef _GLIBCXX_IS_AGGREGATE 745 throw_value_limit() { } 746 747 throw_value_limit(const throw_value_limit& __other) 748 : base_type(__other._M_i) { } 749 750 #if __cplusplus >= 201103L 751 throw_value_limit(throw_value_limit&&) = default; 752 #endif 753 754 explicit throw_value_limit(const std::size_t __i) : base_type(__i) { } 755 #endif 756 757 throw_value_limit& 758 operator=(const throw_value_limit& __other) 759 { 760 base_type::operator=(__other); 761 return *this; 762 } 763 764 #if __cplusplus >= 201103L 765 throw_value_limit& 766 operator=(throw_value_limit&&) = default; 767 #endif 768 }; 769 770 #ifdef _GLIBCXX_USE_C99_STDINT_TR1 771 /// Type throwing via random condition. 772 struct throw_value_random : public throw_value_base
773 { 774 typedef throw_value_base
base_type; 775 776 #ifndef _GLIBCXX_IS_AGGREGATE 777 throw_value_random() { } 778 779 throw_value_random(const throw_value_random& __other) 780 : base_type(__other._M_i) { } 781 782 #if __cplusplus >= 201103L 783 throw_value_random(throw_value_random&&) = default; 784 #endif 785 786 explicit throw_value_random(const std::size_t __i) : base_type(__i) { } 787 #endif 788 789 throw_value_random& 790 operator=(const throw_value_random& __other) 791 { 792 base_type::operator=(__other); 793 return *this; 794 } 795 796 #if __cplusplus >= 201103L 797 throw_value_random& 798 operator=(throw_value_random&&) = default; 799 #endif 800 }; 801 #endif // _GLIBCXX_USE_C99_STDINT_TR1 802 803 /** 804 * @brief Allocator class with logging and exception generation control. 805 * Intended to be used as an allocator_type in templatized code. 806 * @ingroup allocators 807 * 808 * Note: Deallocate not allowed to throw. 809 */ 810 template
811 class throw_allocator_base 812 : public annotate_base, public _Cond 813 { 814 public: 815 typedef std::size_t size_type; 816 typedef std::ptrdiff_t difference_type; 817 typedef _Tp value_type; 818 typedef value_type* pointer; 819 typedef const value_type* const_pointer; 820 typedef value_type& reference; 821 typedef const value_type& const_reference; 822 823 #if __cplusplus >= 201103L 824 // _GLIBCXX_RESOLVE_LIB_DEFECTS 825 // 2103. std::allocator propagate_on_container_move_assignment 826 typedef std::true_type propagate_on_container_move_assignment; 827 #endif 828 829 private: 830 typedef _Cond condition_type; 831 832 std::allocator
_M_allocator; 833 834 typedef __gnu_cxx::__alloc_traits
> traits; 835 836 using condition_type::throw_conditionally; 837 838 public: 839 size_type 840 max_size() const _GLIBCXX_USE_NOEXCEPT 841 { return traits::max_size(_M_allocator); } 842 843 pointer 844 address(reference __x) const _GLIBCXX_NOEXCEPT 845 { return std::__addressof(__x); } 846 847 const_pointer 848 address(const_reference __x) const _GLIBCXX_NOEXCEPT 849 { return std::__addressof(__x); } 850 851 _GLIBCXX_NODISCARD pointer 852 allocate(size_type __n, const void* hint = 0) 853 { 854 if (__n > this->max_size()) 855 std::__throw_bad_alloc(); 856 857 throw_conditionally(); 858 pointer const a = traits::allocate(_M_allocator, __n, hint); 859 insert(a, sizeof(value_type) * __n); 860 return a; 861 } 862 863 #if __cplusplus >= 201103L 864 template
865 void 866 construct(_Up* __p, _Args&&... __args) 867 { 868 traits::construct(_M_allocator, __p, std::forward<_Args>(__args)...); 869 insert_construct(__p); 870 } 871 872 template
873 void 874 destroy(_Up* __p) 875 { 876 erase_construct(__p); 877 traits::destroy(_M_allocator, __p); 878 } 879 #else 880 void 881 construct(pointer __p, const value_type& val) 882 { return _M_allocator.construct(__p, val); } 883 884 void 885 destroy(pointer __p) 886 { _M_allocator.destroy(__p); } 887 #endif 888 889 void 890 deallocate(pointer __p, size_type __n) 891 { 892 erase(__p, sizeof(value_type) * __n); 893 _M_allocator.deallocate(__p, __n); 894 } 895 896 void 897 check_allocated(pointer __p, size_type __n) 898 { 899 size_type __t = sizeof(value_type) * __n; 900 annotate_base::check_allocated(__p, __t); 901 } 902 903 void 904 check(size_type __n) 905 { annotate_base::check(__n); } 906 }; 907 908 template
909 inline bool 910 operator==(const throw_allocator_base<_Tp, _Cond>&, 911 const throw_allocator_base<_Tp, _Cond>&) 912 { return true; } 913 914 #if __cpp_impl_three_way_comparison < 201907L 915 template
916 inline bool 917 operator!=(const throw_allocator_base<_Tp, _Cond>&, 918 const throw_allocator_base<_Tp, _Cond>&) 919 { return false; } 920 #endif 921 922 /// Allocator throwing via limit condition. 923 template
924 struct throw_allocator_limit 925 : public throw_allocator_base<_Tp, limit_condition> 926 { 927 template
928 struct rebind 929 { typedef throw_allocator_limit<_Tp1> other; }; 930 931 throw_allocator_limit() _GLIBCXX_USE_NOEXCEPT { } 932 933 throw_allocator_limit(const throw_allocator_limit&) 934 _GLIBCXX_USE_NOEXCEPT { } 935 936 template
937 throw_allocator_limit(const throw_allocator_limit<_Tp1>&) 938 _GLIBCXX_USE_NOEXCEPT { } 939 940 ~throw_allocator_limit() _GLIBCXX_USE_NOEXCEPT { } 941 942 #if __cplusplus >= 201103L 943 throw_allocator_limit& 944 operator=(const throw_allocator_limit&) = default; 945 #endif 946 }; 947 948 #ifdef _GLIBCXX_USE_C99_STDINT_TR1 949 /// Allocator throwing via random condition. 950 template
951 struct throw_allocator_random 952 : public throw_allocator_base<_Tp, random_condition> 953 { 954 template
955 struct rebind 956 { typedef throw_allocator_random<_Tp1> other; }; 957 958 throw_allocator_random() _GLIBCXX_USE_NOEXCEPT { } 959 960 throw_allocator_random(const throw_allocator_random&) 961 _GLIBCXX_USE_NOEXCEPT { } 962 963 template
964 throw_allocator_random(const throw_allocator_random<_Tp1>&) 965 _GLIBCXX_USE_NOEXCEPT { } 966 967 ~throw_allocator_random() _GLIBCXX_USE_NOEXCEPT { } 968 969 #if __cplusplus >= 201103L 970 throw_allocator_random& 971 operator=(const throw_allocator_random&) = default; 972 #endif 973 }; 974 #endif // _GLIBCXX_USE_C99_STDINT_TR1 975 976 _GLIBCXX_END_NAMESPACE_VERSION 977 } // namespace 978 979 #if __cplusplus >= 201103L 980 981 # include
982 983 namespace std _GLIBCXX_VISIBILITY(default) 984 { 985 /// Explicit specialization of std::hash for __gnu_cxx::throw_value_limit. 986 template<> 987 struct hash<__gnu_cxx::throw_value_limit> 988 : public std::unary_function<__gnu_cxx::throw_value_limit, size_t> 989 { 990 size_t 991 operator()(const __gnu_cxx::throw_value_limit& __val) const 992 { 993 __gnu_cxx::throw_value_limit::throw_conditionally(); 994 std::hash
__h; 995 size_t __result = __h(__val._M_i); 996 return __result; 997 } 998 }; 999 1000 #ifdef _GLIBCXX_USE_C99_STDINT_TR1 1001 /// Explicit specialization of std::hash for __gnu_cxx::throw_value_random. 1002 template<> 1003 struct hash<__gnu_cxx::throw_value_random> 1004 : public std::unary_function<__gnu_cxx::throw_value_random, size_t> 1005 { 1006 size_t 1007 operator()(const __gnu_cxx::throw_value_random& __val) const 1008 { 1009 __gnu_cxx::throw_value_random::throw_conditionally(); 1010 std::hash
__h; 1011 size_t __result = __h(__val._M_i); 1012 return __result; 1013 } 1014 }; 1015 #endif 1016 } // end namespace std 1017 #endif 1018 1019 #endif
Contact us
|
About us
|
Term of use
|
Copyright © 2000-2024 MyWebUniversity.com ™