diff --git a/.cache/clangd/index/ft_container.hpp.AE6A49ED28E963FF.idx b/.cache/clangd/index/ft_container.hpp.AE6A49ED28E963FF.idx deleted file mode 100644 index 73e1a8c..0000000 Binary files a/.cache/clangd/index/ft_container.hpp.AE6A49ED28E963FF.idx and /dev/null differ diff --git a/.cache/clangd/index/iterator.hpp.B6BE3296FFA2AF9F.idx b/.cache/clangd/index/iterator.hpp.B6BE3296FFA2AF9F.idx deleted file mode 100644 index 0924e83..0000000 Binary files a/.cache/clangd/index/iterator.hpp.B6BE3296FFA2AF9F.idx and /dev/null differ diff --git a/.cache/clangd/index/tester.cpp.133FD4700F7AEE0A.idx b/.cache/clangd/index/tester.cpp.133FD4700F7AEE0A.idx deleted file mode 100644 index 02746c4..0000000 Binary files a/.cache/clangd/index/tester.cpp.133FD4700F7AEE0A.idx and /dev/null differ diff --git a/.cache/clangd/index/vector.hpp.8C3201A34AC2A736.idx b/.cache/clangd/index/vector.hpp.8C3201A34AC2A736.idx deleted file mode 100644 index d847911..0000000 Binary files a/.cache/clangd/index/vector.hpp.8C3201A34AC2A736.idx and /dev/null differ diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8914ec5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +* + +!README.md +!LICENCE +!.gitignore +!.clang-format +!compile_commands.json +!Session.vim + +!includes/ +!includes/*.hpp + +!Makefile +!tester.cpp diff --git a/Makefile b/Makefile index 07df597..300b30c 100644 --- a/Makefile +++ b/Makefile @@ -1,3 +1,4 @@ +CXX = c++ CXXFLAGS= -std=c++98 -Werror -Wextra -Wall -Iincludes all: tester @@ -11,6 +12,6 @@ clean: fclean: clean rm -rf tester -re: fclean re +re: fclean all .PHONY: all clean fclean re diff --git a/includes/ft_container.hpp b/includes/ft_container.hpp index b8752dc..e74cbec 100644 --- a/includes/ft_container.hpp +++ b/includes/ft_container.hpp @@ -1,21 +1,3 @@ #pragma once - +#include #include "vector.hpp" -#include "iterator.hpp" -#include "iostream" - - -template is_integer(T input) {} - -template struct enable_if {}; - -template struct enable_if { typedef T type; }; - -template -void debug_vector(ft::vector vec) { - ft::ra_iterator i = vec.begin(); - while (i < vec.end()) { - std::cout << *i << " "; - } - std::cout << "\n"; -} diff --git a/includes/iterator.hpp b/includes/iterator.hpp index 4496a50..0c575d3 100644 --- a/includes/iterator.hpp +++ b/includes/iterator.hpp @@ -53,7 +53,7 @@ public: return (*this); } - T base(void) const { return current; } + pointer base(void) const { return current; } reference operator*(void) const { return *current; } pointer operator->(void) const { return current; } reference operator[](const difference_type n) const { return *(current + n); } @@ -189,8 +189,8 @@ public: }; template < class It > std::size_t distance(It first, It last) { - size_t ret = 0; - while (first != last && ret++) + size_t ret = 1; + while (first != last && ++ret) first++; return ret; } diff --git a/includes/utils.hpp b/includes/utils.hpp new file mode 100644 index 0000000..568beea --- /dev/null +++ b/includes/utils.hpp @@ -0,0 +1,40 @@ +#pragma once + +namespace ft { +// is_integral: +template < class T, T val > struct integral_constant { + typedef integral_constant< T, val > type; + typedef T value_type; + static const T value = val; + operator T() const; +}; + +typedef integral_constant< bool, true > true_type; +typedef integral_constant< bool, false > false_type; + +template < class T > struct is_integral : public false_type {}; +template < class T > struct is_integral< const T > : public false_type {}; + +template <> struct is_integral< bool > : public true_type {}; +template <> struct is_integral< double > : public true_type {}; + +template <> struct is_integral< char > : public true_type {}; +template <> struct is_integral< short > : public true_type {}; +template <> struct is_integral< int > : public true_type {}; +template <> struct is_integral< long > : public true_type {}; +template <> struct is_integral< long long > : public true_type {}; + +template <> struct is_integral< unsigned char > : public true_type {}; +template <> struct is_integral< unsigned short > : public true_type {}; +template <> struct is_integral< unsigned int > : public true_type {}; +template <> struct is_integral< unsigned long > : public true_type {}; +template <> struct is_integral< unsigned long long > : public true_type {}; + +// enable_if: +template < bool B, class T = void > struct enable_if {}; + +template < class T > struct enable_if< true, T > { + typedef T type; +}; + +} // namespace ft diff --git a/includes/vector.hpp b/includes/vector.hpp index 972c086..e1f1273 100644 --- a/includes/vector.hpp +++ b/includes/vector.hpp @@ -1,6 +1,8 @@ #pragma once -#include "ft_conatainer.hpp" #include "iterator.hpp" +#include "utils.hpp" + +#include #include #include @@ -8,18 +10,18 @@ namespace ft { template < class T, class Allocator = std::allocator< T > > class vector { public: - typedef T value_type; - typedef Allocator allocator_type; - typedef typename Allocator::pointer pointer; - typedef typename Allocator::const_pointer cst_pointer; - typedef value_type &reference; - typedef const value_type &cst_reference; - typedef ft::ra_iterator< reference > iterator; - typedef ft::ra_iterator< cst_reference > cst_iterator; - typedef ft::rev_iterator< iterator > reverse_iterator; - typedef ft::rev_iterator< cst_iterator > cst_reverse_iterator; - typedef std::ptrdiff_t difference_type; - typedef std::size_t size_type; + typedef T value_type; + typedef Allocator allocator_type; + typedef typename Allocator::pointer pointer; + typedef typename Allocator::const_pointer cst_pointer; + typedef value_type &reference; + typedef const value_type &cst_reference; + typedef ft::ra_iterator< reference > iterator; + typedef ft::ra_iterator< cst_reference > cst_iterator; + typedef ft::rev_iterator< iterator > reverse_iterator; + typedef ft::rev_iterator< cst_iterator > cst_reverse_iterator; + typedef std::ptrdiff_t difference_type; + typedef std::size_t size_type; private: Allocator _alloc; @@ -31,7 +33,8 @@ public: explicit vector(const Allocator &alloc = allocator_type()) : _alloc(alloc), _begin(NULL), _size(0), _capacity(0){}; - explicit vector(size_type count, cst_reference value = T(), const Allocator &alloc = allocator_type()) + explicit vector(size_type count, cst_reference value = T(), + const Allocator &alloc = allocator_type()) : _alloc(alloc), _size(count), _capacity(count) { _begin = _alloc.allocate(count); for (size_type i = 0; i < count; i++) @@ -39,7 +42,8 @@ public: } template < class It > - vector(It first, It last, const Allocator &alloc = allocator_type(), typename enable_if, 1>::type is_it = 0 ) + vector(It first, It last, const Allocator &alloc = allocator_type(), + typename ft::enable_if< !is_integral< It >::value, bool >::type = 0) : _alloc(alloc) { _size = distance(first, last); _capacity = _size; @@ -73,60 +77,75 @@ public: return (*this); } - void assign(size_type count, cst_reference value) { + void assign(size_type count, cst_reference value) { resize(count); - while (count > 0){ - _alloc.destroy(this[count]); - _alloc.contruct(this[count], value); - count--; - } + do { + _alloc.destroy(_begin + count); + _alloc.construct(_begin + count, value); + } while (count-- > 0); } - template < class It > void assign(It first, It last) { + template < class It > + void + assign(It first, It last, + typename ft::enable_if< !is_integral< It >::value, bool >::type = 0) { size_type i = ft::distance(first, last); resize(i); - while (i > 0) { - _alloc.destroy(this[i]); - _alloc.contruct(this[i], first[i - 1]); - i--; - } + do { + _alloc.destroy(_begin + i); + _alloc.construct(_begin + i, first[i]); + } while (i-- > 0); } - allocator_type get_allocator(void) const { return _alloc; } + allocator_type get_allocator(void) const { return _alloc; } // ACCESS: reference at(size_type pos) { - if (pos > _size) throw (std::out_of_range("vector: Out of range access")); + if (pos >= _size) + throw(std::out_of_range("vector: Out of range access")); return *(_begin + pos); } cst_reference at(size_type pos) const { - if (pos > _size) throw (std::out_of_range("vector: Out of range access")); + if (pos >= _size) + throw(std::out_of_range("vector: Out of range access")); return *(_begin + pos); } - reference operator[](size_type pos) {return *(_begin + pos);} - cst_reference operator[](size_type pos) const {return *(_begin + pos);} + reference operator[](size_type pos) { return _begin[pos]; } + cst_reference operator[](size_type pos) const { return _begin[pos]; } - reference front(void) {return this[0];} - cst_reference front(void) const {return this[0];} + reference front(void) { return _begin[0]; } + cst_reference front(void) const { return _begin[0]; } - reference back(void) {return this[_size - 1];} - cst_reference back(void) const {return this[_size - 1];} + reference back(void) { return _begin[_size - 1]; } + cst_reference back(void) const { return _begin[_size - 1]; } - pointer data(void) {return _begin;} - cst_pointer data(void) const {return _begin;} + pointer data(void) { return _begin; } + cst_pointer data(void) const { return _begin; } // ITERATORS: - ra_iterator< T > begin(void) {return ra_iterator(front());} - ra_iterator< const T > begin(void) const {return ra_iterator(front());} + ra_iterator< T > begin(void) { return ra_iterator< T >(_begin); } + ra_iterator< const T > begin(void) const { + return ra_iterator< const T >(_begin); + } - ra_iterator< T > end(void) {return ra_iterator(this[_size]);} - ra_iterator< const T > end(void) const {return ra_iterator(this[_size]);} + ra_iterator< T > end(void) { return ra_iterator< T >(_begin + _size); } + ra_iterator< const T > end(void) const { + return ra_iterator< const T >(_begin + _size); + } - rev_iterator< iterator > rbegin(void) {return rev_iterator(end());} - rev_iterator< cst_iterator > rbegin(void) const {return rev_iterator(end());} + rev_iterator< iterator > rbegin(void) { + return rev_iterator< pointer >(end()); + } + rev_iterator< cst_iterator > rbegin(void) const { + return rev_iterator< cst_pointer >(end()); + } - rev_iterator< iterator > rend(void) {return rev_iterator(begin());} - rev_iterator< cst_iterator > rend(void) const {return rev_iterator(begin());} + rev_iterator< iterator > rend(void) { + return rev_iterator< pointer >(begin()); + } + rev_iterator< cst_iterator > rend(void) const { + return rev_iterator< cst_pointer >(begin()); + } // CAPACITY: bool empty(void) const { return _size == 0; } @@ -157,7 +176,8 @@ public: iterator insert(iterator pos, cst_reference value) { if (_size == _capacity) resize(_size + 1); - iterator it = end() + 1;; + iterator it = end() + 1; + ; while (--it >= pos) *it = *(it - 1); *it = value; @@ -165,7 +185,7 @@ public: } iterator insert(iterator pos, size_type count, cst_reference value) { if ((_size + count) > _capacity) - resize(_size + count); + resize(_size + count); iterator it = end() + count; while (--it >= (pos + count)) *it = *(it - count); @@ -176,7 +196,7 @@ public: return _begin; } template < class It > iterator insert(iterator pos, It first, It last) { - size_type count = ft::distance(first, last); + size_type count = ft::distance(first, last); if ((_size + count) > _capacity) resize(_size + count); iterator it = end() + count; @@ -189,7 +209,7 @@ public: } return _begin; } - iterator erase(iterator pos) { + iterator erase(iterator pos) { while (pos < end()) { _alloc.destroy(pos); *pos = *(pos + 1); @@ -198,8 +218,8 @@ public: _size--; return _begin; } - iterator erase(iterator first, iterator last) { - while (last++ < end()){ + iterator erase(iterator first, iterator last) { + while (last++ < end()) { _alloc.destroy(first); *(first++) = *last; } @@ -209,32 +229,41 @@ public: } return _begin; } - void push_back(cst_reference value) { + void push_back(cst_reference value) { if (_size == _capacity) resize(_size + 1); _alloc.construct(back(), value); } - void pop_back(void) { + void pop_back(void) { _alloc.destroy(back()); _size--; } - void resize(size_type count, T value = T()) { + void resize(size_type count, T value = T()) { size_type i = count; if (count < _size) { while (i < _size && --_size) - _alloc.destroy(this[i]); + _alloc.destroy(_begin + i); } else { if (count > _capacity) reserve(count); while (i >= _size) - _alloc.construct(_begin[--i], value); + _alloc.construct(_begin + --i, value); + _size = count; } } - void swap(vector &other) { - vector tmp = other; + void swap(vector &other) { + vector< T > tmp = other; other = this; this = tmp; } + void print(void) { + ft::ra_iterator< T > i = begin(); + while (i < end()) { + std::cout << *i << " "; + i++; + } + std::cout << "\n"; + } }; } // namespace ft diff --git a/tester.cpp b/tester.cpp index 9d3db52..a1ad581 100644 --- a/tester.cpp +++ b/tester.cpp @@ -1,16 +1,72 @@ #include "ft_container.hpp" -int main(void) { - ft::vector test1 = ft::vector(); - ft::vector test2 = ft::vector(10); - ft::vector test3 = ft::vector(10, 4); - ft::vector test4 = ft::vector(test3.begin(), test3.begin() + 4); - ft::vector test5 = ft::vector(test3); - - debug_vector(test1); - debug_vector(test2); - debug_vector(test3); - debug_vector(test4); - debug_vector(test5); +// debugs: +// +void test_vectors(void) { + + ft::vector< int > test1 = ft::vector< int >(); + ft::vector< int > test2 = ft::vector< int >(10); + ft::vector< int > test3 = ft::vector< int >(10, 4); + ft::vector< int > test4 = ft::vector< int >(test3.begin(), test3.begin() + 4); + ft::vector< int > test5 = ft::vector< int >(test3); + + std::cout << "1) vector() | "; + test1.print(); + std::cout << "2) vector(10) | "; + test2.print(); + std::cout << "3) vector(10, 4) | "; + test3.print(); + std::cout << "4) vector(test3.begin(), test3.begin() + 4) | "; + test4.print(); + std::cout << "5.a) vector(test3) | "; + test5.print(); + + ft::vector< int >::reference test5_begin = *test5.begin(); + std::cout << "5.b) test5_begin = *test5.begin() | " << test5_begin + << std::endl; + test5 = test4; + std::cout << "\ttest5 = test4 | "; + test5.print(); + std::cout << "\ttest5_begin | " << test5_begin << std::endl; + + std::cout << "6.a) test5.assign(2,2) | "; + test5.assign(2, 2); + test5.print(); + + std::cout << "6.b) test5.assign(test3.begin(), test3.begin() + 4) | "; + test5.assign(test3.begin(), test3.begin() + 4); + test5.print(); + std::cout << "7.a) test5.at(0) | " << test5.at(0) << std::endl; + std::cout << "7.b) test5.at(4) | " << test5.at(4) << std::endl; + std::cout << "7.c) test5.at(5) | "; + try { + std::cout << test5.at(5) << std::endl; + } catch (std::exception &e) { + std::cout << e.what() << std::endl; + } + std::cout << "8.a) test5[4] = 1; | " << (test5[4] = 1) << std::endl; + std::cout << "8.b) test5[0] | " << test5[0] << std::endl; + std::cout << "8.c) test5[4] | " << test5[4] << std::endl; + std::cout << "9.a) test5.front() | " << test5.front() << std::endl; + std::cout << "9.b) test5.back() | " << test5.back() << std::endl; + std::cout << "10.a) *test5.data() | " << *test5.data() << std::endl; + + + std::cout << "11.a) test5.empty() | " << test5.empty() << std::endl; + std::cout << "11.b) test5.size() | " << test5.size() << std::endl; + std::cout << "11.c) test5.max_size() | " << test5.max_size() << std::endl; + std::cout << "11.d) test5.capacity() | " << test5.capacity() << std::endl; + + test5.resize(0); + std::cout << "12.a) test5.resize(0) : "<< std::endl; + std::cout << "12.b) test5.empty() | " << test5.empty() << std::endl; + std::cout << "12.c) test5.size() | " << test5.size() << std::endl; + std::cout << "12.d) test5.max_size() | " << test5.max_size() << std::endl; + std::cout << "12.e) test5.capacity() | " << test5.capacity() << std::endl; + + + } + +int main(void) { test_vectors(); }