2 Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
5 * @file AthAllocators/ArenaHeapSTLAllocator.icc
8 * @brief STL-style allocator wrapper for @c ArenaHeapAllocator.
19 //****************************************************************************
20 // Generic specialization
26 * @param nblock Value to set in the parameters structure for the
27 * number of elements to allocate per block.
28 * @param name Value to set in the parameters structure for the
32 ArenaHeapSTLAllocator_initParams<T>::ArenaHeapSTLAllocator_initParams
33 (size_t nblock /*= 1000*/, const std::string& name /*= ""*/)
40 * @brief Return an initialized parameters structure.
43 ArenaAllocatorBase::Params ArenaHeapSTLAllocator_initParams<T>::params() const
45 // Do the base class stuff.
46 ArenaAllocatorBase::Params p =
47 Base::operator ArenaAllocatorBase::Params();
53 // Overlap link over free struct.
54 p.eltSize = std::max (sizeof(T), p.minSize);
62 * @brief Default constructor.
63 * @param nblock Value to set in the parameters structure for the
64 * number of elements to allocate per block.
65 * @param name Value to set in the parameters structure for the
68 template <class T, class VETO>
69 // cppcheck-suppress uninitMemberVar ; false positive
70 ArenaHeapSTLAllocator<T, VETO>::ArenaHeapSTLAllocator
71 (size_t nblock /*= 1000*/, const std::string& name /*= ""*/)
72 : m_pool (ArenaHeapSTLAllocator_initParams<T> (nblock, name))
78 * @brief Copy constructor.
80 * The @c name and @c nblock parameters are copied, but the data are not.
82 template <class T, class VETO>
83 // cppcheck-suppress uninitMemberVar ; false positive
84 ArenaHeapSTLAllocator<T, VETO>::ArenaHeapSTLAllocator
85 (const ArenaHeapSTLAllocator& a)
86 : m_pool (ArenaHeapSTLAllocator_initParams<T> (a.nblock(), a.name()))
92 * @brief Constructor from another @c ArenaHeapSTLAllocator.
94 * The @c name and @c nblock parameters are copied, but the data are not.
96 template <class T, class VETO>
97 template <class U, class V>
98 // cppcheck-suppress uninitMemberVar ; false positive
99 ArenaHeapSTLAllocator<T, VETO>::ArenaHeapSTLAllocator
100 (const ArenaHeapSTLAllocator<U, V>& a)
101 : m_pool (ArenaHeapSTLAllocator_initParams<T> (a.nblock(), a.name()))
107 * @brief Move constructor.
111 template <class T, class VETO>
112 ArenaHeapSTLAllocator<T, VETO>::ArenaHeapSTLAllocator
113 (ArenaHeapSTLAllocator&& a)
114 : m_pool (std::move (a.m_pool))
120 * @brief Move constructor.
124 template <class T, class VETO>
125 ArenaHeapSTLAllocator<T, VETO>&
126 ArenaHeapSTLAllocator<T, VETO>::operator= (ArenaHeapSTLAllocator&& a)
129 m_pool = std::move (a.m_pool);
138 template <class T, class VETO>
139 void ArenaHeapSTLAllocator<T, VETO>::swap (ArenaHeapSTLAllocator& a)
141 m_pool.swap (a.m_pool);
146 * @brief Equality test.
148 * Two allocators should compare equal if objects allocated by one
149 * can be deallocated by the other. We should just check if they
150 * are the same object.
152 template <class T, class VETO>
154 bool ArenaHeapSTLAllocator<T, VETO>::operator==
155 (const ArenaHeapSTLAllocator& other) const
157 return this == &other;
162 * @brief Inequality test.
164 * Two allocators should compare equal if objects allocated by one
165 * can be deallocated by the other. We should just check if they
166 * are the same object.
168 template <class T, class VETO>
170 bool ArenaHeapSTLAllocator<T, VETO>::operator!=
171 (const ArenaHeapSTLAllocator& other) const
173 return this != &other;
178 * @brief Return allocator to use for a copy-constructed container.
180 * When we copy-construct a container, we want the new allocator
181 * to copy parameters from the old one, but not the data.
183 template <class T, class VETO>
185 ArenaHeapSTLAllocator<T, VETO>
186 ArenaHeapSTLAllocator<T, VETO>::select_on_container_copy_construction() const
188 return ArenaHeapSTLAllocator (nblock(), name());
193 * @brief Convert a reference to an address.
195 template <class T, class VETO>
197 typename ArenaHeapSTLAllocator<T, VETO>::pointer
198 ArenaHeapSTLAllocator<T, VETO>::address (reference x) const
205 * @brief Allocate new objects.
206 * @param n Number of objects to allocate. Must be 1.
207 * @param hint Allocation hint. Not used.
209 template <class T, class VETO>
211 typename ArenaHeapSTLAllocator<T, VETO>::pointer
212 ArenaHeapSTLAllocator<T, VETO>::allocate (size_type
216 , const void* /*hint = 0*/)
219 return reinterpret_cast<pointer> (m_pool.allocate());
224 * @brief Deallocate objects.
225 * @param n Number of objects to deallocate. Must be 1.
227 * This implementation doesn't do anything.
229 template <class T, class VETO>
231 void ArenaHeapSTLAllocator<T, VETO>::deallocate (pointer p, size_type
238 using pointer_nc = std::remove_const_t<T>*;
239 pointer_nc pp ATLAS_THREAD_SAFE = const_cast<pointer_nc>(p);
240 m_pool.free (reinterpret_cast<ArenaHeapAllocator::pointer> (pp));
245 * @brief Return the maximum number of objects we can allocate at once.
247 * This always returns 1.
249 template <class T, class VETO>
251 typename ArenaHeapSTLAllocator<T, VETO>::size_type
252 ArenaHeapSTLAllocator<T, VETO>::max_size() const throw()
259 * @brief Call the @c T constructor.
260 * @param p Location of the memory.
261 * @param args Arguments to pass to the constructor.
263 template <class T, class VETO>
264 template <class... Args>
266 void ArenaHeapSTLAllocator<T, VETO>::construct (pointer p, Args&&... args)
268 new (p) T(std::forward<Args>(args)...);
273 * @brief Call the @c T destructor.
274 * @param p Location of the memory.
276 template <class T, class VETO>
278 void ArenaHeapSTLAllocator<T, VETO>::destroy (pointer p)
285 * @brief Return the hinted number of objects allocated per block.
287 template <class T, class VETO>
289 size_t ArenaHeapSTLAllocator<T, VETO>::nblock() const
291 return m_pool.params().nblock;
296 * @brief Return the name of this allocator.
298 template <class T, class VETO>
300 const std::string& ArenaHeapSTLAllocator<T, VETO>::name() const
302 return m_pool.name();
307 * @brief Free all allocated elements.
309 * All elements allocated are returned to the free state.
310 * @c clear should be called on them if it was provided.
311 * The elements may continue to be cached internally, without
312 * returning to the system.
314 template <class T, class VETO>
315 void ArenaHeapSTLAllocator<T, VETO>::reset()
322 * @brief Free all allocated elements and release memory back to the system.
324 * All elements allocated are freed, and all allocated blocks of memory
325 * are released back to the system.
326 * @c destructor should be called on them if it was provided
327 * (preceded by @c clear if provided and @c mustClear was set).
329 template <class T, class VETO>
330 void ArenaHeapSTLAllocator<T, VETO>::erase()
337 * @brief Set the total number of elements cached by the allocator.
338 * @param size The desired pool size.
340 * This allows changing the number of elements that are currently free
341 * but cached. Any allocated elements are not affected by this call.
343 * If @c size is greater than the total number of elements currently
344 * cached, then more will be allocated. This will preferably done
345 * with a single block, but that is not guaranteed; in addition, the
346 * allocator may allocate more elements than is requested.
348 * If @c size is smaller than the total number of elements currently
349 * cached, as many blocks as possible will be released back to the system.
350 * It may not be possible to release the number of elements requested;
351 * this should be implemented on a best-effort basis.
353 template <class T, class VETO>
354 void ArenaHeapSTLAllocator<T, VETO>::reserve (size_t size)
356 m_pool.reserve (size);
361 * @brief Return the statistics block for this allocator.
363 template <class T, class VETO>
364 ArenaAllocatorBase::Stats ArenaHeapSTLAllocator<T, VETO>::stats() const
366 return m_pool.stats();
371 * @brief Return a pointer to the underlying allocator (may be 0).
373 template <class T, class VETO>
374 const ArenaBlockAllocatorBase* ArenaHeapSTLAllocator<T, VETO>::poolptr() const
381 * @brief Write-protect the memory managed by this allocator.
383 * Adjust protection on the memory managed by this allocator
384 * to disallow writes.
386 template <class T, class VETO>
388 void ArenaHeapSTLAllocator<T, VETO>::protect()
395 * @brief Write-enable the memory managed by this allocator.
397 * Adjust protection on the memory managed by this allocator
400 template <class T, class VETO>
402 void ArenaHeapSTLAllocator<T, VETO>::unprotect()
408 //****************************************************************************
409 // Vetoed specialization.
414 * @brief Default constructor.
415 * @param nblock Value to set in the parameters structure for the
416 * number of elements to allocate per block.
417 * @param name Value to set in the parameters structure for the
421 // cppcheck-suppress uninitMemberVar ; false positive
422 ArenaHeapSTLAllocator<T, T>::ArenaHeapSTLAllocator
423 (size_t nblock /*= 1000*/, const std::string& name /*= ""*/)
432 * @brief Constructor from another @c ArenaHeapSTLAllocator.
434 * The @c name and @c nblock parameters are copied, but the data are not.
437 template <class U, class V>
438 // cppcheck-suppress uninitMemberVar ; false positive
439 ArenaHeapSTLAllocator<T, T>::ArenaHeapSTLAllocator
440 (const ArenaHeapSTLAllocator<U, V>& a)
441 : m_nblock (a.nblock()),
443 m_poolptr (a.poolptr())
449 * @brief Return the hinted number of objects allocated per block.
453 size_t ArenaHeapSTLAllocator<T, T>::nblock() const
460 * @brief Return the name of this allocator.
464 const std::string& ArenaHeapSTLAllocator<T, T>::name() const
471 * @brief Return the statistics block for this allocator.
474 ArenaAllocatorBase::Stats
475 ArenaHeapSTLAllocator<T, T>::stats() const
478 return m_poolptr->stats();
479 return ArenaAllocatorBase::Stats();
484 * @brief Return a pointer to the underlying allocator (may be 0).
487 const ArenaBlockAllocatorBase* ArenaHeapSTLAllocator<T, T>::poolptr() const
493 //****************************************************************************
494 // Non-const variant.
499 * @brief Constructor.
500 * @param a Allocator to reference.
501 * @param poolptr_nc Non-const pointer to the underlying allocator.
504 template <class U, class V>
505 ArenaNonConstHeapSTLAllocator<T>::ArenaNonConstHeapSTLAllocator
506 (const ArenaHeapSTLAllocator<U, V>& a,
507 ArenaBlockAllocatorBase* poolptr_nc)
508 : ArenaHeapSTLAllocator<T, T>(a),
509 m_poolptr_nc (poolptr_nc)
515 * @brief Free all allocated elements.
517 * All elements allocated are returned to the free state.
518 * @c clear should be called on them if it was provided.
519 * The elements may continue to be cached internally, without
520 * returning to the system.
523 void ArenaNonConstHeapSTLAllocator<T>::reset()
526 m_poolptr_nc->reset();
531 * @brief Free all allocated elements and release memory back to the system.
533 * All elements allocated are freed, and all allocated blocks of memory
534 * are released back to the system.
535 * @c destructor should be called on them if it was provided
536 * (preceded by @c clear if provided and @c mustClear was set).
539 void ArenaNonConstHeapSTLAllocator<T>::erase()
542 m_poolptr_nc->erase();
547 * @brief Set the total number of elements cached by the allocator.
548 * @param size The desired pool size.
550 * This allows changing the number of elements that are currently free
551 * but cached. Any allocated elements are not affected by this call.
553 * If @c size is greater than the total number of elements currently
554 * cached, then more will be allocated. This will preferably done
555 * with a single block, but that is not guaranteed; in addition, the
556 * allocator may allocate more elements than is requested.
558 * If @c size is smaller than the total number of elements currently
559 * cached, as many blocks as possible will be released back to the system.
560 * It may not be possible to release the number of elements requested;
561 * this should be implemented on a best-effort basis.
564 void ArenaNonConstHeapSTLAllocator<T>::reserve (size_t size)
567 m_poolptr_nc->reserve (size);
572 * @brief Write-protect the memory managed by this allocator.
574 * Adjust protection on the memory managed by this allocator
575 * to disallow writes.
579 void ArenaNonConstHeapSTLAllocator<T>::protect()
582 m_poolptr_nc->protect();
587 * @brief Write-enable the memory managed by this allocator.
589 * Adjust protection on the memory managed by this allocator
594 void ArenaNonConstHeapSTLAllocator<T>::unprotect()
597 m_poolptr_nc->unprotect();
602 * @brief Return an allocator supporting non-const methods from
603 * a non-const container reference.
604 * @param c The (non-const) container.
607 template <class CONT>
608 ArenaNonConstHeapSTLAllocator<T>
609 ArenaHeapSTLAllocator<T, T>::get_allocator ATLAS_NOT_CONST_THREAD_SAFE (CONT& c)
611 // Must be called with a non-const object.
612 typename std::remove_const<CONT>::type& cc = c;
613 ArenaHeapSTLAllocator<T, T> a (cc.get_allocator());
614 return ArenaNonConstHeapSTLAllocator<T> (a,
615 const_cast<ArenaBlockAllocatorBase*>(a.poolptr()));
620 * @brief Hook for unprotecting an arena.
622 * Sometimes we need to ensure that an arena is unprotected before we start
623 * destroying an object that contains the arena. To do that without
624 * making assumptions about whether the arena supports an unprotect
625 * operation, call this function.
627 template <class T, class VETO>
628 void maybeUnprotect (ArenaHeapSTLAllocator<T, VETO>& a)