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