PSP2SDK  dirty-f9e4f2d
The free SDK for PSP2
include/c++/ext/throw_allocator.h
Go to the documentation of this file.
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
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines