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__) 30 State(){} 31 #endif 32 33 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 37 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__) 65 StackAllocator(){} 66 #endif 67 68 StackAllocator(char *beg, char *end) 69 : m_state(beg, end) {} 70 71 const State& getState() const { return m_state; } 72 #if !defined (STLPORT) || defined (_STLP_MEMBER_TEMPLATES) 73 template <class _OtherTp> 74 StackAllocator(StackAllocator<_OtherTp> const& other) 75 : m_state(other.getState()) {} 76 #else 77 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: 113 _Tp* _M_allocate(size_type n, size_type &new_n) { 114 new_n = n; 115 return allocate(n); 116 } 117 #endif 118 119 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 135 pointer address(reference __x) const {return &__x;} 136 const_pointer address(const_reference __x) const { return &__x; } 137 size_type max_size() const { return m_state.m_end - *m_state.m_sharedCur; } 138 void construct(pointer __p, const_reference __val) { new(__p) _Tp(__val); } 139 void destroy(pointer __p) { __p->~_Tp(); } 140 141 bool ok() const { return m_state.m_isOk && (m_state.m_nbAlloc == 0); } 142 void reset () { 143 m_state.m_cur = m_state.m_beg; 144 m_state.m_isOk = true; 145 m_state.m_swaped = false; 146 } 147 bool swaped() const { return m_state.m_swaped; } 148 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) 155 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>& 177 __stl_alloc_rebind(StackAllocator<_Tp1>& __a, const _Tp2*) { return (StackAllocator<_Tp2>&)(__a); } 178 template <class _Tp1, class _Tp2> 179 inline StackAllocator<_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> 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 191 inline void swap(StackAllocator<int>& __a, StackAllocator<int>& __b) 192 { __a.swap(__b); } 193 inline void swap(StackAllocator<char>& __a, StackAllocator<char>& __b) 194 { __a.swap(__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