-
Notifications
You must be signed in to change notification settings - Fork 0
/
ListAllocator.h
108 lines (93 loc) · 2.45 KB
/
ListAllocator.h
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
/*
* ListAllocator.h
*
* Created on: 19 мая 2019 г.
* Author: sveta
*/
#pragma once
#include <iostream>
#include <memory>
#include <string>
// I - для задания размера контейнера.
template<typename T, int I>
class logging_allocator {
public:
// Тип данных контейнера.
using value_type = T;
using pointer = T * ;
using const_pointer = const T*;
using size_type = std::size_t;
// для подсчета количества вызовов аллокатора.
int counter = 0;
T* allocated = nullptr;
template<typename U>
struct rebind {
using other = logging_allocator<U, I>;
};
explicit logging_allocator(const logging_allocator & alloc) {
this->allocated = alloc.allocated;
this->counter = alloc.counter;
};
template<typename U>
explicit logging_allocator(const logging_allocator<U,I> & alloc){
this->allocated = reinterpret_cast<T*>(alloc.allocated);
this->counter = alloc.counter;
}
logging_allocator() {
this->allocated = nullptr;
this->counter = 0;
}
pointer allocate(size_type n) {
// если заполнена вся выделенная память.
if (counter >= I) {
std::cout
<< "The size of the array can not be > " + std::to_string(I)
<< std::endl;
throw std::bad_alloc();
}
counter = counter + 1;
// первый вызов. Выделяем память под все I элементов.
if (counter == 1) {
if (I > 1 && n == 1)
n = n * I;
auto p = std::malloc(n * sizeof(T));
if (!p)
throw std::bad_alloc();
allocated = reinterpret_cast<T *>(p);
return allocated;
}
return allocated + (counter - 1);
}
void deallocate(pointer p, std::size_t n) {
if (I > 1) {
if (counter == 1) {
std::free(allocated);
allocated = NULL;
}
else {
// Чтобы значть, есть ли еще элементы.
counter--;
}
}
else {
std::free(allocated);
}
}
template<typename U, typename ...Args>
void construct(U *p, Args &&...args) {
new (p) U(std::forward<Args>(args)...);
}
void destroy(pointer p) {
p->~T();
}
template<typename U, int J>
bool operator==(const logging_allocator<U, J>& other) const noexcept
{
return this == &other;
}
template<typename U, int J>
bool operator!=(const logging_allocator<U, J>& other) const noexcept
{
return this != &other;
}
};