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