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