diff --git a/Makefile b/Makefile index 2880543..5086b34 100644 --- a/Makefile +++ b/Makefile @@ -38,70 +38,43 @@ CC = clang++ EXT = cpp CFLAGS = -Wall -Wextra -Werror $(INCLUDES) +CFLAGS += -MMD -MP #see end-page note on header dependencie CFLAGS += -std=c++98 CFLAGS += -g3 -CFLAGS_STL = -Wall -Wextra -Werror $(INCLUDES) +CFLAGS_STL = $(CFLAGS) CFLAGS_STL += -D STL -CFLAGS_STL += -std=c++98 -CFLAGS_STL += -g3 VPATH = $(D_SRCS) LIBS = -F_INCLUDES = $(HEADERS:%=$(D_HEADERS)/%) \ - $(TEMPLATES:%=$(D_TEMPLATES)/%) \ - $(TESTS:%=$(D_TESTS)/%) -INCLUDES = -I$(D_HEADERS) \ - -I$(D_TEMPLATES) \ - -I$(D_TESTS) +D_INCLUDE = ./headers \ + ./templates \ + ./tests/includes + +INCLUDES = $(D_INCLUDE:%=-I%) D_SRCS = ./tests #SRCS = main42.cpp #SRCS = main_map_1.cpp #SRCS = main_map_2.cpp #SRCS = main_stack_1.cpp -SRCS = \ - main.cpp \ +SRCS = main.cpp \ tests_definitions.cpp \ \ tests_vector.cpp \ tests_map.cpp \ tests_stack.cpp -D_HEADERS = ./headers -HEADERS = \ - colors.h \ - \ - enable_if.hpp \ - iterator_traits.hpp \ - reverse_iterator.hpp \ - equal.hpp \ - lexicographical_compare.hpp \ - pair.hpp \ - \ - map.hpp \ - map_node.hpp \ - map_iterator.hpp \ - vector.hpp \ - stack.hpp - -D_TEMPLATES = ./templates -TEMPLATES = \ - vector.tpp \ - map.tpp - -D_TESTS = ./tests/includes -TESTS = \ - main.hpp \ - tests_utils.hpp - D_OBJS_FT = builds_ft OBJS_FT = $(SRCS:%.$(EXT)=$(D_OBJS_FT)/%.o) D_OBJS_STL = builds_stl OBJS_STL = $(SRCS:%.$(EXT)=$(D_OBJS_STL)/%.o) +OBJS = $(OBJS_FT) $(OBJS_STL) +DEPS = $(OBJS:.o=.d) #see end-page note on header dependencie + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # # . target: prerequisites . $@ : target # @@ -110,7 +83,6 @@ OBJS_STL = $(SRCS:%.$(EXT)=$(D_OBJS_STL)/%.o) # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # all: $(NAME_FT) $(NAME_STL) - stl: $(NAME_STL) ft: $(NAME_FT) @@ -124,9 +96,6 @@ $(D_OBJS_STL)/%.o: %.$(EXT) | $(D_OBJS_STL) $(D_OBJS_FT) $(D_OBJS_STL): mkdir $@ -$(OBJS_FT) $(OBJS_STL): $(F_INCLUDES) - -# https://stackoverflow.com/questions/19259108/makefile-same-rule-for-multiple-targets $(NAME_FT): $(OBJS_FT) $(NAME_STL): $(OBJS_STL) $(NAME_FT) $(NAME_STL): @@ -150,3 +119,7 @@ re: fclean all .PHONY : all clean fclean re +# header dependencie +# https://spin.atomicobject.com/2016/08/26/makefile-c-projects +-include $(DEPS) + diff --git a/builds_ft/main.d b/builds_ft/main.d new file mode 100644 index 0000000..fc59dad --- /dev/null +++ b/builds_ft/main.d @@ -0,0 +1,8 @@ +builds_ft/main.o: tests/main.cpp tests/includes/main.hpp headers/colors.h \ + tests/includes/tests_structs.hpp + +tests/includes/main.hpp: + +headers/colors.h: + +tests/includes/tests_structs.hpp: diff --git a/builds_ft/tests_definitions.d b/builds_ft/tests_definitions.d new file mode 100644 index 0000000..a1e24c3 --- /dev/null +++ b/builds_ft/tests_definitions.d @@ -0,0 +1,9 @@ +builds_ft/tests_definitions.o: tests/tests_definitions.cpp \ + tests/includes/tests_utils.hpp headers/colors.h \ + tests/includes/tests_structs.hpp + +tests/includes/tests_utils.hpp: + +headers/colors.h: + +tests/includes/tests_structs.hpp: diff --git a/builds_ft/tests_map.d b/builds_ft/tests_map.d new file mode 100644 index 0000000..6d6cbc0 --- /dev/null +++ b/builds_ft/tests_map.d @@ -0,0 +1,32 @@ +builds_ft/tests_map.o: tests/tests_map.cpp tests/includes/tests_map.hpp \ + tests/includes/tests_utils.hpp headers/colors.h \ + tests/includes/tests_structs.hpp headers/map.hpp \ + headers/reverse_iterator.hpp headers/iterator_traits.hpp \ + headers/equal.hpp headers/lexicographical_compare.hpp headers/pair.hpp \ + headers/map_node.hpp headers/map_iterator.hpp templates/map.tpp + +tests/includes/tests_map.hpp: + +tests/includes/tests_utils.hpp: + +headers/colors.h: + +tests/includes/tests_structs.hpp: + +headers/map.hpp: + +headers/reverse_iterator.hpp: + +headers/iterator_traits.hpp: + +headers/equal.hpp: + +headers/lexicographical_compare.hpp: + +headers/pair.hpp: + +headers/map_node.hpp: + +headers/map_iterator.hpp: + +templates/map.tpp: diff --git a/builds_ft/tests_stack.d b/builds_ft/tests_stack.d new file mode 100644 index 0000000..df53f05 --- /dev/null +++ b/builds_ft/tests_stack.d @@ -0,0 +1,33 @@ +builds_ft/tests_stack.o: tests/tests_stack.cpp \ + tests/includes/tests_stack.hpp tests/includes/tests_utils.hpp \ + headers/colors.h tests/includes/tests_structs.hpp headers/stack.hpp \ + headers/vector.hpp headers/enable_if.hpp headers/is_integral.hpp \ + headers/reverse_iterator.hpp headers/iterator_traits.hpp \ + headers/equal.hpp headers/lexicographical_compare.hpp \ + templates/vector.tpp + +tests/includes/tests_stack.hpp: + +tests/includes/tests_utils.hpp: + +headers/colors.h: + +tests/includes/tests_structs.hpp: + +headers/stack.hpp: + +headers/vector.hpp: + +headers/enable_if.hpp: + +headers/is_integral.hpp: + +headers/reverse_iterator.hpp: + +headers/iterator_traits.hpp: + +headers/equal.hpp: + +headers/lexicographical_compare.hpp: + +templates/vector.tpp: diff --git a/builds_ft/tests_vector.d b/builds_ft/tests_vector.d new file mode 100644 index 0000000..b039a21 --- /dev/null +++ b/builds_ft/tests_vector.d @@ -0,0 +1,31 @@ +builds_ft/tests_vector.o: tests/tests_vector.cpp \ + tests/includes/tests_vector.hpp tests/includes/tests_utils.hpp \ + headers/colors.h tests/includes/tests_structs.hpp headers/vector.hpp \ + headers/enable_if.hpp headers/is_integral.hpp \ + headers/reverse_iterator.hpp headers/iterator_traits.hpp \ + headers/equal.hpp headers/lexicographical_compare.hpp \ + templates/vector.tpp + +tests/includes/tests_vector.hpp: + +tests/includes/tests_utils.hpp: + +headers/colors.h: + +tests/includes/tests_structs.hpp: + +headers/vector.hpp: + +headers/enable_if.hpp: + +headers/is_integral.hpp: + +headers/reverse_iterator.hpp: + +headers/iterator_traits.hpp: + +headers/equal.hpp: + +headers/lexicographical_compare.hpp: + +templates/vector.tpp: diff --git a/builds_stl/main.d b/builds_stl/main.d new file mode 100644 index 0000000..8ebc62c --- /dev/null +++ b/builds_stl/main.d @@ -0,0 +1,8 @@ +builds_stl/main.o: tests/main.cpp tests/includes/main.hpp \ + headers/colors.h tests/includes/tests_structs.hpp + +tests/includes/main.hpp: + +headers/colors.h: + +tests/includes/tests_structs.hpp: diff --git a/builds_stl/tests_definitions.d b/builds_stl/tests_definitions.d new file mode 100644 index 0000000..14f3ebd --- /dev/null +++ b/builds_stl/tests_definitions.d @@ -0,0 +1,9 @@ +builds_stl/tests_definitions.o: tests/tests_definitions.cpp \ + tests/includes/tests_utils.hpp headers/colors.h \ + tests/includes/tests_structs.hpp + +tests/includes/tests_utils.hpp: + +headers/colors.h: + +tests/includes/tests_structs.hpp: diff --git a/builds_stl/tests_map.d b/builds_stl/tests_map.d new file mode 100644 index 0000000..1c3d938 --- /dev/null +++ b/builds_stl/tests_map.d @@ -0,0 +1,11 @@ +builds_stl/tests_map.o: tests/tests_map.cpp tests/includes/tests_map.hpp \ + tests/includes/tests_utils.hpp headers/colors.h \ + tests/includes/tests_structs.hpp + +tests/includes/tests_map.hpp: + +tests/includes/tests_utils.hpp: + +headers/colors.h: + +tests/includes/tests_structs.hpp: diff --git a/builds_stl/tests_stack.d b/builds_stl/tests_stack.d new file mode 100644 index 0000000..d245304 --- /dev/null +++ b/builds_stl/tests_stack.d @@ -0,0 +1,11 @@ +builds_stl/tests_stack.o: tests/tests_stack.cpp \ + tests/includes/tests_stack.hpp tests/includes/tests_utils.hpp \ + headers/colors.h tests/includes/tests_structs.hpp + +tests/includes/tests_stack.hpp: + +tests/includes/tests_utils.hpp: + +headers/colors.h: + +tests/includes/tests_structs.hpp: diff --git a/builds_stl/tests_vector.d b/builds_stl/tests_vector.d new file mode 100644 index 0000000..6997635 --- /dev/null +++ b/builds_stl/tests_vector.d @@ -0,0 +1,11 @@ +builds_stl/tests_vector.o: tests/tests_vector.cpp \ + tests/includes/tests_vector.hpp tests/includes/tests_utils.hpp \ + headers/colors.h tests/includes/tests_structs.hpp + +tests/includes/tests_vector.hpp: + +tests/includes/tests_utils.hpp: + +headers/colors.h: + +tests/includes/tests_structs.hpp: diff --git a/containers_ft b/containers_ft index 07d34f3..2f16785 100755 Binary files a/containers_ft and b/containers_ft differ diff --git a/containers_stl b/containers_stl index 88022da..f814a0f 100755 Binary files a/containers_stl and b/containers_stl differ diff --git a/headers/map.hpp b/headers/map.hpp index 2ce22a6..77bbe86 100644 --- a/headers/map.hpp +++ b/headers/map.hpp @@ -162,29 +162,26 @@ public: allocator_type get_allocator() const; private: - size_type _size; - node* _root; - node_sentinel* _sentinel; - Compare _comp; - Alloc _allocator; + size_type _size; + node* _root; + sentinel* _sentinel; + Compare _comp; + Alloc _allocator; // https://stackoverflow.com/questions/14148756/what-does-template-rebind-do - typename Alloc::template rebind< node >::other _allocator_node; // Peu clair, verifier syntaxe - typename Alloc::template rebind< node_sentinel >::other _allocator_node_sentinel; // Peu clair, verifier syntaxe // SENTINELL + typename Alloc::template rebind< node >::other _allocator_node; + typename Alloc::template rebind< sentinel >::other _allocator_sentinel; - void _init_sentinel(); - pair _insert(const value_type& value); - node* _erase(iterator pos); - node* _subtree_shift(node* st_old, node* st_new); + void _init_sentinel(); + node* _subtree_shift(node* st_old, node* st_new); // BBST - void _insert_rebalancing(node* n); - void _erase_rebalancing(node* n); - - short _compute_height(node* n); - short _balance_factor(node* n); - node* _rotate_left(node* n); - node* _rotate_right(node* n); + enum {INSERT, ERASE}; + void _balance(node* n, bool action); + short _compute_height(node* n); + short _balance_factor(node* n); + node* _rotate_left(node* n); + node* _rotate_right(node* n); }; diff --git a/headers/map_iterator.hpp b/headers/map_iterator.hpp index c588098..9903529 100644 --- a/headers/map_iterator.hpp +++ b/headers/map_iterator.hpp @@ -14,101 +14,87 @@ template < typename T, typename Compare, typename Allocator -> class map_iterator -{ - private: - typedef map_iterator Self; +> class map_iterator { - public: - typedef std::bidirectional_iterator_tag iterator_category; - typedef pair value_type; - typedef std::ptrdiff_t difference_type; - typedef value_type* pointer; - typedef value_type& reference; +private: + typedef map_iterator self; - map_iterator() : _node(), _sentinel() {} - map_iterator(node* n, node_sentinel* sentinel) : _node(n), _sentinel(sentinel) {} // SENTINELL - //map_iterator(node* n, node* sentinel) : _node(n), _sentinel(sentinel) {} +public: + typedef std::bidirectional_iterator_tag iterator_category; + typedef pair value_type; + typedef std::ptrdiff_t difference_type; + typedef value_type* pointer; + typedef value_type& reference; - reference operator*() const - { return _node->value; } - pointer operator->() const - { return &_node->value; } + map_iterator() : _node(), _sentinel() {} + map_iterator(node* n, sentinel* sentinel) + : _node(n), _sentinel(sentinel) {} - Self& operator++() + reference operator*() const { + return _node->value; } + pointer operator->() const { + return &_node->value; } + + self& operator++() { + if (_node == NULL) + _node = _sentinel->child->min(); + else if (_node->right) + _node = _node->right->min(); + else { - if (_node == NULL) - _node = _sentinel->child->min(); // SENTINELL - //_node = _sentinel->min(); - else if (_node->right) - _node = _node->right->min(); - else + node* up = _node->up; + while (up != NULL && _node == up->right) { - node* up = _node->up; - while (up != NULL && _node == up->right) - { - _node = up; - up = up->up; - } _node = up; + up = up->up; } - return *this; + _node = up; } + return *this; + } - Self& operator--() + self& operator--() { + if (_node == NULL) + _node = _sentinel->child->max(); + else if (_node->left) + _node = _node->left->max(); + else { - if (_node == NULL) - _node = _sentinel->child->max(); // SENTINELL - //_node = _sentinel->max(); - else if (_node->left) - _node = _node->left->max(); - else + node* up = _node->up; + while (up != NULL && _node == up->left) { - node* up = _node->up; - while (up != NULL && _node == up->left) - { - _node = up; - up = up->up; - } _node = up; + up = up->up; } - return *this; - } - - Self operator++(int) - { - //Self old(*this); - Self old = *this; - ++(*this); - return old; + _node = up; } + return *this; + } + + self operator++(int) { + self old = *this; + ++(*this); + return old; + } - Self operator--(int) - { - //Self old(*this); - Self old = *this; - --(*this); - return old; - } + self operator--(int) { + self old = *this; + --(*this); + return old; + } - node* getNode() - { return _node; } - const node* getNode() const - { return _node; } - const node_sentinel* getSentinel() const // SENTINELL - //const node* getSentinel() const - { return _sentinel; } + node* getNode() { return _node; } + const node* getNode() const { return _node; } + const sentinel* getSentinel() const { return _sentinel; } - // TODO : friend Non-member functions syntaxe pas clair. - friend bool operator==(const Self &lhs, const Self &rhs) - { return lhs._node == rhs._node; } - friend bool operator!=(const Self &lhs, const Self &rhs) - { return !(lhs._node == rhs._node); } + friend bool operator==(const self &lhs, const self &rhs) { + return lhs._node == rhs._node; } + friend bool operator!=(const self &lhs, const self &rhs) { + return !(lhs._node == rhs._node); } - private: - node* _node; - node_sentinel* _sentinel; // SENTINELL - //node* _sentinel; +private: + node* _node; + sentinel* _sentinel; }; template < @@ -116,94 +102,90 @@ template < typename T, typename Compare, typename Allocator -> class map_const_iterator -{ - private: - typedef map_const_iterator Self; +> class map_const_iterator { - public: - typedef std::bidirectional_iterator_tag iterator_category; - typedef pair value_type; - typedef std::ptrdiff_t difference_type; - typedef const value_type* pointer; - typedef const value_type& reference; +private: + typedef map_const_iterator self; - map_const_iterator() : _node(), _sentinel() {} - map_const_iterator(const node* node, const node_sentinel* sentinel) : _node(node), _sentinel(sentinel) {} // SENTINELL - //map_const_iterator(const node* nodee, const node* sentinel) : _node(nodee), _sentinel(sentinel) {} - map_const_iterator(const map_iterator& src) : _node(src.getNode()), _sentinel(src.getSentinel()) {} +public: + typedef std::bidirectional_iterator_tag iterator_category; + typedef pair value_type; + typedef std::ptrdiff_t difference_type; + typedef const value_type* pointer; + typedef const value_type& reference; - reference operator*() const - { return _node->value; } - pointer operator->() const - { return &_node->value; } + map_const_iterator() : _node(), _sentinel() {} + map_const_iterator ( + const node* node, + const sentinel* sentinel) + : _node(node), _sentinel(sentinel) {} + map_const_iterator (const map_iterator< Key, T, Compare, Allocator >& src) + : _node(src.getNode()), _sentinel(src.getSentinel()) {} - Self& operator++() + reference operator*() const { + return _node->value; } + pointer operator->() const { + return &_node->value; } + + self& operator++() { + if (_node == NULL) + _node = _sentinel->child->min(); + else if (_node->right) + _node = _node->right->min(); + else { - if (_node == NULL) - _node = _sentinel->child->min(); // SENTINELL - //_node = _sentinel->min(); - else if (_node->right) - _node = _node->right->min(); - else + node* up = _node->up; + while (up != NULL && _node == up->right) { - node* up = _node->up; - while (up != NULL && _node == up->right) - { - _node = up; - up = up->up; - } _node = up; + up = up->up; } - return *this; + _node = up; } + return *this; + } - Self& operator--() + self& operator--() { + if (_node == NULL) + _node = _sentinel->child->max(); + else if (_node->left) + _node = _node->left->max(); + else { - if (_node == NULL) - _node = _sentinel->child->max(); // SENTINELL - //_node = _sentinel->max(); - else if (_node->left) - _node = _node->left->max(); - else + node* up = _node->up; + while (up != NULL && _node == up->left) { - node* up = _node->up; - while (up != NULL && _node == up->left) - { - _node = up; - up = up->up; - } _node = up; + up = up->up; } - return *this; - } - - Self operator++(int) - { - Self old = *this; - ++(*this); - return old; + _node = up; } + return *this; + } + + self operator++(int) { + self old = *this; + ++(*this); + return old; + } - Self operator--(int) - { - Self old = *this; - --(*this); - return old; - } + self operator--(int) { + self old = *this; + --(*this); + return old; + } - node* getNode() const - { return _node; } + node* getNode() const { + return _node; } - friend bool operator==(const Self &lhs, const Self &rhs) - { return lhs._node == rhs._node; } - friend bool operator!=(const Self &lhs, const Self &rhs) - { return !(lhs._node == rhs._node); } + friend bool operator==(const self &lhs, const self &rhs) { + return lhs._node == rhs._node; } + friend bool operator!=(const self &lhs, const self &rhs) { + return !(lhs._node == rhs._node); } - private: - const node* _node; - const node_sentinel* _sentinel; // SENTINELL - //const node* _sentinel; +private: + const node* _node; + const sentinel* _sentinel; }; } // namespace ft diff --git a/headers/map_node.hpp b/headers/map_node.hpp index 0982288..d34d492 100644 --- a/headers/map_node.hpp +++ b/headers/map_node.hpp @@ -43,11 +43,11 @@ template < typename ValueType > }; template < typename ValueType > - struct node_sentinel { + struct sentinel { node *child; - node_sentinel() : child(NULL) {} + sentinel() : child(NULL) {} }; } // namespace ft diff --git a/templates/map.tpp b/templates/map.tpp index 33e9a9e..37838a0 100644 --- a/templates/map.tpp +++ b/templates/map.tpp @@ -43,8 +43,8 @@ MP_TPL MP:: ~map() { clear(); - _allocator_node_sentinel.destroy(_sentinel); - _allocator_node_sentinel.deallocate(_sentinel, 1); + _allocator_sentinel.destroy(_sentinel); + _allocator_sentinel.deallocate(_sentinel, 1); } // operator= --------------------------------- MP_TPL MP& MP:: @@ -141,12 +141,40 @@ MP_TPL typename MP::mapped_type& MP:: MP_TPL pair MP:: insert(const value_type& value) { - pair ret; - - ret = _insert(value); - if (ret.second == true) - _insert_rebalancing(ret.first.getNode()->up); - return (ret); + node* n = _root; + node* next = n; + + while (next != NULL) + { + if (value.first == n->value.first) + return ft::make_pair(iterator(n, _sentinel), false); + n = next; + if (value.first < n->value.first) + next = n->left; + else if (value.first > n->value.first) + next = n->right; + } + + next = _allocator_node.allocate(1); + _allocator_node.construct(next, node(value)); + + if (_root == NULL) + { + _root = next; + _sentinel->child = next; + } + else + { + if (value.first < n->value.first) + n->left = next; + else if (value.first > n->value.first) + n->right = next; + } + next->up = n; + _size++; + + _balance(n, INSERT); + return (ft::make_pair(iterator(next, _sentinel), true)); } MP_TPL typename MP::iterator MP:: insert(iterator hint, const value_type& value) { @@ -157,19 +185,47 @@ MP_TPL typename MP::iterator MP:: MP_TPL template < typename InputIt > void MP:: insert(InputIt first, InputIt last) { - while (first != last) - { + for (; first != last; first++) insert(*first); - ++first; - } } // erase ------------------------------------- +// https://www.geeksforgeeks.org/binary-search-tree-set-2-delete MP_TPL void MP:: erase(iterator pos) { - node* delete_point; - delete_point = _erase(pos); - _erase_rebalancing(delete_point); + node* n = pos.getNode(); + node* n_del = NULL; + node* next; + + if (n->left && n->right) + { + next = n->right->min(); + + if (next->up != n) + { + _subtree_shift(next, next->right); + next->right = n->right; + next->right->up = next; + } + n_del = _subtree_shift(n, next); + next->left = n->left; + next->left->up = next; + } + else + { + if (n->left) + n_del = _subtree_shift(n, n->left); + else if (n->right) + n_del = _subtree_shift(n, n->right); + else + n_del = _subtree_shift(n, NULL); + } + + _allocator_node.destroy(n); + _allocator_node.deallocate(n, 1); + _size--; + + _balance(n_del, ERASE); } MP_TPL void MP:: erase(iterator first, iterator last) { @@ -180,22 +236,21 @@ MP_TPL void MP:: MP_TPL typename MP::size_type MP:: erase(const Key& key) { - iterator pos = find(key); + iterator pos; + + pos = find(key); if (pos == end()) return (0); - else - { - erase(pos); - return (1); - } + erase(pos); + return (1); } // swap -------------------------------------- MP_TPL void MP:: swap(map& other) { - node* tmp_root = _root; - node_sentinel* tmp_sentinel = _sentinel; - size_type tmp_size = _size; + node* tmp_root = _root; + sentinel* tmp_sentinel = _sentinel; + size_type tmp_size = _size; _root = other._root; _sentinel = other._sentinel; @@ -351,146 +406,35 @@ MP_TPL typename MP::allocator_type MP:: MP_TPL void MP:: _init_sentinel() { - _sentinel = _allocator_node_sentinel.allocate(1); - _allocator_node_sentinel.construct(_sentinel, node_sentinel()); -} -MP_TPL pair MP:: - _insert(const value_type& value) { - - node* n = _root; - node* prev = NULL; - - while (n) - { - prev = n; - if (_comp(value.first, n->value.first)) - n = n->left; - else if (_comp(n->value.first, value.first)) - n = n->right; - else - return ft::make_pair(iterator(n, _sentinel), false); - } - - n = _allocator_node.allocate(1); - _allocator_node.construct(n, node(value)); - if (_root == NULL) - { - _root = n; - _sentinel->child = _root; - } - else if (_comp(value.first, prev->value.first)) - prev->left = n; - else - prev->right = n; - n->up = prev; - ++_size; - return ft::make_pair(iterator(n, _sentinel), true); + _sentinel = _allocator_sentinel.allocate(1); + _allocator_sentinel.construct(_sentinel, sentinel()); } MP_TPL node* MP:: - _erase(iterator pos) { + _subtree_shift(node* n_old, node* n_new) { - node* n = pos.getNode(); - node* delete_point = NULL; + node* p = n_old->up; - if (n->left && n->right) - { - node* next = n->right->min(); - - if (next->up != n) - { - _subtree_shift(next, next->right); - next->right = n->right; - next->right->up = next; - } - delete_point = _subtree_shift(n, next); - next->left = n->left; - next->left->up = next; - } - else if (!n->left && !n->right) - delete_point = _subtree_shift(n, NULL); - else if (n->left) - delete_point = _subtree_shift(n, n->left); - else if (n->right) - delete_point = _subtree_shift(n, n->right); - - _allocator_node.destroy(n); - _allocator_node.deallocate(n, 1); - --_size; - return (delete_point); -} -MP_TPL node* MP:: - _subtree_shift(node* st_old, node* st_new) { - - node* p = st_old->up; - - if (st_old == _root) + if (n_old == _root) { - _root = st_new; + _root = n_new; _sentinel->child = _root; } - else if (st_old == p->left) - p->left = st_new; + else if (n_old == p->left) + p->left = n_new; else - p->right = st_new; + p->right = n_new; - if (st_new == NULL) + if (n_new == NULL) return (p); - st_new->up = p; - return (st_new); + n_new->up = p; + return (n_new); } MP_TPL void MP:: - _insert_rebalancing(node* n) { + _balance(node* n, bool action) { node* old_n; node* parent = NULL; - while (n) - { - n->height = _compute_height(n); - - if (_balance_factor(n) > 1) // Left Heavy - { - parent = n->up; - if (_balance_factor(n->left) < 0) // Left-Right Case - n->left = _rotate_left(n->left); - // Left-Left Case - n = _rotate_right(n); - old_n = n->right; - } - else if (_balance_factor(n) < -1) // Right Heavy - { - parent = n->up; - if (_balance_factor(n->right) > 0) // Right-Left Case - n->right = _rotate_right(n->right); - // Right-Right Case - n = _rotate_left(n); - old_n = n->left; - } - - if (parent) - { - if (parent->left == old_n) - parent->left = n; - else - parent->right = n; - break; - } - - n = n->up; - } - - while (n) - { - n->height = _compute_height(n); - n = n->up; - } -} -MP_TPL void MP:: - _erase_rebalancing(node* n) { - - node* old_n; - node* parent = NULL; - while (n) { n->height = _compute_height(n); @@ -520,11 +464,23 @@ MP_TPL void MP:: parent->left = n; else parent->right = n; - parent = NULL; + if (action == INSERT) + break; + else if (action == ERASE) + parent = NULL; } n = n->up; } + + if (action == INSERT) + { + while (n) + { + n->height = _compute_height(n); + n = n->up; + } + } } MP_TPL short MP:: _compute_height(node* n) { diff --git a/tests/includes/main.hpp b/tests/includes/main.hpp index 6ea460f..bfb3bf0 100644 --- a/tests/includes/main.hpp +++ b/tests/includes/main.hpp @@ -6,7 +6,8 @@ #include #include // std::setw() #include -#include "tests_utils.hpp" + +#include "tests_structs.hpp" // global variables diff --git a/tests/includes/tests_map.hpp b/tests/includes/tests_map.hpp new file mode 100644 index 0000000..3c7d1e2 --- /dev/null +++ b/tests/includes/tests_map.hpp @@ -0,0 +1,33 @@ +#ifndef TESTS_MAP_HPP +# define TESTS_MAP_HPP + +#include "tests_utils.hpp" + + +// toogle between test ft and stl +// ************************* +#ifdef STL + namespace ft = std; +#else + #include "map.hpp" + #include "reverse_iterator.hpp" +#endif + + +// templates print +// ***************************************** +template + void print(ft::map& mp, std::string name) { + + int i = 0; + typename ft::map::iterator it; + typename ft::map::iterator it_end = mp.end(); + + std::cout << "\n" << name << ":(map)\n"; + for (it = mp.begin(); it != it_end; ++it, i++) + std::cout << "[" << i << "]" << it->first << ":" << it->second << " "; + std::cout << "\nsize:" << mp.size() << "\n"; +} + +#endif + diff --git a/tests/includes/tests_stack.hpp b/tests/includes/tests_stack.hpp new file mode 100644 index 0000000..a6e54fe --- /dev/null +++ b/tests/includes/tests_stack.hpp @@ -0,0 +1,28 @@ +#ifndef TESTS_STACK_HPP +# define TESTS_STACK_HPP + +#include "tests_utils.hpp" + + +// toogle between test ft and stl +// ************************* +#ifdef STL + namespace ft = std; +#else + #include "stack.hpp" +#endif + + +// templates print +// ***************************************** +template + void print(ft::stack& st, std::string name) { + + std::cout << "\n" << name << ":(map)\n"; + for (int i = st.size(); i > 0 ; i--, st.pop()) + std::cout << "[" << i << "]" << st.top() << " "; + std::cout << "\nsize:" << st.size() << "\n"; +} + +#endif + diff --git a/tests/includes/tests_structs.hpp b/tests/includes/tests_structs.hpp new file mode 100644 index 0000000..6ec27e9 --- /dev/null +++ b/tests/includes/tests_structs.hpp @@ -0,0 +1,24 @@ +#ifndef TESTS_STRUCTS_HPP +# define TESTS_STRUCTS_HPP + +// abstract class test ----------------------- +struct A_test +{ + virtual ~A_test(){}; + std::string title; + std::string type; + virtual void func() = 0; +}; +// mystruct ---------------------------------- +struct mystruct { +public: + mystruct(int data = 0); + ~mystruct(); + int * get_data() const; +private: + int * _val; +}; +std::ostream & operator<<(std::ostream & o, mystruct const * rhs); + +#endif + diff --git a/tests/includes/tests_utils.hpp b/tests/includes/tests_utils.hpp index b822a0a..446bd28 100644 --- a/tests/includes/tests_utils.hpp +++ b/tests/includes/tests_utils.hpp @@ -11,21 +11,11 @@ #include // std::make_pair #include // std::stringstream #include - - -// toogle between test ft and stl -// ************************* #include #include #include -#ifdef STL - namespace ft = std; -#else - #include "vector.hpp" - #include "map.hpp" - #include "stack.hpp" - #include "reverse_iterator.hpp" -#endif + +#include "tests_structs.hpp" // defines @@ -41,25 +31,6 @@ // prototypes // ********************************************* -// abstract class test ----------------------- -struct A_test -{ - virtual ~A_test(){}; - std::string title; - std::string type; - virtual void func() = 0; -}; -// mystruct ---------------------------------- -struct mystruct { -public: - mystruct(int data = 0); - ~mystruct(); - int * get_data() const; -private: - int * _val; -}; -std::ostream & operator<<(std::ostream & o, mystruct const * rhs); -// functions --------------------------------- void add_to_list(std::string title, std::string type, A_test* test); void delete_structs(); @@ -109,40 +80,6 @@ extern std::vector< mystruct* > mem_list; add_to_list(#f_name, "int, mystruct*", new(s_ ## f_name ));\ */ -// templates print -// ***************************************** -template - void print(ft::vector& vec, std::string name) { - - int i = 0; - typename ft::vector::iterator it; - typename ft::vector::iterator it_end = vec.end(); - - std::cout << "\n" << name << ":(vector)\n"; - for (it = vec.begin(); it != it_end; ++it, i++) - std::cout << "[" << i << "]" << *it << " "; - std::cout << "\nsize:" << vec.size() << " capacty:" << vec.capacity() << "\n"; -} -template - void print(ft::map& mp, std::string name) { - - int i = 0; - typename ft::map::iterator it; - typename ft::map::iterator it_end = mp.end(); - - std::cout << "\n" << name << ":(map)\n"; - for (it = mp.begin(); it != it_end; ++it, i++) - std::cout << "[" << i << "]" << it->first << ":" << it->second << " "; - std::cout << "\nsize:" << mp.size() << "\n"; -} -template - void print(ft::stack& st, std::string name) { - - std::cout << "\n" << name << ":(map)\n"; - for (int i = st.size(); i > 0 ; i--, st.pop()) - std::cout << "[" << i << "]" << st.top() << " "; - std::cout << "\nsize:" << st.size() << "\n"; -} // templates get value // ************************************* diff --git a/tests/includes/tests_vector.hpp b/tests/includes/tests_vector.hpp new file mode 100644 index 0000000..5da7c7a --- /dev/null +++ b/tests/includes/tests_vector.hpp @@ -0,0 +1,33 @@ +#ifndef TESTS_VECTOR_HPP +# define TESTS_VECTOR_HPP + +#include "tests_utils.hpp" + + +// toogle between test ft and stl +// ************************* +#ifdef STL + namespace ft = std; +#else + #include "vector.hpp" + #include "reverse_iterator.hpp" +#endif + + +// templates print +// ***************************************** +template + void print(ft::vector& vec, std::string name) { + + int i = 0; + typename ft::vector::iterator it; + typename ft::vector::iterator it_end = vec.end(); + + std::cout << "\n" << name << ":(vector)\n"; + for (it = vec.begin(); it != it_end; ++it, i++) + std::cout << "[" << i << "]" << *it << " "; + std::cout << "\nsize:" << vec.size() << " capacty:" << vec.capacity() << "\n"; +} + +#endif + diff --git a/tests/main.cpp b/tests/main.cpp index ac6c4c4..5670099 100644 --- a/tests/main.cpp +++ b/tests/main.cpp @@ -4,68 +4,68 @@ int main() { // VECTOR - tests_vector_constructor(); - tests_vector_operator_assignation(); - tests_vector_begin(); - tests_vector_end(); - tests_vector_rbegin(); - tests_vector_rend(); - tests_vector_size(); - tests_vector_max_size(); - tests_vector_resize(); - tests_vector_capacity(); - tests_vector_empty(); - tests_vector_reserve(); - tests_vector_operator_access(); - tests_vector_at(); - tests_vector_front(); - tests_vector_back(); - tests_vector_assign(); - tests_vector_push_back(); - tests_vector_pop_back(); - tests_vector_insert(); - tests_vector_erase(); - tests_vector_swap(); - tests_vector_clear(); - tests_vector_get_allocator(); - tests_vector_swap_non_member(); - tests_vector_reverse_iterators(); - tests_vector_relational_operators(); +// tests_vector_constructor(); +// tests_vector_operator_assignation(); +// tests_vector_begin(); +// tests_vector_end(); +// tests_vector_rbegin(); +// tests_vector_rend(); +// tests_vector_size(); +// tests_vector_max_size(); +// tests_vector_resize(); +// tests_vector_capacity(); +// tests_vector_empty(); +// tests_vector_reserve(); +// tests_vector_operator_access(); +// tests_vector_at(); +// tests_vector_front(); +// tests_vector_back(); +// tests_vector_assign(); +// tests_vector_push_back(); +// tests_vector_pop_back(); +// tests_vector_insert(); +// tests_vector_erase(); +// tests_vector_swap(); +// tests_vector_clear(); +// tests_vector_get_allocator(); +// tests_vector_swap_non_member(); +// tests_vector_reverse_iterators(); +// tests_vector_relational_operators(); // MAP - tests_map_simple(); - tests_map_constructor(); - tests_map_operator_assignation(); - tests_map_begin(); - tests_map_end(); - tests_map_rbegin(); - tests_map_rend(); - tests_map_empty(); - tests_map_size(); - tests_map_max_size(); - tests_map_operator_access(); +// tests_map_simple(); +// tests_map_constructor(); +// tests_map_operator_assignation(); +// tests_map_begin(); +// tests_map_end(); +// tests_map_rbegin(); +// tests_map_rend(); +// tests_map_empty(); +// tests_map_size(); +// tests_map_max_size(); +// tests_map_operator_access(); tests_map_insert(); tests_map_erase(); - tests_map_swap(); - tests_map_clear(); - tests_map_key_comp(); - tests_map_value_comp(); - tests_map_find(); - tests_map_count(); - tests_map_lower_bound(); - tests_map_upper_bound(); - tests_map_equal_range(); - tests_map_get_allocator(); - tests_map_swap_non_member(); - tests_map_relational_operators(); +// tests_map_swap(); +// tests_map_clear(); +// tests_map_key_comp(); +// tests_map_value_comp(); +// tests_map_find(); +// tests_map_count(); +// tests_map_lower_bound(); +// tests_map_upper_bound(); +// tests_map_equal_range(); +// tests_map_get_allocator(); +// tests_map_swap_non_member(); +// tests_map_relational_operators(); // STACK - tests_stack_constructor(); - tests_stack_empty(); - tests_stack_size(); - tests_stack_top(); - tests_stack_push(); - tests_stack_pop(); +// tests_stack_constructor(); +// tests_stack_empty(); +// tests_stack_size(); +// tests_stack_top(); +// tests_stack_push(); +// tests_stack_pop(); // execute tests and print them : int size = test_list.size(); diff --git a/tests/tests_map.cpp b/tests/tests_map.cpp index a6cc264..0a6add0 100644 --- a/tests/tests_map.cpp +++ b/tests/tests_map.cpp @@ -1,5 +1,6 @@ -#include "tests_utils.hpp" +#include "tests_map.hpp" + /**/ // UTILS for some tests /**/ bool fncomp (char lhs, char rhs) {return lhs