aboutsummaryrefslogtreecommitdiff
path: root/test/support/count_new.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'test/support/count_new.hpp')
-rw-r--r--test/support/count_new.hpp206
1 files changed, 206 insertions, 0 deletions
diff --git a/test/support/count_new.hpp b/test/support/count_new.hpp
new file mode 100644
index 000000000000..ddaf036f7d16
--- /dev/null
+++ b/test/support/count_new.hpp
@@ -0,0 +1,206 @@
+#ifndef COUNT_NEW_HPP
+#define COUNT_NEW_HPP
+
+# include <cstdlib>
+# include <cassert>
+# include <new>
+
+#ifndef __has_feature
+# define __has_feature(x) 0
+#endif
+
+#if __has_feature(address_sanitizer) \
+ || __has_feature(memory_sanitizer) \
+ || __has_feature(thread_sanitizer)
+#define DISABLE_NEW_COUNT
+#endif
+
+class MemCounter
+{
+public:
+ // Make MemCounter super hard to accidentally construct or copy.
+ class MemCounterCtorArg_ {};
+ explicit MemCounter(MemCounterCtorArg_) { reset(); }
+
+private:
+ MemCounter(MemCounter const &);
+ MemCounter & operator=(MemCounter const &);
+
+public:
+ // All checks return true when disable_checking is enabled.
+ static const bool disable_checking;
+
+ int outstanding_new;
+ int new_called;
+ int delete_called;
+ int last_new_size;
+
+ int outstanding_array_new;
+ int new_array_called;
+ int delete_array_called;
+ int last_new_array_size;
+
+public:
+ void newCalled(std::size_t s)
+ {
+ assert(s);
+ ++new_called;
+ ++outstanding_new;
+ last_new_size = s;
+ }
+
+ void deleteCalled(void * p)
+ {
+ assert(p);
+ --outstanding_new;
+ ++delete_called;
+ }
+
+ void newArrayCalled(std::size_t s)
+ {
+ assert(s);
+ ++outstanding_array_new;
+ ++new_array_called;
+ last_new_array_size = s;
+ }
+
+ void deleteArrayCalled(void * p)
+ {
+ assert(p);
+ --outstanding_array_new;
+ ++delete_array_called;
+ }
+
+ void reset()
+ {
+ outstanding_new = 0;
+ new_called = 0;
+ delete_called = 0;
+ last_new_size = 0;
+
+ outstanding_array_new = 0;
+ new_array_called = 0;
+ delete_array_called = 0;
+ last_new_array_size = 0;
+ }
+
+public:
+ bool checkOutstandingNewEq(int n) const
+ {
+ return disable_checking || n == outstanding_new;
+ }
+
+ bool checkOutstandingNewNotEq(int n) const
+ {
+ return disable_checking || n != outstanding_new;
+ }
+
+ bool checkNewCalledEq(int n) const
+ {
+ return disable_checking || n == new_called;
+ }
+
+ bool checkNewCalledNotEq(int n) const
+ {
+ return disable_checking || n != new_called;
+ }
+
+ bool checkDeleteCalledEq(int n) const
+ {
+ return disable_checking || n == delete_called;
+ }
+
+ bool checkDeleteCalledNotEq(int n) const
+ {
+ return disable_checking || n != delete_called;
+ }
+
+ bool checkLastNewSizeEq(int n) const
+ {
+ return disable_checking || n == last_new_size;
+ }
+
+ bool checkLastNewSizeNotEq(int n) const
+ {
+ return disable_checking || n != last_new_size;
+ }
+
+ bool checkOutstandingArrayNewEq(int n) const
+ {
+ return disable_checking || n == outstanding_array_new;
+ }
+
+ bool checkOutstandingArrayNewNotEq(int n) const
+ {
+ return disable_checking || n != outstanding_array_new;
+ }
+
+ bool checkNewArrayCalledEq(int n) const
+ {
+ return disable_checking || n == new_array_called;
+ }
+
+ bool checkNewArrayCalledNotEq(int n) const
+ {
+ return disable_checking || n != new_array_called;
+ }
+
+ bool checkDeleteArrayCalledEq(int n) const
+ {
+ return disable_checking || n == delete_array_called;
+ }
+
+ bool checkDeleteArrayCalledNotEq(int n) const
+ {
+ return disable_checking || n != delete_array_called;
+ }
+
+ bool checkLastNewArraySizeEq(int n) const
+ {
+ return disable_checking || n == last_new_array_size;
+ }
+
+ bool checkLastNewArraySizeNotEq(int n) const
+ {
+ return disable_checking || n != last_new_array_size;
+ }
+};
+
+#ifdef DISABLE_NEW_COUNT
+ const bool MemCounter::disable_checking = true;
+#else
+ const bool MemCounter::disable_checking = false;
+#endif
+
+MemCounter globalMemCounter((MemCounter::MemCounterCtorArg_()));
+
+#ifndef DISABLE_NEW_COUNT
+void* operator new(std::size_t s) throw(std::bad_alloc)
+{
+ globalMemCounter.newCalled(s);
+ return std::malloc(s);
+}
+
+void operator delete(void* p) throw()
+{
+ globalMemCounter.deleteCalled(p);
+ std::free(p);
+}
+
+
+void* operator new[](std::size_t s) throw(std::bad_alloc)
+{
+ globalMemCounter.newArrayCalled(s);
+ return operator new(s);
+}
+
+
+void operator delete[](void* p) throw()
+{
+ globalMemCounter.deleteArrayCalled(p);
+ operator delete(p);
+}
+
+#endif // DISABLE_NEW_COUNT
+
+#endif /* COUNT_NEW_HPP */