libstdc++
throw_allocator.h
Go to the documentation of this file.
1 // -*- C++ -*-
2 
3 // Copyright (C) 2005-2023 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 #ifdef _GLIBCXX_USE_C99_STDINT_TR1
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 #endif // _GLIBCXX_USE_C99_STDINT_TR1
617 
618  /**
619  * @brief Class with exception generation control. Intended to be
620  * used as a value_type in templatized code.
621  *
622  * Note: Destructor not allowed to throw.
623  */
624  template<typename _Cond>
625  struct throw_value_base : public _Cond
626  {
627  typedef _Cond condition_type;
628 
629  using condition_type::throw_conditionally;
630 
631  std::size_t _M_i;
632 
633 #ifndef _GLIBCXX_IS_AGGREGATE
634  throw_value_base() : _M_i(0)
635  { throw_conditionally(); }
636 
637  throw_value_base(const throw_value_base& __v) : _M_i(__v._M_i)
638  { throw_conditionally(); }
639 
640 #if __cplusplus >= 201103L
641  // Shall not throw.
642  throw_value_base(throw_value_base&&) = default;
643 #endif
644 
645  explicit throw_value_base(const std::size_t __i) : _M_i(__i)
646  { throw_conditionally(); }
647 #endif
648 
650  operator=(const throw_value_base& __v)
651  {
652  throw_conditionally();
653  _M_i = __v._M_i;
654  return *this;
655  }
656 
657 #if __cplusplus >= 201103L
658  // Shall not throw.
660  operator=(throw_value_base&&) = default;
661 #endif
662 
664  operator++()
665  {
666  throw_conditionally();
667  ++_M_i;
668  return *this;
669  }
670  };
671 
672  template<typename _Cond>
673  inline void
675  {
676  typedef throw_value_base<_Cond> throw_value;
677  throw_value::throw_conditionally();
678  throw_value orig(__a);
679  __a = __b;
680  __b = orig;
681  }
682 
683  // General instantiable types requirements.
684  template<typename _Cond>
685  inline bool
686  operator==(const throw_value_base<_Cond>& __a,
687  const throw_value_base<_Cond>& __b)
688  {
689  typedef throw_value_base<_Cond> throw_value;
690  throw_value::throw_conditionally();
691  bool __ret = __a._M_i == __b._M_i;
692  return __ret;
693  }
694 
695  template<typename _Cond>
696  inline bool
697  operator<(const throw_value_base<_Cond>& __a,
698  const throw_value_base<_Cond>& __b)
699  {
700  typedef throw_value_base<_Cond> throw_value;
701  throw_value::throw_conditionally();
702  bool __ret = __a._M_i < __b._M_i;
703  return __ret;
704  }
705 
706  // Numeric algorithms instantiable types requirements.
707  template<typename _Cond>
708  inline throw_value_base<_Cond>
709  operator+(const throw_value_base<_Cond>& __a,
710  const throw_value_base<_Cond>& __b)
711  {
712  typedef throw_value_base<_Cond> throw_value;
713  throw_value::throw_conditionally();
714  throw_value __ret(__a._M_i + __b._M_i);
715  return __ret;
716  }
717 
718  template<typename _Cond>
719  inline throw_value_base<_Cond>
720  operator-(const throw_value_base<_Cond>& __a,
721  const throw_value_base<_Cond>& __b)
722  {
723  typedef throw_value_base<_Cond> throw_value;
724  throw_value::throw_conditionally();
725  throw_value __ret(__a._M_i - __b._M_i);
726  return __ret;
727  }
728 
729  template<typename _Cond>
730  inline throw_value_base<_Cond>
731  operator*(const throw_value_base<_Cond>& __a,
732  const throw_value_base<_Cond>& __b)
733  {
734  typedef throw_value_base<_Cond> throw_value;
735  throw_value::throw_conditionally();
736  throw_value __ret(__a._M_i * __b._M_i);
737  return __ret;
738  }
739 
740 
741  /// Type throwing via limit condition.
742  struct throw_value_limit : public throw_value_base<limit_condition>
743  {
745 
746 #ifndef _GLIBCXX_IS_AGGREGATE
747  throw_value_limit() { }
748 
749  throw_value_limit(const throw_value_limit& __other)
750  : base_type(__other._M_i) { }
751 
752 #if __cplusplus >= 201103L
754 #endif
755 
756  explicit throw_value_limit(const std::size_t __i) : base_type(__i) { }
757 #endif
758 
760  operator=(const throw_value_limit& __other)
761  {
762  base_type::operator=(__other);
763  return *this;
764  }
765 
766 #if __cplusplus >= 201103L
768  operator=(throw_value_limit&&) = default;
769 #endif
770  };
771 
772 #ifdef _GLIBCXX_USE_C99_STDINT_TR1
773  /// Type throwing via random condition.
774  struct throw_value_random : public throw_value_base<random_condition>
775  {
777 
778 #ifndef _GLIBCXX_IS_AGGREGATE
779  throw_value_random() { }
780 
781  throw_value_random(const throw_value_random& __other)
782  : base_type(__other._M_i) { }
783 
784 #if __cplusplus >= 201103L
786 #endif
787 
788  explicit throw_value_random(const std::size_t __i) : base_type(__i) { }
789 #endif
790 
792  operator=(const throw_value_random& __other)
793  {
794  base_type::operator=(__other);
795  return *this;
796  }
797 
798 #if __cplusplus >= 201103L
800  operator=(throw_value_random&&) = default;
801 #endif
802  };
803 #endif // _GLIBCXX_USE_C99_STDINT_TR1
804 
805  /**
806  * @brief Allocator class with logging and exception generation control.
807  * Intended to be used as an allocator_type in templatized code.
808  * @ingroup allocators
809  *
810  * Note: Deallocate not allowed to throw.
811  */
812  template<typename _Tp, typename _Cond>
814  : public annotate_base, public _Cond
815  {
816  public:
817  typedef std::size_t size_type;
818  typedef std::ptrdiff_t difference_type;
819  typedef _Tp value_type;
820  typedef value_type* pointer;
821  typedef const value_type* const_pointer;
822  typedef value_type& reference;
823  typedef const value_type& const_reference;
824 
825 #if __cplusplus >= 201103L
826  // _GLIBCXX_RESOLVE_LIB_DEFECTS
827  // 2103. std::allocator propagate_on_container_move_assignment
829 #endif
830 
831  private:
832  typedef _Cond condition_type;
833 
834  std::allocator<value_type> _M_allocator;
835 
837 
838  using condition_type::throw_conditionally;
839 
840  public:
841  size_type
842  max_size() const _GLIBCXX_USE_NOEXCEPT
843  { return traits::max_size(_M_allocator); }
844 
845  pointer
846  address(reference __x) const _GLIBCXX_NOEXCEPT
847  { return std::__addressof(__x); }
848 
849  const_pointer
850  address(const_reference __x) const _GLIBCXX_NOEXCEPT
851  { return std::__addressof(__x); }
852 
853  _GLIBCXX_NODISCARD pointer
854  allocate(size_type __n, const void* __hint = 0)
855  {
856  if (__n > this->max_size())
857  std::__throw_bad_alloc();
858 
859  throw_conditionally();
860  pointer const a = traits::allocate(_M_allocator, __n, __hint);
861  insert(a, sizeof(value_type) * __n);
862  return a;
863  }
864 
865 #if __cplusplus >= 201103L
866  template<typename _Up, typename... _Args>
867  void
868  construct(_Up* __p, _Args&&... __args)
869  {
870  traits::construct(_M_allocator, __p, std::forward<_Args>(__args)...);
871  insert_construct(__p);
872  }
873 
874  template<typename _Up>
875  void
876  destroy(_Up* __p)
877  {
878  erase_construct(__p);
879  traits::destroy(_M_allocator, __p);
880  }
881 #else
882  void
883  construct(pointer __p, const value_type& __val)
884  { return _M_allocator.construct(__p, __val); }
885 
886  void
887  destroy(pointer __p)
888  { _M_allocator.destroy(__p); }
889 #endif
890 
891  void
892  deallocate(pointer __p, size_type __n)
893  {
894  erase(__p, sizeof(value_type) * __n);
895  _M_allocator.deallocate(__p, __n);
896  }
897 
898  void
899  check_allocated(pointer __p, size_type __n)
900  {
901  size_type __t = sizeof(value_type) * __n;
902  annotate_base::check_allocated(__p, __t);
903  }
904 
905  void
906  check(size_type __n)
907  { annotate_base::check(__n); }
908  };
909 
910  template<typename _Tp, typename _Cond>
911  inline bool
912  operator==(const throw_allocator_base<_Tp, _Cond>&,
914  { return true; }
915 
916 #if __cpp_impl_three_way_comparison < 201907L
917  template<typename _Tp, typename _Cond>
918  inline bool
919  operator!=(const throw_allocator_base<_Tp, _Cond>&,
920  const throw_allocator_base<_Tp, _Cond>&)
921  { return false; }
922 #endif
923 
924  /// Allocator throwing via limit condition.
925  template<typename _Tp>
927  : public throw_allocator_base<_Tp, limit_condition>
928  {
929  template<typename _Tp1>
930  struct rebind
931  { typedef throw_allocator_limit<_Tp1> other; };
932 
933  throw_allocator_limit() _GLIBCXX_USE_NOEXCEPT { }
934 
936  _GLIBCXX_USE_NOEXCEPT { }
937 
938  template<typename _Tp1>
940  _GLIBCXX_USE_NOEXCEPT { }
941 
942  ~throw_allocator_limit() _GLIBCXX_USE_NOEXCEPT { }
943 
944 #if __cplusplus >= 201103L
946  operator=(const throw_allocator_limit&) = default;
947 #endif
948  };
949 
950 #ifdef _GLIBCXX_USE_C99_STDINT_TR1
951  /// Allocator throwing via random condition.
952  template<typename _Tp>
954  : public throw_allocator_base<_Tp, random_condition>
955  {
956  template<typename _Tp1>
957  struct rebind
958  { typedef throw_allocator_random<_Tp1> other; };
959 
960  throw_allocator_random() _GLIBCXX_USE_NOEXCEPT { }
961 
963  _GLIBCXX_USE_NOEXCEPT { }
964 
965  template<typename _Tp1>
967  _GLIBCXX_USE_NOEXCEPT { }
968 
969  ~throw_allocator_random() _GLIBCXX_USE_NOEXCEPT { }
970 
971 #if __cplusplus >= 201103L
973  operator=(const throw_allocator_random&) = default;
974 #endif
975  };
976 #endif // _GLIBCXX_USE_C99_STDINT_TR1
977 
978 _GLIBCXX_END_NAMESPACE_VERSION
979 } // namespace
980 
981 #if __cplusplus >= 201103L
982 
983 # include <bits/functional_hash.h>
984 
985 namespace std _GLIBCXX_VISIBILITY(default)
986 {
987 #pragma GCC diagnostic push
988 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
989 
990  /// Explicit specialization of std::hash for __gnu_cxx::throw_value_limit.
991  template<>
992  struct hash<__gnu_cxx::throw_value_limit>
993  : public std::unary_function<__gnu_cxx::throw_value_limit, size_t>
994  {
995  size_t
996  operator()(const __gnu_cxx::throw_value_limit& __val) const
997  {
998  __gnu_cxx::throw_value_limit::throw_conditionally();
1000  size_t __result = __h(__val._M_i);
1001  return __result;
1002  }
1003  };
1004 
1005 #ifdef _GLIBCXX_USE_C99_STDINT_TR1
1006  /// Explicit specialization of std::hash for __gnu_cxx::throw_value_random.
1007  template<>
1008  struct hash<__gnu_cxx::throw_value_random>
1009  : public std::unary_function<__gnu_cxx::throw_value_random, size_t>
1010  {
1011  size_t
1012  operator()(const __gnu_cxx::throw_value_random& __val) const
1013  {
1014  __gnu_cxx::throw_value_random::throw_conditionally();
1016  size_t __result = __h(__val._M_i);
1017  return __result;
1018  }
1019  };
1020 #endif
1021 
1022 #pragma GCC diagnostic pop
1023 } // end namespace std
1024 #endif
1025 
1026 #endif
const _CharT * c_str() const noexcept
Return const pointer to null-terminated contents.
Definition: cow_string.h:2215
bool empty() const noexcept
Definition: cow_string.h:1035
_T1 first
The first member.
Definition: stl_pair.h:193
integral_constant
Definition: type_traits:62
static constexpr pointer allocate(_Alloc &__a, size_type __n)
Allocate memory.
Base struct for condition policy.
constexpr _Tp * __addressof(_Tp &__r) noexcept
Same as C++11 std::addressof.
Definition: move.h:51
iterator erase(const_iterator __position)
Erases an element from a map.
Definition: stl_map.h:1081
Allocator throwing via random condition.
static constexpr size_type max_size(const _Alloc &__a) noexcept
The maximum supported allocation size.
A standard container made up of (key,value) pairs, which can be retrieved based on a key...
Definition: stl_map.h:102
insert_return_type insert(node_type &&__nh)
Re-insert an extracted node.
Definition: stl_map.h:661
constexpr _Bind_helper< __is_socketlike< _Func >::value, _Func, _BoundArgs... >::type bind(_Func &&__f, _BoundArgs &&... __args)
Function template for std::bind.
Definition: functional:881
iterator begin() noexcept
Definition: stl_map.h:368
Primary class template hash.
Definition: string_view:779
Struct holding two objects of arbitrary type.
constexpr complex< _Tp > operator*(const complex< _Tp > &__x, const complex< _Tp > &__y)
Return new complex value x times y.
Definition: complex:395
iterator find(const key_type &__x)
Tries to locate an element in a map.
Definition: stl_map.h:1219
Base class for checking address and label information about allocations. Create a std::map between th...
Base class for all library exceptions.
Definition: exception.h:59
_T2 second
The second member.
Definition: stl_pair.h:194
GNU extensions for public use.
Base class for incremental control and throw.
Thrown by utilities for testing exception safety.
ISO C++ entities toplevel namespace is std.
Type throwing via limit condition.
Properties of fundamental types.
Definition: limits:312
Uniform continuous distribution for random numbers.
Definition: random.h:1779
Base class for random probability control and throw.
constexpr complex< _Tp > operator-(const complex< _Tp > &__x, const complex< _Tp > &__y)
Return new complex value x minus y.
Definition: complex:365
mersenne_twister_engine< uint_fast32_t, 32, 624, 397, 31, 0x9908b0dfUL, 11, 0xffffffffUL, 7, 0x9d2c5680UL, 15, 0xefc60000UL, 18, 1812433253UL > mt19937
Definition: random.h:1615
Uniform interface to C++98 and C++11 allocators.
Allocator class with logging and exception generation control. Intended to be used as an allocator_ty...
Class with exception generation control. Intended to be used as a value_type in templatized code...
complex< _Tp > pow(const complex< _Tp > &, int)
Return x to the y&#39;th power.
Definition: complex:1280
Type throwing via random condition.
Allocator throwing via limit condition.
constexpr complex< _Tp > operator+(const complex< _Tp > &__x, const complex< _Tp > &__y)
Return new complex value x plus y.
Definition: complex:335
iterator end() noexcept
Definition: stl_map.h:386