Sequoia
Loading...
Searching...
No Matches
AllocationTestUtilities.hpp
Go to the documentation of this file.
1
2// Copyright Oliver J. Rosten 2020. //
3// Distributed under the GNU GENERAL PUBLIC LICENSE, Version 3.0. //
4// (See accompanying file LICENSE.md or copy at //
5// https://www.gnu.org/licenses/gpl-3.0.en.html) //
7
8#pragma once
9
15
16namespace sequoia::testing
17{
39 template<class T, bool PropagateCopy=true, bool PropagateMove=true, bool PropagateSwap=false>
41 {
42 public:
43 using value_type = T;
44 using size_type = std::size_t;
45 using difference_type = std::ptrdiff_t;
46 using propagate_on_container_copy_assignment = std::bool_constant<PropagateCopy>;
47 using propagate_on_container_move_assignment = std::bool_constant<PropagateMove>;
48 using propagate_on_container_swap = std::bool_constant<PropagateSwap>;
49 using is_always_equal = std::false_type;
50
51 // TO DO: Remove when libc++ is updated
52 template< class U > struct rebind
53 {
55 };
56
58 : m_pAllocs{std::make_shared<int>()}, m_pDeallocs{std::make_shared<int>()}
59 {}
60
62
63 shared_counting_allocator& operator=(const shared_counting_allocator&) = default;
64
65 [[nodiscard]] T* allocate(std::size_t n)
66 {
67 const auto ptr{static_cast<T*>(::operator new(n * sizeof(T)))};
68
69 if(n) ++(*m_pAllocs);
70
71 return ptr;
72 }
73
74 void deallocate(T* p, std::size_t n)
75 {
76 ::operator delete(p);
77 if(n) ++(*m_pDeallocs);
78 }
79
80 [[nodiscard]]
81 int allocs() const noexcept { return *m_pAllocs; }
82
83 [[nodiscard]]
84 int deallocs() const noexcept { return *m_pDeallocs; }
85
86 [[nodiscard]]
87 friend bool operator==(const shared_counting_allocator&, const shared_counting_allocator&) noexcept = default;
88 private:
89 std::shared_ptr<int> m_pAllocs{}, m_pDeallocs{};
90
91#ifdef _MSC_VER
92#if _ITERATOR_DEBUG_LEVEL != 0
93
94 // The MSVC implementation for std::vector's destructor has an interesting structure
95 // for debug builds. The following ensures successful compilation.
96
97 template<class, bool, bool, bool>
98 friend class shared_counting_allocator;
99
100 shared_counting_allocator(std::shared_ptr<int> pAllocs, std::shared_ptr<int> pDeallocs)
101 : m_pAllocs{ std::move(pAllocs) }
102 , m_pDeallocs{ std::move(pDeallocs) }
103 {}
104
105 public:
106 template<class U>
107 explicit operator shared_counting_allocator<U, PropagateCopy, PropagateMove, PropagateSwap>() const
108 {
109 return {m_pAllocs, m_pDeallocs};
110 }
111#endif
112#endif
113 };
114
115 template<class T>
116 struct type_demangler;
117
118 template<class T, bool PropagateCopy, bool PropagateMove, bool PropagateSwap>
119 struct type_demangler<shared_counting_allocator<T, PropagateCopy, PropagateMove, PropagateSwap>>
120 {
121 [[nodiscard]]
122 static std::string make()
123 {
124 auto info{std::string{"shared_counting_allocator<\n\t\t"}.append(demangle<T>()).append(",\n")};
125
126 auto toString{[](bool b){ return b ? "true" : "false";}};
127
128 info.append("\t\tPropagate on copy assignment = ").append(toString(PropagateCopy)).append(",\n");
129 info.append("\t\tPropagate on move assignment = ").append(toString(PropagateMove)).append(",\n");
130 info.append("\t\tPropagate on swap = ").append(toString(PropagateSwap)).append("\n >");
131
132 return info;
133 }
134 };
135}
Traits which are sufficiently general to appear in the sequoia namespace.
Somewhat similar to std::allocator but logs (de)allocations via an counter which is shared upon copyi...
Definition: AllocationTestUtilities.hpp:41
Definition: AllocationTestUtilities.hpp:53
Specialize this struct template to customize the way in which type info is generated for a given clas...
Definition: Output.hpp:256