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