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