Provided by: librheolef-dev_5.93-2_i386 bug

NAME

       stack_allocator - stack-based allocator

DESCRIPTION

       Stack-based  allocator, conform to the STL specification of allocators.
       Designed to use stack-based data passed as a parameter to the allocator
       constructor.   Does  not  "free"  the  memory.   Assumes  that  if  the
       allocator is copied, stack memory is cleared and new allocations  begin
       at the bottom of the stack again.

       Also works with any memory buffer, including heap memory. If the caller
       passes in heap memory,  the  caller  is  responsible  for  freeing  the
       memory.

       This  allocator  handles  a  limited  area  of memory: if this limit is
       reached, a "std::bad_alloc" exception is emmited.   For  a  non-limited
       memory handler in the same spirit, see "heap_allocator"(9).

EXAMPLE

           const size_t stack_size = 1024;
           vector<unsigned char> stack (stack_size);
           stack_allocator<double> stack_alloc (stack.begin().operator->(), stack.size());
           typedef map <size_t, double, less<size_t>, stack_allocator<pair<size_t,double> > >  map_type;
           map_type a (less<size_t>(), stack_alloc);
           a.insert (make_pair (0, 3.14));
           a.insert (make_pair (1, 1.17));
           for (map_type::iterator iter = a.begin(), last = a.end(); iter != last; iter++) {
             cout << (*iter).first << " " << (*iter).second << endl;
           }

IMPLEMENTATION

       template <typename T>
       class stack_allocator {
       protected:
           struct handler_type; // forward declaration:
       public:

       // typedefs:

           typedef size_t    size_type;
           typedef ptrdiff_t difference_type;
           typedef T*        pointer;
           typedef const T*  const_pointer;
           typedef T&        reference;
           typedef const T&  const_reference;
           typedef T         value_type;

       // constructors:

           stack_allocator() throw()
             : handler (new handler_type)
           {
           }
           stack_allocator (unsigned char* stack, size_t stack_size) throw()
             : handler (new handler_type (stack, stack_size))
           {
               warning_macro ("stack_allocator cstor");
           }
           stack_allocator (const stack_allocator& sa) throw()
             : handler (sa.handler)
           {
               ++handler->reference_count;
           }
           template <typename U>
           stack_allocator (const stack_allocator<U>& sa) throw()
             : handler ((typename stack_allocator<T>::handler_type*)(sa.handler))
           {
               ++handler->reference_count;
           }
           ~stack_allocator() throw()
           {
               warning_macro ("stack_allocator dstor");
               check_macro (handler != NULL, "unexpected null mem_info");
               if (--handler->reference_count == 0) delete handler;
           }
           // Rebind to allocators of other types
           template <typename U>
           struct rebind {
               typedef stack_allocator<U> other;
           };

       // assignement:

           stack_allocator& operator= (const stack_allocator& sa)
           {
               handler = sa.handler;
               ++handler->reference_count;
               return *this;
           }

       // utility functions:

           pointer       address (reference r)       const { return &r; }
           const_pointer address (const_reference c) const { return &c; }
           size_type     max_size() const { return std::numeric_limits<size_t>::max() / sizeof(T); }

       // in-place construction/destruction

           void construct (pointer p, const_reference c)
           {
               // placement new operator:
               new( reinterpret_cast<void*>(p) ) T(c);
           }
           void destroy (pointer p)
           {
               // call destructor directly:
               (p)->~T();
           }

       // allocate raw memory

           pointer allocate (size_type n, const void* = NULL)
           {
               warning_macro ("allocate "<<n<<" type " << typename_macro(T));
               check_macro (handler->stack != NULL, "unexpected null stack");
               void* p = handler->stack + handler->allocated_size;
               handler->allocated_size += n*sizeof(T);

               if (handler->allocated_size + 1 > handler->max_size) {
                   warning_macro ("stack is full: throwing...");
                   throw std::bad_alloc();
               }
               return pointer (p);
           }
           void deallocate (pointer p, size_type n)
           {
               warning_macro ("deallocate "<<n<<" type "<<typename_macro(T));
               // No need to free stack memory
           }
           const handler_type* get_handler() const {
               return handler;
           }

       // data:

       protected:
           struct handler_type {
               unsigned char* stack;
               size_t         allocated_size;
               size_t         max_size;
               size_t         reference_count;

               handler_type()
                 : stack (NULL),
                   allocated_size (0),
                   max_size (0),
                   reference_count (1)
               {
                 warning_macro ("stack_allocator::mem_info cstor NULL");
               }
               handler_type (unsigned char* stack1, size_t size1)
                 : stack (stack1),
                   allocated_size (0),
                   max_size (size1),
                   reference_count (1)
               {
                 warning_macro ("stack_allocator::mem_info cstori: size="<<max_size);
               }
               ~handler_type()
               {
                 warning_macro ("stack_allocator::mem_info dstor: size="<<max_size);
               }
           };
           handler_type* handler;
           template <typename U> friend class stack_allocator;
       };
       // Comparison
       template <typename T1>
       bool operator==( const stack_allocator<T1>& lhs, const stack_allocator<T1>& rhs) throw()
       {
           return lhs.get_handler() == rhs.get_handler();
       }
       template <typename T1>
       bool operator!=( const stack_allocator<T1>& lhs, const stack_allocator<T1>& rhs) throw()
       {
           return lhs.get_handler() != rhs.get_handler();
       }