1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
|
#pragma once
#include <exception>
#include <string>
#include <vector>
#define MEMORY_CATCH(expr) \
try { \
(expr); \
} catch (MemoryException exc) { \
MemoryException::HandleException(exc); \
} \
do {} while (0)
#define MEMORY_THROW(...) throw MemoryException(__func__, __LINE__, ##__VA_ARGS__);
class MemoryException : public std::exception {
public:
inline MemoryException(const char* func, int32_t line, const char* message) noexcept
: MemoryException(func, line, message, {}, 0) {}
inline MemoryException(const char* func, int32_t line, const char* message, const std::vector<int>& offsets) noexcept
: MemoryException(func, line, message, offsets, 0) {}
inline MemoryException(const char* func, int32_t line, const char* message, const std::vector<int>& offsets, size_t numItems) noexcept
: _func(func), _line(line), _message(message), _offsets(offsets), _numItems(numItems) {}
~MemoryException() = default;
inline const char* what() const noexcept {
return _message;
}
static void HandleException(const MemoryException& exc) noexcept {
std::string msg = "MemoryException thrown in function ";
msg += exc._func;
msg += " on line " + std::to_string(exc._line) + ":\n" + exc._message + "\nOffsets:";
for (int offset : exc._offsets) {
msg += " " + std::to_string(offset);
}
msg += "\n";
if (exc._numItems != 0) {
msg += "Num Items: " + std::to_string(exc._numItems) + "\n";
}
OutputDebugStringA(msg.c_str());
#ifndef NDEBUG
MessageBoxA(NULL, msg.c_str(), "Memory Exception Thrown", MB_OK);
#endif
}
private:
const char* _func;
int32_t _line;
const char* _message;
const std::vector<int> _offsets;
size_t _numItems = 0;
};
|