xref: /netbsd-src/external/gpl3/gcc.old/dist/libstdc++-v3/include/bits/uses_allocator.h (revision 8feb0f0b7eaff0608f8350bbfa3098827b4bb91b)
11debfc3dSmrg // Uses-allocator Construction -*- C++ -*-
21debfc3dSmrg 
3*8feb0f0bSmrg // Copyright (C) 2010-2020 Free Software Foundation, Inc.
41debfc3dSmrg //
51debfc3dSmrg // This file is part of the GNU ISO C++ Library.  This library is free
61debfc3dSmrg // software; you can redistribute it and/or modify it under the
71debfc3dSmrg // terms of the GNU General Public License as published by the
81debfc3dSmrg // Free Software Foundation; either version 3, or (at your option)
91debfc3dSmrg // any later version.
101debfc3dSmrg 
111debfc3dSmrg // This library is distributed in the hope that it will be useful,
121debfc3dSmrg // but WITHOUT ANY WARRANTY; without even the implied warranty of
131debfc3dSmrg // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
141debfc3dSmrg // GNU General Public License for more details.
151debfc3dSmrg 
161debfc3dSmrg // Under Section 7 of GPL version 3, you are granted additional
171debfc3dSmrg // permissions described in the GCC Runtime Library Exception, version
181debfc3dSmrg // 3.1, as published by the Free Software Foundation.
191debfc3dSmrg 
201debfc3dSmrg // You should have received a copy of the GNU General Public License and
211debfc3dSmrg // a copy of the GCC Runtime Library Exception along with this program;
221debfc3dSmrg // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
231debfc3dSmrg // <http://www.gnu.org/licenses/>.
241debfc3dSmrg 
251debfc3dSmrg #ifndef _USES_ALLOCATOR_H
261debfc3dSmrg #define _USES_ALLOCATOR_H 1
271debfc3dSmrg 
281debfc3dSmrg #if __cplusplus < 201103L
291debfc3dSmrg # include <bits/c++0x_warning.h>
301debfc3dSmrg #else
311debfc3dSmrg 
321debfc3dSmrg #include <type_traits>
331debfc3dSmrg #include <bits/move.h>
341debfc3dSmrg 
_GLIBCXX_VISIBILITY(default)351debfc3dSmrg namespace std _GLIBCXX_VISIBILITY(default)
361debfc3dSmrg {
371debfc3dSmrg _GLIBCXX_BEGIN_NAMESPACE_VERSION
381debfc3dSmrg 
39c0a68be4Smrg   // This is used for std::experimental::erased_type from Library Fundamentals.
401debfc3dSmrg   struct __erased_type { };
411debfc3dSmrg 
42c0a68be4Smrg   // This also supports the "type-erased allocator" protocol from the
43c0a68be4Smrg   // Library Fundamentals TS, where allocator_type is erased_type.
44c0a68be4Smrg   // The second condition will always be false for types not using the TS.
451debfc3dSmrg   template<typename _Alloc, typename _Tp>
461debfc3dSmrg     using __is_erased_or_convertible
47c0a68be4Smrg       = __or_<is_convertible<_Alloc, _Tp>, is_same<_Tp, __erased_type>>;
481debfc3dSmrg 
491debfc3dSmrg   /// [allocator.tag]
501debfc3dSmrg   struct allocator_arg_t { explicit allocator_arg_t() = default; };
511debfc3dSmrg 
521debfc3dSmrg   _GLIBCXX17_INLINE constexpr allocator_arg_t allocator_arg =
531debfc3dSmrg     allocator_arg_t();
541debfc3dSmrg 
551debfc3dSmrg   template<typename _Tp, typename _Alloc, typename = __void_t<>>
561debfc3dSmrg     struct __uses_allocator_helper
571debfc3dSmrg     : false_type { };
581debfc3dSmrg 
591debfc3dSmrg   template<typename _Tp, typename _Alloc>
601debfc3dSmrg     struct __uses_allocator_helper<_Tp, _Alloc,
611debfc3dSmrg 				   __void_t<typename _Tp::allocator_type>>
621debfc3dSmrg     : __is_erased_or_convertible<_Alloc, typename _Tp::allocator_type>::type
631debfc3dSmrg     { };
641debfc3dSmrg 
651debfc3dSmrg   /// [allocator.uses.trait]
661debfc3dSmrg   template<typename _Tp, typename _Alloc>
671debfc3dSmrg     struct uses_allocator
681debfc3dSmrg     : __uses_allocator_helper<_Tp, _Alloc>::type
691debfc3dSmrg     { };
701debfc3dSmrg 
711debfc3dSmrg   struct __uses_alloc_base { };
721debfc3dSmrg 
731debfc3dSmrg   struct __uses_alloc0 : __uses_alloc_base
741debfc3dSmrg   {
75*8feb0f0bSmrg     struct _Sink { void _GLIBCXX20_CONSTEXPR operator=(const void*) { } } _M_a;
761debfc3dSmrg   };
771debfc3dSmrg 
781debfc3dSmrg   template<typename _Alloc>
791debfc3dSmrg     struct __uses_alloc1 : __uses_alloc_base { const _Alloc* _M_a; };
801debfc3dSmrg 
811debfc3dSmrg   template<typename _Alloc>
821debfc3dSmrg     struct __uses_alloc2 : __uses_alloc_base { const _Alloc* _M_a; };
831debfc3dSmrg 
841debfc3dSmrg   template<bool, typename _Tp, typename _Alloc, typename... _Args>
851debfc3dSmrg     struct __uses_alloc;
861debfc3dSmrg 
871debfc3dSmrg   template<typename _Tp, typename _Alloc, typename... _Args>
881debfc3dSmrg     struct __uses_alloc<true, _Tp, _Alloc, _Args...>
891debfc3dSmrg     : conditional<
90a2dc1f3fSmrg         is_constructible<_Tp, allocator_arg_t, const _Alloc&, _Args...>::value,
911debfc3dSmrg         __uses_alloc1<_Alloc>,
921debfc3dSmrg        	__uses_alloc2<_Alloc>>::type
931debfc3dSmrg     {
94a2dc1f3fSmrg       // _GLIBCXX_RESOLVE_LIB_DEFECTS
95a2dc1f3fSmrg       // 2586. Wrong value category used in scoped_allocator_adaptor::construct
961debfc3dSmrg       static_assert(__or_<
97a2dc1f3fSmrg 	  is_constructible<_Tp, allocator_arg_t, const _Alloc&, _Args...>,
98a2dc1f3fSmrg 	  is_constructible<_Tp, _Args..., const _Alloc&>>::value,
99a2dc1f3fSmrg 	  "construction with an allocator must be possible"
100a2dc1f3fSmrg 	  " if uses_allocator is true");
1011debfc3dSmrg     };
1021debfc3dSmrg 
1031debfc3dSmrg   template<typename _Tp, typename _Alloc, typename... _Args>
1041debfc3dSmrg     struct __uses_alloc<false, _Tp, _Alloc, _Args...>
1051debfc3dSmrg     : __uses_alloc0 { };
1061debfc3dSmrg 
1071debfc3dSmrg   template<typename _Tp, typename _Alloc, typename... _Args>
1081debfc3dSmrg     using __uses_alloc_t =
1091debfc3dSmrg       __uses_alloc<uses_allocator<_Tp, _Alloc>::value, _Tp, _Alloc, _Args...>;
1101debfc3dSmrg 
1111debfc3dSmrg   template<typename _Tp, typename _Alloc, typename... _Args>
112*8feb0f0bSmrg     _GLIBCXX20_CONSTEXPR
1131debfc3dSmrg     inline __uses_alloc_t<_Tp, _Alloc, _Args...>
1141debfc3dSmrg     __use_alloc(const _Alloc& __a)
1151debfc3dSmrg     {
1161debfc3dSmrg       __uses_alloc_t<_Tp, _Alloc, _Args...> __ret;
1171debfc3dSmrg       __ret._M_a = std::__addressof(__a);
1181debfc3dSmrg       return __ret;
1191debfc3dSmrg     }
1201debfc3dSmrg 
1211debfc3dSmrg   template<typename _Tp, typename _Alloc, typename... _Args>
1221debfc3dSmrg     void
1231debfc3dSmrg     __use_alloc(const _Alloc&&) = delete;
1241debfc3dSmrg 
1251debfc3dSmrg #if __cplusplus > 201402L
1261debfc3dSmrg   template <typename _Tp, typename _Alloc>
1271debfc3dSmrg     inline constexpr bool uses_allocator_v =
1281debfc3dSmrg       uses_allocator<_Tp, _Alloc>::value;
1291debfc3dSmrg #endif // C++17
1301debfc3dSmrg 
1311debfc3dSmrg   template<template<typename...> class _Predicate,
1321debfc3dSmrg 	   typename _Tp, typename _Alloc, typename... _Args>
1331debfc3dSmrg     struct __is_uses_allocator_predicate
1341debfc3dSmrg     : conditional<uses_allocator<_Tp, _Alloc>::value,
1351debfc3dSmrg       __or_<_Predicate<_Tp, allocator_arg_t, _Alloc, _Args...>,
1361debfc3dSmrg 	    _Predicate<_Tp, _Args..., _Alloc>>,
1371debfc3dSmrg       _Predicate<_Tp, _Args...>>::type { };
1381debfc3dSmrg 
1391debfc3dSmrg   template<typename _Tp, typename _Alloc, typename... _Args>
1401debfc3dSmrg     struct __is_uses_allocator_constructible
1411debfc3dSmrg     : __is_uses_allocator_predicate<is_constructible, _Tp, _Alloc, _Args...>
1421debfc3dSmrg     { };
1431debfc3dSmrg 
1441debfc3dSmrg #if __cplusplus >= 201402L
1451debfc3dSmrg   template<typename _Tp, typename _Alloc, typename... _Args>
1461debfc3dSmrg     _GLIBCXX17_INLINE constexpr bool __is_uses_allocator_constructible_v =
1471debfc3dSmrg       __is_uses_allocator_constructible<_Tp, _Alloc, _Args...>::value;
1481debfc3dSmrg #endif // C++14
1491debfc3dSmrg 
1501debfc3dSmrg   template<typename _Tp, typename _Alloc, typename... _Args>
1511debfc3dSmrg     struct __is_nothrow_uses_allocator_constructible
1521debfc3dSmrg     : __is_uses_allocator_predicate<is_nothrow_constructible,
1531debfc3dSmrg 				    _Tp, _Alloc, _Args...>
1541debfc3dSmrg     { };
1551debfc3dSmrg 
1561debfc3dSmrg 
1571debfc3dSmrg #if __cplusplus >= 201402L
1581debfc3dSmrg   template<typename _Tp, typename _Alloc, typename... _Args>
1591debfc3dSmrg     _GLIBCXX17_INLINE constexpr bool
1601debfc3dSmrg     __is_nothrow_uses_allocator_constructible_v =
1611debfc3dSmrg       __is_nothrow_uses_allocator_constructible<_Tp, _Alloc, _Args...>::value;
1621debfc3dSmrg #endif // C++14
1631debfc3dSmrg 
1641debfc3dSmrg   template<typename _Tp, typename... _Args>
1651debfc3dSmrg     void __uses_allocator_construct_impl(__uses_alloc0 __a, _Tp* __ptr,
1661debfc3dSmrg 					 _Args&&... __args)
1671debfc3dSmrg     { ::new ((void*)__ptr) _Tp(std::forward<_Args>(__args)...); }
1681debfc3dSmrg 
1691debfc3dSmrg   template<typename _Tp, typename _Alloc, typename... _Args>
1701debfc3dSmrg     void __uses_allocator_construct_impl(__uses_alloc1<_Alloc> __a, _Tp* __ptr,
1711debfc3dSmrg 					 _Args&&... __args)
1721debfc3dSmrg     {
1731debfc3dSmrg       ::new ((void*)__ptr) _Tp(allocator_arg, *__a._M_a,
1741debfc3dSmrg 			       std::forward<_Args>(__args)...);
1751debfc3dSmrg     }
1761debfc3dSmrg 
1771debfc3dSmrg   template<typename _Tp, typename _Alloc, typename... _Args>
1781debfc3dSmrg     void __uses_allocator_construct_impl(__uses_alloc2<_Alloc> __a, _Tp* __ptr,
1791debfc3dSmrg 					 _Args&&... __args)
1801debfc3dSmrg     { ::new ((void*)__ptr) _Tp(std::forward<_Args>(__args)..., *__a._M_a); }
1811debfc3dSmrg 
1821debfc3dSmrg   template<typename _Tp, typename _Alloc, typename... _Args>
1831debfc3dSmrg     void __uses_allocator_construct(const _Alloc& __a, _Tp* __ptr,
1841debfc3dSmrg 				    _Args&&... __args)
1851debfc3dSmrg     {
186c0a68be4Smrg       std::__uses_allocator_construct_impl(
187c0a68be4Smrg 	  std::__use_alloc<_Tp, _Alloc, _Args...>(__a), __ptr,
188c0a68be4Smrg 	  std::forward<_Args>(__args)...);
1891debfc3dSmrg     }
1901debfc3dSmrg 
1911debfc3dSmrg _GLIBCXX_END_NAMESPACE_VERSION
1921debfc3dSmrg } // namespace std
1931debfc3dSmrg 
1941debfc3dSmrg #endif
1951debfc3dSmrg #endif
196