WPILibC++ 2025.1.1
Loading...
Searching...
No Matches
error.hpp
Go to the documentation of this file.
1// Copyright (C) 2015-2023 Jonathan Müller and foonathan/memory contributors
2// SPDX-License-Identifier: Zlib
3
4/// \file
5/// The exception classes.
6
7#ifndef WPI_MEMORY_ERROR_HPP_INCLUDED
8#define WPI_MEMORY_ERROR_HPP_INCLUDED
9
10#include <cstddef>
11#include <new>
12
13#include "config.hpp"
14
15namespace wpi
16{
17 namespace memory
18 {
19 /// Contains information about an allocator.
20 /// It can be used for logging in the various handler functions.
21 /// \ingroup memory_core
23 {
24 /// The name of the allocator.
25 /// It is a NTBS whose lifetime is not managed by this object,
26 /// it must be stored elsewhere or be a string literal.
27 const char* name;
28
29 /// A pointer representing an allocator.
30 /// It does not necessarily point to the beginning of the allocator object,
31 /// the only guarantee is that different allocator objects result in a different pointer value.
32 /// For stateless allocators it is sometimes \c nullptr.
33 /// \note The pointer must not be cast back to any allocator type.
34 const void* allocator;
35
36 /// \effects Creates it by giving it the name of the allocator and a pointer.
37 constexpr allocator_info(const char* n, const void* alloc) noexcept
38 : name(n), allocator(alloc)
39 {
40 }
41
42 /// @{
43 /// \effects Compares two \ref allocator_info objects, they are equal, if the \ref allocator is the same.
44 /// \returns The result of the comparision.
45 friend constexpr bool operator==(const allocator_info& a,
46 const allocator_info& b) noexcept
47 {
48 return a.allocator == b.allocator;
49 }
50
51 friend constexpr bool operator!=(const allocator_info& a,
52 const allocator_info& b) noexcept
53 {
54 return a.allocator != b.allocator;
55 }
56 /// @}
57 };
58
59 /// The exception class thrown when a low level allocator runs out of memory.
60 /// It is derived from \c std::bad_alloc.
61 /// This can happen if a low level allocation function like \c std::malloc() runs out of memory.
62 /// Throwing can be prohibited by the handler function.
63 /// \ingroup memory_core
64 class out_of_memory : public std::bad_alloc
65 {
66 public:
67 /// The type of the handler called in the constructor of \ref out_of_memory.
68 /// When an out of memory situation is encountered and the exception class created,
69 /// this handler gets called.
70 /// It is especially useful if exception support is disabled.
71 /// It gets the \ref allocator_info and the amount of memory that was tried to be allocated.
72 /// \requiredbe It can log the error, throw a different exception derived from \c std::bad_alloc or abort the program.
73 /// If it returns, this exception object will be created and thrown.
74 /// \defaultbe On a hosted implementation it logs the error on \c stderr and continues execution,
75 /// leading to this exception being thrown.
76 /// On a freestanding implementation it does nothing.
77 /// \note It is different from \c std::new_handler; it will not be called in a loop trying to allocate memory
78 /// or something like that. Its only job is to report the error.
79 using handler = void (*)(const allocator_info& info, std::size_t amount);
80
81 /// \effects Sets \c h as the new \ref handler in an atomic operation.
82 /// A \c nullptr sets the default \ref handler.
83 /// \returns The previous \ref handler. This is never \c nullptr.
85
86 /// \returns The current \ref handler. This is never \c nullptr.
88
89 /// \effects Creates it by passing it the \ref allocator_info and the amount of memory failed to be allocated.
90 /// It also calls the \ref handler to control whether or not it will be thrown.
91 out_of_memory(const allocator_info& info, std::size_t amount);
92
93 /// \returns A static NTBS that describes the error.
94 /// It does not contain any specific information since there is no memory for formatting.
95 const char* what() const noexcept override;
96
97 /// \returns The \ref allocator_info passed to it in the constructor.
98 const allocator_info& allocator() const noexcept
99 {
100 return info_;
101 }
102
103 /// \returns The amount of memory that was tried to be allocated.
104 /// This is the value passed in the constructor.
105 std::size_t failed_allocation_size() const noexcept
106 {
107 return amount_;
108 }
109
110 private:
111 allocator_info info_;
112 std::size_t amount_;
113 };
114
115 /// A special case of \ref out_of_memory errors
116 /// thrown when a low-level allocator with a fixed size runs out of memory.
117 /// For example, thrown by \ref fixed_block_allocator or \ref static_allocator.<br>
118 /// It is derived from \ref out_of_memory but does not provide its own handler.
119 /// \ingroup memory_core
121 {
122 public:
123 /// \effects Just forwards to \ref out_of_memory.
124 out_of_fixed_memory(const allocator_info& info, std::size_t amount)
125 : out_of_memory(info, amount)
126 {
127 }
128
129 /// \returns A static NTBS that describes the error.
130 /// It does not contain any specific information since there is no memory for formatting.
131 const char* what() const noexcept override;
132 };
133
134 /// The exception class thrown when an allocation size is bigger than the supported maximum.
135 /// This size is either the node, array or alignment parameter in a call to an allocation function.
136 /// If those exceed the supported maximum returned by \c max_node_size(), \c max_array_size() or \c max_alignment(),
137 /// one of its derived classes will be thrown or this class if in a situation where the type is unknown.
138 /// It is derived from \c std::bad_alloc.
139 /// Throwing can be prohibited by the handler function.
140 /// \note Even if all parameters are less than the maximum, \ref out_of_memory or a similar exception can be thrown,
141 /// because the maximum functions return an upper bound and not the actual supported maximum size,
142 /// since it always depends on fence memory, alignment buffer and the like.
143 /// \note A user should only \c catch for \c bad_allocation_size, not the derived classes.
144 /// \note Most checks will only be done if \ref WPI_MEMORY_CHECK_ALLOCATION_SIZE is \c true.
145 /// \ingroup memory_core
146 class bad_allocation_size : public std::bad_alloc
147 {
148 public:
149 /// The type of the handler called in the constructor of \ref bad_allocation_size.
150 /// When a bad allocation size is detected and the exception object created,
151 /// this handler gets called.
152 /// It is especially useful if exception support is disabled.
153 /// It gets the \ref allocator_info, the size passed to the function and the supported size
154 /// (the latter is still an upper bound).
155 /// \requiredbe It can log the error, throw a different exception derived from \c std::bad_alloc or abort the program.
156 /// If it returns, this exception object will be created and thrown.
157 /// \defaultbe On a hosted implementation it logs the error on \c stderr and continues execution,
158 /// leading to this exception being thrown.
159 /// On a freestanding implementation it does nothing.
160 using handler = void (*)(const allocator_info& info, std::size_t passed,
161 std::size_t supported);
162
163 /// \effects Sets \c h as the new \ref handler in an atomic operation.
164 /// A \c nullptr sets the default \ref handler.
165 /// \returns The previous \ref handler. This is never \c nullptr.
167
168 /// \returns The current \ref handler. This is never \c nullptr.
170
171 /// \effects Creates it by passing it the \ref allocator_info, the size passed to the allocation function
172 /// and an upper bound on the supported size.
173 /// It also calls the \ref handler to control whether or not it will be thrown.
174 bad_allocation_size(const allocator_info& info, std::size_t passed,
175 std::size_t supported);
176
177 /// \returns A static NTBS that describes the error.
178 /// It does not contain any specific information since there is no memory for formatting.
179 const char* what() const noexcept override;
180
181 /// \returns The \ref allocator_info passed to it in the constructor.
182 const allocator_info& allocator() const noexcept
183 {
184 return info_;
185 }
186
187 /// \returns The size or alignment value that was passed to the allocation function
188 /// which was too big. This is the same value passed to the constructor.
189 std::size_t passed_value() const noexcept
190 {
191 return passed_;
192 }
193
194 /// \returns An upper bound on the maximum supported size/alignment.
195 /// It is only an upper bound, values below can fail, but values above will always fail.
196 std::size_t supported_value() const noexcept
197 {
198 return supported_;
199 }
200
201 private:
202 allocator_info info_;
203 std::size_t passed_, supported_;
204 };
205
206 /// The exception class thrown when the node size exceeds the supported maximum,
207 /// i.e. it is bigger than \c max_node_size().
208 /// It is derived from \ref bad_allocation_size but does not override the handler.
209 /// \ingroup memory_core
211 {
212 public:
213 /// \effects Just forwards to \ref bad_allocation_size.
214 bad_node_size(const allocator_info& info, std::size_t passed, std::size_t supported)
215 : bad_allocation_size(info, passed, supported)
216 {
217 }
218
219 /// \returns A static NTBS that describes the error.
220 /// It does not contain any specific information since there is no memory for formatting.
221 const char* what() const noexcept override;
222 };
223
224 /// The exception class thrown when the array size exceeds the supported maximum,
225 /// i.e. it is bigger than \c max_array_size().
226 /// It is derived from \ref bad_allocation_size but does not override the handler.
227 /// \ingroup memory_core
229 {
230 public:
231 /// \effects Just forwards to \ref bad_allocation_size.
232 bad_array_size(const allocator_info& info, std::size_t passed, std::size_t supported)
233 : bad_allocation_size(info, passed, supported)
234 {
235 }
236
237 /// \returns A static NTBS that describes the error.
238 /// It does not contain any specific information since there is no memory for formatting.
239 const char* what() const noexcept override;
240 };
241
242 /// The exception class thrown when the alignment exceeds the supported maximum,
243 /// i.e. it is bigger than \c max_alignment().
244 /// It is derived from \ref bad_allocation_size but does not override the handler.
245 /// \ingroup memory_core
247 {
248 public:
249 /// \effects Just forwards to \ref bad_allocation_size.
250 /// \c passed is <tt>count * size</tt>, \c supported the size in bytes.
251 bad_alignment(const allocator_info& info, std::size_t passed, std::size_t supported)
252 : bad_allocation_size(info, passed, supported)
253 {
254 }
255
256 /// \returns A static NTBS that describes the error.
257 /// It does not contain any specific information since there is no memory for formatting.
258 const char* what() const noexcept override;
259 };
260
261 namespace detail
262 {
263 template <class Ex, typename Func>
264 void check_allocation_size(std::size_t passed, Func f, const allocator_info& info)
265 {
266#if WPI_MEMORY_CHECK_ALLOCATION_SIZE
267 auto supported = f();
268 if (passed > supported)
269 WPI_THROW(Ex(info, passed, supported));
270#else
271 (void)passed;
272 (void)f;
273 (void)info;
274#endif
275 }
276
277 template <class Ex>
278 void check_allocation_size(std::size_t passed, std::size_t supported,
279 const allocator_info& info)
280 {
281 check_allocation_size<Ex>(
282 passed, [&] { return supported; }, info);
283 }
284 } // namespace detail
285 } // namespace memory
286} // namespace wpi
287
288#endif // WPI_MEMORY_ERROR_HPP_INCLUDED
The exception class thrown when the alignment exceeds the supported maximum, i.e.
Definition error.hpp:247
bad_alignment(const allocator_info &info, std::size_t passed, std::size_t supported)
Definition error.hpp:251
const char * what() const noexcept override
The exception class thrown when an allocation size is bigger than the supported maximum.
Definition error.hpp:147
std::size_t passed_value() const noexcept
Definition error.hpp:189
bad_allocation_size(const allocator_info &info, std::size_t passed, std::size_t supported)
static handler set_handler(handler h)
void(*)(const allocator_info &info, std::size_t passed, std::size_t supported) handler
The type of the handler called in the constructor of bad_allocation_size.
Definition error.hpp:160
const char * what() const noexcept override
std::size_t supported_value() const noexcept
Definition error.hpp:196
The exception class thrown when the array size exceeds the supported maximum, i.e.
Definition error.hpp:229
bad_array_size(const allocator_info &info, std::size_t passed, std::size_t supported)
Definition error.hpp:232
const char * what() const noexcept override
The exception class thrown when the node size exceeds the supported maximum, i.e.
Definition error.hpp:211
bad_node_size(const allocator_info &info, std::size_t passed, std::size_t supported)
Definition error.hpp:214
const char * what() const noexcept override
A special case of out_of_memory errors thrown when a low-level allocator with a fixed size runs out o...
Definition error.hpp:121
out_of_fixed_memory(const allocator_info &info, std::size_t amount)
Definition error.hpp:124
const char * what() const noexcept override
The exception class thrown when a low level allocator runs out of memory.
Definition error.hpp:65
const char * what() const noexcept override
static handler set_handler(handler h)
static handler get_handler()
void(*)(const allocator_info &info, std::size_t amount) handler
The type of the handler called in the constructor of out_of_memory.
Definition error.hpp:79
std::size_t failed_allocation_size() const noexcept
Definition error.hpp:105
const allocator_info & allocator() const noexcept
Definition error.hpp:98
out_of_memory(const allocator_info &info, std::size_t amount)
Configuration macros.
#define WPI_THROW(Ex)
Definition config.hpp:33
detail namespace with internal helper functions
Definition input_adapters.h:32
Implement std::hash so that hash_code can be used in STL containers.
Definition PointerIntPair.h:280
void check_allocation_size(std::size_t passed, Func f, const allocator_info &info)
Definition error.hpp:264
Memory namespace.
Definition heap_allocator.hpp:20
Foonathan namespace.
Definition ntcore_cpp.h:26
Contains information about an allocator.
Definition error.hpp:23
const void * allocator
A pointer representing an allocator.
Definition error.hpp:34
friend constexpr bool operator==(const allocator_info &a, const allocator_info &b) noexcept
Definition error.hpp:45
friend constexpr bool operator!=(const allocator_info &a, const allocator_info &b) noexcept
Definition error.hpp:51
constexpr allocator_info(const char *n, const void *alloc) noexcept
Definition error.hpp:37
const char * name
The name of the allocator.
Definition error.hpp:27