202 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			202 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			C++
		
	
	
	
#ifndef COUNT_NEW_HPP
 | 
						|
#define COUNT_NEW_HPP
 | 
						|
 | 
						|
# include <cstdlib>
 | 
						|
# include <cassert>
 | 
						|
# include <new>
 | 
						|
 | 
						|
#if  __has_feature(address_sanitizer) \
 | 
						|
  || __has_feature(memory_sanitizer)
 | 
						|
#define DISABLE_NEW_COUNT
 | 
						|
#endif
 | 
						|
 | 
						|
class MemCounter
 | 
						|
{
 | 
						|
public:
 | 
						|
    // Make MemCounter super hard to accidentally construct or copy.
 | 
						|
    class MemCounterCtorArg_ {};
 | 
						|
    explicit MemCounter(MemCounterCtorArg_) {}
 | 
						|
 | 
						|
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 = 0;
 | 
						|
    int new_called = 0;
 | 
						|
    int delete_called = 0;
 | 
						|
    int last_new_size = 0;
 | 
						|
 | 
						|
    int outstanding_array_new = 0;
 | 
						|
    int new_array_called = 0;
 | 
						|
    int delete_array_called = 0;
 | 
						|
    int last_new_array_size = 0;
 | 
						|
 | 
						|
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 */
 |