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
32ArenaPoolSTLAllocator_initParams<T>::ArenaPoolSTLAllocator_initParams
33 (size_t nblock /*= 1000*/, const std::string& name /*= ""*/)
40 * @brief Return an initialized parameters structure.
43ArenaAllocatorBase::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
64template <class T, class VETO>
65// False positive --- cppcheck doesn't grok template specialization
66// cppcheck-suppress uninitMemberVar
67ArenaPoolSTLAllocator<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.
79template <class T, class VETO>
80ArenaPoolSTLAllocator<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.
92template <class T, class VETO>
93template <class U, class V>
94// False positive --- cppcheck doesn't grok template specialization
95// cppcheck-suppress uninitMemberVar
96ArenaPoolSTLAllocator<T, VETO>::ArenaPoolSTLAllocator
97 (const ArenaPoolSTLAllocator<U, V>& a)
98 : m_pool (ArenaPoolSTLAllocator_initParams<T> (a.nblock(), a.name()))
104 * @brief Move constructor.
108template <class T, class VETO>
109ArenaPoolSTLAllocator<T, VETO>::ArenaPoolSTLAllocator
110 (ArenaPoolSTLAllocator&& a)
111 : m_pool (std::move (a.m_pool))
117 * @brief Move constructor.
121template <class T, class VETO>
122ArenaPoolSTLAllocator<T, VETO>&
123ArenaPoolSTLAllocator<T, VETO>::operator= (ArenaPoolSTLAllocator&& a)
126 m_pool = std::move (a.m_pool);
135template <class T, class VETO>
136void 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.
149template <class T, class VETO>
151bool 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.
165template <class T, class VETO>
167bool 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.
180template <class T, class VETO>
182ArenaPoolSTLAllocator<T, VETO>
183ArenaPoolSTLAllocator<T, VETO>::select_on_container_copy_construction() const
185 return ArenaPoolSTLAllocator (nblock(), name());
190 * @brief Convert a reference to an address.
192template <class T, class VETO>
194typename ArenaPoolSTLAllocator<T, VETO>::pointer
195ArenaPoolSTLAllocator<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.
206template <class T, class VETO>
208typename ArenaPoolSTLAllocator<T, VETO>::pointer
209ArenaPoolSTLAllocator<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.
228template <class T, class VETO>
230void 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.
247template <class T, class VETO>
249typename ArenaPoolSTLAllocator<T, VETO>::size_type
250ArenaPoolSTLAllocator<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.
261template <class T, class VETO>
262template <class... Args>
264void 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.
274template <class T, class VETO>
276void ArenaPoolSTLAllocator<T, VETO>::destroy (pointer p)
283 * @brief Return the hinted number of objects allocated per block.
285template <class T, class VETO>
287size_t ArenaPoolSTLAllocator<T, VETO>::nblock() const
289 return m_pool.params().nblock;
294 * @brief Return the name of this allocator.
296template <class T, class VETO>
298const 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.
312template <class T, class VETO>
313void 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).
327template <class T, class VETO>
328void 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.
351template <class T, class VETO>
352void ArenaPoolSTLAllocator<T, VETO>::reserve (size_t size)
354 m_pool.reserve (size);
359 * @brief Return the statistics block for this allocator.
361template <class T, class VETO>
362ArenaAllocatorBase::Stats ArenaPoolSTLAllocator<T, VETO>::stats() const
364 return m_pool.stats();
369 * @brief Return a pointer to the underlying allocator (may be 0).
371template <class T, class VETO>
372const 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.
384template <class T, class VETO>
386void ArenaPoolSTLAllocator<T, VETO>::protect()
393 * @brief Write-enable the memory managed by this allocator.
395 * Adjust protection on the memory managed by this allocator
398template <class T, class VETO>
400void 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
418template <class T, class VETO>
419ArenaPoolSTLAllocator<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.
432template <class T, class VETO>
433template <class U, class V>
434ArenaPoolSTLAllocator<T*, VETO>::ArenaPoolSTLAllocator
435 (const ArenaPoolSTLAllocator<U, V>&)
441 * @brief Return the hinted number of objects allocated per block.
443template <class T, class VETO>
445size_t ArenaPoolSTLAllocator<T*, VETO>::nblock() const
452 * @brief Return the name of this allocator.
454template <class T, class VETO>
456const 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
476ArenaPoolSTLAllocator<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.
491template <class U, class V>
492ArenaPoolSTLAllocator<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.
506size_t ArenaPoolSTLAllocator<T, ATHVETO>::nblock() const
513 * @brief Return the name of this allocator.
517const std::string& ArenaPoolSTLAllocator<T, ATHVETO>::name() const
524 * @brief Return the statistics block for this allocator.
527ArenaAllocatorBase::Stats
528ArenaPoolSTLAllocator<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).
541const ArenaBlockAllocatorBase* ArenaPoolSTLAllocator<T, ATHVETO>::poolptr() const
547//****************************************************************************
553 * @brief Constructor.
554 * @param a Allocator to reference.
555 * @param poolptr_nc Non-const pointer to the underlying allocator.
558template <class U, class V>
559ArenaNonConstPoolSTLAllocator<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.
577void 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).
593void 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.
618void 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.
633void 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
648void 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.
662ArenaNonConstPoolSTLAllocator<T>
663ArenaPoolSTLAllocator<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.
684template <class T, class VETO>
685void maybeUnprotect (ArenaPoolSTLAllocator<T, VETO>& a)