diff --git a/headers/vector.hpp b/headers/vector.hpp index e4b3540..4816261 100644 --- a/headers/vector.hpp +++ b/headers/vector.hpp @@ -1,11 +1,14 @@ #ifndef VECTOR_HPP # define VECTOR_HPP -# include "colors.h" # include # include # include // std::allocator # include // std::min +# include // out_of_range, length_error, logic_error +# include // NULL, size_t, ptrdiff_t + +# include "colors.h" # include "enable_if.hpp" # include "is_integral.hpp" @@ -13,24 +16,34 @@ namespace ft { template < class T, - class Allocator = std::allocator -> class vector { + class Allocator = std::allocator > +class vector { public: - typedef T value_type; - typedef Allocator allocator_type; - typedef std::size_t size_type; + typedef T value_type; + typedef Allocator allocator_type; + typedef std::size_t size_type; +// typedef std::ptrdiff_t difference_type; - typedef T * iterator; + typedef T * iterator; + typedef T const * const_iterator; +// typedef ft::reverse_iterator reverse_iterator; +// typedef ft::reverse_iterator const_reverse_iterator; + + // dependent qualified name : + // https://en.cppreference.com/w/cpp/keyword/typename + typedef typename Allocator::reference reference; + typedef typename Allocator::const_reference const_reference; +// typedef typename Allocator::pointer pointer; +// typedef typename Allocator::const_pointer const_pointer; - typedef typename allocator_type::reference reference; /************ * copliens : ************/ -// constructor ------------------------------- +// constructors ------------------------------ explicit vector (const allocator_type & alloc = allocator_type()); explicit vector (size_type n, const value_type& val = value_type(), const allocator_type& alloc = allocator_type()); @@ -66,13 +79,13 @@ public: // size -------------------------------------- size_type size() const; // max_size ---------------------------------- - //size_type max_size() const; + size_type max_size() const; // resize ------------------------------------ - //void resize(size_type n, value_type val = value_type()); + void resize(size_type n, value_type val = value_type()); // capacity ---------------------------------- size_type capacity() const; // empty ------------------------------------- - //bool empty() const; + bool empty() const; // reserve ----------------------------------- void reserve(size_type n); @@ -81,16 +94,16 @@ public: ******************/ // operator[] -------------------------------- reference operator[](size_type n); - //const_reference operator[](size_type n) const; + const_reference operator[](size_type n) const; // at ---------------------------------------- - //reference at(size_type n); - //const_reference at(size_type n) const; + reference at(size_type n); + const_reference at(size_type n) const; // front ------------------------------------- - //reference front(); - //const_reference front() const; + reference front(); + const_reference front() const; // back -------------------------------------- - //reference back(); - //const_reference back() const; + reference back(); + const_reference back() const; /************* * modifiers : @@ -126,6 +139,7 @@ private: allocator_type _allocator; void _destroy(iterator first, iterator last); + void _increment_capacity(size_type n); }; diff --git a/templates/vector.tpp b/templates/vector.tpp index 5f6959d..03e030b 100644 --- a/templates/vector.tpp +++ b/templates/vector.tpp @@ -5,66 +5,52 @@ namespace ft { /********************************************* - * CONSTRUCTORS + * COPLIENS *********************************************/ - +// constructors ------------------------------ VT_TPL VT:: -vector( const Allocator & alloc ) -: _size(0) -, _capacity(0) -, _mem_ptr(NULL) -, _allocator(alloc) -{ + vector( const Allocator & alloc ) + : _size(0) + , _capacity(0) + , _mem_ptr(NULL) + , _allocator(alloc) { + return; } - VT_TPL VT:: -vector( size_type n, const T & val, const Allocator & alloc ) -: _size(0) -, _capacity(0) -, _mem_ptr(NULL) -, _allocator(alloc) -{ + vector( size_type n, const T & val, const Allocator & alloc ) + : _size(0) + , _capacity(0) + , _mem_ptr(NULL) + , _allocator(alloc) { + assign(n, val); return; } - VT_TPL template VT:: vector(InputIterator first, InputIterator last, const Allocator & alloc) -: _size(0) -, _capacity(0) -, _mem_ptr(NULL) -, _allocator(alloc) -{ + : _size(0) + , _capacity(0) + , _mem_ptr(NULL) + , _allocator(alloc) { + assign(first, last); return; } - VT_TPL VT:: -vector( vector const & src ) -{ + vector( vector const & src ) { + *this = src; return; } - -/********************************************* - * DESTRUCTORS - *********************************************/ - +// destructors ------------------------------- VT_TPL VT:: -~vector() -{ - return; -} - -/********************************************* - * OPERATORS - *********************************************/ - + ~vector() { return; } +// operator= --------------------------------- VT_TPL VT & VT:: -operator=( vector const & rhs ) -{ -// Base::operator=(rhs); + operator=( vector const & rhs ) { + + //Base::operator=(rhs); if ( this != &rhs ) { _size = rhs.size(); @@ -72,12 +58,6 @@ operator=( vector const & rhs ) return *this; } -//std::ostream & operator<<(std::ostream & o, vector const & rhs) -//{ -// o << rhs.getFoo(); -// return (o); -//} - /********************************************* * PUBLIC MEMBER FUNCTIONS @@ -106,26 +86,40 @@ VT_TPL typename VT::iterator VT:: ************/ // size -------------------------------------- VT_TPL typename VT::size_type VT:: - size( ) const -{ - return _size; -} + size( ) const { return _size; } // max_size ---------------------------------- -//size_type max_size() const; +VT_TPL typename VT::size_type VT:: + max_size() const { return (_allocator.max_size()); } // resize ------------------------------------ -//void resize(size_type n, value_type val = value_type()); +VT_TPL void VT:: + resize(size_type n, value_type val) { + + if (n > _size) + { + if (n > _capacity) + _increment_capacity(n); + while (_size != n) + { + _allocator.construct(&_mem_ptr[_size], val); + ++_size; + } + } + else if (n < _size) + { + while (_size != n) + _allocator.destroy(&_mem_ptr[--_size]); + } +} // capacity ---------------------------------- VT_TPL typename VT::size_type VT:: - capacity() const -{ - return _capacity; -} + capacity() const { return _capacity; } // empty ------------------------------------- -//bool empty() const; +VT_TPL bool VT:: + empty() const { return (_size == 0); } // reserve ----------------------------------- VT_TPL void VT:: - reserve( size_type new_cap ) -{ + reserve( size_type new_cap ) { + value_type * tmp_ptr; if (new_cap > _allocator.max_size()) @@ -140,10 +134,8 @@ VT_TPL void VT:: if (_mem_ptr) { - // TMP replacing assign(first, last) for (size_type i = 0; i < _size; i++) tmp_ptr[i] = _mem_ptr[i]; - // TMP END _destroy(begin(), end()); _allocator.deallocate(_mem_ptr, _capacity); } @@ -155,20 +147,34 @@ VT_TPL void VT:: ******************/ // operator[] -------------------------------- VT_TPL typename VT::reference VT:: - operator[](size_type n) -{ - return _mem_ptr[n]; -} -//const_reference operator[](size_type n) const; + operator[](size_type n) { return _mem_ptr[n]; } +VT_TPL typename VT::const_reference VT:: + operator[](size_type n) const { return _mem_ptr[n]; } // at ---------------------------------------- -//reference at(size_type n); -//const_reference at(size_type n) const; +VT_TPL typename VT::reference VT:: + at(size_type n) { + + if (n >= _size) + throw std::out_of_range("vector out of range"); + return (_mem_ptr[n]); +} +VT_TPL typename VT::const_reference VT:: + at(size_type n) const { + + if (n >= _size) + throw std::out_of_range("vector out of range"); + return (_mem_ptr[n]); +} // front ------------------------------------- -//reference front(); -//const_reference front() const; +VT_TPL typename VT::reference VT:: + front() { return (*_mem_ptr); } +VT_TPL typename VT::const_reference VT:: + front() const { return (*_mem_ptr); } // back -------------------------------------- -//reference back(); -//const_reference back() const; +VT_TPL typename VT::reference VT:: + back() { return (_mem_ptr[_size - 1]); } +VT_TPL typename VT::const_reference VT:: + back() const { return (_mem_ptr[_size - 1]); } /************* * modifiers : @@ -176,8 +182,8 @@ VT_TPL typename VT::reference VT:: // assign ------------------------------------ VT_TPL template typename enable_if< !is_integral::value,void >::type VT:: - assign( InputIterator first, InputIterator last) -{ + assign( InputIterator first, InputIterator last) { + InputIterator tmp = first; unsigned int range = 0; @@ -186,7 +192,7 @@ typename enable_if< !is_integral::value,void >::type VT:: while (tmp++ != last) range++; if (range >= _capacity) - reserve(range); + _increment_capacity(range); while (first != last) { _allocator.construct(&_mem_ptr[_size], *first); @@ -195,8 +201,8 @@ typename enable_if< !is_integral::value,void >::type VT:: } } VT_TPL void VT:: - assign( size_type n, const T & val ) -{ + assign( size_type n, const T & val ) { + if (n > _allocator.max_size()) throw std::length_error("assign: n > max_size"); @@ -217,25 +223,16 @@ VT_TPL void VT:: } // push_back --------------------------------- VT_TPL void VT:: - push_back( const value_type & element ) -{ + push_back( const value_type & element ) { + if (_size >= _capacity) - { - if (_size == 0) - reserve(1); - else - reserve(std::min(_size * 2, _allocator.max_size())); - } + _increment_capacity(1); _allocator.construct(&_mem_ptr[_size], element); _size++; } // pop_back ---------------------------------- VT_TPL void VT:: - pop_back() -{ - _allocator.destroy(end() - 1); - _size--; -} + pop_back() { _allocator.destroy(end() - 1); _size--; } // insert ------------------------------------ //iterator insert(iterator position, const value_type& val); //void insert(iterator position, size_type n, const value_type& val); @@ -248,11 +245,7 @@ VT_TPL void VT:: //void swap(vector& x); // clear ------------------------------------- VT_TPL void VT:: - clear() -{ - _destroy(begin(), end()); - _size = 0; -} + clear() { _destroy(begin(), end()); _size = 0; } @@ -262,8 +255,8 @@ VT_TPL void VT:: *********************************************/ VT_TPL void VT:: - _destroy(iterator first, iterator last) -{ + _destroy(iterator first, iterator last) { + while (first != last) { _allocator.destroy(first); @@ -271,12 +264,34 @@ VT_TPL void VT:: } } +VT_TPL void VT:: + _increment_capacity(size_type n) { + + size_type res; + + res = std::max(_size * 2, n); + reserve(std::min(res, _allocator.max_size())); +} + + +/********************************************* + * OPERATORS + *********************************************/ + +//std::ostream & operator<<(std::ostream & o, vector const & rhs) +//{ +// o << rhs.getFoo(); +// return (o); +//} + + /********************************************* * NESTED CLASS *********************************************/ //void vector::Class::function() {} + /********************************************* * STATICS *********************************************/ diff --git a/tests/main.cpp b/tests/main.cpp index bd8ee50..eb604ac 100644 --- a/tests/main.cpp +++ b/tests/main.cpp @@ -16,6 +16,9 @@ int main() { /* TEST(vector::vector (constructor)) { + // title + TITLE(cplusplus.com reference :) + // constructors used in the same order as described above: std::vector first; // empty vector of ints std::vector second (4,100); // four ints with value 100 @@ -36,6 +39,9 @@ int main() { TEST(vector::=operator) { + // title + TITLE(cplusplus.com reference :) + std::vector foo (3,0); std::vector bar (5,0); @@ -50,6 +56,9 @@ int main() { TEST(vector::begin) { + // title + TITLE(cplusplus.com reference :) + std::vector myvector; for (int i=1; i<=5; i++) myvector.push_back(i); @@ -63,6 +72,9 @@ int main() { TEST(vector::end) { + // title + TITLE(cplusplus.com reference :) + std::vector myvector; for (int i=1; i<=5; i++) myvector.push_back(i); @@ -76,6 +88,9 @@ int main() { TEST(vector::rbegin) { + // title + TITLE(cplusplus.com reference :) + std::vector myvector (5); // 5 default-constructed ints int i=0; @@ -94,6 +109,9 @@ int main() { TEST(vector::rend) { + // title + TITLE(cplusplus.com reference :) + std::vector myvector (5); // 5 default-constructed ints std::vector::reverse_iterator rit = myvector.rbegin(); @@ -112,6 +130,9 @@ int main() { TEST(vector::size) { + // title + TITLE(cplusplus.com reference :) + std::vector myints; std::cout << "0. size: " << myints.size() << '\n'; @@ -129,6 +150,9 @@ int main() { TEST(vector::max_size) { + // title + TITLE(cplusplus.com reference :) + std::vector myvector; // set some content in the vector: @@ -139,11 +163,15 @@ int main() { std::cout << "max_size: " << myvector.max_size() << "\n"; } TESTEND +*/ TEST(vector::resize) { - std::vector myvector; + // title + TITLE(cplusplus.com reference :) + + ft::vector myvector; // set some initial content: for (int i = 1; i < 10; i++) myvector.push_back(i); @@ -156,13 +184,94 @@ int main() { for (unsigned int i = 0; i < myvector.size(); i++) std::cout << ' ' << myvector[i]; std::cout << '\n'; + + + // title + TITLE(test size and capacity 1 :) + + ft::vector vector2; + + std::cout << "size: " << vector2.size() << " - capacity: " << vector2.capacity() << "\n\n"; + + std::cout << "assign(10, 1)\n"; + vector2.assign(10, 1); + for (unsigned int i = 0; i < vector2.size(); i++) + std::cout << "[" << i << "]" << vector2[i] << " "; + std::cout << "\n"; + + std::cout << "\nsize: " << vector2.size() << " - capacity: " << vector2.capacity() << "\n\n"; + + std::cout << "resize(15)\n"; + vector2.resize(15); + for (unsigned int i = 0; i < vector2.size(); i++) + std::cout << "[" << i << "]" << vector2[i] << " "; + std::cout << "\n"; + + std::cout << "\nsize: " << vector2.size() << " - capacity: " << vector2.capacity() << "\n\n"; + + std::cout << "resize(10)\n"; + vector2.resize(10); + for (unsigned int i = 0; i < vector2.size(); i++) + std::cout << "[" << i << "]" << vector2[i] << " "; + std::cout << "\n"; + + std::cout << "\nsize: " << vector2.size() << " - capacity: " << vector2.capacity() << "\n\n"; + + std::cout << "resize(19)\n"; + vector2.resize(19); + for (unsigned int i = 0; i < vector2.size(); i++) + std::cout << "[" << i << "]" << vector2[i] << " "; + std::cout << "\n"; + + std::cout << "\nsize: " << vector2.size() << " - capacity: " << vector2.capacity() << "\n\n"; + + std::cout << "resize(20)\n"; + vector2.resize(20); + for (unsigned int i = 0; i < vector2.size(); i++) + std::cout << "[" << i << "]" << vector2[i] << " "; + std::cout << "\n"; + + std::cout << "\nsize: " << vector2.size() << " - capacity: " << vector2.capacity() << "\n\n"; + + std::cout << "resize(21)\n"; + vector2.resize(21); + for (unsigned int i = 0; i < vector2.size(); i++) + std::cout << "[" << i << "]" << vector2[i] << " "; + std::cout << "\n"; + + + // title + TITLE(test size and capacity 2 :) + + ft::vector vector3; + + std::cout << "size: " << vector3.size() << " - capacity: " << vector3.capacity() << "\n\n"; + + std::cout << "assign(10, 1)\n"; + vector3.assign(10, 1); + for (unsigned int i = 0; i < vector3.size(); i++) + std::cout << "[" << i << "]" << vector3[i] << " "; + std::cout << "\n"; + + std::cout << "\nsize: " << vector3.size() << " - capacity: " << vector3.capacity() << "\n\n"; + + std::cout << "resize(21)\n"; + vector3.resize(21); + for (unsigned int i = 0; i < vector3.size(); i++) + std::cout << "[" << i << "]" << vector3[i] << " "; + std::cout << "\n"; + + std::cout << "\nsize: " << vector3.size() << " - capacity: " << vector3.capacity() << "\n\n"; } TESTEND TEST(vector::capacity) { - std::vector myvector; + // title + TITLE(cplusplus.com reference :) + + ft::vector myvector; // set some content in the vector: for (int i=0; i<100; i++) myvector.push_back(i); @@ -176,8 +285,11 @@ int main() { TEST(vector::empty) { - std::vector myvector; - int sum (0); + // title + TITLE(cplusplus.com reference :) + + ft::vector myvector; + int sum (0); for (int i=1;i<=10;i++) myvector.push_back(i); @@ -194,9 +306,12 @@ int main() { TEST(vector::reserve) { - std::vector::size_type sz; + // title + TITLE(cplusplus.com reference :) + + ft::vector::size_type sz; + ft::vector foo; - std::vector foo; sz = foo.capacity(); std::cout << "making foo grow:\n"; for (int i=0; i<100; ++i) { @@ -207,7 +322,8 @@ int main() { } } - std::vector bar; + ft::vector bar; + sz = bar.capacity(); bar.reserve(100); // this is the only difference with foo above std::cout << "making bar grow:\n"; @@ -224,9 +340,11 @@ int main() { TEST(vector::operator[]) { - std::vector myvector (10); // 10 zero-initialized elements + // title + TITLE(cplusplus.com reference :) - std::vector::size_type sz = myvector.size(); + ft::vector myvector (10); // 10 zero-initialized elements + ft::vector::size_type sz = myvector.size(); // assign some values: for (unsigned i=0; i myvector (10); // 10 zero-initialized ints + // title + TITLE(cplusplus.com reference :) + + ft::vector myvector (10); // 10 zero-initialized ints // assign some values: for (unsigned i=0; i myvector; + // title + TITLE(cplusplus.com reference :) + + ft::vector myvector; myvector.push_back(78); myvector.push_back(16); @@ -282,7 +406,10 @@ int main() { TEST(vector::back) { - std::vector myvector; + // title + TITLE(cplusplus.com reference :) + + ft::vector myvector; myvector.push_back(78); myvector.push_back(16); @@ -290,11 +417,35 @@ int main() { // now front equals 78, and back 16 myvector.front() -= myvector.back(); - std::cout << "myvector.front() is now " << myvector.front() << '\n'; + + + // title + TITLE(test with negatives :) + + myvector.push_back(236); + myvector.push_back(8973); + + myvector.front() -= myvector.back(); + std::cout << "myvector.front() is now " << myvector.front() << '\n'; + + + // title + TITLE(test with char :) + + ft::vector letters; + letters.push_back('o'); + letters.push_back('m'); + letters.push_back('g'); + letters.push_back('w'); + letters.push_back('t'); + letters.push_back('f'); + + if (!letters.empty()) { + std::cout << "The first character is '" << letters.front() << "'.\n"; + } } TESTEND -*/ TEST(vector::assign) { @@ -387,9 +538,11 @@ int main() { TEST(vector::push_back) { + // title + TITLE(cplusplus.com reference :) + ft::vector myvector; - // first test int myint[] = {12434, -2432, 12, 5345, 23, 0, -4, 387, 8432, -934723, 1}; int size = sizeof(myint) / sizeof(myint[0]); for (int i = 0; i < size; i++) @@ -403,7 +556,10 @@ int main() { std::cout << "[" << std::setw(2) << i << "] " << myvector[i] << "\n"; std::cout << " -> size : " << myvector.size() << " , capacity :" << myvector.capacity() << "\n"; - // second test + + // title + TITLE(big push back :) + for (int i = 0; i < 72363; i++) { myvector.push_back(9); @@ -414,11 +570,15 @@ int main() { } TESTEND -/* TEST(vector::pop_back) { - std::vector myvector; + // title + TITLE(cplusplus.com reference :) + + ft::vector myvector; + int sum (0); + myvector.push_back (100); myvector.push_back (200); myvector.push_back (300); @@ -430,11 +590,23 @@ int main() { } std::cout << "The elements of myvector add up to " << sum << '\n'; + + + // title + TITLE(check state :) + + std::cout << "size : " << myvector.size() << '\n'; + std::cout << "capacity : " << myvector.capacity() << '\n'; } TESTEND + +/* TEST(vector::insert) { + // title + TITLE(cplusplus.com reference :) + std::vector myvector (3,100); std::vector::iterator it; @@ -461,6 +633,9 @@ int main() { TEST(vector::erase) { + // title + TITLE(cplusplus.com reference :) + std::vector myvector; // set some values (from 1 to 10) @@ -481,6 +656,9 @@ int main() { TEST(vector::swap) { + // title + TITLE(cplusplus.com reference :) + std::vector foo (3,100); // three ints with a value of 100 std::vector bar (5,200); // five ints with a value of 200 @@ -500,6 +678,9 @@ int main() { TEST(vector::clear) { + // title + TITLE(cplusplus.com reference :) + std::vector myvector; myvector.push_back (100); myvector.push_back (200); @@ -523,6 +704,9 @@ int main() { TEST(vector::get_allocator) { + // title + TITLE(cplusplus.com reference :) + std::vector myvector; int * p; unsigned int i;