PSP2SDK
dirty-f9e4f2d
The free SDK for PSP2
|
00001 // -*- C++ -*- 00002 00003 // Copyright (C) 2015 PSP2SDK Project 00004 // This file is modified by PSP2SDK Team 00005 00006 // Copyright (C) 2005-2014 Free Software Foundation, Inc. 00007 // 00008 // This file is part of the GNU ISO C++ Library. This library is free 00009 // software; you can redistribute it and/or modify it under the terms 00010 // of the GNU General Public License as published by the Free Software 00011 // Foundation; either version 3, or (at your option) any later 00012 // version. 00013 00014 // This library is distributed in the hope that it will be useful, but 00015 // WITHOUT ANY WARRANTY; without even the implied warranty of 00016 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00017 // General Public License for more details. 00018 00019 // Under Section 7 of GPL version 3, you are granted additional 00020 // permissions described in the GCC Runtime Library Exception, version 00021 // 3.1, as published by the Free Software Foundation. 00022 00023 // You should have received a copy of the GNU General Public License and 00024 // a copy of the GCC Runtime Library Exception along with this program; 00025 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 00026 // <http://www.gnu.org/licenses/>. 00027 00028 // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. 00029 00030 // Permission to use, copy, modify, sell, and distribute this software 00031 // is hereby granted without fee, provided that the above copyright 00032 // notice appears in all copies, and that both that copyright notice 00033 // and this permission notice appear in supporting documentation. None 00034 // of the above authors, nor IBM Haifa Research Laboratories, make any 00035 // representation about the suitability of this software for any 00036 // purpose. It is provided "as is" without express or implied 00037 // warranty. 00038 00049 #ifndef _THROW_ALLOCATOR_H 00050 #define _THROW_ALLOCATOR_H 1 00051 00052 #include <cmath> 00053 #include <ctime> 00054 #include <map> 00055 #include <string> 00056 #include <ostream> 00057 #include <stdexcept> 00058 #include <utility> 00059 #include <bits/functexcept.h> 00060 #include <bits/move.h> 00061 #if __cplusplus >= 201103L 00062 # include <functional> 00063 # include <random> 00064 #else 00065 # include <tr1/functional> 00066 # include <tr1/random> 00067 #endif 00068 00069 namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) 00070 { 00071 _GLIBCXX_BEGIN_NAMESPACE_VERSION 00072 00077 struct forced_error : public std::exception 00078 { }; 00079 00080 // Substitute for forced_error object when -fno-exceptions. 00081 inline void 00082 __throw_forced_error() 00083 { _GLIBCXX_THROW_OR_ABORT(forced_error()); } 00084 00091 struct annotate_base 00092 { 00093 annotate_base() 00094 { 00095 label(); 00096 map_alloc(); 00097 } 00098 00099 static void 00100 set_label(size_t l) 00101 { label() = l; } 00102 00103 static size_t 00104 get_label() 00105 { return label(); } 00106 00107 void 00108 insert(void* p, size_t size) 00109 { 00110 if (!p) 00111 { 00112 std::string error("annotate_base::insert null insert!\n"); 00113 log_to_string(error, make_entry(p, size)); 00114 throw logic_error(error.c_str()); 00115 } 00116 00117 const_iterator found = map_alloc().find(p); 00118 if (found != map_alloc().end()) 00119 { 00120 std::string error("annotate_base::insert double insert!\n"); 00121 log_to_string(error, make_entry(p, size)); 00122 log_to_string(error, *found); 00123 throw logic_error(error.c_str()); 00124 } 00125 00126 map_alloc().insert(make_entry(p, size)); 00127 } 00128 00129 void 00130 erase(void* p, size_t size) 00131 { 00132 check_allocated(p, size); 00133 map_alloc().erase(p); 00134 } 00135 00136 #if __cplusplus >= 201103L 00137 void 00138 insert_construct(void* p) 00139 { 00140 if (!p) 00141 { 00142 std::string error("annotate_base::insert_construct null!\n"); 00143 throw logic_error(error.c_str()); 00144 } 00145 00146 auto found = map_construct().find(p); 00147 if (found != map_construct().end()) 00148 { 00149 std::string error("annotate_base::insert_construct double insert!\n"); 00150 log_to_string(error, std::make_pair(p, get_label())); 00151 log_to_string(error, *found); 00152 throw logic_error(error.c_str()); 00153 } 00154 00155 map_construct().insert(std::make_pair(p, get_label())); 00156 } 00157 00158 void 00159 erase_construct(void* p) 00160 { 00161 check_constructed(p); 00162 map_construct().erase(p); 00163 } 00164 #endif 00165 00166 // See if a particular address and allocation size has been saved. 00167 inline void 00168 check_allocated(void* p, size_t size) 00169 { 00170 const_iterator found = map_alloc().find(p); 00171 if (found == map_alloc().end()) 00172 { 00173 std::string error("annotate_base::check_allocated by value " 00174 "null erase!\n"); 00175 log_to_string(error, make_entry(p, size)); 00176 throw logic_error(error.c_str()); 00177 } 00178 00179 if (found->second.second != size) 00180 { 00181 std::string error("annotate_base::check_allocated by value " 00182 "wrong-size erase!\n"); 00183 log_to_string(error, make_entry(p, size)); 00184 log_to_string(error, *found); 00185 throw logic_error(error.c_str()); 00186 } 00187 } 00188 00189 // See if a given label has been allocated. 00190 inline void 00191 check(size_t label) 00192 { 00193 std::string found; 00194 { 00195 const_iterator beg = map_alloc().begin(); 00196 const_iterator end = map_alloc().end(); 00197 while (beg != end) 00198 { 00199 if (beg->second.first == label) 00200 log_to_string(found, *beg); 00201 ++beg; 00202 } 00203 } 00204 00205 #if __cplusplus >= 201103L 00206 { 00207 auto beg = map_construct().begin(); 00208 auto end = map_construct().end(); 00209 while (beg != end) 00210 { 00211 if (beg->second == label) 00212 log_to_string(found, *beg); 00213 ++beg; 00214 } 00215 } 00216 #endif 00217 00218 if (!found.empty()) 00219 { 00220 std::string error("annotate_base::check by label\n"); 00221 error += found; 00222 throw logic_error(error.c_str()); 00223 } 00224 } 00225 00226 // See if there is anything left allocated or constructed. 00227 inline static void 00228 check() 00229 { 00230 std::string found; 00231 { 00232 const_iterator beg = map_alloc().begin(); 00233 const_iterator end = map_alloc().end(); 00234 while (beg != end) 00235 { 00236 log_to_string(found, *beg); 00237 ++beg; 00238 } 00239 } 00240 00241 #if __cplusplus >= 201103L 00242 { 00243 auto beg = map_construct().begin(); 00244 auto end = map_construct().end(); 00245 while (beg != end) 00246 { 00247 log_to_string(found, *beg); 00248 ++beg; 00249 } 00250 } 00251 #endif 00252 00253 if (!found.empty()) 00254 { 00255 std::string error("annotate_base::check \n"); 00256 error += found; 00257 throw logic_error(error.c_str()); 00258 } 00259 } 00260 00261 #if __cplusplus >= 201103L 00262 inline void 00263 check_constructed(void* p) 00264 { 00265 auto found = map_construct().find(p); 00266 if (found == map_construct().end()) 00267 { 00268 std::string error("annotate_base::check_constructed not " 00269 "constructed!\n"); 00270 log_to_string(error, std::make_pair(p, get_label())); 00271 throw logic_error(error.c_str()); 00272 } 00273 } 00274 00275 inline void 00276 check_constructed(size_t label) 00277 { 00278 auto beg = map_construct().begin(); 00279 auto end = map_construct().end(); 00280 std::string found; 00281 while (beg != end) 00282 { 00283 if (beg->second == label) 00284 log_to_string(found, *beg); 00285 ++beg; 00286 } 00287 00288 if (!found.empty()) 00289 { 00290 std::string error("annotate_base::check_constructed by label\n"); 00291 error += found; 00292 throw logic_error(error.c_str()); 00293 } 00294 } 00295 #endif 00296 00297 private: 00298 typedef std::pair<size_t, size_t> data_type; 00299 typedef std::map<void*, data_type> map_alloc_type; 00300 typedef map_alloc_type::value_type entry_type; 00301 typedef map_alloc_type::const_iterator const_iterator; 00302 typedef map_alloc_type::const_reference const_reference; 00303 #if __cplusplus >= 201103L 00304 typedef std::map<void*, size_t> map_construct_type; 00305 #endif 00306 00307 friend std::ostream& 00308 operator<<(std::ostream&, const annotate_base&); 00309 00310 entry_type 00311 make_entry(void* p, size_t size) 00312 { return std::make_pair(p, data_type(get_label(), size)); } 00313 00314 static void 00315 log_to_string(std::string& s, const_reference ref) 00316 { 00317 char buf[40]; 00318 const char tab('\t'); 00319 s += "label: "; 00320 unsigned long l = static_cast<unsigned long>(ref.second.first); 00321 __builtin_sprintf(buf, "%lu", l); 00322 s += buf; 00323 s += tab; 00324 s += "size: "; 00325 l = static_cast<unsigned long>(ref.second.second); 00326 __builtin_sprintf(buf, "%lu", l); 00327 s += buf; 00328 s += tab; 00329 s += "address: "; 00330 __builtin_sprintf(buf, "%p", ref.first); 00331 s += buf; 00332 s += '\n'; 00333 } 00334 00335 #if __cplusplus >= 201103L 00336 static void 00337 log_to_string(std::string& s, const std::pair<const void*, size_t>& ref) 00338 { 00339 char buf[40]; 00340 const char tab('\t'); 00341 s += "label: "; 00342 unsigned long l = static_cast<unsigned long>(ref.second); 00343 __builtin_sprintf(buf, "%lu", l); 00344 s += buf; 00345 s += tab; 00346 s += "address: "; 00347 __builtin_sprintf(buf, "%p", ref.first); 00348 s += buf; 00349 s += '\n'; 00350 } 00351 #endif 00352 00353 static size_t& 00354 label() 00355 { 00356 static size_t _S_label(std::numeric_limits<size_t>::max()); 00357 return _S_label; 00358 } 00359 00360 static map_alloc_type& 00361 map_alloc() 00362 { 00363 static map_alloc_type _S_map; 00364 return _S_map; 00365 } 00366 00367 #if __cplusplus >= 201103L 00368 static map_construct_type& 00369 map_construct() 00370 { 00371 static map_construct_type _S_map; 00372 return _S_map; 00373 } 00374 #endif 00375 }; 00376 00377 inline std::ostream& 00378 operator<<(std::ostream& os, const annotate_base& __b) 00379 { 00380 std::string error; 00381 typedef annotate_base base_type; 00382 { 00383 base_type::const_iterator beg = __b.map_alloc().begin(); 00384 base_type::const_iterator end = __b.map_alloc().end(); 00385 for (; beg != end; ++beg) 00386 __b.log_to_string(error, *beg); 00387 } 00388 #if __cplusplus >= 201103L 00389 { 00390 auto beg = __b.map_construct().begin(); 00391 auto end = __b.map_construct().end(); 00392 for (; beg != end; ++beg) 00393 __b.log_to_string(error, *beg); 00394 } 00395 #endif 00396 return os << error; 00397 } 00398 00399 00406 struct condition_base 00407 { 00408 virtual ~condition_base() { }; 00409 }; 00410 00411 00415 struct limit_condition : public condition_base 00416 { 00417 // Scope-level adjustor objects: set limit for throw at the 00418 // beginning of a scope block, and restores to previous limit when 00419 // object is destroyed on exiting the block. 00420 struct adjustor_base 00421 { 00422 private: 00423 const size_t _M_orig; 00424 00425 public: 00426 adjustor_base() : _M_orig(limit()) { } 00427 00428 virtual 00429 ~adjustor_base() { set_limit(_M_orig); } 00430 }; 00431 00433 struct never_adjustor : public adjustor_base 00434 { 00435 never_adjustor() { set_limit(std::numeric_limits<size_t>::max()); } 00436 }; 00437 00439 struct always_adjustor : public adjustor_base 00440 { 00441 always_adjustor() { set_limit(count()); } 00442 }; 00443 00445 struct limit_adjustor : public adjustor_base 00446 { 00447 limit_adjustor(const size_t __l) { set_limit(__l); } 00448 }; 00449 00450 // Increment _S_count every time called. 00451 // If _S_count matches the limit count, throw. 00452 static void 00453 throw_conditionally() 00454 { 00455 if (count() == limit()) 00456 __throw_forced_error(); 00457 ++count(); 00458 } 00459 00460 static size_t& 00461 count() 00462 { 00463 static size_t _S_count(0); 00464 return _S_count; 00465 } 00466 00467 static size_t& 00468 limit() 00469 { 00470 static size_t _S_limit(std::numeric_limits<size_t>::max()); 00471 return _S_limit; 00472 } 00473 00474 // Zero the throw counter, set limit to argument. 00475 static void 00476 set_limit(const size_t __l) 00477 { 00478 limit() = __l; 00479 count() = 0; 00480 } 00481 }; 00482 00483 00487 struct random_condition : public condition_base 00488 { 00489 // Scope-level adjustor objects: set probability for throw at the 00490 // beginning of a scope block, and restores to previous 00491 // probability when object is destroyed on exiting the block. 00492 struct adjustor_base 00493 { 00494 private: 00495 const double _M_orig; 00496 00497 public: 00498 adjustor_base() : _M_orig(probability()) { } 00499 00500 virtual ~adjustor_base() 00501 { set_probability(_M_orig); } 00502 }; 00503 00505 struct group_adjustor : public adjustor_base 00506 { 00507 group_adjustor(size_t size) 00508 { set_probability(1 - std::pow(double(1 - probability()), 00509 double(0.5 / (size + 1)))); 00510 } 00511 }; 00512 00514 struct never_adjustor : public adjustor_base 00515 { 00516 never_adjustor() { set_probability(0); } 00517 }; 00518 00520 struct always_adjustor : public adjustor_base 00521 { 00522 always_adjustor() { set_probability(1); } 00523 }; 00524 00525 random_condition() 00526 { 00527 probability(); 00528 engine(); 00529 } 00530 00531 static void 00532 set_probability(double __p) 00533 { probability() = __p; } 00534 00535 static void 00536 throw_conditionally() 00537 { 00538 if (generate() < probability()) 00539 __throw_forced_error(); 00540 } 00541 00542 void 00543 seed(unsigned long __s) 00544 { engine().seed(__s); } 00545 00546 private: 00547 #if __cplusplus >= 201103L 00548 typedef std::uniform_real_distribution<double> distribution_type; 00549 typedef std::mt19937 engine_type; 00550 #else 00551 typedef std::tr1::uniform_real<double> distribution_type; 00552 typedef std::tr1::mt19937 engine_type; 00553 #endif 00554 00555 static double 00556 generate() 00557 { 00558 #if __cplusplus >= 201103L 00559 const distribution_type distribution(0, 1); 00560 static auto generator = std::bind(distribution, engine()); 00561 #else 00562 // Use variate_generator to get normalized results. 00563 typedef std::tr1::variate_generator<engine_type, distribution_type> gen_t; 00564 distribution_type distribution(0, 1); 00565 static gen_t generator(engine(), distribution); 00566 #endif 00567 00568 double random = generator(); 00569 if (random < distribution.min() || random > distribution.max()) 00570 { 00571 std::string __s("random_condition::generate"); 00572 __s += "\n"; 00573 __s += "random number generated is: "; 00574 char buf[40]; 00575 __builtin_sprintf(buf, "%f", random); 00576 __s += buf; 00577 std::__throw_out_of_range(__s.c_str()); 00578 } 00579 00580 return random; 00581 } 00582 00583 static double& 00584 probability() 00585 { 00586 static double _S_p; 00587 return _S_p; 00588 } 00589 00590 static engine_type& 00591 engine() 00592 { 00593 static engine_type _S_e; 00594 return _S_e; 00595 } 00596 }; 00597 00598 00605 template<typename _Cond> 00606 struct throw_value_base : public _Cond 00607 { 00608 typedef _Cond condition_type; 00609 00610 using condition_type::throw_conditionally; 00611 00612 std::size_t _M_i; 00613 00614 #ifndef _GLIBCXX_IS_AGGREGATE 00615 throw_value_base() : _M_i(0) 00616 { throw_conditionally(); } 00617 00618 throw_value_base(const throw_value_base& __v) : _M_i(__v._M_i) 00619 { throw_conditionally(); } 00620 00621 #if __cplusplus >= 201103L 00622 // Shall not throw. 00623 throw_value_base(throw_value_base&&) = default; 00624 #endif 00625 00626 explicit throw_value_base(const std::size_t __i) : _M_i(__i) 00627 { throw_conditionally(); } 00628 #endif 00629 00630 throw_value_base& 00631 operator=(const throw_value_base& __v) 00632 { 00633 throw_conditionally(); 00634 _M_i = __v._M_i; 00635 return *this; 00636 } 00637 00638 #if __cplusplus >= 201103L 00639 // Shall not throw. 00640 throw_value_base& 00641 operator=(throw_value_base&&) = default; 00642 #endif 00643 00644 throw_value_base& 00645 operator++() 00646 { 00647 throw_conditionally(); 00648 ++_M_i; 00649 return *this; 00650 } 00651 }; 00652 00653 template<typename _Cond> 00654 inline void 00655 swap(throw_value_base<_Cond>& __a, throw_value_base<_Cond>& __b) 00656 { 00657 typedef throw_value_base<_Cond> throw_value; 00658 throw_value::throw_conditionally(); 00659 throw_value orig(__a); 00660 __a = __b; 00661 __b = orig; 00662 } 00663 00664 // General instantiable types requirements. 00665 template<typename _Cond> 00666 inline bool 00667 operator==(const throw_value_base<_Cond>& __a, 00668 const throw_value_base<_Cond>& __b) 00669 { 00670 typedef throw_value_base<_Cond> throw_value; 00671 throw_value::throw_conditionally(); 00672 bool __ret = __a._M_i == __b._M_i; 00673 return __ret; 00674 } 00675 00676 template<typename _Cond> 00677 inline bool 00678 operator<(const throw_value_base<_Cond>& __a, 00679 const throw_value_base<_Cond>& __b) 00680 { 00681 typedef throw_value_base<_Cond> throw_value; 00682 throw_value::throw_conditionally(); 00683 bool __ret = __a._M_i < __b._M_i; 00684 return __ret; 00685 } 00686 00687 // Numeric algorithms instantiable types requirements. 00688 template<typename _Cond> 00689 inline throw_value_base<_Cond> 00690 operator+(const throw_value_base<_Cond>& __a, 00691 const throw_value_base<_Cond>& __b) 00692 { 00693 typedef throw_value_base<_Cond> throw_value; 00694 throw_value::throw_conditionally(); 00695 throw_value __ret(__a._M_i + __b._M_i); 00696 return __ret; 00697 } 00698 00699 template<typename _Cond> 00700 inline throw_value_base<_Cond> 00701 operator-(const throw_value_base<_Cond>& __a, 00702 const throw_value_base<_Cond>& __b) 00703 { 00704 typedef throw_value_base<_Cond> throw_value; 00705 throw_value::throw_conditionally(); 00706 throw_value __ret(__a._M_i - __b._M_i); 00707 return __ret; 00708 } 00709 00710 template<typename _Cond> 00711 inline throw_value_base<_Cond> 00712 operator*(const throw_value_base<_Cond>& __a, 00713 const throw_value_base<_Cond>& __b) 00714 { 00715 typedef throw_value_base<_Cond> throw_value; 00716 throw_value::throw_conditionally(); 00717 throw_value __ret(__a._M_i * __b._M_i); 00718 return __ret; 00719 } 00720 00721 00723 struct throw_value_limit : public throw_value_base<limit_condition> 00724 { 00725 typedef throw_value_base<limit_condition> base_type; 00726 00727 #ifndef _GLIBCXX_IS_AGGREGATE 00728 throw_value_limit() { } 00729 00730 throw_value_limit(const throw_value_limit& __other) 00731 : base_type(__other._M_i) { } 00732 00733 #if __cplusplus >= 201103L 00734 throw_value_limit(throw_value_limit&&) = default; 00735 #endif 00736 00737 explicit throw_value_limit(const std::size_t __i) : base_type(__i) { } 00738 #endif 00739 00740 throw_value_limit& 00741 operator=(const throw_value_limit& __other) 00742 { 00743 base_type::operator=(__other); 00744 return *this; 00745 } 00746 00747 #if __cplusplus >= 201103L 00748 throw_value_limit& 00749 operator=(throw_value_limit&&) = default; 00750 #endif 00751 }; 00752 00754 struct throw_value_random : public throw_value_base<random_condition> 00755 { 00756 typedef throw_value_base<random_condition> base_type; 00757 00758 #ifndef _GLIBCXX_IS_AGGREGATE 00759 throw_value_random() { } 00760 00761 throw_value_random(const throw_value_random& __other) 00762 : base_type(__other._M_i) { } 00763 00764 #if __cplusplus >= 201103L 00765 throw_value_random(throw_value_random&&) = default; 00766 #endif 00767 00768 explicit throw_value_random(const std::size_t __i) : base_type(__i) { } 00769 #endif 00770 00771 throw_value_random& 00772 operator=(const throw_value_random& __other) 00773 { 00774 base_type::operator=(__other); 00775 return *this; 00776 } 00777 00778 #if __cplusplus >= 201103L 00779 throw_value_random& 00780 operator=(throw_value_random&&) = default; 00781 #endif 00782 }; 00783 00784 00792 template<typename _Tp, typename _Cond> 00793 class throw_allocator_base 00794 : public annotate_base, public _Cond 00795 { 00796 public: 00797 typedef size_t size_type; 00798 typedef ptrdiff_t difference_type; 00799 typedef _Tp value_type; 00800 typedef value_type* pointer; 00801 typedef const value_type* const_pointer; 00802 typedef value_type& reference; 00803 typedef const value_type& const_reference; 00804 00805 #if __cplusplus >= 201103L 00806 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00807 // 2103. std::allocator propagate_on_container_move_assignment 00808 typedef std::true_type propagate_on_container_move_assignment; 00809 #endif 00810 00811 private: 00812 typedef _Cond condition_type; 00813 00814 std::allocator<value_type> _M_allocator; 00815 00816 using condition_type::throw_conditionally; 00817 00818 public: 00819 size_type 00820 max_size() const _GLIBCXX_USE_NOEXCEPT 00821 { return _M_allocator.max_size(); } 00822 00823 pointer 00824 address(reference __x) const _GLIBCXX_NOEXCEPT 00825 { return std::__addressof(__x); } 00826 00827 const_pointer 00828 address(const_reference __x) const _GLIBCXX_NOEXCEPT 00829 { return std::__addressof(__x); } 00830 00831 pointer 00832 allocate(size_type __n, std::allocator<void>::const_pointer hint = 0) 00833 { 00834 if (__n > this->max_size()) 00835 std::__throw_bad_alloc(); 00836 00837 throw_conditionally(); 00838 pointer const a = _M_allocator.allocate(__n, hint); 00839 insert(a, sizeof(value_type) * __n); 00840 return a; 00841 } 00842 00843 #if __cplusplus >= 201103L 00844 template<typename _Up, typename... _Args> 00845 void 00846 construct(_Up* __p, _Args&&... __args) 00847 { 00848 _M_allocator.construct(__p, std::forward<_Args>(__args)...); 00849 insert_construct(__p); 00850 } 00851 00852 template<typename _Up> 00853 void 00854 destroy(_Up* __p) 00855 { 00856 erase_construct(__p); 00857 _M_allocator.destroy(__p); 00858 } 00859 #else 00860 void 00861 construct(pointer __p, const value_type& val) 00862 { return _M_allocator.construct(__p, val); } 00863 00864 void 00865 destroy(pointer __p) 00866 { _M_allocator.destroy(__p); } 00867 #endif 00868 00869 void 00870 deallocate(pointer __p, size_type __n) 00871 { 00872 erase(__p, sizeof(value_type) * __n); 00873 _M_allocator.deallocate(__p, __n); 00874 } 00875 00876 void 00877 check_allocated(pointer __p, size_type __n) 00878 { 00879 size_type __t = sizeof(value_type) * __n; 00880 annotate_base::check_allocated(__p, __t); 00881 } 00882 00883 void 00884 check(size_type __n) 00885 { annotate_base::check(__n); } 00886 }; 00887 00888 template<typename _Tp, typename _Cond> 00889 inline bool 00890 operator==(const throw_allocator_base<_Tp, _Cond>&, 00891 const throw_allocator_base<_Tp, _Cond>&) 00892 { return true; } 00893 00894 template<typename _Tp, typename _Cond> 00895 inline bool 00896 operator!=(const throw_allocator_base<_Tp, _Cond>&, 00897 const throw_allocator_base<_Tp, _Cond>&) 00898 { return false; } 00899 00901 template<typename _Tp> 00902 struct throw_allocator_limit 00903 : public throw_allocator_base<_Tp, limit_condition> 00904 { 00905 template<typename _Tp1> 00906 struct rebind 00907 { typedef throw_allocator_limit<_Tp1> other; }; 00908 00909 throw_allocator_limit() _GLIBCXX_USE_NOEXCEPT { } 00910 00911 throw_allocator_limit(const throw_allocator_limit&) 00912 _GLIBCXX_USE_NOEXCEPT { } 00913 00914 template<typename _Tp1> 00915 throw_allocator_limit(const throw_allocator_limit<_Tp1>&) 00916 _GLIBCXX_USE_NOEXCEPT { } 00917 00918 ~throw_allocator_limit() _GLIBCXX_USE_NOEXCEPT { } 00919 }; 00920 00922 template<typename _Tp> 00923 struct throw_allocator_random 00924 : public throw_allocator_base<_Tp, random_condition> 00925 { 00926 template<typename _Tp1> 00927 struct rebind 00928 { typedef throw_allocator_random<_Tp1> other; }; 00929 00930 throw_allocator_random() _GLIBCXX_USE_NOEXCEPT { } 00931 00932 throw_allocator_random(const throw_allocator_random&) 00933 _GLIBCXX_USE_NOEXCEPT { } 00934 00935 template<typename _Tp1> 00936 throw_allocator_random(const throw_allocator_random<_Tp1>&) 00937 _GLIBCXX_USE_NOEXCEPT { } 00938 00939 ~throw_allocator_random() _GLIBCXX_USE_NOEXCEPT { } 00940 }; 00941 00942 _GLIBCXX_END_NAMESPACE_VERSION 00943 } // namespace 00944 00945 #if __cplusplus >= 201103L 00946 00947 # include <bits/functional_hash.h> 00948 00949 namespace std _GLIBCXX_VISIBILITY(default) 00950 { 00952 template<> 00953 struct hash<__gnu_cxx::throw_value_limit> 00954 : public std::unary_function<__gnu_cxx::throw_value_limit, size_t> 00955 { 00956 size_t 00957 operator()(const __gnu_cxx::throw_value_limit& __val) const 00958 { 00959 __gnu_cxx::throw_value_limit::throw_conditionally(); 00960 std::hash<std::size_t> __h; 00961 size_t __result = __h(__val._M_i); 00962 return __result; 00963 } 00964 }; 00965 00967 template<> 00968 struct hash<__gnu_cxx::throw_value_random> 00969 : public std::unary_function<__gnu_cxx::throw_value_random, size_t> 00970 { 00971 size_t 00972 operator()(const __gnu_cxx::throw_value_random& __val) const 00973 { 00974 __gnu_cxx::throw_value_random::throw_conditionally(); 00975 std::hash<std::size_t> __h; 00976 size_t __result = __h(__val._M_i); 00977 return __result; 00978 } 00979 }; 00980 } // end namespace std 00981 #endif 00982 00983 #endif