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