You are on page 1of 17

Contents

1 Basic Test Results 2

2 STATEMENT.pdf 4

3 VLVector.hpp 5

1
1 Basic Test Results
1 ********************************************
2 * *
3 * Hello C++ Workshop Student, *
4 * We wish you good luck on your exam! *
5 * *
6 ********************************************
7 Running...
8
9 Opening tar file
10 OK
11 Tar extracted O.K.
12
13 Checking files...
14 OK
15 Making sure files are not empty...
16 OK
17 Compilation check...
18
19 Compiling...
20 OK
21 Compiling...
22 OK
23
24 **********************************
25 * *
26 * Compilation seems OK! *
27 * Check if you got warnings! *
28 * *
29 **********************************
30
31 =====================
32 Public test cases
33 =====================
34
35 [#0][Presubmission] Test __presubmit_testCreateVLAs... OK!
36 [#1][Presubmission] Test __presubmit_testPushBack... OK!
37 [#2][Presubmission] Test __presubmit_testSize... OK!
38 [#3][Presubmission] Test __presubmit_testCapacity... OK!
39 [#4][Presubmission] Test __presubmit_testEmpty... OK!
40 [#5][Presubmission] Test __presubmit_testClear... OK!
41 [#6][Presubmission] Test __presubmit_testPopBack... OK!
42 [#7][Presubmission] Test __presubmit_testGetElement... OK!
43 [#8][Presubmission] Test __presubmit_testData... OK!
44 [#9][Presubmission] Test __presubmit_testComparison... OK!
45 [#10][Presubmission] Test __presubmit_testAssignment... OK!
46 [#11][Presubmission] Test __presubmit_testIterator... OK!
47 [#12][Presubmission] Test __presubmit_testInsert1... OK!
48 [#13][Presubmission] Test __presubmit_testInsert2... OK!
49 [#14][Presubmission] Test __presubmit_testErase1... OK!
50 [#15][Presubmission] Test __presubmit_testIteratorsCtor... OK!
51 [#16][Presubmission] Test __presubmit_testCopyCtor... OK!
52 Running PresubmissionTests
53 OK
54 ***********************************
55 * *
56 * presubmission script passed *
57 * *
58 ***********************************
59

2
60 =========================
61 = Checking coding style =
62 =========================
63 VLVector.hpp(571, 7): func_name_special {Function name(push_back) should not contains special characters or underbars}
64 VLVector.hpp(599, 7): func_name_special {Function name(pop_back) should not contains special characters or underbars}
65 ** Total Violated Rules : 1
66 ** Total Errors Occurs : 2
67 ** Total Violated Files Count: 1

3
‫ ‬

‫הצהרה על מקוריות עבודה‬

‫)נא לסמן ‪ V‬בכל סעיף(‬

‫אני מצהיר‪/‬ה בזאת שפתרון המבחן‪/‬מטלה בכתב בקורס ‪67315‬‬


‫‪ ++Programming workshop in C & C‬שהתקיים בתאריך ‪ 2.8.20‬הינו‬
‫פרי עבודתי המקורית ולא הועתק מתלמיד אחר‪ .‬כמו כן‪ ,‬לא נעזרתי בחומר שאינו‬
‫מאושר על ידי מורי הקורס‪.‬‬

‫אני מצהיר‪/‬ה בזאת שלא עזרתי לאף תלמיד‪/‬ה בפתרון הבחינה‪/‬המטלה‪.‬‬

‫אני מצהיר‪/‬ה בזאת כי ידוע לי שאם יתגלה כי עברתי עבירת העתקה מסוג זה‪,‬‬
‫תוגש נגדי תלונה על כך לוועדת המשמעת של האוניברסיטה העברית‪.‬‬

‫אני מבין שלמסמך זה תוקף משפטי על כל ההשלכות האמורות מכך‪.‬‬

‫עקוב‬ ‫עידו‬ ‫‪2.8.2020‬‬


‫חתימה‬ ‫שם משפחה‬ ‫שם פרטי‬ ‫תאריך‬
3 VLVector.hpp
1 #include <cstddef> //size_t
2 #include <stdexcept> // std::out_of_range
3 #include <algorithm>
4
5 #ifndef EXAM2_VLVector_HPP
6 #define EXAM2_VLVector_HPP
7
8 //macros
9 #define RANGE_ERROR "index is out of range\n"
10 #define STATIC_CAPACITY 16
11
12 //namespaces
13 using std::size_t;
14 using std::out_of_range;
15 using std::ptrdiff_t;
16 using std::random_access_iterator_tag;
17 using std::distance;
18 using std::rotate;
19 using std::copy;
20 using std::equal;
21
22 //class uses generic types, one fixed
23 template<typename T, size_t C = STATIC_CAPACITY>
24
25 /**
26 * virtual length vector- a vector-like container which makes use of either the stack or the
27 * heap, depending on size and capacity
28 * @tparam T type of element
29 * @tparam C value of static capacity
30 */
31 class VLVector
32 {
33 /**
34 * random access iterator class for VLVector<T,C> container
35 */
36 class Iterator
37 {
38 //pointer to store address
39 T *_ptr;
40
41 public:
42 //iterator traits
43 typedef T value_type;
44 typedef T *&pointer;
45 typedef T &reference;
46 typedef ptrdiff_t difference_type;
47 typedef random_access_iterator_tag iterator_category;
48
49 /**
50 * default ctor
51 */
52 Iterator() : _ptr(nullptr)
53 {}
54
55 /**
56 * pointer ctor
57 * @param ptr pointer
58 */
59 Iterator(T *ptr) : _ptr(ptr)

5
60 {}
61
62
63 /**
64 * get iterator pointer
65 * @return pointer
66 */
67 pointer getPtr()
68 { return _ptr; }
69
70 //read and write
71 /**
72 * dereference operator
73 * @return reference to value
74 */
75 reference operator*()
76 { return *_ptr; }
77
78 //iteration
79 /**
80 * prefix increment
81 * @return iterator
82 */
83 Iterator &operator++()
84 {
85 _ptr++;
86 return *this;
87 }
88
89 /**
90 * postfix increment
91 * @return iterator
92 */
93 Iterator operator++(int)
94 {
95 Iterator it(*this);
96 _ptr++;
97 return it;
98 }
99
100 /**
101 * prefix decrement
102 * @return iterator
103 */
104 Iterator &operator--()
105 {
106 _ptr--;
107 return *this;
108 }
109
110 /**
111 * postfix decrement
112 * @return iterator
113 */
114 Iterator operator--(int)
115 {
116 Iterator it(*this);
117 _ptr--;
118 return it;
119 }
120
121 /**
122 * offset iterator by int
123 * @param i int
124 * @return this iterator
125 */
126 Iterator &operator+=(int i)
127 {

6
128 _ptr += i;
129 return *this;
130 }
131
132 /**
133 * offset iterator by int
134 * @param i int
135 * @return this iterator
136 */
137 Iterator &operator-=(int i)
138 {
139 _ptr -= i;
140 return *this;
141 }
142
143 /**
144 * return offset of iterator as new iterator
145 * @param i int
146 * @return iterator
147 */
148 Iterator operator+(int i) const
149 {
150 Iterator it(*this);
151 return it += i;
152 }
153
154 /**
155 * return offset of iterator as new iterator
156 * @param i int
157 * @return iterator
158 */
159 Iterator operator-(int i) const
160 {
161 Iterator it(*this);
162 return it -= i;
163 }
164
165 /**
166 * return distance between two iterators
167 * @param other iterator
168 * @return distance
169 */
170 difference_type operator-(const Iterator &other) const
171 { return _ptr - other._ptr; }
172
173 //comparison
174 /**
175 * smaller-than operator
176 * @param other iterator
177 * @return true or false
178 */
179 bool operator<(const Iterator &other) const
180 { return _ptr < other._ptr; }
181
182 /**
183 * smaller-than or equal operator
184 * @param other iterator
185 * @return true or false
186 */
187 bool operator<=(const Iterator &other) const
188 { return _ptr <= other._ptr; }
189
190 /**
191 * larger-than operator
192 * @param other iterator
193 * @return true or false
194 */
195 bool operator>(const Iterator &other) const

7
196 { return _ptr > other._ptr; }
197
198 /**
199 * larger-than or equal operator
200 * @param other iterator
201 * @return true or false
202 */
203 bool operator>=(const Iterator &other) const
204 { return _ptr >= other._ptr; }
205
206 /**
207 * comparison operator
208 * @param other iterator
209 * @return true or false
210 */
211 bool operator==(const Iterator &other) const
212 { return _ptr == other._ptr; }
213
214 /**
215 * unequal comparison operator
216 * @param other iterator
217 * @return true or false
218 */
219 bool operator!=(const Iterator &other) const
220 { return _ptr != other._ptr; }
221 };
222
223 /**
224 * random access const iterator class for VLVector<T,C> container
225 */
226 class ConstIterator
227 {
228 T *_ptr;
229
230 public:
231 //const_iterator traits
232 typedef T value_type;
233 typedef const T *pointer;
234 typedef const T &reference;
235 typedef ptrdiff_t difference_type;
236 typedef random_access_iterator_tag iterator_category;
237
238 /**
239 * default ctor
240 */
241 ConstIterator() : _ptr(nullptr)
242 {}
243
244 /**
245 * pointer ctor
246 * @param ptr pointer
247 */
248 ConstIterator(T *ptr) : _ptr(ptr)
249 {}
250
251 /**
252 * conversion constructor
253 * @param it
254 */
255 ConstIterator(Iterator it) : _ptr(it.getPtr())
256 {}
257
258 //read only
259 /**
260 * dereference operator
261 * @return reference to const value
262 */
263 reference operator*() const

8
264 { return *_ptr; }
265
266 //iteration:
267 /**
268 * prefix increment operator
269 * @return const iterator
270 */
271 ConstIterator &operator++()
272 {
273 _ptr++;
274 return *this;
275 }
276
277 /**
278 * postfix increment operator
279 * @return const iterator
280 */
281 ConstIterator operator++(int)
282 {
283 ConstIterator it(*this);
284 _ptr++;
285 return it;
286 }
287
288 /**
289 * prefix decrement operator
290 * @return const iterator
291 */
292 ConstIterator &operator--()
293 {
294 _ptr--;
295 return *this;
296 }
297
298 /**
299 * postfix decrement operator
300 * @return const iterator
301 */
302 ConstIterator operator--(int)
303 {
304 ConstIterator it(*this);
305 _ptr--;
306 return it;
307 }
308
309 /**
310 * offset const iterator by int
311 * @param i int
312 * @return this const iterator
313 */
314 ConstIterator &operator+=(int i)
315 {
316 _ptr += i;
317 return *this;
318 }
319
320 /**
321 * offset const iterator by int
322 * @param i int
323 * @return this const iterator
324 */
325 ConstIterator &operator-=(int i)
326 {
327 _ptr -= i;
328 return *this;
329 }
330
331 /**

9
332 * offset and return new const iterator
333 * @param i int
334 * @return const iterator
335 */
336 ConstIterator operator+(int i) const
337 {
338 ConstIterator it(*this);
339 return it += i;
340 }
341
342 /**
343 * offset and return new const iterator
344 * @param i int
345 * @return this const iterator
346 */
347 ConstIterator operator-(int i) const
348 {
349 ConstIterator it(*this);
350 return it -= i;
351 }
352
353 /**
354 * find distance between two const iterators
355 * @param other const iterator
356 * @return distance
357 */
358 difference_type operator-(const ConstIterator &other) const
359 { return _ptr - other._ptr; }
360
361 //comparison
362 /**
363 * smaller-than operator
364 * @param other const iterator
365 * @return true or false
366 */
367 bool operator<(const ConstIterator &other) const
368 { return _ptr < other._ptr; }
369
370 /**
371 * smaller-than or equal operator
372 * @param other const iterator
373 * @return true or false
374 */
375 bool operator<=(const ConstIterator &other) const
376 { return _ptr <= other._ptr; }
377
378 /**
379 * larger-than operator
380 * @param other const iterator
381 * @return true or false
382 */
383 bool operator>(const ConstIterator &other) const
384 { return _ptr > other._ptr; }
385
386 /**
387 * larger-than or equal operator
388 * @param other const iterator
389 * @return true or false
390 */
391 bool operator>=(const ConstIterator &other) const
392 { return _ptr >= other._ptr; }
393
394 /**
395 * comparison operator
396 * @param other const iterator
397 * @return true or false
398 */
399 bool operator==(const ConstIterator &other) const

10
400 { return _ptr == other._ptr; }
401
402 /**
403 * unequal comparison operator
404 * @param other const iterator
405 * @return true or false
406 */
407 bool operator!=(const ConstIterator &other) const
408 { return _ptr != other._ptr; }
409 };
410
411 public:
412 typedef Iterator iterator;
413 typedef ConstIterator const_iterator;
414
415 /**
416 * default constructor
417 */
418 VLVector<T, C>() : _vectorSize(0), _buff(_staticBuff), _staticCap(C), _currentCap(_staticCap)
419 {}
420
421 /**
422 * copy constructor
423 * @param other VLVector<T,C>
424 */
425 VLVector<T, C>(VLVector<T, C> const &other) : _vectorSize(other.size()),
426 _staticCap(C),
427 _currentCap(other.capacity())
428 {
429 //check if data should be copied to static buffer or to dynamically allocated buffer
430 _buff = _currentCap > _staticCap ? new T[_currentCap] : _staticBuff;
431 copy(other.begin(), other.end(), begin());
432 }
433
434 /**
435 * iterator range constructor, copies elements [first, last)
436 * @tparam InputIterator an iterator to an element of another container
437 * @param first element in range
438 * @param last element in range
439 */
440 template<class InputIterator>
441 VLVector<T, C>(const InputIterator first, const InputIterator last): _staticCap(C)
442 {
443 _vectorSize = distance(first, last);
444 _currentCap = _getCurrentCap(_vectorSize);
445 _buff = _currentCap > _staticCap ? new T[_currentCap] : _staticBuff;
446 std::copy(first, last, begin());
447 }
448
449 /**
450 * destructor
451 */
452 ~VLVector<T, C>()
453 {
454 if (_currentCap != _staticCap)
455 {
456 //buffer is dynamically allocated
457 delete[] _buff;
458 }
459 }
460
461 /**
462 * get VlVector size parameter
463 * @return size
464 */
465 const size_t &size() const
466 { return _vectorSize; }
467

11
468 /**
469 * get VlVector capacity param
470 * @return capacity
471 */
472 const size_t &capacity() const
473 { return _currentCap; }
474
475 /**
476 * check if VlVector is empty
477 * @return true or false
478 */
479 bool empty() const
480 { return _vectorSize == 0; }
481
482 /**
483 * access to ith index, throw exception of index is illegal
484 * @param i index
485 * @return reference to element at index
486 */
487 T &at(const size_t i)
488 {
489 if (i >= _vectorSize)
490 {
491 throw out_of_range(RANGE_ERROR);
492 }
493 return _buff[i];
494 }
495
496 /**
497 * const version, can't be written into
498 * @param i index
499 * @return reference to element at index
500 */
501 const T &at(const size_t i) const
502 {
503 if (i >= _vectorSize)
504 {
505 throw out_of_range(RANGE_ERROR);
506 }
507 return _buff[i];
508 }
509
510 /**
511 * access to VlVector element, non exception-throwing
512 * @param i index
513 * @return element at index
514 */
515 T &operator[](const size_t i)
516 { return _buff[i]; }
517
518 /**
519 * access to const VlVector element, non exception-throwing
520 * @param i index
521 * @return element at index
522 */
523 const T &operator[](const size_t i) const
524 { return _buff[i]; }
525
526 /**
527 * assignment operator
528 * @param other VlVector
529 * @return reference to this VlVector
530 */
531 VLVector<T, C> &operator=(const VLVector<T, C> &other)
532 {
533 if (this == &other)
534 {
535 return *this;

12
536 }
537 if (_currentCap != _staticCap)
538 {
539 //dynamically allocated buffer
540 delete[] _buff;
541 }
542 _vectorSize = other.size();
543 _currentCap = other.capacity();
544 _buff = _vectorSize >= _staticCap ? new T[_currentCap] : _staticBuff;
545 copy(other.begin(), other.end(), begin());
546 return *this;
547 }
548
549 /**
550 * vector comparison operator, return true if equal
551 * @param other VlVlVector
552 * @return true if hold same data
553 */
554 bool operator==(const VLVector<T, C> &other) const
555 {
556 return equal(begin(), end(), other.begin());
557 }
558
559 /**
560 * VlVector comparison operator, return true if unequal
561 * @param other VlVector
562 * @return true if hold same data
563 */
564 bool operator!=(const VLVector<T, C> &other) const
565 { return !(*this == other); }
566
567 /**
568 * add element to VlVector at O(1) amortized
569 * @param elem to be added
570 */
571 void push_back(const T &elem)
572 {
573 if (_vectorSize == _currentCap)
574 {
575 _buff = _upSize(_vectorSize);
576 }
577 _buff[_vectorSize] = elem;
578 _vectorSize++;
579 }
580
581 /**
582 * get pointer to VlVector data
583 * @return reference to pointer
584 */
585 T *&data()
586 { return _buff; }
587
588
589 /**
590 * * get pointer to const VlVector data
591 * @return reference to pointer
592 */
593 const T *&data() const
594 { return _buff; }
595
596 /**
597 * make last element no longer part of the VlVector
598 */
599 void pop_back()
600 {
601 if (_vectorSize == 0)
602 {
603 return;

13
604 }
605 _vectorSize--;
606 if (_currentCap > _staticCap && _vectorSize < _staticCap)
607 {
608 _buff = _downSize();
609 }
610 }
611
612 /**
613 * reset VlVector to default constructor
614 */
615 void clear()
616 {
617 if (_currentCap != _staticCap)
618 {
619 delete[] _buff;
620 }
621 _vectorSize = 0;
622 _currentCap = _staticCap;
623 _buff = _staticBuff;
624 }
625
626 /**
627 * insert element to VlVector to the left of iterator position
628 * @param pos iterator to element of VLVector
629 * @param val value to be inserted
630 * @return iterator to new value
631 */
632 iterator insert(iterator pos, const T &val)
633 {
634 //helps us find starting point of insertion in case vector is resized
635 size_t dist = distance(begin(), pos);
636 push_back(val);
637 //iterator points to where elem will be after rotation
638 iterator it = begin() + dist;
639 rotate(it, end() - 1, end());
640 return it;
641 }
642
643 /**
644 * insert element to VlVector to the left of iterator position
645 * @param pos iterator to element of VLVector
646 * @param val value to be inserted
647 * @return iterator to new value
648 */
649 const_iterator insert(const_iterator pos, const T &val)
650 {
651 size_t dist = distance(cbegin(), pos);
652 push_back(val);
653 iterator it = begin() + dist;
654 std::rotate(it, end() - 1, end());
655 return begin() + dist;
656 }
657
658 /**
659 * insert range of values [first, last) from a different container left of the iterator position
660 * @tparam InputIterator type
661 * @param pos iterator to VLVector
662 * @param first iterator to other container
663 * @param last iterator to other container
664 * @return iterator to first new value inserted
665 */
666 template<class InputIterator>
667 iterator insert(iterator pos, InputIterator first, InputIterator last)
668 {
669 size_t dist1 = distance(begin(), pos);
670 size_t dist2 = distance(first, last);
671 while (first != last)

14
672 {
673 push_back(*first);
674 first++;
675 }
676 iterator it = begin() + dist1;
677 rotate(it, end() - dist2, end());
678 return it;
679 }
680
681 /**
682 * insert range of values [first, last) from a different container left of the const_iterator
683 * position
684 * @tparam InputIterator type
685 * @param pos const_iterator to VLVector
686 * @param first iterator to other container
687 * @param last iterator to other container
688 * @return const_iterator to first new value inserted
689 */
690 template<class InputIterator>
691 const_iterator insert(const_iterator pos, InputIterator first, InputIterator last)
692 {
693 size_t dist1 = distance(cbegin(), pos);
694 size_t dist2 = distance(first, last);
695 while (first != last)
696 {
697 push_back(*first);
698 first++;
699 }
700 //rotate can't be used with const_iterator
701 rotate(begin() + dist1, end() - dist2, end());
702 return cbegin() + dist1;
703 }
704
705 /**
706 * erase element at iterator position
707 * @param pos iterator to element in VLVector
708 * @return iterator to object to the right
709 */
710 iterator erase(iterator pos)
711 {
712 size_t dist = distance(begin(), pos);
713 rotate(pos, pos + 1, end());
714 pop_back();
715 return begin() + dist;
716 }
717
718 /**
719 * erase element at const_iterator position
720 * @param pos const_iterator to element in VLVector
721 * @return const_iterator to object to the right
722 */
723 const_iterator erase(const_iterator pos)
724 {
725 size_t dist = distance(cbegin(), pos);
726 //can't use rotate with const_iterator
727 iterator it = begin() + dist;
728 rotate(it, it + 1, end());
729 pop_back();
730 return begin() + dist;
731 }
732
733 /**
734 * erase range of elements [first, last) within VLVector
735 * @tparam InputIterator generic input iterator type
736 * @param first iterator to VLVector
737 * @param last iterator to VLVector
738 * @return iterator to first position to right of erased elements
739 */

15
740 iterator erase(iterator first, iterator last)
741 {
742 size_t dist1 = distance(begin(), first);
743 size_t dist2 = distance(first, last);
744 rotate(first, last, end());
745 for (size_t i = 0; i < dist2; i++)
746 {
747 pop_back();
748 }
749 return begin() + dist1;
750 }
751
752 /**
753 * erase range of elements [first, last) within VLVector
754 * @tparam InputIterator generic input iterator type
755 * @param first iterator to VLVector
756 * @param last iterator to VLVector
757 * @return const_iterator to first position to right of erased elements
758 */
759 const_iterator erase(const_iterator first, const_iterator last)
760 {
761 size_t dist1 = distance(cbegin(), first);
762 size_t dist2 = distance(first, last);
763 //rotate can't be used with const_iterator
764 rotate(begin() + dist1, begin() + dist1 + dist2, end());
765 for (size_t i = 0; i < dist2; i++)
766 {
767 pop_back();
768 }
769 return begin() + dist1;
770 }
771
772 /**
773 * get iterator to first element in the VLVector
774 * @return iterator
775 */
776 iterator begin()
777 { return _buff; }
778
779 /**
780 * get const iterator to first element in the VLVector
781 * @return iterator
782 */
783 const_iterator begin() const
784 { return _buff; }
785
786 /**
787 * get const iterator unconditionally to first element in the VLVector
788 * @return iterator
789 */
790 const_iterator cbegin() const
791 { return _buff; }
792
793 /**
794 * get iterator to position after last element in the VLVector
795 * @return iterator
796 */
797 iterator end()
798 { return _buff + _vectorSize; }
799
800 /**
801 * get const iterator to position after last element in the VLVector
802 * @return iterator
803 */
804 const_iterator end() const
805 { return _buff + _vectorSize; }
806
807 /**

16
808 * get const iterator unconditionally to position after last element in the VLVector
809 * @return iterator
810 */
811 const_iterator cend() const
812 { return _buff + _vectorSize; }
813
814 private:
815 //data members
816 size_t _vectorSize{}; //number of data entries in VLVector
817 T _staticBuff[C]; //static array to hold data
818 T *_buff; //pointer to data array
819 const size_t _staticCap{}; //static capacity of VLVector
820 size_t _currentCap{}; //current capacity of VLVector
821
822 /**
823 * down-size VLVector capacity
824 * @param size of VLVector
825 * @return pointer to data array of correct capacity
826 */
827 T *_downSize()
828 {
829 _currentCap = _staticCap;
830 //use copy with pointers
831 copy(_buff, _buff + _vectorSize, _staticBuff);
832 delete[] _buff;
833 return _staticBuff;
834 }
835
836 /**
837 * up-size VLVector capacity
838 * @param size of VLVector
839 * @return pointer to data array of correct capacity
840 */
841 T *_upSize(size_t size)
842 {
843 //update current capacity- if size is smaller than static Capacity update to static.
844 _currentCap = _getCurrentCap(size);
845 //we need to allocate memory on the heap
846 T *newBuff = new T[_currentCap];
847 copy(_buff, _buff + _vectorSize, newBuff);
848 if (_buff != _staticBuff)
849 {
850 //meaning we were already working with a dynamically allocated buffer
851 delete[] _buff;
852 }
853 return newBuff;
854 }
855
856 /**
857 * calculate the capacity of a vector given its current size
858 * @param size of vector
859 * @return capacity
860 */
861 size_t _getCurrentCap(size_t size)
862 {
863 //lambda function calculates capacity with respect to current size
864 auto f = [](size_t x) -> size_t
865 { return ((x + 1) * 3) / 2; };
866 return size >= _staticCap ? f(size) : _staticCap;
867 }
868 };
869
870 #endif //EXAM2_VLVector_HPP

17

You might also like