1// 2// Copyright (C) 2007-2015 Free Software Foundation, Inc. 3// 4// This file is part of the GNU ISO C++ Library. This library is free 5// software; you can redistribute it and/or modify it under the 6// terms of the GNU General Public License as published by the 7// Free Software Foundation; either version 3, or (at your option) 8// any later version. 9// 10// This library is distributed in the hope that it will be useful, 11// but WITHOUT ANY WARRANTY; without even the implied warranty of 12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13// GNU General Public License for more details. 14// 15// You should have received a copy of the GNU General Public License along 16// with this library; see the file COPYING3. If not see 17// <http://www.gnu.org/licenses/>. 18 19#include <exception> 20#include <stdexcept> 21#include <cstdlib> 22#include <cstdio> 23 24namespace __gnu_test 25{ 26 struct counter_error : public std::exception { }; 27 28 struct counter 29 { 30 std::size_t _M_count; 31 bool _M_throw; 32 33 counter() : _M_count(0), _M_throw(true) { } 34 35 ~counter() 36 { 37 if (_M_throw && _M_count != 0) 38 throw counter_error(); 39 } 40 41 static void 42 increment() { get()._M_count++; } 43 44 static void 45 decrement() { get()._M_count--; } 46 47 static counter& 48 get() 49 { 50 static counter g; 51 return g; 52 } 53 54 static std::size_t 55 count() { return get()._M_count; } 56 57 static void 58 exceptions(bool __b) { get()._M_throw = __b; } 59 }; 60 61 template<typename Alloc, bool uses_global_new> 62 bool 63 check_new(Alloc a = Alloc()) 64 { 65 __gnu_test::counter::exceptions(false); 66 a.allocate(10); 67 const bool __b((__gnu_test::counter::count() > 0) == uses_global_new); 68 if (!__b) 69 throw std::logic_error("counter not incremented"); 70 return __b; 71 } 72 73 template<typename Alloc, bool uses_global_delete> 74 bool 75 check_delete(Alloc a = Alloc()) 76 { 77 __gnu_test::counter::exceptions(false); 78 typename Alloc::pointer p = a.allocate(10); 79 const std::size_t count1 = __gnu_test::counter::count(); 80 a.deallocate(p, 10); 81 const std::size_t count2 = __gnu_test::counter::count(); 82 const bool __b((count2 < count1) == uses_global_delete); 83 if (!__b) 84 throw std::logic_error("counter not decremented"); 85 return __b; 86 } 87} // namespace __gnu_test 88 89void* operator new(std::size_t size) throw(std::bad_alloc) 90{ 91 std::printf("operator new is called \n"); 92 void* p = std::malloc(size); 93 if (!p) 94 throw std::bad_alloc(); 95 __gnu_test::counter::increment(); 96 return p; 97} 98 99void operator delete(void* p) throw() 100{ 101 std::printf("operator delete is called \n"); 102 if (p) 103 { 104 std::free(p); 105 __gnu_test::counter::decrement(); 106 107 std::size_t count = __gnu_test::counter::count(); 108 if (count == 0) 109 std::printf("All memory released \n"); 110 else 111 std::printf("%lu allocations to be released \n", (unsigned long)count); 112 } 113} 114