1 2 // Copyright (C) 2008-2018 Lorenzo Caminiti 3 // Distributed under the Boost Software License, Version 1.0 (see accompanying 4 // file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt). 5 // See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html 6 7 //[n1962_vector_n1962 8 // Extra spaces, newlines, etc. for visual alignment with this library code. 9 10 #include <boost/algorithm/cxx11/all_of.hpp> 11 #include <boost/type_traits/has_equal_to.hpp> 12 #include <boost/next_prior.hpp> 13 #include <vector> 14 #include <iterator> 15 #include <memory> 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 template< class T, class Allocator = std::allocator<T> > 46 class vector { 47 48 49 invariant { 50 empty() == (size() == 0); 51 std::distance(begin(), end()) == int(size()); 52 std::distance(rbegin(), rend()) == int(size()); 53 size() <= capacity(); 54 capacity() <= max_size(); 55 } 56 57 public: 58 typedef typename std::vector<T, Allocator>::allocator_type allocator_type; 59 typedef typename std::vector<T, Allocator>::pointer pointer; 60 typedef typename std::vector<T, Allocator>::const_pointer const_pointer; 61 typedef typename std::vector<T, Allocator>::reference reference; 62 typedef typename std::vector<T, Allocator>::const_reference const_reference; 63 typedef typename std::vector<T, Allocator>::value_type value_type; 64 typedef typename std::vector<T, Allocator>::iterator iterator; 65 typedef typename std::vector<T, Allocator>::const_iterator const_iterator; 66 typedef typename std::vector<T, Allocator>::size_type size_type; 67 typedef typename std::vector<T, Allocator>::difference_type difference_type; 68 typedef typename std::vector<T, Allocator>::reverse_iterator 69 reverse_iterator; 70 typedef typename std::vector<T, Allocator>::const_reverse_iterator 71 const_reverse_iterator; 72 vector()73 vector() 74 postcondition { 75 empty(); 76 } 77 : vect_() 78 {} 79 80 vector(Allocator const & alloc)81 explicit vector(Allocator const& alloc) 82 postcondition { 83 empty(); 84 get_allocator() == alloc; 85 } 86 : vect_(alloc) 87 {} 88 89 vector(size_type count)90 explicit vector(size_type count) 91 postcondition { 92 size() == count; 93 if constexpr(boost::has_equal_to<T>::value) { 94 boost::algorithm::all_of_equal(begin(), end(), T()); 95 } 96 } 97 : vect_(count) 98 {} 99 100 101 102 vector(size_type count,T const & value)103 vector(size_type count, T const& value) 104 postcondition { 105 size() == count; 106 if constexpr(boost::has_equal_to<T>::value) { 107 boost::algorithm::all_of_equal(begin(), end(), value); 108 } 109 } 110 : vect_(count, value) 111 {} 112 113 114 115 116 vector(size_type count,T const & value,Allocator const & alloc)117 vector(size_type count, T const& value, Allocator const& alloc) 118 postcondition { 119 size() == count; 120 if constexpr(boost::has_equal_to<T>::value) { 121 boost::algorithm::all_of_equal(begin(), end(), value); 122 } 123 get_allocator() == alloc; 124 } 125 : vect_(count, value, alloc) 126 {} 127 128 129 130 131 132 133 template<typename InputIter> vector(InputIter first,InputIter last)134 vector(InputIter first, InputIter last) 135 postcondition { 136 std::distance(first, last) == int(size()); 137 } 138 : vect_(first, last) 139 {} 140 141 142 143 template<typename InputIter> vector(InputIter first,InputIter last,Allocator const & alloc)144 vector(InputIter first, InputIter last, Allocator const& alloc) 145 postcondition { 146 std::distance(first, last) == int(size()); 147 get_allocator() == alloc; 148 } 149 : vect_(first, last, alloc) 150 {} 151 152 153 154 vector(vector const & other)155 /* implicit */ vector(vector const& other) 156 postcondition { 157 if constexpr(boost::has_equal_to<T>::value) { 158 *this == other; 159 } 160 } 161 : vect_(other.vect_) 162 {} 163 164 165 166 167 operator =(vector const & other)168 vector& operator=(vector const& other) 169 postcondition(result) { 170 if constexpr(boost::has_equal_to<T>::value) { 171 *this == other; 172 result == *this; 173 } 174 } 175 { 176 if(this != &other) vect_ = other.vect_; 177 return *this; 178 } 179 180 181 182 183 184 185 186 187 188 189 190 ~vector()191 virtual ~vector() {} 192 193 194 195 reserve(size_type count)196 void reserve(size_type count) 197 precondition { 198 count < max_size(); 199 } 200 postcondition { 201 capacity() >= count; 202 } 203 { 204 vect_.reserve(count); 205 } 206 207 208 capacity() const209 size_type capacity() const 210 postcondition(result) { 211 result >= size(); 212 } 213 { 214 return vect_.capacity(); 215 } 216 217 218 219 begin()220 iterator begin() 221 postcondition { 222 if(empty()) result == end(); 223 } 224 { 225 return vect_.begin(); 226 } 227 228 229 230 begin() const231 const_iterator begin() const 232 postcondition(result) { 233 if(empty()) result == end(); 234 } 235 { 236 return vect_.begin(); 237 } 238 239 240 241 end()242 iterator end() { 243 return vect_.end(); 244 } 245 246 247 end() const248 const_iterator end() const { 249 return vect_.end(); 250 } 251 252 253 rbegin()254 reverse_iterator rbegin() 255 postcondition(result) { 256 if(empty()) result == rend(); 257 } 258 { 259 return vect_.rbegin(); 260 } 261 262 263 264 rbegin() const265 const_reverse_iterator rbegin() const 266 postcondition(result) { 267 if(empty()) result == rend(); 268 } 269 { 270 return vect_.rbegin(); 271 } 272 273 274 275 rend()276 reverse_iterator rend() { 277 return vect_.rend(); 278 } 279 280 281 rend() const282 const_reverse_iterator rend() const { 283 return vect_.rend(); 284 } 285 286 287 resize(size_type count,T const & value=T ())288 void resize(size_type count, T const& value = T()) 289 postcondition { 290 size() == count; 291 if constexpr(boost::has_equal_to<T>::value) { 292 if(count > oldof(size())) { 293 boost::algorithm::all_of_equal(begin() + oldof(size()), 294 end(), value); 295 } 296 } 297 } 298 { 299 vect_.resize(count, value); 300 } 301 302 303 304 305 306 307 size() const308 size_type size() const 309 postcondition(result) { 310 result <= capacity(); 311 } 312 { 313 return vect_.size(); 314 } 315 316 317 318 max_size() const319 size_type max_size() const 320 postcondition(result) { 321 result >= capacity(); 322 } 323 { 324 return vect_.max_size(); 325 } 326 327 328 329 empty() const330 bool empty() const 331 postcondition(result) { 332 result == (size() == 0); 333 } 334 { 335 return vect_.empty(); 336 } 337 338 339 340 get_allocator() const341 Alloctor get_allocator() const { 342 return vect_.get_allocator(); 343 } 344 345 346 at(size_type index)347 reference at(size_type index) { 348 // No precondition (throw out_of_range for invalid index). 349 return vect_.at(index); 350 } 351 352 at(size_type index) const353 const_reference at(size_type index) const { 354 // No precondition (throw out_of_range for invalid index). 355 return vect_.at(index); 356 } 357 358 operator [](size_type index)359 reference operator[](size_type index) 360 precondition { 361 index < size(); 362 } 363 { 364 return vect_[index]; 365 } 366 367 368 operator [](size_type index) const369 const_reference operator[](size_type index) const 370 precondition { 371 index < size(); 372 } 373 { 374 return vect_[index]; 375 } 376 377 378 front()379 reference front() 380 precondition { 381 !empty(); 382 } 383 { 384 return vect_.front(); 385 } 386 387 388 front() const389 const_reference front() const 390 precondition { 391 !empty(); 392 } 393 { 394 return vect_.front(); 395 } 396 397 398 back()399 reference back() 400 precondition { 401 !empty(); 402 } 403 { 404 return vect_.back(); 405 } 406 407 408 back() const409 const_reference back() const 410 precondition { 411 !empty(); 412 } 413 { 414 return vect_.back(); 415 } 416 417 418 push_back(T const & value)419 void push_back(T const& value) 420 precondition { 421 size() < max_size(); 422 } 423 postcondition { 424 size() == oldof(size()) + 1; 425 capacity() >= oldof(capacity()) 426 if constexpr(boost::has_equal_to<T>::value) { 427 back() == value; 428 } 429 } 430 { 431 vect_.push_back(value); 432 } 433 434 435 436 437 438 439 440 441 442 pop_back()443 void pop_back() 444 precondition { 445 !empty(); 446 } 447 postcondition { 448 size() == oldof(size()) - 1; 449 } 450 { 451 vect_.pop_back(); 452 } 453 454 455 456 457 458 template<typename InputIter> assign(InputIter first,InputIter last)459 void assign(InputIter first, InputIter last) 460 // Precondition: [begin(), end()) does not contain [first, last). 461 postcondition { 462 std::distance(first, last) == int(size()); 463 } 464 { 465 vect_.assign(first, last); 466 } 467 468 469 470 471 472 473 assign(size_type count,T const & vallue)474 void assign(size_type count, T const& vallue) 475 precondition { 476 count <= max_size(); 477 } 478 postcondition { 479 if constexpr(boost::has_equal_to<T>::value) { 480 boost::algorithm::all_of_equal(begin(), end(), value); 481 } 482 } 483 { 484 vect_.assign(count, value); 485 } 486 487 488 489 490 491 insert(iterator where,T const & value)492 iterator insert(iterator where, T const& value) 493 precondition { 494 size() < max_size(); 495 } postcondition(result)496 postcondition(result) { 497 size() == oldof(size()) + 1; 498 capacity() >= oldof(capacity()); 499 if constexpr(boost::has_equal_to<T>::value) { 500 *result == value; 501 } 502 // if(capacity() > oldof(capacity())) 503 // [begin(), end()) is invalid 504 // else 505 // [where, end()) is invalid 506 } 507 { 508 return vect_.insert(where, value); 509 } 510 511 512 513 514 515 516 517 518 519 520 521 insert(iterator where,size_type count,T const & value)522 void insert(iterator where, size_type count, T const& value) 523 precondition { 524 size() + count < max_size(); 525 } 526 postcondition { 527 size() == oldof(size()) + count; 528 capacity() >= oldof(capacity()); 529 if(capacity() == oldof(capacity())) { 530 if constexpr(boost::has_equal_to<T>::value) { 531 boost::algorithm::all_of_equal(boost::prior(oldof(where)), 532 boost::prior(oldof(where)) + count, value); 533 } 534 // [where, end()) is invalid 535 } 536 // else [begin(), end()) is invalid 537 } 538 { 539 vect_.insert(where, count, value); 540 } 541 542 543 544 545 546 547 548 549 550 551 552 553 554 template<typename InputIter> insert(iterator where,Iterator first,Iterator last)555 void insert(iterator where, Iterator first, Iterator last) 556 precondition { 557 size() + std::distance(first, last) < max_size(); 558 // [first, last) is not contained in [begin(), end()) 559 } 560 postcondition { 561 size() == oldof(size()) + std::distance(first, last); 562 capacity() >= oldof(capacity()); 563 if(capacity() == oldof(capacity())) { 564 if constexpr(boost::has_equal_to<T>::value) { 565 boost::algorithm::all_of_equal(first, last, oldof(where)); 566 } 567 // [where, end()) is invalid 568 } 569 // else [begin(), end()) is invalid 570 } 571 { 572 vect_.insert(where, first, last); 573 } 574 575 576 577 578 579 580 581 582 583 584 585 586 587 erase(iterator where)588 iterator erase(iterator where) 589 precondition { 590 !empty(); 591 where != end(); 592 } postcondition(result)593 postcondition(result) { 594 size() == oldod size() - 1; 595 if(empty()) result == end(); 596 // [where, end()) is invalid 597 } 598 { 599 return vect_.erase(where); 600 } 601 602 603 604 605 606 erase(iterator first,iterator last)607 iterator erase(iterator first, iterator last) 608 precondition { 609 size() >= std::distance(first, lasst); 610 } postcondition(result)611 postcondition(result) { 612 size() == oldof(size()) - std::distance(first, last); 613 if(empty()) result == end(); 614 // [first, last) is invalid 615 } 616 { 617 return vect_.erase(first, last); 618 } 619 620 621 622 623 624 625 clear()626 void clear() 627 postcondition { 628 empty(); 629 } 630 { 631 vect_.clear(); 632 } 633 634 635 swap(vector & other)636 void swap(vector& other) 637 precondition { 638 get_allocator() == other.get_allocator(); 639 } 640 postcondition { 641 if constexpr(boost::has_equal_to<T>::value) { 642 *this == oldof(other); 643 other == oldof(*this); 644 } 645 } 646 { 647 vect_.swap(other); 648 } 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 operator ==(vector const & left,vector const & right)667 friend bool operator==(vector const& left, vector const& right) { 668 // Cannot check class invariants for left and right objects. 669 return left.vect_ == right.vect_; 670 } 671 672 673 674 675 676 private: 677 std::vector<T, Allocator> vect_; 678 }; 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 // End. 724 //] 725 726