xref: /dflybsd-src/contrib/gcc-8.0/libstdc++-v3/include/bits/alloc_traits.h (revision 38fd149817dfbff97799f62fcb70be98c4e32523)
1*38fd1498Szrj // Allocator traits -*- C++ -*-
2*38fd1498Szrj 
3*38fd1498Szrj // Copyright (C) 2011-2018 Free Software Foundation, Inc.
4*38fd1498Szrj //
5*38fd1498Szrj // This file is part of the GNU ISO C++ Library.  This library is free
6*38fd1498Szrj // software; you can redistribute it and/or modify it under the
7*38fd1498Szrj // terms of the GNU General Public License as published by the
8*38fd1498Szrj // Free Software Foundation; either version 3, or (at your option)
9*38fd1498Szrj // any later version.
10*38fd1498Szrj 
11*38fd1498Szrj // This library is distributed in the hope that it will be useful,
12*38fd1498Szrj // but WITHOUT ANY WARRANTY; without even the implied warranty of
13*38fd1498Szrj // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14*38fd1498Szrj // GNU General Public License for more details.
15*38fd1498Szrj 
16*38fd1498Szrj // Under Section 7 of GPL version 3, you are granted additional
17*38fd1498Szrj // permissions described in the GCC Runtime Library Exception, version
18*38fd1498Szrj // 3.1, as published by the Free Software Foundation.
19*38fd1498Szrj 
20*38fd1498Szrj // You should have received a copy of the GNU General Public License and
21*38fd1498Szrj // a copy of the GCC Runtime Library Exception along with this program;
22*38fd1498Szrj // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23*38fd1498Szrj // <http://www.gnu.org/licenses/>.
24*38fd1498Szrj 
25*38fd1498Szrj /** @file bits/alloc_traits.h
26*38fd1498Szrj  *  This is an internal header file, included by other library headers.
27*38fd1498Szrj  *  Do not attempt to use it directly. @headername{memory}
28*38fd1498Szrj  */
29*38fd1498Szrj 
30*38fd1498Szrj #ifndef _ALLOC_TRAITS_H
31*38fd1498Szrj #define _ALLOC_TRAITS_H 1
32*38fd1498Szrj 
33*38fd1498Szrj #if __cplusplus >= 201103L
34*38fd1498Szrj 
35*38fd1498Szrj #include <bits/memoryfwd.h>
36*38fd1498Szrj #include <bits/ptr_traits.h>
37*38fd1498Szrj #include <ext/numeric_traits.h>
38*38fd1498Szrj 
39*38fd1498Szrj #define __cpp_lib_allocator_traits_is_always_equal 201411
40*38fd1498Szrj 
41*38fd1498Szrj namespace std _GLIBCXX_VISIBILITY(default)
42*38fd1498Szrj {
43*38fd1498Szrj _GLIBCXX_BEGIN_NAMESPACE_VERSION
44*38fd1498Szrj 
45*38fd1498Szrj   struct __allocator_traits_base
46*38fd1498Szrj   {
47*38fd1498Szrj     template<typename _Tp, typename _Up, typename = void>
48*38fd1498Szrj       struct __rebind : __replace_first_arg<_Tp, _Up> { };
49*38fd1498Szrj 
50*38fd1498Szrj     template<typename _Tp, typename _Up>
51*38fd1498Szrj       struct __rebind<_Tp, _Up,
52*38fd1498Szrj 		      __void_t<typename _Tp::template rebind<_Up>::other>>
53*38fd1498Szrj       { using type = typename _Tp::template rebind<_Up>::other; };
54*38fd1498Szrj 
55*38fd1498Szrj   protected:
56*38fd1498Szrj     template<typename _Tp>
57*38fd1498Szrj       using __pointer = typename _Tp::pointer;
58*38fd1498Szrj     template<typename _Tp>
59*38fd1498Szrj       using __c_pointer = typename _Tp::const_pointer;
60*38fd1498Szrj     template<typename _Tp>
61*38fd1498Szrj       using __v_pointer = typename _Tp::void_pointer;
62*38fd1498Szrj     template<typename _Tp>
63*38fd1498Szrj       using __cv_pointer = typename _Tp::const_void_pointer;
64*38fd1498Szrj     template<typename _Tp>
65*38fd1498Szrj       using __pocca = typename _Tp::propagate_on_container_copy_assignment;
66*38fd1498Szrj     template<typename _Tp>
67*38fd1498Szrj       using __pocma = typename _Tp::propagate_on_container_move_assignment;
68*38fd1498Szrj     template<typename _Tp>
69*38fd1498Szrj       using __pocs = typename _Tp::propagate_on_container_swap;
70*38fd1498Szrj     template<typename _Tp>
71*38fd1498Szrj       using __equal = typename _Tp::is_always_equal;
72*38fd1498Szrj   };
73*38fd1498Szrj 
74*38fd1498Szrj   template<typename _Alloc, typename _Up>
75*38fd1498Szrj     using __alloc_rebind
76*38fd1498Szrj       = typename __allocator_traits_base::template __rebind<_Alloc, _Up>::type;
77*38fd1498Szrj 
78*38fd1498Szrj   /**
79*38fd1498Szrj    * @brief  Uniform interface to all allocator types.
80*38fd1498Szrj    * @ingroup allocators
81*38fd1498Szrj   */
82*38fd1498Szrj   template<typename _Alloc>
83*38fd1498Szrj     struct allocator_traits : __allocator_traits_base
84*38fd1498Szrj     {
85*38fd1498Szrj       /// The allocator type
86*38fd1498Szrj       typedef _Alloc allocator_type;
87*38fd1498Szrj       /// The allocated type
88*38fd1498Szrj       typedef typename _Alloc::value_type value_type;
89*38fd1498Szrj 
90*38fd1498Szrj       /**
91*38fd1498Szrj        * @brief   The allocator's pointer type.
92*38fd1498Szrj        *
93*38fd1498Szrj        * @c Alloc::pointer if that type exists, otherwise @c value_type*
94*38fd1498Szrj       */
95*38fd1498Szrj       using pointer = __detected_or_t<value_type*, __pointer, _Alloc>;
96*38fd1498Szrj 
97*38fd1498Szrj     private:
98*38fd1498Szrj       // Select _Func<_Alloc> or pointer_traits<pointer>::rebind<_Tp>
99*38fd1498Szrj       template<template<typename> class _Func, typename _Tp, typename = void>
100*38fd1498Szrj 	struct _Ptr
101*38fd1498Szrj 	{
102*38fd1498Szrj 	  using type = typename pointer_traits<pointer>::template rebind<_Tp>;
103*38fd1498Szrj 	};
104*38fd1498Szrj 
105*38fd1498Szrj       template<template<typename> class _Func, typename _Tp>
106*38fd1498Szrj 	struct _Ptr<_Func, _Tp, __void_t<_Func<_Alloc>>>
107*38fd1498Szrj 	{
108*38fd1498Szrj 	  using type = _Func<_Alloc>;
109*38fd1498Szrj 	};
110*38fd1498Szrj 
111*38fd1498Szrj       // Select _A2::difference_type or pointer_traits<_Ptr>::difference_type
112*38fd1498Szrj       template<typename _A2, typename _PtrT, typename = void>
113*38fd1498Szrj 	struct _Diff
114*38fd1498Szrj 	{ using type = typename pointer_traits<_PtrT>::difference_type; };
115*38fd1498Szrj 
116*38fd1498Szrj       template<typename _A2, typename _PtrT>
117*38fd1498Szrj 	struct _Diff<_A2, _PtrT, __void_t<typename _A2::difference_type>>
118*38fd1498Szrj 	{ using type = typename _A2::difference_type; };
119*38fd1498Szrj 
120*38fd1498Szrj       // Select _A2::size_type or make_unsigned<_DiffT>::type
121*38fd1498Szrj       template<typename _A2, typename _DiffT, typename = void>
122*38fd1498Szrj 	struct _Size : make_unsigned<_DiffT> { };
123*38fd1498Szrj 
124*38fd1498Szrj       template<typename _A2, typename _DiffT>
125*38fd1498Szrj 	struct _Size<_A2, _DiffT, __void_t<typename _A2::size_type>>
126*38fd1498Szrj 	{ using type = typename _A2::size_type; };
127*38fd1498Szrj 
128*38fd1498Szrj     public:
129*38fd1498Szrj       /**
130*38fd1498Szrj        * @brief   The allocator's const pointer type.
131*38fd1498Szrj        *
132*38fd1498Szrj        * @c Alloc::const_pointer if that type exists, otherwise
133*38fd1498Szrj        * <tt> pointer_traits<pointer>::rebind<const value_type> </tt>
134*38fd1498Szrj       */
135*38fd1498Szrj       using const_pointer = typename _Ptr<__c_pointer, const value_type>::type;
136*38fd1498Szrj 
137*38fd1498Szrj       /**
138*38fd1498Szrj        * @brief   The allocator's void pointer type.
139*38fd1498Szrj        *
140*38fd1498Szrj        * @c Alloc::void_pointer if that type exists, otherwise
141*38fd1498Szrj        * <tt> pointer_traits<pointer>::rebind<void> </tt>
142*38fd1498Szrj       */
143*38fd1498Szrj       using void_pointer = typename _Ptr<__v_pointer, void>::type;
144*38fd1498Szrj 
145*38fd1498Szrj       /**
146*38fd1498Szrj        * @brief   The allocator's const void pointer type.
147*38fd1498Szrj        *
148*38fd1498Szrj        * @c Alloc::const_void_pointer if that type exists, otherwise
149*38fd1498Szrj        * <tt> pointer_traits<pointer>::rebind<const void> </tt>
150*38fd1498Szrj       */
151*38fd1498Szrj       using const_void_pointer = typename _Ptr<__cv_pointer, const void>::type;
152*38fd1498Szrj 
153*38fd1498Szrj       /**
154*38fd1498Szrj        * @brief   The allocator's difference type
155*38fd1498Szrj        *
156*38fd1498Szrj        * @c Alloc::difference_type if that type exists, otherwise
157*38fd1498Szrj        * <tt> pointer_traits<pointer>::difference_type </tt>
158*38fd1498Szrj       */
159*38fd1498Szrj       using difference_type = typename _Diff<_Alloc, pointer>::type;
160*38fd1498Szrj 
161*38fd1498Szrj       /**
162*38fd1498Szrj        * @brief   The allocator's size type
163*38fd1498Szrj        *
164*38fd1498Szrj        * @c Alloc::size_type if that type exists, otherwise
165*38fd1498Szrj        * <tt> make_unsigned<difference_type>::type </tt>
166*38fd1498Szrj       */
167*38fd1498Szrj       using size_type = typename _Size<_Alloc, difference_type>::type;
168*38fd1498Szrj 
169*38fd1498Szrj       /**
170*38fd1498Szrj        * @brief   How the allocator is propagated on copy assignment
171*38fd1498Szrj        *
172*38fd1498Szrj        * @c Alloc::propagate_on_container_copy_assignment if that type exists,
173*38fd1498Szrj        * otherwise @c false_type
174*38fd1498Szrj       */
175*38fd1498Szrj       using propagate_on_container_copy_assignment
176*38fd1498Szrj 	= __detected_or_t<false_type, __pocca, _Alloc>;
177*38fd1498Szrj 
178*38fd1498Szrj       /**
179*38fd1498Szrj        * @brief   How the allocator is propagated on move assignment
180*38fd1498Szrj        *
181*38fd1498Szrj        * @c Alloc::propagate_on_container_move_assignment if that type exists,
182*38fd1498Szrj        * otherwise @c false_type
183*38fd1498Szrj       */
184*38fd1498Szrj       using propagate_on_container_move_assignment
185*38fd1498Szrj 	= __detected_or_t<false_type, __pocma, _Alloc>;
186*38fd1498Szrj 
187*38fd1498Szrj       /**
188*38fd1498Szrj        * @brief   How the allocator is propagated on swap
189*38fd1498Szrj        *
190*38fd1498Szrj        * @c Alloc::propagate_on_container_swap if that type exists,
191*38fd1498Szrj        * otherwise @c false_type
192*38fd1498Szrj       */
193*38fd1498Szrj       using propagate_on_container_swap
194*38fd1498Szrj 	= __detected_or_t<false_type, __pocs, _Alloc>;
195*38fd1498Szrj 
196*38fd1498Szrj       /**
197*38fd1498Szrj        * @brief   Whether all instances of the allocator type compare equal.
198*38fd1498Szrj        *
199*38fd1498Szrj        * @c Alloc::is_always_equal if that type exists,
200*38fd1498Szrj        * otherwise @c is_empty<Alloc>::type
201*38fd1498Szrj       */
202*38fd1498Szrj       using is_always_equal
203*38fd1498Szrj 	= __detected_or_t<typename is_empty<_Alloc>::type, __equal, _Alloc>;
204*38fd1498Szrj 
205*38fd1498Szrj       template<typename _Tp>
206*38fd1498Szrj 	using rebind_alloc = __alloc_rebind<_Alloc, _Tp>;
207*38fd1498Szrj       template<typename _Tp>
208*38fd1498Szrj 	using rebind_traits = allocator_traits<rebind_alloc<_Tp>>;
209*38fd1498Szrj 
210*38fd1498Szrj     private:
211*38fd1498Szrj       template<typename _Alloc2>
212*38fd1498Szrj 	static auto
213*38fd1498Szrj 	_S_allocate(_Alloc2& __a, size_type __n, const_void_pointer __hint, int)
214*38fd1498Szrj 	-> decltype(__a.allocate(__n, __hint))
215*38fd1498Szrj 	{ return __a.allocate(__n, __hint); }
216*38fd1498Szrj 
217*38fd1498Szrj       template<typename _Alloc2>
218*38fd1498Szrj 	static pointer
219*38fd1498Szrj 	_S_allocate(_Alloc2& __a, size_type __n, const_void_pointer, ...)
220*38fd1498Szrj 	{ return __a.allocate(__n); }
221*38fd1498Szrj 
222*38fd1498Szrj       template<typename _Tp, typename... _Args>
223*38fd1498Szrj 	struct __construct_helper
224*38fd1498Szrj 	{
225*38fd1498Szrj 	  template<typename _Alloc2,
226*38fd1498Szrj 	    typename = decltype(std::declval<_Alloc2*>()->construct(
227*38fd1498Szrj 		  std::declval<_Tp*>(), std::declval<_Args>()...))>
228*38fd1498Szrj 	    static true_type __test(int);
229*38fd1498Szrj 
230*38fd1498Szrj 	  template<typename>
231*38fd1498Szrj 	    static false_type __test(...);
232*38fd1498Szrj 
233*38fd1498Szrj 	  using type = decltype(__test<_Alloc>(0));
234*38fd1498Szrj 	};
235*38fd1498Szrj 
236*38fd1498Szrj       template<typename _Tp, typename... _Args>
237*38fd1498Szrj 	using __has_construct
238*38fd1498Szrj 	  = typename __construct_helper<_Tp, _Args...>::type;
239*38fd1498Szrj 
240*38fd1498Szrj       template<typename _Tp, typename... _Args>
241*38fd1498Szrj 	static _Require<__has_construct<_Tp, _Args...>>
242*38fd1498Szrj 	_S_construct(_Alloc& __a, _Tp* __p, _Args&&... __args)
243*38fd1498Szrj 	{ __a.construct(__p, std::forward<_Args>(__args)...); }
244*38fd1498Szrj 
245*38fd1498Szrj       template<typename _Tp, typename... _Args>
246*38fd1498Szrj 	static
247*38fd1498Szrj 	_Require<__and_<__not_<__has_construct<_Tp, _Args...>>,
248*38fd1498Szrj 			       is_constructible<_Tp, _Args...>>>
249*38fd1498Szrj 	_S_construct(_Alloc&, _Tp* __p, _Args&&... __args)
250*38fd1498Szrj 	{ ::new((void*)__p) _Tp(std::forward<_Args>(__args)...); }
251*38fd1498Szrj 
252*38fd1498Szrj       template<typename _Alloc2, typename _Tp>
253*38fd1498Szrj 	static auto
254*38fd1498Szrj 	_S_destroy(_Alloc2& __a, _Tp* __p, int)
255*38fd1498Szrj 	-> decltype(__a.destroy(__p))
256*38fd1498Szrj 	{ __a.destroy(__p); }
257*38fd1498Szrj 
258*38fd1498Szrj       template<typename _Alloc2, typename _Tp>
259*38fd1498Szrj 	static void
260*38fd1498Szrj 	_S_destroy(_Alloc2&, _Tp* __p, ...)
261*38fd1498Szrj 	{ __p->~_Tp(); }
262*38fd1498Szrj 
263*38fd1498Szrj       template<typename _Alloc2>
264*38fd1498Szrj 	static auto
265*38fd1498Szrj 	_S_max_size(_Alloc2& __a, int)
266*38fd1498Szrj 	-> decltype(__a.max_size())
267*38fd1498Szrj 	{ return __a.max_size(); }
268*38fd1498Szrj 
269*38fd1498Szrj       template<typename _Alloc2>
270*38fd1498Szrj 	static size_type
271*38fd1498Szrj 	_S_max_size(_Alloc2&, ...)
272*38fd1498Szrj 	{
273*38fd1498Szrj 	  // _GLIBCXX_RESOLVE_LIB_DEFECTS
274*38fd1498Szrj 	  // 2466. allocator_traits::max_size() default behavior is incorrect
275*38fd1498Szrj 	  return __gnu_cxx::__numeric_traits<size_type>::__max
276*38fd1498Szrj 	    / sizeof(value_type);
277*38fd1498Szrj 	}
278*38fd1498Szrj 
279*38fd1498Szrj       template<typename _Alloc2>
280*38fd1498Szrj 	static auto
281*38fd1498Szrj 	_S_select(_Alloc2& __a, int)
282*38fd1498Szrj 	-> decltype(__a.select_on_container_copy_construction())
283*38fd1498Szrj 	{ return __a.select_on_container_copy_construction(); }
284*38fd1498Szrj 
285*38fd1498Szrj       template<typename _Alloc2>
286*38fd1498Szrj 	static _Alloc2
287*38fd1498Szrj 	_S_select(_Alloc2& __a, ...)
288*38fd1498Szrj 	{ return __a; }
289*38fd1498Szrj 
290*38fd1498Szrj     public:
291*38fd1498Szrj 
292*38fd1498Szrj       /**
293*38fd1498Szrj        *  @brief  Allocate memory.
294*38fd1498Szrj        *  @param  __a  An allocator.
295*38fd1498Szrj        *  @param  __n  The number of objects to allocate space for.
296*38fd1498Szrj        *
297*38fd1498Szrj        *  Calls @c a.allocate(n)
298*38fd1498Szrj       */
299*38fd1498Szrj       static pointer
300*38fd1498Szrj       allocate(_Alloc& __a, size_type __n)
301*38fd1498Szrj       { return __a.allocate(__n); }
302*38fd1498Szrj 
303*38fd1498Szrj       /**
304*38fd1498Szrj        *  @brief  Allocate memory.
305*38fd1498Szrj        *  @param  __a  An allocator.
306*38fd1498Szrj        *  @param  __n  The number of objects to allocate space for.
307*38fd1498Szrj        *  @param  __hint Aid to locality.
308*38fd1498Szrj        *  @return Memory of suitable size and alignment for @a n objects
309*38fd1498Szrj        *          of type @c value_type
310*38fd1498Szrj        *
311*38fd1498Szrj        *  Returns <tt> a.allocate(n, hint) </tt> if that expression is
312*38fd1498Szrj        *  well-formed, otherwise returns @c a.allocate(n)
313*38fd1498Szrj       */
314*38fd1498Szrj       static pointer
315*38fd1498Szrj       allocate(_Alloc& __a, size_type __n, const_void_pointer __hint)
316*38fd1498Szrj       { return _S_allocate(__a, __n, __hint, 0); }
317*38fd1498Szrj 
318*38fd1498Szrj       /**
319*38fd1498Szrj        *  @brief  Deallocate memory.
320*38fd1498Szrj        *  @param  __a  An allocator.
321*38fd1498Szrj        *  @param  __p  Pointer to the memory to deallocate.
322*38fd1498Szrj        *  @param  __n  The number of objects space was allocated for.
323*38fd1498Szrj        *
324*38fd1498Szrj        *  Calls <tt> a.deallocate(p, n) </tt>
325*38fd1498Szrj       */
326*38fd1498Szrj       static void
327*38fd1498Szrj       deallocate(_Alloc& __a, pointer __p, size_type __n)
328*38fd1498Szrj       { __a.deallocate(__p, __n); }
329*38fd1498Szrj 
330*38fd1498Szrj       /**
331*38fd1498Szrj        *  @brief  Construct an object of type @a _Tp
332*38fd1498Szrj        *  @param  __a  An allocator.
333*38fd1498Szrj        *  @param  __p  Pointer to memory of suitable size and alignment for Tp
334*38fd1498Szrj        *  @param  __args Constructor arguments.
335*38fd1498Szrj        *
336*38fd1498Szrj        *  Calls <tt> __a.construct(__p, std::forward<Args>(__args)...) </tt>
337*38fd1498Szrj        *  if that expression is well-formed, otherwise uses placement-new
338*38fd1498Szrj        *  to construct an object of type @a _Tp at location @a __p from the
339*38fd1498Szrj        *  arguments @a __args...
340*38fd1498Szrj       */
341*38fd1498Szrj       template<typename _Tp, typename... _Args>
342*38fd1498Szrj 	static auto construct(_Alloc& __a, _Tp* __p, _Args&&... __args)
343*38fd1498Szrj 	-> decltype(_S_construct(__a, __p, std::forward<_Args>(__args)...))
344*38fd1498Szrj 	{ _S_construct(__a, __p, std::forward<_Args>(__args)...); }
345*38fd1498Szrj 
346*38fd1498Szrj       /**
347*38fd1498Szrj        *  @brief  Destroy an object of type @a _Tp
348*38fd1498Szrj        *  @param  __a  An allocator.
349*38fd1498Szrj        *  @param  __p  Pointer to the object to destroy
350*38fd1498Szrj        *
351*38fd1498Szrj        *  Calls @c __a.destroy(__p) if that expression is well-formed,
352*38fd1498Szrj        *  otherwise calls @c __p->~_Tp()
353*38fd1498Szrj       */
354*38fd1498Szrj       template<typename _Tp>
355*38fd1498Szrj 	static void destroy(_Alloc& __a, _Tp* __p)
356*38fd1498Szrj 	{ _S_destroy(__a, __p, 0); }
357*38fd1498Szrj 
358*38fd1498Szrj       /**
359*38fd1498Szrj        *  @brief  The maximum supported allocation size
360*38fd1498Szrj        *  @param  __a  An allocator.
361*38fd1498Szrj        *  @return @c __a.max_size() or @c numeric_limits<size_type>::max()
362*38fd1498Szrj        *
363*38fd1498Szrj        *  Returns @c __a.max_size() if that expression is well-formed,
364*38fd1498Szrj        *  otherwise returns @c numeric_limits<size_type>::max()
365*38fd1498Szrj       */
366*38fd1498Szrj       static size_type max_size(const _Alloc& __a) noexcept
367*38fd1498Szrj       { return _S_max_size(__a, 0); }
368*38fd1498Szrj 
369*38fd1498Szrj       /**
370*38fd1498Szrj        *  @brief  Obtain an allocator to use when copying a container.
371*38fd1498Szrj        *  @param  __rhs  An allocator.
372*38fd1498Szrj        *  @return @c __rhs.select_on_container_copy_construction() or @a __rhs
373*38fd1498Szrj        *
374*38fd1498Szrj        *  Returns @c __rhs.select_on_container_copy_construction() if that
375*38fd1498Szrj        *  expression is well-formed, otherwise returns @a __rhs
376*38fd1498Szrj       */
377*38fd1498Szrj       static _Alloc
378*38fd1498Szrj       select_on_container_copy_construction(const _Alloc& __rhs)
379*38fd1498Szrj       { return _S_select(__rhs, 0); }
380*38fd1498Szrj     };
381*38fd1498Szrj 
382*38fd1498Szrj   /// Partial specialization for std::allocator.
383*38fd1498Szrj   template<typename _Tp>
384*38fd1498Szrj     struct allocator_traits<allocator<_Tp>>
385*38fd1498Szrj     {
386*38fd1498Szrj       /// The allocator type
387*38fd1498Szrj       using allocator_type = allocator<_Tp>;
388*38fd1498Szrj       /// The allocated type
389*38fd1498Szrj       using value_type = _Tp;
390*38fd1498Szrj 
391*38fd1498Szrj       /// The allocator's pointer type.
392*38fd1498Szrj       using pointer = _Tp*;
393*38fd1498Szrj 
394*38fd1498Szrj       /// The allocator's const pointer type.
395*38fd1498Szrj       using const_pointer = const _Tp*;
396*38fd1498Szrj 
397*38fd1498Szrj       /// The allocator's void pointer type.
398*38fd1498Szrj       using void_pointer = void*;
399*38fd1498Szrj 
400*38fd1498Szrj       /// The allocator's const void pointer type.
401*38fd1498Szrj       using const_void_pointer = const void*;
402*38fd1498Szrj 
403*38fd1498Szrj       /// The allocator's difference type
404*38fd1498Szrj       using difference_type = std::ptrdiff_t;
405*38fd1498Szrj 
406*38fd1498Szrj       /// The allocator's size type
407*38fd1498Szrj       using size_type = std::size_t;
408*38fd1498Szrj 
409*38fd1498Szrj       /// How the allocator is propagated on copy assignment
410*38fd1498Szrj       using propagate_on_container_copy_assignment = false_type;
411*38fd1498Szrj 
412*38fd1498Szrj       /// How the allocator is propagated on move assignment
413*38fd1498Szrj       using propagate_on_container_move_assignment = true_type;
414*38fd1498Szrj 
415*38fd1498Szrj       /// How the allocator is propagated on swap
416*38fd1498Szrj       using propagate_on_container_swap = false_type;
417*38fd1498Szrj 
418*38fd1498Szrj       /// Whether all instances of the allocator type compare equal.
419*38fd1498Szrj       using is_always_equal = true_type;
420*38fd1498Szrj 
421*38fd1498Szrj       template<typename _Up>
422*38fd1498Szrj 	using rebind_alloc = allocator<_Up>;
423*38fd1498Szrj 
424*38fd1498Szrj       template<typename _Up>
425*38fd1498Szrj 	using rebind_traits = allocator_traits<allocator<_Up>>;
426*38fd1498Szrj 
427*38fd1498Szrj       /**
428*38fd1498Szrj        *  @brief  Allocate memory.
429*38fd1498Szrj        *  @param  __a  An allocator.
430*38fd1498Szrj        *  @param  __n  The number of objects to allocate space for.
431*38fd1498Szrj        *
432*38fd1498Szrj        *  Calls @c a.allocate(n)
433*38fd1498Szrj       */
434*38fd1498Szrj       static pointer
435*38fd1498Szrj       allocate(allocator_type& __a, size_type __n)
436*38fd1498Szrj       { return __a.allocate(__n); }
437*38fd1498Szrj 
438*38fd1498Szrj       /**
439*38fd1498Szrj        *  @brief  Allocate memory.
440*38fd1498Szrj        *  @param  __a  An allocator.
441*38fd1498Szrj        *  @param  __n  The number of objects to allocate space for.
442*38fd1498Szrj        *  @param  __hint Aid to locality.
443*38fd1498Szrj        *  @return Memory of suitable size and alignment for @a n objects
444*38fd1498Szrj        *          of type @c value_type
445*38fd1498Szrj        *
446*38fd1498Szrj        *  Returns <tt> a.allocate(n, hint) </tt>
447*38fd1498Szrj       */
448*38fd1498Szrj       static pointer
449*38fd1498Szrj       allocate(allocator_type& __a, size_type __n, const_void_pointer __hint)
450*38fd1498Szrj       { return __a.allocate(__n, __hint); }
451*38fd1498Szrj 
452*38fd1498Szrj       /**
453*38fd1498Szrj        *  @brief  Deallocate memory.
454*38fd1498Szrj        *  @param  __a  An allocator.
455*38fd1498Szrj        *  @param  __p  Pointer to the memory to deallocate.
456*38fd1498Szrj        *  @param  __n  The number of objects space was allocated for.
457*38fd1498Szrj        *
458*38fd1498Szrj        *  Calls <tt> a.deallocate(p, n) </tt>
459*38fd1498Szrj       */
460*38fd1498Szrj       static void
461*38fd1498Szrj       deallocate(allocator_type& __a, pointer __p, size_type __n)
462*38fd1498Szrj       { __a.deallocate(__p, __n); }
463*38fd1498Szrj 
464*38fd1498Szrj       /**
465*38fd1498Szrj        *  @brief  Construct an object of type @a _Up
466*38fd1498Szrj        *  @param  __a  An allocator.
467*38fd1498Szrj        *  @param  __p  Pointer to memory of suitable size and alignment for Tp
468*38fd1498Szrj        *  @param  __args Constructor arguments.
469*38fd1498Szrj        *
470*38fd1498Szrj        *  Calls <tt> __a.construct(__p, std::forward<Args>(__args)...) </tt>
471*38fd1498Szrj       */
472*38fd1498Szrj       template<typename _Up, typename... _Args>
473*38fd1498Szrj 	static void
474*38fd1498Szrj 	construct(allocator_type& __a, _Up* __p, _Args&&... __args)
475*38fd1498Szrj 	{ __a.construct(__p, std::forward<_Args>(__args)...); }
476*38fd1498Szrj 
477*38fd1498Szrj       /**
478*38fd1498Szrj        *  @brief  Destroy an object of type @a _Up
479*38fd1498Szrj        *  @param  __a  An allocator.
480*38fd1498Szrj        *  @param  __p  Pointer to the object to destroy
481*38fd1498Szrj        *
482*38fd1498Szrj        *  Calls @c __a.destroy(__p).
483*38fd1498Szrj       */
484*38fd1498Szrj       template<typename _Up>
485*38fd1498Szrj 	static void
486*38fd1498Szrj 	destroy(allocator_type& __a, _Up* __p)
487*38fd1498Szrj 	{ __a.destroy(__p); }
488*38fd1498Szrj 
489*38fd1498Szrj       /**
490*38fd1498Szrj        *  @brief  The maximum supported allocation size
491*38fd1498Szrj        *  @param  __a  An allocator.
492*38fd1498Szrj        *  @return @c __a.max_size()
493*38fd1498Szrj       */
494*38fd1498Szrj       static size_type
495*38fd1498Szrj       max_size(const allocator_type& __a) noexcept
496*38fd1498Szrj       { return __a.max_size(); }
497*38fd1498Szrj 
498*38fd1498Szrj       /**
499*38fd1498Szrj        *  @brief  Obtain an allocator to use when copying a container.
500*38fd1498Szrj        *  @param  __rhs  An allocator.
501*38fd1498Szrj        *  @return @c __rhs
502*38fd1498Szrj       */
503*38fd1498Szrj       static allocator_type
504*38fd1498Szrj       select_on_container_copy_construction(const allocator_type& __rhs)
505*38fd1498Szrj       { return __rhs; }
506*38fd1498Szrj     };
507*38fd1498Szrj 
508*38fd1498Szrj 
509*38fd1498Szrj   template<typename _Alloc>
510*38fd1498Szrj     inline void
511*38fd1498Szrj     __do_alloc_on_copy(_Alloc& __one, const _Alloc& __two, true_type)
512*38fd1498Szrj     { __one = __two; }
513*38fd1498Szrj 
514*38fd1498Szrj   template<typename _Alloc>
515*38fd1498Szrj     inline void
516*38fd1498Szrj     __do_alloc_on_copy(_Alloc&, const _Alloc&, false_type)
517*38fd1498Szrj     { }
518*38fd1498Szrj 
519*38fd1498Szrj   template<typename _Alloc>
520*38fd1498Szrj     inline void __alloc_on_copy(_Alloc& __one, const _Alloc& __two)
521*38fd1498Szrj     {
522*38fd1498Szrj       typedef allocator_traits<_Alloc> __traits;
523*38fd1498Szrj       typedef typename __traits::propagate_on_container_copy_assignment __pocca;
524*38fd1498Szrj       __do_alloc_on_copy(__one, __two, __pocca());
525*38fd1498Szrj     }
526*38fd1498Szrj 
527*38fd1498Szrj   template<typename _Alloc>
528*38fd1498Szrj     inline _Alloc __alloc_on_copy(const _Alloc& __a)
529*38fd1498Szrj     {
530*38fd1498Szrj       typedef allocator_traits<_Alloc> __traits;
531*38fd1498Szrj       return __traits::select_on_container_copy_construction(__a);
532*38fd1498Szrj     }
533*38fd1498Szrj 
534*38fd1498Szrj   template<typename _Alloc>
535*38fd1498Szrj     inline void __do_alloc_on_move(_Alloc& __one, _Alloc& __two, true_type)
536*38fd1498Szrj     { __one = std::move(__two); }
537*38fd1498Szrj 
538*38fd1498Szrj   template<typename _Alloc>
539*38fd1498Szrj     inline void __do_alloc_on_move(_Alloc&, _Alloc&, false_type)
540*38fd1498Szrj     { }
541*38fd1498Szrj 
542*38fd1498Szrj   template<typename _Alloc>
543*38fd1498Szrj     inline void __alloc_on_move(_Alloc& __one, _Alloc& __two)
544*38fd1498Szrj     {
545*38fd1498Szrj       typedef allocator_traits<_Alloc> __traits;
546*38fd1498Szrj       typedef typename __traits::propagate_on_container_move_assignment __pocma;
547*38fd1498Szrj       __do_alloc_on_move(__one, __two, __pocma());
548*38fd1498Szrj     }
549*38fd1498Szrj 
550*38fd1498Szrj   template<typename _Alloc>
551*38fd1498Szrj     inline void __do_alloc_on_swap(_Alloc& __one, _Alloc& __two, true_type)
552*38fd1498Szrj     {
553*38fd1498Szrj       using std::swap;
554*38fd1498Szrj       swap(__one, __two);
555*38fd1498Szrj     }
556*38fd1498Szrj 
557*38fd1498Szrj   template<typename _Alloc>
558*38fd1498Szrj     inline void __do_alloc_on_swap(_Alloc&, _Alloc&, false_type)
559*38fd1498Szrj     { }
560*38fd1498Szrj 
561*38fd1498Szrj   template<typename _Alloc>
562*38fd1498Szrj     inline void __alloc_on_swap(_Alloc& __one, _Alloc& __two)
563*38fd1498Szrj     {
564*38fd1498Szrj       typedef allocator_traits<_Alloc> __traits;
565*38fd1498Szrj       typedef typename __traits::propagate_on_container_swap __pocs;
566*38fd1498Szrj       __do_alloc_on_swap(__one, __two, __pocs());
567*38fd1498Szrj     }
568*38fd1498Szrj 
569*38fd1498Szrj   template<typename _Alloc>
570*38fd1498Szrj     class __is_copy_insertable_impl
571*38fd1498Szrj     {
572*38fd1498Szrj       typedef allocator_traits<_Alloc> _Traits;
573*38fd1498Szrj 
574*38fd1498Szrj       template<typename _Up, typename
575*38fd1498Szrj 	       = decltype(_Traits::construct(std::declval<_Alloc&>(),
576*38fd1498Szrj 					     std::declval<_Up*>(),
577*38fd1498Szrj 					     std::declval<const _Up&>()))>
578*38fd1498Szrj 	static true_type
579*38fd1498Szrj 	_M_select(int);
580*38fd1498Szrj 
581*38fd1498Szrj       template<typename _Up>
582*38fd1498Szrj 	static false_type
583*38fd1498Szrj 	_M_select(...);
584*38fd1498Szrj 
585*38fd1498Szrj     public:
586*38fd1498Szrj       typedef decltype(_M_select<typename _Alloc::value_type>(0)) type;
587*38fd1498Szrj     };
588*38fd1498Szrj 
589*38fd1498Szrj   // true if _Alloc::value_type is CopyInsertable into containers using _Alloc
590*38fd1498Szrj   template<typename _Alloc>
591*38fd1498Szrj     struct __is_copy_insertable
592*38fd1498Szrj     : __is_copy_insertable_impl<_Alloc>::type
593*38fd1498Szrj     { };
594*38fd1498Szrj 
595*38fd1498Szrj   // std::allocator<_Tp> just requires CopyConstructible
596*38fd1498Szrj   template<typename _Tp>
597*38fd1498Szrj     struct __is_copy_insertable<allocator<_Tp>>
598*38fd1498Szrj     : is_copy_constructible<_Tp>
599*38fd1498Szrj     { };
600*38fd1498Szrj 
601*38fd1498Szrj #if __cplusplus >= 201103L
602*38fd1498Szrj   // Trait to detect Allocator-like types.
603*38fd1498Szrj   template<typename _Alloc, typename = void>
604*38fd1498Szrj     struct __is_allocator : false_type { };
605*38fd1498Szrj 
606*38fd1498Szrj   template<typename _Alloc>
607*38fd1498Szrj     struct __is_allocator<_Alloc,
608*38fd1498Szrj       __void_t<typename _Alloc::value_type,
609*38fd1498Szrj 	       decltype(std::declval<_Alloc&>().allocate(size_t{}))>>
610*38fd1498Szrj     : true_type { };
611*38fd1498Szrj 
612*38fd1498Szrj   template<typename _Alloc>
613*38fd1498Szrj     using _RequireAllocator
614*38fd1498Szrj       = typename enable_if<__is_allocator<_Alloc>::value, _Alloc>::type;
615*38fd1498Szrj #endif
616*38fd1498Szrj 
617*38fd1498Szrj _GLIBCXX_END_NAMESPACE_VERSION
618*38fd1498Szrj } // namespace std
619*38fd1498Szrj 
620*38fd1498Szrj #endif
621*38fd1498Szrj #endif
622