1*b0d29bc4SBrooks Davis // Copyright 2010 The Kyua Authors.
2*b0d29bc4SBrooks Davis // All rights reserved.
3*b0d29bc4SBrooks Davis //
4*b0d29bc4SBrooks Davis // Redistribution and use in source and binary forms, with or without
5*b0d29bc4SBrooks Davis // modification, are permitted provided that the following conditions are
6*b0d29bc4SBrooks Davis // met:
7*b0d29bc4SBrooks Davis //
8*b0d29bc4SBrooks Davis // * Redistributions of source code must retain the above copyright
9*b0d29bc4SBrooks Davis //   notice, this list of conditions and the following disclaimer.
10*b0d29bc4SBrooks Davis // * Redistributions in binary form must reproduce the above copyright
11*b0d29bc4SBrooks Davis //   notice, this list of conditions and the following disclaimer in the
12*b0d29bc4SBrooks Davis //   documentation and/or other materials provided with the distribution.
13*b0d29bc4SBrooks Davis // * Neither the name of Google Inc. nor the names of its contributors
14*b0d29bc4SBrooks Davis //   may be used to endorse or promote products derived from this software
15*b0d29bc4SBrooks Davis //   without specific prior written permission.
16*b0d29bc4SBrooks Davis //
17*b0d29bc4SBrooks Davis // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18*b0d29bc4SBrooks Davis // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19*b0d29bc4SBrooks Davis // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20*b0d29bc4SBrooks Davis // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21*b0d29bc4SBrooks Davis // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22*b0d29bc4SBrooks Davis // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23*b0d29bc4SBrooks Davis // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24*b0d29bc4SBrooks Davis // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25*b0d29bc4SBrooks Davis // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26*b0d29bc4SBrooks Davis // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27*b0d29bc4SBrooks Davis // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28*b0d29bc4SBrooks Davis 
29*b0d29bc4SBrooks Davis #include "utils/auto_array.ipp"
30*b0d29bc4SBrooks Davis 
31*b0d29bc4SBrooks Davis extern "C" {
32*b0d29bc4SBrooks Davis #include <sys/types.h>
33*b0d29bc4SBrooks Davis }
34*b0d29bc4SBrooks Davis 
35*b0d29bc4SBrooks Davis #include <iostream>
36*b0d29bc4SBrooks Davis 
37*b0d29bc4SBrooks Davis #include <atf-c++.hpp>
38*b0d29bc4SBrooks Davis 
39*b0d29bc4SBrooks Davis #include "utils/defs.hpp"
40*b0d29bc4SBrooks Davis 
41*b0d29bc4SBrooks Davis using utils::auto_array;
42*b0d29bc4SBrooks Davis 
43*b0d29bc4SBrooks Davis 
44*b0d29bc4SBrooks Davis namespace {
45*b0d29bc4SBrooks Davis 
46*b0d29bc4SBrooks Davis 
47*b0d29bc4SBrooks Davis /// Mock class to capture calls to the new and delete operators.
48*b0d29bc4SBrooks Davis class test_array {
49*b0d29bc4SBrooks Davis public:
50*b0d29bc4SBrooks Davis     /// User-settable cookie to disambiguate instances of this class.
51*b0d29bc4SBrooks Davis     int m_value;
52*b0d29bc4SBrooks Davis 
53*b0d29bc4SBrooks Davis     /// The current balance of existing test_array instances.
54*b0d29bc4SBrooks Davis     static ssize_t m_nblocks;
55*b0d29bc4SBrooks Davis 
56*b0d29bc4SBrooks Davis     /// Captures invalid calls to new on an array.
57*b0d29bc4SBrooks Davis     ///
58*b0d29bc4SBrooks Davis     /// \return Nothing; this always fails the test case.
59*b0d29bc4SBrooks Davis     void*
operator new(const size_t)60*b0d29bc4SBrooks Davis     operator new(const size_t /* size */)
61*b0d29bc4SBrooks Davis     {
62*b0d29bc4SBrooks Davis         ATF_FAIL("New called but should have been new[]");
63*b0d29bc4SBrooks Davis         return new int(5);
64*b0d29bc4SBrooks Davis     }
65*b0d29bc4SBrooks Davis 
66*b0d29bc4SBrooks Davis     /// Obtains memory for a new instance and increments m_nblocks.
67*b0d29bc4SBrooks Davis     ///
68*b0d29bc4SBrooks Davis     /// \param size The amount of memory to allocate, in bytes.
69*b0d29bc4SBrooks Davis     ///
70*b0d29bc4SBrooks Davis     /// \return A pointer to the allocated memory.
71*b0d29bc4SBrooks Davis     ///
72*b0d29bc4SBrooks Davis     /// \throw std::bad_alloc If the memory cannot be allocated.
73*b0d29bc4SBrooks Davis     void*
operator new[](const size_t size)74*b0d29bc4SBrooks Davis     operator new[](const size_t size)
75*b0d29bc4SBrooks Davis     {
76*b0d29bc4SBrooks Davis         void* mem = ::operator new(size);
77*b0d29bc4SBrooks Davis         m_nblocks++;
78*b0d29bc4SBrooks Davis         std::cout << "Allocated 'test_array' object " << mem << "\n";
79*b0d29bc4SBrooks Davis         return mem;
80*b0d29bc4SBrooks Davis     }
81*b0d29bc4SBrooks Davis 
82*b0d29bc4SBrooks Davis     /// Captures invalid calls to delete on an array.
83*b0d29bc4SBrooks Davis     ///
84*b0d29bc4SBrooks Davis     /// \return Nothing; this always fails the test case.
85*b0d29bc4SBrooks Davis     void
operator delete(void *)86*b0d29bc4SBrooks Davis     operator delete(void* /* mem */)
87*b0d29bc4SBrooks Davis     {
88*b0d29bc4SBrooks Davis         ATF_FAIL("Delete called but should have been delete[]");
89*b0d29bc4SBrooks Davis     }
90*b0d29bc4SBrooks Davis 
91*b0d29bc4SBrooks Davis     /// Deletes a previously allocated array and decrements m_nblocks.
92*b0d29bc4SBrooks Davis     ///
93*b0d29bc4SBrooks Davis     /// \param mem The pointer to the memory to be deleted.
94*b0d29bc4SBrooks Davis     void
operator delete[](void * mem)95*b0d29bc4SBrooks Davis     operator delete[](void* mem)
96*b0d29bc4SBrooks Davis     {
97*b0d29bc4SBrooks Davis         std::cout << "Releasing 'test_array' object " << mem << "\n";
98*b0d29bc4SBrooks Davis         if (m_nblocks == 0)
99*b0d29bc4SBrooks Davis             ATF_FAIL("Unbalanced delete[]");
100*b0d29bc4SBrooks Davis         m_nblocks--;
101*b0d29bc4SBrooks Davis         ::operator delete(mem);
102*b0d29bc4SBrooks Davis     }
103*b0d29bc4SBrooks Davis };
104*b0d29bc4SBrooks Davis 
105*b0d29bc4SBrooks Davis 
106*b0d29bc4SBrooks Davis ssize_t test_array::m_nblocks = 0;
107*b0d29bc4SBrooks Davis 
108*b0d29bc4SBrooks Davis 
109*b0d29bc4SBrooks Davis }  // anonymous namespace
110*b0d29bc4SBrooks Davis 
111*b0d29bc4SBrooks Davis 
112*b0d29bc4SBrooks Davis ATF_TEST_CASE(scope);
ATF_TEST_CASE_HEAD(scope)113*b0d29bc4SBrooks Davis ATF_TEST_CASE_HEAD(scope)
114*b0d29bc4SBrooks Davis {
115*b0d29bc4SBrooks Davis     set_md_var("descr", "Tests the automatic scope handling in the "
116*b0d29bc4SBrooks Davis                "auto_array smart pointer class");
117*b0d29bc4SBrooks Davis }
ATF_TEST_CASE_BODY(scope)118*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(scope)
119*b0d29bc4SBrooks Davis {
120*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
121*b0d29bc4SBrooks Davis     {
122*b0d29bc4SBrooks Davis         auto_array< test_array > t(new test_array[10]);
123*b0d29bc4SBrooks Davis         ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
124*b0d29bc4SBrooks Davis     }
125*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
126*b0d29bc4SBrooks Davis }
127*b0d29bc4SBrooks Davis 
128*b0d29bc4SBrooks Davis 
129*b0d29bc4SBrooks Davis ATF_TEST_CASE(copy);
ATF_TEST_CASE_HEAD(copy)130*b0d29bc4SBrooks Davis ATF_TEST_CASE_HEAD(copy)
131*b0d29bc4SBrooks Davis {
132*b0d29bc4SBrooks Davis     set_md_var("descr", "Tests the auto_array smart pointer class' copy "
133*b0d29bc4SBrooks Davis                "constructor");
134*b0d29bc4SBrooks Davis }
ATF_TEST_CASE_BODY(copy)135*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(copy)
136*b0d29bc4SBrooks Davis {
137*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
138*b0d29bc4SBrooks Davis     {
139*b0d29bc4SBrooks Davis         auto_array< test_array > t1(new test_array[10]);
140*b0d29bc4SBrooks Davis         ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
141*b0d29bc4SBrooks Davis 
142*b0d29bc4SBrooks Davis         {
143*b0d29bc4SBrooks Davis             auto_array< test_array > t2(t1);
144*b0d29bc4SBrooks Davis             ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
145*b0d29bc4SBrooks Davis         }
146*b0d29bc4SBrooks Davis         ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
147*b0d29bc4SBrooks Davis     }
148*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
149*b0d29bc4SBrooks Davis }
150*b0d29bc4SBrooks Davis 
151*b0d29bc4SBrooks Davis 
152*b0d29bc4SBrooks Davis ATF_TEST_CASE(copy_ref);
ATF_TEST_CASE_HEAD(copy_ref)153*b0d29bc4SBrooks Davis ATF_TEST_CASE_HEAD(copy_ref)
154*b0d29bc4SBrooks Davis {
155*b0d29bc4SBrooks Davis     set_md_var("descr", "Tests the auto_array smart pointer class' copy "
156*b0d29bc4SBrooks Davis                "constructor through the auxiliary ref object");
157*b0d29bc4SBrooks Davis }
ATF_TEST_CASE_BODY(copy_ref)158*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(copy_ref)
159*b0d29bc4SBrooks Davis {
160*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
161*b0d29bc4SBrooks Davis     {
162*b0d29bc4SBrooks Davis         auto_array< test_array > t1(new test_array[10]);
163*b0d29bc4SBrooks Davis         ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
164*b0d29bc4SBrooks Davis 
165*b0d29bc4SBrooks Davis         {
166*b0d29bc4SBrooks Davis             auto_array< test_array > t2 = t1;
167*b0d29bc4SBrooks Davis             ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
168*b0d29bc4SBrooks Davis         }
169*b0d29bc4SBrooks Davis         ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
170*b0d29bc4SBrooks Davis     }
171*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
172*b0d29bc4SBrooks Davis }
173*b0d29bc4SBrooks Davis 
174*b0d29bc4SBrooks Davis 
175*b0d29bc4SBrooks Davis ATF_TEST_CASE(get);
ATF_TEST_CASE_HEAD(get)176*b0d29bc4SBrooks Davis ATF_TEST_CASE_HEAD(get)
177*b0d29bc4SBrooks Davis {
178*b0d29bc4SBrooks Davis     set_md_var("descr", "Tests the auto_array smart pointer class' get "
179*b0d29bc4SBrooks Davis                "method");
180*b0d29bc4SBrooks Davis }
ATF_TEST_CASE_BODY(get)181*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(get)
182*b0d29bc4SBrooks Davis {
183*b0d29bc4SBrooks Davis     test_array* ta = new test_array[10];
184*b0d29bc4SBrooks Davis     auto_array< test_array > t(ta);
185*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ(t.get(), ta);
186*b0d29bc4SBrooks Davis }
187*b0d29bc4SBrooks Davis 
188*b0d29bc4SBrooks Davis 
189*b0d29bc4SBrooks Davis ATF_TEST_CASE(release);
ATF_TEST_CASE_HEAD(release)190*b0d29bc4SBrooks Davis ATF_TEST_CASE_HEAD(release)
191*b0d29bc4SBrooks Davis {
192*b0d29bc4SBrooks Davis     set_md_var("descr", "Tests the auto_array smart pointer class' release "
193*b0d29bc4SBrooks Davis                "method");
194*b0d29bc4SBrooks Davis }
ATF_TEST_CASE_BODY(release)195*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(release)
196*b0d29bc4SBrooks Davis {
197*b0d29bc4SBrooks Davis     test_array* ta1 = new test_array[10];
198*b0d29bc4SBrooks Davis     {
199*b0d29bc4SBrooks Davis         auto_array< test_array > t(ta1);
200*b0d29bc4SBrooks Davis         ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
201*b0d29bc4SBrooks Davis         test_array* ta2 = t.release();
202*b0d29bc4SBrooks Davis         ATF_REQUIRE_EQ(ta2, ta1);
203*b0d29bc4SBrooks Davis         ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
204*b0d29bc4SBrooks Davis     }
205*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
206*b0d29bc4SBrooks Davis     delete [] ta1;
207*b0d29bc4SBrooks Davis }
208*b0d29bc4SBrooks Davis 
209*b0d29bc4SBrooks Davis 
210*b0d29bc4SBrooks Davis ATF_TEST_CASE(reset);
ATF_TEST_CASE_HEAD(reset)211*b0d29bc4SBrooks Davis ATF_TEST_CASE_HEAD(reset)
212*b0d29bc4SBrooks Davis {
213*b0d29bc4SBrooks Davis     set_md_var("descr", "Tests the auto_array smart pointer class' reset "
214*b0d29bc4SBrooks Davis                "method");
215*b0d29bc4SBrooks Davis }
ATF_TEST_CASE_BODY(reset)216*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(reset)
217*b0d29bc4SBrooks Davis {
218*b0d29bc4SBrooks Davis     test_array* ta1 = new test_array[10];
219*b0d29bc4SBrooks Davis     test_array* ta2 = new test_array[10];
220*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ(test_array::m_nblocks, 2);
221*b0d29bc4SBrooks Davis 
222*b0d29bc4SBrooks Davis     {
223*b0d29bc4SBrooks Davis         auto_array< test_array > t(ta1);
224*b0d29bc4SBrooks Davis         ATF_REQUIRE_EQ(test_array::m_nblocks, 2);
225*b0d29bc4SBrooks Davis         t.reset(ta2);
226*b0d29bc4SBrooks Davis         ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
227*b0d29bc4SBrooks Davis         t.reset();
228*b0d29bc4SBrooks Davis         ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
229*b0d29bc4SBrooks Davis     }
230*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
231*b0d29bc4SBrooks Davis }
232*b0d29bc4SBrooks Davis 
233*b0d29bc4SBrooks Davis 
234*b0d29bc4SBrooks Davis ATF_TEST_CASE(assign);
ATF_TEST_CASE_HEAD(assign)235*b0d29bc4SBrooks Davis ATF_TEST_CASE_HEAD(assign)
236*b0d29bc4SBrooks Davis {
237*b0d29bc4SBrooks Davis     set_md_var("descr", "Tests the auto_array smart pointer class' "
238*b0d29bc4SBrooks Davis                "assignment operator");
239*b0d29bc4SBrooks Davis }
ATF_TEST_CASE_BODY(assign)240*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(assign)
241*b0d29bc4SBrooks Davis {
242*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
243*b0d29bc4SBrooks Davis     {
244*b0d29bc4SBrooks Davis         auto_array< test_array > t1(new test_array[10]);
245*b0d29bc4SBrooks Davis         ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
246*b0d29bc4SBrooks Davis 
247*b0d29bc4SBrooks Davis         {
248*b0d29bc4SBrooks Davis             auto_array< test_array > t2;
249*b0d29bc4SBrooks Davis             t2 = t1;
250*b0d29bc4SBrooks Davis             ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
251*b0d29bc4SBrooks Davis         }
252*b0d29bc4SBrooks Davis         ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
253*b0d29bc4SBrooks Davis     }
254*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
255*b0d29bc4SBrooks Davis }
256*b0d29bc4SBrooks Davis 
257*b0d29bc4SBrooks Davis 
258*b0d29bc4SBrooks Davis ATF_TEST_CASE(assign_ref);
ATF_TEST_CASE_HEAD(assign_ref)259*b0d29bc4SBrooks Davis ATF_TEST_CASE_HEAD(assign_ref)
260*b0d29bc4SBrooks Davis {
261*b0d29bc4SBrooks Davis     set_md_var("descr", "Tests the auto_array smart pointer class' "
262*b0d29bc4SBrooks Davis                "assignment operator through the auxiliary ref "
263*b0d29bc4SBrooks Davis                "object");
264*b0d29bc4SBrooks Davis }
ATF_TEST_CASE_BODY(assign_ref)265*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(assign_ref)
266*b0d29bc4SBrooks Davis {
267*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
268*b0d29bc4SBrooks Davis     {
269*b0d29bc4SBrooks Davis         auto_array< test_array > t1(new test_array[10]);
270*b0d29bc4SBrooks Davis         ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
271*b0d29bc4SBrooks Davis 
272*b0d29bc4SBrooks Davis         {
273*b0d29bc4SBrooks Davis             auto_array< test_array > t2;
274*b0d29bc4SBrooks Davis             t2 = t1;
275*b0d29bc4SBrooks Davis             ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
276*b0d29bc4SBrooks Davis         }
277*b0d29bc4SBrooks Davis         ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
278*b0d29bc4SBrooks Davis     }
279*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
280*b0d29bc4SBrooks Davis }
281*b0d29bc4SBrooks Davis 
282*b0d29bc4SBrooks Davis 
283*b0d29bc4SBrooks Davis ATF_TEST_CASE(access);
ATF_TEST_CASE_HEAD(access)284*b0d29bc4SBrooks Davis ATF_TEST_CASE_HEAD(access)
285*b0d29bc4SBrooks Davis {
286*b0d29bc4SBrooks Davis     set_md_var("descr", "Tests the auto_array smart pointer class' access "
287*b0d29bc4SBrooks Davis                "operator");
288*b0d29bc4SBrooks Davis }
ATF_TEST_CASE_BODY(access)289*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(access)
290*b0d29bc4SBrooks Davis {
291*b0d29bc4SBrooks Davis     auto_array< test_array > t(new test_array[10]);
292*b0d29bc4SBrooks Davis 
293*b0d29bc4SBrooks Davis     for (int i = 0; i < 10; i++)
294*b0d29bc4SBrooks Davis         t[i].m_value = i * 2;
295*b0d29bc4SBrooks Davis 
296*b0d29bc4SBrooks Davis     for (int i = 0; i < 10; i++)
297*b0d29bc4SBrooks Davis         ATF_REQUIRE_EQ(t[i].m_value, i * 2);
298*b0d29bc4SBrooks Davis }
299*b0d29bc4SBrooks Davis 
300*b0d29bc4SBrooks Davis 
ATF_INIT_TEST_CASES(tcs)301*b0d29bc4SBrooks Davis ATF_INIT_TEST_CASES(tcs)
302*b0d29bc4SBrooks Davis {
303*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, scope);
304*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, copy);
305*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, copy_ref);
306*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, get);
307*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, release);
308*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, reset);
309*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, assign);
310*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, assign_ref);
311*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, access);
312*b0d29bc4SBrooks Davis }
313