1 #ifndef STLPORT_UNIT_TEST_STACK_ALLOCATOR_H
2 #define STLPORT_UNIT_TEST_STACK_ALLOCATOR_H
3
4 #include <algorithm>
5
6 #if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS)
7 //For bad_alloc:
8 # include <new>
9 #endif
10
11 #undef __STD
12 #if !defined (STLPORT) || defined (_STLP_USE_NAMESPACES)
13 # define __STD std::
14 #else
15 # define __STD
16 #endif
17
18 struct State {
19 char *m_beg, *m_end, *m_cur;
20 bool m_isOk, m_swaped;
21 int m_nbAlloc;
22
23 //The following members are shared among all StackAllocator instance created from
24 //a reference StackAllocator instance:
25 char **m_sharedCur;
26 bool *m_sharedOk;
27 int *m_sharedNbAlloc;
28
29 #if defined (__DMC__)
StateState30 State(){}
31 #endif
32
StateState33 State(char *beg, char *end)
34 : m_beg(beg), m_end(end), m_cur(m_beg), m_isOk(true), m_swaped(false), m_nbAlloc(0),
35 m_sharedCur(&m_cur), m_sharedOk(&m_isOk), m_sharedNbAlloc(&m_nbAlloc) {}
36
StateState37 State(const State& other)
38 : m_beg(other.m_beg), m_end(other.m_end), m_cur(0),
39 m_isOk(true), m_swaped(other.m_swaped), m_nbAlloc(0),
40 m_sharedCur(other.m_sharedCur), m_sharedOk(other.m_sharedOk),
41 m_sharedNbAlloc(other.m_sharedNbAlloc) {}
42 };
43
44 /* This allocator is not thread safe:
45 */
46 template <class _Tp>
47 struct StackAllocator
48 #if defined (STLPORT) && \
49 defined (_STLP_USE_PARTIAL_SPEC_WORKAROUND) && !defined (_STLP_FUNCTION_TMPL_PARTIAL_ORDER)
50 //Special Borland workaround that have problem with function
51 //overloading when one of the overloaded version is a template
52 //one. This is the case for the std::swap function.
53 : public __STD __stlport_class<StackAllocator<_Tp> >
54 #endif
55 {
56 typedef _Tp value_type;
57 typedef value_type * pointer;
58 typedef const _Tp* const_pointer;
59 typedef _Tp& reference;
60 typedef const _Tp& const_reference;
61 typedef size_t size_type;
62 typedef ptrdiff_t difference_type;
63
64 #if defined (__DMC__)
StackAllocatorStackAllocator65 StackAllocator(){}
66 #endif
67
StackAllocatorStackAllocator68 StackAllocator(char *beg, char *end)
69 : m_state(beg, end) {}
70
getStateStackAllocator71 const State& getState() const { return m_state; }
72 #if !defined (STLPORT) || defined (_STLP_MEMBER_TEMPLATES)
73 template <class _OtherTp>
StackAllocatorStackAllocator74 StackAllocator(StackAllocator<_OtherTp> const& other)
75 : m_state(other.getState()) {}
76 #else
StackAllocatorStackAllocator77 StackAllocator(const State& state)
78 : m_state(state) {}
79 #endif
80
81 #if !defined (STLPORT) || defined (_STLP_MEMBER_TEMPLATE_CLASSES)
82 template <class _Other>
83 struct rebind {
84 typedef StackAllocator<_Other> other;
85 };
86 #endif
87
88 _Tp* allocate(size_type n, void* = 0) {
89 if (n == 0)
90 return 0;
91
92 ++(*m_state.m_sharedNbAlloc);
93
94 if (*m_state.m_sharedCur + (n * sizeof(_Tp)) < m_state.m_end) {
95 char *ret = *m_state.m_sharedCur;
96 *m_state.m_sharedCur += n * sizeof(_Tp);
97 return reinterpret_cast<_Tp*>(ret);
98 }
99 #if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS)
100 throw __STD bad_alloc();
101 # if defined (__DMC__)
102 return 0;
103 # endif
104 #else
105 return 0;
106 #endif
107 }
108
109 #if defined (STLPORT) && \
110 defined (_STLP_USE_PARTIAL_SPEC_WORKAROUND) && !defined (_STLP_FUNCTION_TMPL_PARTIAL_ORDER)
111 //Necessary extension to make StackAllocator a real STLport allocator
112 //implementation:
_M_allocateStackAllocator113 _Tp* _M_allocate(size_type n, size_type &new_n) {
114 new_n = n;
115 return allocate(n);
116 }
117 #endif
118
deallocateStackAllocator119 void deallocate(pointer p, size_type n) {
120 if (p == 0)
121 return;
122
123 --(*m_state.m_sharedNbAlloc);
124
125 if ((char*)p == (*m_state.m_sharedCur - n * sizeof(_Tp))) {
126 *m_state.m_sharedCur -= n * sizeof(_Tp);
127 }
128
129 if ((char*)p < m_state.m_beg || (char*)p >= m_state.m_end) {
130 //An object has been returned to the bad allocator instance:
131 *m_state.m_sharedOk = false;
132 }
133 }
134
addressStackAllocator135 pointer address(reference __x) const {return &__x;}
addressStackAllocator136 const_pointer address(const_reference __x) const { return &__x; }
max_sizeStackAllocator137 size_type max_size() const { return m_state.m_end - *m_state.m_sharedCur; }
constructStackAllocator138 void construct(pointer __p, const_reference __val) { new(__p) _Tp(__val); }
destroyStackAllocator139 void destroy(pointer __p) { __p->~_Tp(); }
140
okStackAllocator141 bool ok() const { return m_state.m_isOk && (m_state.m_nbAlloc == 0); }
resetStackAllocator142 void reset () {
143 m_state.m_cur = m_state.m_beg;
144 m_state.m_isOk = true;
145 m_state.m_swaped = false;
146 }
swapedStackAllocator147 bool swaped() const { return m_state.m_swaped; }
swapStackAllocator148 void swap(StackAllocator &other) {
149 __STD swap(m_state, other.m_state);
150 m_state.m_swaped = true;
151 other.m_state.m_swaped = true;
152 }
153 #if defined (STLPORT) && \
154 defined (_STLP_USE_PARTIAL_SPEC_WORKAROUND) && !defined (_STLP_FUNCTION_TMPL_PARTIAL_ORDER)
_M_swap_workaroundStackAllocator155 void _M_swap_workaround(StackAllocator& __x) { swap(__x); }
156 #endif
157
158 //2 StackAllocator instance are identical if they are built on top
159 //of the same buffer.
160 bool operator == (StackAllocator const& other) const
161 { return m_state.m_beg == other.m_state.m_beg; }
162
163 bool operator != (StackAllocator const& other) const
164 { return !(*this == other); }
165
166 private:
167 State m_state;
168 };
169
170 #if !defined (STLPORT) || defined (_STLP_USE_NAMESPACES)
171 namespace std {
172 #endif
173
174 # if defined (STLPORT) && (defined (_STLP_DONT_SUPPORT_REBIND_MEMBER_TEMPLATE) || !defined (_STLP_MEMBER_TEMPLATES))
175 template <class _Tp1, class _Tp2>
176 inline StackAllocator<_Tp2>&
__stl_alloc_rebind(StackAllocator<_Tp1> & __a,const _Tp2 *)177 __stl_alloc_rebind(StackAllocator<_Tp1>& __a, const _Tp2*) { return (StackAllocator<_Tp2>&)(__a); }
178 template <class _Tp1, class _Tp2>
179 inline StackAllocator<_Tp2>
__stl_alloc_create(const StackAllocator<_Tp1> & __a,const _Tp2 *)180 __stl_alloc_create(const StackAllocator<_Tp1>& __a, const _Tp2*) { return StackAllocator<_Tp2>(__a.getState()); }
181 # endif
182
183 # if !defined (STLPORT) || defined (_STLP_FUNCTION_TMPL_PARTIAL_ORDER)
184 template <class _Tp>
swap(StackAllocator<_Tp> & __a,StackAllocator<_Tp> & __b)185 inline void swap(StackAllocator<_Tp>& __a, StackAllocator<_Tp>& __b)
186 { __a.swap(__b); }
187 # elif !defined (_STLP_USE_PARTIAL_SPEC_WORKAROUND)
188 //The following overloads depends on instanciation, if new unit tests are written
189 //with new StackAllocator instanciations associated swap overload should also be
190 //written
swap(StackAllocator<int> & __a,StackAllocator<int> & __b)191 inline void swap(StackAllocator<int>& __a, StackAllocator<int>& __b)
192 { __a.swap(__b); }
swap(StackAllocator<char> & __a,StackAllocator<char> & __b)193 inline void swap(StackAllocator<char>& __a, StackAllocator<char>& __b)
194 { __a.swap(__b); }
swap(StackAllocator<pair<const int,int>> & __a,StackAllocator<pair<const int,int>> & __b)195 inline void swap(StackAllocator<pair<const int, int> >& __a,
196 StackAllocator<pair<const int, int> >& __b)
197 { __a.swap(__b); }
198 # endif
199
200 #if !defined (STLPORT) || defined (_STLP_USE_NAMESPACES)
201 }
202 #endif
203
204 #undef __STD
205
206 #endif //STLPORT_UNIT_TEST_STACK_ALLOCATOR_H
207