ALib C++ Library
Library Version: 2510 R0
Documentation generated by doxygen
Loading...
Searching...
No Matches
stdcontainerallocator.inl
Go to the documentation of this file.
1//==================================================================================================
2/// \file
3/// This header-file is part of module \alib_lang of the \aliblong.
4///
5/// \emoji :copyright: 2013-2025 A-Worx GmbH, Germany.
6/// Published under \ref mainpage_license "Boost Software License".
7//==================================================================================================
8ALIB_EXPORT namespace alib::lang {
9
10namespace detail {
11
12//==================================================================================================
13/// Base struct for types \alib{lang;StdContainerAllocator} and
14/// \alib{lang;StdContainerAllocatorRecycling} containing entities to satisfy requirements for
15/// being a <c>std::allocator</c>.
16///
17/// @tparam T The type of objects to be allocated.
18/// @tparam TAllocator The allocator type, as prototyped with \alib{lang;Allocator}.
19//==================================================================================================
20template<typename T, typename TAllocator>
22{
23 // #############################################################################################
24 // ### Type definitions
25 // #############################################################################################
26 using size_type = size_t ; ///< Type definition as required by C++ library standards.
27 using difference_type= ptrdiff_t ; ///< Type definition as required by C++ library standards.
28 using value_type = T ; ///< Type definition as required by C++ library standards.
29 using is_always_equal= std::false_type; ///< Type definition as required by C++ library standards.
30 using reference = T& ; ///< Type definition as required by C++ library standards.
31 using const_reference= const T& ; ///< Type definition as required by C++ library standards.
32
33
34 /// The allocator type that \p{TAllocator} specifies.
35 using AllocatorType= TAllocator;
36
37}; // struct StdContainerAllocatorBase
38
39} // namespace alib::lang[::detail]
40
41
42//==================================================================================================
43/// This struct is an implementation of C++ standard library type <c>std::allocator</c>.
44/// It is to be used with container types provided by the C++ standard library in combination
45/// with \alib{lang;Allocator;ALib Allocators}.
46///
47/// With the inclusion of module \alib_monomem in the \alibbuild, this allocator is suitable to use
48/// cases of \ref alib_contmono_intro_strictweak "strict or weak monotonic allocation".
49///
50/// ### Shortcuts for Specific ALib Allocators ###
51/// The following alias type definitions exist for this type, each addressing a specific allocator:
52/// - \alib{SCAMono}, and
53/// - \alib{SCAPool}.
54///
55/// Along with this, shortcuts to the container types are likewise provided with:
56/// - \alib{StdVectorMono}, \alib{StdVectorPool},
57/// - \alib{StdListMono}, \alib{StdListPool}, and
58/// - \alib{StdDequeMono}, \alib{StdDequePool}.
59///
60/// \anchor alib_ns_monomem_scamono_reset
61/// ### Resetting A Container ###
62/// While the dedicated container types provided with module \alib_containers offer a method
63/// named \b Reset (see for example \alib{containers;HashTable::Reset}), the C++ standard
64/// containers do not. This is a challenge because their internal memory will be invalid
65/// with a reset. For example, if allocator type \alib{MonoAllocator} was used with calss
66/// <c>std::vector</c>, there is no interface method that makes the vector "forget" its internal
67/// data array. Its method <c>shrink_to_fit</c> by its specification is not forced to shrink
68/// anything or even dispose the data if the size was \c 0 when called.
69/// This is implementation-dependent.
70///
71/// The way out is as simple as radical: The container is just to be destructed and reconstructed
72/// "in place". This can be done using a <em>C++ placement-new</em>. The following
73/// code snippet demonstrates this:
74/// \snippet "ut_stdcontainers.cpp" DOX_MONOMEM_SCAMONO_PLACEMENT_NEW
75///
76/// \see
77/// - An alternative version that \ref alib_contmono_intro_recycling "recycles nodes" (and also
78/// bucket arrays in case of <c>std::unordered_set</c> and <c>std::unordered_map</c>), is
79/// provided with sibling type \alib{lang;StdContainerAllocatorRecycling}.
80/// - Type definitions \alib{SCAMono} and \alib{SCAPool} given with module \alib_monomem.
81/// - Further shortcuts for standard container types, given with \alib{StdVectorMono},
82/// \alib{StdVectorPool}, \alib{StdListMono}, \alib{StdListPool}, \alib{StdDequeMono}, and
83/// \alib{StdDequePool}.
84///
85/// @tparam T The type of objects to be allocated.
86/// @tparam TAllocator The allocator type, as prototyped with \alib{lang;Allocator}.
87//==================================================================================================
88template<typename T, typename TAllocator>
90 , AllocatorMember<TAllocator>
91{
92 /// The allocator type that \p{TAllocator} specifies.
94
95 /// Defaulted copy constructor
96 constexpr StdContainerAllocator( const StdContainerAllocator& ) noexcept =default;
97
98 /// Defaulted move constructor
99 constexpr StdContainerAllocator( StdContainerAllocator&& ) noexcept =default;
100
101 /// Copy constructor using an instance of a different template type.
102 /// @tparam TSibling The originating allocator's type (<b>StdContainerAllocator<X></b>).
103 /// @param origin The originating allocator of type \p{TSibling} .
104 template<typename TSibling>
105 requires alib::lang::IsAllocator<typename TSibling::allocator>
106 StdContainerAllocator(const TSibling& origin)
107 : allocBase(origin)
108 {}
109
110 /// Copy constructor using an instance of different template type.
111 /// @tparam TSibling The originating allocator's type (<b>StdContainerAllocator<X></b>).
112 /// @param origin The originating allocator of type \p{TSibling} .
113 template<typename TSibling>
117
118 /// Constructor for the initial allocator instantiation.
119 /// @param pAllocator The allocator.
120 StdContainerAllocator( TAllocator& pAllocator )
121 : allocBase(pAllocator)
122 {}
123
124 /// Parameterless constructor used with heap allocation.
126
127
128 // #############################################################################################
129 // ### Comparison
130 // #############################################################################################
131 /// Comparison operator.
132 /// @tparam U The allocation type of the other allocator.
133 /// @param rhs The right hand side allocator.
134 /// @return \c true if this and \p{rhs} use the same #allocator, \c false otherwise.
135 template< typename U >
136 bool operator==( const StdContainerAllocator<U,TAllocator>& rhs ) const noexcept
137 {
138 return &allocBase::getAllocator() == &rhs.getAllocator();
139 }
140
141 /// Comparison operator.
142 /// @tparam U The allocation type of the other allocator.
143 /// @param rhs The right hand side allocator.
144 /// @return \c false if this and \p{rhs} use the same #allocator, \c true otherwise.
145 template< typename U >
146 bool operator!=( const StdContainerAllocator<U,TAllocator>& rhs ) const noexcept
147 {
148 return &allocBase::GetAllocator() != &rhs.GetAllocator();
149 }
150
151
152 // #############################################################################################
153 // ### Allocate/de-allocate
154 // #############################################################################################
155 //==============================================================================================
156 /// Passes the allocation request to the \b AllocatorMember.
157 ///
158 /// @param n The number of requested objects to allocate storage for.
159 /// @return Pointer to the start of the array of \p{n} objects of type \p{T}.
160 //==============================================================================================
161 [[nodiscard]]
162 T* allocate( size_t n, const void* = nullptr )
163 { return allocBase::AI().template AllocArray<T>( n ); }
164
165 //==============================================================================================
166 /// Frees the given array of objects.
167 /// @param p Pointer to the previously allocated memory.
168 /// @param n The number of objects allocated.
169 //==============================================================================================
170 void deallocate( T* p, std::size_t n )
171 { allocBase::AI().FreeArray( p, n ); }
172
173}; // struct StdContainerAllocator
174
175//==================================================================================================
176/// Implementation of <c>std::allocator</c> to be used with container types provided by the
177/// C++ standard library.
178///
179/// As the C+++ library's specification does not include details of the container class's
180/// implementation, this allocator uses type \alib{lang;RTTRAllocator} which detects
181/// node types automatically.
182///
183/// \attention
184/// It cannot be guaranteed that a certain, uncommon implementation of the C++ library
185/// allocates memory in a way that this allocator truly recycles objects, and - even if the authors
186/// of \alib are optimistic hat this type works with any implementation - it is recommended
187/// to use the alternative container types found in this \alibmod_nl.
188///
189/// \see
190/// For background information about monotonic memory allocation, recycling, and the issues
191/// of C++ standard container types, see the \ref alib_mods_contmono "Programmer's Manual" of
192/// \alibmods_nl \b Containers and \b Monomem.
193///
194/// @tparam T The type of objects to be allocated.
195/// @tparam TAllocator The allocator type, as prototyped with \alib{lang;Allocator}.
196//==================================================================================================
197template<typename T, typename TAllocator>
199{
200 // #############################################################################################
201 // ### Fields
202 // #############################################################################################
203 /// The only member of this allocator type used to perform all duties.
205
206 // #############################################################################################
207 // ### Construction/Destruction
208 // #############################################################################################
209 /// Defaulted copy constructor
211
212 /// Defaulted move constructor
214
215 /// Copy constructor using an instance of different template type.
216 /// @tparam TSibling The originating allocator's type (<b>StdContainerAllocatorRecycling<X></b>).
217 /// @param StdContainerAllocatorRecycling The originating allocator of type \p{TSibling} .
218 template<typename TSibling>
221
222 /// Constructor for the initial allocator instantiation.
223 /// @param pRecycler The recycler to for allocations and de-allocations.
225 : recycler(pRecycler)
226 {}
227
228 // #############################################################################################
229 // ### Comparison
230 // #############################################################################################
231 /// Comparison operator.
232 /// @tparam U The allocation type of the other allocator.
233 /// @param rhs The right hand side allocator.
234 /// @return \c true if this and \p{rhs} use the same #recycler, \c false otherwise.
235 template< typename U >
237 { return recycler == rhs.recycler; }
238
239 /// Comparison operator.
240 /// @tparam U The allocation type of the other allocator.
241 /// @param rhs The right hand side allocator.
242 /// @return \c false if this and \p{rhs} use the same #recycler, \c true otherwise.
243 template< typename U >
245 { return recycler != rhs.recycler; }
246
247 // #############################################################################################
248 // ### Allocate/de-allocate
249 // #############################################################################################
250 //==============================================================================================
251 /// Implementation of <c>std::allocator</c> interface.
252 /// Dependent on whether a single or multiple objects are requested, this method invokes
253 /// either \alib{lang;RTTRAllocator::Get} or
254 /// \alib{lang;RTTRAllocator::AllocUnrelated} on field #recycler.
255 ///
256 /// @param n The number of requested objects to allocate storage for.
257 /// @return Pointer to the start of the array of \p{n} objects of type \p{T}.
258 //==============================================================================================
259 [[nodiscard]]
260 T* allocate( size_t n, const void* = nullptr )
261 {
262 if( n == 1 )
263 return reinterpret_cast<T*>( recycler.Get( sizeof(T),
264 alignof(T)
265 ALIB_DBG(, typeid(T) ) ) );
266
267 return reinterpret_cast<T*>( recycler.AllocUnrelated( sizeof(T) * n,
268 alignof(T)
269 ALIB_DBG(, typeid(T) ) ) );
270 }
271
272 //==============================================================================================
273 /// Implementation of <c>std::allocator</c> interface.
274 /// Dependent on whether a single or multiple objects are de-allocated (parameter \p{n}), this
275 /// method invokes either \alib{lang;RTTRAllocator::Recycle} or
276 /// \alib{lang;RTTRAllocator::RecycleChunk} on field #recycler.
277 ///
278 /// @param p Pointer to the object to deallocate.
279 /// @param n The number of objects to de-allocate.
280 //==============================================================================================
281 void deallocate( T* p, std::size_t n )
282 {
283 // deallocate node
284 if( n == 1 ) recycler.Recycle( p, sizeof(T) , alignof(T) ALIB_DBG(, typeid(T) ) );
285 else recycler.RecycleChunk ( p, sizeof(T) * n ALIB_DBG(, typeid(T) ) );
286 }
287}; // struct StdContainerAllocatorRecycling
288
289} // namespace [alib::lang]
290
291
#define ALIB_EXPORT
Definition alib.inl:488
#define ALIB_DBG(...)
Definition alib.inl:836
AllocatorInterface< TAllocator > AI() const noexcept
TAllocator & GetAllocator() const noexcept
AllocatorMember()=delete
Deleted default constructor. (The allocator has to be given with construction)
constexpr StdContainerAllocatorRecycling(RTTRAllocator< TAllocator > &pRecycler)
bool operator==(const StdContainerAllocatorRecycling< U, TAllocator > &rhs) const noexcept
T * allocate(size_t n, const void *=nullptr)
constexpr StdContainerAllocatorRecycling(const StdContainerAllocatorRecycling &) noexcept=default
Defaulted copy constructor.
constexpr StdContainerAllocatorRecycling(StdContainerAllocatorRecycling &&) noexcept=default
Defaulted move constructor.
bool operator!=(const StdContainerAllocatorRecycling< U, TAllocator > &rhs) const noexcept
RTTRAllocator< TAllocator > & recycler
The only member of this allocator type used to perform all duties.
StdContainerAllocator()=default
Parameterless constructor used with heap allocation.
bool operator==(const StdContainerAllocator< U, TAllocator > &rhs) const noexcept
constexpr StdContainerAllocator(const StdContainerAllocator &) noexcept=default
Defaulted copy constructor.
constexpr StdContainerAllocator(StdContainerAllocator &&) noexcept=default
Defaulted move constructor.
StdContainerAllocator(const StdContainerAllocator< TSibling, TAllocator > &origin)
T * allocate(size_t n, const void *=nullptr)
AllocatorMember< TAllocator > allocBase
The allocator type that TAllocator specifies.
bool operator!=(const StdContainerAllocator< U, TAllocator > &rhs) const noexcept
const T & const_reference
Type definition as required by C++ library standards.
std::false_type is_always_equal
Type definition as required by C++ library standards.
T value_type
Type definition as required by C++ library standards.
TAllocator AllocatorType
The allocator type that TAllocator specifies.
T & reference
Type definition as required by C++ library standards.
size_t size_type
Type definition as required by C++ library standards.
ptrdiff_t difference_type
Type definition as required by C++ library standards.