diff --git a/Session.vim b/Session.vim index e07b4d4..e2f0486 100644 --- a/Session.vim +++ b/Session.vim @@ -15,14 +15,17 @@ else endif badd +1 Makefile badd +1 tester.cpp -badd +121 includes/vector.hpp +badd +255 includes/vector.hpp badd +1 main.cpp badd +1 includes/ft_container.hpp -badd +193 includes/iterator.hpp +badd +1 includes/iterator.hpp +badd +0 includes/reverse_iterator.hpp +badd +0 includes/stack.hpp argglobal %argdel $argadd main.cpp tabnew +setlocal\ bufhidden=wipe +tabnew +setlocal\ bufhidden=wipe tabrewind edit Makefile let s:save_splitbelow = &splitbelow @@ -44,9 +47,9 @@ set winminheight=0 set winheight=1 set winminwidth=0 set winwidth=1 -exe 'vert 1resize ' . ((&columns * 84 + 127) / 254) -exe 'vert 2resize ' . ((&columns * 84 + 127) / 254) -exe 'vert 3resize ' . ((&columns * 84 + 127) / 254) +exe 'vert 1resize ' . ((&columns * 63 + 95) / 190) +exe 'vert 2resize ' . ((&columns * 62 + 95) / 190) +exe 'vert 3resize ' . ((&columns * 63 + 95) / 190) argglobal balt includes/ft_container.hpp setlocal fdm=manual @@ -59,7 +62,7 @@ setlocal fdn=20 setlocal fen silent! normal! zE let &fdl = &fdl -let s:l = 1 - ((0 * winheight(0) + 32) / 65) +let s:l = 1 - ((0 * winheight(0) + 23) / 46) if s:l < 1 | let s:l = 1 | endif keepjumps exe s:l normal! zt @@ -82,12 +85,12 @@ setlocal fdn=20 setlocal fen silent! normal! zE let &fdl = &fdl -let s:l = 4 - ((3 * winheight(0) + 32) / 65) +let s:l = 3 - ((1 * winheight(0) + 23) / 46) if s:l < 1 | let s:l = 1 | endif keepjumps exe s:l normal! zt -keepjumps 4 -normal! 022| +keepjumps 3 +normal! 021| wincmd w argglobal if bufexists(fnamemodify("tester.cpp", ":p")) | buffer tester.cpp | else | edit tester.cpp | endif @@ -105,16 +108,16 @@ setlocal fdn=20 setlocal fen silent! normal! zE let &fdl = &fdl -let s:l = 3 - ((2 * winheight(0) + 32) / 65) +let s:l = 3 - ((1 * winheight(0) + 23) / 46) if s:l < 1 | let s:l = 1 | endif keepjumps exe s:l normal! zt keepjumps 3 normal! 0 wincmd w -exe 'vert 1resize ' . ((&columns * 84 + 127) / 254) -exe 'vert 2resize ' . ((&columns * 84 + 127) / 254) -exe 'vert 3resize ' . ((&columns * 84 + 127) / 254) +exe 'vert 1resize ' . ((&columns * 63 + 95) / 190) +exe 'vert 2resize ' . ((&columns * 62 + 95) / 190) +exe 'vert 3resize ' . ((&columns * 63 + 95) / 190) tabnext edit includes/iterator.hpp let s:save_splitbelow = &splitbelow @@ -133,10 +136,10 @@ set winminheight=0 set winheight=1 set winminwidth=0 set winwidth=1 -exe 'vert 1resize ' . ((&columns * 126 + 127) / 254) -exe 'vert 2resize ' . ((&columns * 127 + 127) / 254) +exe 'vert 1resize ' . ((&columns * 94 + 95) / 190) +exe 'vert 2resize ' . ((&columns * 95 + 95) / 190) argglobal -balt includes/vector.hpp +balt includes/reverse_iterator.hpp setlocal fdm=manual setlocal fde= setlocal fmr={{{,}}} @@ -147,18 +150,19 @@ setlocal fdn=20 setlocal fen silent! normal! zE let &fdl = &fdl -let s:l = 67 - ((8 * winheight(0) + 32) / 65) +let s:l = 80 - ((21 * winheight(0) + 23) / 46) if s:l < 1 | let s:l = 1 | endif keepjumps exe s:l normal! zt -keepjumps 67 -normal! 03| +keepjumps 80 +normal! 057| wincmd w argglobal -if bufexists(fnamemodify("includes/vector.hpp", ":p")) | buffer includes/vector.hpp | else | edit includes/vector.hpp | endif +if bufexists(fnamemodify("includes/reverse_iterator.hpp", ":p")) | buffer includes/reverse_iterator.hpp | else | edit includes/reverse_iterator.hpp | endif if &buftype ==# 'terminal' - silent file includes/vector.hpp + silent file includes/reverse_iterator.hpp endif +balt includes/iterator.hpp setlocal fdm=manual setlocal fde= setlocal fmr={{{,}}} @@ -169,17 +173,81 @@ setlocal fdn=20 setlocal fen silent! normal! zE let &fdl = &fdl -let s:l = 7 - ((6 * winheight(0) + 32) / 65) +let s:l = 1 - ((0 * winheight(0) + 23) / 46) if s:l < 1 | let s:l = 1 | endif keepjumps exe s:l normal! zt -keepjumps 7 -normal! 02| +keepjumps 1 +normal! 0 +wincmd w +exe 'vert 1resize ' . ((&columns * 94 + 95) / 190) +exe 'vert 2resize ' . ((&columns * 95 + 95) / 190) +tabnext +edit includes/vector.hpp +let s:save_splitbelow = &splitbelow +let s:save_splitright = &splitright +set splitbelow splitright +wincmd _ | wincmd | +vsplit +1wincmd h +wincmd w +let &splitbelow = s:save_splitbelow +let &splitright = s:save_splitright +wincmd t +let s:save_winminheight = &winminheight +let s:save_winminwidth = &winminwidth +set winminheight=0 +set winheight=1 +set winminwidth=0 +set winwidth=1 +exe 'vert 1resize ' . ((&columns * 94 + 95) / 190) +exe 'vert 2resize ' . ((&columns * 95 + 95) / 190) +argglobal +balt includes/stack.hpp +setlocal fdm=manual +setlocal fde= +setlocal fmr={{{,}}} +setlocal fdi=# +setlocal fdl=0 +setlocal fml=1 +setlocal fdn=20 +setlocal fen +silent! normal! zE +let &fdl = &fdl +let s:l = 255 - ((22 * winheight(0) + 23) / 46) +if s:l < 1 | let s:l = 1 | endif +keepjumps exe s:l +normal! zt +keepjumps 255 +normal! 013| +wincmd w +argglobal +if bufexists(fnamemodify("includes/stack.hpp", ":p")) | buffer includes/stack.hpp | else | edit includes/stack.hpp | endif +if &buftype ==# 'terminal' + silent file includes/stack.hpp +endif +balt includes/vector.hpp +setlocal fdm=manual +setlocal fde= +setlocal fmr={{{,}}} +setlocal fdi=# +setlocal fdl=0 +setlocal fml=1 +setlocal fdn=20 +setlocal fen +silent! normal! zE +let &fdl = &fdl +let s:l = 1 - ((0 * winheight(0) + 23) / 46) +if s:l < 1 | let s:l = 1 | endif +keepjumps exe s:l +normal! zt +keepjumps 1 +normal! 0 wincmd w 2wincmd w -exe 'vert 1resize ' . ((&columns * 126 + 127) / 254) -exe 'vert 2resize ' . ((&columns * 127 + 127) / 254) -tabnext 2 +exe 'vert 1resize ' . ((&columns * 94 + 95) / 190) +exe 'vert 2resize ' . ((&columns * 95 + 95) / 190) +tabnext 3 if exists('s:wipebuf') && len(win_findbuf(s:wipebuf)) == 0 && getbufvar(s:wipebuf, '&buftype') isnot# 'terminal' silent exe 'bwipe ' . s:wipebuf endif diff --git a/includes/iterator.hpp b/includes/iterator.hpp index 4b4acfd..d440162 100644 --- a/includes/iterator.hpp +++ b/includes/iterator.hpp @@ -1,14 +1,9 @@ #pragma once #include +#include // only for std/ft tags compatibility namespace ft { -struct input_iterator_tag {}; -struct output_iterator_tag {}; -struct forward_iterator_tag : public input_iterator_tag {}; -struct bidirectional_iterator_tag : public forward_iterator_tag {}; -struct random_access_iterator_tag : public bidirectional_iterator_tag {}; - template < class Iterator > struct iterator_traits { typedef typename Iterator::iterator_category iterator_category; typedef typename Iterator::value_type value_type; @@ -18,19 +13,19 @@ template < class Iterator > struct iterator_traits { }; template < class T > struct iterator_traits< T * > { - typedef random_access_iterator_tag iterator_category; - typedef T value_type; - typedef ptrdiff_t difference_type; - typedef T *pointer; - typedef T &reference; + typedef std::random_access_iterator_tag iterator_category; + typedef T value_type; + typedef ptrdiff_t difference_type; + typedef T *pointer; + typedef T &reference; }; template < class T > struct iterator_traits< const T * > { - typedef random_access_iterator_tag iterator_category; - typedef T value_type; - typedef ptrdiff_t difference_type; - typedef T *pointer; - typedef T &reference; + typedef std::random_access_iterator_tag iterator_category; + typedef T value_type; + typedef ptrdiff_t difference_type; + typedef T *pointer; + typedef T &reference; }; // Iterator classes: @@ -46,14 +41,16 @@ struct iterator { template < class T > class random_access_iterator - : public iterator< random_access_iterator_tag, T > { + : public iterator< std::random_access_iterator_tag, T > { public: - typedef typename iterator< random_access_iterator_tag, T >::iterator_category - iterator_category; typedef - typename iterator< random_access_iterator_tag, T >::value_type value_type; - typedef typename iterator< random_access_iterator_tag, T >::difference_type + typename iterator< std::random_access_iterator_tag, T >::iterator_category + iterator_category; + typedef typename iterator< std::random_access_iterator_tag, T >::value_type + value_type; + typedef + typename iterator< std::random_access_iterator_tag, T >::difference_type difference_type; typedef T *pointer; typedef T &reference; @@ -63,6 +60,7 @@ private: public: random_access_iterator(pointer ptr = NULL) : _ptr(ptr) {} + random_access_iterator(const random_access_iterator &other) : _ptr(other._ptr) {} @@ -71,29 +69,34 @@ public: return *this; } - pointer base(void) { return _ptr; } - reference operator*(void) { return *_ptr; } + pointer base(void) const { return _ptr; } + + reference operator*(void) const { return *_ptr; } random_access_iterator operator+(const difference_type n) const { return (random_access_iterator(_ptr + n)); } - difference_type operator+(const random_access_iterator &right) const { - return _ptr + right._ptr; + + difference_type operator+(const random_access_iterator &rhs) const { + return _ptr + rhs._ptr; } friend random_access_iterator operator+(const difference_type n, - random_access_iterator &right) { - return random_access_iterator(right._ptr + n); + random_access_iterator &rhs) { + return random_access_iterator(rhs._ptr + n); } + random_access_iterator &operator++() { ++_ptr; return *this; } + random_access_iterator operator++(int) { random_access_iterator ret(*this); ++(*this); return ret; } + random_access_iterator &operator+=(const difference_type n) { _ptr += n; return *this; @@ -102,17 +105,17 @@ public: random_access_iterator operator-(const difference_type n) const { return (random_access_iterator(_ptr - n)); } - difference_type operator-(const random_access_iterator &right) const { - return _ptr - right._ptr; - } + friend random_access_iterator operator-(const difference_type n, - random_access_iterator &right) { - return random_access_iterator(right._ptr - n); + random_access_iterator &rhs) { + return random_access_iterator(rhs._ptr - n); } + random_access_iterator &operator--() { --_ptr; return *this; } + random_access_iterator operator--(int) { random_access_iterator ret(*this); --(*this); @@ -123,43 +126,106 @@ public: return *this; } - pointer operator->(void) { return _ptr; } + pointer operator->(void) { return _ptr; } + reference operator[](const difference_type n) { return *(_ptr + n); } - friend bool operator==(const random_access_iterator &left, - const random_access_iterator &right) { - return left._ptr == right._ptr; + friend bool operator==(const random_access_iterator &lhs, + const random_access_iterator &rhs) { + return lhs._ptr == rhs._ptr; } - friend bool operator!=(const random_access_iterator &left, - const random_access_iterator &right) { - return left._ptr != right._ptr; + + friend bool operator!=(const random_access_iterator &lhs, + const random_access_iterator &rhs) { + return lhs._ptr != rhs._ptr; } - friend bool operator<(const random_access_iterator &left, - const random_access_iterator &right) { - return left._ptr < right._ptr; + + friend bool operator<(const random_access_iterator &lhs, + const random_access_iterator &rhs) { + return lhs._ptr < rhs._ptr; } - friend bool operator<=(const random_access_iterator &left, - const random_access_iterator &right) { - return left._ptr <= right._ptr; + + friend bool operator<=(const random_access_iterator &lhs, + const random_access_iterator &rhs) { + return lhs._ptr <= rhs._ptr; } - friend bool operator>(const random_access_iterator &left, - const random_access_iterator &right) { - return left._ptr > right._ptr; + + friend bool operator>(const random_access_iterator &lhs, + const random_access_iterator &rhs) { + return lhs._ptr > rhs._ptr; } - friend bool operator>=(const random_access_iterator &left, - const random_access_iterator &right) { - return left._ptr >= right._ptr; + + friend bool operator>=(const random_access_iterator &lhs, + const random_access_iterator &rhs) { + return lhs._ptr >= rhs._ptr; } + operator random_access_iterator< const T >() const { return random_access_iterator< const T >(_ptr); } }; template < class It > std::size_t distance(It first, It last) { - size_t ret = 1; + size_t ret = 0; while (first != last && ++ret) first++; return ret; } +template < class It1, class It2 > +bool equal(It1 first1, It1 last1, It2 first2) { + while (first1 != last1) { + if (!(*first1 == *first2)) + return false; + ++first1; + ++first2; + } + return true; +} + +template < class It1, class It2, class BinaryPredicate > +bool equal(It1 first1, It1 last1, It2 first2, BinaryPredicate pred) { + while (first1 != last1) { + if (!pred(*first1, *first2)) + return false; + ++first1; + ++first2; + } + return true; +} + +template < class It1, class It2 > +bool lexicographical_compare(It1 first1, It1 last1, It2 first2, It2 last2) { + while (first1 != last1) { + if (first2 == last2 || *first2 < *first1) + return false; + else if (*first1 < *first2) + return true; + ++first1; + ++first2; + } + return (first2 != last2); +} + +template < class It1, class It2, class Compare > +bool lexicographical_compare(It1 first1, It1 last1, It2 first2, It2 last2, + Compare comp) { + while (first1 != last1) { + if (first2 == last2 || comp(*first2, *first1)) + return false; + else if (comp(*first1, *first2)) + return true; + ++first1; + ++first2; + } + return (first2 != last2); +} + +template < class T1, class T2 > +typename random_access_iterator< T1 >::difference_type +operator-(const random_access_iterator< T1 > &lhs, + const random_access_iterator< T2 > &rhs) { + return lhs.base() - rhs.base(); +} + } // namespace ft diff --git a/includes/reverse_iterator.hpp b/includes/reverse_iterator.hpp index 14fc277..26ed873 100644 --- a/includes/reverse_iterator.hpp +++ b/includes/reverse_iterator.hpp @@ -8,8 +8,8 @@ public: typedef typename Iterator::iterator_category iterator_category; typedef typename Iterator::value_type value_type; typedef typename Iterator::difference_type difference_type; - typedef typename Iterator::pointer pointer; - typedef typename Iterator::reference reference; + typedef typename Iterator::pointer pointer; + typedef typename Iterator::reference reference; protected: Iterator current; @@ -17,8 +17,8 @@ protected: public: reverse_iterator(Iterator value = NULL) : current(value) {} - template < typename T > - reverse_iterator(const reverse_iterator< T > &iter) : current(iter.base()) {} + template < typename It > + reverse_iterator(const reverse_iterator< It > &iter) : current(iter.base()) {} reverse_iterator &operator=(const reverse_iterator &other) { current = other.current; @@ -40,7 +40,7 @@ public: } reverse_iterator operator++(int) { reverse_iterator ret(*this); - --(*this); + --current; return ret; } reverse_iterator &operator+=(const difference_type n) { @@ -57,7 +57,7 @@ public: } reverse_iterator operator--(int) { reverse_iterator ret(*this); - ++(*this); + ++current; return ret; } reverse_iterator &operator-=(const difference_type n) { @@ -66,13 +66,17 @@ public: } pointer operator->(void) const { return &(operator*()); } - reference operator[](const difference_type n) const { return base()[-n-1]; } + reference operator[](const difference_type n) const { return base()[-n - 1]; } template < typename It > friend reverse_iterator operator+(const int n, const reverse_iterator< It > &op) { return reverse_iterator(op.current - n); } + + operator reverse_iterator< const Iterator >() const { + return reverse_iterator< const Iterator >(current); + } }; template < typename It1, typename It2 > diff --git a/includes/stack.hpp b/includes/stack.hpp new file mode 100644 index 0000000..6b3e912 --- /dev/null +++ b/includes/stack.hpp @@ -0,0 +1,65 @@ +#pragma once +#include "vector.hpp" + +namespace ft { +template < class T, class Container = ft::vector< T > > class stack { +public: + typedef Container container_type; + typedef typename Container::value_type value_type; + typedef typename Container::size_type size_type; + typedef typename Container::reference reference; + typedef typename Container::const_reference const_reference; + +protected: + container_type c; + +public: + explicit stack(const container_type &ctnr = container_type()) : c(ctnr) {} + ~stack(void) {} + stack &operator=(const stack &other) { + delete c; + c = other.c; + return *this; + } + + bool empty(void) const { return c.empty(); } + size_type size(void) const { return c.size(); } + reference top(void) { return c.back(); } + const_reference top(void) const { return c.back(); } + void push(const value_type &value) { c.push_back(value); } + void pop(void) { c.pop_back(); } +}; + +template < class T, class Container > +bool operator==(const stack< T, Container > &lhs, + const stack< T, Container > &rhs) { + return lhs == rhs; +} +template < class T, class Container > +bool operator!=(const stack< T, Container > &lhs, + const stack< T, Container > &rhs) { + return !(lhs == rhs); +} +template < class T, class Container > +bool operator<(const stack< T, Container > &lhs, + const stack< T, Container > &rhs) { + return lhs < rhs; +} + +template < class T, class Container > +bool operator<=(const stack< T, Container > &lhs, + const stack< T, Container > &rhs) { + return lhs <= rhs; +} +template < class T, class Container > +bool operator>(const stack< T, Container > &lhs, + const stack< T, Container > &rhs) { + return lhs > rhs; +} +template < class T, class Container > +bool operator>=(const stack< T, Container > &lhs, + const stack< T, Container > &rhs) { + return lhs >= rhs; +} + +} // namespace ft diff --git a/includes/vector.hpp b/includes/vector.hpp index fb8be04..c33b875 100644 --- a/includes/vector.hpp +++ b/includes/vector.hpp @@ -7,6 +7,8 @@ #include #include +#define OVER_ALLOC 3 + namespace ft { template < class T, class Alloc = std::allocator< T > > class vector { @@ -36,8 +38,14 @@ public: explicit vector(size_type count, const_reference value = T(), const Alloc &alloc = allocator_type()) - : _alloc(alloc), _size(count), _capacity(count) { - _begin = _alloc.allocate(count); + : _alloc(alloc), _size(count), _capacity(0) { + if (count > _alloc.max_size()) + throw std::length_error("vector: too high size."); + else if (count == 0) + return; + else + _capacity = std::min(OVER_ALLOC * count, _alloc.max_size() - 1); + _begin = _alloc.allocate(_capacity); for (size_type i = 0; i < count; i++) _alloc.construct(_begin + i, value); } @@ -45,16 +53,14 @@ public: template < class It > vector(It first, It last, const Alloc &alloc = allocator_type(), typename ft::enable_if< !is_integral< It >::value, bool >::type = 0) - : _alloc(alloc) { - _size = ft::distance(first, last) - 1; - _capacity = _size; - _begin = _alloc.allocate(_size); - for (size_type i = 0; i < _size; i++) - _alloc.construct(_begin + i, *(first++)); + : _alloc(alloc), _size(0), _capacity(0) { + assign(first, last); } vector(const vector &other) : _alloc(other._alloc), _size(other._size), _capacity(other._capacity) { + if (_capacity == 0) + return; _begin = _alloc.allocate(_capacity); for (size_type i = 0; i < _size; i++) _alloc.construct(_begin + i, other._begin[i]); @@ -62,17 +68,19 @@ public: ~vector(void) { clear(); - if (_capacity) + if (_capacity > 0) _alloc.deallocate(_begin, _capacity); } vector &operator=(const vector &other) { clear(); - _alloc.deallocate(_begin, _capacity); + if (_capacity > 0) + _alloc.deallocate(_begin, _capacity); _alloc = other._alloc; _capacity = other._capacity; _size = other._size; - _begin = _alloc.allocate(_capacity); + if (_capacity > 0) + _begin = _alloc.allocate(_capacity); for (size_type i = 0; i < _size; i++) _alloc.construct(_begin + i, other._begin[i]); return (*this); @@ -80,24 +88,36 @@ public: void assign(size_type count, const_reference value) { resize(count); - while (count--) { - _alloc.destroy(_begin + count); - _alloc.construct(_begin + count, value); - }; + iterator it = begin(); + while (it != end()) + *it++ = value; } template < class It > - void assign(It first, It last, + void + assign(It first, It last, typename ft::enable_if< !is_integral< It >::value, bool >::type = 0) { - size_type count = ft::distance(first, last) - 1; - resize(count); - size_t i = 0; - while (i < count) { - _alloc.destroy(_begin + i); - _alloc.construct(_begin + i, *(first++)); - i++; - } + typename ft::iterator_traits< It >::iterator_category category; + range_assign(first, last, category); + } + + template < class It > + void range_assign(It first, It last, std::input_iterator_tag) { + clear(); + while (first != last) + push_back(*first++); } + template < class It > + void range_assign(It first, It last, std::forward_iterator_tag) { + size_type count = ft::distance(first, last); + if (count == 0) + return clear(); + vector< T, Alloc > ret(count); + iterator it = ret.begin(); + for (size_type i = 0; first != last; i++) + *(it + i) = *(first++); + *this = ret; + } allocator_type get_allocator(void) const { return _alloc; } // ACCESS: @@ -145,115 +165,161 @@ public: bool empty(void) const { return _size == 0; } size_type size(void) const { return _size; } size_type max_size(void) const { return _alloc.max_size(); } - void reserve(size_type new_cap) { + size_type capacity(void) const { return _capacity; } + + void reserve(size_type new_cap) { if (new_cap > max_size()) throw(std::length_error("vector::reserve: new_cap > max_size")); - if (new_cap < _capacity) - return ; - Alloc new_alloc; - pointer new_begin; + if (new_cap <= _capacity) + return; + else + new_cap = std::min(OVER_ALLOC * new_cap, _alloc.max_size() - 1); + Alloc new_alloc; + pointer new_begin; + size_type new_size = _size; new_begin = new_alloc.allocate(new_cap); - size_t new_size; - new_size = new_cap < _capacity ? new_cap : _size; - for (size_type i = 0; i < new_size; i++) + for (size_type i = 0; i < _size; i++) new_alloc.construct(new_begin + i, *(_begin + i)); - if (!empty()) - clear(); - if (_capacity) + clear(); + if (_capacity > 0) _alloc.deallocate(_begin, _capacity); _alloc = new_alloc; _begin = new_begin; - _capacity = new_cap; _size = new_size; + _capacity = new_cap; } - size_type capacity(void) const { return _capacity; } // MODIFIERS: void clear(void) { + if (_size == 0) + return; for (size_type i = 0; i < _size; i++) _alloc.destroy(_begin + i); _size = 0; } - iterator insert(const_iterator pos, const_reference value) { - if (_size == _capacity) - resize(_size + 1); + iterator insert(iterator pos, const_reference value) { + difference_type pos_i = pos - begin(); + resize(_size + 1); + iterator new_pos = begin() + pos_i; iterator it = end(); - while (--it > pos) + while (--it > new_pos) *it = *(it - 1); *it = value; - return _begin; + return new_pos; } - iterator insert(const_iterator pos, size_type count, const_reference value) { - if ((_size + count) > _capacity) - resize(_size + count); + + iterator insert(iterator pos, size_type count, const_reference value) { + if (count == 0) + return pos; + iterator new_pos = begin(); + resize(_size + count); + new_pos = begin() + (pos - new_pos); iterator it = end(); - while (--it >= (pos + count)) + while (--it >= (new_pos + count)) *it = *(it - count); - while (it >= pos) + while (it >= new_pos) { *(it--) = value; - return it; + } + return new_pos; } - template < class It > iterator insert(const_iterator pos, It first, It last, + + template < class It > + iterator + insert(iterator pos, It first, It last, typename ft::enable_if< !is_integral< It >::value, bool >::type = 0) { - size_type count = ft::distance(first, last) - 1; + typename std::iterator_traits< It >::iterator_category cat; + return range_insert(pos, first, last, cat); + } + + template < class It > + iterator range_insert(iterator pos, It first, It last, + std::input_iterator_tag) { + size_type count = 0; + do { + pos = insert(pos, *first); + ++pos; + ++count; + } while (++first != last); + return pos - count; + } + + template < class It > + iterator range_insert(iterator pos, It first, It last, + std::forward_iterator_tag) { + size_type count = ft::distance(first, last); + if (count == 0) + return pos; + iterator new_pos = begin(); resize(_size + count); + new_pos = begin() + (pos - new_pos); iterator it = end(); - while (--it > (pos + count)) + while (--it >= (new_pos + count)) *it = *(it - count); - while (it > pos) { - *(it--) = *(last--); + size_type i = 0; + while (i < count) { + *(new_pos + i++) = *(first++); } - return it; + return new_pos; } iterator erase(iterator pos) { - while (pos < end()) { - _alloc.destroy(pos.base()); + iterator ret = pos; + while ((pos + 1) < end()) { *pos = *(pos + 1); pos++; } + _alloc.destroy(pos.base()); _size--; - return _begin; + return ret; } iterator erase(iterator first, iterator last) { - while (last++ < end()) { - _alloc.destroy(first.base()); - *(first++) = *last; - } - while (first < end() && _size--) { - _alloc.destroy(first.base()); - *(first++) = value_type(); - } - return _begin; + if (first == last) + return last; + iterator pos = first; + size_type diff_size = ft::distance(first, last); + while (last < end()) + *pos++ = *last++; + while (pos < end()) + _alloc.destroy((pos++).base()); + _size -= diff_size; + return first; } void push_back(const_reference value) { - if (_size == _capacity) - resize(_size + 1); - _alloc.construct(_begin + _size - 1, value); - } - void pop_back(void) { - _alloc.destroy(_begin + _size - 1); - _size--; + reserve(_size + 1); + _alloc.construct(_begin + _size++, value); } + void pop_back(void) { _alloc.destroy(_begin + --_size); } + void resize(size_type count, T value = T()) { - if (count < _size) { - while (count < --_size) - _alloc.destroy(_begin + _size); + if (count == _size) + return; + if (count < _size) { // 0 < 5 + while (count < _size) // 0 <= 4 ; 0 <= 3; 0 <=2; 0 <=1; 0<= 0; + _alloc.destroy(_begin + --_size); // --5; --4; --3; --2; --1; } else { - if (count > _capacity) - reserve(count); + reserve(count); while (_size < count) _alloc.construct(_begin + _size++, value); } } void swap(vector &other) { - vector< T > tmp(other); - other = this; - this = tmp; + pointer ptr = other._begin; + size_type size = other._size; + size_type capacity = other._capacity; + allocator_type alloc = other._alloc; + other._begin = _begin; + other._size = _size; + other._capacity = _capacity; + other._alloc = _alloc; + _begin = ptr; + _size = size; + _capacity = capacity; + _alloc = alloc; } + void print(void) { ft::random_access_iterator< T > i = begin(); while (i < end()) { @@ -264,4 +330,43 @@ public: } }; +template < class T2, class Alloc2 > +bool operator==(const vector< T2, Alloc2 > &lhs, + const vector< T2, Alloc2 > &rhs) { + if (lhs.size() != rhs.size()) + return false; + return ft::equal(lhs.begin(), lhs.end(), rhs.begin()); +} +template < class T2, class Alloc2 > +bool operator!=(const vector< T2, Alloc2 > &lhs, + const vector< T2, Alloc2 > &rhs) { + return !(lhs == rhs); +} +template < class T2, class Alloc2 > +bool operator<(const vector< T2, Alloc2 > &lhs, + const vector< T2, Alloc2 > &rhs) { + return ft::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), + rhs.end()); +} +template < class T2, class Alloc2 > +bool operator>(const vector< T2, Alloc2 > &lhs, + const vector< T2, Alloc2 > &rhs) { + return rhs < lhs; +} +template < class T2, class Alloc2 > +bool operator<=(const vector< T2, Alloc2 > &lhs, + const vector< T2, Alloc2 > &rhs) { + return !(lhs > rhs); +} +template < class T2, class Alloc2 > +bool operator>=(const vector< T2, Alloc2 > &lhs, + const vector< T2, Alloc2 > &rhs) { + return !(lhs < rhs); +} + +template < class T, class Alloc > +void swap(ft::vector< T, Alloc > &lhs, ft::vector< T, Alloc > &rhs) { + lhs.swap(rhs); +} + } // namespace ft