1*e4b17023SJohn Marino // <extptr_allocator.h> -*- C++ -*-
2*e4b17023SJohn Marino
3*e4b17023SJohn Marino // Copyright (C) 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
4*e4b17023SJohn Marino //
5*e4b17023SJohn Marino // This file is part of the GNU ISO C++ Library. This library is free
6*e4b17023SJohn Marino // software; you can redistribute it and/or modify it under the
7*e4b17023SJohn Marino // terms of the GNU General Public License as published by the
8*e4b17023SJohn Marino // Free Software Foundation; either version 3, or (at your option)
9*e4b17023SJohn Marino // any later version.
10*e4b17023SJohn Marino
11*e4b17023SJohn Marino // This library is distributed in the hope that it will be useful,
12*e4b17023SJohn Marino // but WITHOUT ANY WARRANTY; without even the implied warranty of
13*e4b17023SJohn Marino // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14*e4b17023SJohn Marino // GNU General Public License for more details.
15*e4b17023SJohn Marino
16*e4b17023SJohn Marino // Under Section 7 of GPL version 3, you are granted additional
17*e4b17023SJohn Marino // permissions described in the GCC Runtime Library Exception, version
18*e4b17023SJohn Marino // 3.1, as published by the Free Software Foundation.
19*e4b17023SJohn Marino
20*e4b17023SJohn Marino // You should have received a copy of the GNU General Public License and
21*e4b17023SJohn Marino // a copy of the GCC Runtime Library Exception along with this program;
22*e4b17023SJohn Marino // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23*e4b17023SJohn Marino // <http://www.gnu.org/licenses/>.
24*e4b17023SJohn Marino
25*e4b17023SJohn Marino /**
26*e4b17023SJohn Marino * @file ext/extptr_allocator.h
27*e4b17023SJohn Marino * This file is a GNU extension to the Standard C++ Library.
28*e4b17023SJohn Marino *
29*e4b17023SJohn Marino * @author Bob Walters
30*e4b17023SJohn Marino *
31*e4b17023SJohn Marino * An example allocator which uses an alternative pointer type from
32*e4b17023SJohn Marino * bits/pointer.h. Supports test cases which confirm container support
33*e4b17023SJohn Marino * for alternative pointers.
34*e4b17023SJohn Marino */
35*e4b17023SJohn Marino
36*e4b17023SJohn Marino #ifndef _EXTPTR_ALLOCATOR_H
37*e4b17023SJohn Marino #define _EXTPTR_ALLOCATOR_H 1
38*e4b17023SJohn Marino
39*e4b17023SJohn Marino #include <memory>
40*e4b17023SJohn Marino #include <ext/numeric_traits.h>
41*e4b17023SJohn Marino #include <ext/pointer.h>
42*e4b17023SJohn Marino
_GLIBCXX_VISIBILITY(default)43*e4b17023SJohn Marino namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
44*e4b17023SJohn Marino {
45*e4b17023SJohn Marino _GLIBCXX_BEGIN_NAMESPACE_VERSION
46*e4b17023SJohn Marino
47*e4b17023SJohn Marino /**
48*e4b17023SJohn Marino * @brief An example allocator which uses a non-standard pointer type.
49*e4b17023SJohn Marino * @ingroup allocators
50*e4b17023SJohn Marino *
51*e4b17023SJohn Marino * This allocator specifies that containers use a 'relative pointer' as it's
52*e4b17023SJohn Marino * pointer type. (See ext/pointer.h) Memory allocation in this example
53*e4b17023SJohn Marino * is still performed using std::allocator.
54*e4b17023SJohn Marino */
55*e4b17023SJohn Marino template<typename _Tp>
56*e4b17023SJohn Marino class _ExtPtr_allocator
57*e4b17023SJohn Marino {
58*e4b17023SJohn Marino public:
59*e4b17023SJohn Marino typedef std::size_t size_type;
60*e4b17023SJohn Marino typedef std::ptrdiff_t difference_type;
61*e4b17023SJohn Marino
62*e4b17023SJohn Marino // Note the non-standard pointer types.
63*e4b17023SJohn Marino typedef _Pointer_adapter<_Relative_pointer_impl<_Tp> > pointer;
64*e4b17023SJohn Marino typedef _Pointer_adapter<_Relative_pointer_impl<const _Tp> >
65*e4b17023SJohn Marino const_pointer;
66*e4b17023SJohn Marino
67*e4b17023SJohn Marino typedef _Tp& reference;
68*e4b17023SJohn Marino typedef const _Tp& const_reference;
69*e4b17023SJohn Marino typedef _Tp value_type;
70*e4b17023SJohn Marino
71*e4b17023SJohn Marino template<typename _Up>
72*e4b17023SJohn Marino struct rebind
73*e4b17023SJohn Marino { typedef _ExtPtr_allocator<_Up> other; };
74*e4b17023SJohn Marino
75*e4b17023SJohn Marino _ExtPtr_allocator() _GLIBCXX_USE_NOEXCEPT
76*e4b17023SJohn Marino : _M_real_alloc() { }
77*e4b17023SJohn Marino
78*e4b17023SJohn Marino _ExtPtr_allocator(const _ExtPtr_allocator& __rarg) _GLIBCXX_USE_NOEXCEPT
79*e4b17023SJohn Marino : _M_real_alloc(__rarg._M_real_alloc) { }
80*e4b17023SJohn Marino
81*e4b17023SJohn Marino template<typename _Up>
82*e4b17023SJohn Marino _ExtPtr_allocator(const _ExtPtr_allocator<_Up>& __rarg)
83*e4b17023SJohn Marino _GLIBCXX_USE_NOEXCEPT
84*e4b17023SJohn Marino : _M_real_alloc(__rarg._M_getUnderlyingImp()) { }
85*e4b17023SJohn Marino
86*e4b17023SJohn Marino ~_ExtPtr_allocator() _GLIBCXX_USE_NOEXCEPT
87*e4b17023SJohn Marino { }
88*e4b17023SJohn Marino
89*e4b17023SJohn Marino pointer address(reference __x) const _GLIBCXX_NOEXCEPT
90*e4b17023SJohn Marino { return std::__addressof(__x); }
91*e4b17023SJohn Marino
92*e4b17023SJohn Marino const_pointer address(const_reference __x) const _GLIBCXX_NOEXCEPT
93*e4b17023SJohn Marino { return std::__addressof(__x); }
94*e4b17023SJohn Marino
95*e4b17023SJohn Marino pointer allocate(size_type __n, void* __hint = 0)
96*e4b17023SJohn Marino { return _M_real_alloc.allocate(__n,__hint); }
97*e4b17023SJohn Marino
98*e4b17023SJohn Marino void deallocate(pointer __p, size_type __n)
99*e4b17023SJohn Marino { _M_real_alloc.deallocate(__p.get(), __n); }
100*e4b17023SJohn Marino
101*e4b17023SJohn Marino size_type max_size() const _GLIBCXX_USE_NOEXCEPT
102*e4b17023SJohn Marino { return __numeric_traits<size_type>::__max / sizeof(_Tp); }
103*e4b17023SJohn Marino
104*e4b17023SJohn Marino #ifdef __GXX_EXPERIMENTAL_CXX0X__
105*e4b17023SJohn Marino template<typename _Up, typename... _Args>
106*e4b17023SJohn Marino void
107*e4b17023SJohn Marino construct(_Up* __p, _Args&&... __args)
108*e4b17023SJohn Marino { ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
109*e4b17023SJohn Marino
110*e4b17023SJohn Marino template<typename... _Args>
111*e4b17023SJohn Marino void
112*e4b17023SJohn Marino construct(pointer __p, _Args&&... __args)
113*e4b17023SJohn Marino { construct(__p.get(), std::forward<_Args>(__args)...); }
114*e4b17023SJohn Marino
115*e4b17023SJohn Marino template<typename _Up>
116*e4b17023SJohn Marino void
117*e4b17023SJohn Marino destroy(_Up* __p)
118*e4b17023SJohn Marino { __p->~_Up(); }
119*e4b17023SJohn Marino
120*e4b17023SJohn Marino void destroy(pointer __p)
121*e4b17023SJohn Marino { destroy(__p.get()); }
122*e4b17023SJohn Marino
123*e4b17023SJohn Marino #else
124*e4b17023SJohn Marino
125*e4b17023SJohn Marino void construct(pointer __p, const _Tp& __val)
126*e4b17023SJohn Marino { ::new(__p.get()) _Tp(__val); }
127*e4b17023SJohn Marino
128*e4b17023SJohn Marino void destroy(pointer __p)
129*e4b17023SJohn Marino { __p->~_Tp(); }
130*e4b17023SJohn Marino #endif
131*e4b17023SJohn Marino
132*e4b17023SJohn Marino template<typename _Up>
133*e4b17023SJohn Marino inline bool
134*e4b17023SJohn Marino operator==(const _ExtPtr_allocator<_Up>& __rarg)
135*e4b17023SJohn Marino { return _M_real_alloc == __rarg._M_getUnderlyingImp(); }
136*e4b17023SJohn Marino
137*e4b17023SJohn Marino inline bool
138*e4b17023SJohn Marino operator==(const _ExtPtr_allocator& __rarg)
139*e4b17023SJohn Marino { return _M_real_alloc == __rarg._M_real_alloc; }
140*e4b17023SJohn Marino
141*e4b17023SJohn Marino template<typename _Up>
142*e4b17023SJohn Marino inline bool
143*e4b17023SJohn Marino operator!=(const _ExtPtr_allocator<_Up>& __rarg)
144*e4b17023SJohn Marino { return _M_real_alloc != __rarg._M_getUnderlyingImp(); }
145*e4b17023SJohn Marino
146*e4b17023SJohn Marino inline bool
147*e4b17023SJohn Marino operator!=(const _ExtPtr_allocator& __rarg)
148*e4b17023SJohn Marino { return _M_real_alloc != __rarg._M_real_alloc; }
149*e4b17023SJohn Marino
150*e4b17023SJohn Marino template<typename _Up>
151*e4b17023SJohn Marino inline friend void
152*e4b17023SJohn Marino swap(_ExtPtr_allocator<_Up>&, _ExtPtr_allocator<_Up>&);
153*e4b17023SJohn Marino
154*e4b17023SJohn Marino // A method specific to this implementation.
155*e4b17023SJohn Marino const std::allocator<_Tp>&
156*e4b17023SJohn Marino _M_getUnderlyingImp() const
157*e4b17023SJohn Marino { return _M_real_alloc; }
158*e4b17023SJohn Marino
159*e4b17023SJohn Marino private:
160*e4b17023SJohn Marino std::allocator<_Tp> _M_real_alloc;
161*e4b17023SJohn Marino };
162*e4b17023SJohn Marino
163*e4b17023SJohn Marino // _ExtPtr_allocator<void> specialization.
164*e4b17023SJohn Marino template<>
165*e4b17023SJohn Marino class _ExtPtr_allocator<void>
166*e4b17023SJohn Marino {
167*e4b17023SJohn Marino public:
168*e4b17023SJohn Marino typedef std::size_t size_type;
169*e4b17023SJohn Marino typedef std::ptrdiff_t difference_type;
170*e4b17023SJohn Marino typedef void value_type;
171*e4b17023SJohn Marino
172*e4b17023SJohn Marino // Note the non-standard pointer types
173*e4b17023SJohn Marino typedef _Pointer_adapter<_Relative_pointer_impl<void> > pointer;
174*e4b17023SJohn Marino typedef _Pointer_adapter<_Relative_pointer_impl<const void> >
175*e4b17023SJohn Marino const_pointer;
176*e4b17023SJohn Marino
177*e4b17023SJohn Marino template<typename _Up>
178*e4b17023SJohn Marino struct rebind
179*e4b17023SJohn Marino { typedef _ExtPtr_allocator<_Up> other; };
180*e4b17023SJohn Marino
181*e4b17023SJohn Marino private:
182*e4b17023SJohn Marino std::allocator<void> _M_real_alloc;
183*e4b17023SJohn Marino };
184*e4b17023SJohn Marino
185*e4b17023SJohn Marino template<typename _Tp>
186*e4b17023SJohn Marino inline void
187*e4b17023SJohn Marino swap(_ExtPtr_allocator<_Tp>& __larg, _ExtPtr_allocator<_Tp>& __rarg)
188*e4b17023SJohn Marino {
189*e4b17023SJohn Marino std::allocator<_Tp> __tmp( __rarg._M_real_alloc );
190*e4b17023SJohn Marino __rarg._M_real_alloc = __larg._M_real_alloc;
191*e4b17023SJohn Marino __larg._M_real_alloc = __tmp;
192*e4b17023SJohn Marino }
193*e4b17023SJohn Marino
194*e4b17023SJohn Marino _GLIBCXX_END_NAMESPACE_VERSION
195*e4b17023SJohn Marino } // namespace
196*e4b17023SJohn Marino
197*e4b17023SJohn Marino #endif /* _EXTPTR_ALLOCATOR_H */
198