1*f8a1b7d9SAlexander Kabaev // array allocator -*- C++ -*-
2*f8a1b7d9SAlexander Kabaev 
3*f8a1b7d9SAlexander Kabaev // Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
4*f8a1b7d9SAlexander Kabaev //
5*f8a1b7d9SAlexander Kabaev // This file is part of the GNU ISO C++ Library.  This library is free
6*f8a1b7d9SAlexander Kabaev // software; you can redistribute it and/or modify it under the
7*f8a1b7d9SAlexander Kabaev // terms of the GNU General Public License as published by the
8*f8a1b7d9SAlexander Kabaev // Free Software Foundation; either version 2, or (at your option)
9*f8a1b7d9SAlexander Kabaev // any later version.
10*f8a1b7d9SAlexander Kabaev 
11*f8a1b7d9SAlexander Kabaev // This library is distributed in the hope that it will be useful,
12*f8a1b7d9SAlexander Kabaev // but WITHOUT ANY WARRANTY; without even the implied warranty of
13*f8a1b7d9SAlexander Kabaev // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14*f8a1b7d9SAlexander Kabaev // GNU General Public License for more details.
15*f8a1b7d9SAlexander Kabaev 
16*f8a1b7d9SAlexander Kabaev // You should have received a copy of the GNU General Public License along
17*f8a1b7d9SAlexander Kabaev // with this library; see the file COPYING.  If not, write to the Free
18*f8a1b7d9SAlexander Kabaev // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
19*f8a1b7d9SAlexander Kabaev // USA.
20*f8a1b7d9SAlexander Kabaev 
21*f8a1b7d9SAlexander Kabaev // As a special exception, you may use this file as part of a free software
22*f8a1b7d9SAlexander Kabaev // library without restriction.  Specifically, if other files instantiate
23*f8a1b7d9SAlexander Kabaev // templates or use macros or inline functions from this file, or you compile
24*f8a1b7d9SAlexander Kabaev // this file and link it with other files to produce an executable, this
25*f8a1b7d9SAlexander Kabaev // file does not by itself cause the resulting executable to be covered by
26*f8a1b7d9SAlexander Kabaev // the GNU General Public License.  This exception does not however
27*f8a1b7d9SAlexander Kabaev // invalidate any other reasons why the executable file might be covered by
28*f8a1b7d9SAlexander Kabaev // the GNU General Public License.
29*f8a1b7d9SAlexander Kabaev 
30*f8a1b7d9SAlexander Kabaev /** @file ext/array_allocator.h
31*f8a1b7d9SAlexander Kabaev  *  This file is a GNU extension to the Standard C++ Library.
32*f8a1b7d9SAlexander Kabaev  */
33*f8a1b7d9SAlexander Kabaev 
34*f8a1b7d9SAlexander Kabaev #ifndef _ARRAY_ALLOCATOR_H
35*f8a1b7d9SAlexander Kabaev #define _ARRAY_ALLOCATOR_H 1
36*f8a1b7d9SAlexander Kabaev 
37*f8a1b7d9SAlexander Kabaev #include <cstddef>
38*f8a1b7d9SAlexander Kabaev #include <new>
39*f8a1b7d9SAlexander Kabaev #include <bits/functexcept.h>
40*f8a1b7d9SAlexander Kabaev #include <tr1/array>
41*f8a1b7d9SAlexander Kabaev 
42*f8a1b7d9SAlexander Kabaev _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
43*f8a1b7d9SAlexander Kabaev 
44*f8a1b7d9SAlexander Kabaev  using std::size_t;
45*f8a1b7d9SAlexander Kabaev  using std::ptrdiff_t;
46*f8a1b7d9SAlexander Kabaev 
47*f8a1b7d9SAlexander Kabaev   /// @brief  Base class.
48*f8a1b7d9SAlexander Kabaev  template<typename _Tp>
49*f8a1b7d9SAlexander Kabaev     class array_allocator_base
50*f8a1b7d9SAlexander Kabaev     {
51*f8a1b7d9SAlexander Kabaev     public:
52*f8a1b7d9SAlexander Kabaev       typedef size_t     	size_type;
53*f8a1b7d9SAlexander Kabaev       typedef ptrdiff_t  	difference_type;
54*f8a1b7d9SAlexander Kabaev       typedef _Tp*       	pointer;
55*f8a1b7d9SAlexander Kabaev       typedef const _Tp* 	const_pointer;
56*f8a1b7d9SAlexander Kabaev       typedef _Tp&       	reference;
57*f8a1b7d9SAlexander Kabaev       typedef const _Tp&	const_reference;
58*f8a1b7d9SAlexander Kabaev       typedef _Tp        	value_type;
59*f8a1b7d9SAlexander Kabaev 
60*f8a1b7d9SAlexander Kabaev       pointer
address(reference __x)61*f8a1b7d9SAlexander Kabaev       address(reference __x) const { return &__x; }
62*f8a1b7d9SAlexander Kabaev 
63*f8a1b7d9SAlexander Kabaev       const_pointer
address(const_reference __x)64*f8a1b7d9SAlexander Kabaev       address(const_reference __x) const { return &__x; }
65*f8a1b7d9SAlexander Kabaev 
66*f8a1b7d9SAlexander Kabaev       void
deallocate(pointer,size_type)67*f8a1b7d9SAlexander Kabaev       deallocate(pointer, size_type)
68*f8a1b7d9SAlexander Kabaev       {
69*f8a1b7d9SAlexander Kabaev 	// Does nothing.
70*f8a1b7d9SAlexander Kabaev       }
71*f8a1b7d9SAlexander Kabaev 
72*f8a1b7d9SAlexander Kabaev       size_type
max_size()73*f8a1b7d9SAlexander Kabaev       max_size() const throw()
74*f8a1b7d9SAlexander Kabaev       { return size_t(-1) / sizeof(_Tp); }
75*f8a1b7d9SAlexander Kabaev 
76*f8a1b7d9SAlexander Kabaev       // _GLIBCXX_RESOLVE_LIB_DEFECTS
77*f8a1b7d9SAlexander Kabaev       // 402. wrong new expression in [some_] allocator::construct
78*f8a1b7d9SAlexander Kabaev       void
construct(pointer __p,const _Tp & __val)79*f8a1b7d9SAlexander Kabaev       construct(pointer __p, const _Tp& __val)
80*f8a1b7d9SAlexander Kabaev       { ::new(__p) value_type(__val); }
81*f8a1b7d9SAlexander Kabaev 
82*f8a1b7d9SAlexander Kabaev       void
destroy(pointer __p)83*f8a1b7d9SAlexander Kabaev       destroy(pointer __p) { __p->~_Tp(); }
84*f8a1b7d9SAlexander Kabaev     };
85*f8a1b7d9SAlexander Kabaev 
86*f8a1b7d9SAlexander Kabaev   /**
87*f8a1b7d9SAlexander Kabaev    *  @brief  An allocator that uses previously allocated memory.
88*f8a1b7d9SAlexander Kabaev    *  This memory can be externally, globally, or otherwise allocated.
89*f8a1b7d9SAlexander Kabaev    */
90*f8a1b7d9SAlexander Kabaev   template<typename _Tp, typename _Array = std::tr1::array<_Tp, 1> >
91*f8a1b7d9SAlexander Kabaev     class array_allocator : public array_allocator_base<_Tp>
92*f8a1b7d9SAlexander Kabaev     {
93*f8a1b7d9SAlexander Kabaev     public:
94*f8a1b7d9SAlexander Kabaev       typedef size_t     	size_type;
95*f8a1b7d9SAlexander Kabaev       typedef ptrdiff_t  	difference_type;
96*f8a1b7d9SAlexander Kabaev       typedef _Tp*       	pointer;
97*f8a1b7d9SAlexander Kabaev       typedef const _Tp* 	const_pointer;
98*f8a1b7d9SAlexander Kabaev       typedef _Tp&       	reference;
99*f8a1b7d9SAlexander Kabaev       typedef const _Tp& 	const_reference;
100*f8a1b7d9SAlexander Kabaev       typedef _Tp        	value_type;
101*f8a1b7d9SAlexander Kabaev       typedef _Array		array_type;
102*f8a1b7d9SAlexander Kabaev 
103*f8a1b7d9SAlexander Kabaev     private:
104*f8a1b7d9SAlexander Kabaev       array_type* 	_M_array;
105*f8a1b7d9SAlexander Kabaev       size_type 	_M_used;
106*f8a1b7d9SAlexander Kabaev 
107*f8a1b7d9SAlexander Kabaev     public:
108*f8a1b7d9SAlexander Kabaev      template<typename _Tp1, typename _Array1 = _Array>
109*f8a1b7d9SAlexander Kabaev         struct rebind
110*f8a1b7d9SAlexander Kabaev         { typedef array_allocator<_Tp1, _Array1> other; };
111*f8a1b7d9SAlexander Kabaev 
throw()112*f8a1b7d9SAlexander Kabaev       array_allocator(array_type* __array = NULL) throw()
113*f8a1b7d9SAlexander Kabaev       : _M_array(__array), _M_used(size_type()) { }
114*f8a1b7d9SAlexander Kabaev 
throw()115*f8a1b7d9SAlexander Kabaev       array_allocator(const array_allocator& __o)  throw()
116*f8a1b7d9SAlexander Kabaev       : _M_array(__o._M_array), _M_used(__o._M_used) { }
117*f8a1b7d9SAlexander Kabaev 
118*f8a1b7d9SAlexander Kabaev       template<typename _Tp1, typename _Array1>
array_allocator(const array_allocator<_Tp1,_Array1> &)119*f8a1b7d9SAlexander Kabaev         array_allocator(const array_allocator<_Tp1, _Array1>&) throw()
120*f8a1b7d9SAlexander Kabaev 	: _M_array(NULL), _M_used(size_type()) { }
121*f8a1b7d9SAlexander Kabaev 
throw()122*f8a1b7d9SAlexander Kabaev       ~array_allocator() throw() { }
123*f8a1b7d9SAlexander Kabaev 
124*f8a1b7d9SAlexander Kabaev       pointer
125*f8a1b7d9SAlexander Kabaev       allocate(size_type __n, const void* = 0)
126*f8a1b7d9SAlexander Kabaev       {
127*f8a1b7d9SAlexander Kabaev 	if (_M_array == 0 || _M_used + __n > _M_array->size())
128*f8a1b7d9SAlexander Kabaev 	  std::__throw_bad_alloc();
129*f8a1b7d9SAlexander Kabaev 	pointer __ret = _M_array->begin() + _M_used;
130*f8a1b7d9SAlexander Kabaev 	_M_used += __n;
131*f8a1b7d9SAlexander Kabaev 	return __ret;
132*f8a1b7d9SAlexander Kabaev       }
133*f8a1b7d9SAlexander Kabaev     };
134*f8a1b7d9SAlexander Kabaev 
135*f8a1b7d9SAlexander Kabaev   template<typename _Tp, typename _Array>
136*f8a1b7d9SAlexander Kabaev     inline bool
137*f8a1b7d9SAlexander Kabaev     operator==(const array_allocator<_Tp, _Array>&,
138*f8a1b7d9SAlexander Kabaev 	       const array_allocator<_Tp, _Array>&)
139*f8a1b7d9SAlexander Kabaev     { return true; }
140*f8a1b7d9SAlexander Kabaev 
141*f8a1b7d9SAlexander Kabaev   template<typename _Tp, typename _Array>
142*f8a1b7d9SAlexander Kabaev     inline bool
143*f8a1b7d9SAlexander Kabaev     operator!=(const array_allocator<_Tp, _Array>&,
144*f8a1b7d9SAlexander Kabaev 	       const array_allocator<_Tp, _Array>&)
145*f8a1b7d9SAlexander Kabaev     { return false; }
146*f8a1b7d9SAlexander Kabaev 
147*f8a1b7d9SAlexander Kabaev _GLIBCXX_END_NAMESPACE
148*f8a1b7d9SAlexander Kabaev 
149*f8a1b7d9SAlexander Kabaev #endif
150