OpenCores
URL https://opencores.org/ocsvn/altor32/altor32/trunk

Subversion Repositories altor32

[/] [altor32/] [trunk/] [gcc-x64/] [or1knd-elf/] [or1knd-elf/] [include/] [c++/] [4.8.0/] [ext/] [throw_allocator.h] - Blame information for rev 35

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 35 ultra_embe
// -*- C++ -*-
2
 
3
// Copyright (C) 2005-2012 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
   */
88
  struct annotate_base
89
  {
90
    annotate_base()
91
    {
92
      label();
93
      map();
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().find(p);
115
      if (found != map().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().insert(make_entry(p, size));
124
    }
125
 
126
    void
127
    erase(void* p, size_t size)
128
    {
129
      check_allocated(p, size);
130
      map().erase(p);
131
    }
132
 
133
    // See if a particular address and allocation size has been saved.
134
    inline void
135
    check_allocated(void* p, size_t size)
136
    {
137
      const_iterator found = map().find(p);
138
      if (found == map().end())
139
        {
140
          std::string error("annotate_base::check_allocated by value "
141
                            "null erase!\n");
142
          log_to_string(error, make_entry(p, size));
143
          std::__throw_logic_error(error.c_str());
144
        }
145
 
146
      if (found->second.second != size)
147
        {
148
          std::string error("annotate_base::check_allocated by value "
149
                            "wrong-size erase!\n");
150
          log_to_string(error, make_entry(p, size));
151
          log_to_string(error, *found);
152
          std::__throw_logic_error(error.c_str());
153
        }
154
    }
155
 
156
    // See if a given label has been allocated.
157
    inline void
158
    check_allocated(size_t label)
159
    {
160
      const_iterator beg = map().begin();
161
      const_iterator end = map().end();
162
      std::string found;
163
      while (beg != end)
164
        {
165
          if (beg->second.first == label)
166
            log_to_string(found, *beg);
167
          ++beg;
168
        }
169
 
170
      if (!found.empty())
171
        {
172
          std::string error("annotate_base::check_allocated by label\n");
173
          error += found;
174
          std::__throw_logic_error(error.c_str());
175
        }
176
    }
177
 
178
  private:
179
    typedef std::pair<size_t, size_t>           data_type;
180
    typedef std::map<void*, data_type>          map_type;
181
    typedef map_type::value_type                entry_type;
182
    typedef map_type::const_iterator            const_iterator;
183
    typedef map_type::const_reference           const_reference;
184
 
185
    friend std::ostream&
186
    operator<<(std::ostream&, const annotate_base&);
187
 
188
    entry_type
189
    make_entry(void* p, size_t size)
190
    { return std::make_pair(p, data_type(get_label(), size)); }
191
 
192
    void
193
    log_to_string(std::string& s, const_reference ref) const
194
    {
195
      char buf[40];
196
      const char tab('\t');
197
      s += "label: ";
198
      unsigned long l = static_cast<unsigned long>(ref.second.first);
199
      __builtin_sprintf(buf, "%lu", l);
200
      s += buf;
201
      s += tab;
202
      s += "size: ";
203
      l = static_cast<unsigned long>(ref.second.second);
204
      __builtin_sprintf(buf, "%lu", l);
205
      s += buf;
206
      s += tab;
207
      s += "address: ";
208
      __builtin_sprintf(buf, "%p", ref.first);
209
      s += buf;
210
      s += '\n';
211
    }
212
 
213
    static size_t&
214
    label()
215
    {
216
      static size_t _S_label(std::numeric_limits<size_t>::max());
217
      return _S_label;
218
    }
219
 
220
    static map_type&
221
    map()
222
    {
223
      static map_type _S_map;
224
      return _S_map;
225
    }
226
  };
227
 
228
  inline std::ostream&
229
  operator<<(std::ostream& os, const annotate_base& __b)
230
  {
231
    std::string error;
232
    typedef annotate_base base_type;
233
    base_type::const_iterator beg = __b.map().begin();
234
    base_type::const_iterator end = __b.map().end();
235
    for (; beg != end; ++beg)
236
      __b.log_to_string(error, *beg);
237
    return os << error;
238
  }
239
 
240
 
241
  /**
242
   *  @brief Base struct for condition policy.
243
   *
244
   * Requires a public member function with the signature
245
   * void throw_conditionally()
246
   */
247
  struct condition_base
248
  {
249
    virtual ~condition_base() { };
250
  };
251
 
252
 
253
  /**
254
   *  @brief Base class for incremental control and throw.
255
   */
256
  struct limit_condition : public condition_base
257
  {
258
    // Scope-level adjustor objects: set limit for throw at the
259
    // beginning of a scope block, and restores to previous limit when
260
    // object is destroyed on exiting the block.
261
    struct adjustor_base
262
    {
263
    private:
264
      const size_t _M_orig;
265
 
266
    public:
267
      adjustor_base() : _M_orig(limit()) { }
268
 
269
      virtual
270
      ~adjustor_base() { set_limit(_M_orig); }
271
    };
272
 
273
    /// Never enter the condition.
274
    struct never_adjustor : public adjustor_base
275
    {
276
      never_adjustor() { set_limit(std::numeric_limits<size_t>::max()); }
277
    };
278
 
279
    /// Always enter the condition.
280
    struct always_adjustor : public adjustor_base
281
    {
282
      always_adjustor() { set_limit(count()); }
283
    };
284
 
285
    /// Enter the nth condition.
286
    struct limit_adjustor : public adjustor_base
287
    {
288
      limit_adjustor(const size_t __l) { set_limit(__l); }
289
    };
290
 
291
    // Increment _S_count every time called.
292
    // If _S_count matches the limit count, throw.
293
    static void
294
    throw_conditionally()
295
    {
296
      if (count() == limit())
297
        __throw_forced_error();
298
      ++count();
299
    }
300
 
301
    static size_t&
302
    count()
303
    {
304
      static size_t _S_count(0);
305
      return _S_count;
306
    }
307
 
308
    static size_t&
309
    limit()
310
    {
311
      static size_t _S_limit(std::numeric_limits<size_t>::max());
312
      return _S_limit;
313
    }
314
 
315
    // Zero the throw counter, set limit to argument.
316
    static void
317
    set_limit(const size_t __l)
318
    {
319
      limit() = __l;
320
      count() = 0;
321
    }
322
  };
323
 
324
 
325
  /**
326
   *  @brief Base class for random probability control and throw.
327
   */
328
  struct random_condition : public condition_base
329
  {
330
    // Scope-level adjustor objects: set probability for throw at the
331
    // beginning of a scope block, and restores to previous
332
    // probability when object is destroyed on exiting the block.
333
    struct adjustor_base
334
    {
335
    private:
336
      const double _M_orig;
337
 
338
    public:
339
      adjustor_base() : _M_orig(probability()) { }
340
 
341
      virtual ~adjustor_base()
342
      { set_probability(_M_orig); }
343
    };
344
 
345
    /// Group condition.
346
    struct group_adjustor : public adjustor_base
347
    {
348
      group_adjustor(size_t size)
349
      { set_probability(1 - std::pow(double(1 - probability()),
350
                                     double(0.5 / (size + 1))));
351
      }
352
    };
353
 
354
    /// Never enter the condition.
355
    struct never_adjustor : public adjustor_base
356
    {
357
      never_adjustor() { set_probability(0); }
358
    };
359
 
360
    /// Always enter the condition.
361
    struct always_adjustor : public adjustor_base
362
    {
363
      always_adjustor() { set_probability(1); }
364
    };
365
 
366
    random_condition()
367
    {
368
      probability();
369
      engine();
370
    }
371
 
372
    static void
373
    set_probability(double __p)
374
    { probability() = __p; }
375
 
376
    static void
377
    throw_conditionally()
378
    {
379
      if (generate() < probability())
380
        __throw_forced_error();
381
    }
382
 
383
    void
384
    seed(unsigned long __s)
385
    { engine().seed(__s); }
386
 
387
  private:
388
#if __cplusplus >= 201103L
389
    typedef std::uniform_real_distribution<double>      distribution_type;
390
    typedef std::mt19937                                engine_type;
391
#else
392
    typedef std::tr1::uniform_real<double>              distribution_type;
393
    typedef std::tr1::mt19937                           engine_type;
394
#endif
395
 
396
    static double
397
    generate()
398
    {
399
#if __cplusplus >= 201103L
400
      const distribution_type distribution(0, 1);
401
      static auto generator = std::bind(distribution, engine());
402
#else
403
      // Use variate_generator to get normalized results.
404
      typedef std::tr1::variate_generator<engine_type, distribution_type> gen_t;
405
      distribution_type distribution(0, 1);
406
      static gen_t generator(engine(), distribution);
407
#endif
408
 
409
      double random = generator();
410
      if (random < distribution.min() || random > distribution.max())
411
        {
412
          std::string __s("random_condition::generate");
413
          __s += "\n";
414
          __s += "random number generated is: ";
415
          char buf[40];
416
          __builtin_sprintf(buf, "%f", random);
417
          __s += buf;
418
          std::__throw_out_of_range(__s.c_str());
419
        }
420
 
421
      return random;
422
    }
423
 
424
    static double&
425
    probability()
426
    {
427
      static double _S_p;
428
      return _S_p;
429
    }
430
 
431
    static engine_type&
432
    engine()
433
    {
434
      static engine_type _S_e;
435
      return _S_e;
436
    }
437
  };
438
 
439
 
440
  /**
441
   *  @brief Class with exception generation control. Intended to be
442
   *  used as a value_type in templatized code.
443
   *
444
   *  Note: Destructor not allowed to throw.
445
   */
446
  template<typename _Cond>
447
    struct throw_value_base : public _Cond
448
    {
449
      typedef _Cond                             condition_type;
450
 
451
      using condition_type::throw_conditionally;
452
 
453
      std::size_t                               _M_i;
454
 
455
#ifndef _GLIBCXX_IS_AGGREGATE
456
      throw_value_base() : _M_i(0)
457
      { throw_conditionally(); }
458
 
459
      throw_value_base(const throw_value_base& __v) : _M_i(__v._M_i)
460
      { throw_conditionally(); }
461
 
462
#if __cplusplus >= 201103L
463
      // Shall not throw.
464
      throw_value_base(throw_value_base&&) = default;
465
#endif
466
 
467
      explicit throw_value_base(const std::size_t __i) : _M_i(__i)
468
      { throw_conditionally(); }
469
#endif
470
 
471
      throw_value_base&
472
      operator=(const throw_value_base& __v)
473
      {
474
        throw_conditionally();
475
        _M_i = __v._M_i;
476
        return *this;
477
      }
478
 
479
#if __cplusplus >= 201103L
480
      // Shall not throw.
481
      throw_value_base&
482
      operator=(throw_value_base&&) = default;
483
#endif
484
 
485
      throw_value_base&
486
      operator++()
487
      {
488
        throw_conditionally();
489
        ++_M_i;
490
        return *this;
491
      }
492
    };
493
 
494
  template<typename _Cond>
495
    inline void
496
    swap(throw_value_base<_Cond>& __a, throw_value_base<_Cond>& __b)
497
    {
498
      typedef throw_value_base<_Cond> throw_value;
499
      throw_value::throw_conditionally();
500
      throw_value orig(__a);
501
      __a = __b;
502
      __b = orig;
503
    }
504
 
505
  // General instantiable types requirements.
506
  template<typename _Cond>
507
    inline bool
508
    operator==(const throw_value_base<_Cond>& __a,
509
               const throw_value_base<_Cond>& __b)
510
    {
511
      typedef throw_value_base<_Cond> throw_value;
512
      throw_value::throw_conditionally();
513
      bool __ret = __a._M_i == __b._M_i;
514
      return __ret;
515
    }
516
 
517
  template<typename _Cond>
518
    inline bool
519
    operator<(const throw_value_base<_Cond>& __a,
520
              const throw_value_base<_Cond>& __b)
521
    {
522
      typedef throw_value_base<_Cond> throw_value;
523
      throw_value::throw_conditionally();
524
      bool __ret = __a._M_i < __b._M_i;
525
      return __ret;
526
    }
527
 
528
  // Numeric algorithms instantiable types requirements.
529
  template<typename _Cond>
530
    inline throw_value_base<_Cond>
531
    operator+(const throw_value_base<_Cond>& __a,
532
              const throw_value_base<_Cond>& __b)
533
    {
534
      typedef throw_value_base<_Cond> throw_value;
535
      throw_value::throw_conditionally();
536
      throw_value __ret(__a._M_i + __b._M_i);
537
      return __ret;
538
    }
539
 
540
  template<typename _Cond>
541
    inline throw_value_base<_Cond>
542
    operator-(const throw_value_base<_Cond>& __a,
543
              const throw_value_base<_Cond>& __b)
544
    {
545
      typedef throw_value_base<_Cond> throw_value;
546
      throw_value::throw_conditionally();
547
      throw_value __ret(__a._M_i - __b._M_i);
548
      return __ret;
549
    }
550
 
551
  template<typename _Cond>
552
    inline throw_value_base<_Cond>
553
    operator*(const throw_value_base<_Cond>& __a,
554
              const throw_value_base<_Cond>& __b)
555
    {
556
      typedef throw_value_base<_Cond> throw_value;
557
      throw_value::throw_conditionally();
558
      throw_value __ret(__a._M_i * __b._M_i);
559
      return __ret;
560
    }
561
 
562
 
563
  /// Type throwing via limit condition.
564
  struct throw_value_limit : public throw_value_base<limit_condition>
565
  {
566
    typedef throw_value_base<limit_condition> base_type;
567
 
568
#ifndef _GLIBCXX_IS_AGGREGATE
569
    throw_value_limit() { }
570
 
571
    throw_value_limit(const throw_value_limit& __other)
572
    : base_type(__other._M_i) { }
573
 
574
#if __cplusplus >= 201103L
575
    throw_value_limit(throw_value_limit&&) = default;
576
#endif
577
 
578
    explicit throw_value_limit(const std::size_t __i) : base_type(__i) { }
579
#endif
580
 
581
    throw_value_limit&
582
    operator=(const throw_value_limit& __other)
583
    {
584
      base_type::operator=(__other);
585
      return *this;
586
    }
587
 
588
#if __cplusplus >= 201103L
589
    throw_value_limit&
590
    operator=(throw_value_limit&&) = default;
591
#endif
592
  };
593
 
594
  /// Type throwing via random condition.
595
  struct throw_value_random : public throw_value_base<random_condition>
596
  {
597
    typedef throw_value_base<random_condition> base_type;
598
 
599
#ifndef _GLIBCXX_IS_AGGREGATE
600
    throw_value_random() { }
601
 
602
    throw_value_random(const throw_value_random& __other)
603
    : base_type(__other._M_i) { }
604
 
605
#if __cplusplus >= 201103L
606
    throw_value_random(throw_value_random&&) = default;
607
#endif
608
 
609
    explicit throw_value_random(const std::size_t __i) : base_type(__i) { }
610
#endif
611
 
612
    throw_value_random&
613
    operator=(const throw_value_random& __other)
614
    {
615
      base_type::operator=(__other);
616
      return *this;
617
    }
618
 
619
#if __cplusplus >= 201103L
620
    throw_value_random&
621
    operator=(throw_value_random&&) = default;
622
#endif
623
  };
624
 
625
 
626
  /**
627
   *  @brief Allocator class with logging and exception generation control.
628
   * Intended to be used as an allocator_type in templatized code.
629
   *  @ingroup allocators
630
   *
631
   *  Note: Deallocate not allowed to throw.
632
   */
633
  template<typename _Tp, typename _Cond>
634
    class throw_allocator_base
635
    : public annotate_base, public _Cond
636
    {
637
    public:
638
      typedef size_t                            size_type;
639
      typedef ptrdiff_t                         difference_type;
640
      typedef _Tp                               value_type;
641
      typedef value_type*                       pointer;
642
      typedef const value_type*                 const_pointer;
643
      typedef value_type&                       reference;
644
      typedef const value_type&                 const_reference;
645
 
646
#if __cplusplus >= 201103L
647
      // _GLIBCXX_RESOLVE_LIB_DEFECTS
648
      // 2103. std::allocator propagate_on_container_move_assignment
649
      typedef std::true_type propagate_on_container_move_assignment;
650
#endif
651
 
652
    private:
653
      typedef _Cond                             condition_type;
654
 
655
      std::allocator<value_type>                _M_allocator;
656
 
657
      using condition_type::throw_conditionally;
658
 
659
    public:
660
      size_type
661
      max_size() const _GLIBCXX_USE_NOEXCEPT
662
      { return _M_allocator.max_size(); }
663
 
664
      pointer
665
      address(reference __x) const _GLIBCXX_NOEXCEPT
666
      { return std::__addressof(__x); }
667
 
668
      const_pointer
669
      address(const_reference __x) const _GLIBCXX_NOEXCEPT
670
      { return std::__addressof(__x); }
671
 
672
      pointer
673
      allocate(size_type __n, std::allocator<void>::const_pointer hint = 0)
674
      {
675
        if (__n > this->max_size())
676
          std::__throw_bad_alloc();
677
 
678
        throw_conditionally();
679
        pointer const a = _M_allocator.allocate(__n, hint);
680
        insert(a, sizeof(value_type) * __n);
681
        return a;
682
      }
683
 
684
#if __cplusplus >= 201103L
685
      template<typename _Up, typename... _Args>
686
        void
687
        construct(_Up* __p, _Args&&... __args)
688
        { return _M_allocator.construct(__p, std::forward<_Args>(__args)...); }
689
 
690
      template<typename _Up>
691
        void
692
        destroy(_Up* __p)
693
        { _M_allocator.destroy(__p); }
694
#else
695
      void
696
      construct(pointer __p, const value_type& val)
697
      { return _M_allocator.construct(__p, val); }
698
 
699
      void
700
      destroy(pointer __p)
701
      { _M_allocator.destroy(__p); }
702
#endif
703
 
704
      void
705
      deallocate(pointer __p, size_type __n)
706
      {
707
        erase(__p, sizeof(value_type) * __n);
708
        _M_allocator.deallocate(__p, __n);
709
      }
710
 
711
      void
712
      check_allocated(pointer __p, size_type __n)
713
      {
714
        size_type __t = sizeof(value_type) * __n;
715
        annotate_base::check_allocated(__p, __t);
716
      }
717
 
718
      void
719
      check_allocated(size_type __n)
720
      { annotate_base::check_allocated(__n); }
721
  };
722
 
723
  template<typename _Tp, typename _Cond>
724
    inline bool
725
    operator==(const throw_allocator_base<_Tp, _Cond>&,
726
               const throw_allocator_base<_Tp, _Cond>&)
727
    { return true; }
728
 
729
  template<typename _Tp, typename _Cond>
730
    inline bool
731
    operator!=(const throw_allocator_base<_Tp, _Cond>&,
732
               const throw_allocator_base<_Tp, _Cond>&)
733
    { return false; }
734
 
735
  /// Allocator throwing via limit condition.
736
  template<typename _Tp>
737
    struct throw_allocator_limit
738
    : public throw_allocator_base<_Tp, limit_condition>
739
    {
740
      template<typename _Tp1>
741
        struct rebind
742
        { typedef throw_allocator_limit<_Tp1> other; };
743
 
744
      throw_allocator_limit() _GLIBCXX_USE_NOEXCEPT { }
745
 
746
      throw_allocator_limit(const throw_allocator_limit&)
747
      _GLIBCXX_USE_NOEXCEPT { }
748
 
749
      template<typename _Tp1>
750
        throw_allocator_limit(const throw_allocator_limit<_Tp1>&)
751
        _GLIBCXX_USE_NOEXCEPT { }
752
 
753
      ~throw_allocator_limit() _GLIBCXX_USE_NOEXCEPT { }
754
    };
755
 
756
  /// Allocator throwing via random condition.
757
  template<typename _Tp>
758
    struct throw_allocator_random
759
    : public throw_allocator_base<_Tp, random_condition>
760
    {
761
      template<typename _Tp1>
762
        struct rebind
763
        { typedef throw_allocator_random<_Tp1> other; };
764
 
765
      throw_allocator_random() _GLIBCXX_USE_NOEXCEPT { }
766
 
767
      throw_allocator_random(const throw_allocator_random&)
768
      _GLIBCXX_USE_NOEXCEPT { }
769
 
770
      template<typename _Tp1>
771
        throw_allocator_random(const throw_allocator_random<_Tp1>&)
772
        _GLIBCXX_USE_NOEXCEPT { }
773
 
774
      ~throw_allocator_random() _GLIBCXX_USE_NOEXCEPT { }
775
    };
776
 
777
_GLIBCXX_END_NAMESPACE_VERSION
778
} // namespace
779
 
