libstdc++
throw_allocator.h
Go to the documentation of this file.
1 // -*- C++ -*-
2 
3 // Copyright (C) 2005-2024 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
ISO C++ entities toplevel namespace is std.
Base struct for condition policy.
Uniform continuous distribution for random numbers.
Definition: random.h:1881
_T2 second
The second member.
Definition: stl_pair.h:291
static constexpr pointer allocate(_Alloc &__a, size_type __n)
Allocate memory.
iterator find(const key_type &__x)
Tries to locate an element in a map.
Definition: stl_map.h:1218
constexpr complex< _Tp > operator-(const complex< _Tp > &__x, const complex< _Tp > &__y)
Return new complex value x minus y.
Definition: complex:370
iterator end() noexcept
Definition: stl_map.h:386
Uniform interface to C++98 and C++11 allocators.
Type throwing via random condition.
const _CharT * c_str() const noexcept
Return const pointer to null-terminated contents.
Definition: cow_string.h:2249
insert_return_type insert(node_type &&__nh)
Re-insert an extracted node.
Definition: stl_map.h:661
_T1 first
The first member.
Definition: stl_pair.h:290
constexpr _Bind_helper< __is_socketlike< _Func >::value, _Func, _BoundArgs... >::type bind(_Func &&__f, _BoundArgs &&... __args)
Function template for std::bind.
Definition: functional:888
Allocator throwing via limit condition.
Type throwing via limit condition.
Primary class template hash.
Definition: string_view:778
Thrown by utilities for testing exception safety.
Allocator throwing via random condition.
A standard container made up of (key,value) pairs, which can be retrieved based on a key...
Definition: stl_map.h:102
Struct holding two objects of arbitrary type.
GNU extensions for public use.
__bool_constant< true > true_type
The type used as a compile-time boolean with true value.
Definition: type_traits:111
constexpr complex< _Tp > operator+(const complex< _Tp > &__x, const complex< _Tp > &__y)
Return new complex value x plus y.
Definition: complex:340
constexpr auto size(const _Container &__cont) noexcept(noexcept(__cont.size())) -> decltype(__cont.size())
Return the size of a container.
Definition: range_access.h:262
constexpr complex< _Tp > operator*(const complex< _Tp > &__x, const complex< _Tp > &__y)
Return new complex value x times y.
Definition: complex:400
Base class for checking address and label information about allocations. Create a std::map between th...
Template class basic_ostream.
Definition: iosfwd:88
iterator begin() noexcept
Definition: stl_map.h:368
mersenne_twister_engine< uint_fast32_t, 32, 624, 397, 31, 0x9908b0dfUL, 11, 0xffffffffUL, 7, 0x9d2c5680UL, 15, 0xefc60000UL, 18, 1812433253UL > mt19937
Definition: random.h:1717
Base class for all library exceptions.
Definition: exception.h:59
complex< _Tp > pow(const complex< _Tp > &, int)
Return x to the y&#39;th power.
Definition: complex:1285
Base class for incremental control and throw.
_Tp * end(valarray< _Tp > &__va) noexcept
Return an iterator pointing to one past the last element of the valarray.
Definition: valarray:1249
Base class for random probability control and throw.
Properties of fundamental types.
Definition: limits:312
static constexpr size_type max_size(const _Alloc &__a) noexcept
The maximum supported allocation size.
bool empty() const noexcept
Definition: cow_string.h:1069
iterator erase(const_iterator __position)
Erases an element from a map.
Definition: stl_map.h:1080
Allocator class with logging and exception generation control. Intended to be used as an allocator_ty...
constexpr _Tp * __addressof(_Tp &__r) noexcept
Same as C++11 std::addressof.
Definition: move.h:51
Class with exception generation control. Intended to be used as a value_type in templatized code...