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