1 //
2 // Copyright (C) 2007-2013 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 
24 namespace __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 
countercounter33     counter() : _M_count(0), _M_throw(true) { }
34 
~countercounter35     ~counter()
36     {
37       if (_M_throw && _M_count != 0)
38 	throw counter_error();
39     }
40 
41     static void
incrementcounter42     increment() { get()._M_count++; }
43 
44     static void
decrementcounter45     decrement() { get()._M_count--; }
46 
47     static counter&
getcounter48     get()
49     {
50       static counter g;
51       return g;
52     }
53 
54     static std::size_t
countcounter55     count() { return get()._M_count; }
56 
57     static void
exceptionscounter58     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 
new(std::size_t size)89 void* 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 
delete(void * p)99 void 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