├── README.md ├── tester ├── tester.cpp ├── main.cpp ├── tester.hpp ├── tester_stack.cpp └── tester_queue.cpp ├── Makefile └── containers ├── stack.hpp ├── queue.hpp ├── utils ├── binary_search_tree.hpp ├── list_iterator.hpp ├── deque_iterator.hpp ├── binary_search_tree_iterator.hpp └── random_access_iterator.hpp ├── map.hpp └── vector.hpp /README.md: -------------------------------------------------------------------------------- 1 | # ft_containers 2 | Ft_containers (42cursus) 2019-2021 3 | 4 | - Actual Status : Finished 5 | - Result : 103% 6 | - Obsetvations : I think this is the project I'm most proud of. 7 | 8 | [![forthebadge](https://forthebadge.com/images/badges/made-with-c-plus-plus.svg)](https://forthebadge.com) 9 | [![forthebadge](https://forthebadge.com/images/badges/built-with-love.svg)](https://forthebadge.com) 10 | 11 | This is my ft_containers project from the 42 cursus, 12 | need help: 13 | rchallie@student.42.fr 14 | -------------------------------------------------------------------------------- /tester/tester.cpp: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* tester.cpp :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: rchallie +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2020/11/29 16:56:18 by rchallie #+# #+# */ 9 | /* Updated: 2020/11/29 16:56:35 by rchallie ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | # include "tester.hpp" 14 | 15 | bool printBoolResult(std::fstream& fs, bool stl_bool, bool ft_bool) 16 | { 17 | fs << "\nBool result : \n"; 18 | fs << " - STL : " << (stl_bool ? "true" : "false") << std::endl; 19 | fs << " - FT : " << (ft_bool ? "true" : "false") << std::endl; 20 | 21 | return (stl_bool == ft_bool); 22 | } -------------------------------------------------------------------------------- /tester/main.cpp: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* main.cpp :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: rchallie +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2020/11/27 17:53:07 by rchallie #+# #+# */ 9 | /* Updated: 2020/12/10 21:36:17 by rchallie ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "tester.hpp" 14 | 15 | #include 16 | 17 | int main() 18 | { 19 | test_vector(); 20 | std::cout << "\n"; 21 | test_list(); 22 | std::cout << "\n"; 23 | test_map(); 24 | std::cout << "\n"; 25 | test_deque(); 26 | std::cout << "\n"; 27 | test_stack(); 28 | std::cout << "\n"; 29 | test_queue(); 30 | } -------------------------------------------------------------------------------- /tester/tester.hpp: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* tester.hpp :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: rchallie +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2020/11/27 18:17:44 by rchallie #+# #+# */ 9 | /* Updated: 2020/12/07 18:24:43 by rchallie ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #ifndef TESTER_HPP 14 | # define TESTER_HPP 15 | 16 | # include 17 | # include 18 | # include 19 | # include 20 | # include 21 | 22 | # define NORMAL "\033[0;37m" 23 | # define UNDERLINE "\033[4m" 24 | # define BOLD_RED "\033[1;31m" 25 | # define BOLD_GREEN "\033[1;32m" 26 | 27 | template 28 | std::string equal(const T& t1, const T& t2) 29 | { 30 | return (t1 == t2 ? "✔" : "✘"); 31 | } 32 | 33 | template 34 | bool equalbool(const T& t1, const T& t2) 35 | { 36 | return (t1 == t2 ? true : false); 37 | } 38 | 39 | // t1 == stl 40 | // t2 == ft 41 | template 42 | static bool printSingleValue(std::fstream& fs, const T& t1, const T& t2) 43 | { 44 | fs << "\n══════════════════════════════════════════════════════════════\n"; 45 | fs << "Value from :\n"; 46 | fs << "STL : " << t1 << "\n"; 47 | fs << "FT [" << equal(t1, t2) << "]: " << t2 << "\n"; 48 | fs << "══════════════════════════════════════════════════════════════\n"; 49 | return (t1 == t2 ? true : false); 50 | } 51 | 52 | bool printBoolResult(std::fstream& fs, bool stl_bool, bool ft_bool); 53 | 54 | void test_vector(); 55 | void test_list(); 56 | void test_map(); 57 | void test_stack(); 58 | void test_queue(); 59 | void test_deque(); 60 | 61 | #endif -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # **************************************************************************** # 2 | # # 3 | # ::: :::::::: # 4 | # Makefile :+: :+: :+: # 5 | # +:+ +:+ +:+ # 6 | # By: rchallie +#+ +:+ +#+ # 7 | # +#+#+#+#+#+ +#+ # 8 | # Created: 2020/12/03 23:23:13 by rchallie #+# #+# # 9 | # Updated: 2020/12/10 21:36:51 by rchallie ### ########.fr # 10 | # # 11 | # **************************************************************************** # 12 | 13 | # SIMPLE ======================================================================= 14 | NAME = ft_container_tester 15 | # ============================================================================== 16 | 17 | # SRCS ========================================================================= 18 | SOURCES_FOLDER = ./tester/ 19 | 20 | SOURCES = main.cpp \ 21 | tester.cpp \ 22 | tester_map.cpp \ 23 | tester_list.cpp \ 24 | tester_deque.cpp \ 25 | tester_vector.cpp \ 26 | tester_queue.cpp \ 27 | tester_stack.cpp 28 | 29 | # ============================================================================== 30 | 31 | # INCLUDES ===================================================================== 32 | INCLUDE = ./tester/tester.hpp 33 | # ============================================================================== 34 | 35 | # FLAGS ======================================================================== 36 | FLAGS = -Wall -Wextra -Werror --std=c++98 37 | # ============================================================================== 38 | 39 | # OBJECTS ====================================================================== 40 | OBJECTS_FOLDER = ./tester/objects/ 41 | 42 | OBJECT = $(SOURCES:.cpp=.o) 43 | OBJECTS = $(addprefix $(OBJECTS_FOLDER), $(OBJECT)); 44 | # ============================================================================== 45 | 46 | # TESTER ======================================================================= 47 | 48 | $(OBJECTS_FOLDER)%.o : $(SOURCES_FOLDER)%.cpp $(INCLUDE) 49 | @mkdir -p $(OBJECTS_FOLDER) 50 | @echo "Compiling: $<" 51 | @clang++ $(FLAGS) -c $< -o $@ 52 | 53 | $(NAME): $(OBJECTS) 54 | @clang++ $(FLAGS) -o $(NAME) $(OBJECTS) 55 | 56 | all: $(NAME) 57 | 58 | clean: 59 | @echo "Cleaning: $(OBJECTS_FOLDER)" 60 | @rm -rf $(OBJECTS_FOLDER) 61 | @echo "Cleaning: ./tester/vectors_output" 62 | @rm -rf ./tester/vectors_output 63 | @echo "Cleaning: ./tester/lists_output" 64 | @rm -rf ./tester/lists_output 65 | @echo "Cleaning: ./tester/stacks_output" 66 | @rm -rf ./tester/stacks_output 67 | @echo "Cleaning: ./tester/queues_output" 68 | @rm -rf ./tester/queues_output 69 | @echo "Cleaning: ./tester/deques_output" 70 | @rm -rf ./tester/deques_output 71 | @echo "Cleaning: ./tester/maps_output" 72 | @rm -rf ./tester/maps_output 73 | 74 | fclean: clean 75 | @echo "Cleaning: $(NAME)" 76 | @rm -f $(NAME) 77 | 78 | re: fclean all 79 | # ============================================================================== 80 | 81 | # SUP ========================================================================== 82 | 83 | run: $(NAME) 84 | @./$(NAME) 85 | 86 | # ============================================================================== 87 | -------------------------------------------------------------------------------- /containers/stack.hpp: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* stack.hpp :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: rchallie +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2020/08/07 11:10:54 by rchallie #+# #+# */ 9 | /* Updated: 2020/12/10 21:34:35 by rchallie ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #ifndef STACK_HPP 14 | # define STACK_HPP 15 | 16 | # include "deque.hpp" 17 | 18 | namespace ft 19 | { 20 | template > class stack 21 | { 22 | public: 23 | 24 | /* 25 | ** The first template parameter (T) 26 | */ 27 | typedef T value_type; 28 | 29 | /* 30 | ** The second template parameter (container) 31 | ** It's the type of underlying container object. 32 | */ 33 | typedef Container container_type; 34 | 35 | /* 36 | ** The size type (usually size_t) 37 | */ 38 | typedef size_t size_type; 39 | 40 | /* 41 | ** Default constructor. 42 | ** Construct an empty stack container adaptor object. 43 | ** 44 | ** @param Container object, is the type of the 45 | ** underlying container type. 46 | */ 47 | explicit stack (const container_type& ctnr = container_type()) 48 | : 49 | ct(ctnr) 50 | {} 51 | 52 | /* 53 | ** @brief Destroy the container object. 54 | ** Detroy all elements in the container. 55 | ** Use the destructor of the underlying containter object. 56 | */ 57 | ~stack() 58 | {} 59 | 60 | /* 61 | ** @brief Call member "empty()" of the underlying 62 | ** container object. 63 | ** 64 | ** @return true if the container is empty, otherwise 65 | ** false. 66 | */ 67 | bool empty() const { return (this->ct.empty()); } 68 | 69 | /* 70 | ** @brief Call member "size()" of the underlying 71 | ** container object. 72 | ** 73 | ** @return the size of the container. (Number of elements 74 | ** in it). 75 | */ 76 | size_type size() const { return (this->ct.size()); } 77 | 78 | /* 79 | ** @brief Give a reference to the last 80 | ** element inserted in the container. 81 | ** Call member "back()" of the underlying container 82 | ** object. 83 | ** 84 | ** @return a reference to the top element in the stack. 85 | */ 86 | value_type& top() { return (this->ct.back()); } 87 | 88 | /* 89 | ** @brief Give a constant reference to the last 90 | ** element inserted in the container. 91 | ** Call member "back()" of the underlying container 92 | ** object. 93 | ** 94 | ** @return a constant reference to the top element in the stack. 95 | */ 96 | const value_type& top() const { return (this->ct.back()); } 97 | 98 | /* 99 | ** @brief insert a new element at the top of the 100 | ** stack. The element is a copy of value parameter. 101 | ** Call member "push_back()" of the underlying container 102 | ** object. 103 | ** 104 | ** @param val the value to insert. 105 | */ 106 | void push (const value_type& val) { this->ct.push_back(val); } 107 | 108 | /* 109 | ** @brief Remove the element on the top of the stack. 110 | ** The element removed the last inserted on the stack. 111 | ** Call the member "pop_back()" of the underlying container 112 | ** object. 113 | */ 114 | void pop() { this->ct.pop_back(); } 115 | 116 | /* 117 | ** @brief Declarations of prototypes for the 118 | ** non members functions that needs to access 119 | ** the protected variable. 120 | */ 121 | 122 | template 123 | friend bool operator== (const ft::stack& lhs, const ft::stack& rhs); 124 | 125 | template 126 | friend bool operator!= (const ft::stack& lhs, const ft::stack& rhs); 127 | 128 | template 129 | friend bool operator< (const ft::stack& lhs, const ft::stack& rhs); 130 | 131 | template 132 | friend bool operator<= (const ft::stack& lhs, const ft::stack& rhs); 133 | 134 | template 135 | friend bool operator> (const ft::stack& lhs, const ft::stack& rhs); 136 | 137 | template 138 | friend bool operator>= (const ft::stack& lhs, const ft::stack& rhs); 139 | 140 | protected: 141 | container_type ct; 142 | }; 143 | 144 | // Each of the operator call the same operator of the 145 | // underlying container objects. 146 | 147 | /* 148 | ** @brief Compare stack container to know 149 | ** if they are different. Equivalent to !(lsh == rhs). 150 | ** 151 | ** @param lhs stack to compare with "rhs". 152 | ** @param rhs stack for comparison of "lhs". 153 | ** @return true if they are different, false otherwise. 154 | */ 155 | template 156 | bool operator== (const ft::stack& lhs, const ft::stack& rhs) 157 | { return (lhs.ct == rhs.ct); } 158 | 159 | /* 160 | ** @brief Compare stack container to know 161 | ** if they are different. Equivalent to !(lsh == rhs). 162 | ** 163 | ** @param lhs stack to compare with "rhs". 164 | ** @param rhs stack for comparison of "lhs". 165 | ** @return true if they are different, false otherwise. 166 | */ 167 | template 168 | bool operator!= (const ft::stack& lhs, const ft::stack& rhs) 169 | { return (lhs.ct != rhs.ct); } 170 | 171 | /* 172 | ** @brief Compare stack container to know 173 | ** if "lhs" elements are less than "rhs". 174 | ** 175 | ** @param lhs stack to compare with "rhs". 176 | ** @param rhs stack for comparison of "lhs". 177 | ** @return true if "lhs" is less, false otherwise. 178 | */ 179 | template 180 | bool operator< (const ft::stack& lhs, const ft::stack& rhs) 181 | { return (lhs.ct < rhs.ct); } 182 | 183 | /* 184 | ** @brief Compare stack container to know 185 | ** if "lhs" elements are less or equal than "rhs". 186 | ** 187 | ** @param lhs stack to compare with "rhs". 188 | ** @param rhs stack for comparison of "lhs". 189 | ** @return true if "lhs" is less of equal, false otherwise. 190 | */ 191 | template 192 | bool operator<= (const ft::stack& lhs, const ft::stack& rhs) 193 | { return (lhs.ct <= rhs.ct); } 194 | 195 | /* 196 | ** @brief Compare stack container to know 197 | ** if "lhs" elements are superior than "rhs". 198 | ** 199 | ** @param lhs stack to compare with "rhs". 200 | ** @param rhs stack for comparison of "lhs". 201 | ** @return true if "lhs" is superior, false otherwise. 202 | */ 203 | template 204 | bool operator> (const ft::stack& lhs, const ft::stack& rhs) 205 | { return (lhs.ct > rhs.ct); } 206 | 207 | /* 208 | ** @brief Compare stack container to know 209 | ** if "lhs" elements are superior or equal than "rhs". 210 | ** 211 | ** @param lhs stack to compare with "rhs". 212 | ** @param rhs stack for comparison of "lhs". 213 | ** @return true if "lhs" is superior or equal, false otherwise. 214 | */ 215 | template 216 | bool operator>= (const ft::stack& lhs, const ft::stack& rhs) 217 | { return (lhs.ct >= rhs.ct); } 218 | } 219 | 220 | #endif -------------------------------------------------------------------------------- /containers/queue.hpp: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* queue.hpp :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: rchallie +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2020/08/07 12:15:32 by rchallie #+# #+# */ 9 | /* Updated: 2020/12/10 21:35:11 by rchallie ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #ifndef QUEUE_HPP 14 | # define QUEUE_HPP 15 | 16 | # include "deque.hpp" 17 | 18 | namespace ft 19 | { 20 | template > class queue 21 | { 22 | public: 23 | 24 | /* 25 | ** The first template parameter (T) 26 | */ 27 | typedef T value_type; 28 | 29 | /* 30 | ** The second template parameter (container) 31 | ** It's the type of underlying container object. 32 | */ 33 | typedef Container container_type; 34 | 35 | /* 36 | ** The size type (usually size_t) 37 | */ 38 | typedef size_t size_type; 39 | 40 | /* 41 | ** Default constructor. 42 | ** Construct an empty queue container adaptor object. 43 | ** 44 | ** @param Container object, is the type of the 45 | ** underlying container type. 46 | */ 47 | explicit queue (const container_type& ctnr = container_type()) 48 | : 49 | ct(ctnr) 50 | {} 51 | 52 | /* 53 | ** @brief Destroy the container object. 54 | ** Detroy all elements in the container. 55 | ** Use the destructor of the underlying containter object. 56 | */ 57 | ~queue() 58 | {} 59 | 60 | /* 61 | ** @brief Call member "empty()" of the underlying 62 | ** container object. 63 | ** 64 | ** @return true if the container is empty, otherwise 65 | ** false. 66 | */ 67 | bool empty() const { return (ct.empty()); } 68 | 69 | /* 70 | ** @brief Call member "size()" of the underlying 71 | ** container object. 72 | ** 73 | ** @return the size of the container. (Number of elements 74 | ** in it). 75 | */ 76 | size_type size() const { return (ct.size()); } 77 | 78 | /* 79 | ** @brief Give a reference to the oldest element in the 80 | ** queue. It's the same element that is popped 81 | ** out when member "pop()" is called. 82 | ** 83 | ** @return the reference. 84 | */ 85 | value_type& front() { return (ct.front()); } 86 | 87 | /* 88 | ** @brief Give a constant reference to the oldest element 89 | ** in the queue. It's the same element that is popped 90 | ** out when member "pop()" is called. 91 | ** 92 | ** @return the const reference. 93 | */ 94 | const value_type& front() const { return (ct.front()); } 95 | 96 | /* 97 | ** @brief Give a reference to the last 98 | ** element inserted in the container. 99 | ** Call member "back()" of the underlying container 100 | ** object. 101 | ** 102 | ** @return a reference to the last element in the queue. 103 | */ 104 | value_type& back() { return (ct.back()); } 105 | 106 | /* 107 | ** @brief Give a constant reference to the last 108 | ** element inserted in the container. 109 | ** Call member "back()" of the underlying container 110 | ** object. 111 | ** 112 | ** @return a constant reference to the last element in the queue. 113 | */ 114 | const value_type& back() const { return (ct.back()); } 115 | 116 | /* 117 | ** @brief insert a new element at the end of the 118 | ** queue. The element is a copy of value parameter. 119 | ** Call member "push_back()" of the underlying container 120 | ** object. 121 | ** 122 | ** @param val the value to insert. 123 | */ 124 | void push (const value_type& val) { ct.push_back(val); } 125 | 126 | /* 127 | ** @brief Remove the element is the oldest element on the queue. 128 | ** Call the member "pop_back()" of the underlying container 129 | ** object. 130 | */ 131 | void pop () { ct.pop_front(); } 132 | 133 | /* 134 | ** @brief Declarations of prototypes for the 135 | ** non members functions that needs to access 136 | ** the protected variable. 137 | */ 138 | 139 | template 140 | friend bool operator== (const ft::queue& lhs, const ft::queue& rhs); 141 | 142 | template 143 | friend bool operator!= (const ft::queue& lhs, const ft::queue& rhs); 144 | 145 | template 146 | friend bool operator< (const ft::queue& lhs, const ft::queue& rhs); 147 | 148 | template 149 | friend bool operator<= (const ft::queue& lhs, const ft::queue& rhs); 150 | 151 | template 152 | friend bool operator> (const ft::queue& lhs, const ft::queue& rhs); 153 | 154 | template 155 | friend bool operator>= (const ft::queue& lhs, const ft::queue& rhs); 156 | 157 | protected: 158 | container_type ct; 159 | }; 160 | 161 | // Each of the operator call the same operator of the 162 | // underlying container objects. 163 | 164 | /* 165 | ** @brief Compare queue container to know 166 | ** if they are different. Equivalent to !(lsh == rhs). 167 | ** 168 | ** @param lhs queue to compare with "rhs". 169 | ** @param rhs queue for comparison of "lhs". 170 | ** @return true if they are different, false otherwise. 171 | */ 172 | template 173 | bool operator== (const ft::queue& lhs, const ft::queue& rhs) 174 | { return (lhs.ct == rhs.ct); } 175 | 176 | /* 177 | ** @brief Compare queue container to know 178 | ** if they are different. Equivalent to !(lsh == rhs). 179 | ** 180 | ** @param lhs queue to compare with "rhs". 181 | ** @param rhs queue for comparison of "lhs". 182 | ** @return true if they are different, false otherwise. 183 | */ 184 | template 185 | bool operator!= (const ft::queue& lhs, const ft::queue& rhs) 186 | { return (lhs.ct != rhs.ct); } 187 | 188 | /* 189 | ** @brief Compare queue container to know 190 | ** if "lhs" elements are less than "rhs". 191 | ** 192 | ** @param lhs queue to compare with "rhs". 193 | ** @param rhs queue for comparison of "lhs". 194 | ** @return true if "lhs" is less, false otherwise. 195 | */ 196 | template 197 | bool operator< (const ft::queue& lhs, const ft::queue& rhs) 198 | { return (lhs.ct < rhs.ct); } 199 | 200 | /* 201 | ** @brief Compare queue container to know 202 | ** if "lhs" elements are less or equal than "rhs". 203 | ** 204 | ** @param lhs queue to compare with "rhs". 205 | ** @param rhs queue for comparison of "lhs". 206 | ** @return true if "lhs" is less of equal, false otherwise. 207 | */ 208 | template 209 | bool operator<= (const ft::queue& lhs, const ft::queue& rhs) 210 | { return (lhs.ct <= rhs.ct); } 211 | 212 | /* 213 | ** @brief Compare queue container to know 214 | ** if "lhs" elements are superior than "rhs". 215 | ** 216 | ** @param lhs queue to compare with "rhs". 217 | ** @param rhs queue for comparison of "lhs". 218 | ** @return true if "lhs" is superior, false otherwise. 219 | */ 220 | template 221 | bool operator> (const ft::queue& lhs, const ft::queue& rhs) 222 | { return (lhs.ct > rhs.ct); } 223 | 224 | /* 225 | ** @brief Compare queue container to know 226 | ** if "lhs" elements are superior or equal than "rhs". 227 | ** 228 | ** @param lhs queue to compare with "rhs". 229 | ** @param rhs queue for comparison of "lhs". 230 | ** @return true if "lhs" is superior or equal, false otherwise. 231 | */ 232 | template 233 | bool operator>= (const ft::queue& lhs, const ft::queue& rhs) 234 | { return (lhs.ct >= rhs.ct); } 235 | } 236 | 237 | #endif -------------------------------------------------------------------------------- /containers/utils/binary_search_tree.hpp: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* binary_search_tree.hpp :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: rchallie +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2020/12/07 17:12:26 by rchallie #+# #+# */ 9 | /* Updated: 2020/12/10 21:32:14 by rchallie ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #ifndef BINARY_SEARCH_TREE_HPP 14 | # define BINARY_SEARCH_TREE_HPP 15 | 16 | #include "./utils.hpp" 17 | #include "./binary_search_tree_iterator.hpp" 18 | 19 | /* 20 | ** Binary Search Tree: 21 | ** Classement method of nodes values in tree. If a node value is 22 | ** superior to the a node, it's classed at right, otherwise at left 23 | ** if it's lower. Like : 24 | ** 25 | ** 42 26 | ** / \ 27 | ** 15 58 28 | ** / \ 29 | ** 2 26 30 | */ 31 | 32 | namespace ft 33 | { 34 | template , class Node = ft::BST_Node, 35 | class Type_Alloc = std::allocator, class Node_Alloc = std::allocator > 36 | class Binary_search_tree 37 | { 38 | public : 39 | 40 | /* Self type */ 41 | typedef Binary_search_tree self; 42 | 43 | /* A reference to the self type */ 44 | typedef self& self_reference; 45 | 46 | /* The first template argument */ 47 | typedef T value_type; 48 | 49 | /* Stored Node type */ 50 | typedef Node node_type; 51 | 52 | /* Pointer to stored node */ 53 | typedef Node * node_pointer; 54 | 55 | /* Node allocator */ 56 | typedef Node_Alloc node_alloc; 57 | 58 | /* Iterator on stored node */ 59 | typedef ft::BST_iterator iterator; 60 | 61 | /* Same than iterator, here for base container template */ 62 | typedef ft::BST_const_iterator const_iterator; 63 | 64 | /* Size_t */ 65 | typedef size_t size_type; 66 | 67 | /* 68 | ** @brief Contruct an empty binary search tree 69 | */ 70 | Binary_search_tree (const node_alloc& node_alloc_init = node_alloc()) 71 | : 72 | _node_alloc(node_alloc_init) 73 | { 74 | _last_node = _node_alloc.allocate(1); 75 | _node_alloc.construct(_last_node, Node(_last_node, _last_node, _last_node)); 76 | } 77 | 78 | /* 79 | ** It's at that use the tree to delete all nodes. 80 | */ 81 | ~Binary_search_tree () 82 | { 83 | _node_alloc.destroy(_last_node); 84 | _node_alloc.deallocate(_last_node, 1); 85 | } 86 | 87 | /* 88 | ** @brief Insert a new node that contain "to_insert". 89 | */ 90 | ft::pair insertPair(value_type to_insert) 91 | { 92 | Node * new_node = _node_alloc.allocate(1); 93 | Node * prev_node = _last_node; 94 | Node * start_node = _last_node->parent; 95 | 96 | // side == false = left; side == true = right; 97 | bool side = true; 98 | 99 | while (start_node != _last_node) 100 | { 101 | int curkey = start_node->value.first; 102 | if (curkey == to_insert.first) 103 | return (ft::make_pair(iterator(start_node, _last_node), false)); 104 | prev_node = start_node; 105 | if (to_insert.first > curkey) 106 | { 107 | side = true; 108 | start_node = start_node->right; 109 | } 110 | else 111 | { 112 | side = false; 113 | start_node = start_node->left; 114 | } 115 | } 116 | _node_alloc.construct(new_node, Node(to_insert, prev_node, _last_node, _last_node)); 117 | 118 | if (prev_node == _last_node) 119 | _last_node->parent = new_node; 120 | else if (side == true) 121 | prev_node->right = new_node; 122 | else 123 | prev_node->left = new_node; 124 | 125 | _last_node->left = _BST_get_lower_node(_last_node->parent); 126 | _last_node->right = _BST_get_higher_node(_last_node->parent); 127 | _last_node->value.first += 1; 128 | return (ft::make_pair(iterator(new_node, _last_node), true)); 129 | } 130 | 131 | /* 132 | ** @brief need a pair create like : make_pair(key, mapped_type()) 133 | */ 134 | void removeByKey(value_type to_remove) 135 | { _removeByKey(_last_node->parent, to_remove); } 136 | 137 | /* 138 | ** @brief need a pair create like : make_pair(key, mapped_type()) 139 | */ 140 | node_pointer searchByKey(value_type to_remove) 141 | { 142 | node_pointer node = _last_node->parent; 143 | 144 | while (node != _last_node) 145 | { 146 | if (node->value.first == to_remove.first) 147 | return (node); 148 | if (node->value.first > to_remove.first) 149 | node = node->left; 150 | else 151 | node = node->right; 152 | } 153 | return (node); 154 | } 155 | 156 | /* 157 | ** @brief Swap this elements with "x" elements 158 | */ 159 | void swap(self& x) 160 | { 161 | if (&x == this) 162 | return ; 163 | 164 | node_pointer save = this->_last_node; 165 | this->_last_node = x._last_node; 166 | x._last_node = save; 167 | } 168 | 169 | /* 170 | ** @brief return max_size of allocator. 171 | */ 172 | size_type max_size() const 173 | { return (node_alloc().max_size()); } 174 | 175 | // last_node parent = root of tree, last_node right = last node, last_node left = first node 176 | node_pointer _last_node; 177 | node_alloc _node_alloc; 178 | 179 | private : 180 | 181 | /* 182 | ** @brief Give node pointer on lower key. 183 | */ 184 | node_pointer _BST_get_lower_node(node_pointer root) 185 | { 186 | while (root != _last_node && root->left != _last_node) 187 | root = root->left; 188 | return (root); 189 | } 190 | 191 | /* 192 | ** @brief Give node pointer on higher key. 193 | */ 194 | node_pointer _BST_get_higher_node(node_pointer root) 195 | { 196 | while (root != _last_node && root->right != _last_node) 197 | root = root->right; 198 | return (root); 199 | } 200 | 201 | /* 202 | ** @brief Used to re set link between node is necessary, and 203 | ** delete node. 204 | */ 205 | void _replaceNodeInParent(node_pointer node, node_pointer new_node) 206 | { 207 | if (node->parent != _last_node) 208 | { 209 | if (_last_node->parent == node) 210 | _last_node->parent = new_node; 211 | 212 | if (node == node->parent->left) 213 | node->parent->left = new_node; 214 | else 215 | node->parent->right = new_node; 216 | } 217 | else 218 | _last_node->parent = new_node; 219 | 220 | _last_node->left = _BST_get_lower_node(_last_node->parent); 221 | _last_node->right = _BST_get_higher_node(_last_node->parent); 222 | _last_node->value.first -= 1; 223 | 224 | new_node->parent = node->parent; 225 | 226 | _node_alloc.destroy(node); 227 | _node_alloc.deallocate(node, 1); 228 | } 229 | 230 | /* 231 | ** @brief used to move replacer node and re set all link between 232 | ** node where it's necessary and delete to_remove. 233 | */ 234 | void _replaceDoubleChildren(node_pointer& to_remove, node_pointer new_node) 235 | { 236 | if (new_node->parent != _last_node) 237 | { 238 | if (new_node->parent != to_remove) 239 | new_node->parent->left = new_node->right; 240 | } 241 | 242 | new_node->parent = to_remove->parent; 243 | if (to_remove->left != new_node) 244 | new_node->left = to_remove->left; 245 | if (to_remove->right != new_node) 246 | new_node->right = to_remove->right; 247 | 248 | if (to_remove->parent != _last_node) 249 | { 250 | if (to_remove->parent->left == to_remove) 251 | to_remove->parent->left = new_node; 252 | else if (to_remove->parent->right == to_remove) 253 | to_remove->parent->right = new_node; 254 | } 255 | else 256 | _last_node->parent = new_node; 257 | 258 | if (to_remove->left != _last_node && to_remove->left != new_node) 259 | to_remove->left->parent = new_node; 260 | if (to_remove->right != _last_node && to_remove->right != new_node) 261 | to_remove->right->parent = new_node; 262 | 263 | if (to_remove->parent != _last_node) 264 | { 265 | to_remove->left = _last_node; 266 | to_remove->right = _last_node; 267 | to_remove->parent = new_node; 268 | } 269 | 270 | _last_node->left = _BST_get_lower_node(_last_node->parent); 271 | _last_node->right = _BST_get_higher_node(_last_node->parent); 272 | _last_node->value.first -= 1; 273 | 274 | _node_alloc.destroy(to_remove); 275 | _node_alloc.deallocate(to_remove, 1); 276 | } 277 | 278 | /* 279 | ** @brief need a pair create like : make_pair(key, mapped_type()) 280 | */ 281 | void _removeByKey(node_pointer node, value_type to_remove) 282 | { 283 | if (to_remove.first < node->value.first) 284 | { 285 | _removeByKey(node->left, to_remove); 286 | return ; 287 | } 288 | 289 | if (to_remove.first > node->value.first) 290 | { 291 | _removeByKey(node->right, to_remove); 292 | return ; 293 | } 294 | 295 | if (node->left != _last_node && node->right != _last_node) 296 | { 297 | node_pointer successor = _BST_get_lower_node(node->right); 298 | _replaceDoubleChildren(node, successor); 299 | return ; 300 | } 301 | else if (node->left != _last_node) 302 | _replaceNodeInParent(node, node->left); 303 | else if (node->right != _last_node) 304 | _replaceNodeInParent(node, node->right); 305 | else 306 | _replaceNodeInParent(node, _last_node); 307 | } 308 | }; 309 | } 310 | 311 | #endif -------------------------------------------------------------------------------- /containers/utils/list_iterator.hpp: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* list_iterator.hpp :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: rchallie +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2020/12/04 17:45:48 by rchallie #+# #+# */ 9 | /* Updated: 2020/12/08 19:40:33 by rchallie ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #ifndef LIST_ITERATOR_HPP 14 | # define LIST_ITERATOR_HPP 15 | 16 | #include "utils.hpp" 17 | 18 | namespace ft 19 | { 20 | template 21 | class List_iterator : public ft::iterator 22 | { 23 | public: 24 | /* Category of the iterator. */ 25 | typedef typename ft::iterator::iterator_category iterator_category; 26 | 27 | /* Type of elements pointed. */ 28 | typedef typename ft::iterator::value_type value_type; 29 | 30 | /* Type to represent the difference between two iterators. */ 31 | typedef typename ft::iterator::difference_type difference_type; 32 | 33 | /* Type to represent a pointer to an element pointed */ 34 | typedef T* pointer; 35 | 36 | /* Type to represent a reference to an element pointed */ 37 | typedef T& reference; 38 | 39 | /* 40 | ** @brief Default construtor: 41 | ** The bidirectional iterator point to null. 42 | */ 43 | List_iterator() 44 | : 45 | _node(u_nullptr) 46 | {} 47 | 48 | /* 49 | ** @brief Constructor from pointer: 50 | ** Construct a bidirectional iterator and point to the 51 | ** element passed in argument. 52 | ** 53 | ** @param elem the pointer to the element to iterate. 54 | */ 55 | List_iterator(Doubly_Linked_Node *init_node) 56 | : 57 | _node(init_node) 58 | {} 59 | 60 | /* 61 | ** Copy constructor: 62 | ** Construct a bidirectional iterator and copy the pointer 63 | ** who point to the element from "x" to this. 64 | ** 65 | ** @param op the const reference to the bidirectional iterator 66 | ** to copy. 67 | */ 68 | List_iterator(const List_iterator& x) 69 | : 70 | _node(x._node) 71 | {} 72 | 73 | /* 74 | ** Copy assignation: 75 | ** Give a bidirectional iterator who is a copy 76 | ** from "x". 77 | ** 78 | ** @param op the const reference to the bidirectional 79 | ** iterator to copy. 80 | ** @return the bidirectional iterator. 81 | */ 82 | List_iterator &operator= (const List_iterator& x) 83 | { 84 | if (&x == this) 85 | return (*this); 86 | this->_node = x._node; 87 | return (*this); 88 | } 89 | 90 | /* Destructor: */ 91 | virtual ~List_iterator() {} 92 | 93 | /* 94 | ** @brief Give a reference to the rvalue pointed by the 95 | ** bidirectionnal iterator. 96 | ** 97 | ** @return the rvalue (value where point the pointer). 98 | */ 99 | reference operator* (void) { return (_node->data); } 100 | 101 | /* 102 | ** @brief Give the lvalue of the element where is the 103 | ** bidirectional iterator. 104 | ** 105 | ** @return the lvalue (the pointer to the element). 106 | */ 107 | pointer operator->(void) { return &(this->operator*()); } 108 | 109 | /* 110 | ** @brief Preincrement the iterator to point to the 111 | ** next element of the list. 112 | ** 113 | ** @return A reference of to this bidiretional iterator 114 | ** where it point to the next element of the list. 115 | */ 116 | List_iterator& operator++(void) 117 | { 118 | this->_node = this->_node->next; 119 | return (*this); 120 | } 121 | 122 | /* 123 | ** @brief Postincrement the iterator to point to the 124 | ** next element of the list. 125 | ** 126 | ** @return a bidiretional iterator incremented (copy 127 | ** of this). 128 | */ 129 | List_iterator operator++(int) 130 | { 131 | List_iterator rtn(*this); 132 | operator++(); 133 | return (rtn); 134 | } 135 | 136 | /* 137 | ** @brief Predecrement the iterator to point to the 138 | ** previous element in the list. 139 | ** 140 | ** @return A reference of to this bidirectional iterator 141 | ** where it point to the previous element in the list. 142 | */ 143 | List_iterator& operator--(void) 144 | { 145 | this->_node = this->_node->prev; 146 | return (*this); 147 | } 148 | 149 | /* 150 | ** @brief Postdecrement the iterator to point to the 151 | ** previous element in the list. 152 | ** 153 | ** @return a bidirectional iterator decremented (copy 154 | ** of this). 155 | */ 156 | List_iterator operator--(int) 157 | { 158 | List_iterator rtn(*this); 159 | operator--(); 160 | return (rtn); 161 | } 162 | 163 | friend bool operator==(const List_iterator& lhs, const List_iterator& rhs) 164 | { return (lhs._node == rhs._node); } 165 | 166 | friend bool operator!=(const List_iterator& lhs, const List_iterator& rhs) 167 | { return (lhs._node != rhs._node); } 168 | 169 | Doubly_Linked_Node *_node; 170 | }; 171 | 172 | template 173 | class List_const_iterator : public ft::iterator 174 | { 175 | public: 176 | /* Category of the iterator. */ 177 | typedef typename ft::iterator::iterator_category iterator_category; 178 | 179 | /* Type of elements pointed. */ 180 | typedef typename ft::iterator::value_type value_type; 181 | 182 | /* Type to represent the difference between two iterators. */ 183 | typedef typename ft::iterator::difference_type difference_type; 184 | 185 | /* Type to represent a pointer to an element pointed */ 186 | typedef const T* pointer; 187 | 188 | /* Type to represent a reference to an element pointed */ 189 | typedef const T& reference; 190 | 191 | /* 192 | ** @brief Default construtor: 193 | ** The bidirectional iterator point to null. 194 | */ 195 | List_const_iterator() 196 | : 197 | _node(u_nullptr) 198 | {} 199 | 200 | /* 201 | ** @brief Constructor from pointer: 202 | ** Construct a bidirectional iterator and point to the 203 | ** element passed in argument. 204 | ** 205 | ** @param elem the pointer to the element to iterate. 206 | */ 207 | List_const_iterator(Doubly_Linked_Node *init_node) 208 | : 209 | _node(init_node) 210 | {} 211 | 212 | /* 213 | ** Copy constructor: 214 | ** Construct a bidirectional iterator and copy the pointer 215 | ** who point to the element from "x" to this. 216 | ** 217 | ** @param op the const reference to the bidirectional iterator 218 | ** to copy. 219 | */ 220 | List_const_iterator(const List_const_iterator& x) 221 | : 222 | _node(x._node) 223 | {} 224 | 225 | List_const_iterator(const List_iterator& x) 226 | : 227 | _node(x._node) 228 | {} 229 | 230 | /* 231 | ** Copy assignation: 232 | ** Give a bidirectional iterator who is a copy 233 | ** from "x". 234 | ** 235 | ** @param op the const reference to the bidirectional 236 | ** iterator to copy. 237 | ** @return the bidirectional iterator. 238 | */ 239 | List_const_iterator &operator= (const List_const_iterator& x) 240 | { 241 | if (&x == this) 242 | return (*this); 243 | this->_node = x._node; 244 | return (*this); 245 | } 246 | 247 | /* Destructor: */ 248 | virtual ~List_const_iterator() {} 249 | 250 | /* 251 | ** @brief Give a reference to the rvalue pointed by the 252 | ** bidirectionnal iterator. 253 | ** 254 | ** @return the rvalue (value where point the pointer). 255 | */ 256 | reference operator* (void) { return (_node->data); } 257 | 258 | /* 259 | ** @brief Give the lvalue of the element where is the 260 | ** bidirectional iterator. 261 | ** 262 | ** @return the lvalue (the pointer to the element). 263 | */ 264 | pointer operator->(void) { return &(this->operator*()); } 265 | 266 | /* 267 | ** @brief Preincrement the iterator to point to the 268 | ** next element of the list. 269 | ** 270 | ** @return A reference of to this bidiretional iterator 271 | ** where it point to the next element of the list. 272 | */ 273 | List_const_iterator& operator++(void) 274 | { 275 | this->_node = this->_node->next; 276 | return (*this); 277 | } 278 | 279 | /* 280 | ** @brief Postincrement the iterator to point to the 281 | ** next element of the list. 282 | ** 283 | ** @return a bidiretional iterator incremented (copy 284 | ** of this). 285 | */ 286 | List_const_iterator operator++(int) 287 | { 288 | List_const_iterator rtn(*this); 289 | operator++(); 290 | return (rtn); 291 | } 292 | 293 | /* 294 | ** @brief Predecrement the iterator to point to the 295 | ** previous element in the list. 296 | ** 297 | ** @return A reference of to this bidirectional iterator 298 | ** where it point to the previous element in the list. 299 | */ 300 | List_const_iterator& operator--(void) 301 | { 302 | this->_node = this->_node->prev; 303 | return (*this); 304 | } 305 | 306 | /* 307 | ** @brief Postdecrement the iterator to point to the 308 | ** previous element in the list. 309 | ** 310 | ** @return a bidirectional iterator decremented (copy 311 | ** of this). 312 | */ 313 | List_const_iterator operator--(int) 314 | { 315 | List_const_iterator rtn(*this); 316 | operator--(); 317 | return (rtn); 318 | } 319 | 320 | friend bool operator==(const List_const_iterator& lhs, const List_const_iterator& rhs) 321 | { return (lhs._node == rhs._node); } 322 | 323 | friend bool operator!=(const List_const_iterator& lhs, const List_const_iterator& rhs) 324 | { return (lhs._node != rhs._node); } 325 | 326 | Doubly_Linked_Node *_node; 327 | }; 328 | // /* 329 | // ** @brief Check if the pointer of "lhs" 330 | // ** is equal than "rhs" in the memory. 331 | // ** 332 | // ** @param lhs the bidirectional iterator to compare. 333 | // ** @param rhs the bidirectional iterator with who check. 334 | // ** @return true if the pointer of lhs 335 | // ** if equal than "rhs", otherwise false. 336 | // */ 337 | // template 338 | // typename ft::List_iterator::difference_type 339 | // operator==(const ft::List_iterator lhs, 340 | // const ft::List_iterator rhs) 341 | // { 342 | // return (lhs._node == rhs._node); 343 | // } 344 | 345 | // /* For iterator == const_iterator */ 346 | // template 347 | // typename ft::List_iterator::difference_type 348 | // operator==(const ft::List_iterator lhs, 349 | // const ft::List_iterator rhs) 350 | // { 351 | // return (lhs._node == rhs._node); 352 | // } 353 | 354 | // /* 355 | // ** @brief Check if the pointer of "lhs" 356 | // ** is equal than "rhs" in the memory. 357 | // ** 358 | // ** @param lhs the bidirectional iterator to compare. 359 | // ** @param rhs the bidirectional iterator with who check. 360 | // ** @return true if the pointer of lhs 361 | // ** if equal than "rhs", otherwise false. 362 | // */ 363 | // template 364 | // typename ft::List_iterator::difference_type 365 | // operator!=(const ft::List_iterator lhs, 366 | // const ft::List_iterator rhs) 367 | // { 368 | // return (lhs._node != rhs._node); 369 | // } 370 | 371 | // /* For iterator != const_iterator */ 372 | // template 373 | // typename ft::List_iterator::difference_type 374 | // operator!=(const ft::List_iterator lhs, 375 | // const ft::List_iterator rhs) 376 | // { 377 | // return (lhs._node != rhs._node); 378 | // } 379 | } 380 | 381 | #endif -------------------------------------------------------------------------------- /containers/utils/deque_iterator.hpp: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* deque_iterator.hpp :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: rchallie +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2020/11/29 16:39:39 by rchallie #+# #+# */ 9 | /* Updated: 2020/12/04 18:16:44 by rchallie ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #ifndef DEQUE_ITERATOR_HPP 14 | # define DEQUE_ITERATOR_HPP 15 | 16 | #include "utils.hpp" 17 | 18 | namespace ft 19 | { 20 | template 21 | class Deque_Iterator : public ft::iterator 22 | { 23 | public: 24 | /* Category of the iterator. */ 25 | typedef typename ft::iterator::iterator_category iterator_category; 26 | 27 | /* Type of elements pointed. */ 28 | typedef typename ft::iterator::value_type value_type; 29 | 30 | /* Type to represent the difference between two iterators. */ 31 | typedef typename ft::iterator::difference_type difference_type; 32 | 33 | /* Type to represent a pointer to an element pointed */ 34 | typedef T* pointer; 35 | 36 | /* Type to represent a reference to an element pointed */ 37 | typedef T& reference; 38 | 39 | typedef T** map_pointer; 40 | 41 | Deque_Iterator() 42 | : 43 | _map(), 44 | _elem(), 45 | _start_cur_block(), 46 | _end_cur_block() 47 | {} 48 | 49 | Deque_Iterator(pointer elem, map_pointer map) 50 | : 51 | _map(map), 52 | _elem(elem), 53 | _start_cur_block(*map), 54 | _end_cur_block(*map + _deque_block_size(sizeof(value_type))) 55 | {} 56 | 57 | Deque_Iterator(const Deque_Iterator& di) 58 | : 59 | _map(di._map), 60 | _elem(di._elem), 61 | _start_cur_block(di._start_cur_block), 62 | _end_cur_block(di._end_cur_block) 63 | {} 64 | 65 | Deque_Iterator& operator=(const Deque_Iterator& di) 66 | { 67 | this->_map = di._map; 68 | this->_elem = di._elem; 69 | this->_start_cur_block = di._start_cur_block; 70 | this->_end_cur_block = di._end_cur_block; 71 | return (*this); 72 | } 73 | 74 | ~Deque_Iterator() {} 75 | 76 | reference operator*() 77 | { return (*this->_elem); } 78 | 79 | pointer operator->() 80 | { return (this->_elem); } 81 | 82 | Deque_Iterator& operator++(void) 83 | { 84 | ++this->_elem; 85 | if (this->_elem == this->_end_cur_block) 86 | { 87 | this->_map++; 88 | this->_start_cur_block = *this->_map; 89 | this->_end_cur_block = this->_start_cur_block + difference_type(_deque_block_size(sizeof(value_type))); 90 | this->_elem = this->_start_cur_block; 91 | } 92 | return (*this); 93 | } 94 | 95 | Deque_Iterator operator++(int) 96 | { 97 | Deque_Iterator tmp(*this); 98 | operator++(); 99 | return (tmp); 100 | } 101 | 102 | Deque_Iterator& operator--(void) 103 | { 104 | if (this->_elem == this->_start_cur_block) 105 | { 106 | this->_map--; 107 | this->_start_cur_block = *this->_map; 108 | this->_end_cur_block = this->_start_cur_block + _deque_block_size(sizeof(value_type)); 109 | this->_elem = this->_end_cur_block; 110 | } 111 | this->_elem--; 112 | return (*this); 113 | } 114 | 115 | Deque_Iterator operator--(int) 116 | { 117 | Deque_Iterator tmp(*this); 118 | operator--(); 119 | return (tmp); 120 | } 121 | 122 | Deque_Iterator operator+(difference_type n) const 123 | { 124 | Deque_Iterator tmp(*this); 125 | while (n--) 126 | { 127 | tmp._elem++; 128 | if (tmp._elem == tmp._end_cur_block) 129 | { 130 | tmp._map++; 131 | tmp._start_cur_block = *tmp._map; 132 | tmp._end_cur_block = tmp._start_cur_block + tmp._deque_block_size(sizeof(value_type)); 133 | tmp._elem = tmp._start_cur_block; 134 | } 135 | } 136 | return (tmp); 137 | } 138 | 139 | Deque_Iterator operator-(difference_type n) const 140 | { 141 | Deque_Iterator tmp(*this); 142 | while (n--) 143 | { 144 | if (tmp._elem == tmp._start_cur_block) 145 | { 146 | tmp._map--; 147 | tmp._start_cur_block = *tmp._map; 148 | tmp._end_cur_block = tmp._start_cur_block + tmp._deque_block_size(sizeof(value_type)); 149 | tmp._elem = tmp._end_cur_block; 150 | } 151 | tmp._elem--; 152 | } 153 | return (tmp); 154 | } 155 | 156 | Deque_Iterator& operator+=(difference_type n) 157 | { 158 | while (n--) 159 | operator++(); 160 | return (*this); 161 | } 162 | 163 | Deque_Iterator& operator-=(difference_type n) 164 | { 165 | while (n--) 166 | operator--(); 167 | return (*this); 168 | } 169 | 170 | reference operator[](difference_type n) 171 | { 172 | return (*((*this) + n)); 173 | } 174 | 175 | map_pointer _map; 176 | pointer _elem; 177 | pointer _start_cur_block; 178 | pointer _end_cur_block; 179 | 180 | size_t _deque_block_size(size_t size) const 181 | { return ((size < 512) ? size_t(512 / sizeof(value_type)) : size_t(1)); } 182 | 183 | /* 184 | ** @brief Operator to cast Deque_Iterator to const Deque_Iterator 185 | ** 186 | ** @return a new Deque_Iterator converted to const. 187 | */ 188 | operator Deque_Iterator () const 189 | { return (Deque_Iterator(this->_elem, const_cast(this->_map))); } 190 | }; 191 | 192 | template 193 | typename ft::Deque_Iterator::difference_type 194 | operator==(const ft::Deque_Iterator& lhs, 195 | const ft::Deque_Iterator& rhs) 196 | { 197 | return (lhs._elem == rhs._elem); 198 | } 199 | 200 | template 202 | typename ft::Deque_Iterator::difference_type 203 | operator==(const ft::Deque_Iterator& lhs, 204 | const ft::Deque_Iterator& rhs) 205 | { 206 | return (lhs._elem == rhs._elem); 207 | } 208 | 209 | template 210 | typename ft::Deque_Iterator::difference_type 211 | operator!=(const ft::Deque_Iterator& lhs, 212 | const ft::Deque_Iterator& rhs) 213 | { 214 | return (lhs._elem != rhs._elem); 215 | } 216 | 217 | template 219 | typename ft::Deque_Iterator::difference_type 220 | operator!=(const ft::Deque_Iterator& lhs, 221 | const ft::Deque_Iterator& rhs) 222 | { 223 | return (lhs._elem != rhs._elem); 224 | } 225 | 226 | template 227 | ft::Deque_Iterator operator+( 228 | typename ft::Deque_Iterator::difference_type n, 229 | const ft::Deque_Iterator& di) 230 | { 231 | return (di + n); 232 | } 233 | 234 | template 235 | typename ft::Deque_Iterator::difference_type 236 | operator-(const ft::Deque_Iterator& lhs, 237 | const ft::Deque_Iterator& rhs) 238 | { 239 | /* nbr block between the two iterator blocks * nbr of element in one block 240 | + (difference between this iterator element - start of is block) 241 | + (iterator, with which to make a difference, end block - it element) */ 242 | return (typename ft::Deque_Iterator::difference_type( 243 | ((lhs._map - rhs._map - 1) 244 | * lhs._deque_block_size(sizeof(T))) 245 | + (lhs._elem - lhs._start_cur_block) + (rhs._end_cur_block - rhs._elem))); 246 | } 247 | 248 | template 250 | typename ft::Deque_Iterator::difference_type 251 | operator-(const ft::Deque_Iterator& lhs, 252 | const ft::Deque_Iterator& rhs) 253 | { 254 | /* nbr block between the two iterator blocks * nbr of element in one block 255 | + (difference between this iterator element - start of is block) 256 | + (iterator, with which to make a difference, end block - it element) */ 257 | return (typename ft::Deque_Iterator::difference_type( 258 | ((lhs._map - rhs._map - 1) 259 | * lhs._deque_block_size(sizeof(T_L))) 260 | + (lhs._elem - lhs._start_cur_block) + (rhs._end_cur_block - rhs._elem))); 261 | } 262 | 263 | template 264 | typename ft::Deque_Iterator::difference_type 265 | operator<(const ft::Deque_Iterator& lhs, 266 | const ft::Deque_Iterator& rhs) 267 | { 268 | if (lhs._map == rhs._map) 269 | return (lhs._elem < rhs._elem); 270 | return (lhs._map < rhs._map); 271 | } 272 | 273 | template 275 | typename ft::Deque_Iterator::difference_type 276 | operator<(const ft::Deque_Iterator& lhs, 277 | const ft::Deque_Iterator& rhs) 278 | { 279 | if (lhs._map == rhs._map) 280 | return (lhs._elem < rhs._elem); 281 | return (lhs._map < rhs._map); 282 | } 283 | 284 | template 285 | typename ft::Deque_Iterator::difference_type 286 | operator>(const ft::Deque_Iterator& lhs, 287 | const ft::Deque_Iterator& rhs) 288 | { 289 | if (lhs._map == rhs._map) 290 | return (lhs._elem > rhs._elem); 291 | return (lhs._map > rhs._map); 292 | } 293 | 294 | template 296 | typename ft::Deque_Iterator::difference_type 297 | operator>(const ft::Deque_Iterator& lhs, 298 | const ft::Deque_Iterator& rhs) 299 | { 300 | if (lhs._map == rhs._map) 301 | return (lhs._elem > rhs._elem); 302 | return (lhs._map > rhs._map); 303 | } 304 | 305 | template 306 | typename ft::Deque_Iterator::difference_type 307 | operator<=(const ft::Deque_Iterator& lhs, 308 | const ft::Deque_Iterator& rhs) 309 | { 310 | if (lhs._map == rhs._map) 311 | return (lhs._elem <= rhs._elem); 312 | return (lhs._map <= rhs._map); 313 | } 314 | 315 | template 317 | typename ft::Deque_Iterator::difference_type 318 | operator<=(const ft::Deque_Iterator& lhs, 319 | const ft::Deque_Iterator& rhs) 320 | { 321 | if (lhs._map == rhs._map) 322 | return (lhs._elem <= rhs._elem); 323 | return (lhs._map <= rhs._map); 324 | } 325 | 326 | template 327 | typename ft::Deque_Iterator::difference_type 328 | operator>=(const ft::Deque_Iterator& lhs, 329 | const ft::Deque_Iterator& rhs) 330 | { 331 | if (lhs._map == rhs._map) 332 | return (lhs._elem >= rhs._elem); 333 | return (lhs._map >= rhs._map); 334 | } 335 | 336 | template 338 | typename ft::Deque_Iterator::difference_type 339 | operator>=(const ft::Deque_Iterator& lhs, 340 | const ft::Deque_Iterator& rhs) 341 | { 342 | if (lhs._map == rhs._map) 343 | return (lhs._elem >= rhs._elem); 344 | return (lhs._map >= rhs._map); 345 | } 346 | } 347 | 348 | #endif -------------------------------------------------------------------------------- /containers/utils/binary_search_tree_iterator.hpp: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* binary_search_tree_iterator.hpp :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: rchallie +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2020/12/07 17:22:36 by rchallie #+# #+# */ 9 | /* Updated: 2020/12/10 17:39:37 by rchallie ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #ifndef BINARY_SEARCH_TREE_ITERATOR_HPP 14 | # define BINARY_SEARCH_TREE_ITERATOR_HPP 15 | 16 | namespace ft 17 | { 18 | template 19 | class BST_iterator : ft::iterator 20 | { 21 | public : 22 | 23 | typedef typename T::value_type value_type; 24 | 25 | /* The iterator category */ 26 | typedef typename ft::iterator::iterator_category iterator_category; 27 | 28 | /* The value_type pointed by the iterator (BST)*/ 29 | 30 | /* The difference type */ 31 | typedef typename ft::iterator::difference_type difference_type; 32 | 33 | /* The pointer to the value */ 34 | typedef typename ft::iterator::pointer pointer; 35 | 36 | /* The reference to the value */ 37 | typedef typename ft::iterator::reference reference; 38 | 39 | /* 40 | ** @brief Default. 41 | ** Create an iterator that pointing to inisialized 42 | ** binary search tree. 43 | */ 44 | BST_iterator(const Compare& comp = Compare()) 45 | : 46 | _node(), 47 | _last_node(), 48 | _comp(comp) 49 | {} 50 | 51 | /* 52 | ** @brief Create an iterator on "node_p". 53 | */ 54 | BST_iterator(T * node_p, T * last_node, 55 | const Compare& comp = Compare()) 56 | : 57 | _node(node_p), 58 | _last_node(last_node), 59 | _comp(comp) 60 | {} 61 | 62 | /* 63 | ** @brief Copy constructor. 64 | ** Create a new Binary search tree iterator to be 65 | ** a copy of another. 66 | ** 67 | ** @param bst_it the binary search tree to be inpired by. 68 | */ 69 | BST_iterator(const BST_iterator& bst_it) 70 | : 71 | _node(bst_it._node), 72 | _last_node(bst_it._last_node), 73 | _comp() 74 | {} 75 | 76 | // Added for subject 77 | virtual ~BST_iterator() { } 78 | 79 | /* 80 | ** @brief Assignement operator. 81 | ** Create an iterator that will iterate the same than 82 | ** "bst_it". 83 | ** 84 | ** @param bst_it the binary search tree to be inpired by. 85 | ** @return a reference to this. 86 | */ 87 | BST_iterator &operator=(const BST_iterator& bst_it) 88 | { 89 | if (*this == bst_it) 90 | return (*this); 91 | this->_node = bst_it._node; 92 | this->_last_node = bst_it._last_node; 93 | this->_comp = bst_it._comp; 94 | return (*this); 95 | } 96 | 97 | /* 98 | ** @brief Strictment equal operator. 99 | ** Return a boolean that contains : if this iterator 100 | ** and another one contains two equal binary search tree. 101 | ** 102 | ** @param bst_it the other binaray search tree iterator. 103 | ** @return true if the two iterator iterate on two equal 104 | ** tree, otherwise false. 105 | */ 106 | bool operator==(const BST_iterator& bst_it) 107 | { return (this->_node == bst_it._node); } 108 | 109 | /* 110 | ** @brief Different operator. 111 | ** Return a boolean that contains : if this iterator 112 | ** and another one contains two different binary search tree. 113 | ** 114 | ** @param bst_it the other binaray search tree iterator. 115 | ** @return true if the two iterator iterate on two different 116 | ** tree, otherwise false. 117 | */ 118 | bool operator!=(const BST_iterator& bst_it) 119 | { return (this->_node != bst_it._node); } 120 | 121 | /* 122 | ** @brief Give a reference to the value that contains 123 | ** the binary search tree (value on a node) at the iterator 124 | ** position. 125 | ** 126 | ** @return the const reference. 127 | */ 128 | reference operator*() const 129 | { return (this->_node->value); } 130 | 131 | /* 132 | ** @brief Give a pointer to the value that contain 133 | ** the binary search tree (value on a node) at the iterator 134 | ** position. 135 | ** 136 | ** @return the const pointer. 137 | */ 138 | pointer operator->() const 139 | { return (&this->_node->value); } 140 | 141 | /* 142 | ** @brief Increment the iterator to the next value 143 | ** after the value in the tree at iterator position. 144 | ** 145 | ** @return a reference to this. 146 | */ 147 | BST_iterator& operator++(void) 148 | { 149 | T* cursor = _node; 150 | 151 | if (_node->right == _last_node) 152 | { 153 | cursor = _node->parent; 154 | while (cursor != _last_node 155 | && _comp(cursor->value.first, _node->value.first)) 156 | cursor = cursor->parent; 157 | _node = cursor; 158 | } 159 | else if (cursor == _last_node) 160 | _node = _last_node->right; 161 | else 162 | { 163 | cursor = _node->right; 164 | if (cursor == _last_node->parent 165 | && cursor->right == _last_node) 166 | _node = cursor; 167 | else 168 | { 169 | while (cursor->left != _last_node) 170 | cursor = cursor->left; 171 | } 172 | _node = cursor; 173 | } 174 | return (*this); 175 | } 176 | 177 | /* 178 | ** @brief Post increment the iterator to the next value 179 | ** after the value in the tree at iterator position. 180 | ** 181 | ** @return this before the incrementation. 182 | */ 183 | BST_iterator operator++(int) 184 | { 185 | BST_iterator tmp(*this); 186 | operator++(); 187 | return (tmp); 188 | } 189 | 190 | /* 191 | ** @brief decrement the iterator to the previous value 192 | ** before the value in the tree at iterator position. 193 | ** 194 | ** @return a reference to this. 195 | */ 196 | BST_iterator& operator--(void) 197 | { 198 | T* cursor = _node; 199 | 200 | if (_node->left == _last_node) 201 | { 202 | cursor = _node->parent; 203 | while (cursor != _last_node 204 | && !_comp(cursor->value.first, _node->value.first)) 205 | cursor = cursor->parent; 206 | _node = cursor; 207 | } 208 | else if (cursor == _last_node) 209 | _node = _last_node->right; 210 | else 211 | { 212 | cursor = _node->left; 213 | if (cursor == _last_node->parent 214 | && cursor->left == _last_node) 215 | _node = cursor; 216 | else 217 | { 218 | while (cursor->right != _last_node) 219 | cursor = cursor->right; 220 | } 221 | _node = cursor; 222 | } 223 | return (*this); 224 | } 225 | 226 | /* 227 | ** @brief Post decrement the iterator to the previous value 228 | ** before the value in the tree at iterator position. 229 | ** 230 | ** @return this before the decrementation. 231 | */ 232 | BST_iterator operator--(int) 233 | { 234 | BST_iterator tmp(*this); 235 | operator--(); 236 | return (tmp); 237 | } 238 | 239 | T * _node; 240 | T * _last_node; 241 | Compare _comp; 242 | }; 243 | 244 | template 245 | class BST_const_iterator : ft::iterator 246 | { 247 | public : 248 | 249 | typedef typename T::value_type value_type; 250 | 251 | /* The iterator category */ 252 | typedef typename ft::iterator::iterator_category iterator_category; 253 | 254 | /* The value_type pointed by the iterator (BST)*/ 255 | 256 | /* The difference type */ 257 | typedef typename ft::iterator::difference_type difference_type; 258 | 259 | /* The pointer to the value */ 260 | typedef typename ft::iterator::pointer pointer; 261 | 262 | /* The reference to the value */ 263 | typedef typename ft::iterator::reference reference; 264 | 265 | 266 | /* 267 | ** @brief Default. 268 | ** Create an iterator that pointing to inisialized 269 | ** binary search tree. 270 | */ 271 | BST_const_iterator(const Compare& comp = Compare()) 272 | : 273 | _node(), 274 | _last_node(), 275 | _comp(comp) 276 | {} 277 | 278 | /* 279 | ** @brief Create an iterator on "node_p". 280 | */ 281 | BST_const_iterator(T * node_p, T * last_node, 282 | const Compare& comp = Compare()) 283 | : 284 | _node(node_p), 285 | _last_node(last_node), 286 | _comp(comp) 287 | {} 288 | 289 | /* 290 | ** @brief Copy constructor. 291 | ** Create a new Binary search tree iterator to be 292 | ** a copy of another. 293 | ** 294 | ** @param bst_it the binary search tree to be inpired by. 295 | */ 296 | BST_const_iterator(const BST_const_iterator& bst_it) 297 | : 298 | _node(bst_it._node), 299 | _last_node(bst_it._last_node), 300 | _comp() 301 | {} 302 | 303 | BST_const_iterator(const BST_iterator& bst_it) 304 | : 305 | _node(bst_it._node), 306 | _last_node(bst_it._last_node), 307 | _comp() 308 | {} 309 | 310 | // Added for subject 311 | virtual ~BST_const_iterator() { } 312 | 313 | /* 314 | ** @brief Assignement operator. 315 | ** Create an iterator that will iterate the same than 316 | ** "bst_it". 317 | ** 318 | ** @param bst_it the binary search tree to be inpired by. 319 | ** @return a reference to this. 320 | */ 321 | BST_const_iterator &operator=(const BST_const_iterator& bst_it) 322 | { 323 | if (*this == bst_it) 324 | return (*this); 325 | this->_node = bst_it._node; 326 | this->_last_node = bst_it._last_node; 327 | this->_comp = bst_it._comp; 328 | return (*this); 329 | } 330 | 331 | /* 332 | ** @brief Strictment equal operator. 333 | ** Return a boolean that contains : if this iterator 334 | ** and another one contains two equal binary search tree. 335 | ** 336 | ** @param bst_it the other binaray search tree iterator. 337 | ** @return true if the two iterator iterate on two equal 338 | ** tree, otherwise false. 339 | */ 340 | bool operator==(const BST_const_iterator& bst_it) 341 | { return (this->_node == bst_it._node); } 342 | 343 | /* 344 | ** @brief Different operator. 345 | ** Return a boolean that contains : if this iterator 346 | ** and another one contains two different binary search tree. 347 | ** 348 | ** @param bst_it the other binaray search tree iterator. 349 | ** @return true if the two iterator iterate on two different 350 | ** tree, otherwise false. 351 | */ 352 | bool operator!=(const BST_const_iterator& bst_it) 353 | { return (this->_node != bst_it._node); } 354 | 355 | /* 356 | ** @brief Give a reference to the value that contains 357 | ** the binary search tree (value on a node) at the iterator 358 | ** position. 359 | ** 360 | ** @return the const reference. 361 | */ 362 | reference operator*() const 363 | { return (this->_node->value); } 364 | 365 | /* 366 | ** @brief Give a pointer to the value that contain 367 | ** the binary search tree (value on a node) at the iterator 368 | ** position. 369 | ** 370 | ** @return the const pointer. 371 | */ 372 | pointer operator->() const 373 | { return (&this->_node->value); } 374 | 375 | /* 376 | ** @brief Increment the iterator to the next value 377 | ** after the value in the tree at iterator position. 378 | ** 379 | ** @return a reference to this. 380 | */ 381 | BST_const_iterator& operator++(void) 382 | { 383 | T * cursor = _node; 384 | 385 | if (_node->right == _last_node) 386 | { 387 | cursor = _node->parent; 388 | while (cursor != _last_node 389 | && _comp(cursor->value.first, _node->value.first)) 390 | cursor = cursor->parent; 391 | _node = cursor; 392 | } 393 | else if (cursor == _last_node) 394 | _node = _last_node->right; 395 | else 396 | { 397 | cursor = _node->right; 398 | if (cursor == _last_node->parent 399 | && cursor->right == _last_node) 400 | _node = cursor; 401 | else 402 | { 403 | while (cursor->left != _last_node) 404 | cursor = cursor->left; 405 | } 406 | _node = cursor; 407 | } 408 | return (*this); 409 | } 410 | 411 | /* 412 | ** @brief Post increment the iterator to the next value 413 | ** after the value in the tree at iterator position. 414 | ** 415 | ** @return this before the incrementation. 416 | */ 417 | BST_const_iterator operator++(int) 418 | { 419 | BST_const_iterator tmp(*this); 420 | operator++(); 421 | return (tmp); 422 | } 423 | 424 | /* 425 | ** @brief decrement the iterator to the previous value 426 | ** before the value in the tree at iterator position. 427 | ** 428 | ** @return a reference to this. 429 | */ 430 | BST_const_iterator& operator--(void) 431 | { 432 | T * cursor = _node; 433 | 434 | if (_node->left == _last_node) 435 | { 436 | cursor = _node->parent; 437 | while (cursor != _last_node 438 | && !_comp(cursor->value.first, _node->value.first)) 439 | cursor = cursor->parent; 440 | _node = cursor; 441 | } 442 | else if (cursor == _last_node) 443 | _node = _last_node->right; 444 | else 445 | { 446 | cursor = _node->left; 447 | if (cursor == _last_node->parent 448 | && cursor->left == _last_node) 449 | _node = cursor; 450 | else 451 | { 452 | while (cursor->right != _last_node) 453 | cursor = cursor->right; 454 | } 455 | _node = cursor; 456 | } 457 | return (*this); 458 | } 459 | 460 | /* 461 | ** @brief Post decrement the iterator to the previous value 462 | ** before the value in the tree at iterator position. 463 | ** 464 | ** @return this before the decrementation. 465 | */ 466 | BST_const_iterator operator--(int) 467 | { 468 | BST_const_iterator tmp(*this); 469 | operator--(); 470 | return (tmp); 471 | } 472 | 473 | T * _node; 474 | T * _last_node; 475 | Compare _comp; 476 | }; 477 | } 478 | 479 | #endif -------------------------------------------------------------------------------- /containers/utils/random_access_iterator.hpp: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* random_access_iterator.hpp :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: rchallie +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2020/11/27 17:50:14 by rchallie #+# #+# */ 9 | /* Updated: 2020/11/29 17:20:04 by rchallie ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #ifndef RANDOM_ACCESS_ITERATOR_HPP 14 | # define RANDOM_ACCESS_ITERATOR_HPP 15 | 16 | #include "utils.hpp" 17 | 18 | namespace ft 19 | { 20 | 21 | /* 22 | ** @brief Random-access iterators allow to access elements at an 23 | ** arbitrary offset position relative to the element they point 24 | ** to. This is the most complete iterators. All pointer types 25 | ** are also valid random-access-iterators. 26 | */ 27 | template 28 | class random_access_iterator : ft::iterator 29 | { 30 | public: 31 | 32 | /* Category of the iterator. */ 33 | typedef typename ft::iterator::iterator_category iterator_category; 34 | 35 | /* Type of elements pointed. */ 36 | typedef typename ft::iterator::value_type value_type; 37 | 38 | /* Type to represent the difference between two iterators. */ 39 | typedef typename ft::iterator::difference_type difference_type; 40 | 41 | /* Type to represent a pointer to an element pointed */ 42 | typedef T* pointer; 43 | 44 | /* Type to represent a reference to an element pointed */ 45 | typedef T& reference; 46 | 47 | /* 48 | ** @brief Default construtor: 49 | ** The random access iterator point to null. 50 | */ 51 | random_access_iterator(void) 52 | : 53 | _elem(u_nullptr) 54 | {} 55 | 56 | /* 57 | ** @brief Constructor from pointer: 58 | ** Construct a random access iterator and point to the 59 | ** element passed in argument. 60 | ** 61 | ** @param elem the pointer to the element to iterate. 62 | */ 63 | random_access_iterator(pointer elem) 64 | : 65 | _elem(elem) 66 | {} 67 | 68 | /* 69 | ** Copy constructor: 70 | ** Construct a random access iterator and copy the pointer 71 | ** who point to the element from "op" to this. 72 | ** 73 | ** @param op the const reference to the random access iterator 74 | ** to copy. 75 | */ 76 | random_access_iterator(const random_access_iterator& op) 77 | : 78 | _elem(op._elem) 79 | {} 80 | 81 | /* 82 | ** Copy assignation: 83 | ** Give a random access iterator who is a copy 84 | ** from "op". 85 | ** 86 | ** @param op the const reference to the random access 87 | ** iterator to copy. 88 | ** @return the random access iterator. 89 | */ 90 | random_access_iterator &operator=(const random_access_iterator& op) 91 | { 92 | if (this == &op) 93 | return (*this); 94 | this->_elem = op._elem; 95 | return (*this); 96 | } 97 | 98 | /* Destructor: */ 99 | virtual ~random_access_iterator() {} 100 | 101 | /* 102 | ** @brief Give a pointer to the 103 | ** element where the iterator point. 104 | ** 105 | ** @return the iterator. 106 | */ 107 | pointer base() const 108 | { return (this->_elem); } 109 | 110 | /* 111 | ** @brief Give a reference to the rvalue pointed by the 112 | ** random access iterator. 113 | ** 114 | ** @return the rvalue (value where point the pointer). 115 | */ 116 | reference operator*(void) const { return (*_elem); } 117 | 118 | /* 119 | ** @brief Give the lvalue of the element where is the 120 | ** random access iterator. 121 | ** 122 | ** @return the lvalue (the pointer to the element). 123 | */ 124 | pointer operator->(void) { return &(this->operator*()); } 125 | 126 | /* 127 | ** @brief Preincrement the iterator to point to the 128 | ** next element in memory. 129 | ** 130 | ** @return A reference of to this random access iterator 131 | ** where it point to the next element in memory. 132 | */ 133 | random_access_iterator& operator++(void) 134 | { 135 | _elem++; 136 | return (*this); 137 | } 138 | 139 | /* 140 | ** @brief Postincrement the iterator to point to the 141 | ** next element in memory. 142 | ** 143 | ** @return a random access iterator incremented (copy 144 | ** of this). 145 | */ 146 | random_access_iterator operator++(int) 147 | { 148 | random_access_iterator rtn(*this); 149 | operator++(); 150 | return (rtn); 151 | } 152 | 153 | /* 154 | ** @brief Predecrement the iterator to point to the 155 | ** previous element in memory. 156 | ** 157 | ** @return A reference of to this random access iterator 158 | ** where it point to the previous element in memory. 159 | */ 160 | random_access_iterator& operator--(void) 161 | { 162 | _elem--; 163 | return (*this); 164 | } 165 | 166 | /* 167 | ** @brief Postdecrement the iterator to point to the 168 | ** previous element in memory. 169 | ** 170 | ** @return a random access iterator decremented (copy 171 | ** of this). 172 | */ 173 | random_access_iterator operator--(int) 174 | { 175 | random_access_iterator rtn(*this); 176 | operator--(); 177 | return (rtn); 178 | } 179 | 180 | /* 181 | ** @brief Give a random access iterator where the 182 | ** element is pointed at this + "n" in memory. 183 | ** 184 | ** @param n the number of elements. 185 | ** @return the random access iterator. 186 | */ 187 | random_access_iterator operator+(difference_type n) const { return (_elem + n); } 188 | 189 | /* 190 | ** @brief Give a random access iterator where the 191 | ** element is pointed at this - "n" in memory. 192 | ** 193 | ** @param n the number of elements. 194 | ** @return the random access iterator. 195 | */ 196 | random_access_iterator operator-(difference_type n) const { return (_elem - n); } 197 | 198 | /* 199 | ** @brief Give a reference to this random access iterator 200 | ** where the element pointed is at the actual pointer memory 201 | ** plus "n". 202 | ** 203 | ** @param n the number of elements. 204 | ** @return the random access iterator. 205 | */ 206 | random_access_iterator& operator+=(difference_type n) 207 | { 208 | _elem += n; 209 | return (*this); 210 | } 211 | 212 | /* 213 | ** @brief Give a reference to this random access iterator 214 | ** where the element pointed is at the actual pointer memory 215 | ** minus "n". 216 | ** 217 | ** @param n the number of elements. 218 | ** @return the random access iterator. 219 | */ 220 | random_access_iterator& operator-=(difference_type n) 221 | { 222 | _elem -= n; 223 | return (*this); 224 | } 225 | 226 | /* 227 | ** @brief Give a reference to the elements at an arbitrary offset 228 | ** position relative to the element pointed by the random access 229 | ** iterator. 230 | ** 231 | ** @param n the offset position. 232 | ** @return the reference. 233 | */ 234 | reference operator[](difference_type n) { return (*(operator+(n))); } 235 | 236 | operator random_access_iterator () const 237 | { return (random_access_iterator(this->_elem)); } 238 | 239 | private: 240 | /* Element pointed by the iterator. */ 241 | pointer _elem; 242 | }; 243 | 244 | /* 245 | ** @brief Check if the pointer of "lhs" 246 | ** is equal than "rhs" in the memory. 247 | ** 248 | ** @param lhs the random access iterator to compare. 249 | ** @param rhs the random access iterator with who check. 250 | ** @return true if the pointer of lhs 251 | ** if equal than "rhs", otherwise false. 252 | */ 253 | template 254 | typename ft::random_access_iterator::difference_type 255 | operator==(const ft::random_access_iterator lhs, 256 | const ft::random_access_iterator rhs) 257 | { 258 | return (lhs.base() == rhs.base()); 259 | } 260 | 261 | /* For iterator == const_iterator */ 262 | template 263 | typename ft::random_access_iterator::difference_type 264 | operator==(const ft::random_access_iterator lhs, 265 | const ft::random_access_iterator rhs) 266 | { 267 | return (lhs.base() == rhs.base()); 268 | } 269 | 270 | /* 271 | ** @brief Check if the pointer of "lhs" 272 | ** is different than "rhs" in the memory. 273 | ** 274 | ** @param lhs the random access iterator to compare. 275 | ** @param rhs the random access iterator with who check. 276 | ** @return true if the pointer of lhs 277 | ** if different than "rhs", otherwise false. 278 | */ 279 | template 280 | typename ft::random_access_iterator::difference_type 281 | operator!=(const ft::random_access_iterator lhs, 282 | const ft::random_access_iterator rhs) 283 | { 284 | return (lhs.base() != rhs.base()); 285 | } 286 | 287 | /* For iterator != const_iterator */ 288 | template 289 | typename ft::random_access_iterator::difference_type 290 | operator!=(const ft::random_access_iterator lhs, 291 | const ft::random_access_iterator rhs) 292 | { 293 | return (lhs.base() != rhs.base()); 294 | } 295 | 296 | /* 297 | ** @brief Check if the pointer of "lhs" 298 | ** is lower than "rhs" in the memory. 299 | ** 300 | ** @param lhs the random access iterator to compare. 301 | ** @param rhs the random access iterator with who check. 302 | ** @return true if the pointer of lhs 303 | ** if lower than "rhs", otherwise false. 304 | */ 305 | template 306 | typename ft::random_access_iterator::difference_type 307 | operator<(const ft::random_access_iterator lhs, 308 | const ft::random_access_iterator rhs) 309 | { 310 | return (lhs.base() < rhs.base()); 311 | } 312 | 313 | /* For iterator < const_iterator */ 314 | template 315 | typename ft::random_access_iterator::difference_type 316 | operator<(const ft::random_access_iterator lhs, 317 | const ft::random_access_iterator rhs) 318 | { 319 | return (lhs.base() < rhs.base()); 320 | } 321 | 322 | /* 323 | ** @brief Check if the pointer of "lhs" 324 | ** is upper than "rhs" in the memory. 325 | ** 326 | ** @param lhs the random access iterator to compare. 327 | ** @param rhs the random access iterator with who check. 328 | ** @return true if the pointer of lhs 329 | ** if upper than "rhs", otherwise false. 330 | */ 331 | template 332 | typename ft::random_access_iterator::difference_type 333 | operator>(const ft::random_access_iterator lhs, 334 | const ft::random_access_iterator rhs) 335 | { 336 | return (lhs.base() > rhs.base()); 337 | } 338 | 339 | /* For iterator > const_iterator */ 340 | template 342 | typename ft::random_access_iterator::difference_type 343 | operator>(const ft::random_access_iterator lhs, 344 | const ft::random_access_iterator rhs) 345 | { 346 | return (lhs.base() > rhs.base()); 347 | } 348 | 349 | /* 350 | ** @brief Check if the pointer of "lhs" 351 | ** is lower or equal than "rhs" in the memory. 352 | ** 353 | ** @param lhs the random access iterator to compare. 354 | ** @param rhs the random access iterator with who check. 355 | ** @return true if the pointer of lhs 356 | ** if lower or equal than "rhs", otherwise false. 357 | */ 358 | template 359 | typename ft::random_access_iterator::difference_type 360 | operator<=(const ft::random_access_iterator lhs, 361 | const ft::random_access_iterator rhs) 362 | { 363 | return (lhs.base() <= rhs.base()); 364 | } 365 | 366 | /* For iterator <= const_iterator */ 367 | template 368 | typename ft::random_access_iterator::difference_type 369 | operator<=(const ft::random_access_iterator lhs, 370 | const ft::random_access_iterator rhs) 371 | { 372 | return (lhs.base() <= rhs.base()); 373 | } 374 | 375 | /* 376 | ** @brief Check if the pointer of "lhs" 377 | ** is upper or equal than "rhs" in the memory. 378 | ** 379 | ** @param lhs the random access iterator to compare. 380 | ** @param rhs the random access iterator with who check. 381 | ** @return true if the pointer of lhs 382 | ** if upper or equal than "rhs", otherwise false. 383 | */ 384 | template 385 | typename ft::random_access_iterator::difference_type 386 | operator>=(const ft::random_access_iterator lhs, 387 | const ft::random_access_iterator rhs) 388 | { 389 | return (lhs.base() >= rhs.base()); 390 | } 391 | 392 | /* For iterator >= const_iterator */ 393 | template 395 | typename ft::random_access_iterator::difference_type 396 | operator>=(const ft::random_access_iterator lhs, 397 | const ft::random_access_iterator rhs) 398 | { 399 | return (lhs.base() >= rhs.base()); 400 | } 401 | 402 | /* 403 | ** @brief Give a random access iterator pointing to 404 | ** "rai" plus "n". 405 | ** 406 | ** @param n The number of location away the element pointed 407 | ** by rai. 408 | ** @param rai The random access iterator. 409 | ** @return A random access iterator pointing to n element 410 | ** after rai pointed element. 411 | */ 412 | template 413 | ft::random_access_iterator operator+( 414 | typename ft::random_access_iterator::difference_type n, 415 | typename ft::random_access_iterator& rai) 416 | { 417 | return (&(*rai) + n); 418 | } 419 | 420 | /* 421 | ** @brief Give the difference between the address 422 | ** of two random access iterators. 423 | ** 424 | ** @param lhs,rhs the two random access iterator with whom 425 | ** to make a difference. 426 | ** @return The difference. 427 | */ 428 | template 429 | typename ft::random_access_iterator::difference_type 430 | operator-(const ft::random_access_iterator lhs, 431 | const ft::random_access_iterator rhs) 432 | { 433 | return (lhs.base() - rhs.base()); 434 | } 435 | 436 | /* For iterator - const_iterator */ 437 | template 438 | typename ft::random_access_iterator::difference_type 439 | operator-(const ft::random_access_iterator lhs, 440 | const ft::random_access_iterator rhs) 441 | { 442 | return (lhs.base() - rhs.base()); 443 | } 444 | 445 | } 446 | 447 | #endif -------------------------------------------------------------------------------- /containers/map.hpp: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* map.hpp :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: rchallie +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2020/12/07 17:14:11 by rchallie #+# #+# */ 9 | /* Updated: 2020/12/10 21:35:37 by rchallie ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #ifndef MAP_HPP 14 | # define MAP_HPP 15 | 16 | #include "./utils/utils.hpp" 17 | #include "./utils/binary_search_tree.hpp" 18 | 19 | namespace ft 20 | { 21 | template < class Key, class T, class Compare = ft::less, 22 | class Alloc = std::allocator > > 23 | class map 24 | { 25 | public: 26 | 27 | /* 28 | ** The first template parameter (Key) 29 | */ 30 | typedef Key key_type; 31 | 32 | /* 33 | ** The second template parameter (T) 34 | */ 35 | typedef T mapped_type; 36 | 37 | /* 38 | ** Type of stocked value create with Key and T. 39 | ** pair 40 | */ 41 | typedef ft::pair value_type; 42 | 43 | /* 44 | ** The third template parameter (Compare) 45 | */ 46 | typedef Compare key_compare; 47 | 48 | /* 49 | ** Function class to compare elements 50 | */ 51 | class value_compare : ft::binary_function 52 | { 53 | friend class map; 54 | 55 | protected: 56 | Compare comp; 57 | value_compare (Compare c) : comp(c) {} 58 | 59 | public: 60 | 61 | /* 62 | ** Result type, first argument type and second argument type are 63 | ** stocked int binary_function. 64 | */ 65 | 66 | /* 67 | ** @brief Call the compare function to compare 68 | ** "x" and "y". 69 | ** 70 | ** @param x,y values to compare. 71 | ** @return boolean from comparison function. 72 | */ 73 | bool operator() (const value_type& x, const value_type& y) const 74 | { return (comp(x.first, y.first)); } 75 | }; 76 | 77 | /* 78 | ** The fourth template parameter (Alloc) 79 | */ 80 | typedef Alloc allocator_type; 81 | 82 | /* 83 | ** allocator_type::reference 84 | ** A type provides a reference to an element stored in 85 | ** the container. 86 | ** For the default allocator is a reference to value_type 87 | ** (value_type&) 88 | */ 89 | typedef typename allocator_type::reference reference; 90 | 91 | /* 92 | ** allocator_type::const_reference 93 | ** Type that give a reference to a const element stored. 94 | ** Usefull to read and perform const operator. 95 | ** A type const_reference can't be used to modify the value 96 | ** of an element. 97 | ** For the default allocator is a const reference to value_type 98 | ** (const value_type&) 99 | */ 100 | typedef typename allocator_type::const_reference const_reference; 101 | 102 | /* 103 | ** allocator_type::pointer 104 | ** Type that give a pointer to an element stored. 105 | ** A type pointer can be used to modify the value of 106 | ** an element. 107 | ** For the default allocator is a pointer to value_type 108 | ** (value_type*) 109 | */ 110 | typedef typename allocator_type::pointer pointer; 111 | 112 | /* 113 | ** allocator_type::const_pointer 114 | ** Type that give a const pointer to an element stored. 115 | ** Can't be used to modify the value of an element. 116 | ** An iterator is prefered to access to an element. 117 | ** For the default allocator is a const pointer to value_type 118 | ** (const value_type*) 119 | */ 120 | typedef typename allocator_type::const_pointer const_pointer; 121 | 122 | /* 123 | ** A bidirectional iterator to value_type 124 | ** That can read or modify any element stored. 125 | ** Convertible to const_iterator; 126 | */ 127 | typedef typename ft::Binary_search_tree::iterator iterator; 128 | 129 | /* 130 | ** A bidirectional iterator to const value_type 131 | ** That can read element stored. 132 | */ 133 | typedef typename ft::Binary_search_tree::const_iterator const_iterator; 134 | 135 | /* 136 | ** ft::reverse_iterator 137 | ** That can read or modify any element in a reversed container. 138 | ** Used to iterate through the container in reverse. 139 | */ 140 | typedef typename ft::reverse_iterator reverse_iterator; 141 | 142 | /* 143 | ** ft::reverse_iterator 144 | ** That can read any element in a reversed the container. 145 | ** Can't be used to modify, used to iterate through the 146 | ** the container in reverse. 147 | */ 148 | typedef typename ft::reverse_iterator const_reverse_iterator; 149 | 150 | /* 151 | ** A signed integral type: 152 | ** Usually the same as ptrdiff_t. 153 | ** Can represent the difference between iterators to the 154 | ** element actually stored. 155 | ** Can be described as the number of element between two pointers. 156 | ** (Pointer to an element contains its address). 157 | */ 158 | typedef typename ft::iterator_traits::difference_type difference_type; 159 | 160 | /* 161 | ** An unsigned integral type that can represent any 162 | ** non-negative value of difference_type 163 | ** Usually the same as size_t. 164 | */ 165 | typedef size_t size_type; 166 | 167 | /* 168 | ** @brief Default : 169 | ** Construct an empty map container object. 170 | ** 171 | ** @param alloc the Allocator type. 172 | */ 173 | explicit map (const key_compare& comp = key_compare(), 174 | const allocator_type& alloc = allocator_type()) 175 | : 176 | _alloc(alloc), 177 | _comp(comp), 178 | _bst() 179 | {} 180 | 181 | /* 182 | ** @brief Iterator: 183 | ** Construct a list container, of size last-first containing 184 | ** value of [first, last). 185 | ** 186 | ** @param first,last the range of content. 187 | ** @param alloc the allocator type. 188 | */ 189 | template 190 | map (InputIterator first, InputIterator last, 191 | const key_compare& comp = key_compare(), 192 | const allocator_type& alloc = allocator_type(), 193 | typename ft::enable_if::value, InputIterator>::type* = u_nullptr) 194 | : 195 | _alloc(alloc), 196 | _comp(comp), 197 | _bst() 198 | { 199 | bool is_valid; 200 | if (!(is_valid = ft::is_input_iterator_tagged::iterator_category >::value)) 201 | throw (ft::InvalidIteratorException::iterator_category >::type>()); 202 | this->insert(first, last); 203 | } 204 | 205 | /* 206 | ** @brief Copy : 207 | ** Construct the container to be a copy of "x". 208 | ** 209 | ** @param x the lsit to copy. 210 | */ 211 | map(const map& x) 212 | : 213 | _alloc(x._alloc), 214 | _comp(x._comp), 215 | _bst() 216 | { 217 | this->insert(x.begin(), x.end()); 218 | } 219 | 220 | /* 221 | ** @brief Destructor: 222 | ** Clear the container and deallocate everythings. 223 | */ 224 | ~map() 225 | { this->clear(); } 226 | 227 | /* 228 | ** @brief Assign "x" to this. 229 | ** 230 | ** @param x the list where get elements. 231 | ** @return this list. 232 | */ 233 | map& operator= (const map& x) 234 | { 235 | if (&x == this) 236 | return (*this); 237 | this->clear(); 238 | this->insert(x.begin(), x.end()); 239 | return (*this); 240 | } 241 | 242 | /* 243 | ** @brief Return an iterator pointing on the first element 244 | ** in the container. If the container is empty, the 245 | ** returned iterator value shall no be dereferenced. 246 | ** The iterator is of type iterator (bidirectional iterator 247 | ** on value_type reference). 248 | ** 249 | ** @return The iterator to the first element. 250 | */ 251 | iterator begin() 252 | { return (iterator(_bst._last_node->left, _bst._last_node)); } 253 | 254 | /* 255 | ** @brief Return a const iterator pointing on the first element 256 | ** in the container. If the container is empty, the 257 | ** returned iterator value shall no be dereferenced. 258 | ** The iterator is of type const_iterator (bidirectional 259 | ** iterator on const value_type reference). 260 | ** 261 | ** @return The const iterator to the first element. 262 | */ 263 | const_iterator begin() const 264 | { return (const_iterator(_bst._last_node->left, _bst._last_node)); } 265 | 266 | /* 267 | ** @brief Return an iterator pointing on the past-the-end element 268 | ** in the container. Past-the-end is the theorical element 269 | ** following the last element in the container. If the container is 270 | ** empty, return the same than begin. 271 | ** The iterator is of type iterator (bidirectional iterator 272 | ** on value_type reference). 273 | ** 274 | ** @return The iterator to the past-the-end element or begin if 275 | ** the container is empty. 276 | */ 277 | iterator end() 278 | { return (iterator(_bst._last_node, _bst._last_node)); } 279 | 280 | /* 281 | ** @brief Return a const iterator pointing on the past-the-end element 282 | ** in the container. Past-the-end is the theorical element 283 | ** following the last element in the container. If the container is 284 | ** empty, return the same than begin. 285 | ** The iterator is of type const_iterator (bidirectional 286 | ** iterator on const value_type reference). 287 | ** 288 | ** @return The const iterator to the past-the-end element or begin if 289 | ** the container is empty. 290 | */ 291 | const_iterator end() const 292 | { return (const_iterator(_bst._last_node, _bst._last_node)); } 293 | 294 | /* 295 | ** @brief Give a reverse iterator pointing to the last element 296 | ** in the container (this->end() - 1). 297 | ** This is a reversed bidirectional iterator. 298 | ** 299 | ** @return A reverse Iterator to the reverse beginning of the container. 300 | */ 301 | reverse_iterator rbegin() 302 | { return (reverse_iterator(this->end())); } 303 | 304 | /* 305 | ** @brief Give a const reverse iterator pointing to the last 306 | ** element in the container (this->end() - 1). 307 | ** This is a constant reversed bidirectional iterator. 308 | ** 309 | ** @return A const reverse Iterator to the reverse beginning of the container. 310 | */ 311 | const_reverse_iterator rbegin() const 312 | { return (const_reverse_iterator(this->end())); } 313 | 314 | /* 315 | ** @brief Give a reverse iterator point to the 316 | ** theorical element preceding the first element 317 | ** in the container. 318 | ** 319 | ** @return the reverse iterator. 320 | */ 321 | reverse_iterator rend() 322 | { return (reverse_iterator(this->begin())); } 323 | 324 | /* 325 | ** @brief Give a const reverse iterator point to the 326 | ** theorical element preceding the first element 327 | ** in the container. 328 | ** 329 | ** @return the const reverse iterator. 330 | */ 331 | const_reverse_iterator rend() const 332 | { return (const_reverse_iterator(this->begin())); } 333 | 334 | /* 335 | ** @brief Returns whether the container is empty. 336 | ** Does not modify container in any way. 337 | ** 338 | ** @return true if the container size is 0, false otherwise. 339 | */ 340 | bool empty() const 341 | { return (_bst._last_node->parent == _bst._last_node); } 342 | 343 | /* 344 | ** @brief return the number of elements 345 | ** in the container. 346 | ** 347 | ** @return the number of elements. 348 | */ 349 | size_type size() const 350 | { return (_bst._last_node->value.first); } 351 | 352 | /* 353 | ** @brief Returns the maximum potential number of elements the the 354 | ** container can hold. 355 | ** This size is due to known system or library limitations. 356 | ** The container is not garanteed to have this size, it can 357 | ** fail a allocation for exemple. 358 | ** 359 | ** Documentation : 360 | ** https://www.viva64.com/en/a/0050/ 361 | ** 362 | ** @return The maximum potential number of elements the 363 | ** container can hold. 364 | ** (An unsigned integral type) 365 | */ 366 | size_type max_size() const 367 | { return (_bst.max_size()); } 368 | 369 | /* 370 | ** @brief If "k" match with the key of an 371 | ** element in the container, this will return 372 | ** the mapped value from this element. If "k" doesn't 373 | ** match, this will insert a new element with "k" like 374 | ** key and a mapped value initialized. 375 | ** 376 | ** @param k the key. 377 | ** @return an reference to the mapped value. 378 | */ 379 | mapped_type& operator[] (const key_type& k) 380 | { 381 | iterator tmp = this->find(k); 382 | 383 | if (tmp == this->end()) 384 | this->insert(ft::make_pair(k, mapped_type())); 385 | tmp = this->find(k); 386 | return ((*tmp).second); 387 | } 388 | 389 | /* 390 | ** @brief Insert a "value_type" (pair) in the container. 391 | ** Can increase the container size. 392 | ** 393 | ** @param val the pair to add to the container. 394 | ** @return An pair containing in key the iterator 395 | ** position of the inserted value and contain 396 | ** a bool at true if a new element was inserted 397 | ** or false if an equivalent key already exist, on value. 398 | */ 399 | pair insert (const value_type& val) 400 | { return (_bst.insertPair(val)); } 401 | 402 | /* 403 | ** @brief Use "position" like an hint to know 404 | ** where "val" can be insert. Like this information 405 | ** can be wrong and that the allocation system is 406 | ** based on a strict stoage, "position" is not used. 407 | ** 408 | ** @param position hint. 409 | ** @param val the pair to insert in the container. 410 | ** @return an iterator pointing to the newly inserted 411 | ** value or to the already existed value. 412 | */ 413 | iterator insert (iterator position, const value_type& val) 414 | { 415 | (void)position; 416 | return (_bst.insertPair(val).first); 417 | } 418 | 419 | /* 420 | ** @brief Insert element in range from ["first" to 421 | ** "last"). Can increase the size of 422 | ** the container. Throw if the iterator given is not valid. 423 | ** 424 | ** @param first the first element in the range. 425 | ** @param last the last element in the range. 426 | */ 427 | template 428 | void insert (InputIterator first, InputIterator last, 429 | typename ft::enable_if::value, InputIterator>::type* = u_nullptr) 430 | { 431 | bool is_valid; 432 | if (!(is_valid = ft::is_input_iterator_tagged::iterator_category >::value)) 433 | throw (ft::InvalidIteratorException::iterator_category >::type>()); 434 | 435 | difference_type n = ft::distance(first, last); 436 | while (n--) 437 | this->insert(*(first++)); 438 | } 439 | 440 | /* 441 | ** @brief Remove the element in the container at the iterator 442 | ** position. Reduce the size of the container. 443 | ** 444 | ** @param position the iterator pointing to the element to remove. 445 | */ 446 | void erase (iterator position) 447 | { this->erase((*position).first); } 448 | 449 | /* 450 | ** @brief Remove the element in the container that has like key 451 | ** "k". Reduce the size of the container. 452 | ** 453 | ** @param k the key. 454 | ** @return The number of element removed, 0 if no element have "k" 455 | ** like key, 1 otherwise. 456 | */ 457 | size_type erase (const key_type& k) 458 | { 459 | if (this->find(k) == this->end()) 460 | return (0); 461 | _bst.removeByKey(ft::make_pair(k, mapped_type())); 462 | return (1); 463 | } 464 | 465 | /* 466 | ** @brief Remove a range [first, last) element of the container. 467 | ** The container size is reduced by the number of element 468 | ** int the range. 469 | ** 470 | ** @param first,last the range. 471 | */ 472 | void erase (iterator first, iterator last) 473 | { 474 | while (first != last) 475 | this->erase((*(first++)).first); 476 | } 477 | 478 | /* 479 | ** @brief Exchanges the content with "x" content. 480 | ** "x" is of same type. Elements of "x" are elements 481 | ** of this container and elements of this are of "x". 482 | ** All iterators, references, pointer on the swaped 483 | ** objects stay valid. 484 | ** 485 | ** @param x the container to swap. 486 | */ 487 | void swap (map& x) 488 | { _bst.swap(x._bst); } 489 | 490 | /* 491 | ** @brief Removes (destroy) & deallocate 492 | ** all elements from the container. Final size is 0. 493 | */ 494 | void clear() 495 | { this->erase(this->begin(), this->end()); } 496 | 497 | /* 498 | ** @brief Return a copy of the key comparison object. 499 | ** 500 | ** @param the key comparison object. 501 | */ 502 | key_compare key_comp() const 503 | { return (key_compare()); } 504 | 505 | /* 506 | ** @brief Return a copy of the value comparison object. 507 | ** 508 | ** @param the value comparison object. 509 | */ 510 | value_compare value_comp() const 511 | { return (value_compare(key_compare())); } 512 | 513 | /* 514 | ** @brief Search in the container to find the pair 515 | ** that have like key "k". 516 | ** 517 | ** @param k the key to find. 518 | ** @return an iterator pointing to the pair object that 519 | ** have like key "k". 520 | */ 521 | iterator find (const key_type& k) 522 | { return (iterator(_bst.searchByKey(ft::make_pair(k, mapped_type())), _bst._last_node)); } 523 | 524 | /* 525 | ** @brief Search in the container to find the pair 526 | ** that have like key "k". 527 | ** 528 | ** @param k the key to find. 529 | ** @return an const iterator pointing to the pair object that 530 | ** have like key "k". 531 | */ 532 | const_iterator find (const key_type& k) const 533 | { return (const_iterator(_bst.searchByKey(ft::make_pair(k, mapped_type())), _bst._last_node)); } 534 | 535 | /* 536 | ** @brief Search in the countair if an element 537 | ** has "k" like key. 538 | ** 539 | ** @param k the key to find. 540 | ** @return 1 if the container have an element 541 | ** with k like key, 0 otherwise. 542 | */ 543 | size_type count (const key_type& k) const 544 | { 545 | const_iterator beg = this->begin(); 546 | const_iterator end = this->end(); 547 | 548 | while (beg != end) 549 | if ((*(beg++)).first == k) 550 | return (1); 551 | return (0); 552 | } 553 | 554 | /* 555 | ** @brief Return a iterator pointing to the first element 556 | ** in the container who have a key that is not 557 | ** concidered to go before "k". If an element have "k" 558 | ** like key, give an iterator to it. 559 | ** 560 | ** @param k the key. 561 | ** @return the iterator. 562 | */ 563 | iterator lower_bound (const key_type& k) 564 | { 565 | iterator beg = this->begin(); 566 | iterator end = this->end(); 567 | 568 | while (beg != end) 569 | { 570 | if (_comp((*beg).first, k) == false) 571 | break; 572 | beg++; 573 | } 574 | return (beg); 575 | } 576 | 577 | /* 578 | ** @brief Return a const iterator pointing to the first element 579 | ** in the container who have a key that is not 580 | ** concidered to go before "k". If an element have "k" 581 | ** like key, give an const iterator to it. 582 | ** 583 | ** @param k the key. 584 | ** @return the iterator. 585 | */ 586 | const_iterator lower_bound (const key_type& k) const 587 | { return (const_iterator(this->lower_bound(k))); } 588 | 589 | /* 590 | ** @brief return an iterator pointing to the next element 591 | ** whose key is concidered to go after "k". 592 | ** 593 | ** @param k the key. 594 | ** @return the iterator. 595 | */ 596 | iterator upper_bound (const key_type& k) 597 | { 598 | iterator beg = this->begin(); 599 | iterator end = this->end(); 600 | 601 | while (beg != end) 602 | { 603 | if (_comp(k, (*beg).first)) 604 | break; 605 | beg++; 606 | } 607 | return (beg); 608 | } 609 | 610 | /* 611 | ** @brief return an const iterator pointing to the next element 612 | ** whose key is concidered to go after "k". 613 | ** 614 | ** @param k the key. 615 | ** @return the const iterator. 616 | */ 617 | const_iterator upper_bound (const key_type& k) const 618 | { return (const_iterator(this->upper_bound(k))); } 619 | 620 | /* 621 | ** @brief Return all the element that have "k" like key. 622 | ** Like all element in map are unique, that give a pair 623 | ** that contain two const iterator. The first iterator 624 | ** pointing to the lower bound of "k" and the second pointing 625 | ** to the upper bound of "k". 626 | ** 627 | ** @param k the key. 628 | ** @return the pair containing the two const iterator. 629 | */ 630 | ft::pair equal_range (const key_type& k) const 631 | { return (ft::make_pair(this->lower_bound(k), this->upper_bound(k))); } 632 | 633 | /* 634 | ** @brief Return the element that have "k" like key. 635 | ** Like all element in map are unique, that give a pair 636 | ** that contain two iterator. The first iterator 637 | ** pointing to the lower bound of "k" and the second pointing 638 | ** to the upper bound of "k". 639 | ** 640 | ** @param k the key. 641 | ** @return the pair containing the two iterator. 642 | */ 643 | ft::pair equal_range (const key_type& k) 644 | { return (ft::make_pair(this->lower_bound(k), this->upper_bound(k))); } 645 | 646 | private: 647 | 648 | allocator_type _alloc; 649 | Compare _comp; 650 | Binary_search_tree _bst; 651 | 652 | }; 653 | } 654 | 655 | #endif -------------------------------------------------------------------------------- /tester/tester_stack.cpp: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* tester_stack.cpp :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: rchallie +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2020/12/01 00:25:51 by rchallie #+# #+# */ 9 | /* Updated: 2020/12/03 23:44:35 by rchallie ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "tester.hpp" 14 | #include "../containers/stack.hpp" 15 | #include 16 | 17 | template 18 | std::string equalContent( 19 | std::stack stl_stack, 20 | ft::stack ft_stack 21 | ) 22 | { 23 | while (42) 24 | { 25 | if (stl_stack.size() == 0 || ft_stack.size() == 0) 26 | break; 27 | if (ft_stack.top() != stl_stack.top()) 28 | return ("✘"); 29 | ft_stack.pop(); 30 | stl_stack.pop(); 31 | } 32 | return ("✔"); 33 | } 34 | 35 | template 36 | bool printStackAttributes( 37 | std::fstream& fs, 38 | std::stack stl_stack, 39 | ft::stack ft_stack 40 | ) 41 | { 42 | /* STL Values */ 43 | std::string stl_empty = ((stl_stack.empty() == 1) ? "true" : "false"); 44 | size_t stl_size = stl_stack.size(); 45 | 46 | /* FT Values */ 47 | std::string ft_empty = ((ft_stack.empty() == 1) ? "true" : "false"); 48 | size_t ft_size = ft_stack.size(); 49 | 50 | /* FT Result compare values */ 51 | bool empty = equalbool(ft_empty, stl_empty); 52 | bool size = equalbool(ft_size, stl_size); 53 | std::string content = equalContent(stl_stack, ft_stack); 54 | 55 | fs << "\n══════════════════════════════════════════════════════════════\n"; 56 | fs << "stacks attributes : \n"; 57 | fs << "STL : \n"; 58 | fs << "Empty : " << stl_empty << std::endl; 59 | fs << "Size : " << stl_size << std::endl; 60 | fs << "Content : ["; 61 | 62 | while (42) 63 | { 64 | if (stl_stack.size() == 0) 65 | break; 66 | fs << stl_stack.top(); 67 | stl_stack.pop(); 68 | if (stl_stack.size() != 0) 69 | fs << ", "; 70 | } 71 | 72 | fs << "]\n"; 73 | 74 | fs << std::endl; 75 | 76 | fs << "FT : \n"; 77 | fs << "Empty [" << equal(ft_empty, stl_empty) << "]: " << ft_empty << std::endl; 78 | fs << "Size [" << equal(ft_size, stl_size) << "]: " << ft_size << std::endl; 79 | 80 | fs << "Content [" << content << "]: ["; 81 | 82 | while (42) 83 | { 84 | if (ft_stack.size() == 0) 85 | break; 86 | fs << ft_stack.top(); 87 | ft_stack.pop(); 88 | if (ft_stack.size() != 0) 89 | fs << ", "; 90 | } 91 | fs << "]\n"; 92 | 93 | fs << "══════════════════════════════════════════════════════════════\n"; 94 | 95 | /* Error case */ 96 | if (empty == false) 97 | return (false); 98 | else if (size == false) 99 | return (false); 100 | else if (content == "✘") 101 | return (false); 102 | return (true); 103 | } 104 | 105 | void test_stack() 106 | { 107 | std::cout << UNDERLINE << "STACK :\n" << NORMAL ; 108 | 109 | mkdir("./tester/stacks_output", 0777); 110 | 111 | std::fstream fs; 112 | 113 | /* Member functions */ 114 | std::cout << "Member functions : "; 115 | 116 | /* Default Constructor */ 117 | { 118 | std::stack stl_default; 119 | ft::stack ft_default; 120 | 121 | fs.open("./tester/stacks_output/constructor_default", std::fstream::in | std::fstream::out | std::fstream::trunc); 122 | std::cout << ((printStackAttributes(fs, stl_default, ft_default) == true) ? "[OK]" : "[NOP]"); 123 | 124 | fs << "\nCode executed:\n"; 125 | fs << "¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\n"; 126 | fs << "ft::stack ft_default;\n"; 127 | fs << "\nCompared with:\n"; 128 | fs << "¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\n"; 129 | fs << "std::stack stl_default;\n"; 130 | fs.close(); 131 | 132 | } 133 | 134 | /* Empty true */ 135 | { 136 | std::stack stl_empty; 137 | ft::stack ft_empty; 138 | 139 | fs.open("./tester/stacks_output/empty_true", std::fstream::in | std::fstream::out | std::fstream::trunc); 140 | std::cout << ((printStackAttributes(fs, stl_empty, ft_empty) == true) ? "[OK]" : "[NOP]"); 141 | 142 | fs << "\nCode executed:\n"; 143 | fs << "¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\n"; 144 | fs << "ft::stack ft_empty;\n"; 145 | fs << "\nCompared with:\n"; 146 | fs << "¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\n"; 147 | fs << "std::stack stl_empty;\n"; 148 | fs.close(); 149 | } 150 | 151 | /* Empty false */ 152 | { 153 | std::stack stl_empty; 154 | ft::stack ft_empty; 155 | 156 | stl_empty.push(42); 157 | ft_empty.push(42); 158 | 159 | fs.open("./tester/stacks_output/empty_false", std::fstream::in | std::fstream::out | std::fstream::trunc); 160 | std::cout << ((printStackAttributes(fs, stl_empty, ft_empty) == true) ? "[OK]" : "[NOP]"); 161 | 162 | fs << "\nCode executed:\n"; 163 | fs << "¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\n"; 164 | fs << "ft::stack ft_empty;\n"; 165 | fs << "ft_empty.push(42);\n"; 166 | fs << "\nCompared with:\n"; 167 | fs << "¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\n"; 168 | fs << "std::stack stl_empty;\n"; 169 | fs << "stl_empty.push(42);\n"; 170 | fs.close(); 171 | } 172 | 173 | /* Size */ 174 | { 175 | std::stack stl_size; 176 | ft::stack ft_size; 177 | 178 | for (int i = 0; i < 42; i++) 179 | { 180 | stl_size.push(i); 181 | ft_size.push(i); 182 | } 183 | 184 | fs.open("./tester/stacks_output/size", std::fstream::in | std::fstream::out | std::fstream::trunc); 185 | std::cout << ((printStackAttributes(fs, stl_size, ft_size) == true) ? "[OK]" : "[NOP]"); 186 | 187 | fs << "\nCode executed:\n"; 188 | fs << "¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\n"; 189 | fs << "ft::stack ft_size;\n"; 190 | fs << "for (int i = 0; i < 42; i++)\n"; 191 | fs << " ft_size.push(i);\n"; 192 | fs << "\nCompared with:\n"; 193 | fs << "¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\n"; 194 | fs << "std::stack stl_size;\n"; 195 | fs << "for (int i = 0; i < 42; i++)\n"; 196 | fs << " stl_size.push(i);\n"; 197 | fs.close(); 198 | } 199 | 200 | /* Top */ 201 | { 202 | std::stack stl_top; 203 | ft::stack ft_top; 204 | 205 | for (int i = 0; i < 42; i++) 206 | { 207 | stl_top.push(i); 208 | ft_top.push(i); 209 | } 210 | 211 | fs.open("./tester/stacks_output/top", std::fstream::in | std::fstream::out | std::fstream::trunc); 212 | std::cout << ((printSingleValue(fs, stl_top.top(), ft_top.top()) == true) ? "[OK]" : "[NOP]"); 213 | 214 | stl_top.pop(); 215 | ft_top.pop(); 216 | 217 | std::cout << ((printSingleValue(fs, stl_top.top(), ft_top.top()) == true) ? "[OK]" : "[NOP]"); 218 | 219 | fs << "\nCode executed:\n"; 220 | fs << "¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\n"; 221 | fs << "ft::stack ft_top;\n"; 222 | fs << "for (int i = 0; i < 42; i++)\n"; 223 | fs << " ft_top.push(i);\n"; 224 | fs << "Send output...\n"; 225 | fs << "ft_top.pop();\n"; 226 | fs << "\nCompared with:\n"; 227 | fs << "¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\n"; 228 | fs << "std::stack stl_top;\n"; 229 | fs << "for (int i = 0; i < 42; i++)\n"; 230 | fs << " stl_top.push(i);\n"; 231 | fs << "Send output...\n"; 232 | fs << "stl_top.pop();\n"; 233 | fs.close(); 234 | } 235 | 236 | /* Push */ 237 | { 238 | std::stack stl_size; 239 | ft::stack ft_size; 240 | 241 | for (int i = 0; i < 42; i++) 242 | { 243 | stl_size.push(i * 2); 244 | ft_size.push(i * 2); 245 | } 246 | 247 | fs.open("./tester/stacks_output/push", std::fstream::in | std::fstream::out | std::fstream::trunc); 248 | std::cout << ((printStackAttributes(fs, stl_size, ft_size) == true) ? "[OK]" : "[NOP]"); 249 | 250 | fs << "\nCode executed:\n"; 251 | fs << "¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\n"; 252 | fs << "ft::stack ft_size;\n"; 253 | fs << "for (int i = 0; i < 42; i++)\n"; 254 | fs << " ft_size.push(i * 2);\n"; 255 | fs << "\nCompared with:\n"; 256 | fs << "¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\n"; 257 | fs << "std::stack stl_size;\n"; 258 | fs << "for (int i = 0; i < 42; i++)\n"; 259 | fs << " stl_size.push(i * 2);\n"; 260 | fs.close(); 261 | } 262 | 263 | /* Pop */ 264 | { 265 | std::stack stl_pop; 266 | ft::stack ft_pop; 267 | 268 | for (int i = 0; i < 42; i++) 269 | { 270 | stl_pop.push(i); 271 | ft_pop.push(i); 272 | } 273 | 274 | fs.open("./tester/stacks_output/pop", std::fstream::in | std::fstream::out | std::fstream::trunc); 275 | std::cout << ((printStackAttributes(fs, stl_pop, ft_pop) == true) ? "[OK]" : "[NOP]"); 276 | 277 | stl_pop.pop(); 278 | ft_pop.pop(); 279 | 280 | std::cout << ((printStackAttributes(fs, stl_pop, ft_pop) == true) ? "[OK]" : "[NOP]"); 281 | 282 | fs << "\nCode executed:\n"; 283 | fs << "¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\n"; 284 | fs << "ft::stack ft_pop;\n"; 285 | fs << "for (int i = 0; i < 42; i++)\n"; 286 | fs << " ft_pop.push(i);\n"; 287 | fs << "Send output...\n"; 288 | fs << "ft_pop.pop();\n"; 289 | fs << "\nCompared with:\n"; 290 | fs << "¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\n"; 291 | fs << "std::stack stl_pop;\n"; 292 | fs << "for (int i = 0; i < 42; i++)\n"; 293 | fs << " stl_pop.push(i);\n"; 294 | fs << "Send output...\n"; 295 | fs << "stl_pop.pop();\n"; 296 | fs.close(); 297 | } 298 | 299 | std::cout << std::endl; 300 | std::cout << "Non-member function overloads : "; 301 | 302 | /* RL = relational operator */ 303 | 304 | /* RL == true */ 305 | { 306 | std::stack stl_pop_one; 307 | std::stack stl_pop_two; 308 | ft::stack ft_pop_one; 309 | ft::stack ft_pop_two; 310 | 311 | for (int i = 0; i < 42; i++) 312 | { 313 | stl_pop_one.push(i); 314 | stl_pop_two.push(i); 315 | ft_pop_one.push(i); 316 | ft_pop_two.push(i); 317 | } 318 | 319 | fs.open("./tester/stacks_output/operator_equal_true", std::fstream::in | std::fstream::out | std::fstream::trunc); 320 | printStackAttributes(fs, stl_pop_one, ft_pop_one); 321 | printStackAttributes(fs, stl_pop_two, ft_pop_two); 322 | 323 | std::cout << ((printBoolResult(fs, (stl_pop_one == stl_pop_two), (ft_pop_one == ft_pop_two)) == true) ? "[OK]" : "[NOP]"); 324 | 325 | fs << "\nCode executed:\n"; 326 | fs << "¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\n"; 327 | fs << "ft::stack ft_pop;\n"; 328 | fs << "for (int i = 0; i < 42; i++)\n"; 329 | fs << "{\n"; 330 | fs << " ft_pop_one.push(i);\n"; 331 | fs << " ft_pop_two.push(i);\n"; 332 | fs << "}\n"; 333 | fs << "\nCompared with:\n"; 334 | fs << "¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\n"; 335 | fs << "std::stack stl_pop;\n"; 336 | fs << "for (int i = 0; i < 42; i++)\n"; 337 | fs << "{\n"; 338 | fs << " stl_pop_one.push(i);\n"; 339 | fs << " stl_pop_two.push(i);\n"; 340 | fs << "}\n"; 341 | fs.close(); 342 | } 343 | 344 | /* RL == false */ 345 | { 346 | std::stack stl_pop_one; 347 | std::stack stl_pop_two; 348 | ft::stack ft_pop_one; 349 | ft::stack ft_pop_two; 350 | 351 | for (int i = 0; i < 42; i++) 352 | { 353 | stl_pop_one.push(i); 354 | stl_pop_two.push(i * 2); 355 | ft_pop_one.push(i); 356 | ft_pop_two.push(i * 2); 357 | } 358 | 359 | fs.open("./tester/stacks_output/operator_equal_false", std::fstream::in | std::fstream::out | std::fstream::trunc); 360 | printStackAttributes(fs, stl_pop_one, ft_pop_one); 361 | printStackAttributes(fs, stl_pop_two, ft_pop_two); 362 | 363 | std::cout << ((printBoolResult(fs, (stl_pop_one == stl_pop_two), (ft_pop_one == ft_pop_two)) == true) ? "[OK]" : "[NOP]"); 364 | 365 | fs << "\nCode executed:\n"; 366 | fs << "¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\n"; 367 | fs << "ft::stack ft_pop;\n"; 368 | fs << "for (int i = 0; i < 42; i++)\n"; 369 | fs << "{\n"; 370 | fs << " ft_pop_one.push(i);\n"; 371 | fs << " ft_pop_two.push(i * 2);\n"; 372 | fs << "}\n"; 373 | fs << "\nCompared with:\n"; 374 | fs << "¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\n"; 375 | fs << "std::stack stl_pop;\n"; 376 | fs << "for (int i = 0; i < 42; i++)\n"; 377 | fs << "{\n"; 378 | fs << " stl_pop_one.push(i);\n"; 379 | fs << " stl_pop_two.push(i * 2);\n"; 380 | fs << "}\n"; 381 | fs.close(); 382 | } 383 | 384 | /* RL != true */ 385 | { 386 | std::stack stl_pop_one; 387 | std::stack stl_pop_two; 388 | ft::stack ft_pop_one; 389 | ft::stack ft_pop_two; 390 | 391 | for (int i = 0; i < 42; i++) 392 | { 393 | stl_pop_one.push(i); 394 | stl_pop_two.push(i * 2); 395 | ft_pop_one.push(i); 396 | ft_pop_two.push(i * 2); 397 | } 398 | 399 | fs.open("./tester/stacks_output/operator_net_equal_true", std::fstream::in | std::fstream::out | std::fstream::trunc); 400 | printStackAttributes(fs, stl_pop_one, ft_pop_one); 401 | printStackAttributes(fs, stl_pop_two, ft_pop_two); 402 | 403 | std::cout << ((printBoolResult(fs, (stl_pop_one != stl_pop_two), (ft_pop_one != ft_pop_two)) == true) ? "[OK]" : "[NOP]"); 404 | 405 | fs << "\nCode executed:\n"; 406 | fs << "¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\n"; 407 | fs << "ft::stack ft_pop;\n"; 408 | fs << "for (int i = 0; i < 42; i++)\n"; 409 | fs << "{\n"; 410 | fs << " ft_pop_one.push(i);\n"; 411 | fs << " ft_pop_two.push(i * 2);\n"; 412 | fs << "}\n"; 413 | fs << "\nCompared with:\n"; 414 | fs << "¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\n"; 415 | fs << "std::stack stl_pop;\n"; 416 | fs << "for (int i = 0; i < 42; i++)\n"; 417 | fs << "{\n"; 418 | fs << " stl_pop_one.push(i);\n"; 419 | fs << " stl_pop_two.push(i * 2);\n"; 420 | fs << "}\n"; 421 | fs.close(); 422 | } 423 | 424 | /* RL != false */ 425 | { 426 | std::stack stl_pop_one; 427 | std::stack stl_pop_two; 428 | ft::stack ft_pop_one; 429 | ft::stack ft_pop_two; 430 | 431 | for (int i = 0; i < 42; i++) 432 | { 433 | stl_pop_one.push(i); 434 | stl_pop_two.push(i); 435 | ft_pop_one.push(i); 436 | ft_pop_two.push(i); 437 | } 438 | 439 | fs.open("./tester/stacks_output/operator_not_equal_false", std::fstream::in | std::fstream::out | std::fstream::trunc); 440 | printStackAttributes(fs, stl_pop_one, ft_pop_one); 441 | printStackAttributes(fs, stl_pop_two, ft_pop_two); 442 | 443 | std::cout << ((printBoolResult(fs, (stl_pop_one != stl_pop_two), (ft_pop_one != ft_pop_two)) == true) ? "[OK]" : "[NOP]"); 444 | 445 | fs << "\nCode executed:\n"; 446 | fs << "¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\n"; 447 | fs << "ft::stack ft_pop;\n"; 448 | fs << "for (int i = 0; i < 42; i++)\n"; 449 | fs << "{\n"; 450 | fs << " ft_pop_one.push(i);\n"; 451 | fs << " ft_pop_two.push(i);\n"; 452 | fs << "}\n"; 453 | fs << "\nCompared with:\n"; 454 | fs << "¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\n"; 455 | fs << "std::stack stl_pop;\n"; 456 | fs << "for (int i = 0; i < 42; i++)\n"; 457 | fs << "{\n"; 458 | fs << " stl_pop_one.push(i);\n"; 459 | fs << " stl_pop_two.push(i);\n"; 460 | fs << "}\n"; 461 | fs.close(); 462 | } 463 | 464 | /* RL < true */ 465 | { 466 | std::stack stl_pop_one; 467 | std::stack stl_pop_two; 468 | ft::stack ft_pop_one; 469 | ft::stack ft_pop_two; 470 | 471 | for (int i = 0; i < 42; i++) 472 | { 473 | stl_pop_one.push(i); 474 | ft_pop_one.push(i); 475 | if (i == 30) 476 | { 477 | stl_pop_two.push(i * 2); 478 | ft_pop_two.push(i * 2); 479 | } 480 | else 481 | { 482 | stl_pop_two.push(i); 483 | ft_pop_two.push(i); 484 | } 485 | } 486 | 487 | fs.open("./tester/stacks_output/operator_inf_true", std::fstream::in | std::fstream::out | std::fstream::trunc); 488 | printStackAttributes(fs, stl_pop_one, ft_pop_one); 489 | printStackAttributes(fs, stl_pop_two, ft_pop_two); 490 | 491 | std::cout << ((printBoolResult(fs, (stl_pop_one < stl_pop_two), (ft_pop_one < ft_pop_two)) == true) ? "[OK]" : "[NOP]"); 492 | 493 | fs << "\nCode executed:\n"; 494 | fs << "¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\n"; 495 | fs << "ft::stack ft_pop;\n"; 496 | fs << "for (int i = 0; i < 42; i++)\n"; 497 | fs << "{\n"; 498 | fs << " ft_pop_one.push(i);\n"; 499 | fs << " if (i == 30)\n"; 500 | fs << " ft_pop_two.push(i * 2);\n"; 501 | fs << " else\n"; 502 | fs << " ft_pop_two.push(i);\n"; 503 | fs << "}\n"; 504 | fs << "\nCompared with:\n"; 505 | fs << "¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\n"; 506 | fs << "std::stack stl_pop;\n"; 507 | fs << "for (int i = 0; i < 42; i++)\n"; 508 | fs << "{\n"; 509 | fs << " stl_pop_one.push(i);\n"; 510 | fs << " if (i == 30)\n"; 511 | fs << " stl_pop_two.push(i * 2);\n"; 512 | fs << " else\n"; 513 | fs << " stl_pop_two.push(i);\n"; 514 | fs << "}\n"; 515 | fs.close(); 516 | } 517 | 518 | /* RL < false */ 519 | { 520 | std::stack stl_pop_one; 521 | std::stack stl_pop_two; 522 | ft::stack ft_pop_one; 523 | ft::stack ft_pop_two; 524 | 525 | for (int i = 0; i < 42; i++) 526 | { 527 | stl_pop_two.push(i); 528 | ft_pop_two.push(i); 529 | if (i == 30) 530 | { 531 | stl_pop_one.push(i * 2); 532 | ft_pop_one.push(i * 2); 533 | } 534 | else 535 | { 536 | stl_pop_one.push(i); 537 | ft_pop_one.push(i); 538 | } 539 | } 540 | 541 | fs.open("./tester/stacks_output/operator_inf_false", std::fstream::in | std::fstream::out | std::fstream::trunc); 542 | printStackAttributes(fs, stl_pop_one, ft_pop_one); 543 | printStackAttributes(fs, stl_pop_two, ft_pop_two); 544 | 545 | std::cout << ((printBoolResult(fs, (stl_pop_one < stl_pop_two), (ft_pop_one < ft_pop_two)) == true) ? "[OK]" : "[NOP]"); 546 | 547 | fs << "\nCode executed:\n"; 548 | fs << "¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\n"; 549 | fs << "ft::stack ft_pop;\n"; 550 | fs << "for (int i = 0; i < 42; i++)\n"; 551 | fs << "{\n"; 552 | fs << " ft_pop_two.push(i);\n"; 553 | fs << " if (i == 30)\n"; 554 | fs << " ft_pop_one.push(i * 2);\n"; 555 | fs << " else\n"; 556 | fs << " ft_pop_one.push(i);\n"; 557 | fs << "}\n"; 558 | fs << "\nCompared with:\n"; 559 | fs << "¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\n"; 560 | fs << "std::stack stl_pop;\n"; 561 | fs << "for (int i = 0; i < 42; i++)\n"; 562 | fs << "{\n"; 563 | fs << " stl_pop_two.push(i);\n"; 564 | fs << " if (i == 30)\n"; 565 | fs << " stl_pop_two.push(i * 2);\n"; 566 | fs << " else\n"; 567 | fs << " stl_pop_one.push(i);\n"; 568 | fs << "}\n"; 569 | fs.close(); 570 | } 571 | 572 | /* RL <= true */ 573 | { 574 | std::stack stl_pop_one; 575 | std::stack stl_pop_two; 576 | ft::stack ft_pop_one; 577 | ft::stack ft_pop_two; 578 | 579 | for (int i = 0; i < 42; i++) 580 | { 581 | stl_pop_one.push(i); 582 | stl_pop_two.push(i * 2); 583 | ft_pop_one.push(i); 584 | ft_pop_two.push(i * 2); 585 | } 586 | 587 | fs.open("./tester/stacks_output/operator_inf_equal_true", std::fstream::in | std::fstream::out | std::fstream::trunc); 588 | printStackAttributes(fs, stl_pop_one, ft_pop_one); 589 | printStackAttributes(fs, stl_pop_two, ft_pop_two); 590 | 591 | std::cout << ((printBoolResult(fs, (stl_pop_one <= stl_pop_two), (ft_pop_one <= ft_pop_two)) == true) ? "[OK]" : "[NOP]"); 592 | 593 | fs << "\nCode executed:\n"; 594 | fs << "¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\n"; 595 | fs << "ft::stack ft_pop;\n"; 596 | fs << "for (int i = 0; i < 42; i++)\n"; 597 | fs << "{\n"; 598 | fs << " ft_pop_one.push(i);\n"; 599 | fs << " ft_pop_two.push(i * 2);\n"; 600 | fs << "}\n"; 601 | fs << "\nCompared with:\n"; 602 | fs << "¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\n"; 603 | fs << "std::stack stl_pop;\n"; 604 | fs << "for (int i = 0; i < 42; i++)\n"; 605 | fs << "{\n"; 606 | fs << " stl_pop_one.push(i);\n"; 607 | fs << " stl_pop_two.push(i * 2);\n"; 608 | fs << "}\n"; 609 | fs.close(); 610 | } 611 | 612 | /* RL <= true equal */ 613 | { 614 | std::stack stl_pop_one; 615 | std::stack stl_pop_two; 616 | ft::stack ft_pop_one; 617 | ft::stack ft_pop_two; 618 | 619 | for (int i = 0; i < 42; i++) 620 | { 621 | stl_pop_one.push(i); 622 | stl_pop_two.push(i); 623 | ft_pop_one.push(i); 624 | ft_pop_two.push(i); 625 | } 626 | 627 | fs.open("./tester/stacks_output/operator_inf_equal_true", std::fstream::in | std::fstream::out | std::fstream::trunc); 628 | printStackAttributes(fs, stl_pop_one, ft_pop_one); 629 | printStackAttributes(fs, stl_pop_two, ft_pop_two); 630 | 631 | std::cout << ((printBoolResult(fs, (stl_pop_one <= stl_pop_two), (ft_pop_one <= ft_pop_two)) == true) ? "[OK]" : "[NOP]"); 632 | 633 | fs << "\nCode executed:\n"; 634 | fs << "¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\n"; 635 | fs << "ft::stack ft_pop;\n"; 636 | fs << "for (int i = 0; i < 42; i++)\n"; 637 | fs << "{\n"; 638 | fs << " ft_pop_one.push(i);\n"; 639 | fs << " ft_pop_two.push(i);\n"; 640 | fs << "}\n"; 641 | fs << "\nCompared with:\n"; 642 | fs << "¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\n"; 643 | fs << "std::stack stl_pop;\n"; 644 | fs << "for (int i = 0; i < 42; i++)\n"; 645 | fs << "{\n"; 646 | fs << " stl_pop_one.push(i);\n"; 647 | fs << " stl_pop_two.push(i);\n"; 648 | fs << "}\n"; 649 | fs.close(); 650 | } 651 | 652 | /* RL <= false */ 653 | { 654 | std::stack stl_pop_one; 655 | std::stack stl_pop_two; 656 | ft::stack ft_pop_one; 657 | ft::stack ft_pop_two; 658 | 659 | for (int i = 0; i < 42; i++) 660 | { 661 | stl_pop_one.push(i * 2); 662 | stl_pop_two.push(i); 663 | ft_pop_one.push(i * 2); 664 | ft_pop_two.push(i); 665 | } 666 | 667 | fs.open("./tester/stacks_output/operator_inf_equal_false", std::fstream::in | std::fstream::out | std::fstream::trunc); 668 | printStackAttributes(fs, stl_pop_one, ft_pop_one); 669 | printStackAttributes(fs, stl_pop_two, ft_pop_two); 670 | 671 | std::cout << ((printBoolResult(fs, (stl_pop_one <= stl_pop_two), (ft_pop_one <= ft_pop_two)) == true) ? "[OK]" : "[NOP]"); 672 | 673 | fs << "\nCode executed:\n"; 674 | fs << "¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\n"; 675 | fs << "ft::stack ft_pop;\n"; 676 | fs << "for (int i = 0; i < 42; i++)\n"; 677 | fs << "{\n"; 678 | fs << " ft_pop_one.push(i * 2);\n"; 679 | fs << " ft_pop_two.push(i);\n"; 680 | fs << "}\n"; 681 | fs << "\nCompared with:\n"; 682 | fs << "¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\n"; 683 | fs << "std::stack stl_pop;\n"; 684 | fs << "for (int i = 0; i < 42; i++)\n"; 685 | fs << "{\n"; 686 | fs << " stl_pop_one.push(i * 2);\n"; 687 | fs << " stl_pop_two.push(i);\n"; 688 | fs << "}\n"; 689 | fs.close(); 690 | } 691 | 692 | /* RL > true */ 693 | { 694 | std::stack stl_pop_one; 695 | std::stack stl_pop_two; 696 | ft::stack ft_pop_one; 697 | ft::stack ft_pop_two; 698 | 699 | for (int i = 0; i < 42; i++) 700 | { 701 | stl_pop_one.push(i * 2); 702 | stl_pop_two.push(i); 703 | ft_pop_one.push(i * 2); 704 | ft_pop_two.push(i); 705 | } 706 | 707 | fs.open("./tester/stacks_output/operator_sup_true", std::fstream::in | std::fstream::out | std::fstream::trunc); 708 | printStackAttributes(fs, stl_pop_one, ft_pop_one); 709 | printStackAttributes(fs, stl_pop_two, ft_pop_two); 710 | 711 | std::cout << ((printBoolResult(fs, (stl_pop_one > stl_pop_two), (ft_pop_one > ft_pop_two)) == true) ? "[OK]" : "[NOP]"); 712 | 713 | fs << "\nCode executed:\n"; 714 | fs << "¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\n"; 715 | fs << "ft::stack ft_pop;\n"; 716 | fs << "for (int i = 0; i < 42; i++)\n"; 717 | fs << "{\n"; 718 | fs << " ft_pop_one.push(i * 2);\n"; 719 | fs << " ft_pop_two.push(i);\n"; 720 | fs << "}\n"; 721 | fs << "\nCompared with:\n"; 722 | fs << "¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\n"; 723 | fs << "std::stack stl_pop;\n"; 724 | fs << "for (int i = 0; i < 42; i++)\n"; 725 | fs << "{\n"; 726 | fs << " stl_pop_one.push(i * 2);\n"; 727 | fs << " stl_pop_two.push(i);\n"; 728 | fs << "}\n"; 729 | fs.close(); 730 | } 731 | 732 | /* RL > false */ 733 | { 734 | std::stack stl_pop_one; 735 | std::stack stl_pop_two; 736 | ft::stack ft_pop_one; 737 | ft::stack ft_pop_two; 738 | 739 | for (int i = 0; i < 42; i++) 740 | { 741 | stl_pop_one.push(i); 742 | stl_pop_two.push(i); 743 | ft_pop_one.push(i); 744 | ft_pop_two.push(i); 745 | } 746 | 747 | fs.open("./tester/stacks_output/operator_sup_false", std::fstream::in | std::fstream::out | std::fstream::trunc); 748 | printStackAttributes(fs, stl_pop_one, ft_pop_one); 749 | printStackAttributes(fs, stl_pop_two, ft_pop_two); 750 | 751 | std::cout << ((printBoolResult(fs, (stl_pop_one > stl_pop_two), (ft_pop_one > ft_pop_two)) == true) ? "[OK]" : "[NOP]"); 752 | 753 | fs << "\nCode executed:\n"; 754 | fs << "¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\n"; 755 | fs << "ft::stack ft_pop;\n"; 756 | fs << "for (int i = 0; i < 42; i++)\n"; 757 | fs << "{\n"; 758 | fs << " ft_pop_one.push(i);\n"; 759 | fs << " ft_pop_two.push(i);\n"; 760 | fs << "}\n"; 761 | fs << "\nCompared with:\n"; 762 | fs << "¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\n"; 763 | fs << "std::stack stl_pop;\n"; 764 | fs << "for (int i = 0; i < 42; i++)\n"; 765 | fs << "{\n"; 766 | fs << " stl_pop_one.push(i);\n"; 767 | fs << " stl_pop_two.push(i);\n"; 768 | fs << "}\n"; 769 | fs.close(); 770 | } 771 | 772 | /* RL >= true */ 773 | { 774 | std::stack stl_pop_one; 775 | std::stack stl_pop_two; 776 | ft::stack ft_pop_one; 777 | ft::stack ft_pop_two; 778 | 779 | for (int i = 0; i < 42; i++) 780 | { 781 | stl_pop_one.push(i); 782 | stl_pop_two.push(i); 783 | ft_pop_one.push(i); 784 | ft_pop_two.push(i); 785 | } 786 | 787 | fs.open("./tester/stacks_output/operator_sup_equal_true", std::fstream::in | std::fstream::out | std::fstream::trunc); 788 | printStackAttributes(fs, stl_pop_one, ft_pop_one); 789 | printStackAttributes(fs, stl_pop_two, ft_pop_two); 790 | 791 | std::cout << ((printBoolResult(fs, (stl_pop_one >= stl_pop_two), (ft_pop_one >= ft_pop_two)) == true) ? "[OK]" : "[NOP]"); 792 | 793 | fs << "\nCode executed:\n"; 794 | fs << "¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\n"; 795 | fs << "ft::stack ft_pop;\n"; 796 | fs << "for (int i = 0; i < 42; i++)\n"; 797 | fs << "{\n"; 798 | fs << " ft_pop_one.push(i);\n"; 799 | fs << " ft_pop_two.push(i);\n"; 800 | fs << "}\n"; 801 | fs << "\nCompared with:\n"; 802 | fs << "¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\n"; 803 | fs << "std::stack stl_pop;\n"; 804 | fs << "for (int i = 0; i < 42; i++)\n"; 805 | fs << "{\n"; 806 | fs << " stl_pop_one.push(i);\n"; 807 | fs << " stl_pop_two.push(i);\n"; 808 | fs << "}\n"; 809 | fs.close(); 810 | } 811 | 812 | /* RL >= false */ 813 | { 814 | std::stack stl_pop_one; 815 | std::stack stl_pop_two; 816 | ft::stack ft_pop_one; 817 | ft::stack ft_pop_two; 818 | 819 | for (int i = 0; i < 42; i++) 820 | { 821 | stl_pop_one.push(i); 822 | ft_pop_one.push(i); 823 | if (i == 30) 824 | { 825 | stl_pop_two.push(i * 2); 826 | ft_pop_two.push(i * 2); 827 | } 828 | else 829 | { 830 | stl_pop_two.push(i); 831 | ft_pop_two.push(i); 832 | } 833 | } 834 | 835 | fs.open("./tester/stacks_output/operator_sup_equal_false", std::fstream::in | std::fstream::out | std::fstream::trunc); 836 | printStackAttributes(fs, stl_pop_one, ft_pop_one); 837 | printStackAttributes(fs, stl_pop_two, ft_pop_two); 838 | 839 | std::cout << ((printBoolResult(fs, (stl_pop_one >= stl_pop_two), (ft_pop_one >= ft_pop_two)) == true) ? "[OK]" : "[NOP]"); 840 | 841 | fs << "\nCode executed:\n"; 842 | fs << "¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\n"; 843 | fs << "ft::stack ft_pop;\n"; 844 | fs << "for (int i = 0; i < 42; i++)\n"; 845 | fs << "{\n"; 846 | fs << " ft_pop_one.push(i);\n"; 847 | fs << " if (i == 30)\n"; 848 | fs << " ft_pop_two.push(i * 2);\n"; 849 | fs << " else\n"; 850 | fs << " ft_pop_two.push(i);\n"; 851 | fs << "}\n"; 852 | fs << "\nCompared with:\n"; 853 | fs << "¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\n"; 854 | fs << "std::stack stl_pop;\n"; 855 | fs << "for (int i = 0; i < 42; i++)\n"; 856 | fs << "{\n"; 857 | fs << " stl_pop_one.push(i);\n"; 858 | fs << " if (i == 30)\n"; 859 | fs << " stl_pop_two.push(i * 2);\n"; 860 | fs << " else\n"; 861 | fs << " stl_pop_two.push(i);\n"; 862 | fs << "}\n"; 863 | fs.close(); 864 | } 865 | 866 | std::cout << std::endl; 867 | } -------------------------------------------------------------------------------- /tester/tester_queue.cpp: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* tester_queue.cpp :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: rchallie +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2020/12/01 00:37:19 by rchallie #+# #+# */ 9 | /* Updated: 2020/12/03 23:44:26 by rchallie ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "tester.hpp" 14 | #include "../containers/queue.hpp" 15 | #include 16 | 17 | template 18 | std::string equalContent( 19 | std::queue stl_queue, 20 | ft::queue ft_queue 21 | ) 22 | { 23 | while (42) 24 | { 25 | if (stl_queue.size() == 0 || ft_queue.size() == 0) 26 | break; 27 | if (ft_queue.front() != stl_queue.front()) 28 | return ("✘"); 29 | ft_queue.pop(); 30 | stl_queue.pop(); 31 | } 32 | return ("✔"); 33 | } 34 | 35 | 36 | template 37 | bool printQueueAttributes( 38 | std::fstream& fs, 39 | std::queue stl_queue, 40 | ft::queue ft_queue 41 | ) 42 | { 43 | /* STL Values */ 44 | std::string stl_empty = ((stl_queue.empty() == 1) ? "true" : "false"); 45 | size_t stl_size = stl_queue.size(); 46 | 47 | /* FT Values */ 48 | std::string ft_empty = ((ft_queue.empty() == 1) ? "true" : "false"); 49 | size_t ft_size = ft_queue.size(); 50 | 51 | /* FT Result compare values */ 52 | bool empty = equalbool(ft_empty, stl_empty); 53 | bool size = equalbool(ft_size, stl_size); 54 | std::string content = equalContent(stl_queue, ft_queue); 55 | 56 | fs << "\n══════════════════════════════════════════════════════════════\n"; 57 | fs << "queues attributes : \n"; 58 | fs << "STL : \n"; 59 | fs << "Empty : " << stl_empty << std::endl; 60 | fs << "Size : " << stl_size << std::endl; 61 | fs << "Content : ["; 62 | 63 | while (42) 64 | { 65 | if (stl_queue.size() == 0) 66 | break; 67 | fs << stl_queue.front(); 68 | stl_queue.pop(); 69 | if (stl_queue.size() != 0) 70 | fs << ", "; 71 | } 72 | 73 | fs << "]\n"; 74 | 75 | fs << std::endl; 76 | 77 | fs << "FT : \n"; 78 | fs << "Empty [" << equal(ft_empty, stl_empty) << "]: " << ft_empty << std::endl; 79 | fs << "Size [" << equal(ft_size, stl_size) << "]: " << ft_size << std::endl; 80 | 81 | fs << "Content [" << content << "]: ["; 82 | 83 | while (42) 84 | { 85 | if (ft_queue.size() == 0) 86 | break; 87 | fs << ft_queue.front(); 88 | ft_queue.pop(); 89 | if (ft_queue.size() != 0) 90 | fs << ", "; 91 | } 92 | fs << "]\n"; 93 | 94 | fs << "══════════════════════════════════════════════════════════════\n"; 95 | 96 | /* Error case */ 97 | if (empty == false) 98 | return (false); 99 | else if (size == false) 100 | return (false); 101 | else if (content == "✘") 102 | return (false); 103 | return (true); 104 | } 105 | 106 | void test_queue() 107 | { 108 | std::cout << UNDERLINE << "QUEUE :\n" << NORMAL ; 109 | 110 | mkdir("./tester/queues_output", 0777); 111 | 112 | std::fstream fs; 113 | 114 | /* Member functions */ 115 | std::cout << "Member functions : "; 116 | 117 | /* Default constructor */ 118 | { 119 | std::queue stl_queue; 120 | ft::queue ft_queue; 121 | 122 | fs.open("./tester/queues_output/constructor_default", std::fstream::in | std::fstream::out | std::fstream::trunc); 123 | std::cout << ((printQueueAttributes(fs, stl_queue, ft_queue) == true) ? "[OK]" : "[NOP]"); 124 | 125 | fs << "\nCode executed:\n"; 126 | fs << "¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\n"; 127 | fs << "ft::queue ft_queue;\n"; 128 | fs << "\nCompared with:\n"; 129 | fs << "¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\n"; 130 | fs << "std::queue stl_queue;\n"; 131 | fs.close(); 132 | } 133 | 134 | /* Empty true */ 135 | { 136 | std::queue stl_queue; 137 | ft::queue ft_queue; 138 | 139 | fs.open("./tester/queues_output/empty_true", std::fstream::in | std::fstream::out | std::fstream::trunc); 140 | std::cout << ((printQueueAttributes(fs, stl_queue, ft_queue) == true) ? "[OK]" : "[NOP]"); 141 | 142 | fs << "\nCode executed:\n"; 143 | fs << "¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\n"; 144 | fs << "ft::queue ft_queue;\n"; 145 | fs << "\nCompared with:\n"; 146 | fs << "¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\n"; 147 | fs << "std::queue stl_queue;\n"; 148 | fs.close(); 149 | } 150 | 151 | /* Empty false */ 152 | { 153 | std::queue stl_queue; 154 | ft::queue ft_queue; 155 | 156 | stl_queue.push(42); 157 | ft_queue.push(42); 158 | 159 | fs.open("./tester/queues_output/empty_false", std::fstream::in | std::fstream::out | std::fstream::trunc); 160 | std::cout << ((printQueueAttributes(fs, stl_queue, ft_queue) == true) ? "[OK]" : "[NOP]"); 161 | 162 | fs << "\nCode executed:\n"; 163 | fs << "¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\n"; 164 | fs << "ft::queue ft_queue;\n"; 165 | fs << "ft_queue.push(42);\n"; 166 | fs << "\nCompared with:\n"; 167 | fs << "¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\n"; 168 | fs << "std::queue stl_queue;\n"; 169 | fs << "stl_queue.push(42);\n"; 170 | fs.close(); 171 | } 172 | 173 | /* Size */ 174 | { 175 | std::queue stl_queue; 176 | ft::queue ft_queue; 177 | 178 | for (int i = 0; i < 42; i++) 179 | { 180 | stl_queue.push(42); 181 | ft_queue.push(42); 182 | } 183 | 184 | fs.open("./tester/queues_output/size", std::fstream::in | std::fstream::out | std::fstream::trunc); 185 | std::cout << ((printQueueAttributes(fs, stl_queue, ft_queue) == true) ? "[OK]" : "[NOP]"); 186 | 187 | fs << "\nCode executed:\n"; 188 | fs << "¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\n"; 189 | fs << "ft::queue ft_queue;\n"; 190 | fs << "ft_queue.push(42);\n"; 191 | fs << "\nCompared with:\n"; 192 | fs << "¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\n"; 193 | fs << "std::queue stl_queue;\n"; 194 | fs << "stl_queue.push(42);\n"; 195 | fs.close(); 196 | } 197 | 198 | /* Front */ 199 | { 200 | std::queue stl_queue; 201 | ft::queue ft_queue; 202 | 203 | for (int i = 0; i < 42; i++) 204 | { 205 | stl_queue.push(i); 206 | ft_queue.push(i); 207 | } 208 | 209 | fs.open("./tester/queues_output/front", std::fstream::in | std::fstream::out | std::fstream::trunc); 210 | printQueueAttributes(fs, stl_queue, ft_queue); 211 | 212 | std::cout << ((printSingleValue(fs, stl_queue.front(), ft_queue.front()) == true) ? "[OK]" : "[NOP]"); 213 | 214 | stl_queue.pop(); 215 | ft_queue.pop(); 216 | 217 | std::cout << ((printSingleValue(fs, stl_queue.front(), ft_queue.front()) == true) ? "[OK]" : "[NOP]"); 218 | 219 | fs << "\nCode executed:\n"; 220 | fs << "¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\n"; 221 | fs << "ft::queue ft_queue;\n"; 222 | fs << "for (int i = 0; i < 42; i++)\n"; 223 | fs << " ft_queue.push(i);\n"; 224 | fs << "Output...\n"; 225 | fs << "ft_queue.pop();\n"; 226 | fs << "\nCompared with:\n"; 227 | fs << "¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\n"; 228 | fs << "std::queue stl_queue;\n"; 229 | fs << "for (int i = 0; i < 42; i++)\n"; 230 | fs << " stl_queue.push(i);\n"; 231 | fs << "Output...\n"; 232 | fs << "stl_queue.pop();\n"; 233 | fs.close(); 234 | } 235 | 236 | /* Back */ 237 | { 238 | std::queue stl_queue; 239 | ft::queue ft_queue; 240 | 241 | for (int i = 0; i < 42; i++) 242 | { 243 | stl_queue.push(i); 244 | ft_queue.push(i); 245 | } 246 | 247 | fs.open("./tester/queues_output/back", std::fstream::in | std::fstream::out | std::fstream::trunc); 248 | printQueueAttributes(fs, stl_queue, ft_queue); 249 | 250 | std::cout << ((printSingleValue(fs, stl_queue.back(), ft_queue.back()) == true) ? "[OK]" : "[NOP]"); 251 | 252 | fs << "\nCode executed:\n"; 253 | fs << "¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\n"; 254 | fs << "ft::queue ft_queue;\n"; 255 | fs << "for (int i = 0; i < 42; i++)\n"; 256 | fs << " ft_queue.push(i);\n"; 257 | fs << "\nCompared with:\n"; 258 | fs << "¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\n"; 259 | fs << "std::queue stl_queue;\n"; 260 | fs << "for (int i = 0; i < 42; i++)\n"; 261 | fs << " stl_queue.push(i);\n"; 262 | fs.close(); 263 | } 264 | 265 | /* Push */ 266 | { 267 | std::queue stl_queue; 268 | ft::queue ft_queue; 269 | 270 | stl_queue.push(42); 271 | ft_queue.push(42); 272 | 273 | fs.open("./tester/queues_output/push", std::fstream::in | std::fstream::out | std::fstream::trunc); 274 | std::cout << ((printQueueAttributes(fs, stl_queue, ft_queue) == true) ? "[OK]" : "[NOP]"); 275 | 276 | stl_queue.push(19); 277 | ft_queue.push(19); 278 | 279 | std::cout << ((printQueueAttributes(fs, stl_queue, ft_queue) == true) ? "[OK]" : "[NOP]"); 280 | 281 | fs << "\nCode executed:\n"; 282 | fs << "¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\n"; 283 | fs << "ft::queue ft_queue;\n"; 284 | fs << "ft_queue.push(42);\n"; 285 | fs << "Output...\n"; 286 | fs << "ft_queue.push(19);\n"; 287 | fs << "\nCompared with:\n"; 288 | fs << "¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\n"; 289 | fs << "std::queue stl_queue;\n"; 290 | fs << "stl_queue.push(42);\n"; 291 | fs << "Output...\n"; 292 | fs << "ft_queue.push(19);\n"; 293 | fs.close(); 294 | } 295 | 296 | /* Pop */ 297 | { 298 | std::queue stl_queue; 299 | ft::queue ft_queue; 300 | 301 | stl_queue.push(42); 302 | ft_queue.push(42); 303 | 304 | fs.open("./tester/queues_output/push", std::fstream::in | std::fstream::out | std::fstream::trunc); 305 | std::cout << ((printQueueAttributes(fs, stl_queue, ft_queue) == true) ? "[OK]" : "[NOP]"); 306 | 307 | stl_queue.pop(); 308 | ft_queue.pop(); 309 | 310 | std::cout << ((printQueueAttributes(fs, stl_queue, ft_queue) == true) ? "[OK]" : "[NOP]"); 311 | 312 | fs << "\nCode executed:\n"; 313 | fs << "¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\n"; 314 | fs << "ft::queue ft_queue;\n"; 315 | fs << "ft_queue.push(42);\n"; 316 | fs << "Output...\n"; 317 | fs << "ft_queue.pop();\n"; 318 | fs << "\nCompared with:\n"; 319 | fs << "¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\n"; 320 | fs << "std::queue stl_queue;\n"; 321 | fs << "stl_queue.push(42);\n"; 322 | fs << "Output...\n"; 323 | fs << "ft_queue.pop();\n"; 324 | fs.close(); 325 | } 326 | 327 | std::cout << std::endl; 328 | std::cout << "Non-member function overloads : "; 329 | 330 | /* RL = relational operator */ 331 | 332 | /* RL == true */ 333 | { 334 | std::queue stl_pop_one; 335 | std::queue stl_pop_two; 336 | ft::queue ft_pop_one; 337 | ft::queue ft_pop_two; 338 | 339 | for (int i = 0; i < 42; i++) 340 | { 341 | stl_pop_one.push(i); 342 | stl_pop_two.push(i); 343 | ft_pop_one.push(i); 344 | ft_pop_two.push(i); 345 | } 346 | 347 | fs.open("./tester/queues_output/operator_equal_true", std::fstream::in | std::fstream::out | std::fstream::trunc); 348 | printQueueAttributes(fs, stl_pop_one, ft_pop_one); 349 | printQueueAttributes(fs, stl_pop_two, ft_pop_two); 350 | 351 | std::cout << ((printBoolResult(fs, (stl_pop_one == stl_pop_two), (ft_pop_one == ft_pop_two)) == true) ? "[OK]" : "[NOP]"); 352 | 353 | fs << "\nCode executed:\n"; 354 | fs << "¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\n"; 355 | fs << "ft::queue ft_pop;\n"; 356 | fs << "for (int i = 0; i < 42; i++)\n"; 357 | fs << "{\n"; 358 | fs << " ft_pop_one.push(i);\n"; 359 | fs << " ft_pop_two.push(i);\n"; 360 | fs << "}\n"; 361 | fs << "\nCompared with:\n"; 362 | fs << "¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\n"; 363 | fs << "std::queue stl_pop;\n"; 364 | fs << "for (int i = 0; i < 42; i++)\n"; 365 | fs << "{\n"; 366 | fs << " stl_pop_one.push(i);\n"; 367 | fs << " stl_pop_two.push(i);\n"; 368 | fs << "}\n"; 369 | fs.close(); 370 | } 371 | 372 | /* RL == false */ 373 | { 374 | std::queue stl_pop_one; 375 | std::queue stl_pop_two; 376 | ft::queue ft_pop_one; 377 | ft::queue ft_pop_two; 378 | 379 | for (int i = 0; i < 42; i++) 380 | { 381 | stl_pop_one.push(i); 382 | stl_pop_two.push(i * 2); 383 | ft_pop_one.push(i); 384 | ft_pop_two.push(i * 2); 385 | } 386 | 387 | fs.open("./tester/queues_output/operator_equal_false", std::fstream::in | std::fstream::out | std::fstream::trunc); 388 | printQueueAttributes(fs, stl_pop_one, ft_pop_one); 389 | printQueueAttributes(fs, stl_pop_two, ft_pop_two); 390 | 391 | std::cout << ((printBoolResult(fs, (stl_pop_one == stl_pop_two), (ft_pop_one == ft_pop_two)) == true) ? "[OK]" : "[NOP]"); 392 | 393 | fs << "\nCode executed:\n"; 394 | fs << "¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\n"; 395 | fs << "ft::queue ft_pop;\n"; 396 | fs << "for (int i = 0; i < 42; i++)\n"; 397 | fs << "{\n"; 398 | fs << " ft_pop_one.push(i);\n"; 399 | fs << " ft_pop_two.push(i * 2);\n"; 400 | fs << "}\n"; 401 | fs << "\nCompared with:\n"; 402 | fs << "¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\n"; 403 | fs << "std::queue stl_pop;\n"; 404 | fs << "for (int i = 0; i < 42; i++)\n"; 405 | fs << "{\n"; 406 | fs << " stl_pop_one.push(i);\n"; 407 | fs << " stl_pop_two.push(i * 2);\n"; 408 | fs << "}\n"; 409 | fs.close(); 410 | } 411 | 412 | /* RL != true */ 413 | { 414 | std::queue stl_pop_one; 415 | std::queue stl_pop_two; 416 | ft::queue ft_pop_one; 417 | ft::queue ft_pop_two; 418 | 419 | for (int i = 0; i < 42; i++) 420 | { 421 | stl_pop_one.push(i); 422 | stl_pop_two.push(i * 2); 423 | ft_pop_one.push(i); 424 | ft_pop_two.push(i * 2); 425 | } 426 | 427 | fs.open("./tester/queues_output/operator_net_equal_true", std::fstream::in | std::fstream::out | std::fstream::trunc); 428 | printQueueAttributes(fs, stl_pop_one, ft_pop_one); 429 | printQueueAttributes(fs, stl_pop_two, ft_pop_two); 430 | 431 | std::cout << ((printBoolResult(fs, (stl_pop_one != stl_pop_two), (ft_pop_one != ft_pop_two)) == true) ? "[OK]" : "[NOP]"); 432 | 433 | fs << "\nCode executed:\n"; 434 | fs << "¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\n"; 435 | fs << "ft::queue ft_pop;\n"; 436 | fs << "for (int i = 0; i < 42; i++)\n"; 437 | fs << "{\n"; 438 | fs << " ft_pop_one.push(i);\n"; 439 | fs << " ft_pop_two.push(i * 2);\n"; 440 | fs << "}\n"; 441 | fs << "\nCompared with:\n"; 442 | fs << "¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\n"; 443 | fs << "std::queue stl_pop;\n"; 444 | fs << "for (int i = 0; i < 42; i++)\n"; 445 | fs << "{\n"; 446 | fs << " stl_pop_one.push(i);\n"; 447 | fs << " stl_pop_two.push(i * 2);\n"; 448 | fs << "}\n"; 449 | fs.close(); 450 | } 451 | 452 | /* RL != false */ 453 | { 454 | std::queue stl_pop_one; 455 | std::queue stl_pop_two; 456 | ft::queue ft_pop_one; 457 | ft::queue ft_pop_two; 458 | 459 | for (int i = 0; i < 42; i++) 460 | { 461 | stl_pop_one.push(i); 462 | stl_pop_two.push(i); 463 | ft_pop_one.push(i); 464 | ft_pop_two.push(i); 465 | } 466 | 467 | fs.open("./tester/queues_output/operator_not_equal_false", std::fstream::in | std::fstream::out | std::fstream::trunc); 468 | printQueueAttributes(fs, stl_pop_one, ft_pop_one); 469 | printQueueAttributes(fs, stl_pop_two, ft_pop_two); 470 | 471 | std::cout << ((printBoolResult(fs, (stl_pop_one != stl_pop_two), (ft_pop_one != ft_pop_two)) == true) ? "[OK]" : "[NOP]"); 472 | 473 | fs << "\nCode executed:\n"; 474 | fs << "¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\n"; 475 | fs << "ft::queue ft_pop;\n"; 476 | fs << "for (int i = 0; i < 42; i++)\n"; 477 | fs << "{\n"; 478 | fs << " ft_pop_one.push(i);\n"; 479 | fs << " ft_pop_two.push(i);\n"; 480 | fs << "}\n"; 481 | fs << "\nCompared with:\n"; 482 | fs << "¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\n"; 483 | fs << "std::queue stl_pop;\n"; 484 | fs << "for (int i = 0; i < 42; i++)\n"; 485 | fs << "{\n"; 486 | fs << " stl_pop_one.push(i);\n"; 487 | fs << " stl_pop_two.push(i);\n"; 488 | fs << "}\n"; 489 | fs.close(); 490 | } 491 | 492 | /* RL < true */ 493 | { 494 | std::queue stl_pop_one; 495 | std::queue stl_pop_two; 496 | ft::queue ft_pop_one; 497 | ft::queue ft_pop_two; 498 | 499 | for (int i = 0; i < 42; i++) 500 | { 501 | stl_pop_one.push(i); 502 | ft_pop_one.push(i); 503 | if (i == 30) 504 | { 505 | stl_pop_two.push(i * 2); 506 | ft_pop_two.push(i * 2); 507 | } 508 | else 509 | { 510 | stl_pop_two.push(i); 511 | ft_pop_two.push(i); 512 | } 513 | } 514 | 515 | fs.open("./tester/queues_output/operator_inf_true", std::fstream::in | std::fstream::out | std::fstream::trunc); 516 | printQueueAttributes(fs, stl_pop_one, ft_pop_one); 517 | printQueueAttributes(fs, stl_pop_two, ft_pop_two); 518 | 519 | std::cout << ((printBoolResult(fs, (stl_pop_one < stl_pop_two), (ft_pop_one < ft_pop_two)) == true) ? "[OK]" : "[NOP]"); 520 | 521 | fs << "\nCode executed:\n"; 522 | fs << "¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\n"; 523 | fs << "ft::queue ft_pop;\n"; 524 | fs << "for (int i = 0; i < 42; i++)\n"; 525 | fs << "{\n"; 526 | fs << " ft_pop_one.push(i);\n"; 527 | fs << " if (i == 30)\n"; 528 | fs << " ft_pop_two.push(i * 2);\n"; 529 | fs << " else\n"; 530 | fs << " ft_pop_two.push(i);\n"; 531 | fs << "}\n"; 532 | fs << "\nCompared with:\n"; 533 | fs << "¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\n"; 534 | fs << "std::queue stl_pop;\n"; 535 | fs << "for (int i = 0; i < 42; i++)\n"; 536 | fs << "{\n"; 537 | fs << " stl_pop_one.push(i);\n"; 538 | fs << " if (i == 30)\n"; 539 | fs << " stl_pop_two.push(i * 2);\n"; 540 | fs << " else\n"; 541 | fs << " stl_pop_two.push(i);\n"; 542 | fs << "}\n"; 543 | fs.close(); 544 | } 545 | 546 | /* RL < false */ 547 | { 548 | std::queue stl_pop_one; 549 | std::queue stl_pop_two; 550 | ft::queue ft_pop_one; 551 | ft::queue ft_pop_two; 552 | 553 | for (int i = 0; i < 42; i++) 554 | { 555 | stl_pop_two.push(i); 556 | ft_pop_two.push(i); 557 | if (i == 30) 558 | { 559 | stl_pop_one.push(i * 2); 560 | ft_pop_one.push(i * 2); 561 | } 562 | else 563 | { 564 | stl_pop_one.push(i); 565 | ft_pop_one.push(i); 566 | } 567 | } 568 | 569 | fs.open("./tester/queues_output/operator_inf_false", std::fstream::in | std::fstream::out | std::fstream::trunc); 570 | printQueueAttributes(fs, stl_pop_one, ft_pop_one); 571 | printQueueAttributes(fs, stl_pop_two, ft_pop_two); 572 | 573 | std::cout << ((printBoolResult(fs, (stl_pop_one < stl_pop_two), (ft_pop_one < ft_pop_two)) == true) ? "[OK]" : "[NOP]"); 574 | 575 | fs << "\nCode executed:\n"; 576 | fs << "¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\n"; 577 | fs << "ft::queue ft_pop;\n"; 578 | fs << "for (int i = 0; i < 42; i++)\n"; 579 | fs << "{\n"; 580 | fs << " ft_pop_two.push(i);\n"; 581 | fs << " if (i == 30)\n"; 582 | fs << " ft_pop_one.push(i * 2);\n"; 583 | fs << " else\n"; 584 | fs << " ft_pop_one.push(i);\n"; 585 | fs << "}\n"; 586 | fs << "\nCompared with:\n"; 587 | fs << "¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\n"; 588 | fs << "std::queue stl_pop;\n"; 589 | fs << "for (int i = 0; i < 42; i++)\n"; 590 | fs << "{\n"; 591 | fs << " stl_pop_two.push(i);\n"; 592 | fs << " if (i == 30)\n"; 593 | fs << " stl_pop_two.push(i * 2);\n"; 594 | fs << " else\n"; 595 | fs << " stl_pop_one.push(i);\n"; 596 | fs << "}\n"; 597 | fs.close(); 598 | } 599 | 600 | /* RL <= true */ 601 | { 602 | std::queue stl_pop_one; 603 | std::queue stl_pop_two; 604 | ft::queue ft_pop_one; 605 | ft::queue ft_pop_two; 606 | 607 | for (int i = 0; i < 42; i++) 608 | { 609 | stl_pop_one.push(i); 610 | stl_pop_two.push(i * 2); 611 | ft_pop_one.push(i); 612 | ft_pop_two.push(i * 2); 613 | } 614 | 615 | fs.open("./tester/queues_output/operator_inf_equal_true", std::fstream::in | std::fstream::out | std::fstream::trunc); 616 | printQueueAttributes(fs, stl_pop_one, ft_pop_one); 617 | printQueueAttributes(fs, stl_pop_two, ft_pop_two); 618 | 619 | std::cout << ((printBoolResult(fs, (stl_pop_one <= stl_pop_two), (ft_pop_one <= ft_pop_two)) == true) ? "[OK]" : "[NOP]"); 620 | 621 | fs << "\nCode executed:\n"; 622 | fs << "¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\n"; 623 | fs << "ft::queue ft_pop;\n"; 624 | fs << "for (int i = 0; i < 42; i++)\n"; 625 | fs << "{\n"; 626 | fs << " ft_pop_one.push(i);\n"; 627 | fs << " ft_pop_two.push(i * 2);\n"; 628 | fs << "}\n"; 629 | fs << "\nCompared with:\n"; 630 | fs << "¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\n"; 631 | fs << "std::queue stl_pop;\n"; 632 | fs << "for (int i = 0; i < 42; i++)\n"; 633 | fs << "{\n"; 634 | fs << " stl_pop_one.push(i);\n"; 635 | fs << " stl_pop_two.push(i * 2);\n"; 636 | fs << "}\n"; 637 | fs.close(); 638 | } 639 | 640 | /* RL <= true equal */ 641 | { 642 | std::queue stl_pop_one; 643 | std::queue stl_pop_two; 644 | ft::queue ft_pop_one; 645 | ft::queue ft_pop_two; 646 | 647 | for (int i = 0; i < 42; i++) 648 | { 649 | stl_pop_one.push(i); 650 | stl_pop_two.push(i); 651 | ft_pop_one.push(i); 652 | ft_pop_two.push(i); 653 | } 654 | 655 | fs.open("./tester/queues_output/operator_inf_equal_true", std::fstream::in | std::fstream::out | std::fstream::trunc); 656 | printQueueAttributes(fs, stl_pop_one, ft_pop_one); 657 | printQueueAttributes(fs, stl_pop_two, ft_pop_two); 658 | 659 | std::cout << ((printBoolResult(fs, (stl_pop_one <= stl_pop_two), (ft_pop_one <= ft_pop_two)) == true) ? "[OK]" : "[NOP]"); 660 | 661 | fs << "\nCode executed:\n"; 662 | fs << "¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\n"; 663 | fs << "ft::queue ft_pop;\n"; 664 | fs << "for (int i = 0; i < 42; i++)\n"; 665 | fs << "{\n"; 666 | fs << " ft_pop_one.push(i);\n"; 667 | fs << " ft_pop_two.push(i);\n"; 668 | fs << "}\n"; 669 | fs << "\nCompared with:\n"; 670 | fs << "¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\n"; 671 | fs << "std::queue stl_pop;\n"; 672 | fs << "for (int i = 0; i < 42; i++)\n"; 673 | fs << "{\n"; 674 | fs << " stl_pop_one.push(i);\n"; 675 | fs << " stl_pop_two.push(i);\n"; 676 | fs << "}\n"; 677 | fs.close(); 678 | } 679 | 680 | /* RL <= false */ 681 | { 682 | std::queue stl_pop_one; 683 | std::queue stl_pop_two; 684 | ft::queue ft_pop_one; 685 | ft::queue ft_pop_two; 686 | 687 | for (int i = 0; i < 42; i++) 688 | { 689 | stl_pop_one.push(i * 2); 690 | stl_pop_two.push(i); 691 | ft_pop_one.push(i * 2); 692 | ft_pop_two.push(i); 693 | } 694 | 695 | fs.open("./tester/queues_output/operator_inf_equal_false", std::fstream::in | std::fstream::out | std::fstream::trunc); 696 | printQueueAttributes(fs, stl_pop_one, ft_pop_one); 697 | printQueueAttributes(fs, stl_pop_two, ft_pop_two); 698 | 699 | std::cout << ((printBoolResult(fs, (stl_pop_one <= stl_pop_two), (ft_pop_one <= ft_pop_two)) == true) ? "[OK]" : "[NOP]"); 700 | 701 | fs << "\nCode executed:\n"; 702 | fs << "¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\n"; 703 | fs << "ft::queue ft_pop;\n"; 704 | fs << "for (int i = 0; i < 42; i++)\n"; 705 | fs << "{\n"; 706 | fs << " ft_pop_one.push(i * 2);\n"; 707 | fs << " ft_pop_two.push(i);\n"; 708 | fs << "}\n"; 709 | fs << "\nCompared with:\n"; 710 | fs << "¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\n"; 711 | fs << "std::queue stl_pop;\n"; 712 | fs << "for (int i = 0; i < 42; i++)\n"; 713 | fs << "{\n"; 714 | fs << " stl_pop_one.push(i * 2);\n"; 715 | fs << " stl_pop_two.push(i);\n"; 716 | fs << "}\n"; 717 | fs.close(); 718 | } 719 | 720 | /* RL > true */ 721 | { 722 | std::queue stl_pop_one; 723 | std::queue stl_pop_two; 724 | ft::queue ft_pop_one; 725 | ft::queue ft_pop_two; 726 | 727 | for (int i = 0; i < 42; i++) 728 | { 729 | stl_pop_one.push(i * 2); 730 | stl_pop_two.push(i); 731 | ft_pop_one.push(i * 2); 732 | ft_pop_two.push(i); 733 | } 734 | 735 | fs.open("./tester/queues_output/operator_sup_true", std::fstream::in | std::fstream::out | std::fstream::trunc); 736 | printQueueAttributes(fs, stl_pop_one, ft_pop_one); 737 | printQueueAttributes(fs, stl_pop_two, ft_pop_two); 738 | 739 | std::cout << ((printBoolResult(fs, (stl_pop_one > stl_pop_two), (ft_pop_one > ft_pop_two)) == true) ? "[OK]" : "[NOP]"); 740 | 741 | fs << "\nCode executed:\n"; 742 | fs << "¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\n"; 743 | fs << "ft::queue ft_pop;\n"; 744 | fs << "for (int i = 0; i < 42; i++)\n"; 745 | fs << "{\n"; 746 | fs << " ft_pop_one.push(i * 2);\n"; 747 | fs << " ft_pop_two.push(i);\n"; 748 | fs << "}\n"; 749 | fs << "\nCompared with:\n"; 750 | fs << "¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\n"; 751 | fs << "std::queue stl_pop;\n"; 752 | fs << "for (int i = 0; i < 42; i++)\n"; 753 | fs << "{\n"; 754 | fs << " stl_pop_one.push(i * 2);\n"; 755 | fs << " stl_pop_two.push(i);\n"; 756 | fs << "}\n"; 757 | fs.close(); 758 | } 759 | 760 | /* RL > false */ 761 | { 762 | std::queue stl_pop_one; 763 | std::queue stl_pop_two; 764 | ft::queue ft_pop_one; 765 | ft::queue ft_pop_two; 766 | 767 | for (int i = 0; i < 42; i++) 768 | { 769 | stl_pop_one.push(i); 770 | stl_pop_two.push(i); 771 | ft_pop_one.push(i); 772 | ft_pop_two.push(i); 773 | } 774 | 775 | fs.open("./tester/queues_output/operator_sup_false", std::fstream::in | std::fstream::out | std::fstream::trunc); 776 | printQueueAttributes(fs, stl_pop_one, ft_pop_one); 777 | printQueueAttributes(fs, stl_pop_two, ft_pop_two); 778 | 779 | std::cout << ((printBoolResult(fs, (stl_pop_one > stl_pop_two), (ft_pop_one > ft_pop_two)) == true) ? "[OK]" : "[NOP]"); 780 | 781 | fs << "\nCode executed:\n"; 782 | fs << "¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\n"; 783 | fs << "ft::queue ft_pop;\n"; 784 | fs << "for (int i = 0; i < 42; i++)\n"; 785 | fs << "{\n"; 786 | fs << " ft_pop_one.push(i);\n"; 787 | fs << " ft_pop_two.push(i);\n"; 788 | fs << "}\n"; 789 | fs << "\nCompared with:\n"; 790 | fs << "¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\n"; 791 | fs << "std::queue stl_pop;\n"; 792 | fs << "for (int i = 0; i < 42; i++)\n"; 793 | fs << "{\n"; 794 | fs << " stl_pop_one.push(i);\n"; 795 | fs << " stl_pop_two.push(i);\n"; 796 | fs << "}\n"; 797 | fs.close(); 798 | } 799 | 800 | /* RL >= true */ 801 | { 802 | std::queue stl_pop_one; 803 | std::queue stl_pop_two; 804 | ft::queue ft_pop_one; 805 | ft::queue ft_pop_two; 806 | 807 | for (int i = 0; i < 42; i++) 808 | { 809 | stl_pop_one.push(i); 810 | stl_pop_two.push(i); 811 | ft_pop_one.push(i); 812 | ft_pop_two.push(i); 813 | } 814 | 815 | fs.open("./tester/queues_output/operator_sup_equal_true", std::fstream::in | std::fstream::out | std::fstream::trunc); 816 | printQueueAttributes(fs, stl_pop_one, ft_pop_one); 817 | printQueueAttributes(fs, stl_pop_two, ft_pop_two); 818 | 819 | std::cout << ((printBoolResult(fs, (stl_pop_one >= stl_pop_two), (ft_pop_one >= ft_pop_two)) == true) ? "[OK]" : "[NOP]"); 820 | 821 | fs << "\nCode executed:\n"; 822 | fs << "¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\n"; 823 | fs << "ft::queue ft_pop;\n"; 824 | fs << "for (int i = 0; i < 42; i++)\n"; 825 | fs << "{\n"; 826 | fs << " ft_pop_one.push(i);\n"; 827 | fs << " ft_pop_two.push(i);\n"; 828 | fs << "}\n"; 829 | fs << "\nCompared with:\n"; 830 | fs << "¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\n"; 831 | fs << "std::queue stl_pop;\n"; 832 | fs << "for (int i = 0; i < 42; i++)\n"; 833 | fs << "{\n"; 834 | fs << " stl_pop_one.push(i);\n"; 835 | fs << " stl_pop_two.push(i);\n"; 836 | fs << "}\n"; 837 | fs.close(); 838 | } 839 | 840 | /* RL >= false */ 841 | { 842 | std::queue stl_pop_one; 843 | std::queue stl_pop_two; 844 | ft::queue ft_pop_one; 845 | ft::queue ft_pop_two; 846 | 847 | for (int i = 0; i < 42; i++) 848 | { 849 | stl_pop_one.push(i); 850 | ft_pop_one.push(i); 851 | if (i == 30) 852 | { 853 | stl_pop_two.push(i * 2); 854 | ft_pop_two.push(i * 2); 855 | } 856 | else 857 | { 858 | stl_pop_two.push(i); 859 | ft_pop_two.push(i); 860 | } 861 | } 862 | 863 | fs.open("./tester/queues_output/operator_sup_equal_false", std::fstream::in | std::fstream::out | std::fstream::trunc); 864 | printQueueAttributes(fs, stl_pop_one, ft_pop_one); 865 | printQueueAttributes(fs, stl_pop_two, ft_pop_two); 866 | 867 | std::cout << ((printBoolResult(fs, (stl_pop_one >= stl_pop_two), (ft_pop_one >= ft_pop_two)) == true) ? "[OK]" : "[NOP]"); 868 | 869 | fs << "\nCode executed:\n"; 870 | fs << "¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\n"; 871 | fs << "ft::queue ft_pop;\n"; 872 | fs << "for (int i = 0; i < 42; i++)\n"; 873 | fs << "{\n"; 874 | fs << " ft_pop_one.push(i);\n"; 875 | fs << " if (i == 30)\n"; 876 | fs << " ft_pop_two.push(i * 2);\n"; 877 | fs << " else\n"; 878 | fs << " ft_pop_two.push(i);\n"; 879 | fs << "}\n"; 880 | fs << "\nCompared with:\n"; 881 | fs << "¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\n"; 882 | fs << "std::queue stl_pop;\n"; 883 | fs << "for (int i = 0; i < 42; i++)\n"; 884 | fs << "{\n"; 885 | fs << " stl_pop_one.push(i);\n"; 886 | fs << " if (i == 30)\n"; 887 | fs << " stl_pop_two.push(i * 2);\n"; 888 | fs << " else\n"; 889 | fs << " stl_pop_two.push(i);\n"; 890 | fs << "}\n"; 891 | fs.close(); 892 | } 893 | 894 | std::cout << std::endl; 895 | } -------------------------------------------------------------------------------- /containers/vector.hpp: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* vector.hpp :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: rchallie +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2020/04/18 12:45:54 by excalibur #+# #+# */ 9 | /* Updated: 2020/12/10 21:42:20 by rchallie ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | /* 14 | ** Documentation : 15 | ** (fr) https://github.com/rchallie/ft_containers/blob/master/vector.txt 16 | ** http://www.cplusplus.com/reference/vector/vector/?kw=vector 17 | ** (fr) https://docs.microsoft.com/fr-fr/cpp/standard-library/vector-class?view=vs-2019 18 | */ 19 | 20 | #ifndef VECTOR_HPP 21 | # define VECTOR_HPP 22 | 23 | // LIBS ======================================================================== 24 | # include 25 | # include 26 | # include 27 | # include 28 | # include "./utils/utils.hpp" 29 | # include "./utils/random_access_iterator.hpp" 30 | 31 | // ============================================================================= 32 | 33 | // CLASS DEFINITIONS =========================================================== 34 | 35 | namespace ft 36 | { 37 | template < class T, class Alloc = std::allocator > 38 | class vector 39 | { 40 | public: 41 | 42 | /* 43 | ** The first template parameter (T) 44 | */ 45 | typedef T value_type; 46 | 47 | /* 48 | ** The second template parameter (Alloc) 49 | */ 50 | typedef Alloc allocator_type; 51 | 52 | /* 53 | ** allocator_type::reference 54 | ** A type provides a reference to an element stored in 55 | ** a vector. 56 | ** For the default allocator is a reference to value_type 57 | ** (value_type&) 58 | */ 59 | typedef typename allocator_type::reference reference; 60 | 61 | /* 62 | ** allocator_type::const_reference 63 | ** Type that give a reference to a const element stored. 64 | ** Usefull to read and perform const operator. 65 | ** A type const_reference can't be used to modify the value 66 | ** of an element. 67 | ** For the default allocator is a const reference to value_type 68 | ** (const value_type&) 69 | */ 70 | typedef typename allocator_type::const_reference const_reference; 71 | 72 | /* 73 | ** allocator_type::pointer 74 | ** Type that give a pointer to an element stored. 75 | ** A type pointer can be used to modify the value of 76 | ** an element. 77 | ** For the default allocator is a pointer to value_type 78 | ** (value_type*) 79 | */ 80 | typedef typename allocator_type::pointer pointer; 81 | 82 | /* 83 | ** allocator_type::const_pointer 84 | ** Type that give a const pointer to an element stored. 85 | ** Can't be used to modify the value of an element. 86 | ** An iterator is prefered to access to an element. 87 | ** For the default allocator is a const pointer to value_type 88 | ** (const value_type*) 89 | */ 90 | typedef typename allocator_type::const_pointer const_pointer; 91 | 92 | /* 93 | ** A random access iterator to value_type 94 | ** That can read or modify any element stored. 95 | ** Convertible to const_iterator; 96 | */ 97 | typedef ft::random_access_iterator iterator; 98 | 99 | /* 100 | ** A random access iterator to const value_type 101 | ** That can read element stored. 102 | */ 103 | typedef ft::random_access_iterator const_iterator; 104 | 105 | /* 106 | ** ft::reverse_iterator 107 | ** That can read or modify any element in a reversed vector. 108 | ** Used to iterate through the vector in reverse. 109 | */ 110 | typedef ft::reverse_iterator reverse_iterator; 111 | 112 | /* 113 | ** ft::reverse_iterator 114 | ** That can read any element in a reversed the vector. 115 | ** Can't be used to modify, used to iterate through the 116 | ** the vector in reverse. 117 | */ 118 | typedef ft::reverse_iterator const_reverse_iterator; 119 | 120 | /* 121 | ** A signed integral type: 122 | ** Usually the same as ptrdiff_t. 123 | ** Can represent the difference between iterators to the 124 | ** element actually stored. 125 | ** Can be described as te number of element between two pointers. 126 | ** (Pointer to an element contains its address). 127 | */ 128 | typedef typename ft::iterator_traits::difference_type difference_type; 129 | 130 | /* 131 | ** An unsigned integral type that can represent any 132 | ** non-negative value of difference_type 133 | ** Usually the same as size_t. 134 | */ 135 | typedef typename allocator_type::size_type size_type; 136 | 137 | // Constructors: 138 | 139 | /* 140 | ** @brief Default. 141 | ** Constructs an empty container, with no elements. 142 | ** 143 | ** @param Allocator object. 144 | ** The container keeps and uses an internal copy of this 145 | ** allocator. It's an alias to the second template parameter. 146 | ** If in template this second argument is not defined, 147 | ** std::allocator will be used. 148 | */ 149 | explicit vector (const allocator_type& alloc = allocator_type()) 150 | : 151 | _alloc(alloc), 152 | _start(u_nullptr), 153 | _end(u_nullptr), 154 | _end_capacity(u_nullptr) 155 | {} 156 | 157 | /* 158 | ** @brief Fill. 159 | ** Constructs a container with "n" elements. 160 | ** Each element is a copy of val. 161 | ** 162 | ** @param n The number of elements. 163 | ** @param val The element. 164 | ** @param allocator_type Allocator object. 165 | */ 166 | explicit vector (size_type n, const value_type& val = value_type(), 167 | const allocator_type& alloc = allocator_type()) 168 | : 169 | _alloc(alloc), 170 | _start(u_nullptr), 171 | _end(u_nullptr), 172 | _end_capacity(u_nullptr) 173 | { 174 | _start = _alloc.allocate( n ); 175 | _end_capacity = _start + n; 176 | _end = _start; 177 | while (n--) 178 | { 179 | _alloc.construct(_end, val); 180 | _end++; 181 | } 182 | } 183 | 184 | /* 185 | ** @brief Range. 186 | ** Constructs a container with as many elements as the 187 | ** range [first,last), with each element constructed from 188 | ** its corresponding element in that range, in the same order. 189 | ** (Adapted to counter the effect of : 190 | ** vector(static_cast(first), static_cast(last), a)) 191 | ** 192 | ** @param first An iterator is the first value in x. 193 | ** @param last An iterator is the last value in x. 194 | */ 195 | template 196 | vector (InputIterator first, InputIterator last, 197 | const allocator_type& alloc = allocator_type(), 198 | typename ft::enable_if::value, InputIterator>::type* = u_nullptr) 199 | : 200 | _alloc(alloc) 201 | { 202 | bool is_valid; 203 | if (!(is_valid = ft::is_ft_iterator_tagged::iterator_category >::value)) 204 | throw (ft::InvalidIteratorException::iterator_category >::type>()); 205 | 206 | difference_type n = ft::distance(first, last); 207 | _start = _alloc.allocate( n ); 208 | _end_capacity = _start + n; 209 | _end = _start; 210 | while (n--) 211 | { 212 | _alloc.construct(_end, *first++); 213 | _end++; 214 | } 215 | } 216 | 217 | /* 218 | ** @brief Copy. 219 | ** Construct a vector, initializing its contents 220 | ** with a copy of each element of "x" elements in 221 | ** the same order. Use a copy of "x" allocator. 222 | ** 223 | ** @param "x" the vector container to copy. 224 | */ 225 | vector (const vector& x) 226 | : 227 | _alloc(x._alloc), 228 | _start(u_nullptr), 229 | _end(u_nullptr), 230 | _end_capacity(u_nullptr) 231 | { 232 | this->insert(this->begin(), x.begin(), x.end()); 233 | } 234 | 235 | /* 236 | ** @brief Destroy the container object. 237 | ** Destroy all elements in the container and deallocate 238 | ** the container capacity. 239 | */ 240 | ~vector() 241 | { 242 | this->clear(); 243 | _alloc.deallocate(_start, this->capacity()); 244 | } 245 | 246 | /* 247 | ** @brief Assigns contents from "x" to the container. 248 | ** Replace content of this and according size. 249 | ** All elements before the call are destroyed. 250 | ** 251 | ** @param x the container which we inspire. 252 | ** @return *this. 253 | */ 254 | vector &operator=(const vector& x) 255 | { 256 | if (x == *this) 257 | return (*this); 258 | this->clear(); 259 | this->insert(this->end(), x.begin(), x.end()); 260 | return (*this); 261 | } 262 | 263 | // Iterators: 264 | 265 | /* 266 | ** @brief Return an iterator pointing on the first element 267 | ** in the container. If the container is empty, the 268 | ** returned iterator value shall no be dereferenced. 269 | ** The iterator is of type iterator (random access iterator 270 | ** on value_type reference). 271 | ** 272 | ** @return The iterator to the first element. 273 | */ 274 | iterator begin() { return (_start); }; 275 | 276 | /* 277 | ** @brief Return an iterator pointing on the first element 278 | ** in the container. If the container is empty, the 279 | ** returned iterator value shall no be dereferenced. 280 | ** The iterator is of type const_iterator (random access 281 | ** iterator on const value_type reference). 282 | ** 283 | ** @return The iterator to the first element. 284 | */ 285 | const_iterator begin() const { return (_start); } 286 | 287 | /* 288 | ** @brief Return an iterator pointing on the past-the-end element 289 | ** in the vector container. Past-the-end is the theorical element 290 | ** following the last element in the container. If the container is 291 | ** empty, return the same than begin. 292 | ** The iterator is of type iterator (random access iterator 293 | ** on value_type reference). 294 | ** 295 | ** @return The iterator to the past-the-end element or begin if 296 | ** the container is empty. 297 | */ 298 | iterator end() 299 | { 300 | if (this->empty()) 301 | return (this->begin()); 302 | return (_end); 303 | } 304 | 305 | /* 306 | ** @brief Return an iterator pointing on the past-the-end element 307 | ** in the vector container. Past-the-end is the theorical element 308 | ** following the last element in the container. If the container is 309 | ** empty, return the same than begin. 310 | ** The iterator is of type const_iterator (random access 311 | ** iterator on const value_type reference). 312 | ** 313 | ** @return The iterator to the past-the-end element or begin if 314 | ** the container is empty. 315 | */ 316 | const_iterator end() const 317 | { 318 | if (this->empty()) 319 | return (this->begin()); 320 | return (_end); 321 | } 322 | 323 | /* 324 | ** @brief Give a reverse iterator pointing to the last element 325 | ** in the container (this->end() - 1). 326 | ** This is a reversed random access iterator. 327 | ** 328 | ** @return A reverse Iterator to the reverse beginning of the. 329 | */ 330 | reverse_iterator rbegin() { return (reverse_iterator(this->end())); } 331 | 332 | /* 333 | ** @brief Give a const reverse iterator pointing to the last 334 | ** element in the container (this->end() - 1). 335 | ** This is a constant reversed random access iterator. 336 | ** 337 | ** @return A const reverse Iterator to the reverse beginning of the. 338 | */ 339 | const_reverse_iterator rbegin() const { return (reverse_iterator(this->end())); } 340 | 341 | /* 342 | ** @brief Give a reverse iterator point to the 343 | ** theorical element preceding the first element 344 | ** in the container. 345 | ** 346 | ** @return the reverse iterator. 347 | */ 348 | reverse_iterator rend() { return (reverse_iterator(this->begin())); } 349 | 350 | /* 351 | ** @brief Give a const reverse iterator point to the 352 | ** theorical element preceding the first element 353 | ** in the container. 354 | ** 355 | ** @return the const reverse iterator. 356 | */ 357 | const_reverse_iterator rend() const { return (reverse_iterator(this->begin())); } 358 | 359 | // Capacity: 360 | 361 | /* 362 | ** @brief Returns the number of elements stored. 363 | ** It's not necessarily equal to the storage capacity 364 | ** 365 | ** @return The number of elements in the container. 366 | ** (An unsigned integral type) 367 | */ 368 | size_type size(void) const { return (this->_end - this->_start); } 369 | 370 | /* 371 | ** @brief Returns the maximum potential number of elements the the 372 | ** vector can hold. 373 | ** This size is due to known system or library limitations. 374 | ** The vector is not garanteed to have this size, it can 375 | ** fail a allocation for exemple. 376 | ** 377 | ** Documentation : 378 | ** https://www.viva64.com/en/a/0050/ 379 | ** 380 | ** @return The maximum potential number of elements the 381 | ** container can hold. 382 | ** (An unsigned integral type) 383 | */ 384 | size_type max_size(void) const { return allocator_type().max_size(); } 385 | 386 | /* 387 | ** @brief Resizes the container so that it contain "n" 388 | ** element. If "n" is smaller than the actual size 389 | ** the container is reduced to "n". If it is greater, 390 | ** val is inserting at the end and according capacity 391 | ** to allocation calcul system. 392 | ** 393 | ** @param n the new size of the container. 394 | ** @param val the element to set. 395 | */ 396 | void resize (size_type n, value_type val = value_type()) 397 | { 398 | if (n > this->max_size()) 399 | throw (std::length_error("vector::resize")); 400 | else if (n < this->size()) 401 | { 402 | while (this->size() > n) 403 | { 404 | --_end; 405 | _alloc.destroy(_end); 406 | } 407 | } 408 | else 409 | this->insert(this->end(), n - this->size(), val); 410 | } 411 | 412 | /* 413 | ** @brief Return size of allocated storage capacity. 414 | ** Not necessarily equal to vector size. Can be equal 415 | ** or greater, because extra space allocated by the container 416 | ** forecast allocation system. 417 | ** 418 | ** @return The size of currntly allocated storage capacity. 419 | ** The number elements it can hold. 420 | ** (An unsigned integral type) 421 | */ 422 | size_type capacity (void) const { return (this->_end_capacity - this->_start); } 423 | 424 | /* 425 | ** @brief Returns whether the container is empty. 426 | ** Does not modify container in any way. 427 | ** 428 | ** @return true if the container size is 0, false otherwise. 429 | */ 430 | bool empty (void) const { return (size() == 0 ? true : false); } 431 | 432 | /* 433 | ** @brief Request that the vector capacity be at least 434 | ** enougth to contain "n" element. 435 | ** If n is greater that the actual capacity a reallocation 436 | ** can be happen, otherwise nothing happen. 437 | ** 438 | ** @param n the capacity asked. 439 | */ 440 | void reserve (size_type n) 441 | { 442 | if (n > this->max_size()) 443 | throw (std::length_error("vector::reserve")); 444 | else if (n > this->capacity()) 445 | { 446 | pointer prev_start = _start; 447 | pointer prev_end = _end; 448 | size_type prev_size = this->size(); 449 | size_type prev_capacity = this->capacity(); 450 | 451 | _start = _alloc.allocate( n ); 452 | _end_capacity = _start + n; 453 | _end = _start; 454 | while (prev_start != prev_end) 455 | { 456 | _alloc.construct(_end, *prev_start); 457 | _end++; 458 | prev_start++; 459 | } 460 | _alloc.deallocate(prev_start - prev_size, prev_capacity); 461 | } 462 | } 463 | 464 | // Element access: 465 | 466 | /* 467 | ** @brief Returns a reference to the element at 468 | ** position n in the vector container. 469 | ** If "n" is out of range that's causes undefined behavior. 470 | ** 471 | ** @param n Position of the element in the container. 472 | ** @return The specified element at "n" position. 473 | */ 474 | reference operator[] (size_type n) { return (*(_start + n)); } 475 | 476 | /* 477 | ** @brief Returns a const reference to the element at 478 | ** position n in the vector container. 479 | ** If "n" is out of range that's causes undefined behavior. 480 | ** 481 | ** @param n Position of the element in the container. 482 | ** @return The specified element at "n" position. 483 | */ 484 | const_reference operator[] (size_type n) const { return (*(_start + n)); } 485 | 486 | /* 487 | ** @brief Returns a reference to the element at 488 | ** position n in the vector container. 489 | ** The main difference between this function and the 490 | ** operator "[]" is that the function throw an 491 | ** std::out_of_range exception if "n" is out of the range of 492 | ** the container. 493 | ** 494 | ** @param n Position of the element in the container. 495 | ** @return The specified element at "n" position. 496 | */ 497 | reference at (size_type n) 498 | { 499 | checkRange(n); 500 | return ((*this)[n]); 501 | } 502 | 503 | /* 504 | ** @brief Returns a const reference to the element at 505 | ** position n in the vector container. 506 | ** The main difference between this function and the 507 | ** operator "[]" is that the function throw an 508 | ** std::out_of_range exception if "n" is out of the range of 509 | ** the container. 510 | ** 511 | ** @param n Position of the element in the container. 512 | ** @return The specified element at "n" position. 513 | */ 514 | const_reference at (size_type n) const 515 | { 516 | checkRange(n); 517 | return ((*this)[n]); 518 | } 519 | 520 | /* 521 | ** @brief Return a reference to the first element 522 | ** of the container. Call this on an empty container 523 | ** cause undefined behavior. 524 | ** 525 | ** @return The reference. 526 | */ 527 | reference front () { return (*_start); } 528 | 529 | /* 530 | ** @brief Return a const reference to the first element 531 | ** of the container. Call this on an empty container 532 | ** cause undefined behavior. 533 | ** 534 | ** @return The const reference. 535 | */ 536 | const_reference front () const { return (*_start); } 537 | 538 | /* 539 | ** @brief Return a reference to the last element in the container. 540 | ** If the container is empty, occur undefined behavior. 541 | ** 542 | ** @return The reference to the last element. 543 | */ 544 | reference back () { return (*(_end - 1)); } 545 | 546 | /* 547 | ** @brief Return a const reference to the last element in the container. 548 | ** If the container is empty, occur undefined behavior. 549 | ** 550 | ** @return The const reference to the last element. 551 | */ 552 | const_reference back () const { return (*(_end - 1)); } 553 | 554 | // Modifiers: 555 | 556 | /* 557 | ** Range (1) 558 | ** @brief Assigns new contents to the vector, replacing its current 559 | ** contents, add modifying its size accordingly. 560 | ** New elements are contruct from each of the elements in tht 561 | ** range, between first and last, in the same order. 562 | ** 563 | ** @param first the first element in the range. 564 | ** @param last the last element in the range. 565 | */ 566 | template 567 | void assign (InputIterator first, InputIterator last, 568 | typename ft::enable_if::value, InputIterator>::type* = u_nullptr) 569 | { 570 | bool is_valid; 571 | if (!(is_valid = ft::is_ft_iterator_tagged::iterator_category>::value)) 572 | throw (ft::InvalidIteratorException::iterator_category >::type>()); 573 | this->clear(); 574 | size_type dist = ft::distance(first, last); 575 | if (size_type(_end_capacity - _start) >= dist) 576 | { 577 | for(; &(*first) != &(*last); first++, _end++) 578 | _alloc.construct(_end, *first); 579 | } 580 | else 581 | { 582 | pointer new_start = pointer(); 583 | pointer new_end = pointer(); 584 | pointer new_end_capacity = pointer(); 585 | 586 | new_start = _alloc.allocate(dist); 587 | new_end = new_start; 588 | new_end_capacity = new_start + dist; 589 | 590 | for(; &(*first) != &(*last); first++, new_end++) 591 | _alloc.construct(new_end, *first); 592 | 593 | _alloc.deallocate(_start, this->capacity()); 594 | 595 | _start = new_start; 596 | _end = new_end; 597 | _end_capacity = new_end_capacity; 598 | } 599 | } 600 | 601 | /* 602 | ** @brief Fill assign. 603 | ** Clear the container, fill it with val "n" times. 604 | ** According size to "n". 605 | ** 606 | ** @param "n" the number of element. 607 | ** @param "val" the value of element. 608 | */ 609 | void assign (size_type n, const value_type& val) 610 | { 611 | this->clear(); 612 | if (n == 0) 613 | return ; 614 | if (size_type(_end_capacity - _start) >= n) 615 | { 616 | while (n) 617 | { 618 | _alloc.construct(_end++ , val); 619 | n--; 620 | } 621 | } 622 | else 623 | { 624 | _alloc.deallocate(_start, this->capacity()); 625 | _start = _alloc.allocate( n ); 626 | _end = _start; 627 | _end_capacity = _start + n; 628 | while (n) 629 | { 630 | _alloc.construct(_end++, val); 631 | n--; 632 | } 633 | } 634 | } 635 | 636 | /* 637 | ** @brief Add new element at the end of the vector. 638 | ** The content of "val" is copied (moved) to the new element. 639 | ** 640 | ** @param val The value to be copied. 641 | */ 642 | void push_back (const value_type& val) 643 | { 644 | if (_end == _end_capacity) 645 | { 646 | int next_capacity = (this->size() > 0) ? (int)(this->size() * 2) : 1; 647 | this->reserve(next_capacity); 648 | } 649 | _alloc.construct(_end, val); 650 | _end++; 651 | } 652 | 653 | /* 654 | ** @brief Delete the last element of the container. 655 | ** Reduce the size of the vector of one. 656 | ** If the container is empty, cause undefined behavior. 657 | */ 658 | void pop_back() 659 | { 660 | _alloc.destroy(&this->back()); 661 | _end--; 662 | } 663 | 664 | /* 665 | ** @brief Insert an element a the position. Can ecrease de size 666 | ** of the container. This action force the container to 667 | ** realocate all the elements that were after "postion" 668 | ** to their new positions. 669 | ** 670 | ** @param position The position where insert. 671 | ** @param val The element to insert. 672 | ** @return An iterator to the new element in the container. 673 | */ 674 | iterator insert (iterator position, const value_type& val) 675 | { 676 | size_type pos_len = &(*position) - _start; 677 | if (size_type(_end_capacity - _end) >= this->size() + 1) 678 | { 679 | for (size_type i = 0; i < pos_len; i++) 680 | _alloc.construct(_end - i, *(_end - i - 1)); 681 | _end++; 682 | _alloc.construct(&(*position), val); 683 | } 684 | else 685 | { 686 | pointer new_start = pointer(); 687 | pointer new_end = pointer(); 688 | pointer new_end_capacity = pointer(); 689 | 690 | int next_capacity = (this->size() * 2 > 0) ? this->size() * 2 : 1; 691 | new_start = _alloc.allocate( next_capacity ); 692 | new_end = new_start + this->size() + 1; 693 | new_end_capacity = new_start + next_capacity; 694 | 695 | for (size_type i = 0; i < pos_len; i++) 696 | _alloc.construct(new_start + i, *(_start + i)); 697 | _alloc.construct(new_start + pos_len, val); 698 | for (size_type j = 0; j < this->size() - pos_len; j++) 699 | _alloc.construct(new_end - j - 1, *(_end - j - 1)); 700 | 701 | for (size_type l = 0; l < this->size(); l++) 702 | _alloc.destroy(_start + l); 703 | if (_start) 704 | _alloc.deallocate(_start, this->capacity()); 705 | 706 | _start = new_start; 707 | _end = new_end; 708 | _end_capacity = new_end_capacity; 709 | } 710 | return (iterator(_start + pos_len)); 711 | } 712 | 713 | /* 714 | ** @brief Insert an element a "n" amount of time 715 | ** before the specified position. Can ecrease de capacity 716 | ** of the container. This action force the container to 717 | ** realocate all the elements that were after "position" 718 | ** to their new positions. 719 | ** 720 | ** @param position The position where insert. 721 | ** @param n Amout of element to insert. 722 | ** @param val The element to insert. 723 | */ 724 | void insert (iterator position, size_type n, const value_type& val) 725 | { 726 | if (n == 0) 727 | return ; 728 | if (n > this->max_size()) 729 | throw (std::length_error("vector::insert (fill)")); 730 | size_type pos_len = &(*position) - _start; 731 | if (size_type(_end_capacity - _end) >= n) 732 | { 733 | for (size_type i = 0; i < this->size() - pos_len; i++) 734 | _alloc.construct(_end - i + (n - 1), *(_end - i - 1)); 735 | _end += n; 736 | while (n) 737 | { 738 | _alloc.construct(&(*position) + (n - 1), val); 739 | n--; 740 | } 741 | } 742 | else 743 | { 744 | pointer new_start = pointer(); 745 | pointer new_end = pointer(); 746 | pointer new_end_capacity = pointer(); 747 | 748 | int next_capacity = (this->capacity() > 0) ? (int)(this->size() * 2) : 1; 749 | new_start = _alloc.allocate(next_capacity); 750 | new_end_capacity = new_start + next_capacity; 751 | 752 | if (size_type(new_end_capacity - new_start) < this->size() + n) 753 | { 754 | if (new_start) 755 | _alloc.deallocate(new_start, new_start - new_end_capacity); 756 | next_capacity = this->size() + n; 757 | new_start = _alloc.allocate(next_capacity); 758 | new_end = new_start + this->size() + n; 759 | new_end_capacity = new_start + next_capacity; 760 | } 761 | 762 | new_end = new_start + this->size() + n; 763 | 764 | for (int i = 0; i < (&(*position) - _start); i++) 765 | _alloc.construct(new_start + i, *(_start + i)); 766 | for (size_type k = 0; k < n; k++) 767 | _alloc.construct(new_start + pos_len + k, val); 768 | for (size_type j = 0; j < (this->size() - pos_len); j++) 769 | _alloc.construct(new_end - j - 1, *(_end - j - 1)); 770 | 771 | for (size_type u = 0; u < this->size(); u++) 772 | _alloc.destroy(_start + u); 773 | _alloc.deallocate(_start, this->capacity()); 774 | 775 | _start = new_start; 776 | _end = new_end; 777 | _end_capacity = new_end_capacity; 778 | } 779 | } 780 | 781 | /* 782 | ** @brief Insert element in range from ["first" to 783 | ** "last") at "position". Can increase the capacity of 784 | ** the container. Throw if the iterator given is not valid. 785 | ** Reallocate all elements after the dist between first and last. 786 | ** 787 | ** @param position the position where insert. 788 | ** @param first the first element in the range. 789 | ** @param last the last element in the range. 790 | */ 791 | template 792 | void insert (iterator position, InputIterator first, InputIterator last, 793 | typename ft::enable_if::value, InputIterator>::type* = u_nullptr) 794 | { 795 | bool is_valid; 796 | if (!(is_valid = ft::is_ft_iterator_tagged::iterator_category >::value)) 797 | throw (ft::InvalidIteratorException::iterator_category >::type>()); 798 | 799 | size_type dist = ft::distance(first, last); 800 | if (size_type(_end_capacity - _end) >= dist) 801 | { 802 | for(size_type i = 0; i < this->size() - (&(*position) - _start); i++) 803 | _alloc.construct(_end - i + (dist - 1), *(_end - i - 1)); 804 | _end += dist; 805 | for (; &(*first) != &(*last); first++, position++) 806 | _alloc.construct(&(*position), *first); 807 | } 808 | else 809 | { 810 | pointer new_start = pointer(); 811 | pointer new_end = pointer(); 812 | pointer new_end_capacity = pointer(); 813 | 814 | new_start = _alloc.allocate( this->size() * 2 ); 815 | new_end = new_start + this->size() + dist; 816 | new_end_capacity = new_start + ( this->size() * 2 ); 817 | 818 | if (size_type(new_end_capacity - new_start) < this->size() + dist) 819 | { 820 | if (new_start) 821 | _alloc.deallocate(new_start, new_end_capacity - new_start); 822 | new_start = _alloc.allocate (this->size() + dist); 823 | new_end = new_start + this->size() + dist; 824 | new_end_capacity = new_end; 825 | } 826 | 827 | for (int i = 0; i < &(*position) - _start; i++) 828 | _alloc.construct(new_start + i, *(_start + i)); 829 | for (int j = 0; &(*first) != &(*last); first++, j++) 830 | _alloc.construct(new_start + (&(*position) - _start) + j, *first); 831 | for (size_type k = 0; k < this->size() - (&(*position) - _start); k++) 832 | _alloc.construct(new_start + (&(*position) - _start) + dist + k, *(_start + (&(*position) - _start) + k)); 833 | 834 | for (size_type l = 0; l < this->size(); l++) 835 | _alloc.destroy(_start + l); 836 | _alloc.deallocate(_start, this->capacity()); 837 | 838 | _start = new_start; 839 | _end = new_end; 840 | _end_capacity = new_end_capacity; 841 | } 842 | } 843 | 844 | /* 845 | ** @brief Remove element from the vector at "position". 846 | ** Reduce the size of 1; 847 | ** 848 | ** @param position the iterator pointing to the 849 | ** element to remove. 850 | ** @return a pointer to the element a "&(*position) + 1"; 851 | */ 852 | iterator erase (iterator position) 853 | { 854 | pointer p_pos = &(*position); 855 | _alloc.destroy(&(*position)); 856 | if (&(*position) + 1 == _end) 857 | _alloc.destroy(&(*position)); 858 | else 859 | { 860 | for (int i = 0; i < _end - &(*position) - 1; i++) 861 | { 862 | _alloc.construct(&(*position) + i, *(&(*position) + i + 1)); 863 | _alloc.destroy(&(*position) + i + 1); 864 | } 865 | } 866 | _end -= 1; 867 | return (iterator(p_pos)); 868 | } 869 | 870 | /* 871 | ** @brief Remove element from the vector a range of element. 872 | ** Reduce the size by the number of element removed. 873 | ** 874 | ** @param first the first element in the range. 875 | ** @param last the last element in the range. 876 | ** @return An iterator that point to the first element 877 | ** after "last". 878 | */ 879 | iterator erase (iterator first, iterator last) 880 | { 881 | pointer p_first = &(*first); 882 | for (; &(*first) != &(*last); first++) 883 | _alloc.destroy(&(*first)); 884 | for (int i = 0; i < _end - &(*last); i++) 885 | { 886 | _alloc.construct(p_first + i, *(&(*last) + i)); 887 | _alloc.destroy(&(*last) + i); 888 | } 889 | _end -= (&(*last) - p_first); 890 | return (iterator(p_first)); 891 | } 892 | 893 | /* 894 | ** @brief Exchanges the content with "x" content. 895 | ** "x" is of same type. Elements of "x" are elements 896 | ** of this container and elements of this are of "x". 897 | ** All iterators, references, pointer on the swaped 898 | ** objects stay valid. 899 | ** 900 | ** @param x the vector to swap. 901 | */ 902 | void swap (vector& x) 903 | { 904 | if (x == *this) 905 | return; 906 | 907 | pointer save_start = x._start; 908 | pointer save_end = x._end; 909 | pointer save_end_capacity = x._end_capacity; 910 | allocator_type save_alloc = x._alloc; 911 | 912 | x._start = this->_start; 913 | x._end = this->_end; 914 | x._end_capacity = this->_end_capacity; 915 | x._alloc = this->_alloc; 916 | 917 | this->_start = save_start; 918 | this->_end = save_end; 919 | this->_end_capacity = save_end_capacity; 920 | this->_alloc = save_alloc; 921 | } 922 | 923 | /* 924 | ** @brief Removes (destroy) all elements from the 925 | ** container. Final size is 0. 926 | */ 927 | void clear() 928 | { 929 | size_type save_size = this->size(); 930 | for (size_type i = 0; i < save_size; i++) 931 | { 932 | _end--; 933 | _alloc.destroy(_end); 934 | } 935 | } 936 | 937 | private: 938 | allocator_type _alloc; 939 | pointer _start; 940 | pointer _end; 941 | pointer _end_capacity; 942 | 943 | /* 944 | ** @brief Check if "n" is in the range of the container. 945 | ** If "n" is out of range that's throw an std::out_of_range 946 | ** exception. 947 | ** 948 | ** @param n The position of the element to check. 949 | */ 950 | void checkRange(const size_type& n) const 951 | { 952 | if (n >= this->size()) 953 | throw (std::out_of_range("vector::checkRange: n (which is " 954 | + ft::to_string(n) + ") >= this->size() (which is " 955 | + ft::to_string(this->size()) + ")")); 956 | } 957 | }; 958 | 959 | // Non-member function overloads 960 | 961 | /* 962 | ** @brief Compare vector container to know 963 | ** if they are equal. Start to check if the size 964 | ** is different. 965 | ** 966 | ** @param lhs vector to compare with "rhs". 967 | ** @param rhs vector for comparison of "lhs". 968 | ** @return true if they are equal, false otherwise. 969 | */ 970 | template 971 | bool operator== (const ft::vector& lhs, const ft::vector& rhs) 972 | { 973 | if (lhs.size() != rhs.size()) 974 | return (false); 975 | typename ft::vector::const_iterator first1 = lhs.begin(); 976 | typename ft::vector::const_iterator first2 = rhs.begin(); 977 | while (first1 != lhs.end()) 978 | { 979 | if (first2 == rhs.end() || *first1 != *first2) 980 | return (false); 981 | ++first1; 982 | ++first2; 983 | } 984 | return (true); 985 | } 986 | 987 | /* 988 | ** @brief Compare vector container to know 989 | ** if they are different. Equivalent to !(lsh == rhs). 990 | ** 991 | ** @param lhs vector to compare with "rhs". 992 | ** @param rhs vector for comparison of "lhs". 993 | ** @return true if they are different, false otherwise. 994 | */ 995 | template 996 | bool operator!= (const vector& lhs, const vector& rhs) 997 | { 998 | return (!(lhs == rhs)); 999 | } 1000 | 1001 | /* 1002 | ** @brief Compare vector container to know 1003 | ** if "lhs" elements are lexicographicalement less than "rhs". 1004 | ** 1005 | ** @param lhs vector to compare with "rhs". 1006 | ** @param rhs vector for comparison of "lhs". 1007 | ** @return true if "lhs" is lexicographicalement less, false otherwise. 1008 | */ 1009 | template 1010 | bool operator< (const vector& lhs, const vector& rhs) 1011 | { 1012 | return (ft::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end())); 1013 | } 1014 | 1015 | /* 1016 | ** @brief Compare vector container to know 1017 | ** if "lhs" elements are lexicographicalement less or equal than "rhs". 1018 | ** 1019 | ** @param lhs vector to compare with "rhs". 1020 | ** @param rhs vector for comparison of "lhs". 1021 | ** @return true if "lhs" is lexicographicalement less or equal, false otherwise. 1022 | */ 1023 | template 1024 | bool operator<= (const vector& lhs, const vector& rhs) 1025 | { 1026 | return (!(rhs < lhs)); 1027 | } 1028 | 1029 | /* 1030 | ** @brief Compare vector container to know 1031 | ** if "lhs" elements are lexicographicalement superior than "rhs". 1032 | ** 1033 | ** @param lhs vector to compare with "rhs". 1034 | ** @param rhs vector for comparison of "lhs". 1035 | ** @return true if "lhs" is lexicographicalement superior, false otherwise. 1036 | */ 1037 | template 1038 | bool operator> (const vector& lhs, const vector& rhs) 1039 | { 1040 | return (rhs < lhs); 1041 | } 1042 | 1043 | /* 1044 | ** @brief Compare vector container to know 1045 | ** if "lhs" elements are lexicographicalement superior or equal than "rhs". 1046 | ** 1047 | ** @param lhs vector to compare with "rhs". 1048 | ** @param rhs vector for comparison of "lhs". 1049 | ** @return true if "lhs" is lexicographicalement superior or equal, false otherwise. 1050 | */ 1051 | template 1052 | bool operator>= (const vector& lhs, const vector& rhs) 1053 | { 1054 | return (!(lhs < rhs)); 1055 | } 1056 | 1057 | /* 1058 | ** @brief Overload of swap (vector). 1059 | ** The contents of container are swaped. 1060 | ** 1061 | ** @param x, y the containers to swap. 1062 | */ 1063 | template 1064 | void swap (vector& x, vector&y) 1065 | { 1066 | x.swap(y); 1067 | } 1068 | } 1069 | 1070 | // ============================================================================= 1071 | 1072 | #endif --------------------------------------------------------------------------------