OpenTTD

- Main Page
- Related Pages
- Modules
- Namespaces
- Data Structures
- Files

- File List
- Globals

alloc_func.hpp
Go to the documentation of this file.
1 /* $Id: alloc_func.hpp 23640 2011-12-20 17:57:56Z truebrain $ */
2
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 */
9
12 #ifndef ALLOC_FUNC_HPP
13 #define ALLOC_FUNC_HPP
14
15 /*
16 * Functions to exit badly with an error message.
17 * It has to be linked so the error messages are not
18 * duplicated in each object file making the final
19 * binary needlessly large.
20 */
21
22 void NORETURN MallocError(size_t size);
23 void NORETURN ReallocError(size_t size);
24
31 static inline void CheckAllocationConstraints(size_t element_size, size_t num_elements)
32 {
33 if (num_elements > SIZE_MAX / element_size) MallocError(SIZE_MAX);
34 }
35
42 template <typename T>
43 static inline void CheckAllocationConstraints(size_t num_elements)
44 {
45 CheckAllocationConstraints(sizeof(T), num_elements);
46 }
47
58 template <typename T>
59 static inline T *MallocT(size_t num_elements)
60 {
61 /*
62 * MorphOS cannot handle 0 elements allocations, or rather that always
63 * returns NULL. So we do that for *all* allocations, thus causing it
64 * to behave the same on all OSes.
65 */
66 if (num_elements == 0) return NULL;
67
68 /* Ensure the size does not overflow. */
69 CheckAllocationConstraints<T>(num_elements);
70
71 T *t_ptr = (T*)malloc(num_elements * sizeof(T));
72 if (t_ptr == NULL) MallocError(num_elements * sizeof(T));
73 return t_ptr;
74 }
75
86 template <typename T>
87 static inline T *CallocT(size_t num_elements)
88 {
89 /*
90 * MorphOS cannot handle 0 elements allocations, or rather that always
91 * returns NULL. So we do that for *all* allocations, thus causing it
92 * to behave the same on all OSes.
93 */
94 if (num_elements == 0) return NULL;
95
96 T *t_ptr = (T*)calloc(num_elements, sizeof(T));
97 if (t_ptr == NULL) MallocError(num_elements * sizeof(T));
98 return t_ptr;
99 }
100
112 template <typename T>
113 static inline T *ReallocT(T *t_ptr, size_t num_elements)
114 {
115 /*
116 * MorphOS cannot handle 0 elements allocations, or rather that always
117 * returns NULL. So we do that for *all* allocations, thus causing it
118 * to behave the same on all OSes.
119 */
120 if (num_elements == 0) {
121 free(t_ptr);
122 return NULL;
123 }
124
125 /* Ensure the size does not overflow. */
126 CheckAllocationConstraints<T>(num_elements);
127
128 t_ptr = (T*)realloc(t_ptr, num_elements * sizeof(T));
129 if (t_ptr == NULL) ReallocError(num_elements * sizeof(T));
130 return t_ptr;
131 }
132
134 #define AllocaM(T, num_elements) \
135 (CheckAllocationConstraints<T>(num_elements), \
136 (T*)alloca((num_elements) * sizeof(T)))
137
138 #endif /* ALLOC_FUNC_HPP */