33// This is internal headerfile to be included by vector.h only
44
55#include < new.h>
6+ #include < stdio.h>
67#include < stdlib.h>
78#include < string.h>
89#include < vector.h>
910
1011namespace std {
1112
12- static std::size_t next_power2 (std::size_t size) {
13- // assumes no overflow
14- std::size_t p = 1 ;
15- while (p && p < size)
16- p <<= 1 ;
17- return p;
18- }
13+ template <typename T>
14+ vector<T>::vector() : _data(NULL ), _capacity(0 ), _size(0 ) {}
1915
2016template <typename T>
21- vector<T>::vector() : _data(NULL ), _capacity(0 ), _size(0 ) {
22- resize_capacity (1 );
17+ vector<T>::vector(std::size_t size) : _data(NULL ), _capacity(0 ), _size(0 ) {
18+ reserve (size);
19+ // initializing the members
20+ for (std::size_t i = 0 ; i < size; i++) {
21+ new (_data + i) T (); // default constructor
22+ }
23+ _size = size;
2324}
2425
2526template <typename T>
2627vector<T>::vector(std::size_t size, const T &_default)
27- : _data(NULL ), _capacity(0 ), _size(size) {
28- resize_capacity (size);
28+ : _data(NULL ), _capacity(0 ), _size(0 ) {
29+ reserve (size);
30+ // initializing the members
2931 for (std::size_t i = 0 ; i < size; i++) {
30- this -> _data [i] = _default;
32+ new ( _data + i) T ( _default); // copy constructor
3133 }
34+ _size = size;
3235}
3336
3437template <typename T>
35- vector<T>::vector(const vector<T> &o)
36- : _data(NULL ), _capacity(0 ), _size(o._size) {
37- resize_capacity (o._capacity );
38- std::memcpy (_data, o._data , _capacity * sizeof (T));
38+ vector<T>::vector(const vector<T> &o) : _data(NULL ), _capacity(0 ), _size(0 ) {
39+ reserve (o._size );
40+ // initializing the members
41+ for (std::size_t i = 0 ; i < o._size ; i++) {
42+ new (_data + i) T (o._data [i]); // copy constructor
43+ }
44+ _size = o._size ;
3945}
4046
4147template <typename T> vector<T> &vector<T>::operator =(const vector<T> &o) {
42- resize_capacity (o._capacity );
43- _size = o._size ;
44- std::memcpy (_data, o._data , _capacity * sizeof (T));
48+ resize (o._size );
49+ // re-initialize the members
50+ for (std::size_t i = 0 ; i < o._size ; i++) {
51+ _data[i] = o._data [i]; // assignment operator
52+ }
4553 return *this ;
4654}
4755
48- template <typename T> vector<T>::~vector () { delete[] _data; }
56+ template <typename T> vector<T>::~vector () {
57+ clear ();
58+ reserve (0 );
59+ }
4960
50- template <typename T> typename vector<T>::iterator vector<T>::begin() {
51- return this ->_data ;
61+ template <typename T> void vector<T>::reserve(std::size_t new_capacity) {
62+ if (new_capacity < _size)
63+ new_capacity = _size; // never reserve less than size
64+ if (new_capacity == _capacity)
65+ return ; // resize not needed
66+
67+ const std::size_t new_capacity_size = (new_capacity) * sizeof (T);
68+
69+ // make a copy of array and move _data pointer.
70+ _data = (T *)std::realloc (_data, new_capacity_size);
71+ _capacity = new_capacity;
5272}
5373
54- template <typename T> typename vector<T>::iterator vector<T>::end() {
55- return this ->_data + this ->_size ;
74+ template <typename T> void vector<T>::resize(const std::size_t new_size) {
75+ if (_size < new_size) {
76+ reserve (new_size);
77+ for (std::size_t i = _size; i < new_size; i++) {
78+ new (_data + i) T (); // default constructor
79+ }
80+ _size = new_size;
81+ } else {
82+ for (std::size_t i = new_size; i < _size; i++) {
83+ _data[i].~T (); // explicit destructor call
84+ }
85+ _size = new_size;
86+ // not reducing the allocated capacity.
87+ }
5688}
5789
5890template <typename T>
59- typename vector<T>::const_iterator vector<T>::begin() const {
60- return this ->_data ;
91+ void vector<T>::resize(const std::size_t new_size, const T &_default) {
92+ if (_size < new_size) {
93+ reserve (new_size);
94+ for (std::size_t i = _size; i < new_size; i++) {
95+ new (_data + i) T (_default); // copy constructor
96+ }
97+ _size = new_size;
98+ } else {
99+ for (std::size_t i = new_size; i < _size; i++) {
100+ _data[i].~T (); // explicit destructor call
101+ }
102+ _size = new_size;
103+ // not reducing the allocated capacity.
104+ }
61105}
62106
63- template <typename T>
64- typename vector<T>::const_iterator vector<T>::end() const {
65- return this ->_data + this ->_size ;
107+ template <typename T> void vector<T>::push_back(const T &val) {
108+ if (_size == _capacity) {
109+ reserve (max (1 , _capacity * 2 ));
110+ }
111+ new (_data + (_size++)) T (val); // copy constructor
66112}
67113
68- template <typename T> void vector<T>::resize_capacity(std::size_t capacity) {
69- // internal; assumes capacity to be power of 2
70- // and will also make a copy of array and move _data pointer.
71- // assumes size<=current_capacity and size<=new_capacity
72- const std::size_t data_size =
73- std::min (capacity, this ->_capacity ) * sizeof (T);
74- T *_new_data = new T[capacity];
75- if (!_new_data)
76- return ; // malloc failed
77- std::memcpy (_new_data, this ->_data , data_size);
114+ template <typename T> void vector<T>::pop_back() {
115+ if (!(_size > 0 )) {
116+ return ;
117+ }
78118
79- delete[] this ->_data ; // should be no-op if _data == NULL
80- this ->_data = _new_data;
81- this ->_capacity = capacity;
82- }
119+ _size--;
120+ _data[_size].~T (); // explicit destructor call
83121
84- template <typename T> void vector<T>::clear() {
85- // not reducing capacity for now
86- this ->_size = 0 ;
122+ // not reducing the allocated capacity.
87123}
88124
89- template <typename T> bool vector<T>::empty () const { return this -> _size == 0 ; }
125+ template <typename T> void vector<T>::clear () { resize ( 0 ) ; }
90126
91- template <typename T> std:: size_t vector<T>::size() const {
92- return this -> _size ;
127+ template <typename T> typename vector<T>::iterator vector<T>::begin() {
128+ return _data ;
93129}
94130
95- template <typename T> void vector<T>::push_back(const T &val) {
96- if (this ->_size == this ->_capacity ) {
97- resize_capacity (this ->_capacity * 2 );
98- }
99- this ->_data [this ->_size ++] = val;
131+ template <typename T> typename vector<T>::iterator vector<T>::end() {
132+ return _data + _size;
100133}
101134
102- template <typename T> void vector<T>::pop_back() {
103- // not reducing the capacity for now
104- if (this ->_size > 0 ) {
105- this ->_size --;
106- }
135+ template <typename T>
136+ typename vector<T>::const_iterator vector<T>::begin() const {
137+ return _data;
107138}
108139
109- template <typename T> T &vector<T>::back() {
110- return this ->_data [this ->_size - 1 ];
140+ template <typename T>
141+ typename vector<T>::const_iterator vector<T>::end() const {
142+ return _data + _size;
111143}
112144
113- template <typename T> T & vector<T>::front () { return this -> _data [ 0 ] ; }
145+ template <typename T> bool vector<T>::empty () const { return _size == 0 ; }
114146
115- template <typename T> T &vector<T>::at(std::size_t pos) {
116- return this ->_data [pos];
117- }
147+ template <typename T> std::size_t vector<T>::size() const { return _size; }
148+
149+ template <typename T> T &vector<T>::back() { return _data[_size - 1 ]; }
150+
151+ template <typename T> T &vector<T>::front() { return _data[0 ]; }
152+
153+ template <typename T> T &vector<T>::at(std::size_t pos) { return _data[pos]; }
118154
119155template <typename T> T &vector<T>::operator [](std::size_t pos) {
120- return this -> _data [pos];
156+ return _data[pos];
121157}
122158
123159template <typename T> const T &vector<T>::operator [](std::size_t pos) const {
124- return this -> _data [pos];
160+ return _data[pos];
125161}
126162
127- } // namespace std
163+ } // namespace std
0 commit comments