1// 2001-12-27 pme 2// 3// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2009 4// Free Software Foundation, Inc. 5// 6// This file is part of the GNU ISO C++ Library. This library is free 7// software; you can redistribute it and/or modify it under the 8// terms of the GNU General Public License as published by the 9// Free Software Foundation; either version 3, or (at your option) 10// any later version. 11// 12// This library is distributed in the hope that it will be useful, 13// but WITHOUT ANY WARRANTY; without even the implied warranty of 14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15// GNU General Public License for more details. 16// 17// You should have received a copy of the GNU General Public License along 18// with this library; see the file COPYING3. If not see 19// <http://www.gnu.org/licenses/>. 20 21// 23.2.1.1 deque constructors, copy, and assignment 22 23#include <deque> 24#include <iterator> 25#include <sstream> 26#include <testsuite_allocator.h> 27#include <testsuite_hooks.h> 28 29using __gnu_test::copy_tracker; 30using __gnu_test::tracker_allocator_counter; 31using __gnu_test::tracker_allocator; 32using __gnu_test::copy_constructor; 33using __gnu_test::assignment_operator; 34using __gnu_test::object_counter; 35using __gnu_test::destructor; 36 37typedef std::deque<object_counter> gdeque; 38 39bool test __attribute__((unused)) = true; 40 41// 23.2.1 required types 42// 43// A missing required type will cause a compile failure. 44// 45void 46requiredTypesCheck() 47{ 48 typedef int T; 49 typedef std::deque<T> X; 50 51 typedef X::reference reference; 52 typedef X::const_reference const_reference; 53 typedef X::iterator iterator; 54 typedef X::const_iterator const_iterator; 55 typedef X::size_type size_type; 56 typedef X::difference_type difference_type; 57 typedef X::value_type value_type; 58 typedef X::allocator_type allocator_type; 59 typedef X::pointer pointer; 60 typedef X::const_pointer const_pointer; 61 typedef X::reverse_iterator reverse_iterator; 62 typedef X::const_reverse_iterator const_reverse_iterator; 63} 64 65 66// @fn defaultConstructorCheck 67// Explicitly checks the default deque constructor and destructor for both 68// trivial and non-trivial types. In addition, the size() and empty() 69// member functions are explicitly checked here since it should be their 70// first use. Checking those functions means checking the begin() and 71// end() and their const brethren functions as well. 72// 73// @verbatim 74// 23.2.1.1 default ctor/dtor 75// effects: 76// 23.2.1.1 constructs an empty deque using the specified allocator 77// postconditions: 78// 23.1 table 65 u.size() == 0 79// throws: 80// complexity: 81// 23.1 table 65 constant 82// 83// 23.2.1.2 bool empty() const 84// semantics: 85// 23.1 table 65 a.size() == 0 86// 23.1 (7) a.begin() == a.end() 87// throws: 88// complexity: 89// 23.1 table 65 constant 90// 91// 23.2.1.2 size_type size() const 92// semantics: 93// 23.1 table 65 a.end() - a.begin() 94// throws: 95// complexity: 96// 23.1 table 65(A) should be constant 97// 98// 23.2.1 iterator begin() 99// const_iterator begin() const 100// iterator end() 101// const_iterator end() const 102// throws: 103// 23.1 (10) pt. 4 does not throw 104// complexity: 105// 23.1 table 65 constant 106// @endverbatim 107void 108defaultConstructorCheckPOD() 109{ 110 // setup 111 typedef int T; 112 typedef std::deque<T> X; 113 114 // run test 115 X u; 116 117 // assert postconditions 118 VERIFY(u.empty()); 119 VERIFY(0 == u.size()); 120 VERIFY(u.begin() == u.end()); 121 VERIFY(0 == std::distance(u.begin(), u.end())); 122 123 // teardown 124} 125 126 127void 128defaultConstructorCheck() 129{ 130 // setup 131 typedef copy_tracker T; 132 typedef std::deque<T> X; 133 134 copy_tracker::reset(); 135 136 // run test 137 const X u; 138 139 // assert postconditions 140 VERIFY(u.empty()); 141 VERIFY(0 == u.size()); 142 VERIFY(u.begin() == u.end()); 143 VERIFY(0 == std::distance(u.begin(), u.end())); 144 145 // teardown 146} 147 148 149// @fn copyConstructorCheck() 150// Explicitly checks the deque copy constructor. Continues verificaton of 151// ancillary member functions documented under defaultConstructorCheck(). 152// 153// This check also tests the push_back() member function. 154// 155// @verbatim 156// 23.2.1 copy constructor 157// effects: 158// postconditions: 159// 22.1.1 table 65 a == X(a) 160// u == a 161// throws: 162// complexity: 163// 22.1.1 table 65 linear 164// @endverbatim 165void 166copyConstructorCheck() 167{ 168 // setup 169 typedef copy_tracker T; 170 typedef std::deque<T> X; 171 172 const std::size_t copyBaseSize = 17; // arbitrary 173 174 X a; 175 for (std::size_t i = 0; i < copyBaseSize; ++i) 176 a.push_back(i); 177 copy_tracker::reset(); 178 179 // assert preconditions 180 VERIFY(!a.empty()); 181 VERIFY(copyBaseSize == a.size()); 182 VERIFY(a.begin() != a.end()); 183 VERIFY( copyBaseSize == static_cast<std::size_t>(std::distance(a.begin(), a.end())) ); 184 185 // run test 186 X u = a; 187 188 // assert postconditions 189 VERIFY(u == a); 190 VERIFY(copyBaseSize == copy_constructor::count()); 191 192 // teardown 193} 194 195 196// @fn fillConstructorCheck() 197// This test explicitly verifies the basic fill constructor. Like the default 198// constructor, later tests depend on the fill constructor working correctly. 199// That means this explicit test should preceed the later tests so the error 200// message given on assertion failure can be more helpful n tracking the 201// problem. 202// 203// 23.2.1.1 fill constructor 204// complexity: 205// 23.2.1.1 linear in N 206void 207fillConstructorCheck() 208{ 209 // setup 210 typedef copy_tracker T; 211 typedef std::deque<T> X; 212 213 const X::size_type n(23); 214 const X::value_type t(111); 215 216 copy_tracker::reset(); 217 218 // run test 219 X a(n, t); 220 221 // assert postconditions 222 VERIFY(n == a.size()); 223 VERIFY(n == copy_constructor::count()); 224 225 // teardown 226} 227 228 229// @fn fillConstructorCheck2() 230// Explicit check for fill constructors masqueraded as range constructors as 231// elucidated in clause 23.1.1 paragraph 9 of the standard. 232// 233// 23.1.1 (9) fill constructor looking like a range constructor 234void 235fillConstructorCheck2() 236{ 237 typedef copy_tracker T; 238 typedef std::deque<T> X; 239 240 const std::size_t f = 23; 241 const std::size_t l = 111; 242 243 copy_tracker::reset(); 244 245 X a(f, l); 246 247 VERIFY(f == a.size()); 248 VERIFY(f == copy_constructor::count()); 249} 250 251 252// @fn rangeConstructorCheckForwardIterator() 253// This test copies from one deque to another to force the copy 254// constructor for T to be used because the compiler will kindly 255// elide copies if the default constructor can be used with 256// type conversions. Trust me. 257// 258// 23.2.1.1 range constructor, forward iterators 259void 260rangeConstructorCheckForwardIterator() 261{ 262 // setup 263 typedef copy_tracker T; 264 typedef std::deque<T> X; 265 266 const X::size_type n(726); 267 const X::value_type t(307); 268 X source(n, t); 269 X::iterator i = source.begin(); 270 X::iterator j = source.end(); 271 X::size_type rangeSize = std::distance(i, j); 272 273 copy_tracker::reset(); 274 275 // test 276 X a(i, j); 277 278 // assert postconditions 279 VERIFY(rangeSize == a.size()); 280 VERIFY(copy_constructor::count() <= rangeSize); 281} 282 283 284// @fn rangeConstructorCheckInputIterator() 285// An explicit check for range construction on an input iterator 286// range, which the standard expounds upon as having a different 287// complexity than forward iterators. 288// 289// 23.2.1.1 range constructor, input iterators 290void 291rangeConstructorCheckInputIterator() 292{ 293 typedef copy_tracker T; 294 typedef std::deque<T> X; 295 296 std::istringstream ibuf("1234567890123456789"); 297 const X::size_type rangeSize = ibuf.str().size(); 298 std::istream_iterator<char> i(ibuf); 299 std::istream_iterator<char> j; 300 301 copy_tracker::reset(); 302 303 X a(i, j); 304 305 VERIFY(rangeSize == a.size()); 306 VERIFY(copy_constructor::count() <= (2 * rangeSize)); 307} 308 309 310// 23.2.1 copy assignment 311void 312copyAssignmentCheck() 313{ 314 typedef copy_tracker T; 315 typedef std::deque<T> X; 316 317 const X::size_type n(18); 318 const X::value_type t(1023); 319 X a(n, t); 320 X r; 321 322 copy_tracker::reset(); 323 324 r = a; 325 326 VERIFY(r == a); 327 VERIFY(n == copy_constructor::count()); 328} 329 330 331// 23.2.1.1 fill assignment 332// 333// The complexity check must check dtors+copyAssign and 334// copyCtor+copyAssign because that's the way the SGI implementation 335// works. Dunno if it's true standard compliant (which specifies fill 336// assignment in terms of erase and insert only), but it should work 337// as (most) users expect and is more efficient. 338void 339fillAssignmentCheck() 340{ 341 typedef copy_tracker T; 342 typedef std::deque<T> X; 343 344 const X::size_type starting_size(10); 345 const X::value_type starting_value(66); 346 const X::size_type n(23); 347 const X::value_type t(111); 348 349 X a(starting_size, starting_value); 350 copy_tracker::reset(); 351 352 // preconditions 353 VERIFY(starting_size == a.size()); 354 355 // test 356 a.assign(n, t); 357 358 // postconditions 359 VERIFY(n == a.size()); 360 VERIFY(n == (copy_constructor::count() + assignment_operator::count())); 361 VERIFY(starting_size == (destructor::count() + assignment_operator::count())); 362} 363 364 365// @verbatim 366// 23.2.1 range assignment 367// 23.2.1.1 deque constructors, copy, and assignment 368// effects: 369// Constructs a deque equal to the range [first, last), using the 370// specified allocator. 371// 372// template<typename InputIterator> 373// assign(InputIterator first, InputIterator last); 374// 375// is equivalent to 376// 377// erase(begin(), end()); 378// insert(begin(), first, last); 379// 380// postconditions: 381// throws: 382// complexity: 383// forward iterators: N calls to the copy constructor, 0 reallocations 384// input iterators: 2N calls to the copy constructor, log(N) reallocations 385// @endverbatim 386void 387rangeAssignmentCheck() 388{ 389 typedef copy_tracker T; 390 typedef std::deque<T> X; 391 392 const X::size_type source_size(726); 393 const X::value_type source_value(307); 394 const X::size_type starting_size(10); 395 const X::value_type starting_value(66); 396 397 X source(source_size, source_value); 398 X::iterator i = source.begin(); 399 X::iterator j = source.end(); 400 X::size_type rangeSize = std::distance(i, j); 401 402 X a(starting_size, starting_value); 403 VERIFY(starting_size == a.size()); 404 405 copy_tracker::reset(); 406 407 a.assign(i, j); 408 409 VERIFY(source == a); 410 VERIFY(rangeSize == (copy_constructor::count() + assignment_operator::count())); 411 VERIFY(starting_size == (destructor::count() + assignment_operator::count())); 412} 413 414 415// 23.1 (10) range assignment 416// 23.2.1.3 with exception 417void 418rangeAssignmentCheckWithException() 419{ 420 // setup 421 typedef copy_tracker T; 422 typedef std::deque<T> X; 423 424 // test 425 // What does "no effects" mean? 426} 427 428 429// 23.1.1 (9) fill assignment looking like a range assignment 430void 431fillAssignmentCheck2() 432{ 433 // setup 434 typedef copy_tracker T; 435 typedef std::deque<T> X; 436 437 // test 438 // What does "no effects" mean? 439} 440 441// Verify that the default deque constructor offers the basic exception 442// guarantee. 443void 444test_default_ctor_exception_safety() 445{ 446 // setup 447 typedef copy_tracker T; 448 typedef std::deque<T, tracker_allocator<T> > X; 449 450 T::reset(); 451 copy_constructor::throw_on(3); 452 tracker_allocator_counter::reset(); 453 454 // test 455 try 456 { 457 X a(7); 458 VERIFY( false ); 459 } 460 catch (...) 461 { 462 } 463 464 // assert postconditions 465 VERIFY(tracker_allocator_counter::get_allocation_count() == tracker_allocator_counter::get_deallocation_count()); 466 467 // teardown 468} 469 470// Verify that the copy constructor offers the basic exception guarantee. 471void 472test_copy_ctor_exception_safety() 473{ 474 // setup 475 typedef copy_tracker T; 476 typedef std::deque<T, tracker_allocator<T> > X; 477 478 tracker_allocator_counter::reset(); 479 { 480 X a(7); 481 T::reset(); 482 copy_constructor::throw_on(3); 483 484 485 // test 486 try 487 { 488 X u(a); 489 VERIFY(false); 490 } 491 catch (...) 492 { 493 } 494 } 495 496 // assert postconditions 497 VERIFY(tracker_allocator_counter::get_allocation_count() == tracker_allocator_counter::get_deallocation_count()); 498 499 // teardown 500} 501 502int main() 503{ 504 // basic functionality and standard conformance checks 505 requiredTypesCheck(); 506 defaultConstructorCheckPOD(); 507 defaultConstructorCheck(); 508 test_default_ctor_exception_safety(); 509 copyConstructorCheck(); 510 test_copy_ctor_exception_safety(); 511 fillConstructorCheck(); 512 fillConstructorCheck2(); 513 rangeConstructorCheckInputIterator(); 514 rangeConstructorCheckForwardIterator(); 515 copyAssignmentCheck(); 516 fillAssignmentCheck(); 517 fillAssignmentCheck2(); 518 rangeAssignmentCheck(); 519 rangeAssignmentCheckWithException(); 520 return 0; 521} 522