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