]>
Commit | Line | Data |
---|---|---|
b5b3f66b PC |
1 | // <extptr_allocator.h> -*- C++ -*- |
2 | ||
5b9daa7e | 3 | // Copyright (C) 2008, 2009 Free Software Foundation, Inc. |
b5b3f66b PC |
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 | |
7 | // terms of the GNU General Public License as published by the | |
748086b7 | 8 | // Free Software Foundation; either version 3, or (at your option) |
b5b3f66b PC |
9 | // any later version. |
10 | ||
11 | // This library is distributed in the hope that it will be useful, | |
12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | // GNU General Public License for more details. | |
15 | ||
748086b7 JJ |
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/>. | |
b5b3f66b PC |
24 | |
25 | /** | |
26 | * @file ext/extptr_allocator.h | |
27 | * @author Bob Walters | |
28 | * | |
29 | * An example allocator which uses an alternative pointer type from | |
30 | * bits/pointer.h. Supports test cases which confirm container support | |
31 | * for alternative pointers. | |
32 | */ | |
33 | ||
34 | #ifndef _EXTPTR_ALLOCATOR_H | |
35 | #define _EXTPTR_ALLOCATOR_H 1 | |
36 | ||
37 | #include <memory> | |
38 | #include <limits> | |
39 | #include <ext/pointer.h> | |
40 | ||
b5b3f66b PC |
41 | _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) |
42 | ||
b5b3f66b PC |
43 | /** |
44 | * @brief An example allocator which uses a non-standard pointer type. | |
5b9daa7e | 45 | * @ingroup allocators |
b5b3f66b PC |
46 | * |
47 | * This allocator specifies that containers use a 'relative pointer' as it's | |
8d8a4e9d | 48 | * pointer type. (See ext/pointer.h) Memory allocation in this example |
b5b3f66b PC |
49 | * is still performed using std::allocator. |
50 | */ | |
51 | template<typename _Tp> | |
52 | class _ExtPtr_allocator | |
53 | { | |
54 | public: | |
8d8a4e9d PC |
55 | typedef std::size_t size_type; |
56 | typedef std::ptrdiff_t difference_type; | |
b5b3f66b PC |
57 | |
58 | // Note the non-standard pointer types. | |
59 | typedef _Pointer_adapter<_Relative_pointer_impl<_Tp> > pointer; | |
8d8a4e9d PC |
60 | typedef _Pointer_adapter<_Relative_pointer_impl<const _Tp> > |
61 | const_pointer; | |
b5b3f66b PC |
62 | |
63 | typedef _Tp& reference; | |
64 | typedef const _Tp& const_reference; | |
65 | typedef _Tp value_type; | |
66 | ||
67 | template<typename _Up> | |
68 | struct rebind | |
69 | { typedef _ExtPtr_allocator<_Up> other; }; | |
70 | ||
71 | _ExtPtr_allocator() throw() | |
72 | : _M_real_alloc() { } | |
73 | ||
74 | _ExtPtr_allocator(const _ExtPtr_allocator &__rarg) throw() | |
75 | : _M_real_alloc(__rarg._M_real_alloc) { } | |
76 | ||
8d8a4e9d | 77 | template<typename _Up> |
b5b3f66b PC |
78 | _ExtPtr_allocator(const _ExtPtr_allocator<_Up>& __rarg) throw() |
79 | : _M_real_alloc(__rarg._M_getUnderlyingImp()) { } | |
80 | ||
81 | ~_ExtPtr_allocator() throw() | |
82 | { } | |
83 | ||
84 | pointer address(reference __x) const | |
85 | { return &__x; } | |
86 | ||
87 | const_pointer address(const_reference __x) const | |
88 | { return &__x; } | |
89 | ||
90 | pointer allocate(size_type __n, void* __hint = 0) | |
91 | { return _M_real_alloc.allocate(__n,__hint); } | |
92 | ||
93 | void deallocate(pointer __p, size_type __n) | |
94 | { _M_real_alloc.deallocate(__p.get(), __n); } | |
95 | ||
96 | size_type max_size() const throw() | |
97 | { return std::numeric_limits<size_type>::max() / sizeof(_Tp); } | |
98 | ||
99 | void construct(pointer __p, const _Tp& __val) | |
100 | { ::new(__p.get()) _Tp(__val); } | |
101 | ||
102 | #ifdef __GXX_EXPERIMENTAL_CXX0X__ | |
103 | template<typename... _Args> | |
104 | void | |
105 | construct(pointer __p, _Args&&... __args) | |
106 | { ::new(__p.get()) _Tp(std::forward<_Args>(__args)...); } | |
107 | #endif | |
108 | ||
109 | void destroy(pointer __p) | |
110 | { __p->~_Tp(); } | |
111 | ||
112 | template<typename _Up> | |
113 | inline bool | |
114 | operator==(const _ExtPtr_allocator<_Up>& __rarg) | |
115 | { return _M_real_alloc == __rarg._M_getUnderlyingImp(); } | |
116 | ||
117 | inline bool | |
118 | operator==(const _ExtPtr_allocator& __rarg) | |
119 | { return _M_real_alloc == __rarg._M_real_alloc; } | |
120 | ||
121 | template<typename _Up> | |
122 | inline bool | |
123 | operator!=(const _ExtPtr_allocator<_Up>& __rarg) | |
124 | { return _M_real_alloc != __rarg._M_getUnderlyingImp(); } | |
125 | ||
126 | inline bool | |
127 | operator!=(const _ExtPtr_allocator& __rarg) | |
128 | { return _M_real_alloc != __rarg._M_real_alloc; } | |
129 | ||
130 | template<typename _Up> | |
131 | inline friend void | |
8d8a4e9d | 132 | swap(_ExtPtr_allocator<_Up>&, _ExtPtr_allocator<_Up>&); |
b5b3f66b PC |
133 | |
134 | // A method specific to this implementation. | |
135 | const std::allocator<_Tp>& | |
136 | _M_getUnderlyingImp() const | |
137 | { return _M_real_alloc; } | |
138 | ||
139 | private: | |
b5b3f66b PC |
140 | std::allocator<_Tp> _M_real_alloc; |
141 | }; | |
142 | ||
8d8a4e9d PC |
143 | // _ExtPtr_allocator<void> specialization. |
144 | template<> | |
145 | class _ExtPtr_allocator<void> | |
146 | { | |
147 | public: | |
148 | typedef std::size_t size_type; | |
149 | typedef std::ptrdiff_t difference_type; | |
150 | typedef void value_type; | |
151 | ||
152 | // Note the non-standard pointer types | |
153 | typedef _Pointer_adapter<_Relative_pointer_impl<void> > pointer; | |
154 | typedef _Pointer_adapter<_Relative_pointer_impl<const void> > | |
155 | const_pointer; | |
156 | ||
157 | template<typename _Up> | |
158 | struct rebind | |
159 | { typedef _ExtPtr_allocator<_Up> other; }; | |
160 | ||
161 | private: | |
162 | std::allocator<void> _M_real_alloc; | |
163 | }; | |
164 | ||
b5b3f66b PC |
165 | template<typename _Tp> |
166 | inline void | |
167 | swap(_ExtPtr_allocator<_Tp>& __larg, _ExtPtr_allocator<_Tp>& __rarg) | |
168 | { | |
8d8a4e9d | 169 | std::allocator<_Tp> __tmp( __rarg._M_real_alloc ); |
b5b3f66b | 170 | __rarg._M_real_alloc = __larg._M_real_alloc; |
8d8a4e9d | 171 | __larg._M_real_alloc = __tmp; |
b5b3f66b PC |
172 | } |
173 | ||
174 | _GLIBCXX_END_NAMESPACE | |
175 | ||
176 | #endif /* _EXTPTR_ALLOCATOR_H */ |