libstdc++
ext/alloc_traits.h
Go to the documentation of this file.
1 // Allocator traits -*- C++ -*-
2 
3 // Copyright (C) 2011, 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
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 3, or (at your option)
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 
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 /** @file ext/alloc_traits.h
26  * This file is a GNU extension to the Standard C++ Library.
27  */
28 
29 #ifndef _EXT_ALLOC_TRAITS_H
30 #define _EXT_ALLOC_TRAITS_H 1
31 
32 #pragma GCC system_header
33 
34 #ifdef __GXX_EXPERIMENTAL_CXX0X__
35 # include <bits/alloc_traits.h>
36 #else
37 # include <bits/allocator.h> // for __alloc_swap
38 #endif
39 
40 namespace std _GLIBCXX_VISIBILITY(default)
41 {
42 _GLIBCXX_BEGIN_NAMESPACE_VERSION
43  template<typename> struct allocator;
44 _GLIBCXX_END_NAMESPACE_VERSION
45 } // namespace
46 
47 namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
48 {
49 _GLIBCXX_BEGIN_NAMESPACE_VERSION
50 
51 #ifdef __GXX_EXPERIMENTAL_CXX0X__
52  template<typename _Alloc>
53  struct __allocator_always_compares_equal
54  { static const bool value = false; };
55 
56  template<typename _Alloc>
57  const bool __allocator_always_compares_equal<_Alloc>::value;
58 
59  template<typename _Tp>
60  struct __allocator_always_compares_equal<std::allocator<_Tp>>
61  { static const bool value = true; };
62 
63  template<typename _Tp>
64  const bool __allocator_always_compares_equal<std::allocator<_Tp>>::value;
65 
66  template<typename, typename> struct array_allocator;
67 
68  template<typename _Tp, typename _Array>
69  struct __allocator_always_compares_equal<array_allocator<_Tp, _Array>>
70  { static const bool value = true; };
71 
72  template<typename _Tp, typename _Array>
73  const bool
74  __allocator_always_compares_equal<array_allocator<_Tp, _Array>>::value;
75 
76  template<typename> struct mt_allocator;
77 
78  template<typename _Tp>
79  struct __allocator_always_compares_equal<mt_allocator<_Tp>>
80  { static const bool value = true; };
81 
82  template<typename _Tp>
83  const bool __allocator_always_compares_equal<mt_allocator<_Tp>>::value;
84 
85  template<typename> struct new_allocator;
86 
87  template<typename _Tp>
88  struct __allocator_always_compares_equal<new_allocator<_Tp>>
89  { static const bool value = true; };
90 
91  template<typename _Tp>
92  const bool __allocator_always_compares_equal<new_allocator<_Tp>>::value;
93 
94  template<typename> struct pool_allocator;
95 
96  template<typename _Tp>
97  struct __allocator_always_compares_equal<pool_allocator<_Tp>>
98  { static const bool value = true; };
99 
100  template<typename _Tp>
101  const bool __allocator_always_compares_equal<pool_allocator<_Tp>>::value;
102 #endif
103 
104 /**
105  * @brief Uniform interface to C++98 and C++0x allocators.
106  * @ingroup allocators
107 */
108 template<typename _Alloc>
110 #ifdef __GXX_EXPERIMENTAL_CXX0X__
111  : std::allocator_traits<_Alloc>
112 #endif
113  {
114  typedef _Alloc allocator_type;
115 #ifdef __GXX_EXPERIMENTAL_CXX0X__
118  typedef typename _Base_type::pointer pointer;
121  // C++0x allocators do not define reference or const_reference
122  typedef value_type& reference;
123  typedef const value_type& const_reference;
124  using _Base_type::allocate;
126  using _Base_type::construct;
127  using _Base_type::destroy;
128  using _Base_type::max_size;
129 
130  private:
131  template<typename _Ptr>
132  struct __is_custom_pointer
133  : std::integral_constant<bool, std::is_same<pointer, _Ptr>::value
134  && !std::is_pointer<_Ptr>::value>
135  { };
136 
137  public:
138  // overload construct for non-standard pointer types
139  template<typename _Ptr, typename... _Args>
141  construct(_Alloc& __a, _Ptr __p, _Args&&... __args)
142  {
144  std::forward<_Args>(__args)...);
145  }
146 
147  // overload destroy for non-standard pointer types
148  template<typename _Ptr>
150  destroy(_Alloc& __a, _Ptr __p)
151  { _Base_type::destroy(__a, std::addressof(*__p)); }
152 
153  static _Alloc _S_select_on_copy(const _Alloc& __a)
155 
156  static void _S_on_swap(_Alloc& __a, _Alloc& __b)
157  { std::__alloc_on_swap(__a, __b); }
158 
159  static constexpr bool _S_propagate_on_copy_assign()
160  { return _Base_type::propagate_on_container_copy_assignment::value; }
161 
162  static constexpr bool _S_propagate_on_move_assign()
163  { return _Base_type::propagate_on_container_move_assignment::value; }
164 
165  static constexpr bool _S_propagate_on_swap()
166  { return _Base_type::propagate_on_container_swap::value; }
167 
168  static constexpr bool _S_always_equal()
169  { return __allocator_always_compares_equal<_Alloc>::value; }
170 
171  static constexpr bool _S_nothrow_move()
172  { return _S_propagate_on_move_assign() || _S_always_equal(); }
173 
174  static constexpr bool _S_nothrow_swap()
175  {
176  using std::swap;
177  return !_S_propagate_on_swap()
178  || noexcept(swap(std::declval<_Alloc&>(), std::declval<_Alloc&>()));
179  }
180 
181  template<typename _Tp>
182  struct rebind
183  { typedef typename _Base_type::template rebind_alloc<_Tp> other; };
184 #else
185 
186  typedef typename _Alloc::pointer pointer;
187  typedef typename _Alloc::const_pointer const_pointer;
188  typedef typename _Alloc::value_type value_type;
189  typedef typename _Alloc::reference reference;
190  typedef typename _Alloc::const_reference const_reference;
191  typedef typename _Alloc::size_type size_type;
192 
193  static pointer
194  allocate(_Alloc& __a, size_type __n)
195  { return __a.allocate(__n); }
196 
197  static void deallocate(_Alloc& __a, pointer __p, size_type __n)
198  { __a.deallocate(__p, __n); }
199 
200  template<typename _Tp>
201  static void construct(_Alloc& __a, pointer __p, const _Tp& __arg)
202  { __a.construct(__p, __arg); }
203 
204  static void destroy(_Alloc& __a, pointer __p)
205  { __a.destroy(__p); }
206 
207  static size_type max_size(const _Alloc& __a)
208  { return __a.max_size(); }
209 
210  static const _Alloc& _S_select_on_copy(const _Alloc& __a) { return __a; }
211 
212  static void _S_on_swap(_Alloc& __a, _Alloc& __b)
213  {
214  // _GLIBCXX_RESOLVE_LIB_DEFECTS
215  // 431. Swapping containers with unequal allocators.
216  std::__alloc_swap<_Alloc>::_S_do_it(__a, __b);
217  }
218 
219  template<typename _Tp>
220  struct rebind
221  { typedef typename _Alloc::template rebind<_Tp>::other other; };
222 #endif
223  };
224 
225 _GLIBCXX_END_NAMESPACE_VERSION
226 } // namespace
227 
228 #endif