-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathAllocator.cpp
More file actions
149 lines (115 loc) · 4.38 KB
/
Allocator.cpp
File metadata and controls
149 lines (115 loc) · 4.38 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
// =====================================================================================
// Allocator.cpp // Allocator
// =====================================================================================
module modern_cpp:allocator;
import :dummy;
namespace Allocator {
static void test_01_allocator() {
std::allocator<int> myIntAlloc; // default allocator for ints
int* ip = myIntAlloc.allocate(3); // space for three ints
*ip = 123; // access memory (write)
*(ip+1) = 456; // access memory (write)
*(ip+2) = 789; // access memory (write)
std::cout << ip[0] << std::endl; // access memory (read)
std::cout << ip[1] << std::endl; // access memory (read)
std::cout << ip[2] << std::endl; // access memory (read)
// note: size (2. parameter for deallocate not necessarily needed,
// but: std::allocator is an abstraction over an underlying memory model
myIntAlloc.deallocate(ip, 3); // deallocate space for ints
}
// Minimalistic C++11 allocator with debug output
template <typename T>
struct MyAlloc {
// An allocator that is used to acquire/release memory
// and to construct/destroy the elements in that memory.
// The type must meet the requirements of Allocator.
// The behavior is undefined if Allocator::value_type is not the same as T
typedef T value_type;
MyAlloc() = default;
template <class TP>
MyAlloc(const MyAlloc<TP>& alloc) {
std::cout << __FUNCSIG__ << std::endl;
}
T* allocate(std::size_t n);
void deallocate(T* p, std::size_t n);
};
template <class T>
T* MyAlloc<T>::allocate(std::size_t n) {
n = n * sizeof(T);
std::cout << "allocating " << n << " bytes" << std::endl;
return static_cast<T*>(::operator new(n));
}
template <class T>
void MyAlloc<T>::deallocate(T* p, std::size_t n) {
std::cout << "deallocating " << n * sizeof(T) << " bytes" << std::endl;
::operator delete(p);
}
template <class T, class U>
bool operator==(const MyAlloc<T>&, const MyAlloc<U>&) {
return true;
}
template <class T, class U>
bool operator!=(const MyAlloc<T>&, const MyAlloc<U>&) {
return false;
}
/*
* Note:
*
* Watch difference between executions with and without
* 'vec.reserve' invocation
*/
constexpr int Max = 50;
static void test_02_allocator() {
std::vector<int, MyAlloc<int>> vec;
// vec.reserve(Max); // put into comments ... or not
for (int n = 0; n < Max; ++n) {
std::cout << " ==> push_back(" << n << ")" << std::endl;
vec.push_back(n);
}
}
// =================================================================================
/*
* Note:
*
* Watch difference between executions with and without
* 'vec.reserve' invocation
*/
constexpr int AnotherMax = 5;
static void test_03a_allocator() {
std::cout << "Insertion: push_back - Object by LValue reference" << std::endl;
std::vector<Dummy, MyAlloc<Dummy>> vec;
// vec.reserve(AnotherMax); // put into comments ... or not
for (int n = 0; n < AnotherMax; ++n) {
Dummy dummy(n);
vec.push_back(dummy);
}
}
static void test_03b_allocator() {
std::cout << "Insertion: push_back - Object by RValue reference" << std::endl;
std::vector<Dummy, MyAlloc<Dummy>> vec;
// vec.reserve(AnotherMax); // put into comments ... or not
for (int n = 0; n < AnotherMax; ++n) {
vec.push_back(Dummy(n));
}
}
static void test_03c_allocator() {
std::cout << "Insertion: emplace_back" << std::endl;
std::vector<Dummy, MyAlloc<Dummy>> vec;
// vec.reserve(AnotherMax); // put into comments ... or not
for (int n = 0; n < AnotherMax; ++n) {
vec.emplace_back(n);
}
}
}
void main_allocator()
{
using namespace Allocator;
test_01_allocator();
test_02_allocator();
test_03a_allocator();
test_03b_allocator();
test_03c_allocator();
}
// =====================================================================================
// End-of-File
// =====================================================================================