Rework return statement in FlowsDown
[openttd/fttd.git] / src / core / alloc_type.hpp
blob9c25cc9e3f91083849f745925201e59c9687b564
1 /* $Id$ */
3 /*
4 * This file is part of OpenTTD.
5 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
6 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
7 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
8 */
10 /** @file alloc_type.hpp Helper types related to the allocation of memory */
12 #ifndef ALLOC_TYPE_HPP
13 #define ALLOC_TYPE_HPP
15 #include "alloc_func.hpp"
17 /**
18 * A small 'wrapper' for allocations that can be done on most OSes on the
19 * stack, but are just too large to fit in the stack on devices with a small
20 * stack such as the NDS.
21 * So when it is possible a stack allocation is made, otherwise a heap
22 * allocation is made and this is freed once the struct goes out of scope.
23 * @param T the type to make the allocation for
24 * @param length the amount of items to allocate
26 template <typename T, size_t length>
27 struct SmallStackSafeStackAlloc {
28 #if !defined(__NDS__)
29 /** Storing the data on the stack */
30 T data[length];
31 #else
32 /** Storing it on the heap */
33 T *data;
34 /** The length (in elements) of data in this allocator. */
35 size_t len;
37 /** Allocating the memory */
38 SmallStackSafeStackAlloc() : data(MallocT<T>(length)), len(length) {}
40 /** And freeing when it goes out of scope */
41 ~SmallStackSafeStackAlloc()
43 free(data);
45 #endif
47 /**
48 * Gets a pointer to the data stored in this wrapper.
49 * @return the pointer.
51 inline operator T *()
53 return data;
56 /**
57 * Gets a pointer to the data stored in this wrapper.
58 * @return the pointer.
60 inline T *operator -> ()
62 return data;
65 /**
66 * Gets a pointer to the last data element stored in this wrapper.
67 * @note needed because endof does not work properly for pointers.
68 * @return the 'endof' pointer.
70 inline T *EndOf()
72 #if !defined(__NDS__)
73 return endof(data);
74 #else
75 return &data[len];
76 #endif
80 /**
81 * A reusable buffer that can be used for places that temporary allocate
82 * a bit of memory and do that very often, or for places where static
83 * memory is allocated that might need to be reallocated sometimes.
85 * Every time Allocate or ZeroAllocate is called previous results of both
86 * functions will become invalid.
88 template <typename T>
89 class ReusableBuffer {
90 private:
91 T *buffer; ///< The real data buffer
92 size_t count; ///< Number of T elements in the buffer
94 public:
95 /** Create a new buffer */
96 ReusableBuffer() : buffer(NULL), count(0) {}
97 /** Clear the buffer */
98 ~ReusableBuffer() { free(this->buffer); }
101 * Get buffer of at least count times T.
102 * @note the buffer might be bigger
103 * @note calling this function invalidates any previous buffers given
104 * @param count the minimum buffer size
105 * @return the buffer
107 T *Allocate(size_t count)
109 if (this->count < count) {
110 free(this->buffer);
111 this->buffer = MallocT<T>(count);
112 this->count = count;
114 return this->buffer;
118 * Get buffer of at least count times T with zeroed memory.
119 * @note the buffer might be bigger
120 * @note calling this function invalidates any previous buffers given
121 * @param count the minimum buffer size
122 * @return the buffer
124 T *ZeroAllocate(size_t count)
126 if (this->count < count) {
127 free(this->buffer);
128 this->buffer = CallocT<T>(count);
129 this->count = count;
130 } else {
131 memset(this->buffer, 0, sizeof(T) * count);
133 return this->buffer;
137 * Get the currently allocated buffer.
138 * @return the buffer
140 inline const T *GetBuffer() const
142 return this->buffer;
147 * Base class that provides memory initialization on dynamically created objects.
148 * All allocated memory will be zeroed.
150 class ZeroedMemoryAllocator
152 public:
153 ZeroedMemoryAllocator() {}
154 virtual ~ZeroedMemoryAllocator() {}
157 * Memory allocator for a single class instance.
158 * @param size the amount of bytes to allocate.
159 * @return the given amounts of bytes zeroed.
161 inline void *operator new(size_t size) { return CallocT<byte>(size); }
164 * Memory allocator for an array of class instances.
165 * @param size the amount of bytes to allocate.
166 * @return the given amounts of bytes zeroed.
168 inline void *operator new[](size_t size) { return CallocT<byte>(size); }
171 * Memory release for a single class instance.
172 * @param ptr the memory to free.
174 inline void operator delete(void *ptr) { free(ptr); }
177 * Memory release for an array of class instances.
178 * @param ptr the memory to free.
180 inline void operator delete[](void *ptr) { free(ptr); }
184 * A smart pointer class that free()'s the pointer on destruction.
185 * @tparam T Storage type.
187 template <typename T>
188 class AutoFreePtr
190 T *ptr; ///< Stored pointer.
192 public:
193 AutoFreePtr(T *ptr) : ptr(ptr) {}
194 ~AutoFreePtr() { free(this->ptr); }
197 * Take ownership of a new pointer and free the old one if needed.
198 * @param ptr NEw pointer.
200 inline void Assign(T *ptr)
202 free(this->ptr);
203 this->ptr = ptr;
206 /** Dereference pointer. */
207 inline T *operator ->() { return this->ptr; }
208 /** Dereference pointer. */
209 inline const T *operator ->() const { return this->ptr; }
211 /** Cast to underlaying regular pointer. */
212 inline operator T *() { return this->ptr; }
213 /** Cast to underlaying regular pointer. */
214 inline operator const T *() const { return this->ptr; }
217 #endif /* ALLOC_TYPE_HPP */