• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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