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