-
Notifications
You must be signed in to change notification settings - Fork 0
/
alligator.h
95 lines (78 loc) · 2.09 KB
/
alligator.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
#pragma once
#include <memory>
#include <vector>
template <typename T, unsigned const BuffSize = 10>
struct custom_alligator {
using value_type = T;
using pointer = T*;
using const_pointer = const T*;
using reference = T&;
using const_reference = const T&;
using size_type = std::size_t;
template <typename U>
struct rebind {
using other = custom_alligator<U>;
};
custom_alligator() : is_buff_(true) {
buffer_.reserve(BuffSize);
}
~custom_alligator() {
if (is_buff()) {
for (const auto& p : head_) {
std::free(p);
}
}
}
custom_alligator(const custom_alligator<T, BuffSize>& alligator) {
is_buff_ = alligator.is_buff();
}
template<typename U>
explicit custom_alligator(const custom_alligator<U>&) {
is_buff_ = false;
}
pointer allocate(const size_type n) {
if (is_buff() && n == 1) {
if (buffer_.empty()) {
auto* p = std::malloc(BuffSize*sizeof(T));
if (!p) {
throw std::bad_alloc();
}
auto* alligator_type = reinterpret_cast<pointer>(p);
for (size_type i = 1; i < BuffSize; ++i) {
buffer_.emplace_back(alligator_type + i);
}
head_.emplace_back(alligator_type);
}
pointer p = buffer_.at(buffer_.size() - 1);
buffer_.pop_back();
return p;
}
else {
auto* p = std::malloc(n*sizeof(T));
if (!p) {
throw std::bad_alloc();
}
return reinterpret_cast<pointer>(p);
}
}
void deallocate(pointer p, size_type n) {
if (is_buff() && n == 1) {
buffer_.emplace_back(p);
}
else {
std::free(p);
}
}
template<typename U, typename ...Args>
void construct(U *p, Args &&...args) {
new(p) U(std::forward<Args>(args)...);
}
void destroy(pointer p) {
p->~value_type();
}
bool is_buff() const { return is_buff_; }
private:
bool is_buff_;
std::vector<pointer> buffer_;
std::vector<pointer> head_;
};