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 // cppcheck-suppress uninitMemberVar ; false positive
477 ArenaPoolSTLAllocator<T, ATHVETO>::ArenaPoolSTLAllocator
478 (size_t nblock /*= 1000*/, const std::string& name /*= ""*/)
487 * @brief Constructor from another @c ArenaPoolSTLAllocator.
489 * The @c name and @c nblock parameters are copied, but the data are not.
492 template <class U, class V>
493 ArenaPoolSTLAllocator<T, ATHVETO>::ArenaPoolSTLAllocator
494 (const ArenaPoolSTLAllocator<U, V>& a)
495 : m_nblock (a.nblock()),
497 m_poolptr (a.poolptr())
503 * @brief Return the hinted number of objects allocated per block.
507 size_t ArenaPoolSTLAllocator<T, ATHVETO>::nblock() const
514 * @brief Return the name of this allocator.
518 const std::string& ArenaPoolSTLAllocator<T, ATHVETO>::name() const
525 * @brief Return the statistics block for this allocator.
528 ArenaAllocatorBase::Stats
529 ArenaPoolSTLAllocator<T, ATHVETO>::stats() const
532 return m_poolptr->stats();
534 return ArenaAllocatorBase::Stats();
539 * @brief Return a pointer to the underlying allocator (may be 0).
542 const ArenaBlockAllocatorBase* ArenaPoolSTLAllocator<T, ATHVETO>::poolptr() const
548 //****************************************************************************
549 // Non-const variant.
554 * @brief Constructor.
555 * @param a Allocator to reference.
556 * @param poolptr_nc Non-const pointer to the underlying allocator.
559 template <class U, class V>
560 ArenaNonConstPoolSTLAllocator<T>::ArenaNonConstPoolSTLAllocator
561 (const ArenaPoolSTLAllocator<U, V>& a,
562 ArenaBlockAllocatorBase* poolptr_nc)
563 : ArenaPoolSTLAllocator<T, T>(a),
564 m_poolptr_nc (poolptr_nc)
570 * @brief Free all allocated elements.
572 * All elements allocated are returned to the free state.
573 * @c clear should be called on them if it was provided.
574 * The elements may continue to be cached internally, without
575 * returning to the system.
578 void ArenaNonConstPoolSTLAllocator<T>::reset()
581 m_poolptr_nc->reset();
586 * @brief Free all allocated elements and release memory back to the system.
588 * All elements allocated are freed, and all allocated blocks of memory
589 * are released back to the system.
590 * @c destructor should be called on them if it was provided
591 * (preceded by @c clear if provided and @c mustClear was set).
594 void ArenaNonConstPoolSTLAllocator<T>::erase()
597 m_poolptr_nc->erase();
602 * @brief Set the total number of elements cached by the allocator.
603 * @param size The desired pool size.
605 * This allows changing the number of elements that are currently free
606 * but cached. Any allocated elements are not affected by this call.
608 * If @c size is greater than the total number of elements currently
609 * cached, then more will be allocated. This will preferably done
610 * with a single block, but that is not guaranteed; in addition, the
611 * allocator may allocate more elements than is requested.
613 * If @c size is smaller than the total number of elements currently
614 * cached, as many blocks as possible will be released back to the system.
615 * It may not be possible to release the number of elements requested;
616 * this should be implemented on a best-effort basis.
619 void ArenaNonConstPoolSTLAllocator<T>::reserve (size_t size)
622 m_poolptr_nc->reserve (size);
627 * @brief Write-protect the memory managed by this allocator.
629 * Adjust protection on the memory managed by this allocator
630 * to disallow writes.
634 void ArenaNonConstPoolSTLAllocator<T>::protect()
637 m_poolptr_nc->protect();
642 * @brief Write-enable the memory managed by this allocator.
644 * Adjust protection on the memory managed by this allocator
649 void ArenaNonConstPoolSTLAllocator<T>::unprotect()
652 m_poolptr_nc->unprotect();
657 * @brief Return an allocator supporting non-const methods from
658 * a non-const container reference.
659 * @param c The (non-const) container.
662 template <class CONT>
663 ArenaNonConstPoolSTLAllocator<T>
664 ArenaPoolSTLAllocator<T, ATHVETO>::get_allocator ATLAS_NOT_CONST_THREAD_SAFE (CONT& c)
666 // Must be called with a non-const object.
667 typename std::remove_const<CONT>::type& cc = c;
668 ArenaPoolSTLAllocator<T, T> a (cc.get_allocator());
669 return ArenaNonConstPoolSTLAllocator<T> (a,
670 const_cast<ArenaBlockAllocatorBase*>(a.poolptr()));
678 * @brief Hook for unprotecting an arena.
680 * Sometimes we need to ensure that an arena is unprotected before we start
681 * destroying an object that contains the arena. To do that without
682 * making assumptions about whether the arena supports an unprotect
683 * operation, call this function.
685 template <class T, class VETO>
686 void maybeUnprotect (ArenaPoolSTLAllocator<T, VETO>& a)