forked from HowardHinnant/HowardHinnant.github.io
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathstack_alloc.h
94 lines (80 loc) · 2.36 KB
/
stack_alloc.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
#ifndef STACK_ALLOC_H
#define STACK_ALLOC_H
#define HAS_TYPE_TRAITS 0
#include <cstddef>
#if HAS_TYPE_TRAITS
#include <type_traits>
#else
#include <tr1/type_traits>
#endif
template <class T, std::size_t N> class stack_alloc;
template <std::size_t N>
class stack_alloc<void, N>
{
public:
typedef const void* const_pointer;
typedef void value_type;
};
template <class T, std::size_t N>
class stack_alloc
{
public:
typedef std::size_t size_type;
typedef T value_type;
typedef value_type* pointer;
typedef const value_type* const_pointer;
typedef value_type& reference;
typedef const value_type& const_reference;
private:
#if HAS_TYPE_TRAITS
typename std::aligned_storage<sizeof(T) * N, 16>::type buf_;
#else
typename std::tr1::aligned_storage<sizeof(T) * N, 16>::type buf_;
#endif
pointer ptr_;
public:
stack_alloc() throw() : ptr_((pointer)&buf_) {}
stack_alloc(const stack_alloc&) throw() : ptr_((pointer)&buf_) {}
template <class U> stack_alloc(const stack_alloc<U, N>&) throw()
: ptr_((pointer)&buf_) {}
template <class U> struct rebind {typedef stack_alloc<U, N> other;};
private:
stack_alloc& operator=(const stack_alloc&);
public:
pointer allocate(size_type n, typename stack_alloc<void, N>::const_pointer = 0)
{
if ((pointer)&buf_ + N - ptr_ >= n)
{
pointer r = ptr_;
ptr_ += n;
return r;
}
return static_cast<pointer>(::operator new(n * sizeof(T)));
}
void deallocate(pointer p, size_type n)
{
if ((pointer)&buf_ <= p && p < (pointer)&buf_ + N)
{
if (p + n == ptr_)
ptr_ = p;
}
else
::operator delete(p);
}
size_type max_size() const throw() {return size_type(~0) / sizeof(T);}
void destroy(T* p) {p->~T();}
void
construct(pointer p)
{
::new((void*)p) T();
}
template <class A0>
void
construct(pointer p, const A0& a0)
{
::new((void*)p) T(a0);
}
bool operator==(stack_alloc& a) const {return &buf_ == &a.buf_;}
bool operator!=(stack_alloc& a) const {return &buf_ != &a.buf_;}
};
#endif // STACK_ALLOC_H