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