stack_allocator.h revision e46c9386c4f79aa40185f79a19fc5b2a7ef528b3
15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#ifndef STLPORT_UNIT_TEST_STACK_ALLOCATOR_H 25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#define STLPORT_UNIT_TEST_STACK_ALLOCATOR_H 35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <algorithm> 5cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 6cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS) 75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)//For bad_alloc: 85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)# include <new> 95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif 105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 11a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#undef __STD 125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if !defined (STLPORT) || defined (_STLP_USE_NAMESPACES) 135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)# define __STD std:: 145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#else 155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)# define __STD 165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif 175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)struct State { 195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) char *m_beg, *m_end, *m_cur; 205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool m_isOk, m_swaped; 215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int m_nbAlloc; 225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) //The following members are shared among all StackAllocator instance created from 245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) //a reference StackAllocator instance: 255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) char **m_sharedCur; 265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool *m_sharedOk; 275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int *m_sharedNbAlloc; 285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined (__DMC__) 305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) State(){} 315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif 325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 33a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch State(char *beg, char *end) 34a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch : m_beg(beg), m_end(end), m_cur(m_beg), m_isOk(true), m_swaped(false), m_nbAlloc(0), 355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) m_sharedCur(&m_cur), m_sharedOk(&m_isOk), m_sharedNbAlloc(&m_nbAlloc) {} 365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) State(const State& other) 385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) : m_beg(other.m_beg), m_end(other.m_end), m_cur(0), 395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) m_isOk(true), m_swaped(other.m_swaped), m_nbAlloc(0), 405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) m_sharedCur(other.m_sharedCur), m_sharedOk(other.m_sharedOk), 415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) m_sharedNbAlloc(other.m_sharedNbAlloc) {} 425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}; 435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)/* This allocator is not thread safe: 455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) */ 465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)template <class _Tp> 475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)struct StackAllocator 485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined (STLPORT) && \ 495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) defined (_STLP_USE_PARTIAL_SPEC_WORKAROUND) && !defined (_STLP_FUNCTION_TMPL_PARTIAL_ORDER) 505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) //Special Borland workaround that have problem with function 515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) //overloading when one of the overloaded version is a template 525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) //one. This is the case for the std::swap function. 535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) : public __STD __stlport_class<StackAllocator<_Tp> > 545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif 555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles){ 565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) typedef _Tp value_type; 575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) typedef value_type * pointer; 585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) typedef const _Tp* const_pointer; 595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) typedef _Tp& reference; 605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) typedef const _Tp& const_reference; 61a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch typedef size_t size_type; 625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) typedef ptrdiff_t difference_type; 635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined (__DMC__) 655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) StackAllocator(){} 665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif 675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) StackAllocator(char *beg, char *end) 695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) : m_state(beg, end) {} 705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const State& getState() const { return m_state; } 725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if !defined (STLPORT) || defined (_STLP_MEMBER_TEMPLATES) 735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) template <class _OtherTp> 74a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch StackAllocator(StackAllocator<_OtherTp> const& other) 755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) : m_state(other.getState()) {} 765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#else 775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) StackAllocator(const State& state) 785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) : m_state(state) {} 795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif 805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if !defined (STLPORT) || defined (_STLP_MEMBER_TEMPLATE_CLASSES) 825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) template <class _Other> 835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) struct rebind { 845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) typedef StackAllocator<_Other> other; 855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) }; 865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif 875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) _Tp* allocate(size_type n, void* = 0) { 895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (n == 0) 905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return 0; 915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ++(*m_state.m_sharedNbAlloc); 93a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 94a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (*m_state.m_sharedCur + (n * sizeof(_Tp)) < m_state.m_end) { 955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) char *ret = *m_state.m_sharedCur; 965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *m_state.m_sharedCur += n * sizeof(_Tp); 975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return reinterpret_cast<_Tp*>(ret); 985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS) 1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) throw __STD bad_alloc(); 1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)# if defined (__DMC__) 1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return 0; 1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)# endif 1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#else 1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return 0; 1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif 1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined (STLPORT) && \ 1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) defined (_STLP_USE_PARTIAL_SPEC_WORKAROUND) && !defined (_STLP_FUNCTION_TMPL_PARTIAL_ORDER) 1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) //Necessary extension to make StackAllocator a real STLport allocator 1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) //implementation: 1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) _Tp* _M_allocate(size_type n, size_type &new_n) { 1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) new_n = n; 1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return allocate(n); 1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif 1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void deallocate(pointer p, size_type n) { 1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (p == 0) 121a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return; 1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) --(*m_state.m_sharedNbAlloc); 1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if ((char*)p == (*m_state.m_sharedCur - n * sizeof(_Tp))) { 1265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) *m_state.m_sharedCur -= n * sizeof(_Tp); 1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 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 166private: 167 State m_state; 168}; 169 170#if !defined (STLPORT) || defined (_STLP_USE_NAMESPACES) 171namespace std { 172#endif 173 174# if defined (STLPORT) && (defined (_STLP_DONT_SUPPORT_REBIND_MEMBER_TEMPLATE) || !defined (_STLP_MEMBER_TEMPLATES)) 175template <class _Tp1, class _Tp2> 176inline StackAllocator<_Tp2>& 177__stl_alloc_rebind(StackAllocator<_Tp1>& __a, const _Tp2*) { return (StackAllocator<_Tp2>&)(__a); } 178template <class _Tp1, class _Tp2> 179inline 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 191inline void swap(StackAllocator<int>& __a, StackAllocator<int>& __b) 192{ __a.swap(__b); } 193inline void swap(StackAllocator<char>& __a, StackAllocator<char>& __b) 194{ __a.swap(__b); } 195inline 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