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
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:119
constexpr _Tp * __addressof(_Tp &__r) noexcept
Same as C++11 std::addressof.
Definition: move.h:52
constexpr _Bind_helper< __is_socketlike< _Func >::value, _Func, _BoundArgs... >::type bind(_Func &&__f, _BoundArgs &&... __args)
Function template for std::bind.
Definition: functional:976
mersenne_twister_engine< uint_fast32_t, 32, 624, 397, 31, 0x9908b0dfUL, 11, 0xffffffffUL, 7, 0x9d2c5680UL, 15, 0xefc60000UL, 18, 1812433253UL > mt19937
Definition: random.h:2311
ISO C++ entities toplevel namespace is std.
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:2493
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:107
insert_return_type insert(node_type &&__nh)
Re-insert an extracted node.
Definition: stl_map.h:729
iterator end() noexcept
Definition: stl_map.h:410
iterator find(const key_type &__x)
Tries to locate an element in a map.
Definition: stl_map.h:1412
iterator erase(const_iterator __position)
Erases an element from a map.
Definition: stl_map.h:1262
iterator begin() noexcept
Definition: stl_map.h:392
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.