15 # define ALIGNED_ALLOC(alignment, size) _aligned_malloc(size, alignment)
16 # define ALIGNED_FREE _aligned_free
17 #elif defined(__GNUC__)
19 # define ALIGNED_ALLOC(alignment, size) std::aligned_alloc(alignment, size)
20 # define ALIGNED_FREE std::free
22 static_assert(
false,
"Incompatible compiler");
26 #ifndef DISABLE_NEW_DELETE_COUNTER
43 # define ASSERT_NUM_DELETE_EQ(num_delete_exp) ASSERT_EQ(new_delete_counter.get_num_delete_calls(), num_delete_exp)
64 # define ASSERT_NUM_NEW_AND_DELETE_EQ(num_new_exp, num_delete_exp) \
65 ASSERT_NUM_NEW_EQ(num_new_exp); \
66 ASSERT_NUM_DELETE_EQ(num_delete_exp)
84 # define ASSERT_NUM_NEW_EQ(num_new_exp) ASSERT_EQ(new_delete_counter.get_num_new_calls(), num_new_exp)
94 # define COUNT_NEW_AND_DELETE auto new_delete_counter = NewDeleteCounter()
117 # define EXPECT_NUM_DELETE_EQ(num_delete_exp) EXPECT_EQ(new_delete_counter.get_num_delete_calls(), num_delete_exp)
142 # define EXPECT_NUM_NEW_AND_DELETE_EQ(num_new_exp, num_delete_exp) \
143 EXPECT_NUM_NEW_EQ(num_new_exp); \
144 EXPECT_NUM_DELETE_EQ(num_delete_exp)
166 # define EXPECT_NUM_NEW_EQ(num_new_exp) EXPECT_EQ(new_delete_counter.get_num_new_calls(), num_new_exp)
170 # define ASSERT_NUM_DELETE_EQ(num_delete_exp)
171 # define ASSERT_NUM_NEW_AND_DELETE_EQ(num_new_exp, num_delete_exp)
172 # define ASSERT_NUM_NEW_EQ(num_new_exp)
173 # define COUNT_NEW_AND_DELETE
174 # define EXPECT_NUM_DELETE_EQ(num_delete_exp)
175 # define EXPECT_NUM_NEW_AND_DELETE_EQ(num_new_exp, num_delete_exp)
176 # define EXPECT_NUM_NEW_EQ(num_new_exp)
256 static void increase_total_delete_calls() noexcept;
261 static void increase_total_new_calls() noexcept;
272 [[nodiscard]]
static auto return_value([[maybe_unused]]
I32 value) noexcept ->
I32;
275 std::atomic<I32> m_num_new_at_construction = -1;
276 std::atomic<I32> m_num_del_at_construction = -1;
278 inline static std::atomic<I32> m_num_new_global = 0;
279 inline static std::atomic<I32> m_num_del_global = 0;
282 #ifndef DISABLE_NEW_DELETE_COUNTER
283 friend auto ::operator
new(std::size_t size) ->
void*;
284 friend auto ::operator
new(std::size_t size, std::align_val_t al) ->
void*;
285 friend auto ::operator
new(std::size_t size,
const std::nothrow_t&) noexcept ->
void*;
286 friend auto ::operator
new(std::size_t size, std::align_val_t al,
const std::nothrow_t&) noexcept ->
void*;
287 friend auto ::operator
new[](std::size_t size) ->
void*;
288 friend auto ::operator
new[](std::size_t size, std::align_val_t al) ->
void*;
289 friend auto ::operator
new[](std::size_t size,
const std::nothrow_t&) noexcept ->
void*;
290 friend auto ::operator
new[](std::size_t size, std::align_val_t al,
const std::nothrow_t&) noexcept ->
void*;
291 friend void ::operator
delete(
void* ptr) noexcept;
292 friend void ::operator
delete(
void* ptr,
const std::nothrow_t&) noexcept;
293 friend void ::operator
delete[](
void* ptr) noexcept;
294 friend void ::operator
delete[](
void* ptr,
const std::nothrow_t&) noexcept;
295 friend void ::operator
delete(
void* ptr, std::align_val_t al) noexcept;
296 friend void ::operator
delete[](
void* ptr, std::align_val_t al) noexcept;
297 friend void ::operator
delete(
void* ptr, std::align_val_t al,
const std::nothrow_t& tag) noexcept;
298 friend void ::operator
delete[](
void* ptr, std::align_val_t al,
const std::nothrow_t& tag) noexcept;
299 # ifdef __cpp_sized_deallocation
300 friend void ::operator
delete(
void* ptr, std::size_t sz) noexcept;
301 friend void ::operator
delete[](
void* ptr, std::size_t sz) noexcept;
302 friend void ::operator
delete(
void* ptr, std::size_t sz, std::align_val_t al) noexcept;
303 friend void ::operator
delete[](
void* ptr, std::size_t sz, std::align_val_t al) noexcept;
320 inline NewDeleteCounter::NewDeleteCounter()
321 : m_num_new_at_construction(m_num_new_global.load())
322 , m_num_del_at_construction(m_num_del_global.load())
331 return return_value(m_num_del_global - m_num_del_at_construction);
339 return return_value(m_num_new_global - m_num_new_at_construction);
347 return return_value(m_num_del_global);
355 return return_value(m_num_new_global);
364 #ifndef DISABLE_NEW_DELETE_COUNTER
368 std::cout <<
"Global new counter disabled." << std::endl;
375 inline void NewDeleteCounter::increase_total_delete_calls() noexcept
383 inline void NewDeleteCounter::increase_total_new_calls() noexcept
391 [[nodiscard]]
inline auto NewDeleteCounter::return_value([[maybe_unused]] I32 value) noexcept ->
I32
393 #ifndef DISABLE_NEW_DELETE_COUNTER
412 #ifndef DISABLE_NEW_DELETE_COUNTER
413 auto operator new(std::size_t size) ->
void*
415 void* p = malloc(size);
417 throw std::bad_alloc();
419 mjolnir::NewDeleteCounter::increase_total_new_calls();
423 auto operator new[](std::size_t size) ->
void*
425 void* p = malloc(size);
427 throw std::bad_alloc();
429 mjolnir::NewDeleteCounter::increase_total_new_calls();
433 auto operator new(std::size_t size,
const std::nothrow_t&) noexcept ->
void*
435 mjolnir::NewDeleteCounter::increase_total_new_calls();
439 auto operator new[](std::size_t size,
const std::nothrow_t&) noexcept ->
void*
441 mjolnir::NewDeleteCounter::increase_total_new_calls();
445 auto operator new(std::size_t size, std::align_val_t al) ->
void*
447 void* p = ALIGNED_ALLOC(
static_cast<size_t>(al), size);
449 throw std::bad_alloc();
451 mjolnir::NewDeleteCounter::increase_total_new_calls();
455 auto operator new[](std::size_t size, std::align_val_t al) ->
void*
457 void* p = ALIGNED_ALLOC(
static_cast<size_t>(al), size);
459 throw std::bad_alloc();
461 mjolnir::NewDeleteCounter::increase_total_new_calls();
465 auto operator new(std::size_t size, std::align_val_t al,
const std::nothrow_t&) noexcept ->
void*
467 mjolnir::NewDeleteCounter::increase_total_new_calls();
468 return ALIGNED_ALLOC(
static_cast<size_t>(al), size);
471 auto operator new[](std::size_t size, std::align_val_t al,
const std::nothrow_t&) noexcept ->
void*
473 mjolnir::NewDeleteCounter::increase_total_new_calls();
474 return ALIGNED_ALLOC(
static_cast<size_t>(al), size);
477 void operator delete(
void* ptr) noexcept
479 mjolnir::NewDeleteCounter::increase_total_delete_calls();
483 void operator delete[](
void* ptr) noexcept
485 mjolnir::NewDeleteCounter::increase_total_delete_calls();
489 void operator delete(
void* ptr,
const std::nothrow_t&) noexcept
491 mjolnir::NewDeleteCounter::increase_total_delete_calls();
495 void operator delete[](
void* ptr,
const std::nothrow_t&) noexcept
497 mjolnir::NewDeleteCounter::increase_total_delete_calls();
502 # ifdef __cpp_sized_deallocation
503 void operator delete(
void* ptr, [[maybe_unused]] std::size_t sz) noexcept
505 mjolnir::NewDeleteCounter::increase_total_delete_calls();
509 void operator delete[](
void* ptr, [[maybe_unused]] std::size_t sz) noexcept
511 mjolnir::NewDeleteCounter::increase_total_delete_calls();
515 void operator delete(
void* ptr, [[maybe_unused]] std::size_t sz, [[maybe_unused]] std::align_val_t al) noexcept
517 mjolnir::NewDeleteCounter::increase_total_delete_calls();
521 void operator delete[](
void* ptr, [[maybe_unused]] std::size_t sz, [[maybe_unused]] std::align_val_t al) noexcept
523 mjolnir::NewDeleteCounter::increase_total_delete_calls();
528 void operator delete(
void* ptr, [[maybe_unused]] std::align_val_t al) noexcept
530 mjolnir::NewDeleteCounter::increase_total_delete_calls();
534 void operator delete[](
void* ptr, [[maybe_unused]] std::align_val_t al) noexcept
536 mjolnir::NewDeleteCounter::increase_total_delete_calls();
540 void operator delete(
void* ptr,
541 [[maybe_unused]] std::align_val_t al,
542 [[maybe_unused]]
const std::nothrow_t& tag) noexcept
544 mjolnir::NewDeleteCounter::increase_total_delete_calls();
548 void operator delete[](
void* ptr,
549 [[maybe_unused]] std::align_val_t al,
550 [[maybe_unused]]
const std::nothrow_t& tag) noexcept
552 mjolnir::NewDeleteCounter::increase_total_delete_calls();
static auto get_total_num_delete_calls() noexcept -> I32
Gets the total number of delete calls of the program.
Definition: new_delete_counter.h:345
static auto get_total_num_new_calls() noexcept -> I32
Gets the total number of new calls of the program.
Definition: new_delete_counter.h:353
auto get_num_new_calls() const noexcept -> I32
Gets the number of new calls since the construction of the instance.
Definition: new_delete_counter.h:337
auto get_num_delete_calls() const noexcept -> I32
Gets the number of delete calls since the construction of the instance.
Definition: new_delete_counter.h:329
Counts the number of new and delete calls since the instance was created.
Definition: new_delete_counter.h:205
void print_num_calls() const noexcept
Prints the number of new and delete calls since the construction of the class instance.
Definition: new_delete_counter.h:362
Defines the fundamental data types.
std::int32_t I32
32 bit signed integer type
Definition: fundamental_types.h:22