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