libstdc++
throw_allocator.h
Go to the documentation of this file.
1 // -*- C++ -*-
2 
3 // Copyright (C) 2005-2017 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
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>
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>
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>
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  {
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  {
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
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>&,
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
const _CharT * c_str() const noexcept
Return const pointer to null-terminated contents.
_T2 second
first is a copy of the first object
Definition: stl_pair.h:196
result_type min() const
Returns the inclusive lower bound of the distribution range.
Definition: random.h:1798
Properties of fundamental types.
Definition: limits:312
Allocator throwing via limit condition.
Base class for incremental control and throw.
_Bind_helper< __is_socketlike< _Func >::value, _Func, _BoundArgs... >::type bind(_Func &&__f, _BoundArgs &&... __args)
Function template for std::bind.
Definition: functional:869
iterator end() noexcept
Definition: stl_map.h:362
Thown by exception safety machinery.
constexpr const _Tp * end(initializer_list< _Tp > __ils) noexcept
Return an iterator pointing to one past the last element of the initializer_list. ...
Primary class template hash.
Definition: system_error:141
mersenne_twister_engine< uint_fast32_t, 32, 624, 397, 31, 0x9908b0dfUL, 11, 0xffffffffUL, 7, 0x9d2c5680UL, 15, 0xefc60000UL, 18, 1812433253UL > mt19937
Definition: random.h:1535
constexpr _Tp * __addressof(_Tp &__r) noexcept
Same as C++11 std::addressof.
Definition: move.h:47
complex< _Tp > pow(const complex< _Tp > &, int)
Return x to the y&#39;th power.
Definition: complex:987
Base struct for condition policy.
ISO C++ entities toplevel namespace is std.
result_type max() const
Returns the inclusive upper bound of the distribution range.
Definition: random.h:1805
Template class basic_ostream.
Definition: iosfwd:86
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:507
GNU extensions for public use.
Type throwing via limit condition.
Allocator throwing via random condition.
Allocator class with logging and exception generation control. Intended to be used as an allocator_ty...
Base class for random probability control and throw.
Uniform continuous distribution for random numbers.
Definition: random.h:1702
iterator begin() noexcept
Definition: stl_map.h:344
_T1 first
second_type is the second bound type
Definition: stl_pair.h:195
A standard container made up of (key,value) pairs, which can be retrieved based on a key...
Definition: stl_map.h:99
integral_constant
Definition: type_traits:69
bool empty() const noexcept
Class with exception generation control. Intended to be used as a value_type in templatized code...
Base class for all library exceptions.
Definition: exception.h:60
Base class for checking address and label information about allocations. Create a std::map between th...
Struct holding two objects of arbitrary type.
Definition: stl_pair.h:190
Type throwing via random condition.