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