2 Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
5 * @file AthAllocators/ArenaPoolSTLAllocator.icc
8 * @brief STL-style allocator wrapper for @c ArenaPoolAllocator.
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 ArenaPoolSTLAllocator_initParams<T>::ArenaPoolSTLAllocator_initParams
33 (size_t nblock /*= 1000*/, const std::string& name /*= ""*/)
40 * @brief Return an initialized parameters structure.
43 ArenaAllocatorBase::Params ArenaPoolSTLAllocator_initParams<T>::params() const
45 // Do the base class stuff.
46 ArenaAllocatorBase::Params p =
47 Base::operator ArenaAllocatorBase::Params();
58 * @brief Default constructor.
59 * @param nblock Value to set in the parameters structure for the
60 * number of elements to allocate per block.
61 * @param name Value to set in the parameters structure for the
64 template <class T, class VETO>
65 // False positive --- cppcheck doesn't grok template specialization
66 // cppcheck-suppress uninitMemberVar
67 ArenaPoolSTLAllocator<T, VETO>::ArenaPoolSTLAllocator
68 (size_t nblock /*= 1000*/, const std::string& name /*= ""*/)
69 : m_pool (ArenaPoolSTLAllocator_initParams<T> (nblock, name))
75 * @brief Copy constructor.
77 * The @c name and @c nblock parameters are copied, but the data are not.
79 template <class T, class VETO>
80 ArenaPoolSTLAllocator<T, VETO>::ArenaPoolSTLAllocator
81 (const ArenaPoolSTLAllocator& a)
82 : m_pool (ArenaPoolSTLAllocator_initParams<T> (a.nblock(), a.name()))
88 * @brief Constructor from another @c ArenaPoolSTLAllocator.
90 * The @c name and @c nblock parameters are copied, but the data are not.
92 template <class T, class VETO>
93 template <class U, class V>
94 // False positive --- cppcheck doesn't grok template specialization
95 // cppcheck-suppress uninitMemberVar
96 ArenaPoolSTLAllocator<T, VETO>::ArenaPoolSTLAllocator
97 (const ArenaPoolSTLAllocator<U, V>& a)
98 : m_pool (ArenaPoolSTLAllocator_initParams<T> (a.nblock(), a.name()))
104 * @brief Move constructor.
108 template <class T, class VETO>
109 ArenaPoolSTLAllocator<T, VETO>::ArenaPoolSTLAllocator
110 (ArenaPoolSTLAllocator&& a)
111 : m_pool (std::move (a.m_pool))
117 * @brief Move constructor.
121 template <class T, class VETO>
122 ArenaPoolSTLAllocator<T, VETO>&
123 ArenaPoolSTLAllocator<T, VETO>::operator= (ArenaPoolSTLAllocator&& a)
126 m_pool = std::move (a.m_pool);
135 template <class T, class VETO>
136 void ArenaPoolSTLAllocator<T, VETO>::swap (ArenaPoolSTLAllocator& a)
138 m_pool.swap (a.m_pool);
143 * @brief Equality test.
145 * Two allocators should compare equal if objects allocated by one
146 * can be deallocated by the other. We should just check if they
147 * are the same object.
149 template <class T, class VETO>
151 bool ArenaPoolSTLAllocator<T, VETO>::operator==
152 (const ArenaPoolSTLAllocator& other) const
154 return this == &other;
159 * @brief Inequality test.
161 * Two allocators should compare equal if objects allocated by one
162 * can be deallocated by the other. We should just check if they
163 * are the same object.
165 template <class T, class VETO>
167 bool ArenaPoolSTLAllocator<T, VETO>::operator!=
168 (const ArenaPoolSTLAllocator& other) const
170 return this != &other;
175 * @brief Return allocator to use for a copy-constructed container.
177 * When we copy-construct a container, we want the new allocator
178 * to copy parameters from the old one, but not the data.
180 template <class T, class VETO>
182 ArenaPoolSTLAllocator<T, VETO>
183 ArenaPoolSTLAllocator<T, VETO>::select_on_container_copy_construction() const
185 return ArenaPoolSTLAllocator (nblock(), name());
190 * @brief Convert a reference to an address.
192 template <class T, class VETO>
194 typename ArenaPoolSTLAllocator<T, VETO>::pointer
195 ArenaPoolSTLAllocator<T, VETO>::address (reference x) const
202 * @brief Allocate new objects.
203 * @param n Number of objects to allocate. Must be 1.
204 * @param hint Allocation hint. Not used.
206 template <class T, class VETO>
208 typename ArenaPoolSTLAllocator<T, VETO>::pointer
209 ArenaPoolSTLAllocator<T, VETO>::allocate (size_type
210 #if !defined(NDEBUG) && !defined(__CLING__)
213 , const void* /*hint = 0*/)
215 #if !defined(__CLING__)
218 return reinterpret_cast<pointer> (m_pool.allocate());
223 * @brief Deallocate objects.
224 * @param n Number of objects to deallocate. Must be 1.
226 * This implementation doesn't do anything.
228 template <class T, class VETO>
230 void ArenaPoolSTLAllocator<T, VETO>::deallocate (pointer, size_type
231 #if !defined(NDEBUG) && !defined(__CLING__)
236 #if !defined(__CLING__)
243 * @brief Return the maximum number of objects we can allocate at once.
245 * This always returns 1.
247 template <class T, class VETO>
249 typename ArenaPoolSTLAllocator<T, VETO>::size_type
250 ArenaPoolSTLAllocator<T, VETO>::max_size() const throw()
257 * @brief Call the @c T constructor.
258 * @param p Location of the memory.
259 * @param args Arguments to pass to the constructor.
261 template <class T, class VETO>
262 template <class... Args>
264 void ArenaPoolSTLAllocator<T, VETO>::construct (pointer p, Args&&... args)
266 new (p) T(std::forward<Args>(args)...);
271 * @brief Call the @c T destructor.
272 * @param p Location of the memory.
274 template <class T, class VETO>
276 void ArenaPoolSTLAllocator<T, VETO>::destroy (pointer p)
283 * @brief Return the hinted number of objects allocated per block.
285 template <class T, class VETO>
287 size_t ArenaPoolSTLAllocator<T, VETO>::nblock() const
289 return m_pool.params().nblock;
294 * @brief Return the name of this allocator.
296 template <class T, class VETO>
298 const std::string& ArenaPoolSTLAllocator<T, VETO>::name() const
300 return m_pool.name();
305 * @brief Free all allocated elements.
307 * All elements allocated are returned to the free state.
308 * @c clear should be called on them if it was provided.
309 * The elements may continue to be cached internally, without
310 * returning to the system.
312 template <class T, class VETO>
313 void ArenaPoolSTLAllocator<T, VETO>::reset()
320 * @brief Free all allocated elements and release memory back to the system.
322 * All elements allocated are freed, and all allocated blocks of memory
323 * are released back to the system.
324 * @c destructor should be called on them if it was provided
325 * (preceded by @c clear if provided and @c mustClear was set).
327 template <class T, class VETO>
328 void ArenaPoolSTLAllocator<T, VETO>::erase()
335 * @brief Set the total number of elements cached by the allocator.
336 * @param size The desired pool size.
338 * This allows changing the number of elements that are currently free
339 * but cached. Any allocated elements are not affected by this call.
341 * If @c size is greater than the total number of elements currently
342 * cached, then more will be allocated. This will preferably done
343 * with a single block, but that is not guaranteed; in addition, the
344 * allocator may allocate more elements than is requested.
346 * If @c size is smaller than the total number of elements currently
347 * cached, as many blocks as possible will be released back to the system.
348 * It may not be possible to release the number of elements requested;
349 * this should be implemented on a best-effort basis.
351 template <class T, class VETO>
352 void ArenaPoolSTLAllocator<T, VETO>::reserve (size_t size)
354 m_pool.reserve (size);
359 * @brief Return the statistics block for this allocator.
361 template <class T, class VETO>
362 ArenaAllocatorBase::Stats ArenaPoolSTLAllocator<T, VETO>::stats() const
364 return m_pool.stats();
369 * @brief Return a pointer to the underlying allocator (may be 0).
371 template <class T, class VETO>
372 const ArenaBlockAllocatorBase* ArenaPoolSTLAllocator<T, VETO>::poolptr() const
379 * @brief Write-protect the memory managed by this allocator.
381 * Adjust protection on the memory managed by this allocator
382 * to disallow writes.
384 template <class T, class VETO>
386 void ArenaPoolSTLAllocator<T, VETO>::protect()
393 * @brief Write-enable the memory managed by this allocator.
395 * Adjust protection on the memory managed by this allocator
398 template <class T, class VETO>
400 void ArenaPoolSTLAllocator<T, VETO>::unprotect()
406 //****************************************************************************
407 // Pointer specialization.
412 * @brief Default constructor.
413 * @param nblock Value to set in the parameters structure for the
414 * number of elements to allocate per block.
415 * @param name Value to set in the parameters structure for the
418 template <class T, class VETO>
419 ArenaPoolSTLAllocator<T*, VETO>::ArenaPoolSTLAllocator
420 (size_t nblock /*= 1000*/, const std::string& name /*= ""*/)
428 * @brief Constructor from another @c ArenaPoolSTLAllocator.
430 * The @c name and @c nblock parameters are copied, but the data are not.
432 template <class T, class VETO>
433 template <class U, class V>
434 ArenaPoolSTLAllocator<T*, VETO>::ArenaPoolSTLAllocator
435 (const ArenaPoolSTLAllocator<U, V>&)
441 * @brief Return the hinted number of objects allocated per block.
443 template <class T, class VETO>
445 size_t ArenaPoolSTLAllocator<T*, VETO>::nblock() const
452 * @brief Return the name of this allocator.
454 template <class T, class VETO>
456 const std::string& ArenaPoolSTLAllocator<T*, VETO>::name() const
462 //****************************************************************************
463 // Vetoed specialization.
466 #define ATHVETO typename std::enable_if<!std::is_pointer_v<T>, T>::type
469 * @brief Default constructor.
470 * @param nblock Value to set in the parameters structure for the
471 * number of elements to allocate per block.
472 * @param name Value to set in the parameters structure for the
476 ArenaPoolSTLAllocator<T, ATHVETO>::ArenaPoolSTLAllocator
477 (size_t nblock /*= 1000*/, const std::string& name /*= ""*/)
486 * @brief Constructor from another @c ArenaPoolSTLAllocator.
488 * The @c name and @c nblock parameters are copied, but the data are not.
491 template <class U, class V>
492 ArenaPoolSTLAllocator<T, ATHVETO>::ArenaPoolSTLAllocator
493 (const ArenaPoolSTLAllocator<U, V>& a)
494 : m_nblock (a.nblock()),
496 m_poolptr (a.poolptr())
502 * @brief Return the hinted number of objects allocated per block.
506 size_t ArenaPoolSTLAllocator<T, ATHVETO>::nblock() const
513 * @brief Return the name of this allocator.
517 const std::string& ArenaPoolSTLAllocator<T, ATHVETO>::name() const
524 * @brief Return the statistics block for this allocator.
527 ArenaAllocatorBase::Stats
528 ArenaPoolSTLAllocator<T, ATHVETO>::stats() const
531 return m_poolptr->stats();
533 return ArenaAllocatorBase::Stats();
538 * @brief Return a pointer to the underlying allocator (may be 0).
541 const ArenaBlockAllocatorBase* ArenaPoolSTLAllocator<T, ATHVETO>::poolptr() const
547 //****************************************************************************
548 // Non-const variant.
553 * @brief Constructor.
554 * @param a Allocator to reference.
555 * @param poolptr_nc Non-const pointer to the underlying allocator.
558 template <class U, class V>
559 ArenaNonConstPoolSTLAllocator<T>::ArenaNonConstPoolSTLAllocator
560 (const ArenaPoolSTLAllocator<U, V>& a,
561 ArenaBlockAllocatorBase* poolptr_nc)
562 : ArenaPoolSTLAllocator<T, T>(a),
563 m_poolptr_nc (poolptr_nc)
569 * @brief Free all allocated elements.
571 * All elements allocated are returned to the free state.
572 * @c clear should be called on them if it was provided.
573 * The elements may continue to be cached internally, without
574 * returning to the system.
577 void ArenaNonConstPoolSTLAllocator<T>::reset()
580 m_poolptr_nc->reset();
585 * @brief Free all allocated elements and release memory back to the system.
587 * All elements allocated are freed, and all allocated blocks of memory
588 * are released back to the system.
589 * @c destructor should be called on them if it was provided
590 * (preceded by @c clear if provided and @c mustClear was set).
593 void ArenaNonConstPoolSTLAllocator<T>::erase()
596 m_poolptr_nc->erase();
601 * @brief Set the total number of elements cached by the allocator.
602 * @param size The desired pool size.
604 * This allows changing the number of elements that are currently free
605 * but cached. Any allocated elements are not affected by this call.
607 * If @c size is greater than the total number of elements currently
608 * cached, then more will be allocated. This will preferably done
609 * with a single block, but that is not guaranteed; in addition, the
610 * allocator may allocate more elements than is requested.
612 * If @c size is smaller than the total number of elements currently
613 * cached, as many blocks as possible will be released back to the system.
614 * It may not be possible to release the number of elements requested;
615 * this should be implemented on a best-effort basis.
618 void ArenaNonConstPoolSTLAllocator<T>::reserve (size_t size)
621 m_poolptr_nc->reserve (size);
626 * @brief Write-protect the memory managed by this allocator.
628 * Adjust protection on the memory managed by this allocator
629 * to disallow writes.
633 void ArenaNonConstPoolSTLAllocator<T>::protect()
636 m_poolptr_nc->protect();
641 * @brief Write-enable the memory managed by this allocator.
643 * Adjust protection on the memory managed by this allocator
648 void ArenaNonConstPoolSTLAllocator<T>::unprotect()
651 m_poolptr_nc->unprotect();
656 * @brief Return an allocator supporting non-const methods from
657 * a non-const container reference.
658 * @param c The (non-const) container.
661 template <class CONT>
662 ArenaNonConstPoolSTLAllocator<T>
663 ArenaPoolSTLAllocator<T, ATHVETO>::get_allocator ATLAS_NOT_CONST_THREAD_SAFE (CONT& c)
665 // Must be called with a non-const object.
666 typename std::remove_const<CONT>::type& cc = c;
667 ArenaPoolSTLAllocator<T, T> a (cc.get_allocator());
668 return ArenaNonConstPoolSTLAllocator<T> (a,
669 const_cast<ArenaBlockAllocatorBase*>(a.poolptr()));
677 * @brief Hook for unprotecting an arena.
679 * Sometimes we need to ensure that an arena is unprotected before we start
680 * destroying an object that contains the arena. To do that without
681 * making assumptions about whether the arena supports an unprotect
682 * operation, call this function.
684 template <class T, class VETO>
685 void maybeUnprotect (ArenaPoolSTLAllocator<T, VETO>& a)