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