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 #if __cpp_impl_three_way_comparison < 201907L
899  template<typename _Tp, typename _Cond>
900  inline bool
901  operator!=(const throw_allocator_base<_Tp, _Cond>&,
902  const throw_allocator_base<_Tp, _Cond>&)
903  { return false; }
904 #endif
905 
906  /// Allocator throwing via limit condition.
907  template<typename _Tp>
909  : public throw_allocator_base<_Tp, limit_condition>
910  {
911  template<typename _Tp1>
912  struct rebind
913  { typedef throw_allocator_limit<_Tp1> other; };
914 
915  throw_allocator_limit() _GLIBCXX_USE_NOEXCEPT { }
916 
918  _GLIBCXX_USE_NOEXCEPT { }
919 
920  template<typename _Tp1>
922  _GLIBCXX_USE_NOEXCEPT { }
923 
924  ~throw_allocator_limit() _GLIBCXX_USE_NOEXCEPT { }
925  };
926 
927 #ifdef _GLIBCXX_USE_C99_STDINT_TR1
928  /// Allocator throwing via random condition.
929  template<typename _Tp>
931  : public throw_allocator_base<_Tp, random_condition>
932  {
933  template<typename _Tp1>
934  struct rebind
935  { typedef throw_allocator_random<_Tp1> other; };
936 
937  throw_allocator_random() _GLIBCXX_USE_NOEXCEPT { }
938 
940  _GLIBCXX_USE_NOEXCEPT { }
941 
942  template<typename _Tp1>
944  _GLIBCXX_USE_NOEXCEPT { }
945 
946  ~throw_allocator_random() _GLIBCXX_USE_NOEXCEPT { }
947  };
948 #endif // _GLIBCXX_USE_C99_STDINT_TR1
949 
950 _GLIBCXX_END_NAMESPACE_VERSION
951 } // namespace
952 
953 #if __cplusplus >= 201103L
954 
955 # include <bits/functional_hash.h>
956 
957 namespace std _GLIBCXX_VISIBILITY(default)
958 {
959  /// Explicit specialization of std::hash for __gnu_cxx::throw_value_limit.
960  template<>
961  struct hash<__gnu_cxx::throw_value_limit>
962  : public std::unary_function<__gnu_cxx::throw_value_limit, size_t>
963  {
964  size_t
965  operator()(const __gnu_cxx::throw_value_limit& __val) const
966  {
967  __gnu_cxx::throw_value_limit::throw_conditionally();
969  size_t __result = __h(__val._M_i);
970  return __result;
971  }
972  };
973 
974 #ifdef _GLIBCXX_USE_C99_STDINT_TR1
975  /// Explicit specialization of std::hash for __gnu_cxx::throw_value_random.
976  template<>
977  struct hash<__gnu_cxx::throw_value_random>
978  : public std::unary_function<__gnu_cxx::throw_value_random, size_t>
979  {
980  size_t
981  operator()(const __gnu_cxx::throw_value_random& __val) const
982  {
983  __gnu_cxx::throw_value_random::throw_conditionally();
985  size_t __result = __h(__val._M_i);
986  return __result;
987  }
988  };
989 #endif
990 } // end namespace std
991 #endif
992 
993 #endif
constexpr complex< _Tp > operator*(const complex< _Tp > &__x, const complex< _Tp > &__y)
Return new complex value x times y.
Definition: complex:391
complex< _Tp > pow(const complex< _Tp > &, int)
Return x to the y'th power.
Definition: complex:1018
constexpr complex< _Tp > operator-(const complex< _Tp > &__x, const complex< _Tp > &__y)
Return new complex value x minus y.
Definition: complex:361
constexpr complex< _Tp > operator+(const complex< _Tp > &__x, const complex< _Tp > &__y)
Return new complex value x plus y.
Definition: complex:331
constexpr _Tp * __addressof(_Tp &__r) noexcept
Same as C++11 std::addressof.
Definition: move.h:49
_T1 first
The first member.
Definition: stl_pair.h:217
_T2 second
The second member.
Definition: stl_pair.h:218
_Tp * end(valarray< _Tp > &__va)
Return an iterator pointing to one past the last element of the valarray.
Definition: valarray:1234
constexpr _Bind_helper< __is_socketlike< _Func >::value, _Func, _BoundArgs... >::type bind(_Func &&__f, _BoundArgs &&... __args)
Function template for std::bind.
Definition: functional:785
mersenne_twister_engine< uint_fast32_t, 32, 624, 397, 31, 0x9908b0dfUL, 11, 0xffffffffUL, 7, 0x9d2c5680UL, 15, 0xefc60000UL, 18, 1812433253UL > mt19937
Definition: random.h:1567
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:58
const _CharT * c_str() const noexcept
Return const pointer to null-terminated contents.
bool empty() const noexcept
Base class for all library exceptions.
Definition: exception.h:61
Uniform continuous distribution for random numbers.
Definition: random.h:1732
A standard container made up of (key,value) pairs, which can be retrieved based on a key,...
Definition: stl_map.h:101
std::pair< iterator, bool > insert(const value_type &__x)
Attempts to insert a std::pair into the map.
Definition: stl_map.h:803
iterator end() noexcept
Definition: stl_map.h:374
iterator find(const key_type &__x)
Tries to locate an element in a map.
Definition: stl_map.h:1169
iterator erase(const_iterator __position)
Erases an element from a map.
Definition: stl_map.h:1031
iterator begin() noexcept
Definition: stl_map.h:356
Struct holding two objects of arbitrary type.
Definition: stl_pair.h:213
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.
Thown by exception safety machinery.
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.