OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

[/] [openrisc/] [tags/] [gnu-src/] [gcc-4.5.1/] [gcc-4.5.1-or32-1.0rc3/] [libstdc++-v3/] [testsuite/] [util/] [testsuite_allocator.h] - Blame information for rev 516

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 424 jeremybenn
// -*- C++ -*-
2
// Testing allocator for the C++ library testsuite.
3
//
4
// Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
5
// Free Software Foundation, Inc.
6
//
7
// This file is part of the GNU ISO C++ Library.  This library is free
8
// software; you can redistribute it and/or modify it under the
9
// terms of the GNU General Public License as published by the
10
// Free Software Foundation; either version 3, or (at your option)
11
// any later version.
12
//
13
// This library is distributed in the hope that it will be useful,
14
// but WITHOUT ANY WARRANTY; without even the implied warranty of
15
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
// GNU General Public License for more details.
17
//
18
// You should have received a copy of the GNU General Public License along
19
// with this library; see the file COPYING3.  If not see
20
// <http://www.gnu.org/licenses/>.
21
//
22
 
23
// This file provides an test instrumentation allocator that can be
24
// used to verify allocation functionality of standard library
25
// containers.  2002.11.25 smw
26
 
27
#ifndef _GLIBCXX_TESTSUITE_ALLOCATOR_H
28
#define _GLIBCXX_TESTSUITE_ALLOCATOR_H
29
 
30
#include <cstddef>
31
#include <tr1/unordered_map>
32
#include <cassert>
33
#include <bits/move.h>
34
 
