libstdc++
throw_allocator.h
Go to the documentation of this file.
1// -*- C++ -*-
2
3// Copyright (C) 2005-2023 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#ifdef _GLIBCXX_USE_C99_STDINT_TR1
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#endif // _GLIBCXX_USE_C99_STDINT_TR1
617
618 /**
619 * @brief Class with exception generation control. Intended to be
620 * used as a value_type in templatized code.
621 *
622 * Note: Destructor not allowed to throw.
623 */
624 template<typename _Cond>
625 struct throw_value_base : public _Cond
626 {
627 typedef _Cond condition_type;
628
629 using condition_type::throw_conditionally;
630
631 std::size_t _M_i;
632
633#ifndef _GLIBCXX_IS_AGGREGATE
634 throw_value_base() : _M_i(0)
635 { throw_conditionally(); }
636
637 throw_value_base(const throw_value_base& __v) : _M_i(__v._M_i)
638 { throw_conditionally(); }
639
640#if __cplusplus >= 201103L
641 // Shall not throw.
643#endif
644
645 explicit throw_value_base(const std::size_t __i) : _M_i(__i)
646 { throw_conditionally(); }
647#endif
648
650 operator=(const throw_value_base& __v)
651 {
652 throw_conditionally();
653 _M_i = __v._M_i;
654 return *this;
655 }
656
657#if __cplusplus >= 201103L
658 // Shall not throw.
660 operator=(throw_value_base&&) = default;
661#endif
662
664 operator++()
665 {
666 throw_conditionally();
667 ++_M_i;
668 return *this;
669 }
670 };
671
672 template<typename _Cond>
673 inline void
675 {
676 typedef throw_value_base<_Cond> throw_value;
677 throw_value::throw_conditionally();
678 throw_value orig(__a);
679 __a = __b;
680 __b = orig;
681 }
682
683 // General instantiable types requirements.
684 template<typename _Cond>
685 inline bool
686 operator==(const throw_value_base<_Cond>& __a,
687 const throw_value_base<_Cond>& __b)
688 {
689 typedef throw_value_base<_Cond> throw_value;
690 throw_value::throw_conditionally();
691 bool __ret = __a._M_i == __b._M_i;
692 return __ret;
693 }
694
695 template<typename _Cond>
696 inline bool
697 operator<(const throw_value_base<_Cond>& __a,
698 const throw_value_base<_Cond>& __b)
699 {
700 typedef throw_value_base<_Cond> throw_value;
701 throw_value::throw_conditionally();
702 bool __ret = __a._M_i < __b._M_i;
703 return __ret;
704 }
705
706 // Numeric algorithms instantiable types requirements.
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 template<typename _Cond>
719 inline throw_value_base<_Cond>
720 operator-(const throw_value_base<_Cond>& __a,
721 const throw_value_base<_Cond>& __b)
722 {
723 typedef throw_value_base<_Cond> throw_value;
724 throw_value::throw_conditionally();
725 throw_value __ret(__a._M_i - __b._M_i);
726 return __ret;
727 }
728
729 template<typename _Cond>
730 inline throw_value_base<_Cond>
731 operator*(const throw_value_base<_Cond>& __a,
732 const throw_value_base<_Cond>& __b)
733 {
734 typedef throw_value_base<_Cond> throw_value;
735 throw_value::throw_conditionally();
736 throw_value __ret(__a._M_i * __b._M_i);
737 return __ret;
738 }
739
740
741 /// Type throwing via limit condition.
742 struct throw_value_limit : public throw_value_base<limit_condition>
743 {
745
746#ifndef _GLIBCXX_IS_AGGREGATE
748
750 : base_type(__other._M_i) { }
751
752#if __cplusplus >= 201103L
754#endif
755
756 explicit throw_value_limit(const std::size_t __i) : base_type(__i) { }
757#endif
758
760 operator=(const throw_value_limit& __other)
761 {
762 base_type::operator=(__other);
763 return *this;
764 }
765
766#if __cplusplus >= 201103L
768 operator=(throw_value_limit&&) = default;
769#endif
770 };
771
772#ifdef _GLIBCXX_USE_C99_STDINT_TR1
773 /// Type throwing via random condition.
774 struct throw_value_random : public throw_value_base<random_condition>
775 {
777
778#ifndef _GLIBCXX_IS_AGGREGATE
780
782 : base_type(__other._M_i) { }
783
784#if __cplusplus >= 201103L
786#endif
787
788 explicit throw_value_random(const std::size_t __i) : base_type(__i) { }
789#endif
790
792 operator=(const throw_value_random& __other)
793 {
794 base_type::operator=(__other);
795 return *this;
796 }
797
798#if __cplusplus >= 201103L
800 operator=(throw_value_random&&) = default;
801#endif
802 };
803#endif // _GLIBCXX_USE_C99_STDINT_TR1
804
805 /**
806 * @brief Allocator class with logging and exception generation control.
807 * Intended to be used as an allocator_type in templatized code.
808 * @ingroup allocators
809 *
810 * Note: Deallocate not allowed to throw.
811 */
812 template<typename _Tp, typename _Cond>
814 : public annotate_base, public _Cond
815 {
816 public:
817 typedef std::size_t size_type;
818 typedef std::ptrdiff_t difference_type;
819 typedef _Tp value_type;
820 typedef value_type* pointer;
821 typedef const value_type* const_pointer;
822 typedef value_type& reference;
823 typedef const value_type& const_reference;
824
825#if __cplusplus >= 201103L
826 // _GLIBCXX_RESOLVE_LIB_DEFECTS
827 // 2103. std::allocator propagate_on_container_move_assignment
829#endif
830
831 private:
832 typedef _Cond condition_type;
833
834 std::allocator<value_type> _M_allocator;
835
837
838 using condition_type::throw_conditionally;
839
840 public:
841 size_type
842 max_size() const _GLIBCXX_USE_NOEXCEPT
843 { return traits::max_size(_M_allocator); }
844
845 pointer
846 address(reference __x) const _GLIBCXX_NOEXCEPT
847 { return std::__addressof(__x); }
848
849 const_pointer
850 address(const_reference __x) const _GLIBCXX_NOEXCEPT
851 { return std::__addressof(__x); }
852
853 _GLIBCXX_NODISCARD pointer
854 allocate(size_type __n, const void* __hint = 0)
855 {
856 if (__n > this->max_size())
857 std::__throw_bad_alloc();
858
859 throw_conditionally();
860 pointer const a = traits::allocate(_M_allocator, __n, __hint);
861 insert(a, sizeof(value_type) * __n);
862 return a;
863 }
864
865#if __cplusplus >= 201103L
866 template<typename _Up, typename... _Args>
867 void
868 construct(_Up* __p, _Args&&... __args)
869 {
870 traits::construct(_M_allocator, __p, std::forward<_Args>(__args)...);
871 insert_construct(__p);
872 }
873
874 template<typename _Up>
875 void
876 destroy(_Up* __p)
877 {
878 erase_construct(__p);
879 traits::destroy(_M_allocator, __p);
880 }
881#else
882 void
883 construct(pointer __p, const value_type& __val)
884 { return _M_allocator.construct(__p, __val); }
885
886 void
887 destroy(pointer __p)
888 { _M_allocator.destroy(__p); }
889#endif
890
891 void
892 deallocate(pointer __p, size_type __n)
893 {
894 erase(__p, sizeof(value_type) * __n);
895 _M_allocator.deallocate(__p, __n);
896 }
897
898 void
899 check_allocated(pointer __p, size_type __n)
900 {
901 size_type __t = sizeof(value_type) * __n;
902 annotate_base::check_allocated(__p, __t);
903 }
904
905 void
906 check(size_type __n)
907 { annotate_base::check(__n); }
908 };
909
910 template<typename _Tp, typename _Cond>
911 inline bool
912 operator==(const throw_allocator_base<_Tp, _Cond>&,
914 { return true; }
915
916#if __cpp_impl_three_way_comparison < 201907L
917 template<typename _Tp, typename _Cond>
918 inline bool
919 operator!=(const throw_allocator_base<_Tp, _Cond>&,
920 const throw_allocator_base<_Tp, _Cond>&)
921 { return false; }
922#endif
923
924 /// Allocator throwing via limit condition.
925 template<typename _Tp>
927 : public throw_allocator_base<_Tp, limit_condition>
928 {
929 template<typename _Tp1>
930 struct rebind
931 { typedef throw_allocator_limit<_Tp1> other; };
932
933 throw_allocator_limit() _GLIBCXX_USE_NOEXCEPT { }
934
936 _GLIBCXX_USE_NOEXCEPT { }
937
938 template<typename _Tp1>
940 _GLIBCXX_USE_NOEXCEPT { }
941
942 ~throw_allocator_limit() _GLIBCXX_USE_NOEXCEPT { }
943
944#if __cplusplus >= 201103L
946 operator=(const throw_allocator_limit&) = default;
947#endif
948 };
949
950#ifdef _GLIBCXX_USE_C99_STDINT_TR1
951 /// Allocator throwing via random condition.
952 template<typename _Tp>
954 : public throw_allocator_base<_Tp, random_condition>
955 {
956 template<typename _Tp1>
957 struct rebind
958 { typedef throw_allocator_random<_Tp1> other; };
959
960 throw_allocator_random() _GLIBCXX_USE_NOEXCEPT { }
961
963 _GLIBCXX_USE_NOEXCEPT { }
964
965 template<typename _Tp1>
967 _GLIBCXX_USE_NOEXCEPT { }
968
969 ~throw_allocator_random() _GLIBCXX_USE_NOEXCEPT { }
970
971#if __cplusplus >= 201103L
973 operator=(const throw_allocator_random&) = default;
974#endif
975 };
976#endif // _GLIBCXX_USE_C99_STDINT_TR1
977
978_GLIBCXX_END_NAMESPACE_VERSION
979} // namespace
980
981#if __cplusplus >= 201103L
982
983# include <bits/functional_hash.h>
984
985namespace std _GLIBCXX_VISIBILITY(default)
986{
987#pragma GCC diagnostic push
988#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
989
990 /// Explicit specialization of std::hash for __gnu_cxx::throw_value_limit.
991 template<>
992 struct hash<__gnu_cxx::throw_value_limit>
993 : public std::unary_function<__gnu_cxx::throw_value_limit, size_t>
994 {
995 size_t
996 operator()(const __gnu_cxx::throw_value_limit& __val) const
997 {
998 __gnu_cxx::throw_value_limit::throw_conditionally();
1000 size_t __result = __h(__val._M_i);
1001 return __result;
1002 }
1003 };
1004
1005#ifdef _GLIBCXX_USE_C99_STDINT_TR1
1006 /// Explicit specialization of std::hash for __gnu_cxx::throw_value_random.
1007 template<>
1008 struct hash<__gnu_cxx::throw_value_random>
1009 : public std::unary_function<__gnu_cxx::throw_value_random, size_t>
1010 {
1011 size_t
1012 operator()(const __gnu_cxx::throw_value_random& __val) const
1013 {
1014 __gnu_cxx::throw_value_random::throw_conditionally();
1016 size_t __result = __h(__val._M_i);
1017 return __result;
1018 }
1019 };
1020#endif
1021
1022#pragma GCC diagnostic pop
1023} // end namespace std
1024#endif
1025
1026#endif
constexpr complex< _Tp > operator*(const complex< _Tp > &__x, const complex< _Tp > &__y)
Return new complex value x times y.
Definition: complex:395
constexpr complex< _Tp > operator-(const complex< _Tp > &__x, const complex< _Tp > &__y)
Return new complex value x minus y.
Definition: complex:365
constexpr complex< _Tp > operator+(const complex< _Tp > &__x, const complex< _Tp > &__y)
Return new complex value x plus y.
Definition: complex:335
complex< _Tp > pow(const complex< _Tp > &, int)
Return x to the y'th power.
Definition: complex:1280
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:881
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:131
bool empty() const noexcept
Definition: cow_string.h:1033
const _CharT * c_str() const noexcept
Return const pointer to null-terminated contents.
Definition: cow_string.h:2213
Base class for all library exceptions.
Definition: exception.h:60
Uniform continuous distribution for random numbers.
Definition: random.h:1756
Struct holding two objects of arbitrary type.
Definition: stl_pair.h:189
_T1 first
The first member.
Definition: stl_pair.h:193
_T2 second
The second member.
Definition: stl_pair.h:194
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.