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