35
namespace __gnu_test
36
{
37
  class tracker_allocator_counter
38
  {
39
  public:
40
    typedef std::size_t    size_type;
41
 
42
    static void*
43
    allocate(size_type blocksize)
44
    {
45
      allocationCount_ += blocksize;
46
      return ::operator new(blocksize);
47
    }
48
 
49
    static void
50
    construct() { constructCount_++; }
51
 
52
    static void
53
    destroy() { destructCount_++; }
54
 
55
    static void
56
    deallocate(void* p, size_type blocksize)
57
    {
58
      ::operator delete(p);
59
      deallocationCount_ += blocksize;
60
    }
61
 
62
    static size_type
63
    get_allocation_count() { return allocationCount_; }
64
 
65
    static size_type
66
    get_deallocation_count() { return deallocationCount_; }
67
 
68
    static int
69
    get_construct_count() { return constructCount_; }
70
 
71
    static int
72
    get_destruct_count() { return destructCount_; }
73
 
74
    static void
75
    reset()
76
    {
77
      allocationCount_ = 0;
78
      deallocationCount_ = 0;
79
      constructCount_ = 0;
80
      destructCount_ = 0;
81
    }
82
 
83
 private:
84
    static size_type  allocationCount_;
85
    static size_type  deallocationCount_;
86
    static int        constructCount_;
87
    static int        destructCount_;
88
  };
89
 
90
  // A simple basic allocator that just forwards to the
91
  // tracker_allocator_counter to fulfill memory requests.  This class
92
  // is templated on the target object type, but tracker isn't.
93
  template<class T>
94
  class tracker_allocator
95
  {
96
  private:
97
    typedef tracker_allocator_counter counter_type;
98
 
99
  public:
100
    typedef T              value_type;
101
    typedef T*             pointer;
102
    typedef const T*       const_pointer;
103
    typedef T&             reference;
104
    typedef const T&       const_reference;
105
    typedef std::size_t    size_type;
106
    typedef std::ptrdiff_t difference_type;
107
 
108
    template<class U> struct rebind { typedef tracker_allocator<U> other; };
109
 
110
    pointer
111
    address(reference value) const
112
    { return &value; }
113
 
114
    const_pointer
115
    address(const_reference value) const
116
    { return &value; }
117
 
118
    tracker_allocator() throw()
119
    { }
120
 
121
    tracker_allocator(const tracker_allocator&) throw()
122
    { }
123
 
124
    template<class U>
125
      tracker_allocator(const tracker_allocator<U>&) throw()
126
      { }
127
 
128
    ~tracker_allocator() throw()
129
    { }
130
 
131
    size_type
132
    max_size() const throw()
133
    { return size_type(-1) / sizeof(T); }
134
 
135
    pointer
136
    allocate(size_type n, const void* = 0)
137
    { return static_cast<pointer>(counter_type::allocate(n * sizeof(T))); }
138
 
139
    void
140
    construct(pointer p, const T& value)
141
    {
142
      ::new ((void *)p) T(value);
143
      counter_type::construct();
144
    }
145
 
146
#ifdef __GXX_EXPERIMENTAL_CXX0X__
147
      template<typename... Args>
148
        void
149
        construct(pointer p, Args&&... args)
150
        {
151
          ::new((void *)p) T(std::forward<Args>(args)...);
152
          counter_type::construct();
153
        }
154
#endif
155
 
156
    void
157
    destroy(pointer p)
158
    {
159
      p->~T();
160
      counter_type::destroy();
161
    }
162
 
163
    void
164
    deallocate(pointer p, size_type num)
165
    { counter_type::deallocate(p, num * sizeof(T)); }
166
  };
167
 
168
  template<class T1, class T2>
169
    bool
170
    operator==(const tracker_allocator<T1>&,
171
               const tracker_allocator<T2>&) throw()
172
    { return true; }
173
 
174
  template<class T1, class T2>
175
    bool
176
    operator!=(const tracker_allocator<T1>&,
177
               const tracker_allocator<T2>&) throw()
178
    { return false; }
179
 
180
  bool
181
  check_construct_destroy(const char* tag, int expected_c, int expected_d);
182
 
183
  template<typename Alloc>
184
    bool
185
    check_deallocate_null()
186
    {
187
      // Let's not core here...
188
      Alloc  a;
189
      a.deallocate(NULL, 1);
190
      a.deallocate(NULL, 10);
191
      return true;
192
    }
193
 
194
  template<typename Alloc>
195
    bool
196
    check_allocate_max_size()
197
    {
198
      Alloc a;
199
      try
200
        {
201
          a.allocate(a.max_size() + 1);
202
        }
203
      catch(std::bad_alloc&)
204
        {
205
          return true;
206
        }
207
      catch(...)
208
        {
209
          throw;
210
        }
211
      throw;
212
    }
213
 
214
 
215
  // A simple allocator which can be constructed endowed of a given
216
  // "personality" (an integer), queried in operator== to simulate the
217
  // behavior of realworld "unequal" allocators (i.e., not exploiting
218
  // the provision in 20.1.5/4, first bullet).  A global unordered_map,
219
  // filled at allocation time with (pointer, personality) pairs, is
220
  // then consulted to enforce the requirements in Table 32 about
221
  // deallocation vs allocator equality.  Note that this allocator is
222
  // swappable, not assignable, consistently with Option 3 of DR 431
223
  // (see N1599).
224
  struct uneq_allocator_base
225
  {
226
    typedef std::tr1::unordered_map<void*, int>   map_type;
227
 
228
    // Avoid static initialization troubles and/or bad interactions
229
    // with tests linking testsuite_allocator.o and playing globally
230
    // with operator new/delete.
231
    static map_type&
232
    get_map()
233
    {
234
      static map_type alloc_map;
235
      return alloc_map;
236
    }
237
  };
238
 
239
  template<typename Tp>
240
    class uneq_allocator
241
    : private uneq_allocator_base
242
    {
243
    public:
244
      typedef size_t                              size_type;
245
      typedef ptrdiff_t                           difference_type;
246
      typedef Tp*                                 pointer;
247
      typedef const Tp*                           const_pointer;
248
      typedef Tp&                                 reference;
249
      typedef const Tp&                           const_reference;
250
      typedef Tp                                  value_type;
251
 
252
      template<typename Tp1>
253
        struct rebind
254
        { typedef uneq_allocator<Tp1> other; };
255
 
256
      uneq_allocator() throw()
257
      : personality(0) { }
258
 
259
      uneq_allocator(int person) throw()
260
      : personality(person) { }
261
 
262
      template<typename Tp1>
263
        uneq_allocator(const uneq_allocator<Tp1>& b) throw()
264
        : personality(b.get_personality()) { }
265
 
266
      int get_personality() const { return personality; }
267
 
268
      pointer
269
      address(reference x) const { return &x; }
270
 
271
      const_pointer
272
      address(const_reference x) const { return &x; }
273
 
274
      pointer
275
      allocate(size_type n, const void* = 0)
276
      {
277
        if (__builtin_expect(n > this->max_size(), false))
278
          std::__throw_bad_alloc();
279
 
280
        pointer p = static_cast<Tp*>(::operator new(n * sizeof(Tp)));
281
        try
282
          {
283
            get_map().insert(map_type::value_type(reinterpret_cast<void*>(p),
284
                                                  personality));
285
          }
286
        catch(...)
287
          {
288
            ::operator delete(p);
289
            __throw_exception_again;
290
          }
291
        return p;
292
      }
293
 
294
      void
295
      deallocate(pointer p, size_type)
296
      {
297
        assert( p );
298
 
299
        map_type::iterator it = get_map().find(reinterpret_cast<void*>(p));
300
        assert( it != get_map().end() );
301
 
302
        // Enforce requirements in Table 32 about deallocation vs
303
        // allocator equality.
304
        assert( it->second == personality );
305
 
306
        get_map().erase(it);
307
        ::operator delete(p);
308
      }
309
 
310
      size_type
311
      max_size() const throw()
312
      { return size_type(-1) / sizeof(Tp); }
313
 
314
      void
315
      construct(pointer p, const Tp& val)
316
      { ::new((void *)p) Tp(val); }
317
 
318
#ifdef __GXX_EXPERIMENTAL_CXX0X__
319
      template<typename... Args>
320
        void
321
        construct(pointer p, Args&&... args)
322
        { ::new((void *)p) Tp(std::forward<Args>(args)...); }
323
#endif
324
 
325
      void
326
      destroy(pointer p) { p->~Tp(); }
327
 
328
    private:
329
      // Not assignable...
330
      uneq_allocator&
331
      operator=(const uneq_allocator&);
332
 
333
      // ... yet swappable!
334
      friend inline void
335
      swap(uneq_allocator& a, uneq_allocator& b)
336
      { std::swap(a.personality, b.personality); }
337
 
338
      template<typename Tp1>
339
        friend inline bool
340
        operator==(const uneq_allocator& a, const uneq_allocator<Tp1>& b)
341
        { return a.personality == b.personality; }
342
 
343
      template<typename Tp1>
344
        friend inline bool
345
        operator!=(const uneq_allocator& a, const uneq_allocator<Tp1>& b)
346
        { return !(a == b); }
347
 
348
      int personality;
349
    };
350
} // namespace __gnu_test
351
 
352
#endif // _GLIBCXX_TESTSUITE_ALLOCATOR_H

powered by: WebSVN 2.1.0

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