780
#if __cplusplus >= 201103L
781
 
782
# include <bits/functional_hash.h>
783
 
784
namespace std _GLIBCXX_VISIBILITY(default)
785
{
786
  /// Explicit specialization of std::hash for __gnu_cxx::throw_value_limit.
787
  template<>
788
    struct hash<__gnu_cxx::throw_value_limit>
789
    : public std::unary_function<__gnu_cxx::throw_value_limit, size_t>
790
    {
791
      size_t
792
      operator()(const __gnu_cxx::throw_value_limit& __val) const
793
      {
794
        std::hash<std::size_t> __h;
795
        size_t __result = __h(__val._M_i);
796
        return __result;
797
      }
798
    };
799
 
800
  /// Explicit specialization of std::hash for __gnu_cxx::throw_value_limit.
801
  template<>
802
    struct hash<__gnu_cxx::throw_value_random>
803
    : public std::unary_function<__gnu_cxx::throw_value_random, size_t>
804
    {
805
      size_t
806
      operator()(const __gnu_cxx::throw_value_random& __val) const
807
      {
808
        std::hash<std::size_t> __h;
809
        size_t __result = __h(__val._M_i);
810
        return __result;
811
      }
812
    };
813
} // end namespace std
814
#endif
815
 
816
#endif

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.