rheolef  6.3
stack_allocator.h
Go to the documentation of this file.
1 #ifndef _RHEOLEF_STACK_ALLOCATOR_H
2 #define _RHEOLEF_STACK_ALLOCATOR_H
3 
4 #include <memory>
5 #include <limits>
6 #include "rheolef/compiler.h"
7 #include "rheolef/pretty_name.h"
8 
9 namespace rheolef {
10 
44 //<begin_verbatim:
45 template <typename T>
47 protected:
48  struct handler_type; // forward declaration:
49 public:
50 
51 
52  typedef size_t size_type;
53  typedef std::ptrdiff_t difference_type;
54  typedef T* pointer;
55  typedef const T* const_pointer;
56  typedef T& reference;
57  typedef const T& const_reference;
58  typedef T value_type;
59 
60 
61  stack_allocator() throw()
62  : handler (new handler_type)
63  {
64  }
65  stack_allocator (unsigned char* stack, size_t stack_size) throw()
66  : handler (new handler_type (stack, stack_size))
67  {
68  warning_macro ("stack_allocator cstor");
69  }
70  stack_allocator (const stack_allocator& sa) throw()
71  : handler (sa.handler)
72  {
74  }
75  template <typename U>
76  stack_allocator (const stack_allocator<U>& sa) throw()
77  : handler ((typename stack_allocator<T>::handler_type*)(sa.handler))
78  {
80  }
81  ~stack_allocator() throw()
82  {
83  warning_macro ("stack_allocator dstor");
84  check_macro (handler != NULL, "unexpected null mem_info");
85  if (--handler->reference_count == 0) delete handler;
86  }
87  template <typename U>
88  struct rebind {
90  };
91 
92 
94  {
95  handler = sa.handler;
97  return *this;
98  }
99 
100 
101  pointer address (reference r) const { return &r; }
102  const_pointer address (const_reference c) const { return &c; }
103  size_type max_size() const { return std::numeric_limits<size_t>::max() / sizeof(T); }
104 
105 // in-place construction/destruction
106 
108  {
109  new( reinterpret_cast<void*>(p) ) T(c);
110  }
111  void construct (pointer p) { new ( reinterpret_cast<void*>(p) ) T(); }
112 
113  void destroy (pointer p)
114  {
115  (p)->~T();
116  }
117 
118 
119  pointer allocate (size_type n, const void* = NULL)
120  {
121  warning_macro ("allocate "<<n<<" type " << typename_macro(T));
122  check_macro (handler->stack != NULL, "unexpected null stack");
123  void* p = handler->stack + handler->allocated_size;
124  handler->allocated_size += n*sizeof(T);
125 
126  if (handler->allocated_size + 1 > handler->max_size) {
127  warning_macro ("stack is full: throwing...");
128  throw std::bad_alloc();
129  }
130  return pointer (p);
131  }
133  {
134  warning_macro ("deallocate "<<n<<" type "<<typename_macro(T));
135  }
136  const handler_type* get_handler() const {
137  return handler;
138  }
139 
140 
141 protected:
142  struct handler_type {
143  unsigned char* stack;
145  size_t max_size;
147 
149  : stack (NULL),
150  allocated_size (0),
151  max_size (0),
152  reference_count (1)
153  {
154  warning_macro ("stack_allocator::mem_info cstor NULL");
155  }
156  handler_type (unsigned char* stack1, size_t size1)
157  : stack (stack1),
158  allocated_size (0),
159  max_size (size1),
160  reference_count (1)
161  {
162  warning_macro ("stack_allocator::mem_info cstori: size="<<max_size);
163  }
165  {
166  warning_macro ("stack_allocator::mem_info dstor: size="<<max_size);
167  }
168  };
170  template <typename U> friend class stack_allocator;
171 };
172 template <typename T1>
173 bool operator==( const stack_allocator<T1>& lhs, const stack_allocator<T1>& rhs) throw()
174 {
175  return lhs.get_handler() == rhs.get_handler();
176 }
177 template <typename T1>
178 bool operator!=( const stack_allocator<T1>& lhs, const stack_allocator<T1>& rhs) throw()
179 {
180  return lhs.get_handler() != rhs.get_handler();
181 }
182 //>end_verbatim:
183 
184 } // namespace rheolef
185 #endif // STACK_ALLOCATOR_H
186