libstdc++
throw_allocator.h
Go to the documentation of this file.
1 // -*- C++ -*-
2 
3 // Copyright (C) 2005-2025 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 
73 namespace __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  */
81  struct forced_error : public std::exception
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:
108  annotate_base()
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 
312  entry_type
313  make_entry(void* p, size_t size)
314  { return std::make_pair(p, data_type(get_label(), size)); }
315 
316  static void
317  log_to_string(std::string& s, const_reference ref)
318  {
319 #if ! __has_builtin(__builtin_sprintf)
320  __typeof__(&std::sprintf) __builtin_sprintf = &std::sprintf;
321 #endif
322 
323  char buf[40];
324  const char tab('\t');
325  s += "label: ";
326  unsigned long l = static_cast<unsigned long>(ref.second.first);
327  __builtin_sprintf(buf, "%lu", l);
328  s += buf;
329  s += tab;
330  s += "size: ";
331  l = static_cast<unsigned long>(ref.second.second);
332  __builtin_sprintf(buf, "%lu", l);
333  s += buf;
334  s += tab;
335  s += "address: ";
336  __builtin_sprintf(buf, "%p", ref.first);
337  s += buf;
338  s += '\n';
339  }
340 
341 #if __cplusplus >= 201103L
342  static void
343  log_to_string(std::string& s, const std::pair<const void*, size_t>& ref)
344  {
345 #if ! __has_builtin(__builtin_sprintf)
346  auto __builtin_sprintf = &std::sprintf;
347 #endif
348 
349  char buf[40];
350  const char tab('\t');
351  s += "label: ";
352  unsigned long l = static_cast<unsigned long>(ref.second);
353  __builtin_sprintf(buf, "%lu", l);
354  s += buf;
355  s += tab;
356  s += "address: ";
357  __builtin_sprintf(buf, "%p", ref.first);
358  s += buf;
359  s += '\n';
360  }
361 #endif
362 
363  static size_t&
364  label()
365  {
366  static size_t _S_label(std::numeric_limits<size_t>::max());
367  return _S_label;
368  }
369 
370  static map_alloc_type&
371  map_alloc()
372  {
373  static map_alloc_type _S_map;
374  return _S_map;
375  }
376 
377 #if __cplusplus >= 201103L
378  static map_construct_type&
379  map_construct()
380  {
381  static map_construct_type _S_map;
382  return _S_map;
383  }
384 #endif
385  };
386 
387  inline std::ostream&
388  operator<<(std::ostream& os, const annotate_base& __b)
389  {
390  std::string error;
391  typedef annotate_base base_type;
392  {
393  base_type::const_iterator beg = __b.map_alloc().begin();
394  base_type::const_iterator end = __b.map_alloc().end();
395  for (; beg != end; ++beg)
396  __b.log_to_string(error, *beg);
397  }
398 #if __cplusplus >= 201103L
399  {
400  auto beg = __b.map_construct().begin();
401  auto end = __b.map_construct().end();
402  for (; beg != end; ++beg)
403  __b.log_to_string(error, *beg);
404  }
405 #endif
406  return os << error;
407  }
408 
409 
410  /**
411  * @brief Base struct for condition policy.
412  *
413  * Requires a public member function with the signature
414  * void throw_conditionally()
415  */
417  {
418 #if __cplusplus >= 201103L
419  condition_base() = default;
420  condition_base(const condition_base&) = default;
421  condition_base& operator=(const condition_base&) = default;
422 #endif
423  virtual ~condition_base() { };
424  };
425 
426 
427  /**
428  * @brief Base class for incremental control and throw.
429  */
431  {
432  // Scope-level adjustor objects: set limit for throw at the
433  // beginning of a scope block, and restores to previous limit when
434  // object is destroyed on exiting the block.
435  struct adjustor_base
436  {
437  private:
438  const size_t _M_orig;
439 
440  public:
441  adjustor_base() : _M_orig(limit()) { }
442 
443  virtual
444  ~adjustor_base() { set_limit(_M_orig); }
445  };
446 
447  /// Never enter the condition.
448  struct never_adjustor : public adjustor_base
449  {
451  };
452 
453  /// Always enter the condition.
454  struct always_adjustor : public adjustor_base
455  {
456  always_adjustor() { set_limit(count()); }
457  };
458 
459  /// Enter the nth condition.
460  struct limit_adjustor : public adjustor_base
461  {
462  limit_adjustor(const size_t __l) { set_limit(__l); }
463  };
464 
465  // Increment _S_count every time called.
466  // If _S_count matches the limit count, throw.
467  static void
468  throw_conditionally()
469  {
470  if (count() == limit())
471  __throw_forced_error();
472  ++count();
473  }
474 
475  static size_t&
476  count()
477  {
478  static size_t _S_count(0);
479  return _S_count;
480  }
481 
482  static size_t&
483  limit()
484  {
485  static size_t _S_limit(std::numeric_limits<size_t>::max());
486  return _S_limit;
487  }
488 
489  // Zero the throw counter, set limit to argument.
490  static void
491  set_limit(const size_t __l)
492  {
493  limit() = __l;
494  count() = 0;
495  }
496  };
497 
498  /**
499  * @brief Base class for random probability control and throw.
500  */
502  {
503  // Scope-level adjustor objects: set probability for throw at the
504  // beginning of a scope block, and restores to previous
505  // probability when object is destroyed on exiting the block.
506  struct adjustor_base
507  {
508  private:
509  const double _M_orig;
510 
511  public:
512  adjustor_base() : _M_orig(probability()) { }
513 
514  virtual ~adjustor_base()
515  { set_probability(_M_orig); }
516  };
517 
518  /// Group condition.
519  struct group_adjustor : public adjustor_base
520  {
521  group_adjustor(size_t size)
522  { set_probability(1 - std::pow(double(1 - probability()),
523  double(0.5 / (size + 1))));
524  }
525  };
526 
527  /// Never enter the condition.
528  struct never_adjustor : public adjustor_base
529  {
530  never_adjustor() { set_probability(0); }
531  };
532 
533  /// Always enter the condition.
534  struct always_adjustor : public adjustor_base
535  {
536  always_adjustor() { set_probability(1); }
537  };
538 
540  {
541  probability();
542  engine();
543  }
544 
545  static void
546  set_probability(double __p)
547  { probability() = __p; }
548 
549  static void
550  throw_conditionally()
551  {
552  if (generate() < probability())
553  __throw_forced_error();
554  }
555 
556  void
557  seed(unsigned long __s)
558  { engine().seed(__s); }
559 
560  private:
561 #if __cplusplus >= 201103L
562  typedef std::uniform_real_distribution<double> distribution_type;
563  typedef std::mt19937 engine_type;
564 #else
565  typedef std::tr1::uniform_real<double> distribution_type;
566  typedef std::tr1::mt19937 engine_type;
567 #endif
568 
569  static double
570  generate()
571  {
572 #if __cplusplus >= 201103L
573  const distribution_type distribution(0, 1);
574  static auto generator = std::bind(distribution, engine());
575 #else
576  // Use variate_generator to get normalized results.
577  typedef std::tr1::variate_generator<engine_type, distribution_type> gen_t;
578  distribution_type distribution(0, 1);
579  static gen_t generator(engine(), distribution);
580 #endif
581 
582 #if ! __has_builtin(__builtin_sprintf)
583  __typeof__(&std::sprintf) __builtin_sprintf = &std::sprintf;
584 #endif
585 
586  double random = generator();
587  if (random < distribution.min() || random > distribution.max())
588  {
589  std::string __s("random_condition::generate");
590  __s += "\n";
591  __s += "random number generated is: ";
592  char buf[40];
593  __builtin_sprintf(buf, "%f", random);
594  __s += buf;
595  std::__throw_out_of_range(__s.c_str());
596  }
597 
598  return random;
599  }
600 
601  static double&
602  probability()
603  {
604  static double _S_p;
605  return _S_p;
606  }
607 
608  static engine_type&
609  engine()
610  {
611  static engine_type _S_e;
612  return _S_e;
613  }
614  };
615 
616  /**
617  * @brief Class with exception generation control. Intended to be
618  * used as a value_type in templatized code.
619  *
620  * Note: Destructor not allowed to throw.
621  */
622  template<typename _Cond>
623  struct throw_value_base : public _Cond
624  {
625  typedef _Cond condition_type;
626 
627  using condition_type::throw_conditionally;
628 
629  std::size_t _M_i;
630 
631 #ifndef _GLIBCXX_IS_AGGREGATE
632  throw_value_base() : _M_i(0)
633  { throw_conditionally(); }
634 
635  throw_value_base(const throw_value_base& __v) : _M_i(__v._M_i)
636  { throw_conditionally(); }
637 
638 #if __cplusplus >= 201103L
639  // Shall not throw.
640  throw_value_base(throw_value_base&&) = default;
641 #endif
642 
643  explicit throw_value_base(const std::size_t __i) : _M_i(__i)
644  { throw_conditionally(); }
645 #endif
646 
648  operator=(const throw_value_base& __v)
649  {
650  throw_conditionally();
651  _M_i = __v._M_i;
652  return *this;
653  }
654 
655 #if __cplusplus >= 201103L
656  // Shall not throw.
658  operator=(throw_value_base&&) = default;
659 #endif
660 
662  operator++()
663  {
664  throw_conditionally();
665  ++_M_i;
666  return *this;
667  }
668  };
669 
670  template<typename _Cond>
671  inline void
673  {
674  typedef throw_value_base<_Cond> throw_value;
675  throw_value::throw_conditionally();
676  throw_value orig(__a);
677  __a = __b;
678  __b = orig;
679  }
680 
681  // General instantiable types requirements.
682  template<typename _Cond>
683  inline bool
684  operator==(const throw_value_base<_Cond>& __a,
685  const throw_value_base<_Cond>& __b)
686  {
687  typedef throw_value_base<_Cond> throw_value;
688  throw_value::throw_conditionally();
689  bool __ret = __a._M_i == __b._M_i;
690  return __ret;
691  }
692 
693  template<typename _Cond>
694  inline bool
695  operator<(const throw_value_base<_Cond>& __a,
696  const throw_value_base<_Cond>& __b)
697  {
698  typedef throw_value_base<_Cond> throw_value;
699  throw_value::throw_conditionally();
700  bool __ret = __a._M_i < __b._M_i;
701  return __ret;
702  }
703 
704  // Numeric algorithms instantiable types requirements.
705  template<typename _Cond>
706  inline throw_value_base<_Cond>
707  operator+(const throw_value_base<_Cond>& __a,
708  const throw_value_base<_Cond>& __b)
709  {
710  typedef throw_value_base<_Cond> throw_value;
711  throw_value::throw_conditionally();
712  throw_value __ret(__a._M_i + __b._M_i);
713  return __ret;
714  }
715 
716  template<typename _Cond>
717  inline throw_value_base<_Cond>
718  operator-(const throw_value_base<_Cond>& __a,
719  const throw_value_base<_Cond>& __b)
720  {
721  typedef throw_value_base<_Cond> throw_value;
722  throw_value::throw_conditionally();
723  throw_value __ret(__a._M_i - __b._M_i);
724  return __ret;
725  }
726 
727  template<typename _Cond>
728  inline throw_value_base<_Cond>
729  operator*(const throw_value_base<_Cond>& __a,
730  const throw_value_base<_Cond>& __b)
731  {
732  typedef throw_value_base<_Cond> throw_value;
733  throw_value::throw_conditionally();
734  throw_value __ret(__a._M_i * __b._M_i);
735  return __ret;
736  }
737 
738 
739  /// Type throwing via limit condition.
740  struct throw_value_limit : public throw_value_base<limit_condition>
741  {
743 
744 #ifndef _GLIBCXX_IS_AGGREGATE
745  throw_value_limit() { }
746 
747  throw_value_limit(const throw_value_limit& __other)
748  : base_type(__other._M_i) { }
749 
750 #if __cplusplus >= 201103L
752 #endif
753 
754  explicit throw_value_limit(const std::size_t __i) : base_type(__i) { }
755 #endif
756 
758  operator=(const throw_value_limit& __other)
759  {
760  base_type::operator=(__other);
761  return *this;
762  }
763 
764 #if __cplusplus >= 201103L
766  operator=(throw_value_limit&&) = default;
767 #endif
768  };
769 
770  /// Type throwing via random condition.
771  struct throw_value_random : public throw_value_base<random_condition>
772  {
774 
775 #ifndef _GLIBCXX_IS_AGGREGATE
776  throw_value_random() { }
777 
778  throw_value_random(const throw_value_random& __other)
779  : base_type(__other._M_i) { }
780 
781 #if __cplusplus >= 201103L
783 #endif
784 
785  explicit throw_value_random(const std::size_t __i) : base_type(__i) { }
786 #endif
787 
789  operator=(const throw_value_random& __other)
790  {
791  base_type::operator=(__other);
792  return *this;
793  }
794 
795 #if __cplusplus >= 201103L
797  operator=(throw_value_random&&) = default;
798 #endif
799  };
800 
801  /**
802  * @brief Allocator class with logging and exception generation control.
803  * Intended to be used as an allocator_type in templatized code.
804  * @ingroup allocators
805  *
806  * Note: Deallocate not allowed to throw.
807  */
808  template<typename _Tp, typename _Cond>
810  : public annotate_base, public _Cond
811  {
812  public:
813  typedef std::size_t size_type;
814  typedef std::ptrdiff_t difference_type;
815  typedef _Tp value_type;
816  typedef value_type* pointer;
817  typedef const value_type* const_pointer;
818  typedef value_type& reference;
819  typedef const value_type& const_reference;
820 
821 #if __cplusplus >= 201103L
822  // _GLIBCXX_RESOLVE_LIB_DEFECTS
823  // 2103. std::allocator propagate_on_container_move_assignment
824  typedef std::true_type propagate_on_container_move_assignment;
825 #endif
826 
827  private:
828  typedef _Cond condition_type;
829 
830  std::allocator<value_type> _M_allocator;
831 
833 
834  using condition_type::throw_conditionally;
835 
836  public:
837  size_type
838  max_size() const _GLIBCXX_USE_NOEXCEPT
839  { return traits::max_size(_M_allocator); }
840 
841  pointer
842  address(reference __x) const _GLIBCXX_NOEXCEPT
843  { return std::__addressof(__x); }
844 
845  const_pointer
846  address(const_reference __x) const _GLIBCXX_NOEXCEPT
847  { return std::__addressof(__x); }
848 
849  _GLIBCXX_NODISCARD pointer
850  allocate(size_type __n, const void* __hint = 0)
851  {
852  if (__n > this->max_size())
853  std::__throw_bad_alloc();
854 
855  throw_conditionally();
856  pointer const a = traits::allocate(_M_allocator, __n, __hint);
857  insert(a, sizeof(value_type) * __n);
858  return a;
859  }
860 
861 #if __cplusplus >= 201103L
862  template<typename _Up, typename... _Args>
863  void
864  construct(_Up* __p, _Args&&... __args)
865  {
866  traits::construct(_M_allocator, __p, std::forward<_Args>(__args)...);
867  insert_construct(__p);
868  }
869 
870  template<typename _Up>
871  void
872  destroy(_Up* __p)
873  {
874  erase_construct(__p);
875  traits::destroy(_M_allocator, __p);
876  }
877 #else
878  void
879  construct(pointer __p, const value_type& __val)
880  { return _M_allocator.construct(__p, __val); }
881 
882  void
883  destroy(pointer __p)
884  { _M_allocator.destroy(__p); }
885 #endif
886 
887  void
888  deallocate(pointer __p, size_type __n)
889  {
890  erase(__p, sizeof(value_type) * __n);
891  _M_allocator.deallocate(__p, __n);
892  }
893 
894  void
895  check_allocated(pointer __p, size_type __n)
896  {
897  size_type __t = sizeof(value_type) * __n;
898  annotate_base::check_allocated(__p, __t);
899  }
900 
901  void
902  check(size_type __n)
903  { annotate_base::check(__n); }
904  };
905 
906  template<typename _Tp, typename _Cond>
907  inline bool
908  operator==(const throw_allocator_base<_Tp, _Cond>&,
910  { return true; }
911 
912 #if __cpp_impl_three_way_comparison < 201907L
913  template<typename _Tp, typename _Cond>
914  inline bool
915  operator!=(const throw_allocator_base<_Tp, _Cond>&,
916  const throw_allocator_base<_Tp, _Cond>&)
917  { return false; }
918 #endif
919 
920  /// Allocator throwing via limit condition.
921  template<typename _Tp>
923  : public throw_allocator_base<_Tp, limit_condition>
924  {
925  template<typename _Tp1>
926  struct rebind
927  { typedef throw_allocator_limit<_Tp1> other; };
928 
929  throw_allocator_limit() _GLIBCXX_USE_NOEXCEPT { }
930 
932  _GLIBCXX_USE_NOEXCEPT { }
933 
934  template<typename _Tp1>
936  _GLIBCXX_USE_NOEXCEPT { }
937 
938  ~throw_allocator_limit() _GLIBCXX_USE_NOEXCEPT { }
939 
940 #if __cplusplus >= 201103L
942  operator=(const throw_allocator_limit&) = default;
943 #endif
944  };
945 
946  /// Allocator throwing via random condition.
947  template<typename _Tp>
949  : public throw_allocator_base<_Tp, random_condition>
950  {
951  template<typename _Tp1>
952  struct rebind
953  { typedef throw_allocator_random<_Tp1> other; };
954 
955  throw_allocator_random() _GLIBCXX_USE_NOEXCEPT { }
956 
958  _GLIBCXX_USE_NOEXCEPT { }
959 
960  template<typename _Tp1>
962  _GLIBCXX_USE_NOEXCEPT { }
963 
964  ~throw_allocator_random() _GLIBCXX_USE_NOEXCEPT { }
965 
966 #if __cplusplus >= 201103L
968  operator=(const throw_allocator_random&) = default;
969 #endif
970  };
971 
972 _GLIBCXX_END_NAMESPACE_VERSION
973 } // namespace
974 
975 #if __cplusplus >= 201103L
976 
977 # include <bits/functional_hash.h>
978 
979 namespace std _GLIBCXX_VISIBILITY(default)
980 {
981 #pragma GCC diagnostic push
982 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
983 
984  /// Explicit specialization of std::hash for __gnu_cxx::throw_value_limit.
985  template<>
986  struct hash<__gnu_cxx::throw_value_limit>
987  : public std::unary_function<__gnu_cxx::throw_value_limit, size_t>
988  {
989  size_t
990  operator()(const __gnu_cxx::throw_value_limit& __val) const
991  {
992  __gnu_cxx::throw_value_limit::throw_conditionally();
994  size_t __result = __h(__val._M_i);
995  return __result;
996  }
997  };
998 
999  /// Explicit specialization of std::hash for __gnu_cxx::throw_value_random.
1000  template<>
1001  struct hash<__gnu_cxx::throw_value_random>
1002  : public std::unary_function<__gnu_cxx::throw_value_random, size_t>
1003  {
1004  size_t
1005  operator()(const __gnu_cxx::throw_value_random& __val) const
1006  {
1007  __gnu_cxx::throw_value_random::throw_conditionally();
1009  size_t __result = __h(__val._M_i);
1010  return __result;
1011  }
1012  };
1013 
1014 #pragma GCC diagnostic pop
1015 } // end namespace std
1016 #endif
1017 
1018 #endif
constexpr bool operator<(const duration< _Rep1, _Period1 > &__lhs, const duration< _Rep2, _Period2 > &__rhs)
Definition: chrono.h:826
constexpr complex< _Tp > operator*(const complex< _Tp > &__x, const complex< _Tp > &__y)
Return new complex value x times y.
Definition: complex:434
complex< _Tp > pow(const complex< _Tp > &, int)
Return x to the y'th power.
Definition: complex:1357
constexpr complex< _Tp > operator-(const complex< _Tp > &__x, const complex< _Tp > &__y)
Return new complex value x minus y.
Definition: complex:404
constexpr complex< _Tp > operator+(const complex< _Tp > &__x, const complex< _Tp > &__y)
Return new complex value x plus y.
Definition: complex:374
__bool_constant< true > true_type
The type used as a compile-time boolean with true value.
Definition: type_traits:116
constexpr _Tp * __addressof(_Tp &__r) noexcept
Same as C++11 std::addressof.
Definition: move.h:52
_Tp * end(valarray< _Tp > &__va) noexcept
Return an iterator pointing to one past the last element of the valarray.
Definition: valarray:1251
constexpr _Bind_helper< __is_socketlike< _Func >::value, _Func, _BoundArgs... >::type bind(_Func &&__f, _BoundArgs &&... __args)
Function template for std::bind.
Definition: functional:890
mersenne_twister_engine< uint_fast32_t, 32, 624, 397, 31, 0x9908b0dfUL, 11, 0xffffffffUL, 7, 0x9d2c5680UL, 15, 0xefc60000UL, 18, 1812433253UL > mt19937
Definition: random.h:1717
ISO C++ entities toplevel namespace is std.
constexpr auto size(const _Container &__cont) noexcept(noexcept(__cont.size())) -> decltype(__cont.size())
Return the size of a container.
Definition: range_access.h:274
GNU extensions for public use.
Properties of fundamental types.
Definition: limits:320
Primary class template hash.
const _CharT * c_str() const noexcept
Return const pointer to null-terminated contents.
Definition: cow_string.h:2376
bool empty() const noexcept
Definition: cow_string.h:1116
Base class for all library exceptions.
Definition: exception.h:62
Uniform continuous distribution for random numbers.
Definition: random.h:1882
Struct holding two objects of arbitrary type.
Definition: stl_pair.h:304
_T1 first
The first member.
Definition: stl_pair.h:308
_T2 second
The second member.
Definition: stl_pair.h:309
A standard container made up of (key,value) pairs, which can be retrieved based on a key,...
Definition: stl_map.h:106
insert_return_type insert(node_type &&__nh)
Re-insert an extracted node.
Definition: stl_map.h:684
iterator end() noexcept
Definition: stl_map.h:409
iterator find(const key_type &__x)
Tries to locate an element in a map.
Definition: stl_map.h:1259
iterator erase(const_iterator __position)
Erases an element from a map.
Definition: stl_map.h:1121
iterator begin() noexcept
Definition: stl_map.h:391
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.