xref: /netbsd-src/external/gpl3/gcc.old/dist/libstdc++-v3/include/bits/allocator.h (revision 8feb0f0b7eaff0608f8350bbfa3098827b4bb91b)
11debfc3dSmrg // Allocators -*- C++ -*-
21debfc3dSmrg 
3*8feb0f0bSmrg // Copyright (C) 2001-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 /*
261debfc3dSmrg  * Copyright (c) 1996-1997
271debfc3dSmrg  * Silicon Graphics Computer Systems, Inc.
281debfc3dSmrg  *
291debfc3dSmrg  * Permission to use, copy, modify, distribute and sell this software
301debfc3dSmrg  * and its documentation for any purpose is hereby granted without fee,
311debfc3dSmrg  * provided that the above copyright notice appear in all copies and
321debfc3dSmrg  * that both that copyright notice and this permission notice appear
331debfc3dSmrg  * in supporting documentation.  Silicon Graphics makes no
341debfc3dSmrg  * representations about the suitability of this software for any
351debfc3dSmrg  * purpose.  It is provided "as is" without express or implied warranty.
361debfc3dSmrg  */
371debfc3dSmrg 
381debfc3dSmrg /** @file bits/allocator.h
391debfc3dSmrg  *  This is an internal header file, included by other library headers.
401debfc3dSmrg  *  Do not attempt to use it directly. @headername{memory}
411debfc3dSmrg  */
421debfc3dSmrg 
431debfc3dSmrg #ifndef _ALLOCATOR_H
441debfc3dSmrg #define _ALLOCATOR_H 1
451debfc3dSmrg 
461debfc3dSmrg #include <bits/c++allocator.h> // Define the base class to std::allocator.
471debfc3dSmrg #include <bits/memoryfwd.h>
481debfc3dSmrg #if __cplusplus >= 201103L
491debfc3dSmrg #include <type_traits>
501debfc3dSmrg #endif
511debfc3dSmrg 
521debfc3dSmrg #define __cpp_lib_incomplete_container_elements 201505
531debfc3dSmrg 
_GLIBCXX_VISIBILITY(default)541debfc3dSmrg namespace std _GLIBCXX_VISIBILITY(default)
551debfc3dSmrg {
561debfc3dSmrg _GLIBCXX_BEGIN_NAMESPACE_VERSION
571debfc3dSmrg 
581debfc3dSmrg   /**
591debfc3dSmrg    *  @addtogroup allocators
601debfc3dSmrg    *  @{
611debfc3dSmrg    */
621debfc3dSmrg 
63*8feb0f0bSmrg   // Since C++20 the primary template should be used for allocator<void>,
64*8feb0f0bSmrg   // but then it would have a non-trivial default ctor and dtor for C++20,
65*8feb0f0bSmrg   // but trivial for C++98-17, which would be an ABI incompatibiliy between
66*8feb0f0bSmrg   // different standard dialects. So C++20 still uses the allocator<void>
67*8feb0f0bSmrg   // explicit specialization, with the historical ABI properties, but with
68*8feb0f0bSmrg   // the same members that are present in the primary template.
69*8feb0f0bSmrg 
701debfc3dSmrg   /// allocator<void> specialization.
711debfc3dSmrg   template<>
721debfc3dSmrg     class allocator<void>
731debfc3dSmrg     {
741debfc3dSmrg     public:
75*8feb0f0bSmrg       typedef void        value_type;
761debfc3dSmrg       typedef size_t      size_type;
771debfc3dSmrg       typedef ptrdiff_t   difference_type;
78*8feb0f0bSmrg 
79*8feb0f0bSmrg #if __cplusplus <= 201703L
80*8feb0f0bSmrg       // These were removed for C++20, allocator_traits does the right thing.
811debfc3dSmrg       typedef void*       pointer;
821debfc3dSmrg       typedef const void* const_pointer;
831debfc3dSmrg 
841debfc3dSmrg       template<typename _Tp1>
851debfc3dSmrg 	struct rebind
861debfc3dSmrg 	{ typedef allocator<_Tp1> other; };
87*8feb0f0bSmrg #endif
881debfc3dSmrg 
891debfc3dSmrg #if __cplusplus >= 201103L
901debfc3dSmrg       // _GLIBCXX_RESOLVE_LIB_DEFECTS
911debfc3dSmrg       // 2103. std::allocator propagate_on_container_move_assignment
921debfc3dSmrg       typedef true_type propagate_on_container_move_assignment;
931debfc3dSmrg 
941debfc3dSmrg       typedef true_type is_always_equal;
951debfc3dSmrg 
96*8feb0f0bSmrg #if __cplusplus > 201703L
97*8feb0f0bSmrg       // As noted above, these members are present for C++20 to provide the
98*8feb0f0bSmrg       // same API as the primary template, but still trivial as in pre-C++20.
99*8feb0f0bSmrg       allocator() = default;
100*8feb0f0bSmrg       ~allocator() = default;
1011debfc3dSmrg 
1021debfc3dSmrg       template<typename _Up>
103*8feb0f0bSmrg 	constexpr
104*8feb0f0bSmrg 	allocator(const allocator<_Up>&) noexcept { }
105*8feb0f0bSmrg 
106*8feb0f0bSmrg       // No allocate member because it's ill-formed by LWG 3307.
107*8feb0f0bSmrg       // No deallocate member because it would be undefined to call it
108*8feb0f0bSmrg       // with any pointer which wasn't obtained from allocate.
109*8feb0f0bSmrg #endif // C++20
110*8feb0f0bSmrg #endif // C++11
1111debfc3dSmrg     };
1121debfc3dSmrg 
1131debfc3dSmrg   /**
114*8feb0f0bSmrg    * @brief  The @a standard allocator, as per C++03 [20.4.1].
1151debfc3dSmrg    *
1161debfc3dSmrg    *  See https://gcc.gnu.org/onlinedocs/libstdc++/manual/memory.html#std.util.memory.allocator
1171debfc3dSmrg    *  for further details.
1181debfc3dSmrg    *
1191debfc3dSmrg    *  @tparam  _Tp  Type of allocated object.
1201debfc3dSmrg    */
1211debfc3dSmrg   template<typename _Tp>
1221debfc3dSmrg     class allocator : public __allocator_base<_Tp>
1231debfc3dSmrg     {
1241debfc3dSmrg     public:
125*8feb0f0bSmrg       typedef _Tp        value_type;
1261debfc3dSmrg       typedef size_t     size_type;
1271debfc3dSmrg       typedef ptrdiff_t  difference_type;
128*8feb0f0bSmrg 
129*8feb0f0bSmrg #if __cplusplus <= 201703L
130*8feb0f0bSmrg       // These were removed for C++20.
1311debfc3dSmrg       typedef _Tp*       pointer;
1321debfc3dSmrg       typedef const _Tp* const_pointer;
1331debfc3dSmrg       typedef _Tp&       reference;
1341debfc3dSmrg       typedef const _Tp& const_reference;
1351debfc3dSmrg 
1361debfc3dSmrg       template<typename _Tp1>
1371debfc3dSmrg 	struct rebind
1381debfc3dSmrg 	{ typedef allocator<_Tp1> other; };
139*8feb0f0bSmrg #endif
1401debfc3dSmrg 
1411debfc3dSmrg #if __cplusplus >= 201103L
1421debfc3dSmrg       // _GLIBCXX_RESOLVE_LIB_DEFECTS
1431debfc3dSmrg       // 2103. std::allocator propagate_on_container_move_assignment
1441debfc3dSmrg       typedef true_type propagate_on_container_move_assignment;
1451debfc3dSmrg 
1461debfc3dSmrg       typedef true_type is_always_equal;
1471debfc3dSmrg #endif
1481debfc3dSmrg 
149c0a68be4Smrg       // _GLIBCXX_RESOLVE_LIB_DEFECTS
150c0a68be4Smrg       // 3035. std::allocator's constructors should be constexpr
151c0a68be4Smrg       _GLIBCXX20_CONSTEXPR
152c0a68be4Smrg       allocator() _GLIBCXX_NOTHROW { }
1531debfc3dSmrg 
154c0a68be4Smrg       _GLIBCXX20_CONSTEXPR
155c0a68be4Smrg       allocator(const allocator& __a) _GLIBCXX_NOTHROW
1561debfc3dSmrg       : __allocator_base<_Tp>(__a) { }
1571debfc3dSmrg 
158c0a68be4Smrg #if __cplusplus >= 201103L
159c0a68be4Smrg       // Avoid implicit deprecation.
160c0a68be4Smrg       allocator& operator=(const allocator&) = default;
161c0a68be4Smrg #endif
1621debfc3dSmrg 
163c0a68be4Smrg       template<typename _Tp1>
164c0a68be4Smrg 	_GLIBCXX20_CONSTEXPR
165c0a68be4Smrg 	allocator(const allocator<_Tp1>&) _GLIBCXX_NOTHROW { }
166c0a68be4Smrg 
167*8feb0f0bSmrg #if __cpp_constexpr_dynamic_alloc
168*8feb0f0bSmrg       constexpr
169*8feb0f0bSmrg #endif
170c0a68be4Smrg       ~allocator() _GLIBCXX_NOTHROW { }
171c0a68be4Smrg 
172*8feb0f0bSmrg #if __cplusplus > 201703L
173*8feb0f0bSmrg       [[nodiscard,__gnu__::__always_inline__]]
174*8feb0f0bSmrg       constexpr _Tp*
175*8feb0f0bSmrg       allocate(size_t __n)
176*8feb0f0bSmrg       {
177*8feb0f0bSmrg #ifdef __cpp_lib_is_constant_evaluated
178*8feb0f0bSmrg 	if (std::is_constant_evaluated())
179*8feb0f0bSmrg 	  return static_cast<_Tp*>(::operator new(__n * sizeof(_Tp)));
180*8feb0f0bSmrg #endif
181*8feb0f0bSmrg 	return __allocator_base<_Tp>::allocate(__n, 0);
182*8feb0f0bSmrg       }
183*8feb0f0bSmrg 
184*8feb0f0bSmrg       [[__gnu__::__always_inline__]]
185*8feb0f0bSmrg       constexpr void
186*8feb0f0bSmrg       deallocate(_Tp* __p, size_t __n)
187*8feb0f0bSmrg       {
188*8feb0f0bSmrg #ifdef __cpp_lib_is_constant_evaluated
189*8feb0f0bSmrg 	if (std::is_constant_evaluated())
190*8feb0f0bSmrg 	  {
191*8feb0f0bSmrg 	    ::operator delete(__p);
192*8feb0f0bSmrg 	    return;
193*8feb0f0bSmrg 	  }
194*8feb0f0bSmrg #endif
195*8feb0f0bSmrg 	__allocator_base<_Tp>::deallocate(__p, __n);
196*8feb0f0bSmrg       }
197*8feb0f0bSmrg #endif // C++20
198*8feb0f0bSmrg 
199*8feb0f0bSmrg       friend _GLIBCXX20_CONSTEXPR bool
200c0a68be4Smrg       operator==(const allocator&, const allocator&) _GLIBCXX_NOTHROW
201c0a68be4Smrg       { return true; }
202c0a68be4Smrg 
203*8feb0f0bSmrg #if __cpp_impl_three_way_comparison < 201907L
204*8feb0f0bSmrg       friend _GLIBCXX20_CONSTEXPR bool
205c0a68be4Smrg       operator!=(const allocator&, const allocator&) _GLIBCXX_NOTHROW
206c0a68be4Smrg       { return false; }
207*8feb0f0bSmrg #endif
2081debfc3dSmrg 
2091debfc3dSmrg       // Inherit everything else.
2101debfc3dSmrg     };
2111debfc3dSmrg 
2121debfc3dSmrg   template<typename _T1, typename _T2>
213*8feb0f0bSmrg     inline _GLIBCXX20_CONSTEXPR bool
2141debfc3dSmrg     operator==(const allocator<_T1>&, const allocator<_T2>&)
215c0a68be4Smrg     _GLIBCXX_NOTHROW
2161debfc3dSmrg     { return true; }
2171debfc3dSmrg 
218*8feb0f0bSmrg #if __cpp_impl_three_way_comparison < 201907L
2191debfc3dSmrg   template<typename _T1, typename _T2>
220*8feb0f0bSmrg     inline _GLIBCXX20_CONSTEXPR bool
2211debfc3dSmrg     operator!=(const allocator<_T1>&, const allocator<_T2>&)
222c0a68be4Smrg     _GLIBCXX_NOTHROW
2231debfc3dSmrg     { return false; }
224*8feb0f0bSmrg #endif
2251debfc3dSmrg 
226a2dc1f3fSmrg   // Invalid allocator<cv T> partial specializations.
227a2dc1f3fSmrg   // allocator_traits::rebind_alloc can be used to form a valid allocator type.
228a2dc1f3fSmrg   template<typename _Tp>
229a2dc1f3fSmrg     class allocator<const _Tp>
230a2dc1f3fSmrg     {
231a2dc1f3fSmrg     public:
232a2dc1f3fSmrg       typedef _Tp value_type;
233a2dc1f3fSmrg       template<typename _Up> allocator(const allocator<_Up>&) { }
234a2dc1f3fSmrg     };
235a2dc1f3fSmrg 
236a2dc1f3fSmrg   template<typename _Tp>
237a2dc1f3fSmrg     class allocator<volatile _Tp>
238a2dc1f3fSmrg     {
239a2dc1f3fSmrg     public:
240a2dc1f3fSmrg       typedef _Tp value_type;
241a2dc1f3fSmrg       template<typename _Up> allocator(const allocator<_Up>&) { }
242a2dc1f3fSmrg     };
243a2dc1f3fSmrg 
244a2dc1f3fSmrg   template<typename _Tp>
245a2dc1f3fSmrg     class allocator<const volatile _Tp>
246a2dc1f3fSmrg     {
247a2dc1f3fSmrg     public:
248a2dc1f3fSmrg       typedef _Tp value_type;
249a2dc1f3fSmrg       template<typename _Up> allocator(const allocator<_Up>&) { }
250a2dc1f3fSmrg     };
251a2dc1f3fSmrg 
2521debfc3dSmrg   /// @} group allocator
2531debfc3dSmrg 
2541debfc3dSmrg   // Inhibit implicit instantiations for required instantiations,
2551debfc3dSmrg   // which are defined via explicit instantiations elsewhere.
2561debfc3dSmrg #if _GLIBCXX_EXTERN_TEMPLATE
2571debfc3dSmrg   extern template class allocator<char>;
2581debfc3dSmrg   extern template class allocator<wchar_t>;
2591debfc3dSmrg #endif
2601debfc3dSmrg 
2611debfc3dSmrg   // Undefine.
2621debfc3dSmrg #undef __allocator_base
2631debfc3dSmrg 
2641debfc3dSmrg   // To implement Option 3 of DR 431.
2651debfc3dSmrg   template<typename _Alloc, bool = __is_empty(_Alloc)>
2661debfc3dSmrg     struct __alloc_swap
2671debfc3dSmrg     { static void _S_do_it(_Alloc&, _Alloc&) _GLIBCXX_NOEXCEPT { } };
2681debfc3dSmrg 
2691debfc3dSmrg   template<typename _Alloc>
2701debfc3dSmrg     struct __alloc_swap<_Alloc, false>
2711debfc3dSmrg     {
2721debfc3dSmrg       static void
2731debfc3dSmrg       _S_do_it(_Alloc& __one, _Alloc& __two) _GLIBCXX_NOEXCEPT
2741debfc3dSmrg       {
2751debfc3dSmrg 	// Precondition: swappable allocators.
2761debfc3dSmrg 	if (__one != __two)
2771debfc3dSmrg 	  swap(__one, __two);
2781debfc3dSmrg       }
2791debfc3dSmrg     };
2801debfc3dSmrg 
2811debfc3dSmrg   // Optimize for stateless allocators.
2821debfc3dSmrg   template<typename _Alloc, bool = __is_empty(_Alloc)>
2831debfc3dSmrg     struct __alloc_neq
2841debfc3dSmrg     {
2851debfc3dSmrg       static bool
2861debfc3dSmrg       _S_do_it(const _Alloc&, const _Alloc&)
2871debfc3dSmrg       { return false; }
2881debfc3dSmrg     };
2891debfc3dSmrg 
2901debfc3dSmrg   template<typename _Alloc>
2911debfc3dSmrg     struct __alloc_neq<_Alloc, false>
2921debfc3dSmrg     {
2931debfc3dSmrg       static bool
2941debfc3dSmrg       _S_do_it(const _Alloc& __one, const _Alloc& __two)
2951debfc3dSmrg       { return __one != __two; }
2961debfc3dSmrg     };
2971debfc3dSmrg 
2981debfc3dSmrg #if __cplusplus >= 201103L
2991debfc3dSmrg   template<typename _Tp, bool
3001debfc3dSmrg     = __or_<is_copy_constructible<typename _Tp::value_type>,
3011debfc3dSmrg             is_nothrow_move_constructible<typename _Tp::value_type>>::value>
3021debfc3dSmrg     struct __shrink_to_fit_aux
3031debfc3dSmrg     { static bool _S_do_it(_Tp&) noexcept { return false; } };
3041debfc3dSmrg 
3051debfc3dSmrg   template<typename _Tp>
3061debfc3dSmrg     struct __shrink_to_fit_aux<_Tp, true>
3071debfc3dSmrg     {
3081debfc3dSmrg       static bool
3091debfc3dSmrg       _S_do_it(_Tp& __c) noexcept
3101debfc3dSmrg       {
3111debfc3dSmrg #if __cpp_exceptions
3121debfc3dSmrg 	try
3131debfc3dSmrg 	  {
3141debfc3dSmrg 	    _Tp(__make_move_if_noexcept_iterator(__c.begin()),
3151debfc3dSmrg 		__make_move_if_noexcept_iterator(__c.end()),
3161debfc3dSmrg 		__c.get_allocator()).swap(__c);
3171debfc3dSmrg 	    return true;
3181debfc3dSmrg 	  }
3191debfc3dSmrg 	catch(...)
3201debfc3dSmrg 	  { return false; }
3211debfc3dSmrg #else
3221debfc3dSmrg 	return false;
3231debfc3dSmrg #endif
3241debfc3dSmrg       }
3251debfc3dSmrg     };
3261debfc3dSmrg #endif
3271debfc3dSmrg 
3281debfc3dSmrg _GLIBCXX_END_NAMESPACE_VERSION
3291debfc3dSmrg } // namespace std
3301debfc3dSmrg 
3311debfc3dSmrg #endif
332