diff --git a/.gitignore b/.gitignore index 957974d..cb08bad 100644 --- a/.gitignore +++ b/.gitignore @@ -36,6 +36,10 @@ Thumbs.db *.zip *.pdf /builds +/builds_ft +/builds_stl # cube3d containers +containers_ft +containers_stl diff --git a/Makefile b/Makefile index 9224954..6384635 100644 --- a/Makefile +++ b/Makefile @@ -1,70 +1,126 @@ +# - - - - - - - # +# # +# COLORS # +# # +# - - - - - - - # + +GRAY = "\e[0;30m" +RED = "\e[0;31m" +GREEN = "\e[0;32m" +YELLOW = "\e[0;33m" +BLUE = "\e[0;34m" +PURPLE = "\e[0;35m" +CYAN = "\e[0;36m" +WHITE = "\e[0;37m" + +B_GRAY = "\e[1;30m" +B_RED = "\e[1;31m" +B_GREEN = "\e[1;32m" +B_YELLOW = "\e[1;33m" +B_BLUE = "\e[1;34m" +B_PURPLE = "\e[1;35m" +B_CYAN = "\e[1;36m" +B_WHITE = "\e[1;37m" + +RESET = "\e[0m" + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # # . name = value \ . += append to a variable # # VARIABLES . value . != set result of command # # . name is case sensitive . ?= set if not already set # # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # -NAME = a.out +NAME = containers +NAME_FT = containers_ft +NAME_STL = containers_stl -TYPE = cpp +CC = c++ +EXT = cpp -CC = c++ -EXT = cpp +CFLAGS = -Wall -Wextra -Werror $(INCLUDES) +#CFLAGS += -std=c++98 +#CFLAGS += -MMD -MP #see end-page note on header dependencie +#CFLAGS += -g3 -CFLAGS = -Wall -Wextra -Werror $(INCLUDES) -CFLAGS += -std=c++98 +CFLAGS_STL = $(CFLAGS) +CFLAGS_STL += -D STL -VPATH = $(D_SRCS) +VPATH = $(D_SRCS) -LIBS = +LIBS = -INCLUDES = -I$(D_HEADERS) +D_INCLUDE = ./headers \ + ./templates \ + ./tests/includes -D_SRCS = . -SRCS = main.cpp +INCLUDES = $(D_INCLUDE:%=-I%) -D_HEADERS = headers -HEADERS = colors.h +D_SRCS = ./tests +#SRCS = main42.cpp +#SRCS = main_map_1.cpp +#SRCS = main_map_2.cpp +#SRCS = main_stack_1.cpp +SRCS = main.cpp \ + tests_definitions.cpp \ + \ + tests_vector.cpp \ + tests_map.cpp \ + tests_stack.cpp -D_OBJS = builds -OBJS = $(SRCS:%.$(EXT)=$(D_OBJS)/%.o) +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) -ifeq "$(D_OBJS)" "." - RM_OBJS = rm -f $(OBJS) -else - RM_OBJS = rm -rf $(D_OBJS) -endif +OBJS = $(OBJS_FT) $(OBJS_STL) +DEPS = $(OBJS:.o=.d) #see end-page note on header dependencie # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # -# . target: prerequisites . $@ : target # -# RULES . recipe . $< : 1st prerequisite # -# . recipe . $^ : all prerequisites # +# . target: prerequisites . $@ : target # +# RULES . recipe . $< : 1st prerequisite # +# . @recipe (silent) . $^ : all prerequisites # # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # -all: $(NAME) +all: $(NAME_FT) $(NAME_STL) +stl: $(NAME_STL) +ft: $(NAME_FT) -$(D_OBJS)/%.o: %.$(EXT) | $(D_OBJS) - $(CC) $(CFLAGS) -c $< -o $@ +$(D_OBJS_FT)/%.o: %.$(EXT) | $(D_OBJS_FT) + @echo $(CYAN)"compilation " $@ $(RESET) + @$(CC) $(CFLAGS) -c $< -o $@ +$(D_OBJS_STL)/%.o: %.$(EXT) | $(D_OBJS_STL) + @echo $(CYAN)"compilation -D STL" $@ $(RESET) + @$(CC) $(CFLAGS) -D STL -c $< -o $@ -$(D_OBJS): +$(D_OBJS_FT) $(D_OBJS_STL): mkdir $@ -$(OBJS): $(HEADERS:%=$(D_HEADERS)/%) +$(NAME_FT): $(OBJS_FT) +$(NAME_STL): $(OBJS_STL) +$(NAME_FT) $(NAME_STL): + @echo $(PURPLE)"linkage (link objects.o)"$(RESET) + @$(CC) $^ -o $@ $(LIBS) -$(NAME): $(OBJS) - $(CC) $(OBJS) -o $@ $(LIBS) - -leaks: $(NAME) - valgrind --leak-check=full --show-leak-kinds=all ./$(NAME) +leaks: leaksft +leaksft: $(NAME_FT) + valgrind --leak-check=full --show-leak-kinds=all ./$< +leakstl: $(NAME_STL) + valgrind --leak-check=full --show-leak-kinds=all ./$< clean: - $(RM_OBJS) + rm -rf $(D_OBJS_FT) + rm -rf $(D_OBJS_STL) fclean: clean - rm -f $(NAME) + rm -f $(NAME_FT) $(NAME_STL) re: fclean all .PHONY : all clean fclean re +# header dependencie +# https://spin.atomicobject.com/2016/08/26/makefile-c-projects +# https://stackoverflow.com/questions/13432127/how-to-use-the-include-directive-in-a-makefile-for-a-specific-target +-include $(DEPS) + diff --git a/README.md b/README.md index 7b7f1be..e04b869 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,4 @@ + # CONTAINERS # ### Compilation @@ -62,3 +63,4 @@ saires. Cependant, vous devez éviter le problème de la double inclusion en les * Vous devez créer deux binaires faisant tourner les mêmes tests : l’un avec vos containers et l’autre avec les containers standards. * Comparez les sorties et les performances / temps (vos containers peuvent être jusqu’à 20 fois plus lents que les originaux). * Pour tester vos containers : ft::. + diff --git a/headers/colors.h b/headers/colors.h index 0374e42..2f97a4c 100644 --- a/headers/colors.h +++ b/headers/colors.h @@ -1,3 +1,4 @@ + #ifndef COLORS_H # define COLORS_H diff --git a/headers/enable_if.hpp b/headers/enable_if.hpp new file mode 100644 index 0000000..655ee96 --- /dev/null +++ b/headers/enable_if.hpp @@ -0,0 +1,16 @@ +#ifndef ENABLE_IF_HPP +# define ENABLE_IF_HPP + +namespace ft { + +template +struct enable_if {}; + + +template +struct enable_if { typedef T type; }; + +} // namespace ft + +#endif + diff --git a/headers/equal.hpp b/headers/equal.hpp new file mode 100644 index 0000000..ba7ab74 --- /dev/null +++ b/headers/equal.hpp @@ -0,0 +1,36 @@ + +#ifndef EQUAL_HPP +# define EQUAL_HPP + +namespace ft { + +template < typename InputIt1, typename InputIt2 > + bool equal( InputIt1 first1, InputIt1 last1, InputIt2 first2) { + + while (first1 != last1) + { + if (!(*first1 == *first2)) + return false; + ++first1; + ++first2; + } + return true; +} + +template < class InputIt1, class InputIt2, class BinaryPred > + bool equal( InputIt1 first1, InputIt1 last1, InputIt2 first2, BinaryPred pred) { + + while (first1 != last1) + { + if (!pred(*first1, *first2)) + return false; + ++first1; + ++first2; + } + return true; +} + +} // namespace ft + +#endif + diff --git a/headers/is_integral.hpp b/headers/is_integral.hpp new file mode 100644 index 0000000..8a70806 --- /dev/null +++ b/headers/is_integral.hpp @@ -0,0 +1,46 @@ +#ifndef IS_INTEGRAL_HPP +# define IS_INTEGRAL_HPP + +namespace ft { + +template struct is_integral +{ + typedef char yes[1]; + typedef yes no[2]; + + static T type; + +// integral types : https://www.cplusplus.com/reference/type_traits/is_integral/ + static yes& test(bool); + static yes& test(char); +// static yes& test(char16_t); +// static yes& test(char32_t); + static yes& test(wchar_t); + static yes& test(signed char); + static yes& test(short int); + static yes& test(int); + static yes& test(long int); + static yes& test(long long int); + static yes& test(unsigned char); + static yes& test(unsigned short int); + static yes& test(unsigned int); + static yes& test(unsigned long int); + static yes& test(unsigned long long int); + + // non-template function with direct matching are always considered first + // then the function template with direct matching are considered + // https://stackoverflow.com/questions/12877546/how-do-i-avoid-implicit-conversions-on + template static no& test(C); + + static const bool value = sizeof(test(type)) == sizeof(yes); +}; + +} // namespace ft + +// "template <>" introduce a total specialization of a template : +// https://stackoverflow.com/questions/6288812/what-is-the-meaning-of-template-with-empty-angle-brackets-in-c + +// SFINAE : https://jguegant.github.io/blogs/tech/sfinae-introduction.html + +#endif + diff --git a/headers/iterator_traits.hpp b/headers/iterator_traits.hpp new file mode 100644 index 0000000..e9b3524 --- /dev/null +++ b/headers/iterator_traits.hpp @@ -0,0 +1,44 @@ + +#ifndef ITERATOR_TRAITS_HPP +# define ITERATOR_TRAITS_HPP + +# include // iterator_tag +# include // ptrdiff_t + +namespace ft { + +template < typename Iterator > + struct iterator_traits +{ + 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; +}; + +template < typename T > + struct iterator_traits +{ + typedef std::random_access_iterator_tag iterator_category; + typedef T value_type; + typedef std::ptrdiff_t difference_type; + typedef T* pointer; + typedef T& reference; +}; + +template < typename T > + struct iterator_traits +{ + typedef std::random_access_iterator_tag iterator_category; + typedef T value_type; + typedef std::ptrdiff_t difference_type; + typedef const T* pointer; + typedef const T& reference; +}; + +} // namespace ft + +#endif + +// https://www.fluentcpp.com/2018/05/08/std-iterator-deprecated/ diff --git a/headers/lexicographical_compare.hpp b/headers/lexicographical_compare.hpp new file mode 100644 index 0000000..f42861f --- /dev/null +++ b/headers/lexicographical_compare.hpp @@ -0,0 +1,23 @@ + +#ifndef LEXICOGRAPHICAL_COMPARE_HPP +# define LEXICOGRAPHICAL_COMPARE_HPP + +namespace ft { + +template + bool lexicographical_compare + ( InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2 ) { + + for (; first1 != last1; first1++, first2++) { + if (*first1 < *first2) + return true; + if (*first2 < *first1) + return false; + } + return (first1 == last1 && first2 != last2); +} + +} // namespace ft + +#endif + diff --git a/headers/make_pair.hpp b/headers/make_pair.hpp new file mode 100644 index 0000000..d06fac3 --- /dev/null +++ b/headers/make_pair.hpp @@ -0,0 +1,23 @@ +#ifndef MAKE_PAIR_HPP +# define MAKE_PAIR_HPP + +# define PR_TPL template < class T1, class T2 > +# define PR pair + +#include "pair.hpp" + +namespace ft { + +PR_TPL PR + make_pair(T1 x, T2 y) { + + return PR(x, y) ; +} + +} // namespace ft + +# undef PR +# undef PR_TPL + +#endif + diff --git a/headers/map.hpp b/headers/map.hpp new file mode 100644 index 0000000..48bf5ce --- /dev/null +++ b/headers/map.hpp @@ -0,0 +1,222 @@ + +#ifndef MAP_HPP +# define MAP_HPP + +# include // std::allocator +# include // NULL, std::size_t, std::ptrdiff_t +# include // std::max() +# include // std::less, std::binary_function + +# include "reverse_iterator.hpp" +# include "equal.hpp" +# include "lexicographical_compare.hpp" + +# include "pair.hpp" +# include "make_pair.hpp" +# include "map_node.hpp" +# include "map_iterator.hpp" + +namespace ft { + +template < + class Key, // map::key_type + class T, // map::mapped_type + class Compare = std::less, // map::key_compare + class Alloc = std::allocator< ft::pair > // map::allocator_type +> class map { + +public: + + typedef Key key_type; + typedef T mapped_type; + typedef pair value_type; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + typedef Compare key_compare; + typedef Alloc allocator_type; + + typedef map_iterator iterator; + typedef map_const_iterator const_iterator; + typedef ft::reverse_iterator reverse_iterator; + typedef ft::reverse_iterator const_reverse_iterator; + + + /**************** + * member class : + ****************/ + // https://en.cppreference.com/w/cpp/container/map/value_compare + // https://stackoverflow.com/questions/4571355/why-would-one-use-nested-classes-in-c + class value_compare : public std::binary_function { + + friend class map; + protected: + Compare comp; + value_compare(Compare c) : comp(c) {} + public: + bool operator() (const value_type& x, const value_type& y) const + { return comp(x.first, y.first); } + }; + + + /************ + * copliens : + ************/ +// constructors ------------------------------ + explicit map (const key_compare& comp = key_compare(), + const allocator_type& alloc = allocator_type()); + template + map (InputIterator first, InputIterator last, + const key_compare& comp = key_compare(), + const allocator_type& alloc = allocator_type()); + map(const map& x); +// destructor -------------------------------- + ~map(); +// operator= --------------------------------- + map& operator= (const map& x); + + + /************* + * iterators : + *************/ +// begin ------------------------------------- + iterator begin(); + const_iterator begin() const; +// end --------------------------------------- + iterator end(); + const_iterator end() const; +// rbegin ------------------------------------ + reverse_iterator rbegin(); + const_reverse_iterator rbegin() const; +// rend -------------------------------------- + reverse_iterator rend(); + const_reverse_iterator rend() const; + + + /************ + * capacity : + ************/ +// empty ------------------------------------- + bool empty() const; +// size -------------------------------------- + size_type size() const; +// max_size ---------------------------------- + size_type max_size() const; + + + /****************** + * element access : + ******************/ +// operator[] -------------------------------- + mapped_type & operator[] (const key_type& k); + + + /************* + * modifiers : + *************/ +// insert ------------------------------------ + pair insert (const value_type& val); + iterator insert (iterator position, const value_type& val); + template + void insert (InputIterator first, InputIterator last); +// erase ------------------------------------- + void erase (iterator position); + size_type erase (const key_type& k); + void erase (iterator first, iterator last); +// swap -------------------------------------- + void swap (map& x); +// clear ------------------------------------- + void clear(); + + + /************* + * observers : + *************/ +// key_comp ---------------------------------- + key_compare key_comp() const; +// value_comp -------------------------------- + value_compare value_comp() const; + + + /************** + * operations : + **************/ +// find -------------------------------------- + iterator find (const key_type& k); + const_iterator find (const key_type& k) const; +// count ------------------------------------- + size_type count (const key_type& k) const; +// lower_bound ------------------------------- + iterator lower_bound (const key_type& k); + const_iterator lower_bound (const key_type& k) const; +// upper_bound ------------------------------- + iterator upper_bound (const key_type& k); + const_iterator upper_bound (const key_type& k) const; +// equal_range ------------------------------- + pair equal_range (const key_type& k) const; + pair equal_range (const key_type& k); + + + /************* + * allocator : + *************/ +// get_allocator ----------------------------- + allocator_type get_allocator() const; + +private: + 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; + typename Alloc::template rebind< sentinel >::other _allocator_sentinel; + + // BBST + 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); + }; + + + /************************ + * non-member functions : + ************************/ +// operator == ------------------------------- +template< class K, class T, class Comp, class Alloc > bool operator== + ( const std::map& lhs, const std::map& rhs ); +// operator != ------------------------------- +template< class K, class T, class Comp, class Alloc > bool operator!= + ( const std::map& lhs, const std::map& rhs ); +// operator < -------------------------------- +template< class K, class T, class Comp, class Alloc > bool operator< + ( const std::map& lhs, const std::map& rhs ); +// operator <= ------------------------------- +template< class K, class T, class Comp, class Alloc > bool operator<= + ( const std::map& lhs, const std::map& rhs ); +// operator > -------------------------------- +template< class K, class T, class Comp, class Alloc > bool operator> + ( const std::map& lhs, const std::map& rhs ); +// operator >= ------------------------------- +template< class K, class T, class Comp, class Alloc > bool operator>= + ( const std::map& lhs, const std::map& rhs ); +// swap (map) ----------------------------- +template< class Key, class T, class Compare, class Alloc > void swap + ( std::map& lhs, std::map& rhs ); + +} // namespace ft + +# include "map.tpp" + +// banlanced binary search tree : +// https://www.youtube.com/watch?v=vRwi_UcZGjU + +// entinel node : +// https://en.wikipedia.org/wiki/Sentinel_node + +#endif + diff --git a/headers/map_iterator.hpp b/headers/map_iterator.hpp new file mode 100644 index 0000000..98a729c --- /dev/null +++ b/headers/map_iterator.hpp @@ -0,0 +1,193 @@ +#ifndef MAP_ITERATOR_HPP +# define MAP_ITERATOR_HPP + +# include // NULL, ptrdiff_t +# include // iterator_tag + +# include "pair.hpp" +# include "map_node.hpp" + +namespace ft { + +template < + typename Key, + typename T, + typename Compare, + typename Allocator +> class map_iterator { + +private: + typedef map_iterator self; + +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; + + map_iterator() : _node(), _sentinel() {} + map_iterator(node* n, sentinel* sentinel) + : _node(n), _sentinel(sentinel) {} + + 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 + { + node* up = _node->up; + while (up != NULL && _node == up->right) + { + _node = up; + up = up->up; + } + _node = up; + } + return *this; + } + + self& operator--() { + if (_node == NULL) + _node = _sentinel->child->max(); + else if (_node->left) + _node = _node->left->max(); + else + { + node* up = _node->up; + while (up != NULL && _node == up->left) + { + _node = up; + up = up->up; + } + _node = up; + } + return *this; + } + + self operator++(int) { + self old = *this; + ++(*this); + return old; + } + + self operator--(int) { + self old = *this; + --(*this); + return old; + } + + node* get_node() { return _node; } + const node* get_node() const { return _node; } + const sentinel* getSentinel() const { return _sentinel; } + + 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; + sentinel* _sentinel; +}; + +template < + typename Key, + typename T, + typename Compare, + typename Allocator +> class map_const_iterator { + +private: + typedef map_const_iterator self; + +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; + + 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.get_node()), _sentinel(src.getSentinel()) {} + + 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 + { + node* up = _node->up; + while (up != NULL && _node == up->right) + { + _node = up; + up = up->up; + } + _node = up; + } + return *this; + } + + self& operator--() { + if (_node == NULL) + _node = _sentinel->child->max(); + else if (_node->left) + _node = _node->left->max(); + else + { + node* up = _node->up; + while (up != NULL && _node == up->left) + { + _node = up; + up = up->up; + } + _node = up; + } + return *this; + } + + self operator++(int) { + self old = *this; + ++(*this); + return old; + } + + self operator--(int) { + self old = *this; + --(*this); + return old; + } + + node* get_node() 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); } + +private: + const node* _node; + const sentinel* _sentinel; +}; + +} // namespace ft + +#endif + diff --git a/headers/map_node.hpp b/headers/map_node.hpp new file mode 100644 index 0000000..d34d492 --- /dev/null +++ b/headers/map_node.hpp @@ -0,0 +1,56 @@ + +#ifndef MAP_NODE_HPP +# define MAP_NODE_HPP + +# include // NULL + +namespace ft { + +template < typename ValueType > + struct node { + + ValueType value; + node *up; + node *left; + node *right; + short height; + + node(const ValueType& val) + : value(val) + , up(NULL) + , left(NULL) + , right(NULL) + , height(1) + {} + + node* min() { + + node* n = this; + + while (n->left) + n = n->left; + return n; + } + + node* max() { + + node* n = this; + + while (n->right) + n = n->right; + return n; + } +}; + +template < typename ValueType > + struct sentinel { + + node *child; + + sentinel() : child(NULL) {} +}; + +} // namespace ft + +#endif + diff --git a/headers/pair.hpp b/headers/pair.hpp new file mode 100644 index 0000000..5e3fe6b --- /dev/null +++ b/headers/pair.hpp @@ -0,0 +1,86 @@ +#ifndef PAIR_HPP +# define PAIR_HPP + +# define PR_TPL template < class T1, class T2 > +# define PR pair + +namespace ft { + +PR_TPL + struct pair { + + typedef T1 first_type; + typedef T2 second_type; + + pair(); + template< typename U, typename V > + pair(const pair& pr); + pair(const first_type& a, const second_type& b); + + T1 first; + T2 second; +}; + + + /************ + * copliens : + ************/ +PR_TPL PR:: + pair() {} +PR_TPL template< typename U, typename V > PR:: + pair(const pair& pr) + : first(pr.first) + , second(pr.second) { +} +PR_TPL PR:: + pair(const first_type& a, const second_type& b) + : first(a) + , second(b) { +} + + + + /************************ + * non-member functions : + ************************/ +PR_TPL + bool operator==(const PR& lhs, const PR& rhs) { + + return (lhs.first == rhs.first) && (lhs.second == rhs.second); +} +PR_TPL + bool operator<(const PR& lhs, const PR& rhs) { + + return (lhs.first < rhs.first + || ( !(rhs.first < lhs.first) && (lhs.second < rhs.second) ) + ); +} +PR_TPL + bool operator!=(const PR& lhs, const PR& rhs) { + + return !(lhs == rhs); +} +PR_TPL + bool operator>(const PR& lhs, const PR& rhs) { + + return (rhs < lhs); +} +PR_TPL + bool operator<=(const PR& lhs, const PR& rhs) { + + return !(lhs > rhs); +} + +PR_TPL + bool operator>=(const PR& lhs, const PR& rhs) { + + return !(lhs < rhs); +} + +} // namespace ft + +# undef PR +# undef PR_TPL + +#endif + diff --git a/headers/reverse_iterator.hpp b/headers/reverse_iterator.hpp new file mode 100644 index 0000000..db10560 --- /dev/null +++ b/headers/reverse_iterator.hpp @@ -0,0 +1,140 @@ +#ifndef REVERSE_ITERATOR_HPP +# define REVERSE_ITERATOR_HPP + +# include // iterator_tag +# include "iterator_traits.hpp" + +namespace ft { + +template < class Iter > +class reverse_iterator { + +private: + + Iter _it; + typedef ft::iterator_traits _traits; + +public: + typedef Iter iterator_type; + typedef typename _traits::iterator_category iterator_category; + typedef typename _traits::value_type value_type; + typedef typename _traits::difference_type difference_type; + typedef typename _traits::pointer pointer; + typedef typename _traits::reference reference; + + + /**************** + * constructors : + ****************/ + reverse_iterator() + : _it() + {} + explicit reverse_iterator(iterator_type it) + : _it(it) + {} +// reverse_iterator(const reverse_iterator& src) +// : _it(src._it) +// {} + template < class Iterator > + reverse_iterator(const reverse_iterator& rev_it) + : _it(rev_it.base()) + {} + + /********************* + * members functions : + *********************/ +// base -------------------------------------- + iterator_type base() const + { return _it; } +// operator * -------------------------------- + reference operator*() const + { Iter tmp = _it; return *--tmp; } +// operator + -------------------------------- + reverse_iterator operator+(difference_type n) const + { return reverse_iterator(_it - n); } +// operator ++ ------------------------------- + reverse_iterator operator++(int) + { reverse_iterator old(*this); ++(*this); return old; } + reverse_iterator & operator++() + { --_it; return *this; } +// operator += ------------------------------- + reverse_iterator & operator+=(difference_type n) + { _it -= n; return *this; } +// operator - -------------------------------- + reverse_iterator operator-(difference_type n) const + { return reverse_iterator(_it + n); } +// operator -- ------------------------------- + reverse_iterator operator--(int) + { reverse_iterator old(*this); --(*this); return old; } + reverse_iterator & operator--() + { ++_it; return *this; } +// operator -= ------------------------------- + reverse_iterator & operator-=(difference_type n) + { _it += n; return *this; } +// operator -> ------------------------------- + pointer operator->() const + { return &(operator*()); } +// operator [] ------------------------------- + reference operator[] (difference_type n) const + { return _it[-n-1]; } +}; + + /************************* + * non-members functions : + *************************/ +// operator == ------------------------------- +template + bool operator== (const reverse_iterator& lhs, + const reverse_iterator& rhs) + { return lhs.base() == rhs.base(); } +// operator != ------------------------------- +template + bool operator!= (const reverse_iterator& lhs, + const reverse_iterator& rhs) + { return lhs.base() != rhs.base(); } +// operator < -------------------------------- +template + bool operator< (const reverse_iterator& lhs, + const reverse_iterator& rhs) + { return lhs.base() > rhs.base(); } +// operator <= ------------------------------- +template + bool operator<= (const reverse_iterator& lhs, + const reverse_iterator& rhs) + { return lhs.base() >= rhs.base(); } +// operator > -------------------------------- +template + bool operator> (const reverse_iterator& lhs, + const reverse_iterator& rhs) + { return lhs.base() < rhs.base(); } +// operator >= ------------------------------- +template + bool operator>= (const reverse_iterator& lhs, + const reverse_iterator& rhs) + { return lhs.base() <= rhs.base(); } + + + /******************* + * other operators : + *******************/ +// operator + non-member overload ------------ +template + reverse_iterator operator+ + (typename reverse_iterator::difference_type n + ,const reverse_iterator& rhs) + { return reverse_iterator(rhs.base() - n); } + +// operator - non-member overload ------------ +template + typename reverse_iterator::difference_type operator- + (const reverse_iterator& lhs + ,const reverse_iterator& rhs) + { return rhs.base() - lhs.base(); } + + + + +} // namespace ft + +#endif + diff --git a/headers/stack.hpp b/headers/stack.hpp new file mode 100644 index 0000000..1f7fa82 --- /dev/null +++ b/headers/stack.hpp @@ -0,0 +1,68 @@ + +#ifndef STACK_HPP +# define STACK_HPP + +# include "vector.hpp" + +namespace ft { + +template < + typename T, + typename Container = ft::vector +> class stack { + +public: + typedef Container container_type; + typedef typename Container::value_type value_type; + typedef typename Container::size_type size_type; + + + /************ + * copliens : + ************/ +// constructors ------------------------------ + explicit stack(const container_type& cont = Container()); + + + /********************** + * overload functions : + **********************/ +// empty ------------------------------------- + bool empty() const ; +// size -------------------------------------- + size_type size() const ; +// top --------------------------------------- + value_type& top(); + const value_type& top() const ; +// push -------------------------------------- + void push(const value_type& value); +// pop --------------------------------------- + void pop(); + + /********************************* + * Relational Operators (friend) : + *********************************/ + template < typename T2, typename C2 > + friend bool operator==(const stack& lhs, const stack& rhs); + template < typename T2, typename C2 > + friend bool operator!=(const stack& lhs, const stack& rhs); + template < typename T2, typename C2 > + friend bool operator<(const stack& lhs, const stack& rhs); + template < typename T2, typename C2 > + friend bool operator>(const stack& lhs, const stack& rhs); + template < typename T2, typename C2 > + friend bool operator<=(const stack& lhs, const stack& rhs); + template < typename T2, typename C2 > + friend bool operator>=(const stack& lhs, const stack& rhs); + +protected: + container_type c; + +}; + +} // namespace ft + +# include "stack.tpp" + +#endif + diff --git a/headers/vector.hpp b/headers/vector.hpp new file mode 100644 index 0000000..78bb779 --- /dev/null +++ b/headers/vector.hpp @@ -0,0 +1,188 @@ +#ifndef VECTOR_HPP +# define VECTOR_HPP + +# include "colors.h" +# include +# include +# include // std::allocator +# include // std::min, std::max +# include // out_of_range, length_error, logic_error +# include // NULL, std::size_t, std::ptrdiff_t + +# include "enable_if.hpp" +# include "is_integral.hpp" +# include "reverse_iterator.hpp" +# include "equal.hpp" +# include "lexicographical_compare.hpp" + +namespace ft { + +template < + class T, + class Allocator = std::allocator > +class vector { + +public: + + 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 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; + + + + /************ + * copliens : + ************/ +// 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()); + template + vector (InputIterator first, InputIterator last, + const allocator_type& alloc = allocator_type()); + vector( vector const & src ); +// destructor -------------------------------- + ~vector(); +// operator= --------------------------------- + vector & operator=( vector const & rhs ); + + + /************* + * iterators : + *************/ +// begin ------------------------------------- + iterator begin(); + const_iterator begin() const; +// end --------------------------------------- + iterator end(); + const_iterator end() const; +// rbegin ------------------------------------ + reverse_iterator rbegin(); + const_reverse_iterator rbegin() const; +// rend -------------------------------------- + reverse_iterator rend(); + const_reverse_iterator rend() const; + + + /************ + * capacity : + ************/ +// size -------------------------------------- + size_type size() const; +// max_size ---------------------------------- + size_type max_size() const; +// resize ------------------------------------ + void resize(size_type n, value_type val = value_type()); +// capacity ---------------------------------- + size_type capacity() const; +// empty ------------------------------------- + bool empty() const; +// reserve ----------------------------------- + void reserve(size_type n); + + + /****************** + * element access : + ******************/ +// operator[] -------------------------------- + reference operator[](size_type n); + const_reference operator[](size_type n) const; +// at ---------------------------------------- + reference at(size_type n); + const_reference at(size_type n) const; +// front ------------------------------------- + reference front(); + const_reference front() const; +// back -------------------------------------- + reference back(); + const_reference back() const; + + + /************* + * modifiers : + *************/ +// assign ------------------------------------ + template + typename enable_if< !is_integral::value,void >::type + assign(InputIterator first, InputIterator last); + void assign(size_type n, const value_type& val); +// push_back --------------------------------- + void push_back(const value_type & val); +// pop_back ---------------------------------- + void pop_back(); +// insert ------------------------------------ + iterator insert(iterator position, const value_type& val); + void insert(iterator position, size_type n, const value_type& val); + template + typename enable_if< !is_integral::value,void >::type + insert(iterator position, InputIterator first, InputIterator last); +// erase ------------------------------------- + iterator erase(iterator position); + iterator erase(iterator first, iterator last); +// swap -------------------------------------- + void swap(vector& x); +// clear ------------------------------------- + void clear(); + + + /************* + * allocator : + *************/ +// get_allocator ----------------------------- + allocator_type get_allocator() const; + +private: + + size_type _size; + size_type _capacity; + value_type * _mem_ptr; + allocator_type _allocator; + + void _destroy(iterator first, iterator last); + void _increment_capacity(size_type n); + +}; + + + /************************ + * non-member functions : + ************************/ +// operator == ------------------------------- +template + bool operator== (const vector& lhs, const vector& rhs); +// operator != ------------------------------- +template + bool operator!= (const vector& lhs, const vector& rhs); +// operator < -------------------------------- +template + bool operator< (const vector& lhs, const vector& rhs); +// operator <= ------------------------------- +template + bool operator<= (const vector& lhs, const vector& rhs); +// operator > -------------------------------- +template + bool operator> (const vector& lhs, const vector& rhs); +// operator >= ------------------------------- +template + bool operator>= (const vector& lhs, const vector& rhs); +// swap (vector) ----------------------------- +template + void swap (vector& x, vector& y); + + +} // namespace ft + +# include "vector.tpp" + +#endif diff --git a/main.cpp b/main.cpp deleted file mode 100644 index d12e44a..0000000 --- a/main.cpp +++ /dev/null @@ -1,578 +0,0 @@ -#include -#include -#include "colors.h" - -#include - -#define N_TEST "24" - -int main() { - int i = 0; - - std::cout << B_YELLOW "\n[" << ++i << "/" N_TEST "] " - << "vector::vector (constructor) :" RESET "\n"; - { - // 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 - std::vector third (second.begin(),second.end()); // iterating through second - std::vector fourth (third); // a copy of third - - // the iterator constructor can also be used to construct from arrays: - int myints[] = {16,2,77,29}; - std::vector fifth (myints, myints + sizeof(myints) / sizeof(int) ); - - std::cout << "The contents of fifth are:"; - for (std::vector::iterator it = fifth.begin(); it != fifth.end(); ++it) - std::cout << ' ' << *it; - std::cout << '\n'; - } - - std::cout << B_YELLOW "\n[" << ++i << "/" N_TEST "] " - << "vector::operator= :" RESET "\n"; - { - std::vector foo (3,0); - std::vector bar (5,0); - - bar = foo; - foo = std::vector(); - - std::cout << "Size of foo: " << int(foo.size()) << '\n'; - std::cout << "Size of bar: " << int(bar.size()) << '\n'; - } - - std::cout << B_YELLOW "\n[" << ++i << "/" N_TEST "] " - << "vector::begin :" RESET "\n"; - { - std::vector myvector; - for (int i=1; i<=5; i++) myvector.push_back(i); - - std::cout << "myvector contains:"; - for (std::vector::iterator it = myvector.begin() ; it != myvector.end(); ++it) - std::cout << ' ' << *it; - std::cout << '\n'; - } - - std::cout << B_YELLOW "\n[" << ++i << "/" N_TEST "] " - << "vector::end :" RESET "\n"; - { - std::vector myvector; - for (int i=1; i<=5; i++) myvector.push_back(i); - - std::cout << "myvector contains:"; - for (std::vector::iterator it = myvector.begin() ; it != myvector.end(); ++it) - std::cout << ' ' << *it; - std::cout << '\n'; - } - - std::cout << B_YELLOW "\n[" << ++i << "/" N_TEST "] " - << "vector::rbegin :" RESET "\n"; - { - std::vector myvector (5); // 5 default-constructed ints - - int i=0; - - std::vector::reverse_iterator rit = myvector.rbegin(); - for (; rit!= myvector.rend(); ++rit) - *rit = ++i; - - std::cout << "myvector contains:"; - for (std::vector::iterator it = myvector.begin(); it != myvector.end(); ++it) - std::cout << ' ' << *it; - std::cout << '\n'; - } - - std::cout << B_YELLOW "\n[" << ++i << "/" N_TEST "] " - << "vector::rend :" RESET "\n"; - { - std::vector myvector (5); // 5 default-constructed ints - - std::vector::reverse_iterator rit = myvector.rbegin(); - - int i=0; - for (rit = myvector.rbegin(); rit!= myvector.rend(); ++rit) - *rit = ++i; - - std::cout << "myvector contains:"; - for (std::vector::iterator it = myvector.begin(); it != myvector.end(); ++it) - std::cout << ' ' << *it; - std::cout << '\n'; - } - - std::cout << B_YELLOW "\n[" << ++i << "/" N_TEST "] " - << "vector::size :" RESET "\n"; - { - std::vector myints; - std::cout << "0. size: " << myints.size() << '\n'; - - for (int i=0; i<10; i++) myints.push_back(i); - std::cout << "1. size: " << myints.size() << '\n'; - - myints.insert (myints.end(),10,100); - std::cout << "2. size: " << myints.size() << '\n'; - - myints.pop_back(); - std::cout << "3. size: " << myints.size() << '\n'; - } - - std::cout << B_YELLOW "\n[" << ++i << "/" N_TEST "] " - << "vector::max_size :" RESET "\n"; - { - std::vector myvector; - - // set some content in the vector: - for (int i=0; i<100; i++) myvector.push_back(i); - - std::cout << "size: " << myvector.size() << "\n"; - std::cout << "capacity: " << myvector.capacity() << "\n"; - std::cout << "max_size: " << myvector.max_size() << "\n"; - } - - std::cout << B_YELLOW "\n[" << ++i << "/" N_TEST "] " - << "vector::resize :" RESET "\n"; - { - std::vector myvector; - - // set some initial content: - for (int i = 1; i < 10; i++) myvector.push_back(i); - - myvector.resize(5); - myvector.resize(8,100); - myvector.resize(12); - - std::cout << "myvector contains:"; - for (unsigned int i = 0; i < myvector.size(); i++) - std::cout << ' ' << myvector[i]; - std::cout << '\n'; - } - - std::cout << B_YELLOW "\n[" << ++i << "/" N_TEST "] " - << "vector::capacity :" RESET "\n"; - { - std::vector myvector; - - // set some content in the vector: - for (int i = 0; i < 100; i++) myvector.push_back(i); - - std::cout << "size: " << (int) myvector.size() << '\n'; - std::cout << "capacity: " << (int) myvector.capacity() << '\n'; - std::cout << "max_size: " << (int) myvector.max_size() << '\n'; - } - - std::cout << B_YELLOW "\n[" << ++i << "/" N_TEST "] " - << "vector::empty :" RESET "\n"; - { - std::vector myvector; - int sum (0); - - for (int i = 1; i <= 10; i++) myvector.push_back(i); - - while (!myvector.empty()) - { - sum += myvector.back(); - myvector.pop_back(); - } - - std::cout << "total: " << sum << '\n'; - } - - std::cout << B_YELLOW "\n[" << ++i << "/" N_TEST "] " - << "vector::reserve :" RESET "\n"; - { - std::vector::size_type sz; - - std::vector foo; - sz = foo.capacity(); - std::cout << "making foo grow:\n"; - for (int i=0; i<100; ++i) { - foo.push_back(i); - if (sz!=foo.capacity()) { - sz = foo.capacity(); - std::cout << "capacity changed: " << sz << '\n'; - } - } - - std::vector bar; - sz = bar.capacity(); - bar.reserve(100); // this is the only difference with foo above - std::cout << "making bar grow:\n"; - for (int i=0; i<100; ++i) { - bar.push_back(i); - if (sz!=bar.capacity()) { - sz = bar.capacity(); - std::cout << "capacity changed: " << sz << '\n'; - } - } - } - - std::cout << B_YELLOW "\n[" << ++i << "/" N_TEST "] " - << "vector::operator[] :" RESET "\n"; - { - std::vector myvector (10); // 10 zero-initialized elements - - std::vector::size_type sz = myvector.size(); - - // assign some values: - for (unsigned i=0; i myvector (10); // 10 zero-initialized ints - - // assign some values: - for (unsigned i=0; i myvector; - - myvector.push_back(78); - myvector.push_back(16); - - // now front equals 78, and back 16 - - myvector.front() -= myvector.back(); - - std::cout << "myvector.front() is now " << myvector.front() << '\n'; - } - - std::cout << B_YELLOW "\n[" << ++i << "/" N_TEST "] " - << "vector::back :" RESET "\n"; - { - std::vector myvector; - - myvector.push_back(10); - - while (myvector.back() != 0) - { - myvector.push_back ( myvector.back() -1 ); - } - - std::cout << "myvector contains:"; - for (unsigned i=0; i first; - std::vector second; - std::vector third; - - first.assign (7,100); // 7 ints with a value of 100 - - std::vector::iterator it; - it=first.begin()+1; - - second.assign (it,first.end()-1); // the 5 central values of first - - int myints[] = {1776,7,4}; - third.assign (myints,myints+3); // assigning from array. - - std::cout << "Size of first: " << int (first.size()) << '\n'; - std::cout << "Size of second: " << int (second.size()) << '\n'; - std::cout << "Size of third: " << int (third.size()) << '\n'; - } - - std::cout << B_YELLOW "\n[" << ++i << "/" N_TEST "] " - << "vector::push_back :" RESET "\n"; - { - std::vector myvector; - - // replace : - /* - int myint; - std::cout << "Please enter some integers (enter 0 to end):\n"; - do { - std::cin >> myint; - myvector.push_back (myint); - } while (myint); - */ - // with : - int myints[] = {6,546,3576,457357,7565,3,3,457,37,234,57,4672423}; - int size = sizeof(myints) / sizeof(int); - for (int i = 0; i < size; i++) - myvector.push_back(myints[i]); - - std::cout << "myvector stores " << int(myvector.size()) << " numbers.\n"; - } - - std::cout << B_YELLOW "\n[" << ++i << "/" N_TEST "] " - << "vector::pop_back :" RESET "\n"; - { - std::vector myvector; - int sum (0); - myvector.push_back (100); - myvector.push_back (200); - myvector.push_back (300); - - while (!myvector.empty()) - { - sum+=myvector.back(); - myvector.pop_back(); - } - - std::cout << "The elements of myvector add up to " << sum << '\n'; - } - - std::cout << B_YELLOW "\n[" << ++i << "/" N_TEST "] " - << "vector::insert :" RESET "\n"; - { - std::vector myvector (3,100); - std::vector::iterator it; - - it = myvector.begin(); - it = myvector.insert ( it , 200 ); - - myvector.insert (it,2,300); - - // "it" no longer valid, get a new one: - it = myvector.begin(); - - std::vector anothervector (2,400); - myvector.insert (it+2,anothervector.begin(),anothervector.end()); - - int myarray [] = { 501,502,503 }; - myvector.insert (myvector.begin(), myarray, myarray+3); - - std::cout << "myvector contains:"; - for (it=myvector.begin(); it myvector; - - // set some values (from 1 to 10) - for (int i=1; i<=10; i++) myvector.push_back(i); - - // erase the 6th element - myvector.erase (myvector.begin()+5); - - // erase the first 3 elements: - myvector.erase (myvector.begin(),myvector.begin()+3); - - std::cout << "myvector contains:"; - for (unsigned i=0; i foo (3,100); // three ints with a value of 100 - std::vector bar (5,200); // five ints with a value of 200 - - foo.swap(bar); - - std::cout << "foo contains:"; - for (unsigned i=0; i myvector; - myvector.push_back (100); - myvector.push_back (200); - myvector.push_back (300); - - std::cout << "myvector contains:"; - for (unsigned i=0; i myvector; - int * p; - unsigned int i; - - // allocate an array with space for 5 elements using vector's allocator: - p = myvector.get_allocator().allocate(5); - - // construct values in-place on the array: - for (i=0; i<5; i++) myvector.get_allocator().construct(&p[i],i); - - std::cout << "The allocated array contains:"; - for (i=0; i<5; i++) std::cout << ' ' << p[i]; - std::cout << '\n'; - - // destroy and deallocate: - for (i=0; i<5; i++) myvector.get_allocator().destroy(&p[i]); - myvector.get_allocator().deallocate(p,5); - } - - return 0; -} - - -// main 42 subject -/* - -#include -#include -#include -#if 1 //CREATE A REAL STL EXAMPLE - #include - #include - #include - namespace ft = std; -#else - #include - #include - #include -#endif - -#include - -#define MAX_RAM 4294967296 -#define BUFFER_SIZE 4096 -struct Buffer -{ - int idx; - char buff[BUFFER_SIZE]; -}; - - -#define COUNT (MAX_RAM / (int)sizeof(Buffer)) - -template -class MutantStack : public ft::stack -{ -public: - MutantStack() {} - MutantStack(const MutantStack& src) { *this = src; } - MutantStack& operator=(const MutantStack& rhs) - { - this->c = rhs.c; - return *this; - } - ~MutantStack() {} - - typedef typename ft::stack::container_type::iterator iterator; - - iterator begin() { return this->c.begin(); } - iterator end() { return this->c.end(); } -}; - -int main(int argc, char** argv) { - if (argc != 2) - { - std::cerr << "Usage: ./test seed" << std::endl; - std::cerr << "Provide a seed please" << std::endl; - std::cerr << "Count value:" << COUNT << std::endl; - return 1; - } - const int seed = atoi(argv[1]); - srand(seed); - - ft::vector vector_str; - ft::vector vector_int; - ft::stack stack_int; - ft::vector vector_buffer; - ft::stack > stack_deq_buffer; - ft::map map_int; - - for (int i = 0; i < COUNT; i++) - { - vector_buffer.push_back(Buffer()); - } - - for (int i = 0; i < COUNT; i++) - { - const int idx = rand() % COUNT; - vector_buffer[idx].idx = 5; - } - ft::vector().swap(vector_buffer); - - try - { - for (int i = 0; i < COUNT; i++) - { - const int idx = rand() % COUNT; - vector_buffer.at(idx); - std::cerr << "Error: THIS VECTOR SHOULD BE EMPTY!!" < copy = map_int; - } - MutantStack iterable_stack; - for (char letter = 'a'; letter <= 'z'; letter++) - iterable_stack.push(letter); - for (MutantStack::iterator it = iterable_stack.begin(); it != iterable_stack.end(); it++) - { - std::cout << *it; - } - std::cout << std::endl; - return (0); -} - -*/ diff --git a/templates/map.tpp b/templates/map.tpp new file mode 100644 index 0000000..ada0436 --- /dev/null +++ b/templates/map.tpp @@ -0,0 +1,587 @@ + +#define MP_TPL template < typename Key, typename T, typename Compare, typename Allocator > +#define MP map + +namespace ft { + + + /************ + * copliens : + ************/ +// constructors ------------------------------ +MP_TPL MP:: + map (const key_compare & comp, const allocator_type & alloc) + : _size(0) + , _root(NULL) + , _comp(comp) + , _allocator(alloc) { + + _sentinel = _allocator_sentinel.allocate(1); + _allocator_sentinel.construct(_sentinel, sentinel()); +} +MP_TPL template < typename InputIt > MP:: + map (InputIt first, InputIt last, const key_compare& comp, const allocator_type& alloc) + : _size(0) + , _root(NULL) + , _comp(comp) + , _allocator(alloc) { + + _sentinel = _allocator_sentinel.allocate(1); + _allocator_sentinel.construct(_sentinel, sentinel()); + insert(first, last); +} +MP_TPL MP:: + map(const map& src) + : _size(0) + , _root(NULL) + , _comp(src._comp) + , _allocator(src._allocator) { + + _sentinel = _allocator_sentinel.allocate(1); + _allocator_sentinel.construct(_sentinel, sentinel()); + *this = src; +} +// destructor -------------------------------- +MP_TPL MP:: + ~map() { + + clear(); + _allocator_sentinel.destroy(_sentinel); + _allocator_sentinel.deallocate(_sentinel, 1); +} +// operator= --------------------------------- +MP_TPL MP& MP:: + operator=(const map& rhs) { + + if (this == &rhs) + return (*this); + map new_bst(rhs.begin(), rhs.end()); + swap(new_bst); + return (*this); +} + + + /************* + * iterators : + *************/ +// begin ------------------------------------- +MP_TPL typename MP::iterator MP:: + begin() { + + if (_root) + return iterator(_root->min(), _sentinel); + else + return end(); +} +MP_TPL typename MP::const_iterator MP:: + begin() const { + + if (_root) + return const_iterator(_root->min(), _sentinel); + else + return end(); +} +// end --------------------------------------- +MP_TPL typename MP::iterator MP:: + end() { return iterator(NULL, _sentinel); } +MP_TPL typename MP::const_iterator MP:: + end() const { return const_iterator(NULL, _sentinel); } +// rbegin ------------------------------------ +MP_TPL typename MP::reverse_iterator MP:: + rbegin() { return reverse_iterator(end()); } +MP_TPL typename MP::const_reverse_iterator MP:: + rbegin() const { return const_reverse_iterator(end()); } +// rend -------------------------------------- +MP_TPL typename MP::reverse_iterator MP:: + rend() { return reverse_iterator(begin()); } +MP_TPL typename MP::const_reverse_iterator MP:: + rend() const { return const_reverse_iterator(begin()); } + + + /************ + * capacity : + ************/ +// empty ------------------------------------- +MP_TPL bool MP:: + empty() const { return (_size == 0); } +// size -------------------------------------- +MP_TPL typename MP::size_type MP:: + size() const { return (_size); } +// max_size ---------------------------------- +MP_TPL typename MP::size_type MP:: + max_size() const { return ( _allocator_node.max_size() ); } + + + /****************** + * element access : + ******************/ +// operator[] -------------------------------- +MP_TPL typename MP::mapped_type& MP:: + operator[](const Key& key) { + + node* n = _root; + + while (n) + { + if (_comp(key, n->value.first)) + n = n->left; + else if (_comp(n->value.first, key)) + n = n->right; + else + return (n->value.second); + } + + n = insert( ft::make_pair(key, mapped_type()) ).first.get_node(); + + return (n->value.second); +} + + + /************* + * modifiers : + *************/ +// insert ------------------------------------ +MP_TPL pair MP:: + insert(const value_type& value) { + + 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) { + + (void)hint; + return insert(value).first; +} +MP_TPL template < typename InputIt > void MP:: + insert(InputIt first, InputIt last) { + + for (; first != last; first++) + insert(*first); +} +// erase ------------------------------------- +// https://www.geeksforgeeks.org/binary-search-tree-set-2-delete +MP_TPL void MP:: + erase(iterator pos) { + + node* n = pos.get_node(); + node* replace = NULL; + + if (n->left && n->right) + { + replace = n->right->min(); + + replace->left = n->left; + replace->left->up = replace; + if (replace->up != n) + { + replace->up->left = replace->right; + if (replace->right != NULL) + replace->right->up = replace->up; + replace->right = n->right; + replace->right->up = replace; + } + } + else if (n->left) + replace = n->left; + else if (n->right) + replace = n->right; + else + replace = NULL; + + // share parents from n to replace + if (n == _root) + { + _root = replace; + _sentinel->child = _root; + } + else if (n == n->up->left) + n->up->left = replace; + else + n->up->right = replace; + if (replace != NULL) + replace->up = n->up; + + _allocator_node.destroy(n); + _allocator_node.deallocate(n, 1); + _size--; + + _balance(replace, ERASE); +} +MP_TPL void MP:: + erase(iterator first, iterator last) { + + while (first != last) + erase(first++); +} +MP_TPL typename MP::size_type MP:: + erase(const Key& key) { + + iterator pos; + + pos = find(key); + if (pos == end()) + return (0); + erase(pos); + return (1); +} +// swap -------------------------------------- +MP_TPL void MP:: + swap(map& other) { + + node* tmp_root = _root; + sentinel* tmp_sentinel = _sentinel; + size_type tmp_size = _size; + + _root = other._root; + _sentinel = other._sentinel; + _size = other._size; + + other._root = tmp_root; + other._sentinel = tmp_sentinel; + other._size = tmp_size; +} +// clear ------------------------------------- +MP_TPL void MP:: + clear() { erase(begin(), end()); } + + + /************* + * observers : + *************/ +// key_comp ---------------------------------- +MP_TPL typename MP::key_compare MP:: + key_comp() const { return (value_compare(_comp).comp); } +// value_comp -------------------------------- +MP_TPL typename MP::value_compare MP:: + value_comp() const { return (value_compare(_comp)); } + + + /************** + * operations : + **************/ +// find -------------------------------------- +MP_TPL typename MP::iterator MP:: + find(const Key& key) { + + node* n = _root; + + while (n) + { + if (_comp(key, n->value.first)) + n = n->left; + else if (_comp(n->value.first, key)) + n = n->right; + else + return (iterator(n, _sentinel)); + } + return (end()); +} +MP_TPL typename MP::const_iterator MP:: + find(const Key& key) const { + + node* n = _root; + + while (n) + { + if (_comp(key, n->value.first)) + n = n->left; + else if (_comp(n->value.first, key)) + n = n->right; + else + return (const_iterator(n, _sentinel)); + } + return (end()); +} +// count ------------------------------------- +MP_TPL typename MP::size_type MP:: + count(const Key& key) const { + + if (find(key) != end()) + return (1); + else + return (0); +} +// lower_bound ------------------------------- +MP_TPL typename MP::iterator MP:: + lower_bound (const key_type& k) { + + iterator it = begin(); + iterator it_end = end(); + + while (it != it_end) + { + if (_comp(it->first, k) == false) + return (it); + ++it; + } + return (it_end); +} +MP_TPL typename MP::const_iterator MP:: + lower_bound (const key_type& k) const { + + const_iterator it = begin(); + const_iterator it_end = end(); + + while (it != it_end) + { + if (_comp(it->first, k) == false) + return (it); + ++it; + } + return (it_end); +} +// upper_bound ------------------------------- +MP_TPL typename MP::iterator MP:: + upper_bound (const key_type& k) { + + iterator it = begin(); + iterator it_end = end(); + + while (it != it_end) + { + if (_comp(k, it->first)) + return (it); + ++it; + } + return (it_end); +} +MP_TPL typename MP::const_iterator MP:: + upper_bound (const key_type& k) const { + + const_iterator it = begin(); + const_iterator it_end = end(); + + while (it != it_end) + { + if (_comp(k, it->first)) + return (it); + ++it; + } + return (it_end); +} +// equal_range ------------------------------- +MP_TPL pair MP:: + equal_range (const key_type& k) const { + + return ft::make_pair( lower_bound(k), upper_bound(k) ); +} +MP_TPL pair MP:: + equal_range (const key_type& k) { + + return ft::make_pair( lower_bound(k), upper_bound(k) ); +} + + + /************* + * allocator : + *************/ +// get_allocator ----------------------------- +MP_TPL typename MP::allocator_type MP:: + get_allocator() const { return (_allocator); } + + + /********************* + * private functions : + *********************/ +MP_TPL void MP:: + _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 (BF == -1) + 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 (BF == 1) + 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; + 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) { + + if (n->left && n->right) + return std::max(n->left->height, n->right->height) + 1; + else if (n->left) + return n->left->height + 1; + else if (n->right) + return n->right->height + 1; + else + return 1; +} +MP_TPL short MP:: + _balance_factor(node* n) { + + if (n->left && n->right) + return n->left->height - n->right->height; + else if (n->left) + return n->left->height; + else if (n->right) + return (-(n->right->height)); + else + return 0; +} +MP_TPL node* MP:: + _rotate_left(node* n) { + + node* ori_right = n->right; + + ori_right->up = n->up; + n->up = ori_right; + + n->right = ori_right->left; + if (n->right != NULL) + n->right->up = n; + ori_right->left = n; + + n->height = _compute_height(n); + ori_right->height = _compute_height(ori_right); + + if (n == _root) + { + _root = ori_right; + _sentinel->child = _root; + } + + return ori_right; +} +MP_TPL node* MP:: + _rotate_right(node* n) { + + node* ori_left = n->left; + + ori_left->up = n->up; + n->up = ori_left; + + n->left = ori_left->right; + if (n->left != NULL) + n->left->up = n; + ori_left->right = n; + + n->height = _compute_height(n); + ori_left->height = _compute_height(ori_left); + + if (n == _root) + { + _root = ori_left; + _sentinel->child = _root; + } + + return ori_left; +} + + + /************************ + * non-member functions : + ************************/ +// operator == ------------------------------- +MP_TPL bool operator== (const MP& lhs, const MP& rhs) { + + if (lhs.size() != rhs.size()) + return false; + return ft::equal(lhs.begin(), lhs.end(), rhs.begin()); +} +// operator < -------------------------------- +MP_TPL bool operator< (const MP& lhs, const MP& rhs) { + + return ft::lexicographical_compare( + lhs.begin(), + lhs.end(), + rhs.begin(), + rhs.end() + ); +} +// operator != ------------------------------- +MP_TPL bool operator!= (const MP& lhs, const MP& rhs) { + return !(lhs == rhs); } +// operator <= ------------------------------- +MP_TPL bool operator<= (const MP& lhs, const MP& rhs) { + return !(lhs > rhs); } +// operator > -------------------------------- +MP_TPL bool operator> (const MP& lhs, const MP& rhs) { + return (rhs < lhs); } +// operator >= ------------------------------- +MP_TPL bool operator>= (const MP& lhs, const MP& rhs) { + return !(lhs < rhs); } +// swap (map) ----------------------------- +MP_TPL void swap(MP& lhs, MP& rhs) { + lhs.swap(rhs); } + + +} // namespace ft + +#undef MP +#undef MP_TPL + diff --git a/templates/stack.tpp b/templates/stack.tpp new file mode 100644 index 0000000..640d8dc --- /dev/null +++ b/templates/stack.tpp @@ -0,0 +1,72 @@ + +#define ST_TPL template +#define ST stack + +namespace ft { + + + /************ + * copliens : + ************/ +// constructors ------------------------------ +ST_TPL ST:: + stack(const container_type& cont) + : c(cont) {} + + + /********************** + * overload functions : + **********************/ +// empty ------------------------------------- +ST_TPL bool ST:: + empty() const { return c.empty(); } +// size -------------------------------------- +ST_TPL typename ST::size_type ST:: + size() const { return c.size(); } +// top --------------------------------------- +ST_TPL typename ST::value_type& ST:: + top() { return c.back(); } +ST_TPL const typename ST::value_type& ST:: + top() const { return c.back(); } +// push -------------------------------------- +ST_TPL void ST:: + push(const value_type& value) { c.push_back(value); } +// pop --------------------------------------- +ST_TPL void ST:: + pop() { c.pop_back(); } + + + /************************ + * non-member functions : + ************************/ +// operator == ------------------------------- +ST_TPL bool + operator==(const stack& lhs, const stack& rhs) + { return lhs.c == rhs.c; } +// operator != ------------------------------- +ST_TPL bool + operator!=(const stack& lhs, const stack& rhs) + { return lhs.c != rhs.c; } +// operator < -------------------------------- +ST_TPL bool + operator<(const stack& lhs, const stack& rhs) + { return lhs.c < rhs.c; } +// operator > -------------------------------- +ST_TPL bool + operator>(const stack& lhs, const stack& rhs) + { return lhs.c > rhs.c; } +// operator <= ------------------------------- +ST_TPL bool + operator<=(const stack& lhs, const stack& rhs) + { return lhs.c <= rhs.c; } +// operator >= ------------------------------- +ST_TPL bool + operator>=(const stack& lhs, const stack& rhs) + { return lhs.c >= rhs.c; } + + +} // namespace ft + +#undef VT +#undef VT_TPL + diff --git a/templates/vector.tpp b/templates/vector.tpp new file mode 100644 index 0000000..8716c93 --- /dev/null +++ b/templates/vector.tpp @@ -0,0 +1,497 @@ + +#define VT_TPL template +#define VT vector + +namespace ft { + + +/********************************************* + * COPLIENS + *********************************************/ +// constructors ------------------------------ +VT_TPL VT:: + 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) { + + 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) { + + assign(first, last); + return; +} +// copy constructor -------------------------- +VT_TPL VT:: + vector( vector const & src ) + : _size(0) + , _capacity(0) + , _mem_ptr(NULL) + , _allocator(src._allocator) { + + *this = src; + return; +} +// destructors ------------------------------- +VT_TPL VT:: + ~vector() { + + clear(); + _allocator.deallocate(_mem_ptr, _capacity); + return; +} +// operator= --------------------------------- +VT_TPL VT & VT:: + operator=( vector const & rhs ) { + + vector new_vector; + + if ( this != &rhs ) + { + new_vector.reserve(_capacity); + new_vector.assign(rhs.begin(), rhs.end()); + swap(new_vector); + } + return *this; +} + + + +/************* + * iterators : + *************/ +// begin ------------------------------------- +VT_TPL typename VT::iterator VT:: + begin() { return _mem_ptr; } +VT_TPL typename VT::const_iterator VT:: + begin() const { return _mem_ptr; } +// end --------------------------------------- +VT_TPL typename VT::iterator VT:: + end() { return &_mem_ptr[_size]; } +VT_TPL typename VT::const_iterator VT:: + end() const { return &_mem_ptr[_size]; } +// rbegin ------------------------------------ +VT_TPL typename VT::reverse_iterator VT:: + rbegin() { return reverse_iterator(end()); } +VT_TPL typename VT::const_reverse_iterator VT:: + rbegin() const { return const_reverse_iterator(end()); } +// rend -------------------------------------- +VT_TPL typename VT::reverse_iterator VT:: + rend() { return reverse_iterator(begin()); } +VT_TPL typename VT::const_reverse_iterator VT:: + rend() const { return const_reverse_iterator(begin()); } + + + +/************ + * capacity : + ************/ +// size -------------------------------------- +VT_TPL typename VT::size_type VT:: + size( ) const { return _size; } +// max_size ---------------------------------- +VT_TPL typename VT::size_type VT:: + max_size() const { return (_allocator.max_size()); } +// resize ------------------------------------ +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; } +// empty ------------------------------------- +VT_TPL bool VT:: + empty() const { return (_size == 0); } +// reserve ----------------------------------- +VT_TPL void VT:: + reserve( size_type new_cap ) { + + value_type * tmp_ptr; + value_type * old_ptr = _mem_ptr; + iterator first = begin(); + iterator last = end(); + + if (new_cap > _allocator.max_size()) + throw std::length_error("reserve: new_cap > max_size"); + if (_capacity == _allocator.max_size()) + throw std::length_error("reserve: capacity == max_size"); + if (new_cap <= _capacity) + return ; + + _capacity = new_cap; + tmp_ptr = _allocator.allocate(new_cap); + + _mem_ptr = tmp_ptr; + if (old_ptr) + { + _size = 0; + assign(first, last); + _destroy(begin(), end()); + _allocator.deallocate(old_ptr, _capacity); + } +} + + + +/****************** + * element access : + ******************/ +// operator[] -------------------------------- +VT_TPL typename VT::reference VT:: + 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 ---------------------------------------- +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 ------------------------------------- +VT_TPL typename VT::reference VT:: + front() { return (*_mem_ptr); } +VT_TPL typename VT::const_reference VT:: + front() const { return (*_mem_ptr); } +// back -------------------------------------- +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 : + *************/ +// assign ------------------------------------ +VT_TPL template +typename enable_if< !is_integral::value,void >::type VT:: + assign( InputIterator first, InputIterator last) { + + InputIterator tmp = first; + unsigned int range = 0; + + clear(); + + while (tmp++ != last) + range++; + if (range >= _capacity) + _increment_capacity(range); + while (first != last) + { + _allocator.construct(&_mem_ptr[_size], *first); + first++; + _size++; + } +} +VT_TPL void VT:: + assign( size_type n, const T & val ) { + + if (n > _allocator.max_size()) + throw std::length_error("assign: n > max_size"); + + value_type * tmp_ptr; + + _destroy(begin(), end()); + if (n > _capacity) + { + _capacity = n; + tmp_ptr = _allocator.allocate(n); + if (_mem_ptr) + _allocator.deallocate(_mem_ptr, _capacity); + _mem_ptr = tmp_ptr; + } + _size = n; + while (n) + _allocator.construct(&_mem_ptr[--n], val); +} +// push_back --------------------------------- +VT_TPL void VT:: + push_back( const value_type & element ) { + + if (_size >= _capacity) + _increment_capacity(1); + _allocator.construct(&_mem_ptr[_size], element); + _size++; +} +// pop_back ---------------------------------- +VT_TPL void VT:: + pop_back() { _allocator.destroy(end() - 1); _size--; } +// insert ------------------------------------ +VT_TPL typename VT::iterator VT:: + insert(iterator position, const value_type& val) { + + difference_type distance; + iterator it; + + if (_size + 1 > _capacity) + { + distance = position - begin(); + _increment_capacity(1); + position = begin() + distance; + } + it = end(); + if (position != it) + { + _allocator.construct(it, *(it - 1)); + while (it-- != position) + *(it + 1) = *it; + _allocator.destroy(position); + } + _allocator.construct(position, val); + _size++; + return (position); +} +VT_TPL void VT:: + insert(iterator position, size_type n, const value_type& val) { + + difference_type distance; + iterator it_end; + iterator it; + + if (_size + n > _capacity) + { + distance = position - begin(); + _increment_capacity(n); + position = begin() + distance; + } + + it_end = end(); + if (position != it_end) + { + it = it_end; + while (it + n != it_end && it != position) + { + it--; + _allocator.construct(it + n, *it); + } + while (it != position) + { + it--; + *(it + n) = *it; + } + _destroy(position, std::min(position + n, it_end)); + } + + for (size_type i = 0; i < n; i++, position++) + _allocator.construct(position, val); + _size += n; +} +VT_TPL template +typename enable_if< !is_integral::value,void >::type VT:: + insert(iterator position, InputIterator first, InputIterator last) { + + difference_type dist; + difference_type n; + iterator it_end; + iterator it; + + n = std::distance(first, last); + if (_size + n > _capacity) + { + dist = position - begin(); + _increment_capacity(n); + position = begin() + dist; + } + + it_end = end(); + if (position != it_end) + { + it = it_end; + while (it + n != it_end && it != position) + { + it--; + _allocator.construct(it + n, *it); + } + while (it != position) + { + it--; + *(it + n) = *it; + } + _destroy(position, std::min(position + n, it_end)); + } + + while (first != last) + { + _allocator.construct(position, *first); + ++position; + ++first; + } + + _size += n; +} +// erase ------------------------------------- +VT_TPL typename VT::iterator VT:: + erase(iterator position) { + + iterator i = position; + iterator it_end = end() - 1; + + while (i != it_end) + { + *i = *(i + 1); + ++i; + } + _allocator.destroy(it_end); + _size -= 1; + return (position); +} +VT_TPL typename VT::iterator VT:: + erase(iterator first, iterator last) { + + iterator it_end = end(); + difference_type diff = std::distance(first, last); + + if (diff <= 0) + return (first); + + it_end = end(); + while (last != it_end) + { + *first = *last; + first++; + last++; + } + _destroy(it_end - diff, it_end); + _size -= diff; + + return (first); +} +// swap -------------------------------------- +VT_TPL void VT:: + swap(vector& x) { + + T* tmp_mem_ptr; + size_type tmp_size; + size_type tmp_capacity; + + tmp_mem_ptr = x._mem_ptr; + tmp_size = x._size; + tmp_capacity = x._capacity; + + x._mem_ptr = _mem_ptr; + x._size = _size; + x._capacity = _capacity; + + _mem_ptr = tmp_mem_ptr; + _size = tmp_size; + _capacity = tmp_capacity; +} +// clear ------------------------------------- +VT_TPL void VT:: + clear() { _destroy(begin(), end()); _size = 0; } + + + +/************* + * allocator : + *************/ +// get_allocator ----------------------------- +VT_TPL typename VT::allocator_type VT:: + get_allocator() const { return (_allocator); } + + + +/********************************************* + * PRIVATE MEMBER FUNCTIONS + *********************************************/ +VT_TPL void VT:: + _destroy(iterator first, iterator last) { + + while (first != last) + { + _allocator.destroy(first); + first++; + } +} +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())); +} + + + +/************************ + * non-member functions : + ************************/ +// operator == ------------------------------- +VT_TPL bool + operator== (const VT & lhs, const VT & rhs) { + + if (lhs.size() != rhs.size()) + return false; + return ft::equal(lhs.begin(), lhs.end(), rhs.begin()); +} +// operator < -------------------------------- +VT_TPL bool + operator< (const VT & lhs, const VT & rhs) { + + return ft::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end()); +} +// operator != ------------------------------- +VT_TPL bool + operator!= (const VT & lhs, const VT & rhs) { return !(lhs == rhs); } +// operator <= ------------------------------- +VT_TPL bool + operator<= (const VT & lhs, const VT & rhs) { return !(lhs > rhs); } +// operator > -------------------------------- +VT_TPL bool + operator> (const VT & lhs, const VT & rhs) { return (rhs < lhs); } +// operator >= ------------------------------- +VT_TPL bool + operator>= (const VT & lhs, const VT & rhs) { return !(lhs < rhs); } +// swap (vector) ------------------------------- +VT_TPL void + swap (VT & lhs, VT & rhs) { lhs.swap(rhs); } + +} // namespace ft + +#undef VT +#undef VT_TPL + diff --git a/tests/includes/main.hpp b/tests/includes/main.hpp new file mode 100644 index 0000000..bfb3bf0 --- /dev/null +++ b/tests/includes/main.hpp @@ -0,0 +1,84 @@ +#ifndef MAIN_HPP +# define MAIN_HPP + +#include "colors.h" +#include +#include +#include // std::setw() +#include + +#include "tests_structs.hpp" + + +// global variables +// *************************************** +std::vector< std::vector > test_list; +std::vector< mystruct* > mem_list; + + +// prototypes +// ********************************************* +// vectors +void tests_vector_constructor(); +void tests_vector_operator_assignation(); +void tests_vector_begin(); +void tests_vector_end(); +void tests_vector_rbegin(); +void tests_vector_rend(); +void tests_vector_size(); +void tests_vector_max_size(); +void tests_vector_resize(); +void tests_vector_capacity(); +void tests_vector_empty(); +void tests_vector_reserve(); +void tests_vector_operator_access(); +void tests_vector_at(); +void tests_vector_front(); +void tests_vector_back(); +void tests_vector_assign(); +void tests_vector_push_back(); +void tests_vector_pop_back(); +void tests_vector_insert(); +void tests_vector_erase(); +void tests_vector_swap(); +void tests_vector_clear(); +void tests_vector_get_allocator(); +void tests_vector_relational_operators(); +void tests_vector_swap_non_member(); +void tests_vector_reverse_iterators(); +// map +void tests_map_simple(); +void tests_map_constructor(); +void tests_map_operator_assignation(); +void tests_map_begin(); +void tests_map_end(); +void tests_map_rbegin(); +void tests_map_rend(); +void tests_map_empty(); +void tests_map_size(); +void tests_map_max_size(); +void tests_map_operator_access(); +void tests_map_insert(); +void tests_map_erase(); +void tests_map_swap(); +void tests_map_clear(); +void tests_map_key_comp(); +void tests_map_value_comp(); +void tests_map_find(); +void tests_map_count(); +void tests_map_lower_bound(); +void tests_map_upper_bound(); +void tests_map_equal_range(); +void tests_map_get_allocator(); +void tests_map_relational_operators(); +void tests_map_swap_non_member(); +// stack +void tests_stack_constructor(); +void tests_stack_empty(); +void tests_stack_size(); +void tests_stack_top(); +void tests_stack_push(); +void tests_stack_pop(); + +#endif + 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 new file mode 100644 index 0000000..446bd28 --- /dev/null +++ b/tests/includes/tests_utils.hpp @@ -0,0 +1,159 @@ + +#ifndef TESTS_UTILS_HPP +# define TESTS_UTILS_HPP + + +#include "colors.h" +#include +#include +#include // std::setw() +#include // std::reverse_iterator +#include // std::make_pair +#include // std::stringstream +#include +#include +#include +#include + +#include "tests_structs.hpp" + + +// defines +// **************************************** +# define TITLE(s) std::cout << "\n" B_PURPLE #s RESET "\n\n"; +# define VAL(n) val(n) +# define VALT(n) val(n) +# define VALU(n) val(n) +# define TOI(n) toi(n) +# define PRINT(n) print<>(n, #n); +# define DELETE delete_structs(); + + +// prototypes +// ********************************************* +void add_to_list(std::string title, std::string type, A_test* test); +void delete_structs(); + + +// global variables +// *************************************** +extern std::vector< std::vector > test_list; +extern std::vector< mystruct* > mem_list; + + +// adding each test to the list +// *************************** +#define TEST(f_name) TEST_V(f_name) + +/* +*/ + +#define TEST_V(f_name) \ + template struct s_ ## f_name : public A_test\ + { void func(); };\ + void f_name () {\ + add_to_list("", "", NULL);\ + add_to_list(#f_name, "int", new(s_ ## f_name ));\ + add_to_list(#f_name, "char", new(s_ ## f_name ));\ + add_to_list(#f_name, "std::string", new(s_ ## f_name ));\ + add_to_list(#f_name, "mystruct*", new(s_ ## f_name ));\ + }\ + template \ + void s_ ## f_name ::func() + +#define TEST_M(f_name) \ + template struct s_ ## f_name : public A_test\ + { void func(); };\ + void f_name () {\ + add_to_list("", "", NULL);\ + add_to_list(#f_name, "char, int", new(s_ ## f_name ));\ + add_to_list(#f_name, "char, char", new(s_ ## f_name ));\ + add_to_list(#f_name, "char, std::string", new(s_ ## f_name ));\ + add_to_list(#f_name, "int, int", new(s_ ## f_name ));\ + add_to_list(#f_name, "int, char", new(s_ ## f_name ));\ + add_to_list(#f_name, "int, std::string", new(s_ ## f_name ));\ + }\ + template \ + void s_ ## f_name ::func() +/* + add_to_list(#f_name, "char, mystruct*", new(s_ ## f_name ));\ + add_to_list(#f_name, "int, mystruct*", new(s_ ## f_name ));\ +*/ + + +// templates get value +// ************************************* +// specialization in header, make it inline : +// https://stackoverflow.com/questions/63529059/c-specialized-method-templates-produce-multiple-definition-errors +template + T val(int n) { (void)n; return (T()); } +template <> + inline int val(int n) { return (n); } +template <> + inline char val(int n) { + + if (n <= 126 && n >= 33) + return n; + return (n % 94 + 33); +} +template <> + inline std::string val(int n) { + + std::string str; + std::stringstream stream; + + stream << n; + stream >> str; + stream.clear(); + return (str); +} +template <> + inline mystruct* val(int n) { + + mystruct *s = new mystruct(n); + mem_list.push_back(s); + return ( s ); +} +template + T val(std::string str) { (void)str; return (T()); } +template <> + inline int val(std::string str) { int i = str[0]; return (val(i)); } +template <> + inline char val(std::string str) { int i = str[0]; return (val(i)); } +template <> + inline std::string val(std::string str) { return (str); } +template <> + inline mystruct* val(std::string str) { int i = str[0]; return (val(i)); } + + +// templates to value +// ************************************** +template + int toi(T t) {(void)t; return (0); +} +template <> + inline int toi(int i) {return (i); +} +template <> + inline int toi(char c) {return (c); +} +template <> + inline int toi(std::string str) { + + int i; + std::stringstream stream; + + stream << str; + stream >> i; + stream.clear(); + return (i); +} +template <> + inline int toi(mystruct* s) { + + return ( s->get_data()[0] ); +} + + +#endif + 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 new file mode 100644 index 0000000..ac6c4c4 --- /dev/null +++ b/tests/main.cpp @@ -0,0 +1,90 @@ + +#include "main.hpp" + +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(); + + // 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_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(); + + // STACK + 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(); + int sub_size; + for(int i = 0; i < size; i++) + { + std::cout << "\n" B_YELLOW "[" << i + 1 << "/" << size << "] " + << test_list[i][0]->title << RESET << "\n"; + sub_size = test_list[i].size(); + for (int j = 0; j < sub_size; j++) + { + std::cout << "\n" << B_CYAN << "-- " << test_list[i][j]->type + << " --" << RESET "\n"; + test_list[i][j]->func(); + delete test_list[i][j]; + } + } + std::cout << "\n"; + + return 0; +} + diff --git a/tests/other_mains/main42.cpp b/tests/other_mains/main42.cpp new file mode 100644 index 0000000..5d31ace --- /dev/null +++ b/tests/other_mains/main42.cpp @@ -0,0 +1,118 @@ + +#include +#include +#include +#if 1 //CREATE A REAL STL EXAMPLE + #include + #include + #include + namespace ft = std; +#else + #include + #include + #include +#endif + +#include + +#define MAX_RAM 4294967296 +#define BUFFER_SIZE 4096 +struct Buffer +{ + int idx; + char buff[BUFFER_SIZE]; +}; + + +#define COUNT (MAX_RAM / (int)sizeof(Buffer)) + +template +class MutantStack : public ft::stack +{ +public: + MutantStack() {} + MutantStack(const MutantStack& src) { *this = src; } + MutantStack& operator=(const MutantStack& rhs) + { + this->c = rhs.c; + return *this; + } + ~MutantStack() {} + + typedef typename ft::stack::container_type::iterator iterator; + + iterator begin() { return this->c.begin(); } + iterator end() { return this->c.end(); } +}; + +int main(int argc, char** argv) { + if (argc != 2) + { + std::cerr << "Usage: ./test seed" << std::endl; + std::cerr << "Provide a seed please" << std::endl; + std::cerr << "Count value:" << COUNT << std::endl; + return 1; + } + const int seed = atoi(argv[1]); + srand(seed); + + ft::vector vector_str; + ft::vector vector_int; + ft::stack stack_int; + ft::vector vector_buffer; + ft::stack > stack_deq_buffer; + ft::map map_int; + + for (int i = 0; i < COUNT; i++) + { + vector_buffer.push_back(Buffer()); + } + + for (int i = 0; i < COUNT; i++) + { + const int idx = rand() % COUNT; + vector_buffer[idx].idx = 5; + } + ft::vector().swap(vector_buffer); + + try + { + for (int i = 0; i < COUNT; i++) + { + const int idx = rand() % COUNT; + vector_buffer.at(idx); + std::cerr << "Error: THIS VECTOR SHOULD BE EMPTY!!" < copy = map_int; + } + MutantStack iterable_stack; + for (char letter = 'a'; letter <= 'z'; letter++) + iterable_stack.push(letter); + for (MutantStack::iterator it = iterable_stack.begin(); it != iterable_stack.end(); it++) + { + std::cout << *it; + } + std::cout << std::endl; + return (0); +} + diff --git a/tests/other_mains/main_map_1.cpp b/tests/other_mains/main_map_1.cpp new file mode 100644 index 0000000..6d4019a --- /dev/null +++ b/tests/other_mains/main_map_1.cpp @@ -0,0 +1,741 @@ + +#include +#include +#include // std::setw() +#include // std::reverse_iterator +#include // std::make_pair +#include // std::stringstream +#include +#include + +// toogle ft in stl +#ifdef STL + namespace ft = std; +#else + #include "map.hpp" + #include "reverse_iterator.hpp" +#endif + +// defines +# define TEST_M(s) template void s () +# define TITLE(s) std::cout << "\n" B_PURPLE #s RESET "\n\n"; +# define VALT(n) val(n) +# define VALU(n) val(n) +# define TOI(n) toi(n) +# define PRINT(n) print<>(n, #n); +# define DELETE delete_structs(); + +// colors +# define GRAY "\e[0;30m" +# define RED "\e[0;31m" +# define GREEN "\e[0;32m" +# define YELLOW "\e[0;33m" +# define BLUE "\e[0;34m" +# define PURPLE "\e[0;35m" +# define CYAN "\e[0;36m" +# define WHITE "\e[0;37m" + +# define B_GRAY "\e[1;30m" +# define B_RED "\e[1;31m" +# define B_GREEN "\e[1;32m" +# define B_YELLOW "\e[1;33m" +# define B_BLUE "\e[1;34m" +# define B_PURPLE "\e[1;35m" +# define B_CYAN "\e[1;36m" +# define B_WHITE "\e[1;37m" + +# define RESET "\e[0m" + +// mystruct declaration +struct mystruct { +public: + mystruct(int data = 0); + ~mystruct(); + int * get_data() const; +private: + int * _val; +}; +std::ostream & operator<<(std::ostream & o, mystruct const * rhs); + +// mystruct definition +mystruct::mystruct(int data) + {_val = new int[2]; _val[0] = data; _val[1] = data;} +mystruct::~mystruct() + {delete[] _val;} +int * mystruct::get_data() const + {return _val;} +std::ostream & operator<<(std::ostream & o, mystruct const * rhs) { + if (rhs != NULL) + o << (*rhs).get_data()[0] << "," << (*rhs).get_data()[1]; + else + o << "NULL"; + return (o); +} + +// global variable for mem gestion of mystruct +std::vector< mystruct* > mem_list; + +// template print function +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 val() for instanciation of values for types : +// int, char, std::string, and mystruct* +template + T val(int n) { (void)n; return (T()); } +template <> + inline int val(int n) { return (n); } +template <> + inline char val(int n) { + + if (n <= 126 && n >= 33) + return n; + return (n % 94 + 33); +} +template <> + inline std::string val(int n) { + + std::string str; + std::stringstream stream; + + stream << n; + stream >> str; + stream.clear(); + return (str); +} +template <> + inline mystruct* val(int n) { + + mystruct *s = new mystruct(n); + mem_list.push_back(s); + return ( s ); +} +template + T val(std::string str) { (void)str; return (T()); } +template <> + inline int val(std::string str) { int i = str[0]; return (val(i)); } +template <> + inline char val(std::string str) { int i = str[0]; return (val(i)); } +template <> + inline std::string val(std::string str) { return (str); } +template <> + inline mystruct* val(std::string str) { int i = str[0]; return (val(i)); } + +// delete function for mem gestion of mystruct* +void delete_structs() { + + std::vector::iterator it; + std::vector::iterator it_end = mem_list.end(); + + for (it = mem_list.begin(); it != it_end; ++it) + delete *it; + mem_list.clear(); +} + +// all tests +TEST_M(tests_map_operator_assignation) +{ + // title + TITLE(cplusplus.com reference) + + ft::map first; + ft::map second; + + first[VALT('x')]=VALU(8); + first[VALT('y')]=VALU(16); + first[VALT('z')]=VALU(32); + + PRINT(first) + PRINT(second) + + second=first; // second now contains 3 ints + first=ft::map(); // and first is now empty + + std::cout << "Size of first: " << first.size() << '\n'; + std::cout << "Size of second: " << second.size() << '\n'; + + PRINT(first) + PRINT(second) + + DELETE +} + +TEST_M(tests_map_begin) +{ + // title + TITLE(cplusplus.com reference) + + ft::map mymap; + + mymap[VALT('b')] = VALU(100); + mymap[VALT('a')] = VALU(200); + mymap[VALT('c')] = VALU(300); + + PRINT(mymap) + + DELETE +} + +TEST_M(tests_map_end) +{ + // title + TITLE(cplusplus.com reference) + + ft::map mymap; + + mymap[VALT('b')] = VALU(100); + mymap[VALT('a')] = VALU(200); + mymap[VALT('c')] = VALU(300); + + PRINT(mymap) + + DELETE +} + +TEST_M(tests_map_rbegin) +{ + // title + TITLE(cplusplus.com reference) + + ft::map mymap; + + mymap[VALT('x')] = VALU(100); + mymap[VALT('y')] = VALU(200); + mymap[VALT('z')] = VALU(300); + + // show content: + typename ft::map::reverse_iterator rit; + for (rit=mymap.rbegin(); rit!=mymap.rend(); ++rit) + std::cout << rit->first << " => " << rit->second << '\n'; + + DELETE +} + +TEST_M(tests_map_rend) +{ + // title + TITLE(cplusplus.com reference) + + ft::map mymap; + + mymap[VALT('x')] = VALU(100); + mymap[VALT('y')] = VALU(200); + mymap[VALT('z')] = VALU(300); + + // show content: + typename ft::map::reverse_iterator rit; + for (rit=mymap.rbegin(); rit!=mymap.rend(); ++rit) + std::cout << rit->first << " => " << rit->second << '\n'; + + DELETE +} + +TEST_M(tests_map_empty) +{ + // title + TITLE(cplusplus.com reference) + + ft::map mymap; + + mymap[VALT('a')]=VALU(10); + mymap[VALT('b')]=VALU(20); + mymap[VALT('c')]=VALU(30); + + while (!mymap.empty()) + { + std::cout << mymap.begin()->first << " => " << mymap.begin()->second << '\n'; + mymap.erase(mymap.begin()); + } + + DELETE +} + +TEST_M(tests_map_size) +{ + // title + TITLE(cplusplus.com reference) + + ft::map mymap; + mymap[VALT('a')]=VALU(101); + mymap[VALT('b')]=VALU(202); + mymap[VALT('c')]=VALU(302); + + std::cout << "mymap.size() is " << mymap.size() << '\n'; + + PRINT(mymap) + + DELETE +} + +TEST_M(tests_map_max_size) +{ + // title + TITLE(cplusplus.com reference) + + int i; + std::map mymap; + + if (mymap.max_size()>1000) + { + for (i=0; i<1000; i++) mymap[i]=VALU(0); + std::cout << "The map contains 1000 elements.\n"; + } + else std::cout << "The map could not hold 1000 elements.\n"; + + DELETE +} + +TEST_M(tests_map_operator_access) +{ + // title + TITLE(cplusplus.com reference) + + ft::map mymap; + + mymap[VALT('a')]=VALU("An element"); + mymap[VALT('b')]=VALU("another element"); + mymap[VALT('c')]=mymap[VALT('b')]; + + std::cout << "mymap['a'] is " << mymap[VALT('a')] << '\n'; + std::cout << "mymap['b'] is " << mymap[VALT('b')] << '\n'; + std::cout << "mymap['c'] is " << mymap[VALT('c')] << '\n'; + std::cout << "mymap['d'] is " << mymap[VALT('d')] << '\n'; + + std::cout << "mymap now contains " << mymap.size() << " elements.\n"; + + DELETE +} + +TEST_M(tests_map_insert) +{ + // title + TITLE(cplusplus.com reference) + + ft::map mymap; + + // first insert function version (single parameter): + mymap.insert ( ft::pair(VALT('a'),VALU(100)) ); + mymap.insert ( ft::pair(VALT('z'),VALU(200)) ); + + ft::pair::iterator, bool> ret; + ret = mymap.insert ( ft::pair(VALT('z'),VALU(500)) ); + if (ret.second==false) { + std::cout << "element 'z' already existed"; + std::cout << " with a value of " << ret.first->second << '\n'; + } + + + // second insert function version (with hint position): + typename ft::map::iterator it = mymap.begin(); + mymap.insert (it, ft::pair(VALT('b'),VALU(300))); // max efficiency inserting + mymap.insert (it, ft::pair(VALT('c'),VALU(400))); // no max efficiency inserting + + // third insert function version (range insertion): + ft::map anothermap; + anothermap.insert(mymap.begin(),mymap.find('c')); + + PRINT(mymap) + PRINT(anothermap) + + DELETE +} + +TEST_M(tests_map_erase) +{ + // title + TITLE(cplusplus.com reference) + + ft::map mymap; + typename ft::map::iterator it; + + // insert some values: + mymap[VALT('a')]=VALU(10); + mymap[VALT('b')]=VALU(20); + mymap[VALT('c')]=VALU(30); + mymap[VALT('d')]=VALU(40); + mymap[VALT('e')]=VALU(50); + mymap[VALT('f')]=VALU(60); + + it=mymap.find(VALT('b')); + mymap.erase (it); // erasing by iterator + + mymap.erase (VALT('c')); // erasing by key + + it=mymap.find (VALT('e')); + mymap.erase ( it, mymap.end() ); // erasing by range + + PRINT(mymap) + + DELETE +} + +TEST_M(tests_map_swap) +{ + // title + TITLE(cplusplus.com reference) + + ft::map foo,bar; + + foo[VALT('x')]=VALU(100); + foo[VALT('y')]=VALU(200); + + bar[VALT('a')]=VALU(11); + bar[VALT('b')]=VALU(22); + bar[VALT('c')]=VALU(33); + + foo.swap(bar); + + PRINT(foo) + PRINT(bar) + + DELETE +} + +TEST_M(tests_map_clear) +{ + // title + TITLE(cplusplus.com reference) + + ft::map mymap; + + mymap[VALT('x')]=VALU(100); + mymap[VALT('y')]=VALU(200); + mymap[VALT('z')]=VALU(300); + + PRINT(mymap) + + mymap.clear(); + mymap[VALT('a')]=VALU(1101); + mymap[VALT('b')]=VALU(2202); + + PRINT(mymap) + + DELETE +} + +TEST_M(tests_map_key_comp) +{ + // title + TITLE(cplusplus.com reference) + + ft::map mymap; + + typename ft::map::key_compare mycomp = mymap.key_comp(); + + mymap[VALT('a')]=VALU(100); + mymap[VALT('b')]=VALU(200); + mymap[VALT('c')]=VALU(300); + + std::cout << "mymap contains:\n"; + + T highest = mymap.rbegin()->first; // key value of last element + + typename ft::map::iterator it = mymap.begin(); + do { + std::cout << it->first << " => " << it->second << '\n'; + } while ( mycomp((*it++).first, highest) ); + + std::cout << '\n'; + + DELETE +} + +TEST_M(tests_map_value_comp) +{ + // title + TITLE(cplusplus.com reference) + + ft::map mymap; + + mymap[VALT('x')]=VALU(1001); + mymap[VALT('y')]=VALU(2002); + mymap[VALT('z')]=VALU(3003); + + std::cout << "mymap contains:\n"; + + ft::pair highest = *mymap.rbegin(); // last element + + typename ft::map::iterator it = mymap.begin(); + do { + std::cout << it->first << " => " << it->second << '\n'; + } while ( mymap.value_comp()(*it++, highest) ); + + DELETE +} + +TEST_M(tests_map_find) +{ + // title + TITLE(cplusplus.com reference) + + ft::map mymap; + typename ft::map::iterator it; + + mymap[VALT('a')]=VALU(50); + mymap[VALT('b')]=VALU(100); + mymap[VALT('c')]=VALU(150); + mymap[VALT('d')]=VALU(200); + + it = mymap.find(VALT('b')); + if (it != mymap.end()) + mymap.erase (it); + + // print content: + std::cout << "elements in mymap:" << '\n'; + std::cout << "a => " << mymap.find(VALT('a'))->second << '\n'; + std::cout << "c => " << mymap.find(VALT('c'))->second << '\n'; + std::cout << "d => " << mymap.find(VALT('d'))->second << '\n'; + + DELETE +} + +TEST_M(tests_map_count) +{ + // title + TITLE(cplusplus.com reference) + + ft::map mymap; + T c; + + mymap [VALT('a')]=VALU(101); + mymap [VALT('c')]=VALU(202); + mymap [VALT('f')]=VALU(303); + + // to do this test with T as a 'string' or 'mystruct*' we should add overload + for (c=VALT('a'); c0) + std::cout << " is an element of mymap.\n"; + else + std::cout << " is not an element of mymap.\n"; + } + + DELETE +} + +TEST_M(tests_map_lower_bound) +{ + // title + TITLE(cplusplus.com reference) + + ft::map mymap; + typename ft::map::iterator itlow,itup; + + mymap[VALT('a')]=VALU(20); + mymap[VALT('b')]=VALU(40); + mymap[VALT('c')]=VALU(60); + mymap[VALT('d')]=VALU(80); + mymap[VALT('e')]=VALU(100); + + itlow=mymap.lower_bound (VALT('b')); // itlow points to b + itup=mymap.upper_bound (VALT('d')); // itup points to e (not d!) + + mymap.erase(itlow,itup); // erases [itlow,itup) + + PRINT(mymap) + + DELETE +} + +TEST_M(tests_map_upper_bound) +{ + // title + TITLE(cplusplus.com reference) + + ft::map mymap; + typename ft::map::iterator itlow,itup; + + mymap[VALT('a')]=VALU(20); + mymap[VALT('b')]=VALU(40); + mymap[VALT('c')]=VALU(60); + mymap[VALT('d')]=VALU(80); + mymap[VALT('e')]=VALU(100); + + itlow=mymap.lower_bound (VALT('b')); // itlow points to b + itup=mymap.upper_bound (VALT('d')); // itup points to e (not d!) + + mymap.erase(itlow,itup); // erases [itlow,itup) + + PRINT(mymap) + + DELETE +} + +TEST_M(tests_map_equal_range) +{ + // title + TITLE(cplusplus.com reference) + + ft::map mymap; + + mymap[VALT('a')]=VALU(10); + mymap[VALT('b')]=VALU(20); + mymap[VALT('c')]=VALU(30); + + ft::pair::iterator,typename ft::map::iterator> ret; + ret = mymap.equal_range(VALT('b')); + + std::cout << "lower bound points to: "; + std::cout << ret.first->first << " => " << ret.first->second << '\n'; + + std::cout << "upper bound points to: "; + std::cout << ret.second->first << " => " << ret.second->second << '\n'; + + DELETE +} + +TEST_M(tests_map_get_allocator) +{ + // title + TITLE(cplusplus.com reference) + + int psize; + ft::map mymap; + ft::pair* p; + + // allocate an array of 5 elements using mymap's allocator: + p=mymap.get_allocator().allocate(5); + + // assign some values to array + psize = sizeof(typename ft::map::value_type)*5; + + std::cout << "The allocated array has a size of " << psize << " bytes.\n"; + + mymap.get_allocator().deallocate(p,5); + + DELETE +} + +TEST_M(tests_map_relational_operators) +{ + // title + TITLE(cplusplus.com reference) + + ft::map alice; + ft::map bob; + ft::map eve; + (void)alice; + (void)bob; + (void)eve; + + alice[VALT(1)]=VALU('a'); + alice[VALT(2)]=VALU('b'); + alice[VALT(3)]=VALU('c'); + + bob[VALT(7)]=VALU('Z'); + bob[VALT(8)]=VALU('Y'); + bob[VALT(9)]=VALU('X'); + bob[VALT(10)]=VALU('W'); + + eve[VALT(1)]=VALU('a'); + eve[VALT(2)]=VALU('b'); + eve[VALT(3)]=VALU('c'); + + std::cout << std::boolalpha; + + // Compare non equal containers + std::cout << "alice == bob returns " << (alice == bob) << '\n'; + std::cout << "alice != bob returns " << (alice != bob) << '\n'; + std::cout << "alice < bob returns " << (alice < bob) << '\n'; + std::cout << "alice <= bob returns " << (alice <= bob) << '\n'; + std::cout << "alice > bob returns " << (alice > bob) << '\n'; + std::cout << "alice >= bob returns " << (alice >= bob) << '\n'; + + std::cout << '\n'; + + // Compare equal containers + std::cout << "alice == eve returns " << (alice == eve) << '\n'; + std::cout << "alice != eve returns " << (alice != eve) << '\n'; + std::cout << "alice < eve returns " << (alice < eve) << '\n'; + std::cout << "alice <= eve returns " << (alice <= eve) << '\n'; + std::cout << "alice > eve returns " << (alice > eve) << '\n'; + std::cout << "alice >= eve returns " << (alice >= eve) << '\n'; + + DELETE +} + + +TEST_M(tests_map_swap_non_member) +{ + // title + TITLE(cplusplus.com reference) + + ft::map alice; + ft::map bob; + + alice[VALT(1)]=VALU('a'); + alice[VALT(2)]=VALU('b'); + alice[VALT(3)]=VALU('c'); + + bob[VALT(7)]=VALU('Z'); + bob[VALT(8)]=VALU('Y'); + bob[VALT(9)]=VALU('X'); + bob[VALT(10)]=VALU('W'); + + // Print state before swap + PRINT(alice) + PRINT(bob) + + std::cout << "-- SWAP\n"; + std::swap(alice, bob); + + // Print state after swap + PRINT(alice) + PRINT(bob) + + DELETE +} + +template +void call_tests() { + + 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_relational_operators(); + tests_map_swap_non_member(); +} + +int main() { + + call_tests(); + call_tests(); + call_tests(); + call_tests(); + call_tests(); + call_tests(); + call_tests(); + call_tests(); + + return 0; +} + diff --git a/tests/other_mains/main_map_2.cpp b/tests/other_mains/main_map_2.cpp new file mode 100644 index 0000000..961fdef --- /dev/null +++ b/tests/other_mains/main_map_2.cpp @@ -0,0 +1,862 @@ + + +#include +#include +#include // std::setw() +#include // std::reverse_iterator +#include // std::make_pair +#include // std::stringstream +#include + + +// toogle between test ft and stl +// ************************* +#include +#ifdef STL + namespace ft = std; +#else + #include "vector.hpp" + #include "map.hpp" + #include "reverse_iterator.hpp" +#endif + + +// colors +// ************************************************* +# define GRAY "\e[0;30m" +# define RED "\e[0;31m" +# define GREEN "\e[0;32m" +# define YELLOW "\e[0;33m" +# define BLUE "\e[0;34m" +# define PURPLE "\e[0;35m" +# define CYAN "\e[0;36m" +# define WHITE "\e[0;37m" + +# define B_GRAY "\e[1;30m" +# define B_RED "\e[1;31m" +# define B_GREEN "\e[1;32m" +# define B_YELLOW "\e[1;33m" +# define B_BLUE "\e[1;34m" +# define B_PURPLE "\e[1;35m" +# define B_CYAN "\e[1;36m" +# define B_WHITE "\e[1;37m" + +# define RESET "\e[0m" + + +// defines +// **************************************** +# define TITLE(s) std::cout << "\n" B_PURPLE #s RESET "\n\n"; +# define VAL(n) val(n) +# define VALT(n) val(n) +# define VALU(n) val(n) +# define TOI(n) toi(n) +# define PRINT(n) print<>(n, #n); +# define DELETE delete_structs(); + + +// adding each test to the list +// *************************** +#define TEST_V(f_name) \ + template struct s_ ## f_name : public A_test\ + { void func(); };\ + void f_name () {\ + add_to_list("", "", NULL);\ + add_to_list(#f_name, "int", new(s_ ## f_name ));\ + add_to_list(#f_name, "char", new(s_ ## f_name ));\ + add_to_list(#f_name, "std::string", new(s_ ## f_name ));\ + add_to_list(#f_name, "mystruct*", new(s_ ## f_name ));\ + }\ + template \ + void s_ ## f_name ::func() + +#define TEST_M(f_name) \ + template struct s_ ## f_name : public A_test\ + { void func(); };\ + void f_name () {\ + add_to_list("", "", NULL);\ + add_to_list(#f_name, "char, int", new(s_ ## f_name ));\ + add_to_list(#f_name, "char, char", new(s_ ## f_name ));\ + add_to_list(#f_name, "char, std::string", new(s_ ## f_name ));\ + add_to_list(#f_name, "char, mystruct*", new(s_ ## f_name ));\ + add_to_list(#f_name, "int, int", new(s_ ## f_name ));\ + add_to_list(#f_name, "int, char", new(s_ ## f_name ));\ + add_to_list(#f_name, "int, std::string", new(s_ ## f_name ));\ + add_to_list(#f_name, "int, mystruct*", new(s_ ## f_name ));\ + }\ + template \ + void s_ ## f_name ::func() + + +// structures +// ********************************************* +struct A_test +{ + virtual ~A_test(){}; + std::string title; + std::string type; + virtual void func() = 0; +}; + +struct mystruct { +public: + mystruct(int data = 0) + {_val = new int[2]; _val[0] = data; _val[1] = data;} + ~mystruct() + {delete[] _val;} + int * get_data() const + {return _val;} +private: + int * _val; +}; +std::ostream & operator<<(std::ostream & o, mystruct const * rhs) { + if (rhs != NULL) + o << (*rhs).get_data()[0] << "," << (*rhs).get_data()[1]; + else + o << "NULL"; + return (o); +} + + +// global variables +// *************************************** +std::vector< std::vector > test_list; +std::vector< mystruct* > mem_list; + + +// functions utiles +// *************************************** +void add_to_list(std::string title, std::string type, A_test* test) { + + std::vector test_sub_list; + std::vector< std::vector >::iterator it; + + // title != NULL for the first element + if (test == NULL) + { + test_list.push_back(test_sub_list); + return; + } + + test->title = title; + test->type = type; + it = test_list.end() - 1; + (*it).push_back(test); +} +void delete_structs() { + + std::vector::iterator it; + std::vector::iterator it_end = mem_list.end(); + + for (it = mem_list.begin(); it != it_end; ++it) + delete *it; + mem_list.clear(); +} + + +// 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"; +} + +// templates get value +// ************************************* +// specialization in header, make it inline : +// https://stackoverflow.com/questions/63529059/c-specialized-method-templates-produce-multiple-definition-errors +template + T val(int n) { (void)n; return (T()); } +template <> + inline int val(int n) { return (n); } +template <> + inline char val(int n) { + + if (n <= 126 && n >= 33) + return n; + return (n % 94 + 33); +} +template <> + inline std::string val(int n) { + + std::string str; + std::stringstream stream; + + stream << n; + stream >> str; + stream.clear(); + return (str); +} +template <> + inline mystruct* val(int n) { + + mystruct *s = new mystruct(n); + mem_list.push_back(s); + return ( s ); +} +template + T val(std::string str) { (void)str; return (T()); } +template <> + inline int val(std::string str) { int i = str[0]; return (val(i)); } +template <> + inline char val(std::string str) { int i = str[0]; return (val(i)); } +template <> + inline std::string val(std::string str) { return (str); } +template <> + inline mystruct* val(std::string str) { int i = str[0]; return (val(i)); } + + +// templates to value +// ************************************** +template + int toi(T t) {(void)t; return (0); +} +template <> + inline int toi(int i) {return (i); +} +template <> + inline int toi(char c) {return (c); +} +template <> + inline int toi(std::string str) { + + int i; + std::stringstream stream; + + stream << str; + stream >> i; + stream.clear(); + return (i); +} +template <> + inline int toi(mystruct* s) { + + return ( s->get_data()[0] ); +} + + +// tests functions +// ***************************************** +TEST_M(tests_map_operator_assignation) +{ + // title + TITLE(cplusplus.com reference) + + ft::map first; + ft::map second; + + first[VALT('x')]=VALU(8); + first[VALT('y')]=VALU(16); + first[VALT('z')]=VALU(32); + + PRINT(first) + PRINT(second) + + second=first; // second now contains 3 ints + first=ft::map(); // and first is now empty + + std::cout << "Size of first: " << first.size() << '\n'; + std::cout << "Size of second: " << second.size() << '\n'; + + PRINT(first) + PRINT(second) + + DELETE +} + +TEST_M(tests_map_begin) +{ + // title + TITLE(cplusplus.com reference) + + ft::map mymap; + + mymap[VALT('b')] = VALU(100); + mymap[VALT('a')] = VALU(200); + mymap[VALT('c')] = VALU(300); + + PRINT(mymap) + + DELETE +} + +TEST_M(tests_map_end) +{ + // title + TITLE(cplusplus.com reference) + + ft::map mymap; + + mymap[VALT('b')] = VALU(100); + mymap[VALT('a')] = VALU(200); + mymap[VALT('c')] = VALU(300); + + PRINT(mymap) + + DELETE +} + +TEST_M(tests_map_rbegin) +{ + // title + TITLE(cplusplus.com reference) + + ft::map mymap; + + mymap[VALT('x')] = VALU(100); + mymap[VALT('y')] = VALU(200); + mymap[VALT('z')] = VALU(300); + + // show content: + typename ft::map::reverse_iterator rit; + for (rit=mymap.rbegin(); rit!=mymap.rend(); ++rit) + std::cout << rit->first << " => " << rit->second << '\n'; + + DELETE +} + +TEST_M(tests_map_rend) +{ + // title + TITLE(cplusplus.com reference) + + ft::map mymap; + + mymap[VALT('x')] = VALU(100); + mymap[VALT('y')] = VALU(200); + mymap[VALT('z')] = VALU(300); + + // show content: + typename ft::map::reverse_iterator rit; + for (rit=mymap.rbegin(); rit!=mymap.rend(); ++rit) + std::cout << rit->first << " => " << rit->second << '\n'; + + DELETE +} + +TEST_M(tests_map_empty) +{ + // title + TITLE(cplusplus.com reference) + + ft::map mymap; + + mymap[VALT('a')]=VALU(10); + mymap[VALT('b')]=VALU(20); + mymap[VALT('c')]=VALU(30); + + while (!mymap.empty()) + { + std::cout << mymap.begin()->first << " => " << mymap.begin()->second << '\n'; + mymap.erase(mymap.begin()); + } + + DELETE +} + +TEST_M(tests_map_size) +{ + // title + TITLE(cplusplus.com reference) + + ft::map mymap; + mymap[VALT('a')]=VALU(101); + mymap[VALT('b')]=VALU(202); + mymap[VALT('c')]=VALU(302); + + std::cout << "mymap.size() is " << mymap.size() << '\n'; + + PRINT(mymap) + + DELETE +} + +TEST_M(tests_map_max_size) +{ + // title + TITLE(cplusplus.com reference) + + int i; + std::map mymap; + + if (mymap.max_size()>1000) + { + for (i=0; i<1000; i++) mymap[i]=VALU(0); + std::cout << "The map contains 1000 elements.\n"; + } + else std::cout << "The map could not hold 1000 elements.\n"; + + DELETE +} + +TEST_M(tests_map_operator_access) +{ + // title + TITLE(cplusplus.com reference) + + ft::map mymap; + + mymap[VALT('a')]=VALU("An element"); + mymap[VALT('b')]=VALU("another element"); + mymap[VALT('c')]=mymap[VAL('b')]; + + std::cout << "mymap['a'] is " << mymap[VALT('a')] << '\n'; + std::cout << "mymap['b'] is " << mymap[VALT('b')] << '\n'; + std::cout << "mymap['c'] is " << mymap[VALT('c')] << '\n'; + std::cout << "mymap['d'] is " << mymap[VALT('d')] << '\n'; + + std::cout << "mymap now contains " << mymap.size() << " elements.\n"; + + DELETE +} + +TEST_M(tests_map_insert) +{ + // title + TITLE(cplusplus.com reference) + + ft::map mymap; + + // first insert function version (single parameter): + mymap.insert ( ft::pair(VALT('a'),VALU(100)) ); + mymap.insert ( ft::pair(VALT('z'),VALU(200)) ); + + ft::pair::iterator, bool> ret; + ret = mymap.insert ( ft::pair(VALT('z'),VALU(500)) ); + if (ret.second==false) { + std::cout << "element 'z' already existed"; + std::cout << " with a value of " << ret.first->second << '\n'; + } + + + // second insert function version (with hint position): + typename ft::map::iterator it = mymap.begin(); + mymap.insert (it, ft::pair(VALT('b'),VALU(300))); // max efficiency inserting + mymap.insert (it, ft::pair(VALT('c'),VALU(400))); // no max efficiency inserting + + // third insert function version (range insertion): + ft::map anothermap; + anothermap.insert(mymap.begin(),mymap.find('c')); + + PRINT(mymap) + PRINT(anothermap) + + DELETE +} + +TEST_M(tests_map_erase) +{ + // title + TITLE(cplusplus.com reference) + + ft::map mymap; + typename ft::map::iterator it; + + // insert some values: + mymap[VALT('a')]=VALU(10); + mymap[VALT('b')]=VALU(20); + mymap[VALT('c')]=VALU(30); + mymap[VALT('d')]=VALU(40); + mymap[VALT('e')]=VALU(50); + mymap[VALT('f')]=VALU(60); + + it=mymap.find(VALT('b')); + mymap.erase (it); // erasing by iterator + + mymap.erase (VALT('c')); // erasing by key + + it=mymap.find (VALT('e')); + mymap.erase ( it, mymap.end() ); // erasing by range + + PRINT(mymap) + + DELETE +} + +TEST_M(tests_map_swap) +{ + // title + TITLE(cplusplus.com reference) + + ft::map foo,bar; + + foo[VALT('x')]=VALU(100); + foo[VALT('y')]=VALU(200); + + bar[VALT('a')]=VALU(11); + bar[VALT('b')]=VALU(22); + bar[VALT('c')]=VALU(33); + + foo.swap(bar); + + PRINT(foo) + PRINT(bar) + + DELETE +} + +TEST_M(tests_map_clear) +{ + // title + TITLE(cplusplus.com reference) + + ft::map mymap; + + mymap[VALT('x')]=VALU(100); + mymap[VALT('y')]=VALU(200); + mymap[VALT('z')]=VALU(300); + + PRINT(mymap) + + mymap.clear(); + mymap[VALT('a')]=VALU(1101); + mymap[VALT('b')]=VALU(2202); + + PRINT(mymap) + + DELETE +} + +TEST_M(tests_map_key_comp) +{ + // title + TITLE(cplusplus.com reference) + + ft::map mymap; + + typename ft::map::key_compare mycomp = mymap.key_comp(); + + mymap[VALT('a')]=VALU(100); + mymap[VALT('b')]=VALU(200); + mymap[VALT('c')]=VALU(300); + + std::cout << "mymap contains:\n"; + + T highest = mymap.rbegin()->first; // key value of last element + + typename ft::map::iterator it = mymap.begin(); + do { + std::cout << it->first << " => " << it->second << '\n'; + } while ( mycomp((*it++).first, highest) ); + + std::cout << '\n'; + + DELETE +} + +TEST_M(tests_map_value_comp) +{ + // title + TITLE(cplusplus.com reference) + + ft::map mymap; + + mymap[VALT('x')]=VALU(1001); + mymap[VALT('y')]=VALU(2002); + mymap[VALT('z')]=VALU(3003); + + std::cout << "mymap contains:\n"; + + ft::pair highest = *mymap.rbegin(); // last element + + typename ft::map::iterator it = mymap.begin(); + do { + std::cout << it->first << " => " << it->second << '\n'; + } while ( mymap.value_comp()(*it++, highest) ); + + DELETE +} + +TEST_M(tests_map_find) +{ + // title + TITLE(cplusplus.com reference) + + ft::map mymap; + typename ft::map::iterator it; + + mymap[VALT('a')]=VALU(50); + mymap[VALT('b')]=VALU(100); + mymap[VALT('c')]=VALU(150); + mymap[VALT('d')]=VALU(200); + + it = mymap.find(VALT('b')); + if (it != mymap.end()) + mymap.erase (it); + + // print content: + std::cout << "elements in mymap:" << '\n'; + std::cout << "a => " << mymap.find(VALT('a'))->second << '\n'; + std::cout << "c => " << mymap.find(VALT('c'))->second << '\n'; + std::cout << "d => " << mymap.find(VALT('d'))->second << '\n'; + + DELETE +} + +TEST_M(tests_map_count) +{ + // title + TITLE(cplusplus.com reference) + + ft::map mymap; + T c; + + mymap [VALT('a')]=VALU(101); + mymap [VALT('c')]=VALU(202); + mymap [VALT('f')]=VALU(303); + + // to do this test with T as a 'string' or 'mystruct*' we should add overload + for (c=VALT('a'); c0) + std::cout << " is an element of mymap.\n"; + else + std::cout << " is not an element of mymap.\n"; + } + + DELETE +} + +TEST_M(tests_map_lower_bound) +{ + // title + TITLE(cplusplus.com reference) + + ft::map mymap; + typename ft::map::iterator itlow,itup; + + mymap[VALT('a')]=VALU(20); + mymap[VALT('b')]=VALU(40); + mymap[VALT('c')]=VALU(60); + mymap[VALT('d')]=VALU(80); + mymap[VALT('e')]=VALU(100); + + itlow=mymap.lower_bound (VALT('b')); // itlow points to b + itup=mymap.upper_bound (VALT('d')); // itup points to e (not d!) + + mymap.erase(itlow,itup); // erases [itlow,itup) + + PRINT(mymap) + + DELETE +} + +TEST_M(tests_map_upper_bound) +{ + // title + TITLE(cplusplus.com reference) + + ft::map mymap; + typename ft::map::iterator itlow,itup; + + mymap[VALT('a')]=VALU(20); + mymap[VALT('b')]=VALU(40); + mymap[VALT('c')]=VALU(60); + mymap[VALT('d')]=VALU(80); + mymap[VALT('e')]=VALU(100); + + itlow=mymap.lower_bound (VALT('b')); // itlow points to b + itup=mymap.upper_bound (VALT('d')); // itup points to e (not d!) + + mymap.erase(itlow,itup); // erases [itlow,itup) + + PRINT(mymap) + + DELETE +} + +TEST_M(tests_map_equal_range) +{ + // title + TITLE(cplusplus.com reference) + + ft::map mymap; + + mymap[VALT('a')]=VALU(10); + mymap[VALT('b')]=VALU(20); + mymap[VALT('c')]=VALU(30); + + ft::pair::iterator,typename ft::map::iterator> ret; + ret = mymap.equal_range(VALT('b')); + + std::cout << "lower bound points to: "; + std::cout << ret.first->first << " => " << ret.first->second << '\n'; + + std::cout << "upper bound points to: "; + std::cout << ret.second->first << " => " << ret.second->second << '\n'; + + DELETE +} + +TEST_M(tests_map_get_allocator) +{ + // title + TITLE(cplusplus.com reference) + + int psize; + ft::map mymap; + ft::pair* p; + + // allocate an array of 5 elements using mymap's allocator: + p=mymap.get_allocator().allocate(5); + + // assign some values to array + psize = sizeof(typename ft::map::value_type)*5; + + std::cout << "The allocated array has a size of " << psize << " bytes.\n"; + + mymap.get_allocator().deallocate(p,5); + + DELETE +} + +TEST_M(tests_map_relational_operators) +{ + // title + TITLE(cplusplus.com reference) + + ft::map alice; + ft::map bob; + ft::map eve; + (void)alice; + (void)bob; + (void)eve; + + alice[VALT(1)]=VALU('a'); + alice[VALT(2)]=VALU('b'); + alice[VALT(3)]=VALU('c'); + + bob[VALT(7)]=VALU('Z'); + bob[VALT(8)]=VALU('Y'); + bob[VALT(9)]=VALU('X'); + bob[VALT(10)]=VALU('W'); + + eve[VALT(1)]=VALU('a'); + eve[VALT(2)]=VALU('b'); + eve[VALT(3)]=VALU('c'); + + std::cout << std::boolalpha; + + // Compare non equal containers + std::cout << "alice == bob returns " << (alice == bob) << '\n'; + std::cout << "alice != bob returns " << (alice != bob) << '\n'; + std::cout << "alice < bob returns " << (alice < bob) << '\n'; + std::cout << "alice <= bob returns " << (alice <= bob) << '\n'; + std::cout << "alice > bob returns " << (alice > bob) << '\n'; + std::cout << "alice >= bob returns " << (alice >= bob) << '\n'; + + std::cout << '\n'; + + // Compare equal containers + std::cout << "alice == eve returns " << (alice == eve) << '\n'; + std::cout << "alice != eve returns " << (alice != eve) << '\n'; + std::cout << "alice < eve returns " << (alice < eve) << '\n'; + std::cout << "alice <= eve returns " << (alice <= eve) << '\n'; + std::cout << "alice > eve returns " << (alice > eve) << '\n'; + std::cout << "alice >= eve returns " << (alice >= eve) << '\n'; + + DELETE +} + + +TEST_M(tests_map_swap_non_member) +{ + // title + TITLE(cplusplus.com reference) + + ft::map alice; + ft::map bob; + + alice[VALT(1)]=VALU('a'); + alice[VALT(2)]=VALU('b'); + alice[VALT(3)]=VALU('c'); + + bob[VALT(7)]=VALU('Z'); + bob[VALT(8)]=VALU('Y'); + bob[VALT(9)]=VALU('X'); + bob[VALT(10)]=VALU('W'); + + // Print state before swap + PRINT(alice) + PRINT(bob) + + std::cout << "-- SWAP\n"; + std::swap(alice, bob); + + // Print state after swap + PRINT(alice) + PRINT(bob) + + DELETE +} + + +int main() { + + 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_relational_operators(); + tests_map_swap_non_member(); + + + // execute tests and print them : + int size = test_list.size(); + int sub_size; + for(int i = 0; i < size; i++) + { + std::cout << "\n" B_YELLOW "[" << i + 1 << "/" << size << "] " + << test_list[i][0]->title << RESET << "\n"; + sub_size = test_list[i].size(); + for (int j = 0; j < sub_size; j++) + { + std::cout << "\n" << B_CYAN << "-- " << test_list[i][j]->type + << " --" << RESET "\n"; + test_list[i][j]->func(); + delete test_list[i][j]; + } + } + std::cout << "\n"; + + return 0; +} + diff --git a/tests/other_mains/main_stack_1.cpp b/tests/other_mains/main_stack_1.cpp new file mode 100644 index 0000000..e3c7480 --- /dev/null +++ b/tests/other_mains/main_stack_1.cpp @@ -0,0 +1,187 @@ + +#include +#include +#include // std::setw() +#include // std::reverse_iterator +#include // std::make_pair +#include // std::stringstream +#include +#include +#include + +// toogle ft in stl +#ifdef STL + namespace ft = std; +#else + #include "vector.hpp" + #include "map.hpp" + #include "stack.hpp" + #include "reverse_iterator.hpp" +#endif + +// defines +# define TEST(s) template void s () +# define TITLE(s) std::cout << "\n" B_PURPLE #s RESET "\n\n"; +# define VAL(n) val(n) +# define TOI(n) toi(n) +# define PRINT(n) print<>(n, #n); +# define DELETE delete_structs(); + +// colors +# define GRAY "\e[0;30m" +# define RED "\e[0;31m" +# define GREEN "\e[0;32m" +# define YELLOW "\e[0;33m" +# define BLUE "\e[0;34m" +# define PURPLE "\e[0;35m" +# define CYAN "\e[0;36m" +# define WHITE "\e[0;37m" + +# define B_GRAY "\e[1;30m" +# define B_RED "\e[1;31m" +# define B_GREEN "\e[1;32m" +# define B_YELLOW "\e[1;33m" +# define B_BLUE "\e[1;34m" +# define B_PURPLE "\e[1;35m" +# define B_CYAN "\e[1;36m" +# define B_WHITE "\e[1;37m" + +# define RESET "\e[0m" + +// mystruct declaration +struct mystruct { +public: + mystruct(int data = 0); + ~mystruct(); + int * get_data() const; +private: + int * _val; +}; +std::ostream & operator<<(std::ostream & o, mystruct const * rhs); + +// mystruct definition +mystruct::mystruct(int data) + {_val = new int[2]; _val[0] = data; _val[1] = data;} +mystruct::~mystruct() + {delete[] _val;} +int * mystruct::get_data() const + {return _val;} +std::ostream & operator<<(std::ostream & o, mystruct const * rhs) { + if (rhs != NULL) + o << (*rhs).get_data()[0] << "," << (*rhs).get_data()[1]; + else + o << "NULL"; + return (o); +} + +// global variable for mem gestion of mystruct +std::vector< mystruct* > mem_list; + +// template print function +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"; +} + +// template val() for instanciation of values for types : +// int, char, std::string, and mystruct* +template + T val(int n) { (void)n; return (T()); } +template <> + inline int val(int n) { return (n); } +template <> + inline char val(int n) { + + if (n <= 126 && n >= 33) + return n; + return (n % 94 + 33); +} +template <> + inline std::string val(int n) { + + std::string str; + std::stringstream stream; + + stream << n; + stream >> str; + stream.clear(); + return (str); +} +template <> + inline mystruct* val(int n) { + + mystruct *s = new mystruct(n); + mem_list.push_back(s); + return ( s ); +} +template + T val(std::string str) { (void)str; return (T()); } +template <> + inline int val(std::string str) { int i = str[0]; return (val(i)); } +template <> + inline char val(std::string str) { int i = str[0]; return (val(i)); } +template <> + inline std::string val(std::string str) { return (str); } +template <> + inline mystruct* val(std::string str) { int i = str[0]; return (val(i)); } + +// delete function for mem gestion of mystruct* +void delete_structs() { + + std::vector::iterator it; + std::vector::iterator it_end = mem_list.end(); + + for (it = mem_list.begin(); it != it_end; ++it) + delete *it; + mem_list.clear(); +} + +// all tests +TEST(tests_stack_constructor) +{ + // title + TITLE(simple test) + + std::deque mydeque (3,VAL(100)); // deque with 3 elements + std::vector myvector (2,VAL(200)); // vector with 2 elements + + ft::stack first; // empty stack + ft::stack second (mydeque); // stack initialized to copy of deque + +// ft::stack< T,std::vector > third; // empty stack using vector +// ft::stack< T,std::vector > fourth (myvector); +// +// std::cout << "size of first: " << first.size() << '\n'; +// std::cout << "size of second: " << second.size() << '\n'; +// std::cout << "size of third: " << third.size() << '\n'; +// std::cout << "size of fourth: " << fourth.size() << '\n'; +// +// PRINT(first) +// PRINT(second) +// PRINT(third) +// PRINT(fourth) +// +// DELETE +} + +template +void call_tests() { + + tests_stack_constructor(); +} + +int main() { + + call_tests(); +// call_tests(); +// call_tests(); +// call_tests(); + + return 0; +} + + diff --git a/tests/test.sh b/tests/test.sh new file mode 100644 index 0000000..22f498c --- /dev/null +++ b/tests/test.sh @@ -0,0 +1,19 @@ +#!/bin/bash +# cd $(dirname $0) + +TEST_DIR=$(dirname $0) +OUTPUT_STL="output_stl.log" +OUTPUT_FT="output_ft.log" + +#make -j > /dev/null +make -j + +echo -e "\nstl :" +time ./containers_stl > tests/$OUTPUT_STL + +echo -e "\nft :" +time ./containers_ft > tests/$OUTPUT_FT + +diff --context=0 --color=always tests/$OUTPUT_STL tests/$OUTPUT_FT + +#/bin/rm $TEST_DIR/$OUTPUT_STL $TEST_DIR/$OUTPUT_FT diff --git a/tests/tests_definitions.cpp b/tests/tests_definitions.cpp new file mode 100644 index 0000000..8cd6937 --- /dev/null +++ b/tests/tests_definitions.cpp @@ -0,0 +1,50 @@ + +#include "tests_utils.hpp" + + +// functions +// ********************************************** +void add_to_list(std::string title, std::string type, A_test* test) { + + std::vector test_sub_list; + std::vector< std::vector >::iterator it; + + // title != NULL for the first element + if (test == NULL) + { + test_list.push_back(test_sub_list); + return; + } + + test->title = title; + test->type = type; + it = test_list.end() - 1; + (*it).push_back(test); +} +void delete_structs() { + + std::vector::iterator it; + std::vector::iterator it_end = mem_list.end(); + + for (it = mem_list.begin(); it != it_end; ++it) + delete *it; + mem_list.clear(); +} + + +// mystruct +// *********************************************** +mystruct::mystruct(int data) + {_val = new int[2]; _val[0] = data; _val[1] = data;} +mystruct::~mystruct() + {delete[] _val;} +int * mystruct::get_data() const + {return _val;} +std::ostream & operator<<(std::ostream & o, mystruct const * rhs) { + if (rhs != NULL) + o << (*rhs).get_data()[0] << "," << (*rhs).get_data()[1]; + else + o << "NULL"; + return (o); +} + diff --git a/tests/tests_map.cpp b/tests/tests_map.cpp new file mode 100644 index 0000000..7a5a104 --- /dev/null +++ b/tests/tests_map.cpp @@ -0,0 +1,738 @@ + +#include "tests_map.hpp" + + +/**/ // UTILS for some tests +/**/ bool fncomp (char lhs, char rhs) {return lhs mp; + typename std::map::iterator it; + + mp[VALT('a')] = VALU(10); + + PRINT(mp) + + DELETE +} + +TEST_M(tests_map_constructor) +{ + // title + TITLE(cplusplus.com reference) + + ft::map first; + + first[VALT('a')]=VALU(10); + first[VALT('b')]=VALU(30); + first[VALT('c')]=VALU(50); + first[VALT('d')]=VALU(70); + + ft::map second (first.begin(),first.end()); + + ft::map third (second); + + ft::map fourth; // class as Compare + + bool(*fn_pt)(char,char) = fncomp; + ft::map fifth (fn_pt); // function pointer as Compare + + PRINT(first) + PRINT(second) + PRINT(third) + + DELETE +} + +TEST_M(tests_map_operator_assignation) +{ + // title + TITLE(cplusplus.com reference) + + ft::map first; + ft::map second; + + first[VALT('x')]=VALU(8); + first[VALT('y')]=VALU(16); + first[VALT('z')]=VALU(32); + + PRINT(first) + PRINT(second) + + second=first; // second now contains 3 ints + first=ft::map(); // and first is now empty + + std::cout << "Size of first: " << first.size() << '\n'; + std::cout << "Size of second: " << second.size() << '\n'; + + PRINT(first) + PRINT(second) + + DELETE +} + +TEST_M(tests_map_begin) +{ + // title + TITLE(cplusplus.com reference) + + ft::map mymap; + + mymap[VALT('b')] = VALU(100); + mymap[VALT('a')] = VALU(200); + mymap[VALT('c')] = VALU(300); + + PRINT(mymap) + + DELETE +} + +TEST_M(tests_map_end) +{ + // title + TITLE(cplusplus.com reference) + + ft::map mymap; + + mymap[VALT('b')] = VALU(100); + mymap[VALT('a')] = VALU(200); + mymap[VALT('c')] = VALU(300); + + PRINT(mymap) + + DELETE +} + +TEST_M(tests_map_rbegin) +{ + // title + TITLE(cplusplus.com reference) + + ft::map mymap; + + mymap[VALT('x')] = VALU(100); + mymap[VALT('y')] = VALU(200); + mymap[VALT('z')] = VALU(300); + + // show content: + typename ft::map::reverse_iterator rit; + for (rit=mymap.rbegin(); rit!=mymap.rend(); ++rit) + std::cout << rit->first << " => " << rit->second << '\n'; + + DELETE +} + +TEST_M(tests_map_rend) +{ + // title + TITLE(cplusplus.com reference) + + ft::map mymap; + + mymap[VALT('x')] = VALU(100); + mymap[VALT('y')] = VALU(200); + mymap[VALT('z')] = VALU(300); + + // show content: + typename ft::map::reverse_iterator rit; + for (rit=mymap.rbegin(); rit!=mymap.rend(); ++rit) + std::cout << rit->first << " => " << rit->second << '\n'; + + DELETE +} + +TEST_M(tests_map_empty) +{ + // title + TITLE(cplusplus.com reference) + + ft::map mymap; + + mymap[VALT('a')]=VALU(10); + mymap[VALT('b')]=VALU(20); + mymap[VALT('c')]=VALU(30); + + while (!mymap.empty()) + { + std::cout << mymap.begin()->first << " => " << mymap.begin()->second << '\n'; + mymap.erase(mymap.begin()); + } + + DELETE +} + +TEST_M(tests_map_size) +{ + // title + TITLE(cplusplus.com reference) + + ft::map mymap; + mymap[VALT('a')]=VALU(101); + mymap[VALT('b')]=VALU(202); + mymap[VALT('c')]=VALU(302); + + std::cout << "mymap.size() is " << mymap.size() << '\n'; + + PRINT(mymap) + + DELETE +} + +TEST_M(tests_map_max_size) +{ + // title + TITLE(cplusplus.com reference) + + int i; + std::map mymap; + + if (mymap.max_size()>1000) + { + for (i=0; i<1000; i++) mymap[i]=VALU(0); + std::cout << "The map contains 1000 elements.\n"; + } + else std::cout << "The map could not hold 1000 elements.\n"; + + DELETE +} + +TEST_M(tests_map_operator_access) +{ + // title + TITLE(cplusplus.com reference) + + ft::map mymap; + + mymap[VALT('a')]=VALU("An element"); + mymap[VALT('b')]=VALU("another element"); + mymap[VALT('c')]=mymap[VAL('b')]; + + std::cout << "mymap['a'] is " << mymap[VALT('a')] << '\n'; + std::cout << "mymap['b'] is " << mymap[VALT('b')] << '\n'; + std::cout << "mymap['c'] is " << mymap[VALT('c')] << '\n'; + std::cout << "mymap['d'] is " << mymap[VALT('d')] << '\n'; + + std::cout << "mymap now contains " << mymap.size() << " elements.\n"; + + DELETE +} + +TEST_M(tests_map_insert) +{ + // title + TITLE(cplusplus.com reference) + + ft::map mymap; + + // first insert function version (single parameter): + mymap.insert ( ft::pair(VALT('a'),VALU(100)) ); + mymap.insert ( ft::pair(VALT('z'),VALU(200)) ); + + ft::pair::iterator, bool> ret; + ret = mymap.insert ( ft::pair(VALT('z'),VALU(500)) ); + if (ret.second==false) { + std::cout << "element 'z' already existed"; + std::cout << " with a value of " << ret.first->second << '\n'; + } + + + // second insert function version (with hint position): + typename ft::map::iterator it = mymap.begin(); + mymap.insert (it, ft::pair(VALT('b'),VALU(300))); // max efficiency inserting + mymap.insert (it, ft::pair(VALT('c'),VALU(400))); // no max efficiency inserting + + // third insert function version (range insertion): + ft::map anothermap; + anothermap.insert(mymap.begin(),mymap.find('c')); + + PRINT(mymap) + PRINT(anothermap) + + DELETE +} + +TEST_M(tests_map_erase) +{ + // title + TITLE(cplusplus.com reference) + + ft::map mymap; + typename ft::map::iterator it; + + // insert some values: + mymap[VALT('a')]=VALU(10); + mymap[VALT('b')]=VALU(20); + mymap[VALT('c')]=VALU(30); + mymap[VALT('d')]=VALU(40); + mymap[VALT('e')]=VALU(50); + mymap[VALT('f')]=VALU(60); + + it=mymap.find(VALT('b')); + mymap.erase (it); // erasing by iterator + + mymap.erase (VALT('c')); // erasing by key + + it=mymap.find (VALT('e')); + mymap.erase ( it, mymap.end() ); // erasing by range + + PRINT(mymap) + + + // title + TITLE(more complexe tree) + + mymap[VALT('b')]=VALU(20); + mymap[VALT('c')]=VALU(30); + mymap[VALT('e')]=VALU(50); + mymap[VALT('g')]=VALU(24); + mymap[VALT('h')]=VALU(64); + mymap[VALT('i')]=VALU(52); + mymap[VALT('j')]=VALU(14); + mymap[VALT('k')]=VALU(12); + mymap[VALT('l')]=VALU(46); + mymap[VALT('m')]=VALU(37); + mymap[VALT('n')]=VALU(31); + mymap[VALT('o')]=VALU(58); + mymap[VALT('p')]=VALU(18); + mymap[VALT('q')]=VALU(25); + mymap[VALT('r')]=VALU(36); + mymap[VALT('s')]=VALU(43); + mymap[VALT('t')]=VALU(49); + mymap[VALT('u')]=VALU(21); + mymap[VALT('v')]=VALU(55); + mymap[VALT('w')]=VALU(33); + mymap[VALT('x')]=VALU(44); + mymap[VALT('y')]=VALU(11); + mymap[VALT('z')]=VALU(22); + + mymap.erase (VALT('a')); + mymap[VALT('a')]=VALU(10); + mymap.erase (VALT('b')); + mymap[VALT('b')]=VALU(20); + mymap.erase (VALT('c')); + mymap[VALT('c')]=VALU(30); + mymap.erase (VALT('d')); + mymap[VALT('d')]=VALU(40); + mymap.erase (VALT('e')); + mymap[VALT('e')]=VALU(50); + mymap.erase (VALT('f')); + mymap[VALT('f')]=VALU(60); + mymap.erase (VALT('g')); + mymap[VALT('g')]=VALU(24); + mymap.erase (VALT('h')); + mymap[VALT('h')]=VALU(64); + mymap.erase (VALT('i')); + mymap[VALT('i')]=VALU(52); + mymap.erase (VALT('j')); + mymap[VALT('j')]=VALU(14); + mymap.erase (VALT('k')); + mymap[VALT('k')]=VALU(12); + mymap.erase (VALT('l')); + mymap[VALT('l')]=VALU(46); + mymap.erase (VALT('m')); + mymap[VALT('m')]=VALU(37); + mymap.erase (VALT('n')); + mymap[VALT('n')]=VALU(31); + mymap.erase (VALT('o')); + mymap[VALT('o')]=VALU(58); + mymap.erase (VALT('p')); + mymap[VALT('p')]=VALU(18); + mymap.erase (VALT('q')); + mymap[VALT('q')]=VALU(25); + mymap.erase (VALT('r')); + mymap[VALT('r')]=VALU(36); + mymap.erase (VALT('s')); + mymap[VALT('s')]=VALU(43); + mymap.erase (VALT('t')); + mymap[VALT('t')]=VALU(49); + mymap.erase (VALT('u')); + mymap[VALT('u')]=VALU(21); + mymap.erase (VALT('v')); + mymap[VALT('v')]=VALU(55); + mymap.erase (VALT('w')); + mymap[VALT('w')]=VALU(33); + mymap.erase (VALT('x')); + mymap[VALT('x')]=VALU(44); + mymap.erase (VALT('y')); + mymap[VALT('y')]=VALU(11); + mymap.erase (VALT('z')); + mymap[VALT('z')]=VALU(22); + + PRINT(mymap) + + + // title + TITLE(erasing entire tree) + + mymap.erase (VALT('a')); + mymap.erase (VALT('b')); + mymap.erase (VALT('c')); + mymap.erase (VALT('d')); + mymap.erase (VALT('e')); + mymap.erase (VALT('f')); + mymap.erase (VALT('g')); + mymap.erase (VALT('h')); + mymap.erase (VALT('i')); + mymap.erase (VALT('j')); + mymap.erase (VALT('k')); + mymap.erase (VALT('l')); + mymap.erase (VALT('m')); + mymap.erase (VALT('n')); + mymap.erase (VALT('o')); + mymap.erase (VALT('p')); + mymap.erase (VALT('q')); + mymap.erase (VALT('r')); + mymap.erase (VALT('s')); + mymap.erase (VALT('t')); + mymap.erase (VALT('u')); + mymap.erase (VALT('v')); + mymap.erase (VALT('w')); + mymap.erase (VALT('x')); + mymap.erase (VALT('y')); + mymap.erase (VALT('z')); + + PRINT(mymap) + + + // title + TITLE(big tree) + + int i; + for (i = 0; i < 10000; i++) + mymap[VALT(i)]=VALU(i); + while (i) + mymap.erase (VAL(i--)); + + PRINT(mymap) + + DELETE +} + +TEST_M(tests_map_swap) +{ + // title + TITLE(cplusplus.com reference) + + ft::map foo,bar; + + foo[VALT('x')]=VALU(100); + foo[VALT('y')]=VALU(200); + + bar[VALT('a')]=VALU(11); + bar[VALT('b')]=VALU(22); + bar[VALT('c')]=VALU(33); + + foo.swap(bar); + + PRINT(foo) + PRINT(bar) + + DELETE +} + +TEST_M(tests_map_clear) +{ + // title + TITLE(cplusplus.com reference) + + ft::map mymap; + + mymap[VALT('x')]=VALU(100); + mymap[VALT('y')]=VALU(200); + mymap[VALT('z')]=VALU(300); + + PRINT(mymap) + + mymap.clear(); + mymap[VALT('a')]=VALU(1101); + mymap[VALT('b')]=VALU(2202); + + PRINT(mymap) + + DELETE +} + +TEST_M(tests_map_key_comp) +{ + // title + TITLE(cplusplus.com reference) + + ft::map mymap; + + typename ft::map::key_compare mycomp = mymap.key_comp(); + + mymap[VALT('a')]=VALU(100); + mymap[VALT('b')]=VALU(200); + mymap[VALT('c')]=VALU(300); + + std::cout << "mymap contains:\n"; + + T highest = mymap.rbegin()->first; // key value of last element + + typename ft::map::iterator it = mymap.begin(); + do { + std::cout << it->first << " => " << it->second << '\n'; + } while ( mycomp((*it++).first, highest) ); + + std::cout << '\n'; + + DELETE +} + +TEST_M(tests_map_value_comp) +{ + // title + TITLE(cplusplus.com reference) + + ft::map mymap; + + mymap[VALT('x')]=VALU(1001); + mymap[VALT('y')]=VALU(2002); + mymap[VALT('z')]=VALU(3003); + + std::cout << "mymap contains:\n"; + + ft::pair highest = *mymap.rbegin(); // last element + + typename ft::map::iterator it = mymap.begin(); + do { + std::cout << it->first << " => " << it->second << '\n'; + } while ( mymap.value_comp()(*it++, highest) ); + + DELETE +} + +TEST_M(tests_map_find) +{ + // title + TITLE(cplusplus.com reference) + + ft::map mymap; + typename ft::map::iterator it; + + mymap[VALT('a')]=VALU(50); + mymap[VALT('b')]=VALU(100); + mymap[VALT('c')]=VALU(150); + mymap[VALT('d')]=VALU(200); + + it = mymap.find(VALT('b')); + if (it != mymap.end()) + mymap.erase (it); + + // print content: + std::cout << "elements in mymap:" << '\n'; + std::cout << "a => " << mymap.find(VALT('a'))->second << '\n'; + std::cout << "c => " << mymap.find(VALT('c'))->second << '\n'; + std::cout << "d => " << mymap.find(VALT('d'))->second << '\n'; + + DELETE +} + +TEST_M(tests_map_count) +{ + // title + TITLE(cplusplus.com reference) + + ft::map mymap; + T c; + + mymap [VALT('a')]=VALU(101); + mymap [VALT('c')]=VALU(202); + mymap [VALT('f')]=VALU(303); + + // to do this test with T as a 'string' or 'mystruct*' we should add overload + for (c=VALT('a'); c0) + std::cout << " is an element of mymap.\n"; + else + std::cout << " is not an element of mymap.\n"; + } + + DELETE +} + +TEST_M(tests_map_lower_bound) +{ + // title + TITLE(cplusplus.com reference) + + ft::map mymap; + typename ft::map::iterator itlow,itup; + + mymap[VALT('a')]=VALU(20); + mymap[VALT('b')]=VALU(40); + mymap[VALT('c')]=VALU(60); + mymap[VALT('d')]=VALU(80); + mymap[VALT('e')]=VALU(100); + + itlow=mymap.lower_bound (VALT('b')); // itlow points to b + itup=mymap.upper_bound (VALT('d')); // itup points to e (not d!) + + mymap.erase(itlow,itup); // erases [itlow,itup) + + PRINT(mymap) + + DELETE +} + +TEST_M(tests_map_upper_bound) +{ + // title + TITLE(cplusplus.com reference) + + ft::map mymap; + typename ft::map::iterator itlow,itup; + + mymap[VALT('a')]=VALU(20); + mymap[VALT('b')]=VALU(40); + mymap[VALT('c')]=VALU(60); + mymap[VALT('d')]=VALU(80); + mymap[VALT('e')]=VALU(100); + + itlow=mymap.lower_bound (VALT('b')); // itlow points to b + itup=mymap.upper_bound (VALT('d')); // itup points to e (not d!) + + mymap.erase(itlow,itup); // erases [itlow,itup) + + PRINT(mymap) + + DELETE +} + +TEST_M(tests_map_equal_range) +{ + // title + TITLE(cplusplus.com reference) + + ft::map mymap; + + mymap[VALT('a')]=VALU(10); + mymap[VALT('b')]=VALU(20); + mymap[VALT('c')]=VALU(30); + + ft::pair::iterator,typename ft::map::iterator> ret; + ret = mymap.equal_range(VALT('b')); + + std::cout << "lower bound points to: "; + std::cout << ret.first->first << " => " << ret.first->second << '\n'; + + std::cout << "upper bound points to: "; + std::cout << ret.second->first << " => " << ret.second->second << '\n'; + + DELETE +} + +TEST_M(tests_map_get_allocator) +{ + // title + TITLE(cplusplus.com reference) + + int psize; + ft::map mymap; + ft::pair* p; + + // allocate an array of 5 elements using mymap's allocator: + p=mymap.get_allocator().allocate(5); + + // assign some values to array + psize = sizeof(typename ft::map::value_type)*5; + + std::cout << "The allocated array has a size of " << psize << " bytes.\n"; + + mymap.get_allocator().deallocate(p,5); + + DELETE +} + +TEST_M(tests_map_relational_operators) +{ + // title + TITLE(cplusplus.com reference) + + ft::map alice; + ft::map bob; + ft::map eve; + (void)alice; + (void)bob; + (void)eve; + + alice[VALT(1)]=VALU('a'); + alice[VALT(2)]=VALU('b'); + alice[VALT(3)]=VALU('c'); + + bob[VALT(7)]=VALU('Z'); + bob[VALT(8)]=VALU('Y'); + bob[VALT(9)]=VALU('X'); + bob[VALT(10)]=VALU('W'); + + eve[VALT(1)]=VALU('a'); + eve[VALT(2)]=VALU('b'); + eve[VALT(3)]=VALU('c'); + + std::cout << std::boolalpha; + + // Compare non equal containers + std::cout << "alice == bob returns " << (alice == bob) << '\n'; + std::cout << "alice != bob returns " << (alice != bob) << '\n'; + std::cout << "alice < bob returns " << (alice < bob) << '\n'; + std::cout << "alice <= bob returns " << (alice <= bob) << '\n'; + std::cout << "alice > bob returns " << (alice > bob) << '\n'; + std::cout << "alice >= bob returns " << (alice >= bob) << '\n'; + + std::cout << '\n'; + + // Compare equal containers + std::cout << "alice == eve returns " << (alice == eve) << '\n'; + std::cout << "alice != eve returns " << (alice != eve) << '\n'; + std::cout << "alice < eve returns " << (alice < eve) << '\n'; + std::cout << "alice <= eve returns " << (alice <= eve) << '\n'; + std::cout << "alice > eve returns " << (alice > eve) << '\n'; + std::cout << "alice >= eve returns " << (alice >= eve) << '\n'; + + DELETE +} + + +TEST_M(tests_map_swap_non_member) +{ + // title + TITLE(cplusplus.com reference) + + ft::map alice; + ft::map bob; + + alice[VALT(1)]=VALU('a'); + alice[VALT(2)]=VALU('b'); + alice[VALT(3)]=VALU('c'); + + bob[VALT(7)]=VALU('Z'); + bob[VALT(8)]=VALU('Y'); + bob[VALT(9)]=VALU('X'); + bob[VALT(10)]=VALU('W'); + + // Print state before swap + PRINT(alice) + PRINT(bob) + + std::cout << "-- SWAP\n"; + std::swap(alice, bob); + + // Print state after swap + PRINT(alice) + PRINT(bob) + + DELETE +} + diff --git a/tests/tests_stack.cpp b/tests/tests_stack.cpp new file mode 100644 index 0000000..712bfa1 --- /dev/null +++ b/tests/tests_stack.cpp @@ -0,0 +1,135 @@ + +#include "tests_stack.hpp" + +#ifdef STL + #define DEQ_VEC deque +#else + #define DEQ_VEC vector +#endif + +TEST(tests_stack_constructor) +{ + // title + TITLE(simple test) + + ft::DEQ_VEC mycont (2,VAL(200)); // ft::vector/stl::deque with 2 elements + ft::vector myvector (2,VAL(200)); // vector with 2 elements + + ft::stack first; // empty stack + ft::stack second (mycont); // stack initialized to copy of vector + + ft::stack< T,ft::vector > third; // empty stack using vector + ft::stack< T,ft::vector > fourth (myvector); + + std::cout << "size of first: " << first.size() << '\n'; + std::cout << "size of second: " << second.size() << '\n'; + std::cout << "size of third: " << third.size() << '\n'; + std::cout << "size of fourth: " << fourth.size() << '\n'; + + PRINT(first) + PRINT(second) + PRINT(third) + PRINT(fourth) + + DELETE +} + +TEST(tests_stack_empty) +{ + // title + TITLE(simple test) + + ft::stack mystack; + int sum (0); + + for (int i=1;i<=10;i++) mystack.push(VAL(i)); + + while (!mystack.empty()) + { + sum += TOI(mystack.top()); + mystack.pop(); + } + + std::cout << "total: " << sum << '\n'; + + PRINT(mystack) + + DELETE +} + +TEST(tests_stack_size) +{ + // title + TITLE(simple test) + + ft::stack myints; + std::cout << "0. size: " << myints.size() << '\n'; + + for (int i=0; i<5; i++) myints.push(VAL(i)); + std::cout << "1. size: " << myints.size() << '\n'; + + myints.pop(); + std::cout << "2. size: " << myints.size() << '\n'; + + PRINT(myints) + + DELETE +} + +TEST(tests_stack_top) +{ + // title + TITLE(simple test) + + ft::stack mystack; + + mystack.push(VAL(10)); + std::cout << "mystack.top() is now " << mystack.top() << '\n'; + mystack.push(VAL(20)); + std::cout << "mystack.top() is now " << mystack.top() << '\n'; + mystack.push(VAL(-12)); + std::cout << "mystack.top() is now " << mystack.top() << '\n'; + mystack.push(VAL(26)); + std::cout << "mystack.top() is now " << mystack.top() << '\n'; + +// mystack.top() -= VAL(5); + + + PRINT(mystack) + + DELETE +} + +TEST(tests_stack_push) +{ + // title + TITLE(simple test) + + ft::stack mystack; + + for (int i=0; i<5; ++i) mystack.push(VAL(i)); + + PRINT(mystack) + + DELETE +} + +TEST(tests_stack_pop) +{ + // title + TITLE(simple test) + + ft::stack mystack; + + for (int i=0; i<5; ++i) mystack.push(VAL(i)); + + std::cout << "Popping out elements..."; + while (!mystack.empty()) + { + std::cout << ' ' << mystack.top(); + mystack.pop(); + } + std::cout << '\n'; + + DELETE +} diff --git a/tests/tests_vector.cpp b/tests/tests_vector.cpp new file mode 100644 index 0000000..bcb83e2 --- /dev/null +++ b/tests/tests_vector.cpp @@ -0,0 +1,862 @@ + +#include "tests_vector.hpp" + + +TEST_V(tests_vector_constructor) +{ + // title + TITLE(cplusplus.com reference) + + // constructors used in the same order as described above: + ft::vector first; // empty vector of ints + ft::vector second (4,VAL(100)); // four ints with value 100 + ft::vector third (second.begin(),second.end()); // iterating through second + ft::vector fourth (third); // a copy of third + + // the iterator constructor can also be used to construct from arrays: + T myints[] = {VAL(16),VAL(2),VAL(77),VAL(29)}; + ft::vector fifth (myints, myints + sizeof(myints) / sizeof(T) ); + + PRINT(fifth); + + DELETE +} + +TEST_V(tests_vector_operator_assignation) +{ + // title + TITLE(cplusplus.com reference) + + ft::vector foo (3,VAL(0)); + ft::vector bar (5,VAL(0)); + + bar = foo; + foo = ft::vector(); + + std::cout << "Size of foo: " << int(foo.size()) << '\n'; + std::cout << "Size of bar: " << int(bar.size()) << '\n'; + + DELETE +} + +TEST_V(tests_vector_begin) +{ + // title + TITLE(cplusplus.com reference :) + + ft::vector myvector; + for (int i=1; i<=5; i++) myvector.push_back(VAL(i)); + + PRINT(myvector); + + DELETE +} + +TEST_V(tests_vector_end) +{ + // title + TITLE(cplusplus.com reference :) + + ft::vector myvector; + for (int i=1; i<=5; i++) myvector.push_back(VAL(i)); + + PRINT(myvector); + + DELETE +} + +TEST_V(tests_vector_rbegin) +{ + // title + TITLE(cplusplus.com reference :) + + ft::vector myvector (5); + + int i=0; + + typename ft::vector::reverse_iterator rit = myvector.rbegin(); + for (; rit!= myvector.rend(); ++rit) + *rit = VAL(++i); + + PRINT(myvector); + + DELETE +} + +TEST_V(tests_vector_rend) +{ + // title + TITLE(cplusplus.com reference :) + + ft::vector myvector (5); // 5 default-constructed Ts + + typename ft::vector::reverse_iterator rit = myvector.rbegin(); + + int i=0; + for (rit = myvector.rbegin(); rit!= myvector.rend(); ++rit) + *rit = VAL(++i); + + PRINT(myvector); + + DELETE +} + +TEST_V(tests_vector_size) +{ + // title + TITLE(cplusplus.com reference :) + + ft::vector myarr; + std::cout << "0. size: " << myarr.size() << '\n'; + + for (int i=0; i<10; i++) myarr.push_back(VAL(i)); + std::cout << "1. size: " << myarr.size() << '\n'; + + myarr.insert (myarr.end(),10,VAL(100)); + std::cout << "2. size: " << myarr.size() << '\n'; + + myarr.pop_back(); + std::cout << "3. size: " << myarr.size() << '\n'; + + PRINT(myarr); + + DELETE +} + +TEST_V(tests_vector_max_size) +{ + // title + TITLE(cplusplus.com reference :) + + ft::vector myvector; + + // set some content in the vector: + for (int i=0; i<100; i++) myvector.push_back(VAL(i)); + + std::cout << "size: " << myvector.size() << "\n"; + std::cout << "capacity: " << myvector.capacity() << "\n"; + std::cout << "max_size: " << myvector.max_size() << "\n"; + + PRINT(myvector); + + DELETE +} + +TEST_V(tests_vector_resize) +{ + // title + TITLE(cplusplus.com reference :) + + ft::vector myvector; + + // set some initial content: + for (int i = 1; i < 10; i++) myvector.push_back(VAL(i)); + + myvector.resize(5); + myvector.resize(8,VAL(100)); + myvector.resize(12); + + PRINT(myvector); + + + // 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, VAL(1)); + PRINT(vector2); + + std::cout << "\n"; + + std::cout << "resize(15)\n"; + vector2.resize(15); + PRINT(vector2); + + std::cout << "\n"; + + std::cout << "resize(10)\n"; + vector2.resize(10); + PRINT(vector2); + + std::cout << "\n"; + + std::cout << "resize(19)\n"; + vector2.resize(19); + PRINT(vector2); + + std::cout << "\n"; + + std::cout << "resize(20)\n"; + vector2.resize(20); + PRINT(vector2); + + std::cout << "\n"; + + std::cout << "resize(21)\n"; + vector2.resize(21); + PRINT(vector2); + + 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, VAL(1)); + PRINT(vector3); + + std::cout << "\n"; + + std::cout << "resize(21)\n"; + vector3.resize(21); + PRINT(vector3); + + std::cout << "\n"; + + DELETE +} + +TEST_V(tests_vector_capacity) +{ + // title + TITLE(cplusplus.com reference :) + + ft::vector myvector; + + // set some content in the vector: + for (int i=0; i<100; i++) myvector.push_back(VAL(i)); + + std::cout << "size: " << (int) myvector.size() << '\n'; + std::cout << "capacity: " << (int) myvector.capacity() << '\n'; + std::cout << "max_size: " << (int) myvector.max_size() << '\n'; + + DELETE +} + +TEST_V(tests_vector_empty) +{ + // title + TITLE(cplusplus.com reference :) + + ft::vector myvector; + int sum (0); + + for (int i=1;i<=10;i++) myvector.push_back(VAL(i)); + + while (!myvector.empty()) + { + sum+=TOI(myvector.back()); + myvector.pop_back(); + } + + std::cout << "total: " << sum << '\n'; + + DELETE +} + +TEST_V(tests_vector_reserve) +{ + // title + TITLE(cplusplus.com reference :) + + typename ft::vector::size_type sz; + ft::vector foo; + + sz = foo.capacity(); + std::cout << "making foo grow:\n"; + for (int i=0; i<100; ++i) { + foo.push_back(VAL(i)); + if (sz!=foo.capacity()) { + sz = foo.capacity(); + std::cout << "capacity changed: " << sz << '\n'; + } + } + + ft::vector bar; + + sz = bar.capacity(); + bar.reserve(100); // this is the only difference with foo above + std::cout << "making bar grow:\n"; + for (int i=0; i<100; ++i) { + bar.push_back(VAL(i)); + if (sz!=bar.capacity()) { + sz = bar.capacity(); + std::cout << "capacity changed: " << sz << '\n'; + } + } + + DELETE +} + +TEST_V(tests_vector_operator_access) +{ + // title + TITLE(cplusplus.com reference :) + + ft::vector myvector (10); // 10 zero-initialized elements + typename ft::vector::size_type sz = myvector.size(); + + // assign some values: + for (unsigned i=0; i myvector (10); // 10 zero-initialized ints + + // assign some values: + for (unsigned i=0; i myvector; + + myvector.push_back(VAL(78)); + myvector.push_back(VAL(16)); + + // now front equals 78, and back 16 + + //myvector.front() -= myvector.back(); + + std::cout << "myvector.front() is now " << myvector.front() << '\n'; + + PRINT(myvector) + + DELETE +} + +TEST_V(tests_vector_back) +{ + // title + TITLE(cplusplus.com reference :) + + ft::vector myvector; + + myvector.push_back(VAL(78)); + myvector.push_back(VAL(16)); + + // now front equals 78, and back 16 + + // myvector.front() -= myvector.back(); + std::cout << "myvector.front() is now " << myvector.front() << '\n'; + PRINT(myvector) + + DELETE +} + +TEST_V(tests_vector_assign) +{ + // title + TITLE(cplusplus.com reference :) + + ft::vector first; + ft::vector second; + ft::vector third; + + first.assign (7,VAL(100)); // 7 ints with a value of 100 + + typename ft::vector::iterator it; + it=first.begin()+1; + + second.assign (it,first.end()-1); // the 5 central values of first + + T myints[] = {VAL(1776),VAL(7),VAL(4)}; + third.assign (myints,myints+3); // assigning from array. + + std::cout << "Size of first: " << int (first.size()) << '\n'; + std::cout << "Size of second: " << int (second.size()) << '\n'; + std::cout << "Size of third: " << int (third.size()) << '\n'; + + // title + TITLE(capacity tests of assignation :) + + ft::vector myvector; + + std::cout << "capacity before assignation : " << myvector.capacity() << "\n"; + + std::cout << "\nassign 1\n"; + myvector.assign(1, VAL(12)); + PRINT(myvector) + + std::cout << "\nassign 3\n"; + myvector.assign(3, VAL(12)); + PRINT(myvector) + + std::cout << "\nassign 7268\n"; + myvector.assign(7268, VAL(12)); + PRINT(myvector) + + + // title + TITLE(tests of iterators :) + + ft::vector int_vector_1; + ft::vector int_vector_2; + ft::vector int_vector_3; + ft::vector it_vector; + + std::cout << "\nassign 1\n"; + int_vector_1.assign(1, VAL(12)); + it_vector.assign(int_vector_1.begin(), int_vector_1.end()); + PRINT(it_vector) + + std::cout << "\nassign 0\n"; + int_vector_2.assign(1, VAL(6)); + it_vector.assign(int_vector_2.begin(), int_vector_2.end() - 1); + PRINT(it_vector) + + std::cout << "\nassign 266 - 13 - 172 = 81\n"; + int_vector_3.assign(266, VAL(1)); + it_vector.assign(int_vector_3.begin() + 13, int_vector_3.end() - 172); + PRINT(it_vector) + + DELETE +} + +TEST_V(tests_vector_push_back) +{ + // title + TITLE(cplusplus.com reference :) + + ft::vector myvector; + + 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++) + { + myvector.push_back(VAL(myint[i])); + std::cout << "[capacity : " + << std::setw(2) << myvector.capacity() << "] " + << myvector[i] << "\n"; + } + PRINT(myvector) + + // title + TITLE(big push back :) + + for (int i = 0; i < 72363; i++) + { + myvector.push_back(VAL(9)); + std::cout << "[" << i + << ":" << myvector.capacity() << "] "; + } + std::cout << " -> size : " << myvector.size() << " , capacity :" << myvector.capacity() << "\n"; + + DELETE +} + +TEST_V(tests_vector_pop_back) +{ + // title + TITLE(cplusplus.com reference :) + + ft::vector myvector; + + int sum (0); + + myvector.push_back (VAL(100)); + myvector.push_back (VAL(200)); + myvector.push_back (VAL(300)); + + while (!myvector.empty()) + { + sum+=TOI(myvector.back()); + myvector.pop_back(); + } + + 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'; + + DELETE +} + +TEST_V(tests_vector_insert) +{ + typename ft::vector::iterator it; + + // title + TITLE(cplusplus.com reference :) + + ft::vector myvector (3,VAL(100)); + + it = myvector.begin(); + it = myvector.insert ( it , VAL(200) ); + myvector.insert (it,2,VAL(300)); + + ft::vector anothervector (2,VAL(400)); + it = myvector.begin(); + myvector.insert (it+2,anothervector.begin(),anothervector.end()); + + T myarray [] = { VAL(501),VAL(502),VAL(503) }; + myvector.insert (myvector.begin(), myarray, myarray+3); + + PRINT(myvector) + + // title + TITLE(tests positions on insert(pos, value) :) + + ft::vector myvector2 (3,VAL(100)); + + it = myvector2.begin(); + std::cout << "size:" << myvector2.size() << " capacity:" << myvector2.capacity() << "\n"; + myvector2.insert ( it , VAL(200) ); + PRINT(myvector2) + + ft::vector myvector3 (3,VAL(100)); + + it = myvector3.end(); + std::cout << "\nsize:" << myvector3.size() << " capacity:" << myvector3.capacity() << "\n"; + myvector3.insert ( it , VAL(200) ); + PRINT(myvector3) + + ft::vector myvector4 (3,VAL(100)); + + it = myvector4.begin() + 2; + std::cout << "\nsize:" << myvector3.size() << " capacity:" << myvector3.capacity() << "\n"; + myvector4.insert ( it , VAL(200) ); + PRINT(myvector4) + + + // title + TITLE(tests insert(pos, size, value) :) + + ft::vector myvector5; + + for (int i = 1; i <= 5; i++) + myvector5.push_back(VAL(i * 100)); + + it = myvector5.begin() + 1; + myvector5.insert ( it , VAL(150) ); + + it = myvector5.end(); + myvector5.insert (it,2,VAL(600)); + + it = myvector5.end() - 2; + myvector5.insert (it,2,VAL(550)); + + PRINT(myvector5) + + + // title + TITLE(tests insert(pos, first, last) :) + + ft::vector myvector6; + + myvector6.assign(5, VAL(42)); + + it = myvector6.begin() + 2; + myvector6.insert ( it, myvector5.begin() + 3, myvector5.end() - 2 ); + PRINT(myvector6) + + DELETE +} + +TEST_V(tests_vector_erase) +{ + // title + TITLE(cplusplus.com reference :) + + ft::vector myvector; + + // set some values (from 1 to 10) + for (int i=1; i<=10; i++) myvector.push_back(VAL(i)); + + // erase the 6th element + myvector.erase (myvector.begin()+5); + + // erase the first 3 elements: + myvector.erase (myvector.begin(),myvector.begin()+3); + + PRINT(myvector) + + // title + TITLE(test iterator bigger or equal :) + ft::vector vector2; + + for (int i=1; i<=100; i++) vector2.push_back(VAL(i)); + PRINT(vector2) + + std::cout << "\nerase pos(7,36) :\n"; + vector2.erase(vector2.begin() + 7, vector2.begin() + 36); + PRINT(vector2) + + std::cout << "\nerase pos(46,54) :\n"; + vector2.erase(vector2.begin() + 46, vector2.begin() + 54); + PRINT(vector2) + + std::cout << "\nerase pos(7,7) :\n"; + vector2.erase(vector2.begin() + 7, vector2.begin() + 7); + PRINT(vector2) + + DELETE +} + +TEST_V(tests_vector_swap) +{ + // title + TITLE(cplusplus.com reference :) + + ft::vector foo (3,VAL(100)); // three ints with a value of 100 + ft::vector bar (5,VAL(200)); // five ints with a value of 200 + + foo.swap(bar); + + PRINT(foo) + + PRINT(bar) + + DELETE +} + +TEST_V(tests_vector_clear) +{ + // title + TITLE(cplusplus.com reference :) + + ft::vector myvector; + myvector.push_back (VAL(100)); + myvector.push_back (VAL(200)); + myvector.push_back (VAL(300)); + + PRINT(myvector) + + myvector.clear(); + myvector.push_back (VAL(1101)); + myvector.push_back (VAL(2202)); + + PRINT(myvector) + + DELETE +} + +TEST_V(tests_vector_get_allocator) +{ + // title + TITLE(cplusplus.com reference :) + + ft::vector myvector; + T * p; + unsigned int i; + + // allocate an array with space for 5 elements using vector's allocator: + p = myvector.get_allocator().allocate(5); + + // construct values in-place on the array: + for (i=0; i<5; i++) myvector.get_allocator().construct(&p[i],VAL(i)); + + std::cout << "The allocated array contains:"; + for (i=0; i<5; i++) std::cout << ' ' << p[i]; + std::cout << '\n'; + + // destroy and deallocate: + for (i=0; i<5; i++) myvector.get_allocator().destroy(&p[i]); + myvector.get_allocator().deallocate(p,5); + + DELETE +} + +TEST_V(tests_vector_relational_operators) +{ + // title + TITLE(cplusplus.com reference :) + + ft::vector foo (3,VAL(100)); // three ints with a value of 100 + ft::vector bar (2,VAL(200)); // two ints with a value of 200 + + if (foo==bar) std::cout << "foo and bar are equal\n"; + if (foo!=bar) std::cout << "foo and bar are not equal\n"; + if (foo< bar) std::cout << "foo is less than bar\n"; + if (foo> bar) std::cout << "foo is greater than bar\n"; + if (foo<=bar) std::cout << "foo is less than or equal to bar\n"; + if (foo>=bar) std::cout << "foo is greater than or equal to bar\n"; + + DELETE +} + +TEST_V(tests_vector_swap_non_member) +{ + // title + TITLE(cplusplus.com reference :) + + ft::vector foo (3,VAL(100)); // three ints with a value of 100 + ft::vector bar (5,VAL(200)); // five ints with a value of 200 + + foo.swap(bar); + + PRINT(foo) + + PRINT(bar) + + DELETE +} + +TEST_V(tests_vector_reverse_iterators) +{ + // title + TITLE(cplusplus.com reference) + TITLE(::constructor ::operator* ::operator++(val)) + + ft::vector myvector; + for (int i=0; i<10; i++) myvector.push_back(VAL(i)); + typedef typename ft::vector::iterator iter_type; + // ? 0 1 2 3 4 5 6 7 8 9 ? + iter_type from (myvector.begin()); // ^ + iter_type until (myvector.end()); // ^ + ft::reverse_iterator rev_until (from); // ^ + ft::reverse_iterator rev_from (until); // ^ + + std::cout << "myvector:"; + while (rev_from != rev_until) + std::cout << ' ' << *rev_from++; + std::cout << '\n'; + + + // title + TITLE(::operator++) + + std::cout << "myvector:"; + while (rev_from != rev_until) { + std::cout << ' ' << *rev_from; + ++rev_from; + } + std::cout << '\n'; + + + // title + TITLE(::base) + + ft::reverse_iterator rev_end (myvector.begin()); + ft::reverse_iterator rev_begin (myvector.end()); + std::cout << "myvector:"; + for (iter_type it = rev_end.base(); it != rev_begin.base(); ++it) + std::cout << ' ' << *it; + std::cout << '\n'; + + + // title + TITLE(::operator+) + + ft::reverse_iterator rev_it_add; + rev_it_add = myvector.rbegin() +3; + std::cout << "The fourth element from the end is: " << *rev_it_add << '\n'; + + + // title + TITLE(::operator+=) + + ft::reverse_iterator rev_it_add_equal = myvector.rbegin(); + rev_it_add_equal += 2; + std::cout << "The third element from the end is: " << *rev_it_add_equal << '\n'; + + + // title + TITLE(::operator-) + + ft::reverse_iterator rev_it_minus; + rev_it_minus = myvector.rend() - 3; + std::cout << "myvector.rend()-3 points to: " << *rev_it_minus << '\n'; + + + // title + TITLE(::operator--) + + ft::reverse_iterator rev_it_minus_minus = rev_begin; + while ( rev_it_minus_minus != rev_end ) + std::cout << *rev_it_minus_minus++ << ' '; + std::cout << '\n'; + + while ( rev_it_minus_minus != rev_begin ) + std::cout << *(--rev_it_minus_minus) << ' '; + std::cout << '\n'; + + + // title + TITLE(::operator-=) + + ft::reverse_iterator rev_it_minus_equal = myvector.rend(); + rev_it_minus_equal -= 4; + std::cout << "rev_it_minus_equal now points to: " << *rev_it_minus_equal << '\n'; + + + // title + TITLE(::operator->) + + std::map numbers; + numbers.insert (std::make_pair(1,"one")); + numbers.insert (std::make_pair(2,"two")); + numbers.insert (std::make_pair(3,"three")); + + typedef std::map::iterator map_iter; + ft::reverse_iterator rev_map_end (numbers.begin()); + ft::reverse_iterator rev_map_ite (numbers.end()); + + for ( ; rev_map_ite != rev_map_end ; ++rev_map_ite ) + std::cout << rev_map_ite->first << ' ' << rev_map_ite->second << '\n'; + + + // title + TITLE(::operator[]) + + ft::reverse_iterator rev_it_at = myvector.rbegin(); + std::cout << "The fourth element from the end is: " << rev_it_at[3] << '\n'; + + + // title + TITLE(::operator- non-member) + + ft::reverse_iterator::iterator> rev_it_from,rev_it_until; + rev_it_from = myvector.rbegin(); + rev_it_until = myvector.rend(); + std::cout << "myvector has " << (rev_it_until-rev_it_from) << " elements.\n"; + + + // title + TITLE(::operator+ non-member) + + ft::reverse_iterator rev_it_n_memb; + rev_it_n_memb = 3 + myvector.rbegin(); + std::cout << "The fourth element from the end is: " << *rev_it_n_memb << '\n'; + + DELETE +} +