libstdc++
throw_allocator.h
Go to the documentation of this file.
1 // -*- C++ -*-
2 
3 // Copyright (C) 2005-2022 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 <cmath>
50 #include <ctime>
51 #include <map>
52 #include <string>
53 #include <ostream>
54 #include <stdexcept>
55 #include <utility>
56 #include <bits/functexcept.h>
57 #include <bits/move.h>
58 #if __cplusplus >= 201103L
59 # include <functional>
60 # include <random>
61 #else
62 # include <tr1/functional>
63 # include <tr1/random>
64 #endif
65 #include <ext/alloc_traits.h>
66 
67 #if !__has_builtin(__builtin_sprintf)
68 # include <cstdio>
69 #endif
70 
71 namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
72 {
73 _GLIBCXX_BEGIN_NAMESPACE_VERSION
74 
75  /**
76  * @brief Thrown by utilities for testing exception safety.
77  * @ingroup exceptions
78  */
79  struct forced_error : public std::exception
80  { };
81 
82  // Substitute for forced_error object when -fno-exceptions.
83  inline void
84  __throw_forced_error()
85  { _GLIBCXX_THROW_OR_ABORT(forced_error()); }
86 
87  /**
88  * @brief Base class for checking address and label information
89  * about allocations. Create a std::map between the allocated
90  * address (void*) and a datum for annotations, which are a pair of
91  * numbers corresponding to label and allocated size.
92  */
94  {
95  private:
99  typedef map_alloc_type::const_iterator const_iterator;
100  typedef map_alloc_type::const_reference const_reference;
101 #if __cplusplus >= 201103L
103 #endif
104 
105  public:
106  annotate_base()
107  {
108  label();
109  map_alloc();
110  }
111 
112  static void
113  set_label(size_t l)
114  { label() = l; }
115 
116  static size_t
117  get_label()
118  { return label(); }
119 
120  void
121  insert(void* p, size_t size)
122  {
123  entry_type entry = make_entry(p, size);
124  if (!p)
125  {
126  std::string error("annotate_base::insert null insert!\n");
127  log_to_string(error, entry);
128  std::__throw_logic_error(error.c_str());
129  }
130 
132  = map_alloc().insert(entry);
133  if (!inserted.second)
134  {
135  std::string error("annotate_base::insert double insert!\n");
136  log_to_string(error, entry);
137  log_to_string(error, *inserted.first);
138  std::__throw_logic_error(error.c_str());
139  }
140  }
141 
142  void
143  erase(void* p, size_t size)
144  { map_alloc().erase(check_allocated(p, size)); }
145 
146 #if __cplusplus >= 201103L
147  void
148  insert_construct(void* p)
149  {
150  if (!p)
151  {
152  std::string error("annotate_base::insert_construct null!\n");
153  std::__throw_logic_error(error.c_str());
154  }
155 
156  auto inserted = map_construct().insert(std::make_pair(p, get_label()));
157  if (!inserted.second)
158  {
159  std::string error("annotate_base::insert_construct double insert!\n");
160  log_to_string(error, std::make_pair(p, get_label()));
161  log_to_string(error, *inserted.first);
162  std::__throw_logic_error(error.c_str());
163  }
164  }
165 
166  void
167  erase_construct(void* p)
168  { map_construct().erase(check_constructed(p)); }
169 #endif
170 
171  // See if a particular address and allocation size has been saved.
172  inline map_alloc_type::iterator
173  check_allocated(void* p, size_t size)
174  {
175  map_alloc_type::iterator found = map_alloc().find(p);
176  if (found == map_alloc().end())
177  {
178  std::string error("annotate_base::check_allocated by value "
179  "null erase!\n");
180  log_to_string(error, make_entry(p, size));
181  std::__throw_logic_error(error.c_str());
182  }
183 
184  if (found->second.second != size)
185  {
186  std::string error("annotate_base::check_allocated by value "
187  "wrong-size erase!\n");
188  log_to_string(error, make_entry(p, size));
189  log_to_string(error, *found);
190  std::__throw_logic_error(error.c_str());
191  }
192 
193  return found;
194  }
195 
196  // See if a given label has been allocated.
197  inline void
198  check(size_t label)
199  {
200  std::string found;
201  {
202  const_iterator beg = map_alloc().begin();
203  const_iterator end = map_alloc().end();
204  while (beg != end)
205  {
206  if (beg->second.first == label)
207  log_to_string(found, *beg);
208  ++beg;
209  }
210  }
211 
212 #if __cplusplus >= 201103L
213  {
214  auto beg = map_construct().begin();
215  auto end = map_construct().end();
216  while (beg != end)
217  {
218  if (beg->second == label)
219  log_to_string(found, *beg);
220  ++beg;
221  }
222  }
223 #endif
224 
225  if (!found.empty())
226  {
227  std::string error("annotate_base::check by label\n");
228  error += found;
229  std::__throw_logic_error(error.c_str());
230  }
231  }
232 
233  // See if there is anything left allocated or constructed.
234  inline static void
235  check()
236  {
237  std::string found;
238  {
239  const_iterator beg = map_alloc().begin();
240  const_iterator end = map_alloc().end();
241  while (beg != end)
242  {
243  log_to_string(found, *beg);
244  ++beg;
245  }
246  }
247 
248 #if __cplusplus >= 201103L
249  {
250  auto beg = map_construct().begin();
251  auto end = map_construct().end();
252  while (beg != end)
253  {
254  log_to_string(found, *beg);
255  ++beg;
256  }
257  }
258 #endif
259 
260  if (!found.empty())
261  {
262  std::string error("annotate_base::check \n");
263  error += found;
264  std::__throw_logic_error(error.c_str());
265  }
266  }
267 
268 #if __cplusplus >= 201103L
269  inline map_construct_type::iterator
270  check_constructed(void* p)
271  {
272  auto found = map_construct().find(p);
273  if (found == map_construct().end())
274  {
275  std::string error("annotate_base::check_constructed not "
276  "constructed!\n");
277  log_to_string(error, std::make_pair(p, get_label()));
278  std::__throw_logic_error(error.c_str());
279  }
280 
281  return found;
282  }
283 
284  inline void
285  check_constructed(size_t label)
286  {
287  auto beg = map_construct().begin();
288  auto end = map_construct().end();
289  std::string found;
290  while (beg != end)
291  {
292  if (beg->second == label)
293  log_to_string(found, *beg);
294  ++beg;
295  }
296 
297  if (!found.empty())
298  {
299  std::string error("annotate_base::check_constructed by label\n");
300  error += found;
301  std::__throw_logic_error(error.c_str());
302  }
303  }
304 #endif
305 
306  private:
307  friend std::ostream&
308  operator<<(std::ostream&, const annotate_base&);
309 
310  entry_type
311  make_entry(void* p, size_t size)
312  { return std::make_pair(p, data_type(get_label(), size)); }
313 
314  static void
315  log_to_string(std::string& s, const_reference ref)
316  {
317 #if ! __has_builtin(__builtin_sprintf)
318  __typeof__(&std::sprintf) __builtin_sprintf = &std::sprintf;
319 #endif
320 
321  char buf[40];
322  const char tab('\t');
323  s += "label: ";
324  unsigned long l = static_cast<unsigned long>(ref.second.first);
325  __builtin_sprintf(buf, "%lu", l);
326  s += buf;
327  s += tab;
328  s += "size: ";
329  l = static_cast<unsigned long>(ref.second.second);
330  __builtin_sprintf(buf, "%lu", l);
331  s += buf;
332  s += tab;
333  s += "address: ";
334  __builtin_sprintf(buf, "%p", ref.first);
335  s += buf;
336  s += '\n';
337  }
338 
339 #if __cplusplus >= 201103L
340  static void
341  log_to_string(std::string& s, const std::pair<const void*, size_t>& ref)
342  {
343 #if ! __has_builtin(__builtin_sprintf)
344  auto __builtin_sprintf = &std::sprintf;
345 #endif
346 
347  char buf[40];
348  const char tab('\t');
349  s += "label: ";
350  unsigned long l = static_cast<unsigned long>(ref.second);
351  __builtin_sprintf(buf, "%lu", l);
352  s += buf;
353  s += tab;
354  s += "address: ";
355  __builtin_sprintf(buf, "%p", ref.first);
356  s += buf;
357  s += '\n';
358  }
359 #endif
360 
361  static size_t&
362  label()
363  {
364  static size_t _S_label(std::numeric_limits<size_t>::max());
365  return _S_label;
366  }
367 
368  static map_alloc_type&
369  map_alloc()
370  {
371  static map_alloc_type _S_map;
372  return _S_map;
373  }
374 
375 #if __cplusplus >= 201103L
376  static map_construct_type&
377  map_construct()
378  {
379  static map_construct_type _S_map;
380  return _S_map;
381  }
382 #endif
383  };
384 
385  inline std::ostream&
386  operator<<(std::ostream& os, const annotate_base& __b)
387  {
388  std::string error;
389  typedef annotate_base base_type;
390  {
391  base_type::const_iterator beg = __b.map_alloc().begin();
392  base_type::const_iterator end = __b.map_alloc().end();
393  for (; beg != end; ++beg)
394  __b.log_to_string(error, *beg);
395  }
396 #if __cplusplus >= 201103L
397  {
398  auto beg = __b.map_construct().begin();
399  auto end = __b.map_construct().end();
400  for (; beg != end; ++beg)
401  __b.log_to_string(error, *beg);
402  }
403 #endif
404  return os << error;
405  }
406 
407 
408  /**
409  * @brief Base struct for condition policy.
410  *
411  * Requires a public member function with the signature
412  * void throw_conditionally()
413  */
415  {
416 #if __cplusplus >= 201103L
417  condition_base() = default;
418  condition_base(const condition_base&) = default;
419  condition_base& operator=(const condition_base&) = default;
420 #endif
421  virtual ~condition_base() { };
422  };
423 
424 
425  /**
426  * @brief Base class for incremental control and throw.
427  */
429  {
430  // Scope-level adjustor objects: set limit for throw at the
431  // beginning of a scope block, and restores to previous limit when
432  // object is destroyed on exiting the block.
433  struct adjustor_base
434  {
435  private:
436  const size_t _M_orig;
437 
438  public:
439  adjustor_base() : _M_orig(limit()) { }
440 
441  virtual
442  ~adjustor_base() { set_limit(_M_orig); }
443  };
444 
445  /// Never enter the condition.
446  struct never_adjustor : public adjustor_base
447  {
449  };
450 
451  /// Always enter the condition.
452  struct always_adjustor : public adjustor_base
453  {
454  always_adjustor() { set_limit(count()); }
455  };
456 
457  /// Enter the nth condition.
458  struct limit_adjustor : public adjustor_base
459  {
460  limit_adjustor(const size_t __l) { set_limit(__l); }
461  };
462 
463  // Increment _S_count every time called.
464  // If _S_count matches the limit count, throw.
465  static void
466  throw_conditionally()
467  {
468  if (count() == limit())
469  __throw_forced_error();
470  ++count();
471  }
472 
473  static size_t&
474  count()
475  {
476  static size_t _S_count(0);
477  return _S_count;
478  }
479 
480  static size_t&
481  limit()
482  {
483  static size_t _S_limit(std::numeric_limits<size_t>::max());
484  return _S_limit;
485  }
486 
487  // Zero the throw counter, set limit to argument.
488  static void
489  set_limit(const size_t __l)
490  {
491  limit() = __l;
492  count() = 0;
493  }
494  };
495 
496 #ifdef _GLIBCXX_USE_C99_STDINT_TR1
497  /**
498  * @brief Base class for random probability control and throw.
499  */
501  {
502  // Scope-level adjustor objects: set probability for throw at the
503  // beginning of a scope block, and restores to previous
504  // probability when object is destroyed on exiting the block.
505  struct adjustor_base
506  {
507  private:
508  const double _M_orig;
509 
510  public:
511  adjustor_base() : _M_orig(probability()) { }
512 
513  virtual ~adjustor_base()
514  { set_probability(_M_orig); }
515  };
516 
517  /// Group condition.
518  struct group_adjustor : public adjustor_base
519  {
520  group_adjustor(size_t size)
521  { set_probability(1 - std::pow(double(1 - probability()),
522  double(0.5 / (size + 1))));
523  }
524  };
525 
526  /// Never enter the condition.
527  struct never_adjustor : public adjustor_base
528  {
529  never_adjustor() { set_probability(0); }
530  };
531 
532  /// Always enter the condition.
533  struct always_adjustor : public adjustor_base
534  {
535  always_adjustor() { set_probability(1); }
536  };
537 
539  {
540  probability();
541  engine();
542  }
543 
544  static void
545  set_probability(double __p)
546  { probability() = __p; }
547 
548  static void
549  throw_conditionally()
550  {
551  if (generate() < probability())
552  __throw_forced_error();
553  }
554 
555  void
556  seed(unsigned long __s)
557  { engine().seed(__s); }
558 
559  private:
560 #if __cplusplus >= 201103L
561  typedef std::uniform_real_distribution<double> distribution_type;
562  typedef std::mt19937 engine_type;
563 #else
564  typedef std::tr1::uniform_real<double> distribution_type;
565  typedef std::tr1::mt19937 engine_type;
566 #endif
567 
568  static double
569  generate()
570  {
571 #if __cplusplus >= 201103L
572  const distribution_type distribution(0, 1);
573  static auto generator = std::bind(distribution, engine());
574 #else
575  // Use variate_generator to get normalized results.
576  typedef std::tr1::variate_generator<engine_type, distribution_type> gen_t;
577  distribution_type distribution(0, 1);
578  static gen_t generator(engine(), distribution);
579 #endif
580 
581 #if ! __has_builtin(__builtin_sprintf)
582  __typeof__(&std::sprintf) __builtin_sprintf = &std::sprintf;
583 #endif
584 
585  double random = generator();
586  if (random < distribution.min() || random > distribution.max())
587  {
588  std::string __s("random_condition::generate");
589  __s += "\n";
590  __s += "random number generated is: ";
591  char buf[40];
592  __builtin_sprintf(buf, "%f", random);
593  __s += buf;
594  std::__throw_out_of_range(__s.c_str());
595  }
596 
597  return random;
598  }
599 
600  static double&
601  probability()
602  {
603  static double _S_p;
604  return _S_p;
605  }
606 
607  static engine_type&
608  engine()
609  {
610  static engine_type _S_e;
611  return _S_e;
612  }
613  };
614 #endif // _GLIBCXX_USE_C99_STDINT_TR1
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 #ifdef _GLIBCXX_USE_C99_STDINT_TR1
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 #endif // _GLIBCXX_USE_C99_STDINT_TR1
802 
803  /**
804  * @brief Allocator class with logging and exception generation control.
805  * Intended to be used as an allocator_type in templatized code.
806  * @ingroup allocators
807  *
808  * Note: Deallocate not allowed to throw.
809  */
810  template<typename _Tp, typename _Cond>
812  : public annotate_base, public _Cond
813  {
814  public:
815  typedef std::size_t size_type;
816  typedef std::ptrdiff_t difference_type;
817  typedef _Tp value_type;
818  typedef value_type* pointer;
819  typedef const value_type* const_pointer;
820  typedef value_type& reference;
821  typedef const value_type& const_reference;
822 
823 #if __cplusplus >= 201103L
824  // _GLIBCXX_RESOLVE_LIB_DEFECTS
825  // 2103. std::allocator propagate_on_container_move_assignment
827 #endif
828 
829  private:
830  typedef _Cond condition_type;
831 
832  std::allocator<value_type> _M_allocator;
833 
835 
836  using condition_type::throw_conditionally;
837 
838  public:
839  size_type
840  max_size() const _GLIBCXX_USE_NOEXCEPT
841  { return traits::max_size(_M_allocator); }
842 
843  pointer
844  address(reference __x) const _GLIBCXX_NOEXCEPT
845  { return std::__addressof(__x); }
846 
847  const_pointer
848  address(const_reference __x) const _GLIBCXX_NOEXCEPT
849  { return std::__addressof(__x); }
850 
851  _GLIBCXX_NODISCARD pointer
852  allocate(size_type __n, const void* hint = 0)
853  {
854  if (__n > this->max_size())
855  std::__throw_bad_alloc();
856 
857  throw_conditionally();
858  pointer const a = traits::allocate(_M_allocator, __n, hint);
859  insert(a, sizeof(value_type) * __n);
860  return a;
861  }
862 
863 #if __cplusplus >= 201103L
864  template<typename _Up, typename... _Args>
865  void
866  construct(_Up* __p, _Args&&... __args)
867  {
868  traits::construct(_M_allocator, __p, std::forward<_Args>(__args)...);
869  insert_construct(__p);
870  }
871 
872  template<typename _Up>
873  void
874  destroy(_Up* __p)
875  {
876  erase_construct(__p);
877  traits::destroy(_M_allocator, __p);
878  }
879 #else
880  void
881  construct(pointer __p, const value_type& val)
882  { return _M_allocator.construct(__p, val); }
883 
884  void
885  destroy(pointer __p)
886  { _M_allocator.destroy(__p); }
887 #endif
888 
889  void
890  deallocate(pointer __p, size_type __n)
891  {
892  erase(__p, sizeof(value_type) * __n);
893  _M_allocator.deallocate(__p, __n);
894  }
895 
896  void
897  check_allocated(pointer __p, size_type __n)
898  {
899  size_type __t = sizeof(value_type) * __n;
900  annotate_base::check_allocated(__p, __t);
901  }
902 
903  void
904  check(size_type __n)
905  { annotate_base::check(__n); }
906  };
907 
908  template<typename _Tp, typename _Cond>
909  inline bool
910  operator==(const throw_allocator_base<_Tp, _Cond>&,
912  { return true; }
913 
914 #if __cpp_impl_three_way_comparison < 201907L
915  template<typename _Tp, typename _Cond>
916  inline bool
917  operator!=(const throw_allocator_base<_Tp, _Cond>&,
918  const throw_allocator_base<_Tp, _Cond>&)
919  { return false; }
920 #endif
921 
922  /// Allocator throwing via limit condition.
923  template<typename _Tp>
925  : public throw_allocator_base<_Tp, limit_condition>
926  {
927  template<typename _Tp1>
928  struct rebind
929  { typedef throw_allocator_limit<_Tp1> other; };
930 
931  throw_allocator_limit() _GLIBCXX_USE_NOEXCEPT { }
932 
934  _GLIBCXX_USE_NOEXCEPT { }
935 
936  template<typename _Tp1>
938  _GLIBCXX_USE_NOEXCEPT { }
939 
940  ~throw_allocator_limit() _GLIBCXX_USE_NOEXCEPT { }
941 
942 #if __cplusplus >= 201103L
944  operator=(const throw_allocator_limit&) = default;
945 #endif
946  };
947 
948 #ifdef _GLIBCXX_USE_C99_STDINT_TR1
949  /// Allocator throwing via random condition.
950  template<typename _Tp>
952  : public throw_allocator_base<_Tp, random_condition>
953  {
954  template<typename _Tp1>
955  struct rebind
956  { typedef throw_allocator_random<_Tp1> other; };
957 
958  throw_allocator_random() _GLIBCXX_USE_NOEXCEPT { }
959 
961  _GLIBCXX_USE_NOEXCEPT { }
962 
963  template<typename _Tp1>
965  _GLIBCXX_USE_NOEXCEPT { }
966 
967  ~throw_allocator_random() _GLIBCXX_USE_NOEXCEPT { }
968 
969 #if __cplusplus >= 201103L
971  operator=(const throw_allocator_random&) = default;
972 #endif
973  };
974 #endif // _GLIBCXX_USE_C99_STDINT_TR1
975 
976 _GLIBCXX_END_NAMESPACE_VERSION
977 } // namespace
978 
979 #if __cplusplus >= 201103L
980 
981 # include <bits/functional_hash.h>
982 
983 namespace std _GLIBCXX_VISIBILITY(default)
984 {
985 #pragma GCC diagnostic push
986 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
987 
988  /// Explicit specialization of std::hash for __gnu_cxx::throw_value_limit.
989  template<>
990  struct hash<__gnu_cxx::throw_value_limit>
991  : public std::unary_function<__gnu_cxx::throw_value_limit, size_t>
992  {
993  size_t
994  operator()(const __gnu_cxx::throw_value_limit& __val) const
995  {
996  __gnu_cxx::throw_value_limit::throw_conditionally();
998  size_t __result = __h(__val._M_i);
999  return __result;
1000  }
1001  };
1002 
1003 #ifdef _GLIBCXX_USE_C99_STDINT_TR1
1004  /// Explicit specialization of std::hash for __gnu_cxx::throw_value_random.
1005  template<>
1006  struct hash<__gnu_cxx::throw_value_random>
1007  : public std::unary_function<__gnu_cxx::throw_value_random, size_t>
1008  {
1009  size_t
1010  operator()(const __gnu_cxx::throw_value_random& __val) const
1011  {
1012  __gnu_cxx::throw_value_random::throw_conditionally();
1014  size_t __result = __h(__val._M_i);
1015  return __result;
1016  }
1017  };
1018 #endif
1019 
1020 #pragma GCC diagnostic pop
1021 } // end namespace std
1022 #endif
1023 
1024 #endif
constexpr complex< _Tp > operator*(const complex< _Tp > &__x, const complex< _Tp > &__y)
Return new complex value x times y.
Definition: complex:392
complex< _Tp > pow(const complex< _Tp > &, int)
Return x to the y'th power.
Definition: complex:1019
constexpr complex< _Tp > operator-(const complex< _Tp > &__x, const complex< _Tp > &__y)
Return new complex value x minus y.
Definition: complex:362
constexpr complex< _Tp > operator+(const complex< _Tp > &__x, const complex< _Tp > &__y)
Return new complex value x plus y.
Definition: complex:332
constexpr _Tp * __addressof(_Tp &__r) noexcept
Same as C++11 std::addressof.
Definition: move.h:49
constexpr _Bind_helper< __is_socketlike< _Func >::value, _Func, _BoundArgs... >::type bind(_Func &&__f, _BoundArgs &&... __args)
Function template for std::bind.
Definition: functional:854
mersenne_twister_engine< uint_fast32_t, 32, 624, 397, 31, 0x9908b0dfUL, 11, 0xffffffffUL, 7, 0x9d2c5680UL, 15, 0xefc60000UL, 18, 1812433253UL > mt19937
Definition: random.h:1581
ISO C++ entities toplevel namespace is std.
GNU extensions for public use.
Properties of fundamental types.
Definition: limits:313
Primary class template hash.
integral_constant
Definition: type_traits:63
const _CharT * c_str() const noexcept
Return const pointer to null-terminated contents.
Definition: cow_string.h:2206
bool empty() const noexcept
Definition: cow_string.h:1026
Base class for all library exceptions.
Definition: exception.h:62
Uniform continuous distribution for random numbers.
Definition: random.h:1746
Struct holding two objects of arbitrary type.
Definition: stl_pair.h:187
_T1 first
The first member.
Definition: stl_pair.h:191
_T2 second
The second member.
Definition: stl_pair.h:192
A standard container made up of (key,value) pairs, which can be retrieved based on a key,...
Definition: stl_map.h:101
insert_return_type insert(node_type &&__nh)
Re-insert an extracted node.
Definition: stl_map.h:659
iterator end() noexcept
Definition: stl_map.h:384
iterator find(const key_type &__x)
Tries to locate an element in a map.
Definition: stl_map.h:1217
iterator erase(const_iterator __position)
Erases an element from a map.
Definition: stl_map.h:1079
iterator begin() noexcept
Definition: stl_map.h:366
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.