• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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