libstdc++
throw_allocator.h
Go to the documentation of this file.
1// -*- C++ -*-
2
3// Copyright (C) 2005-2022 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#include <ext/alloc_traits.h>
66
67#if !__has_builtin(__builtin_sprintf)
68# include <cstdio>
69#endif
70
71namespace __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 */
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 */
94 {
95 private:
99 typedef map_alloc_type::const_iterator const_iterator;
100 typedef map_alloc_type::const_reference const_reference;
101#if __cplusplus >= 201103L
103#endif
104
105 public:
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
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
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<unsigned long>(ref.second.first);
325 __builtin_sprintf(buf, "%lu", l);
326 s += buf;
327 s += tab;
328 s += "size: ";
329 l = static_cast<unsigned long>(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<const void*, size_t>& 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<unsigned long>(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<size_t>::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 */
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 */
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 {
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<size_t>::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 */
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
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<double> distribution_type;
562 typedef std::mt19937 engine_type;
563#else
564 typedef std::tr1::uniform_real<double> 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<engine_type, distribution_type> 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<typename _Cond>
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.
641#endif
642
643 explicit throw_value_base(const std::size_t __i) : _M_i(__i)
644 { throw_conditionally(); }
645#endif
646
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.
658 operator=(throw_value_base&&) = default;
659#endif
660
662 operator++()
663 {
664 throw_conditionally();
665 ++_M_i;
666 return *this;
667 }
668 };
669
670 template<typename _Cond>
671 inline void
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<typename _Cond>
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<typename _Cond>
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<typename _Cond>
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<typename _Cond>
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<typename _Cond>
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<limit_condition>
741 {
743
744#ifndef _GLIBCXX_IS_AGGREGATE
746
748 : base_type(__other._M_i) { }
749
750#if __cplusplus >= 201103L
752#endif
753
754 explicit throw_value_limit(const std::size_t __i) : base_type(__i) { }
755#endif
756
758 operator=(const throw_value_limit& __other)
759 {
760 base_type::operator=(__other);
761 return *this;
762 }
763
764#if __cplusplus >= 201103L
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<random_condition>
773 {
775
776#ifndef _GLIBCXX_IS_AGGREGATE
778
780 : base_type(__other._M_i) { }
781
782#if __cplusplus >= 201103L
784#endif
785
786 explicit throw_value_random(const std::size_t __i) : base_type(__i) { }
787#endif
788
790 operator=(const throw_value_random& __other)
791 {
792 base_type::operator=(__other);
793 return *this;
794 }
795
796#if __cplusplus >= 201103L
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<typename _Tp, typename _Cond>
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
827#endif
828
829 private:
830 typedef _Cond condition_type;
831
832 std::allocator<value_type> _M_allocator;
833
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<typename _Up, typename... _Args>
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<typename _Up>
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<typename _Tp, typename _Cond>
909 inline bool
910 operator==(const throw_allocator_base<_Tp, _Cond>&,
912 { return true; }
913
914#if __cpp_impl_three_way_comparison < 201907L
915 template<typename _Tp, typename _Cond>
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<typename _Tp>
925 : public throw_allocator_base<_Tp, limit_condition>
926 {
927 template<typename _Tp1>
928 struct rebind
929 { typedef throw_allocator_limit<_Tp1> other; };
930
931 throw_allocator_limit() _GLIBCXX_USE_NOEXCEPT { }
932
934 _GLIBCXX_USE_NOEXCEPT { }
935
936 template<typename _Tp1>
938 _GLIBCXX_USE_NOEXCEPT { }
939
940 ~throw_allocator_limit() _GLIBCXX_USE_NOEXCEPT { }
941
942#if __cplusplus >= 201103L
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<typename _Tp>
952 : public throw_allocator_base<_Tp, random_condition>
953 {
954 template<typename _Tp1>
955 struct rebind
956 { typedef throw_allocator_random<_Tp1> other; };
957
958 throw_allocator_random() _GLIBCXX_USE_NOEXCEPT { }
959
961 _GLIBCXX_USE_NOEXCEPT { }
962
963 template<typename _Tp1>
965 _GLIBCXX_USE_NOEXCEPT { }
966
967 ~throw_allocator_random() _GLIBCXX_USE_NOEXCEPT { }
968
969#if __cplusplus >= 201103L
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 <bits/functional_hash.h>
982
983namespace std _GLIBCXX_VISIBILITY(default)
984{
985#pragma GCC diagnostic push
986#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
987
988 /// Explicit specialization of std::hash for __gnu_cxx::throw_value_limit.
989 template<>
990 struct hash<__gnu_cxx::throw_value_limit>
991 : public std::unary_function<__gnu_cxx::throw_value_limit, size_t>
992 {
993 size_t
994 operator()(const __gnu_cxx::throw_value_limit& __val) const
995 {
996 __gnu_cxx::throw_value_limit::throw_conditionally();
998 size_t __result = __h(__val._M_i);
999 return __result;
1000 }
1001 };
1002
1003#ifdef _GLIBCXX_USE_C99_STDINT_TR1
1004 /// Explicit specialization of std::hash for __gnu_cxx::throw_value_random.
1005 template<>
1006 struct hash<__gnu_cxx::throw_value_random>
1007 : public std::unary_function<__gnu_cxx::throw_value_random, size_t>
1008 {
1009 size_t
1010 operator()(const __gnu_cxx::throw_value_random& __val) const
1011 {
1012 __gnu_cxx::throw_value_random::throw_conditionally();
1014 size_t __result = __h(__val._M_i);
1015 return __result;
1016 }
1017 };
1018#endif
1019
1020#pragma GCC diagnostic pop
1021} // end namespace std
1022#endif
1023
1024#endif
constexpr complex< _Tp > operator*(const complex< _Tp > &__x, const complex< _Tp > &__y)
Return new complex value x times y.
Definition: complex:392
constexpr complex< _Tp > operator-(const complex< _Tp > &__x, const complex< _Tp > &__y)
Return new complex value x minus y.
Definition: complex:362
constexpr complex< _Tp > operator+(const complex< _Tp > &__x, const complex< _Tp > &__y)
Return new complex value x plus y.
Definition: complex:332
complex< _Tp > pow(const complex< _Tp > &, int)
Return x to the y'th power.
Definition: complex:1019
constexpr _Tp * __addressof(_Tp &__r) noexcept
Same as C++11 std::addressof.
Definition: move.h:49
constexpr _Bind_helper< __is_socketlike< _Func >::value, _Func, _BoundArgs... >::type bind(_Func &&__f, _BoundArgs &&... __args)
Function template for std::bind.
Definition: functional:870
ISO C++ entities toplevel namespace is std.
GNU extensions for public use.
Properties of fundamental types.
Definition: limits:313
Primary class template hash.
integral_constant
Definition: type_traits:63
The standard allocator, as per C++03 [20.4.1].
Definition: allocator.h:125
bool empty() const noexcept
Definition: cow_string.h:1026
const _CharT * c_str() const noexcept
Return const pointer to null-terminated contents.
Definition: cow_string.h:2206
Base class for all library exceptions.
Definition: exception.h:62
Uniform continuous distribution for random numbers.
Definition: random.h:1746
Struct holding two objects of arbitrary type.
Definition: stl_pair.h:187
_T1 first
The first member.
Definition: stl_pair.h:191
_T2 second
The second member.
Definition: stl_pair.h:192
A standard container made up of (key,value) pairs, which can be retrieved based on a key,...
Definition: stl_map.h:101
insert_return_type insert(node_type &&__nh)
Re-insert an extracted node.
Definition: stl_map.h:659
iterator end() noexcept
Definition: stl_map.h:384
iterator find(const key_type &__x)
Tries to locate an element in a map.
Definition: stl_map.h:1217
iterator erase(const_iterator __position)
Erases an element from a map.
Definition: stl_map.h:1079
iterator begin() noexcept
Definition: stl_map.h:366
Uniform interface to C++98 and C++11 allocators.
static constexpr pointer allocate(_Alloc &__a, size_type __n)
Allocate memory.
static constexpr size_type max_size(const _Alloc &__a) noexcept
The maximum supported allocation size.
Thrown by utilities for testing exception safety.
Base class for checking address and label information about allocations. Create a std::map between th...
Base struct for condition policy.
Base class for incremental control and throw.
Base class for random probability control and throw.
Class with exception generation control. Intended to be used as a value_type in templatized code.
Type throwing via limit condition.
Type throwing via random condition.
Allocator class with logging and exception generation control. Intended to be used as an allocator_ty...
Allocator throwing via limit condition.
Allocator throwing via random condition.