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