Last active
February 21, 2022 17:45
-
-
Save ThePhD/eda823f034775b144f328f8b916c49b5 to your computer and use it in GitHub Desktop.
A tracking allocator for mostly testing purposes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <memory> | |
#include <cstddef> | |
#include <type_traits> | |
template<typename Allocator> | |
class tracking_allocator | |
{ | |
private: | |
template <typename> | |
friend class tracking_allocator; | |
using base_alloc_traits = std::allocator_traits<Allocator>; | |
public: | |
using allocator_type = tracking_allocator; | |
using value_type = typename base_alloc_traits::value_type; | |
using pointer = typename base_alloc_traits::pointer; | |
using const_pointer = typename base_alloc_traits::const_pointer; | |
using void_pointer = typename base_alloc_traits::void_pointer; | |
using const_void_pointer = typename base_alloc_traits::const_void_pointer; | |
using difference_type = typename base_alloc_traits::difference_type; | |
using size_type = typename base_alloc_traits::size_type; | |
using propagate_on_container_copy_assignment = | |
typename base_alloc_traits::propagate_on_container_copy_assignment; | |
using propagate_on_container_move_assignment = | |
typename base_alloc_traits::propagate_on_container_move_assignment; | |
using propogate_on_container_swap = | |
typename base_alloc_traits::propagate_on_container_swap; | |
using is_always_equal = typename base_alloc_traits::is_always_equal; | |
template<typename T> | |
struct rebind { using other = tracking_allocator<typename base_alloc_traits::template rebind_alloc<T>>; }; | |
tracking_allocator() = default; | |
tracking_allocator(const tracking_allocator&) = default; | |
tracking_allocator(tracking_allocator&&) = default; | |
tracking_allocator& | |
operator=(const tracking_allocator&) = default; | |
tracking_allocator& | |
operator=(tracking_allocator&&) = default; | |
tracking_allocator(const Allocator& alloc) : _M_allocator(alloc) | |
{ | |
} | |
tracking_allocator(Allocator&& alloc) : _M_allocator(::std::move(alloc)) | |
{ | |
} | |
template <typename RightAlloc, ::std::enable_if_t<!::std::is_same_v<Allocator, RightAlloc>>* = nullptr> | |
tracking_allocator(const tracking_allocator<RightAlloc>& family) : _M_allocator(family._M_allocator) | |
{ | |
} | |
template <typename RightAlloc, ::std::enable_if_t<!::std::is_same_v<Allocator, RightAlloc>>* = nullptr> | |
tracking_allocator(tracking_allocator<RightAlloc>&& family) : _M_allocator(::std::move(family._M_allocator)) | |
{ | |
} | |
template<typename P, typename... Args> | |
void | |
construct(P* at, Args&&... args) | |
{ | |
base_alloc_traits::construct(this->get_allocator(), at, std::forward<Args>(args)...); | |
++constructions_; | |
} | |
template<typename P> | |
void | |
destroy(P* at) | |
{ | |
base_alloc_traits::destroy(this->get_allocator(), at); | |
++this->destructions_; | |
} | |
pointer | |
allocate(size_type n) | |
{ | |
pointer p = base_alloc_traits::allocate(this->get_allocator(), n); | |
++this->allocations_; | |
return p; | |
} | |
pointer | |
allocate(size_type n, const_void_pointer hint) | |
{ | |
pointer p = base_alloc_traits::allocate(this->get_allocator(), n, hint); | |
++this->allocations_; | |
return p; | |
} | |
void | |
deallocate(pointer at, size_type n) | |
{ | |
base_alloc_traits::deallocate(this->get_allocator(), at, n); | |
++this->deallocations_; | |
} | |
difference_type | |
alive() const | |
{ | |
return this->constructions_ - this->destructions_; | |
} | |
difference_type | |
allocations_alive() const | |
{ | |
return this->allocations_ - this->deallocations_; | |
} | |
difference_type | |
allocations() const | |
{ | |
return this->allocations_; | |
} | |
difference_type | |
deallocations() const | |
{ | |
return this->deallocations_; | |
} | |
difference_type | |
constructions() const | |
{ | |
return this->constructions_; | |
} | |
difference_type | |
destructions() const | |
{ | |
return this->destructions_; | |
} | |
private: | |
difference_type allocations_ = 0; | |
difference_type deallocations_ = 0; | |
difference_type constructions_ = 0; | |
difference_type destructions_ = 0; | |
Allocator _M_allocator; | |
Allocator& | |
get_allocator() | |
{ | |
return this->_M_allocator; | |
} | |
const Allocator& | |
get_allocator() const | |
{ | |
return this->_M_allocator; | |
} | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment