1 // Copyright 2010 Google Inc.
2 // All rights reserved.
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above copyright
11 // notice, this list of conditions and the following disclaimer in the
12 // documentation and/or other materials provided with the distribution.
13 // * Neither the name of Google Inc. nor the names of its contributors
14 // may be used to endorse or promote products derived from this software
15 // without specific prior written permission.
17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 #include "utils/auto_array.ipp"
32 #include <sys/types.h>
37 #include <atf-c++.hpp>
39 #include "utils/defs.hpp"
41 using utils::auto_array
;
47 /// Mock class to capture calls to the new and delete operators.
50 /// User-settable cookie to disambiguate instances of this class.
53 /// The current balance of existing test_array instances.
54 static ssize_t m_nblocks
;
56 /// Captures invalid calls to new on an array.
58 /// \param unused_size The amount of memory to allocate, in bytes.
60 /// \return Nothing; this always fails the test case.
62 operator new(const size_t UTILS_UNUSED_PARAM(size
))
64 ATF_FAIL("New called but should have been new[]");
68 /// Obtains memory for a new instance and increments m_nblocks.
70 /// \param size The amount of memory to allocate, in bytes.
72 /// \return A pointer to the allocated memory.
74 /// \throw std::bad_alloc If the memory cannot be allocated.
76 operator new[](const size_t size
)
78 void* mem
= ::operator new(size
);
80 std::cout
<< "Allocated 'test_array' object " << mem
<< "\n";
84 /// Captures invalid calls to delete on an array.
86 /// \param unused_mem The pointer to the memory to be deleted.
88 /// \return Nothing; this always fails the test case.
90 operator delete(void* UTILS_UNUSED_PARAM(mem
))
92 ATF_FAIL("Delete called but should have been delete[]");
95 /// Deletes a previously allocated array and decrements m_nblocks.
97 /// \param mem The pointer to the memory to be deleted.
99 operator delete[](void* mem
)
101 std::cout
<< "Releasing 'test_array' object " << mem
<< "\n";
103 ATF_FAIL("Unbalanced delete[]");
105 ::operator delete(mem
);
110 ssize_t
test_array::m_nblocks
= 0;
113 } // anonymous namespace
116 ATF_TEST_CASE(scope
);
117 ATF_TEST_CASE_HEAD(scope
)
119 set_md_var("descr", "Tests the automatic scope handling in the "
120 "auto_array smart pointer class");
122 ATF_TEST_CASE_BODY(scope
)
124 ATF_REQUIRE_EQ(test_array::m_nblocks
, 0);
126 auto_array
< test_array
> t(new test_array
[10]);
127 ATF_REQUIRE_EQ(test_array::m_nblocks
, 1);
129 ATF_REQUIRE_EQ(test_array::m_nblocks
, 0);
134 ATF_TEST_CASE_HEAD(copy
)
136 set_md_var("descr", "Tests the auto_array smart pointer class' copy "
139 ATF_TEST_CASE_BODY(copy
)
141 ATF_REQUIRE_EQ(test_array::m_nblocks
, 0);
143 auto_array
< test_array
> t1(new test_array
[10]);
144 ATF_REQUIRE_EQ(test_array::m_nblocks
, 1);
147 auto_array
< test_array
> t2(t1
);
148 ATF_REQUIRE_EQ(test_array::m_nblocks
, 1);
150 ATF_REQUIRE_EQ(test_array::m_nblocks
, 0);
152 ATF_REQUIRE_EQ(test_array::m_nblocks
, 0);
156 ATF_TEST_CASE(copy_ref
);
157 ATF_TEST_CASE_HEAD(copy_ref
)
159 set_md_var("descr", "Tests the auto_array smart pointer class' copy "
160 "constructor through the auxiliary ref object");
162 ATF_TEST_CASE_BODY(copy_ref
)
164 ATF_REQUIRE_EQ(test_array::m_nblocks
, 0);
166 auto_array
< test_array
> t1(new test_array
[10]);
167 ATF_REQUIRE_EQ(test_array::m_nblocks
, 1);
170 auto_array
< test_array
> t2
= t1
;
171 ATF_REQUIRE_EQ(test_array::m_nblocks
, 1);
173 ATF_REQUIRE_EQ(test_array::m_nblocks
, 0);
175 ATF_REQUIRE_EQ(test_array::m_nblocks
, 0);
180 ATF_TEST_CASE_HEAD(get
)
182 set_md_var("descr", "Tests the auto_array smart pointer class' get "
185 ATF_TEST_CASE_BODY(get
)
187 test_array
* ta
= new test_array
[10];
188 auto_array
< test_array
> t(ta
);
189 ATF_REQUIRE_EQ(t
.get(), ta
);
193 ATF_TEST_CASE(release
);
194 ATF_TEST_CASE_HEAD(release
)
196 set_md_var("descr", "Tests the auto_array smart pointer class' release "
199 ATF_TEST_CASE_BODY(release
)
201 test_array
* ta1
= new test_array
[10];
203 auto_array
< test_array
> t(ta1
);
204 ATF_REQUIRE_EQ(test_array::m_nblocks
, 1);
205 test_array
* ta2
= t
.release();
206 ATF_REQUIRE_EQ(ta2
, ta1
);
207 ATF_REQUIRE_EQ(test_array::m_nblocks
, 1);
209 ATF_REQUIRE_EQ(test_array::m_nblocks
, 1);
214 ATF_TEST_CASE(reset
);
215 ATF_TEST_CASE_HEAD(reset
)
217 set_md_var("descr", "Tests the auto_array smart pointer class' reset "
220 ATF_TEST_CASE_BODY(reset
)
222 test_array
* ta1
= new test_array
[10];
223 test_array
* ta2
= new test_array
[10];
224 ATF_REQUIRE_EQ(test_array::m_nblocks
, 2);
227 auto_array
< test_array
> t(ta1
);
228 ATF_REQUIRE_EQ(test_array::m_nblocks
, 2);
230 ATF_REQUIRE_EQ(test_array::m_nblocks
, 1);
232 ATF_REQUIRE_EQ(test_array::m_nblocks
, 0);
234 ATF_REQUIRE_EQ(test_array::m_nblocks
, 0);
238 ATF_TEST_CASE(assign
);
239 ATF_TEST_CASE_HEAD(assign
)
241 set_md_var("descr", "Tests the auto_array smart pointer class' "
242 "assignment operator");
244 ATF_TEST_CASE_BODY(assign
)
246 ATF_REQUIRE_EQ(test_array::m_nblocks
, 0);
248 auto_array
< test_array
> t1(new test_array
[10]);
249 ATF_REQUIRE_EQ(test_array::m_nblocks
, 1);
252 auto_array
< test_array
> t2
;
254 ATF_REQUIRE_EQ(test_array::m_nblocks
, 1);
256 ATF_REQUIRE_EQ(test_array::m_nblocks
, 0);
258 ATF_REQUIRE_EQ(test_array::m_nblocks
, 0);
262 ATF_TEST_CASE(assign_ref
);
263 ATF_TEST_CASE_HEAD(assign_ref
)
265 set_md_var("descr", "Tests the auto_array smart pointer class' "
266 "assignment operator through the auxiliary ref "
269 ATF_TEST_CASE_BODY(assign_ref
)
271 ATF_REQUIRE_EQ(test_array::m_nblocks
, 0);
273 auto_array
< test_array
> t1(new test_array
[10]);
274 ATF_REQUIRE_EQ(test_array::m_nblocks
, 1);
277 auto_array
< test_array
> t2
;
279 ATF_REQUIRE_EQ(test_array::m_nblocks
, 1);
281 ATF_REQUIRE_EQ(test_array::m_nblocks
, 0);
283 ATF_REQUIRE_EQ(test_array::m_nblocks
, 0);
287 ATF_TEST_CASE(access
);
288 ATF_TEST_CASE_HEAD(access
)
290 set_md_var("descr", "Tests the auto_array smart pointer class' access "
293 ATF_TEST_CASE_BODY(access
)
295 auto_array
< test_array
> t(new test_array
[10]);
297 for (int i
= 0; i
< 10; i
++)
298 t
[i
].m_value
= i
* 2;
300 for (int i
= 0; i
< 10; i
++)
301 ATF_REQUIRE_EQ(t
[i
].m_value
, i
* 2);
305 ATF_INIT_TEST_CASES(tcs
)
307 ATF_ADD_TEST_CASE(tcs
, scope
);
308 ATF_ADD_TEST_CASE(tcs
, copy
);
309 ATF_ADD_TEST_CASE(tcs
, copy_ref
);
310 ATF_ADD_TEST_CASE(tcs
, get
);
311 ATF_ADD_TEST_CASE(tcs
, release
);
312 ATF_ADD_TEST_CASE(tcs
, reset
);
313 ATF_ADD_TEST_CASE(tcs
, assign
);
314 ATF_ADD_TEST_CASE(tcs
, assign_ref
);
315 ATF_ADD_TEST_CASE(tcs
, access
);