]>
Commit | Line | Data |
---|---|---|
daa15929 | 1 | // |
a945c346 | 2 | // Copyright (C) 2007-2024 Free Software Foundation, Inc. |
daa15929 BK |
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> | |
7ce18a45 PC |
20 | #include <stdexcept> |
21 | #include <cstdlib> | |
22 | #include <cstdio> | |
1f153a1d | 23 | #include <testsuite_hooks.h> |
daa15929 BK |
24 | |
25 | namespace __gnu_test | |
26 | { | |
27 | struct counter_error : public std::exception { }; | |
28 | ||
29 | struct counter | |
30 | { | |
7ce18a45 | 31 | std::size_t _M_count; |
2c43f5ec | 32 | std::size_t _M_increments, _M_decrements; |
daa15929 BK |
33 | bool _M_throw; |
34 | ||
35 | counter() : _M_count(0), _M_throw(true) { } | |
f92ab29f | 36 | |
1f153a1d | 37 | ~counter() THROW (counter_error) |
daa15929 BK |
38 | { |
39 | if (_M_throw && _M_count != 0) | |
40 | throw counter_error(); | |
41 | } | |
42 | ||
43 | static void | |
2c43f5ec FD |
44 | increment() |
45 | { | |
46 | counter& cntr = get(); | |
47 | cntr._M_count++; | |
48 | cntr._M_increments++; | |
49 | } | |
daa15929 BK |
50 | |
51 | static void | |
2c43f5ec FD |
52 | decrement() |
53 | { | |
54 | counter& cntr = get(); | |
55 | cntr._M_count--; | |
56 | cntr._M_decrements++; | |
57 | } | |
daa15929 BK |
58 | |
59 | static counter& | |
f92ab29f | 60 | get() |
daa15929 BK |
61 | { |
62 | static counter g; | |
63 | return g; | |
64 | } | |
f92ab29f | 65 | |
7ce18a45 | 66 | static std::size_t |
daa15929 BK |
67 | count() { return get()._M_count; } |
68 | ||
69 | static void | |
70 | exceptions(bool __b) { get()._M_throw = __b; } | |
2c43f5ec FD |
71 | |
72 | static void | |
73 | reset() | |
74 | { | |
75 | counter& cntr = get(); | |
76 | cntr._M_increments = cntr._M_decrements = 0; | |
77 | } | |
2aa8ebc0 FD |
78 | |
79 | struct scope | |
80 | { | |
81 | scope() : _M_count(counter::count()) | |
82 | { counter::get()._M_count = 0; } | |
83 | ~scope() | |
84 | { counter::get()._M_count = _M_count; } | |
85 | ||
86 | private: | |
87 | std::size_t _M_count; | |
88 | ||
89 | #if __cplusplus >= 201103L | |
90 | scope(const scope&) = delete; | |
91 | scope& operator=(const scope&) = delete; | |
92 | #else | |
93 | scope(const scope&); | |
94 | scope& operator=(const scope&); | |
95 | #endif | |
96 | }; | |
daa15929 BK |
97 | }; |
98 | ||
99 | template<typename Alloc, bool uses_global_new> | |
f92ab29f | 100 | bool |
daa15929 BK |
101 | check_new(Alloc a = Alloc()) |
102 | { | |
2aa8ebc0 | 103 | __gnu_test::counter::scope s; |
daa15929 | 104 | __gnu_test::counter::exceptions(false); |
2104ca71 | 105 | (void) a.allocate(10); |
daa15929 BK |
106 | const bool __b((__gnu_test::counter::count() > 0) == uses_global_new); |
107 | if (!__b) | |
108 | throw std::logic_error("counter not incremented"); | |
109 | return __b; | |
110 | } | |
111 | ||
112 | template<typename Alloc, bool uses_global_delete> | |
f92ab29f | 113 | bool |
daa15929 BK |
114 | check_delete(Alloc a = Alloc()) |
115 | { | |
116 | __gnu_test::counter::exceptions(false); | |
2cae56bd JW |
117 | #if __cplusplus >= 201103L |
118 | auto p = a.allocate(10); | |
119 | #else | |
daa15929 | 120 | typename Alloc::pointer p = a.allocate(10); |
2cae56bd | 121 | #endif |
daa15929 BK |
122 | const std::size_t count1 = __gnu_test::counter::count(); |
123 | a.deallocate(p, 10); | |
124 | const std::size_t count2 = __gnu_test::counter::count(); | |
125 | const bool __b((count2 < count1) == uses_global_delete); | |
126 | if (!__b) | |
127 | throw std::logic_error("counter not decremented"); | |
128 | return __b; | |
129 | } | |
130 | } // namespace __gnu_test | |
131 | ||
1f153a1d | 132 | void* operator new(std::size_t size) THROW(std::bad_alloc) |
daa15929 | 133 | { |
7ce18a45 | 134 | std::printf("operator new is called \n"); |
daa15929 | 135 | void* p = std::malloc(size); |
8fc81078 | 136 | if (!p) |
daa15929 BK |
137 | throw std::bad_alloc(); |
138 | __gnu_test::counter::increment(); | |
139 | return p; | |
140 | } | |
f92ab29f | 141 | |
daa15929 BK |
142 | void operator delete(void* p) throw() |
143 | { | |
7ce18a45 | 144 | std::printf("operator delete is called \n"); |
8fc81078 | 145 | if (p) |
daa15929 BK |
146 | { |
147 | std::free(p); | |
148 | __gnu_test::counter::decrement(); | |
149 | ||
f92ab29f | 150 | std::size_t count = __gnu_test::counter::count(); |
daa15929 | 151 | if (count == 0) |
7ce18a45 | 152 | std::printf("All memory released \n"); |
daa15929 | 153 | else |
ba6a601c | 154 | std::printf("%lu allocations to be released \n", (unsigned long)count); |
daa15929 BK |
155 | } |
156 | } | |
13feb023 JW |
157 | |
158 | #if __cpp_sized_deallocation | |
159 | void operator delete(void* p, std::size_t) throw() { ::operator delete(p); } | |
160 | #endif |