Compare commits
63 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
38e82e4e11 | ||
|
|
ed7d1d1ed9 | ||
|
|
3280f4a754 | ||
|
|
81b76ae040 | ||
|
|
ca066489a7 | ||
|
|
56c42a66b6 | ||
|
|
581458ca37 | ||
|
|
52fa6ff65b | ||
|
|
9bde325ece | ||
|
|
9a87539680 | ||
|
|
de5f718d0c | ||
|
|
ef70cc5938 | ||
|
|
e27bf01db4 | ||
|
|
6e230109db | ||
|
|
ae646ee58a | ||
|
|
a968b4d791 | ||
|
|
38804caea9 | ||
|
|
eeb3c7dfc0 | ||
|
|
b0b63d6238 | ||
|
|
26436c8d8a | ||
|
|
6617d6cdf5 | ||
|
|
58d417742b | ||
|
|
0d98268a74 | ||
|
|
844701201f | ||
|
|
28acc5ef51 | ||
|
|
c7114c1db2 | ||
|
|
8c181b6407 | ||
|
|
8a404b0839 | ||
|
|
3074f7c93c | ||
|
|
50224fb432 | ||
|
|
94745ca8a9 | ||
|
|
72762a79cb | ||
|
|
a939bfc66f | ||
|
|
64d87cb5d4 | ||
|
|
df6332b496 | ||
|
|
da4ebc13fd | ||
|
|
e3151bce4e | ||
|
|
5ee4202020 | ||
|
|
1cc5dabb7b | ||
|
|
32c413f741 | ||
|
|
bb4ac9963d | ||
|
|
005382a3ac | ||
|
|
988d67e908 | ||
|
|
c187d34ce7 | ||
|
|
68ada8ca68 | ||
|
|
8326f7f283 | ||
|
|
b385f6220a | ||
|
|
5d0e631cb7 | ||
|
|
8c232df375 | ||
|
|
647b6eee25 | ||
|
|
a4550a9bb9 | ||
|
|
556807669e | ||
|
|
7d857c5e4e | ||
|
|
aecd2caa1c | ||
|
|
6362a50ffa | ||
|
|
dea7818dfa | ||
|
|
0146ebcbf1 | ||
|
|
f765779b27 | ||
|
|
99f67b808c | ||
|
|
0e51cc655c | ||
|
|
5e65691bc8 | ||
|
|
1a8b81c3cf | ||
|
|
27c6d387ad |
4
.gitignore
vendored
4
.gitignore
vendored
@@ -36,6 +36,10 @@ Thumbs.db
|
||||
*.zip
|
||||
*.pdf
|
||||
/builds
|
||||
/builds_ft
|
||||
/builds_stl
|
||||
|
||||
# cube3d
|
||||
containers
|
||||
containers_ft
|
||||
containers_stl
|
||||
|
||||
129
Makefile
Normal file
129
Makefile
Normal file
@@ -0,0 +1,129 @@
|
||||
|
||||
# - - - - - - - #
|
||||
# #
|
||||
# COLORS #
|
||||
# #
|
||||
# - - - - - - - #
|
||||
|
||||
GRAY = "\e[0;30m"
|
||||
RED = "\e[0;31m"
|
||||
GREEN = "\e[0;32m"
|
||||
YELLOW = "\e[0;33m"
|
||||
BLUE = "\e[0;34m"
|
||||
PURPLE = "\e[0;35m"
|
||||
CYAN = "\e[0;36m"
|
||||
WHITE = "\e[0;37m"
|
||||
|
||||
B_GRAY = "\e[1;30m"
|
||||
B_RED = "\e[1;31m"
|
||||
B_GREEN = "\e[1;32m"
|
||||
B_YELLOW = "\e[1;33m"
|
||||
B_BLUE = "\e[1;34m"
|
||||
B_PURPLE = "\e[1;35m"
|
||||
B_CYAN = "\e[1;36m"
|
||||
B_WHITE = "\e[1;37m"
|
||||
|
||||
RESET = "\e[0m"
|
||||
|
||||
|
||||
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
|
||||
# . name = value \ . += append to a variable #
|
||||
# VARIABLES . value . != set result of command #
|
||||
# . . ?= set if not already set #
|
||||
# . (case sensitive) . := expand once at definition line #
|
||||
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
|
||||
|
||||
NAME = containers
|
||||
NAME_FT = containers_ft
|
||||
NAME_STL = containers_stl
|
||||
|
||||
CC = c++
|
||||
EXT = cpp
|
||||
|
||||
CFLAGS = -Wall -Wextra -Werror $(INCLUDES)
|
||||
CFLAGS += -MMD -MP #see end-page note on header dependencie
|
||||
CFLAGS += -std=c++98
|
||||
CFLAGS += -g3
|
||||
|
||||
CFLAGS_STL = $(CFLAGS)
|
||||
CFLAGS_STL += -D STL
|
||||
|
||||
VPATH = $(D_SRCS)
|
||||
|
||||
LIBS =
|
||||
|
||||
D_INCLUDE = ./headers \
|
||||
./templates \
|
||||
./tests/includes
|
||||
|
||||
INCLUDES = $(D_INCLUDE:%=-I%)
|
||||
|
||||
D_SRCS = ./tests
|
||||
#SRCS = main42.cpp
|
||||
#SRCS = main_map_1.cpp
|
||||
#SRCS = main_map_2.cpp
|
||||
#SRCS = main_stack_1.cpp
|
||||
SRCS = main.cpp \
|
||||
tests_definitions.cpp \
|
||||
tests_vector.cpp \
|
||||
tests_map.cpp \
|
||||
tests_stack.cpp
|
||||
|
||||
D_OBJS_FT = builds_ft
|
||||
OBJS_FT = $(SRCS:%.$(EXT)=$(D_OBJS_FT)/%.o)
|
||||
D_OBJS_STL = builds_stl
|
||||
OBJS_STL = $(SRCS:%.$(EXT)=$(D_OBJS_STL)/%.o)
|
||||
|
||||
OBJS = $(OBJS_FT) $(OBJS_STL)
|
||||
DEPS = $(OBJS:.o=.d) #see end-page note on header dependencie
|
||||
|
||||
|
||||
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
|
||||
# . target: prerequisites . $@ : target #
|
||||
# RULES . recipe . $< : 1st prerequisite #
|
||||
# . @recipe (silent) . $^ : all prerequisites #
|
||||
# . target: VAR = assignment . | : order-only prereq. #
|
||||
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
|
||||
|
||||
all: $(NAME_FT) $(NAME_STL)
|
||||
stl: $(NAME_STL)
|
||||
ft: $(NAME_FT)
|
||||
|
||||
$(D_OBJS_FT)/%.o: %.$(EXT) | $(D_OBJS_FT)
|
||||
@echo $(CYAN)"compilation " $@ $(RESET)
|
||||
@$(CC) $(CFLAGS) -c $< -o $@
|
||||
$(D_OBJS_STL)/%.o: %.$(EXT) | $(D_OBJS_STL)
|
||||
@echo $(CYAN)"compilation -D STL" $@ $(RESET)
|
||||
@$(CC) $(CFLAGS) -D STL -c $< -o $@
|
||||
|
||||
$(D_OBJS_FT) $(D_OBJS_STL):
|
||||
mkdir $@
|
||||
|
||||
$(NAME_FT): $(OBJS_FT)
|
||||
$(NAME_STL): $(OBJS_STL)
|
||||
$(NAME_FT) $(NAME_STL):
|
||||
@echo $(PURPLE)"linkage (link objects.o)"$(RESET)
|
||||
@$(CC) $^ -o $@ $(LIBS)
|
||||
|
||||
leaks: leaksft
|
||||
leaksft: $(NAME_FT)
|
||||
valgrind --leak-check=full --show-leak-kinds=all ./$<
|
||||
leakstl: $(NAME_STL)
|
||||
valgrind --leak-check=full --show-leak-kinds=all ./$<
|
||||
|
||||
clean:
|
||||
rm -rf $(D_OBJS_FT)
|
||||
rm -rf $(D_OBJS_STL)
|
||||
|
||||
fclean: clean
|
||||
rm -f $(NAME_FT) $(NAME_STL)
|
||||
|
||||
re: fclean all
|
||||
|
||||
.PHONY : all clean fclean re
|
||||
|
||||
# header dependencie
|
||||
# https://spin.atomicobject.com/2016/08/26/makefile-c-projects
|
||||
# https://stackoverflow.com/questions/13432127/how-to-use-the-include-directive-in-a-makefile-for-a-specific-target
|
||||
-include $(DEPS)
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
# CONTAINERS #
|
||||
|
||||
### Compilation
|
||||
@@ -62,3 +63,4 @@ saires. Cependant, vous devez éviter le problème de la double inclusion en les
|
||||
* Vous devez créer deux binaires faisant tourner les mêmes tests : l’un avec vos containers et l’autre avec les containers standards.
|
||||
* Comparez les sorties et les performances / temps (vos containers peuvent être jusqu’à 20 fois plus lents que les originaux).
|
||||
* Pour tester vos containers : ft::<container>.
|
||||
|
||||
|
||||
BIN
correction.png
Normal file
BIN
correction.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 836 KiB |
26
headers/colors.h
Normal file
26
headers/colors.h
Normal file
@@ -0,0 +1,26 @@
|
||||
|
||||
#ifndef COLORS_H
|
||||
# define COLORS_H
|
||||
|
||||
# define GRAY "\e[0;30m"
|
||||
# define RED "\e[0;31m"
|
||||
# define GREEN "\e[0;32m"
|
||||
# define YELLOW "\e[0;33m"
|
||||
# define BLUE "\e[0;34m"
|
||||
# define PURPLE "\e[0;35m"
|
||||
# define CYAN "\e[0;36m"
|
||||
# define WHITE "\e[0;37m"
|
||||
|
||||
# define B_GRAY "\e[1;30m"
|
||||
# define B_RED "\e[1;31m"
|
||||
# define B_GREEN "\e[1;32m"
|
||||
# define B_YELLOW "\e[1;33m"
|
||||
# define B_BLUE "\e[1;34m"
|
||||
# define B_PURPLE "\e[1;35m"
|
||||
# define B_CYAN "\e[1;36m"
|
||||
# define B_WHITE "\e[1;37m"
|
||||
|
||||
# define RESET "\e[0m"
|
||||
|
||||
#endif
|
||||
|
||||
16
headers/enable_if.hpp
Normal file
16
headers/enable_if.hpp
Normal file
@@ -0,0 +1,16 @@
|
||||
#ifndef ENABLE_IF_HPP
|
||||
# define ENABLE_IF_HPP
|
||||
|
||||
namespace ft {
|
||||
|
||||
template <bool B, class T = void>
|
||||
struct enable_if {};
|
||||
|
||||
|
||||
template <class T>
|
||||
struct enable_if<true, T> { typedef T type; };
|
||||
|
||||
} // namespace ft
|
||||
|
||||
#endif
|
||||
|
||||
36
headers/equal.hpp
Normal file
36
headers/equal.hpp
Normal file
@@ -0,0 +1,36 @@
|
||||
|
||||
#ifndef EQUAL_HPP
|
||||
# define EQUAL_HPP
|
||||
|
||||
namespace ft {
|
||||
|
||||
template < typename InputIt1, typename InputIt2 >
|
||||
bool equal( InputIt1 first1, InputIt1 last1, InputIt2 first2) {
|
||||
|
||||
while (first1 != last1)
|
||||
{
|
||||
if (!(*first1 == *first2))
|
||||
return false;
|
||||
++first1;
|
||||
++first2;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template < class InputIt1, class InputIt2, class BinaryPred >
|
||||
bool equal( InputIt1 first1, InputIt1 last1, InputIt2 first2, BinaryPred pred) {
|
||||
|
||||
while (first1 != last1)
|
||||
{
|
||||
if (!pred(*first1, *first2))
|
||||
return false;
|
||||
++first1;
|
||||
++first2;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace ft
|
||||
|
||||
#endif
|
||||
|
||||
46
headers/is_integral.hpp
Normal file
46
headers/is_integral.hpp
Normal file
@@ -0,0 +1,46 @@
|
||||
#ifndef IS_INTEGRAL_HPP
|
||||
# define IS_INTEGRAL_HPP
|
||||
|
||||
namespace ft {
|
||||
|
||||
template <class T> struct is_integral
|
||||
{
|
||||
typedef char yes[1];
|
||||
typedef yes no[2];
|
||||
|
||||
static T type;
|
||||
|
||||
// integral types : https://www.cplusplus.com/reference/type_traits/is_integral/
|
||||
static yes& test(bool);
|
||||
static yes& test(char);
|
||||
// static yes& test(char16_t);
|
||||
// static yes& test(char32_t);
|
||||
static yes& test(wchar_t);
|
||||
static yes& test(signed char);
|
||||
static yes& test(short int);
|
||||
static yes& test(int);
|
||||
static yes& test(long int);
|
||||
static yes& test(long long int);
|
||||
static yes& test(unsigned char);
|
||||
static yes& test(unsigned short int);
|
||||
static yes& test(unsigned int);
|
||||
static yes& test(unsigned long int);
|
||||
static yes& test(unsigned long long int);
|
||||
|
||||
// non-template function with direct matching are always considered first
|
||||
// then the function template with direct matching are considered
|
||||
// https://stackoverflow.com/questions/12877546/how-do-i-avoid-implicit-conversions-on
|
||||
template <class C> static no& test(C);
|
||||
|
||||
static const bool value = sizeof(test(type)) == sizeof(yes);
|
||||
};
|
||||
|
||||
} // namespace ft
|
||||
|
||||
// "template <>" introduce a total specialization of a template :
|
||||
// https://stackoverflow.com/questions/6288812/what-is-the-meaning-of-template-with-empty-angle-brackets-in-c
|
||||
|
||||
// SFINAE : https://jguegant.github.io/blogs/tech/sfinae-introduction.html
|
||||
|
||||
#endif
|
||||
|
||||
44
headers/iterator_traits.hpp
Normal file
44
headers/iterator_traits.hpp
Normal file
@@ -0,0 +1,44 @@
|
||||
|
||||
#ifndef ITERATOR_TRAITS_HPP
|
||||
# define ITERATOR_TRAITS_HPP
|
||||
|
||||
# include <iterator> // iterator_tag
|
||||
# include <cstddef> // ptrdiff_t
|
||||
|
||||
namespace ft {
|
||||
|
||||
template < typename Iterator >
|
||||
struct iterator_traits
|
||||
{
|
||||
typedef typename Iterator::iterator_category iterator_category;
|
||||
typedef typename Iterator::value_type value_type;
|
||||
typedef typename Iterator::difference_type difference_type;
|
||||
typedef typename Iterator::pointer pointer;
|
||||
typedef typename Iterator::reference reference;
|
||||
};
|
||||
|
||||
template < typename T >
|
||||
struct iterator_traits<T*>
|
||||
{
|
||||
typedef std::random_access_iterator_tag iterator_category;
|
||||
typedef T value_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef T* pointer;
|
||||
typedef T& reference;
|
||||
};
|
||||
|
||||
template < typename T >
|
||||
struct iterator_traits<const T*>
|
||||
{
|
||||
typedef std::random_access_iterator_tag iterator_category;
|
||||
typedef T value_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef const T* pointer;
|
||||
typedef const T& reference;
|
||||
};
|
||||
|
||||
} // namespace ft
|
||||
|
||||
#endif
|
||||
|
||||
// https://www.fluentcpp.com/2018/05/08/std-iterator-deprecated/
|
||||
23
headers/lexicographical_compare.hpp
Normal file
23
headers/lexicographical_compare.hpp
Normal file
@@ -0,0 +1,23 @@
|
||||
|
||||
#ifndef LEXICOGRAPHICAL_COMPARE_HPP
|
||||
# define LEXICOGRAPHICAL_COMPARE_HPP
|
||||
|
||||
namespace ft {
|
||||
|
||||
template <class InputIt1, class InputIt2>
|
||||
bool lexicographical_compare
|
||||
( InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2 ) {
|
||||
|
||||
for (; first1 != last1; first1++, first2++) {
|
||||
if (*first1 < *first2)
|
||||
return true;
|
||||
if (*first2 < *first1)
|
||||
return false;
|
||||
}
|
||||
return (first1 == last1 && first2 != last2);
|
||||
}
|
||||
|
||||
} // namespace ft
|
||||
|
||||
#endif
|
||||
|
||||
23
headers/make_pair.hpp
Normal file
23
headers/make_pair.hpp
Normal file
@@ -0,0 +1,23 @@
|
||||
#ifndef MAKE_PAIR_HPP
|
||||
# define MAKE_PAIR_HPP
|
||||
|
||||
# define PR_TPL template < class T1, class T2 >
|
||||
# define PR pair<T1, T2>
|
||||
|
||||
#include "pair.hpp"
|
||||
|
||||
namespace ft {
|
||||
|
||||
PR_TPL PR
|
||||
make_pair(T1 x, T2 y) {
|
||||
|
||||
return PR(x, y) ;
|
||||
}
|
||||
|
||||
} // namespace ft
|
||||
|
||||
# undef PR
|
||||
# undef PR_TPL
|
||||
|
||||
#endif
|
||||
|
||||
222
headers/map.hpp
Normal file
222
headers/map.hpp
Normal file
@@ -0,0 +1,222 @@
|
||||
|
||||
#ifndef MAP_HPP
|
||||
# define MAP_HPP
|
||||
|
||||
# include <memory> // std::allocator
|
||||
# include <cstddef> // NULL, std::size_t, std::ptrdiff_t
|
||||
# include <algorithm> // std::max()
|
||||
# include <functional> // std::less, std::binary_function
|
||||
|
||||
# include "reverse_iterator.hpp"
|
||||
# include "equal.hpp"
|
||||
# include "lexicographical_compare.hpp"
|
||||
|
||||
# include "pair.hpp"
|
||||
# include "make_pair.hpp"
|
||||
# include "map_node.hpp"
|
||||
# include "map_iterator.hpp"
|
||||
|
||||
namespace ft {
|
||||
|
||||
template <
|
||||
class Key, // map::key_type
|
||||
class T, // map::mapped_type
|
||||
class Compare = std::less<Key>, // map::key_compare
|
||||
class Alloc = std::allocator< ft::pair<const Key, T> > // map::allocator_type
|
||||
> class map {
|
||||
|
||||
public:
|
||||
|
||||
typedef Key key_type;
|
||||
typedef T mapped_type;
|
||||
typedef pair<const Key, T> value_type;
|
||||
typedef std::size_t size_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef Compare key_compare;
|
||||
typedef Alloc allocator_type;
|
||||
|
||||
typedef map_iterator<Key, T, Compare, Alloc> iterator;
|
||||
typedef map_const_iterator<Key, T, Compare, Alloc> const_iterator;
|
||||
typedef ft::reverse_iterator<iterator> reverse_iterator;
|
||||
typedef ft::reverse_iterator<const_iterator> const_reverse_iterator;
|
||||
|
||||
|
||||
/****************
|
||||
* member class :
|
||||
****************/
|
||||
// https://en.cppreference.com/w/cpp/container/map/value_compare
|
||||
// https://stackoverflow.com/questions/4571355/why-would-one-use-nested-classes-in-c
|
||||
class value_compare : public std::binary_function<value_type, value_type, bool> {
|
||||
|
||||
friend class map;
|
||||
protected:
|
||||
Compare comp;
|
||||
value_compare(Compare c) : comp(c) {}
|
||||
public:
|
||||
bool operator() (const value_type& x, const value_type& y) const
|
||||
{ return comp(x.first, y.first); }
|
||||
};
|
||||
|
||||
|
||||
/************
|
||||
* copliens :
|
||||
************/
|
||||
// constructors ------------------------------
|
||||
explicit map (const key_compare& comp = key_compare(),
|
||||
const allocator_type& alloc = allocator_type());
|
||||
template <class InputIterator>
|
||||
map (InputIterator first, InputIterator last,
|
||||
const key_compare& comp = key_compare(),
|
||||
const allocator_type& alloc = allocator_type());
|
||||
map(const map& x);
|
||||
// destructor --------------------------------
|
||||
~map();
|
||||
// operator= ---------------------------------
|
||||
map& operator= (const map& x);
|
||||
|
||||
|
||||
/*************
|
||||
* iterators :
|
||||
*************/
|
||||
// begin -------------------------------------
|
||||
iterator begin();
|
||||
const_iterator begin() const;
|
||||
// end ---------------------------------------
|
||||
iterator end();
|
||||
const_iterator end() const;
|
||||
// rbegin ------------------------------------
|
||||
reverse_iterator rbegin();
|
||||
const_reverse_iterator rbegin() const;
|
||||
// rend --------------------------------------
|
||||
reverse_iterator rend();
|
||||
const_reverse_iterator rend() const;
|
||||
|
||||
|
||||
/************
|
||||
* capacity :
|
||||
************/
|
||||
// empty -------------------------------------
|
||||
bool empty() const;
|
||||
// size --------------------------------------
|
||||
size_type size() const;
|
||||
// max_size ----------------------------------
|
||||
size_type max_size() const;
|
||||
|
||||
|
||||
/******************
|
||||
* element access :
|
||||
******************/
|
||||
// operator[] --------------------------------
|
||||
mapped_type & operator[] (const key_type& k);
|
||||
|
||||
|
||||
/*************
|
||||
* modifiers :
|
||||
*************/
|
||||
// insert ------------------------------------
|
||||
pair<iterator,bool> insert (const value_type& val);
|
||||
iterator insert (iterator position, const value_type& val);
|
||||
template <class InputIterator>
|
||||
void insert (InputIterator first, InputIterator last);
|
||||
// erase -------------------------------------
|
||||
void erase (iterator position);
|
||||
size_type erase (const key_type& k);
|
||||
void erase (iterator first, iterator last);
|
||||
// swap --------------------------------------
|
||||
void swap (map& x);
|
||||
// clear -------------------------------------
|
||||
void clear();
|
||||
|
||||
|
||||
/*************
|
||||
* observers :
|
||||
*************/
|
||||
// key_comp ----------------------------------
|
||||
key_compare key_comp() const;
|
||||
// value_comp --------------------------------
|
||||
value_compare value_comp() const;
|
||||
|
||||
|
||||
/**************
|
||||
* operations :
|
||||
**************/
|
||||
// find --------------------------------------
|
||||
iterator find (const key_type& k);
|
||||
const_iterator find (const key_type& k) const;
|
||||
// count -------------------------------------
|
||||
size_type count (const key_type& k) const;
|
||||
// lower_bound -------------------------------
|
||||
iterator lower_bound (const key_type& k);
|
||||
const_iterator lower_bound (const key_type& k) const;
|
||||
// upper_bound -------------------------------
|
||||
iterator upper_bound (const key_type& k);
|
||||
const_iterator upper_bound (const key_type& k) const;
|
||||
// equal_range -------------------------------
|
||||
pair<const_iterator,const_iterator> equal_range (const key_type& k) const;
|
||||
pair<iterator,iterator> equal_range (const key_type& k);
|
||||
|
||||
|
||||
/*************
|
||||
* allocator :
|
||||
*************/
|
||||
// get_allocator -----------------------------
|
||||
allocator_type get_allocator() const;
|
||||
|
||||
private:
|
||||
size_type _size;
|
||||
node<value_type>* _root;
|
||||
sentinel<value_type>* _sentinel;
|
||||
Compare _comp;
|
||||
Alloc _allocator;
|
||||
|
||||
// https://stackoverflow.com/questions/14148756/what-does-template-rebind-do
|
||||
typename Alloc::template rebind< node<value_type> >::other _allocator_node;
|
||||
typename Alloc::template rebind< sentinel<value_type> >::other _allocator_sentinel;
|
||||
|
||||
// BBST
|
||||
enum {INSERT, ERASE};
|
||||
void _balance(node<value_type>* n);
|
||||
short _compute_height(node<value_type>* n);
|
||||
short _balance_factor(node<value_type>* n);
|
||||
node<value_type>* _rotate_left(node<value_type>* n);
|
||||
node<value_type>* _rotate_right(node<value_type>* n);
|
||||
};
|
||||
|
||||
|
||||
/************************
|
||||
* non-member functions :
|
||||
************************/
|
||||
// operator == -------------------------------
|
||||
template< class K, class T, class Comp, class Alloc > bool operator==
|
||||
( const std::map<K,T,Comp,Alloc>& lhs, const std::map<K,T,Comp,Alloc>& rhs );
|
||||
// operator != -------------------------------
|
||||
template< class K, class T, class Comp, class Alloc > bool operator!=
|
||||
( const std::map<K,T,Comp,Alloc>& lhs, const std::map<K,T,Comp,Alloc>& rhs );
|
||||
// operator < --------------------------------
|
||||
template< class K, class T, class Comp, class Alloc > bool operator<
|
||||
( const std::map<K,T,Comp,Alloc>& lhs, const std::map<K,T,Comp,Alloc>& rhs );
|
||||
// operator <= -------------------------------
|
||||
template< class K, class T, class Comp, class Alloc > bool operator<=
|
||||
( const std::map<K,T,Comp,Alloc>& lhs, const std::map<K,T,Comp,Alloc>& rhs );
|
||||
// operator > --------------------------------
|
||||
template< class K, class T, class Comp, class Alloc > bool operator>
|
||||
( const std::map<K,T,Comp,Alloc>& lhs, const std::map<K,T,Comp,Alloc>& rhs );
|
||||
// operator >= -------------------------------
|
||||
template< class K, class T, class Comp, class Alloc > bool operator>=
|
||||
( const std::map<K,T,Comp,Alloc>& lhs, const std::map<K,T,Comp,Alloc>& rhs );
|
||||
// swap (map) -----------------------------
|
||||
template< class Key, class T, class Compare, class Alloc > void swap
|
||||
( std::map<Key,T,Compare,Alloc>& lhs, std::map<Key,T,Compare,Alloc>& rhs );
|
||||
|
||||
} // namespace ft
|
||||
|
||||
# include "map.tpp"
|
||||
|
||||
// banlanced binary search tree :
|
||||
// https://www.youtube.com/watch?v=vRwi_UcZGjU
|
||||
|
||||
// entinel node :
|
||||
// https://en.wikipedia.org/wiki/Sentinel_node
|
||||
|
||||
#endif
|
||||
|
||||
193
headers/map_iterator.hpp
Normal file
193
headers/map_iterator.hpp
Normal file
@@ -0,0 +1,193 @@
|
||||
#ifndef MAP_ITERATOR_HPP
|
||||
# define MAP_ITERATOR_HPP
|
||||
|
||||
# include <cstddef> // NULL, ptrdiff_t
|
||||
# include <iterator> // iterator_tag
|
||||
|
||||
# include "pair.hpp"
|
||||
# include "map_node.hpp"
|
||||
|
||||
namespace ft {
|
||||
|
||||
template <
|
||||
typename Key,
|
||||
typename T,
|
||||
typename Compare,
|
||||
typename Allocator
|
||||
> class map_iterator {
|
||||
|
||||
private:
|
||||
typedef map_iterator self;
|
||||
|
||||
public:
|
||||
typedef std::bidirectional_iterator_tag iterator_category;
|
||||
typedef pair<const Key, T> value_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef value_type* pointer;
|
||||
typedef value_type& reference;
|
||||
|
||||
map_iterator() : _node(), _sentinel() {}
|
||||
map_iterator(node<value_type>* n, sentinel<value_type>* sentinel)
|
||||
: _node(n), _sentinel(sentinel) {}
|
||||
|
||||
reference operator*() const {
|
||||
return _node->value; }
|
||||
pointer operator->() const {
|
||||
return &_node->value; }
|
||||
|
||||
self& operator++() {
|
||||
if (_node == NULL)
|
||||
_node = _sentinel->child->min();
|
||||
else if (_node->right)
|
||||
_node = _node->right->min();
|
||||
else
|
||||
{
|
||||
node<value_type>* up = _node->up;
|
||||
while (up != NULL && _node == up->right)
|
||||
{
|
||||
_node = up;
|
||||
up = up->up;
|
||||
}
|
||||
_node = up;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
self& operator--() {
|
||||
if (_node == NULL)
|
||||
_node = _sentinel->child->max();
|
||||
else if (_node->left)
|
||||
_node = _node->left->max();
|
||||
else
|
||||
{
|
||||
node<value_type>* up = _node->up;
|
||||
while (up != NULL && _node == up->left)
|
||||
{
|
||||
_node = up;
|
||||
up = up->up;
|
||||
}
|
||||
_node = up;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
self operator++(int) {
|
||||
self old = *this;
|
||||
++(*this);
|
||||
return old;
|
||||
}
|
||||
|
||||
self operator--(int) {
|
||||
self old = *this;
|
||||
--(*this);
|
||||
return old;
|
||||
}
|
||||
|
||||
node<value_type>* get_node() { return _node; }
|
||||
const node<value_type>* get_node() const { return _node; }
|
||||
const sentinel<value_type>* getSentinel() const { return _sentinel; }
|
||||
|
||||
friend bool operator==(const self &lhs, const self &rhs) {
|
||||
return lhs._node == rhs._node; }
|
||||
friend bool operator!=(const self &lhs, const self &rhs) {
|
||||
return !(lhs._node == rhs._node); }
|
||||
|
||||
private:
|
||||
node<value_type>* _node;
|
||||
sentinel<value_type>* _sentinel;
|
||||
};
|
||||
|
||||
template <
|
||||
typename Key,
|
||||
typename T,
|
||||
typename Compare,
|
||||
typename Allocator
|
||||
> class map_const_iterator {
|
||||
|
||||
private:
|
||||
typedef map_const_iterator self;
|
||||
|
||||
public:
|
||||
typedef std::bidirectional_iterator_tag iterator_category;
|
||||
typedef pair<const Key, T> value_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef const value_type* pointer;
|
||||
typedef const value_type& reference;
|
||||
|
||||
map_const_iterator() : _node(), _sentinel() {}
|
||||
map_const_iterator (
|
||||
const node<value_type>* node,
|
||||
const sentinel<value_type>* sentinel)
|
||||
: _node(node), _sentinel(sentinel) {}
|
||||
map_const_iterator (const map_iterator< Key, T, Compare, Allocator >& src)
|
||||
: _node(src.get_node()), _sentinel(src.getSentinel()) {}
|
||||
|
||||
reference operator*() const {
|
||||
return _node->value; }
|
||||
pointer operator->() const {
|
||||
return &_node->value; }
|
||||
|
||||
self& operator++() {
|
||||
if (_node == NULL)
|
||||
_node = _sentinel->child->min();
|
||||
else if (_node->right)
|
||||
_node = _node->right->min();
|
||||
else
|
||||
{
|
||||
node<value_type>* up = _node->up;
|
||||
while (up != NULL && _node == up->right)
|
||||
{
|
||||
_node = up;
|
||||
up = up->up;
|
||||
}
|
||||
_node = up;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
self& operator--() {
|
||||
if (_node == NULL)
|
||||
_node = _sentinel->child->max();
|
||||
else if (_node->left)
|
||||
_node = _node->left->max();
|
||||
else
|
||||
{
|
||||
node<value_type>* up = _node->up;
|
||||
while (up != NULL && _node == up->left)
|
||||
{
|
||||
_node = up;
|
||||
up = up->up;
|
||||
}
|
||||
_node = up;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
self operator++(int) {
|
||||
self old = *this;
|
||||
++(*this);
|
||||
return old;
|
||||
}
|
||||
|
||||
self operator--(int) {
|
||||
self old = *this;
|
||||
--(*this);
|
||||
return old;
|
||||
}
|
||||
|
||||
node<value_type>* get_node() const { return _node; }
|
||||
|
||||
friend bool operator==(const self &lhs, const self &rhs) {
|
||||
return lhs._node == rhs._node; }
|
||||
friend bool operator!=(const self &lhs, const self &rhs) {
|
||||
return !(lhs._node == rhs._node); }
|
||||
|
||||
private:
|
||||
const node<value_type>* _node;
|
||||
const sentinel<value_type>* _sentinel;
|
||||
};
|
||||
|
||||
} // namespace ft
|
||||
|
||||
#endif
|
||||
|
||||
56
headers/map_node.hpp
Normal file
56
headers/map_node.hpp
Normal file
@@ -0,0 +1,56 @@
|
||||
|
||||
#ifndef MAP_NODE_HPP
|
||||
# define MAP_NODE_HPP
|
||||
|
||||
# include <cstddef> // NULL
|
||||
|
||||
namespace ft {
|
||||
|
||||
template < typename ValueType >
|
||||
struct node {
|
||||
|
||||
ValueType value;
|
||||
node *up;
|
||||
node *left;
|
||||
node *right;
|
||||
short height;
|
||||
|
||||
node(const ValueType& val)
|
||||
: value(val)
|
||||
, up(NULL)
|
||||
, left(NULL)
|
||||
, right(NULL)
|
||||
, height(1)
|
||||
{}
|
||||
|
||||
node* min() {
|
||||
|
||||
node* n = this;
|
||||
|
||||
while (n->left)
|
||||
n = n->left;
|
||||
return n;
|
||||
}
|
||||
|
||||
node* max() {
|
||||
|
||||
node* n = this;
|
||||
|
||||
while (n->right)
|
||||
n = n->right;
|
||||
return n;
|
||||
}
|
||||
};
|
||||
|
||||
template < typename ValueType >
|
||||
struct sentinel {
|
||||
|
||||
node<ValueType> *child;
|
||||
|
||||
sentinel() : child(NULL) {}
|
||||
};
|
||||
|
||||
} // namespace ft
|
||||
|
||||
#endif
|
||||
|
||||
86
headers/pair.hpp
Normal file
86
headers/pair.hpp
Normal file
@@ -0,0 +1,86 @@
|
||||
#ifndef PAIR_HPP
|
||||
# define PAIR_HPP
|
||||
|
||||
# define PR_TPL template < class T1, class T2 >
|
||||
# define PR pair<T1, T2>
|
||||
|
||||
namespace ft {
|
||||
|
||||
PR_TPL
|
||||
struct pair {
|
||||
|
||||
typedef T1 first_type;
|
||||
typedef T2 second_type;
|
||||
|
||||
pair();
|
||||
template< typename U, typename V >
|
||||
pair(const pair<U,V>& pr);
|
||||
pair(const first_type& a, const second_type& b);
|
||||
|
||||
T1 first;
|
||||
T2 second;
|
||||
};
|
||||
|
||||
|
||||
/************
|
||||
* copliens :
|
||||
************/
|
||||
PR_TPL PR::
|
||||
pair() {}
|
||||
PR_TPL template< typename U, typename V > PR::
|
||||
pair(const pair<U,V>& pr)
|
||||
: first(pr.first)
|
||||
, second(pr.second) {
|
||||
}
|
||||
PR_TPL PR::
|
||||
pair(const first_type& a, const second_type& b)
|
||||
: first(a)
|
||||
, second(b) {
|
||||
}
|
||||
|
||||
|
||||
|
||||
/************************
|
||||
* non-member functions :
|
||||
************************/
|
||||
PR_TPL
|
||||
bool operator==(const PR& lhs, const PR& rhs) {
|
||||
|
||||
return (lhs.first == rhs.first) && (lhs.second == rhs.second);
|
||||
}
|
||||
PR_TPL
|
||||
bool operator<(const PR& lhs, const PR& rhs) {
|
||||
|
||||
return (lhs.first < rhs.first
|
||||
|| ( !(rhs.first < lhs.first) && (lhs.second < rhs.second) )
|
||||
);
|
||||
}
|
||||
PR_TPL
|
||||
bool operator!=(const PR& lhs, const PR& rhs) {
|
||||
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
PR_TPL
|
||||
bool operator>(const PR& lhs, const PR& rhs) {
|
||||
|
||||
return (rhs < lhs);
|
||||
}
|
||||
PR_TPL
|
||||
bool operator<=(const PR& lhs, const PR& rhs) {
|
||||
|
||||
return !(lhs > rhs);
|
||||
}
|
||||
|
||||
PR_TPL
|
||||
bool operator>=(const PR& lhs, const PR& rhs) {
|
||||
|
||||
return !(lhs < rhs);
|
||||
}
|
||||
|
||||
} // namespace ft
|
||||
|
||||
# undef PR
|
||||
# undef PR_TPL
|
||||
|
||||
#endif
|
||||
|
||||
140
headers/reverse_iterator.hpp
Normal file
140
headers/reverse_iterator.hpp
Normal file
@@ -0,0 +1,140 @@
|
||||
#ifndef REVERSE_ITERATOR_HPP
|
||||
# define REVERSE_ITERATOR_HPP
|
||||
|
||||
# include <iterator> // iterator_tag
|
||||
# include "iterator_traits.hpp"
|
||||
|
||||
namespace ft {
|
||||
|
||||
template < class Iter >
|
||||
class reverse_iterator {
|
||||
|
||||
private:
|
||||
|
||||
Iter _it;
|
||||
typedef ft::iterator_traits<Iter> _traits;
|
||||
|
||||
public:
|
||||
typedef Iter iterator_type;
|
||||
typedef typename _traits::iterator_category iterator_category;
|
||||
typedef typename _traits::value_type value_type;
|
||||
typedef typename _traits::difference_type difference_type;
|
||||
typedef typename _traits::pointer pointer;
|
||||
typedef typename _traits::reference reference;
|
||||
|
||||
|
||||
/****************
|
||||
* constructors :
|
||||
****************/
|
||||
reverse_iterator()
|
||||
: _it()
|
||||
{}
|
||||
explicit reverse_iterator(iterator_type it)
|
||||
: _it(it)
|
||||
{}
|
||||
// reverse_iterator(const reverse_iterator& src)
|
||||
// : _it(src._it)
|
||||
// {}
|
||||
template < class Iterator >
|
||||
reverse_iterator(const reverse_iterator<Iterator>& rev_it)
|
||||
: _it(rev_it.base())
|
||||
{}
|
||||
|
||||
/*********************
|
||||
* members functions :
|
||||
*********************/
|
||||
// base --------------------------------------
|
||||
iterator_type base() const
|
||||
{ return _it; }
|
||||
// operator * --------------------------------
|
||||
reference operator*() const
|
||||
{ Iter tmp = _it; return *--tmp; }
|
||||
// operator + --------------------------------
|
||||
reverse_iterator operator+(difference_type n) const
|
||||
{ return reverse_iterator(_it - n); }
|
||||
// operator ++ -------------------------------
|
||||
reverse_iterator operator++(int)
|
||||
{ reverse_iterator old(*this); ++(*this); return old; }
|
||||
reverse_iterator & operator++()
|
||||
{ --_it; return *this; }
|
||||
// operator += -------------------------------
|
||||
reverse_iterator & operator+=(difference_type n)
|
||||
{ _it -= n; return *this; }
|
||||
// operator - --------------------------------
|
||||
reverse_iterator operator-(difference_type n) const
|
||||
{ return reverse_iterator(_it + n); }
|
||||
// operator -- -------------------------------
|
||||
reverse_iterator operator--(int)
|
||||
{ reverse_iterator old(*this); --(*this); return old; }
|
||||
reverse_iterator & operator--()
|
||||
{ ++_it; return *this; }
|
||||
// operator -= -------------------------------
|
||||
reverse_iterator & operator-=(difference_type n)
|
||||
{ _it += n; return *this; }
|
||||
// operator -> -------------------------------
|
||||
pointer operator->() const
|
||||
{ return &(operator*()); }
|
||||
// operator [] -------------------------------
|
||||
reference operator[] (difference_type n) const
|
||||
{ return _it[-n-1]; }
|
||||
};
|
||||
|
||||
/*************************
|
||||
* non-members functions :
|
||||
*************************/
|
||||
// operator == -------------------------------
|
||||
template <class Iterator>
|
||||
bool operator== (const reverse_iterator<Iterator>& lhs,
|
||||
const reverse_iterator<Iterator>& rhs)
|
||||
{ return lhs.base() == rhs.base(); }
|
||||
// operator != -------------------------------
|
||||
template <class Iterator>
|
||||
bool operator!= (const reverse_iterator<Iterator>& lhs,
|
||||
const reverse_iterator<Iterator>& rhs)
|
||||
{ return lhs.base() != rhs.base(); }
|
||||
// operator < --------------------------------
|
||||
template <class Iterator>
|
||||
bool operator< (const reverse_iterator<Iterator>& lhs,
|
||||
const reverse_iterator<Iterator>& rhs)
|
||||
{ return lhs.base() > rhs.base(); }
|
||||
// operator <= -------------------------------
|
||||
template <class Iterator>
|
||||
bool operator<= (const reverse_iterator<Iterator>& lhs,
|
||||
const reverse_iterator<Iterator>& rhs)
|
||||
{ return lhs.base() >= rhs.base(); }
|
||||
// operator > --------------------------------
|
||||
template <class Iterator>
|
||||
bool operator> (const reverse_iterator<Iterator>& lhs,
|
||||
const reverse_iterator<Iterator>& rhs)
|
||||
{ return lhs.base() < rhs.base(); }
|
||||
// operator >= -------------------------------
|
||||
template <class Iterator>
|
||||
bool operator>= (const reverse_iterator<Iterator>& lhs,
|
||||
const reverse_iterator<Iterator>& rhs)
|
||||
{ return lhs.base() <= rhs.base(); }
|
||||
|
||||
|
||||
/*******************
|
||||
* other operators :
|
||||
*******************/
|
||||
// operator + non-member overload ------------
|
||||
template <class Iterator>
|
||||
reverse_iterator<Iterator> operator+
|
||||
(typename reverse_iterator<Iterator>::difference_type n
|
||||
,const reverse_iterator<Iterator>& rhs)
|
||||
{ return reverse_iterator<Iterator>(rhs.base() - n); }
|
||||
|
||||
// operator - non-member overload ------------
|
||||
template <class Iterator>
|
||||
typename reverse_iterator<Iterator>::difference_type operator-
|
||||
(const reverse_iterator<Iterator>& lhs
|
||||
,const reverse_iterator<Iterator>& rhs)
|
||||
{ return rhs.base() - lhs.base(); }
|
||||
|
||||
|
||||
|
||||
|
||||
} // namespace ft
|
||||
|
||||
#endif
|
||||
|
||||
68
headers/stack.hpp
Normal file
68
headers/stack.hpp
Normal file
@@ -0,0 +1,68 @@
|
||||
|
||||
#ifndef STACK_HPP
|
||||
# define STACK_HPP
|
||||
|
||||
# include "vector.hpp"
|
||||
|
||||
namespace ft {
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename Container = ft::vector<T>
|
||||
> class stack {
|
||||
|
||||
public:
|
||||
typedef Container container_type;
|
||||
typedef typename Container::value_type value_type;
|
||||
typedef typename Container::size_type size_type;
|
||||
|
||||
|
||||
/************
|
||||
* copliens :
|
||||
************/
|
||||
// constructors ------------------------------
|
||||
explicit stack(const container_type& cont = Container());
|
||||
|
||||
|
||||
/**********************
|
||||
* overload functions :
|
||||
**********************/
|
||||
// empty -------------------------------------
|
||||
bool empty() const ;
|
||||
// size --------------------------------------
|
||||
size_type size() const ;
|
||||
// top ---------------------------------------
|
||||
value_type& top();
|
||||
const value_type& top() const ;
|
||||
// push --------------------------------------
|
||||
void push(const value_type& value);
|
||||
// pop ---------------------------------------
|
||||
void pop();
|
||||
|
||||
/*********************************
|
||||
* Relational Operators (friend) :
|
||||
*********************************/
|
||||
template < typename T2, typename C2 >
|
||||
friend bool operator==(const stack<T2,C2>& lhs, const stack<T2,C2>& rhs);
|
||||
template < typename T2, typename C2 >
|
||||
friend bool operator!=(const stack<T2,C2>& lhs, const stack<T2,C2>& rhs);
|
||||
template < typename T2, typename C2 >
|
||||
friend bool operator<(const stack<T2,C2>& lhs, const stack<T2,C2>& rhs);
|
||||
template < typename T2, typename C2 >
|
||||
friend bool operator>(const stack<T2,C2>& lhs, const stack<T2,C2>& rhs);
|
||||
template < typename T2, typename C2 >
|
||||
friend bool operator<=(const stack<T2,C2>& lhs, const stack<T2,C2>& rhs);
|
||||
template < typename T2, typename C2 >
|
||||
friend bool operator>=(const stack<T2,C2>& lhs, const stack<T2,C2>& rhs);
|
||||
|
||||
protected:
|
||||
container_type c;
|
||||
|
||||
};
|
||||
|
||||
} // namespace ft
|
||||
|
||||
# include "stack.tpp"
|
||||
|
||||
#endif
|
||||
|
||||
188
headers/vector.hpp
Normal file
188
headers/vector.hpp
Normal file
@@ -0,0 +1,188 @@
|
||||
#ifndef VECTOR_HPP
|
||||
# define VECTOR_HPP
|
||||
|
||||
# include "colors.h"
|
||||
# include <iostream>
|
||||
# include <string>
|
||||
# include <memory> // std::allocator
|
||||
# include <algorithm> // std::min, std::max
|
||||
# include <stdexcept> // out_of_range, length_error, logic_error
|
||||
# include <cstddef> // NULL, std::size_t, std::ptrdiff_t
|
||||
|
||||
# include "enable_if.hpp"
|
||||
# include "is_integral.hpp"
|
||||
# include "reverse_iterator.hpp"
|
||||
# include "equal.hpp"
|
||||
# include "lexicographical_compare.hpp"
|
||||
|
||||
namespace ft {
|
||||
|
||||
template <
|
||||
class T,
|
||||
class Allocator = std::allocator<T> >
|
||||
class vector {
|
||||
|
||||
public:
|
||||
|
||||
typedef T value_type;
|
||||
typedef Allocator allocator_type;
|
||||
typedef std::size_t size_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
|
||||
typedef T * iterator;
|
||||
typedef T const * const_iterator;
|
||||
typedef ft::reverse_iterator<iterator> reverse_iterator;
|
||||
typedef ft::reverse_iterator<const_iterator> const_reverse_iterator;
|
||||
|
||||
// dependent qualified name :
|
||||
// https://en.cppreference.com/w/cpp/keyword/typename
|
||||
typedef typename Allocator::reference reference;
|
||||
typedef typename Allocator::const_reference const_reference;
|
||||
|
||||
|
||||
|
||||
/************
|
||||
* copliens :
|
||||
************/
|
||||
// constructors ------------------------------
|
||||
explicit vector (const allocator_type & alloc = allocator_type());
|
||||
explicit vector (size_type n, const value_type& val = value_type(),
|
||||
const allocator_type& alloc = allocator_type());
|
||||
template <class InputIterator>
|
||||
vector (InputIterator first, InputIterator last,
|
||||
const allocator_type& alloc = allocator_type());
|
||||
vector( vector const & src );
|
||||
// destructor --------------------------------
|
||||
~vector();
|
||||
// operator= ---------------------------------
|
||||
vector & operator=( vector const & rhs );
|
||||
|
||||
|
||||
/*************
|
||||
* iterators :
|
||||
*************/
|
||||
// begin -------------------------------------
|
||||
iterator begin();
|
||||
const_iterator begin() const;
|
||||
// end ---------------------------------------
|
||||
iterator end();
|
||||
const_iterator end() const;
|
||||
// rbegin ------------------------------------
|
||||
reverse_iterator rbegin();
|
||||
const_reverse_iterator rbegin() const;
|
||||
// rend --------------------------------------
|
||||
reverse_iterator rend();
|
||||
const_reverse_iterator rend() const;
|
||||
|
||||
|
||||
/************
|
||||
* capacity :
|
||||
************/
|
||||
// size --------------------------------------
|
||||
size_type size() const;
|
||||
// max_size ----------------------------------
|
||||
size_type max_size() const;
|
||||
// resize ------------------------------------
|
||||
void resize(size_type n, value_type val = value_type());
|
||||
// capacity ----------------------------------
|
||||
size_type capacity() const;
|
||||
// empty -------------------------------------
|
||||
bool empty() const;
|
||||
// reserve -----------------------------------
|
||||
void reserve(size_type n);
|
||||
|
||||
|
||||
/******************
|
||||
* element access :
|
||||
******************/
|
||||
// operator[] --------------------------------
|
||||
reference operator[](size_type n);
|
||||
const_reference operator[](size_type n) const;
|
||||
// at ----------------------------------------
|
||||
reference at(size_type n);
|
||||
const_reference at(size_type n) const;
|
||||
// front -------------------------------------
|
||||
reference front();
|
||||
const_reference front() const;
|
||||
// back --------------------------------------
|
||||
reference back();
|
||||
const_reference back() const;
|
||||
|
||||
|
||||
/*************
|
||||
* modifiers :
|
||||
*************/
|
||||
// assign ------------------------------------
|
||||
template <class InputIterator>
|
||||
typename enable_if< !is_integral<InputIterator>::value,void >::type
|
||||
assign(InputIterator first, InputIterator last);
|
||||
void assign(size_type n, const value_type& val);
|
||||
// push_back ---------------------------------
|
||||
void push_back(const value_type & val);
|
||||
// pop_back ----------------------------------
|
||||
void pop_back();
|
||||
// insert ------------------------------------
|
||||
iterator insert(iterator position, const value_type& val);
|
||||
void insert(iterator position, size_type n, const value_type& val);
|
||||
template <class InputIterator>
|
||||
typename enable_if< !is_integral<InputIterator>::value,void >::type
|
||||
insert(iterator position, InputIterator first, InputIterator last);
|
||||
// erase -------------------------------------
|
||||
iterator erase(iterator position);
|
||||
iterator erase(iterator first, iterator last);
|
||||
// swap --------------------------------------
|
||||
void swap(vector& x);
|
||||
// clear -------------------------------------
|
||||
void clear();
|
||||
|
||||
|
||||
/*************
|
||||
* allocator :
|
||||
*************/
|
||||
// get_allocator -----------------------------
|
||||
allocator_type get_allocator() const;
|
||||
|
||||
private:
|
||||
|
||||
size_type _size;
|
||||
size_type _capacity;
|
||||
value_type * _mem_ptr;
|
||||
allocator_type _allocator;
|
||||
|
||||
void _destroy(iterator first, iterator last);
|
||||
void _increment_capacity(size_type n);
|
||||
|
||||
};
|
||||
|
||||
|
||||
/************************
|
||||
* non-member functions :
|
||||
************************/
|
||||
// operator == -------------------------------
|
||||
template <class T, class Alloc>
|
||||
bool operator== (const vector<T,Alloc>& lhs, const vector<T,Alloc>& rhs);
|
||||
// operator != -------------------------------
|
||||
template <class T, class Alloc>
|
||||
bool operator!= (const vector<T,Alloc>& lhs, const vector<T,Alloc>& rhs);
|
||||
// operator < --------------------------------
|
||||
template <class T, class Alloc>
|
||||
bool operator< (const vector<T,Alloc>& lhs, const vector<T,Alloc>& rhs);
|
||||
// operator <= -------------------------------
|
||||
template <class T, class Alloc>
|
||||
bool operator<= (const vector<T,Alloc>& lhs, const vector<T,Alloc>& rhs);
|
||||
// operator > --------------------------------
|
||||
template <class T, class Alloc>
|
||||
bool operator> (const vector<T,Alloc>& lhs, const vector<T,Alloc>& rhs);
|
||||
// operator >= -------------------------------
|
||||
template <class T, class Alloc>
|
||||
bool operator>= (const vector<T,Alloc>& lhs, const vector<T,Alloc>& rhs);
|
||||
// swap (vector) -----------------------------
|
||||
template <class T, class Alloc>
|
||||
void swap (vector<T,Alloc>& x, vector<T,Alloc>& y);
|
||||
|
||||
|
||||
} // namespace ft
|
||||
|
||||
# include "vector.tpp"
|
||||
|
||||
#endif
|
||||
575
templates/map.tpp
Normal file
575
templates/map.tpp
Normal file
@@ -0,0 +1,575 @@
|
||||
|
||||
#define MP_TPL template < typename Key, typename T, typename Compare, typename Allocator >
|
||||
#define MP map<Key, T, Compare, Allocator>
|
||||
|
||||
namespace ft {
|
||||
|
||||
|
||||
/************
|
||||
* copliens :
|
||||
************/
|
||||
// constructors ------------------------------
|
||||
MP_TPL MP::
|
||||
map (const key_compare & comp, const allocator_type & alloc)
|
||||
: _size(0)
|
||||
, _root(NULL)
|
||||
, _comp(comp)
|
||||
, _allocator(alloc) {
|
||||
|
||||
_sentinel = _allocator_sentinel.allocate(1);
|
||||
_allocator_sentinel.construct(_sentinel, sentinel<value_type>());
|
||||
}
|
||||
MP_TPL template < typename InputIt > MP::
|
||||
map (InputIt first, InputIt last, const key_compare& comp, const allocator_type& alloc)
|
||||
: _size(0)
|
||||
, _root(NULL)
|
||||
, _comp(comp)
|
||||
, _allocator(alloc) {
|
||||
|
||||
_sentinel = _allocator_sentinel.allocate(1);
|
||||
_allocator_sentinel.construct(_sentinel, sentinel<value_type>());
|
||||
insert(first, last);
|
||||
}
|
||||
MP_TPL MP::
|
||||
map(const map& src)
|
||||
: _size(0)
|
||||
, _root(NULL)
|
||||
, _comp(src._comp)
|
||||
, _allocator(src._allocator) {
|
||||
|
||||
_sentinel = _allocator_sentinel.allocate(1);
|
||||
_allocator_sentinel.construct(_sentinel, sentinel<value_type>());
|
||||
*this = src;
|
||||
}
|
||||
// destructor --------------------------------
|
||||
MP_TPL MP::
|
||||
~map() {
|
||||
|
||||
clear();
|
||||
_allocator_sentinel.destroy(_sentinel);
|
||||
_allocator_sentinel.deallocate(_sentinel, 1);
|
||||
}
|
||||
// operator= ---------------------------------
|
||||
MP_TPL MP& MP::
|
||||
operator=(const map& rhs) {
|
||||
|
||||
if (this == &rhs)
|
||||
return (*this);
|
||||
map new_bst(rhs.begin(), rhs.end());
|
||||
swap(new_bst);
|
||||
return (*this);
|
||||
}
|
||||
|
||||
|
||||
/*************
|
||||
* iterators :
|
||||
*************/
|
||||
// begin -------------------------------------
|
||||
MP_TPL typename MP::iterator MP::
|
||||
begin() {
|
||||
|
||||
if (_root)
|
||||
return iterator(_root->min(), _sentinel);
|
||||
else
|
||||
return end();
|
||||
}
|
||||
MP_TPL typename MP::const_iterator MP::
|
||||
begin() const {
|
||||
|
||||
if (_root)
|
||||
return const_iterator(_root->min(), _sentinel);
|
||||
else
|
||||
return end();
|
||||
}
|
||||
// end ---------------------------------------
|
||||
MP_TPL typename MP::iterator MP::
|
||||
end() { return iterator(NULL, _sentinel); }
|
||||
MP_TPL typename MP::const_iterator MP::
|
||||
end() const { return const_iterator(NULL, _sentinel); }
|
||||
// rbegin ------------------------------------
|
||||
MP_TPL typename MP::reverse_iterator MP::
|
||||
rbegin() { return reverse_iterator(end()); }
|
||||
MP_TPL typename MP::const_reverse_iterator MP::
|
||||
rbegin() const { return const_reverse_iterator(end()); }
|
||||
// rend --------------------------------------
|
||||
MP_TPL typename MP::reverse_iterator MP::
|
||||
rend() { return reverse_iterator(begin()); }
|
||||
MP_TPL typename MP::const_reverse_iterator MP::
|
||||
rend() const { return const_reverse_iterator(begin()); }
|
||||
|
||||
|
||||
/************
|
||||
* capacity :
|
||||
************/
|
||||
// empty -------------------------------------
|
||||
MP_TPL bool MP::
|
||||
empty() const { return (_size == 0); }
|
||||
// size --------------------------------------
|
||||
MP_TPL typename MP::size_type MP::
|
||||
size() const { return (_size); }
|
||||
// max_size ----------------------------------
|
||||
MP_TPL typename MP::size_type MP::
|
||||
max_size() const { return ( _allocator_node.max_size() ); }
|
||||
|
||||
|
||||
/******************
|
||||
* element access :
|
||||
******************/
|
||||
// operator[] --------------------------------
|
||||
MP_TPL typename MP::mapped_type& MP::
|
||||
operator[](const Key& key) {
|
||||
|
||||
node<value_type>* n = _root;
|
||||
|
||||
while (n)
|
||||
{
|
||||
if (_comp(key, n->value.first))
|
||||
n = n->left;
|
||||
else if (_comp(n->value.first, key))
|
||||
n = n->right;
|
||||
else
|
||||
return (n->value.second);
|
||||
}
|
||||
|
||||
n = insert( ft::make_pair(key, mapped_type()) ).first.get_node();
|
||||
|
||||
return (n->value.second);
|
||||
}
|
||||
|
||||
|
||||
/*************
|
||||
* modifiers :
|
||||
*************/
|
||||
// insert ------------------------------------
|
||||
MP_TPL pair<typename MP::iterator, bool> MP::
|
||||
insert(const value_type& value) {
|
||||
|
||||
node<value_type>* n = _root;
|
||||
node<value_type>* next = n;
|
||||
|
||||
while (next != NULL)
|
||||
{
|
||||
if (value.first == n->value.first)
|
||||
return ft::make_pair(iterator(n, _sentinel), false);
|
||||
n = next;
|
||||
if (_comp(value.first, n->value.first))
|
||||
next = n->left;
|
||||
else if (_comp(n->value.first, value.first))
|
||||
next = n->right;
|
||||
}
|
||||
|
||||
next = _allocator_node.allocate(1);
|
||||
_allocator_node.construct(next, node<value_type>(value));
|
||||
|
||||
if (_root == NULL)
|
||||
{
|
||||
_root = next;
|
||||
_sentinel->child = next;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_comp(value.first, n->value.first))
|
||||
n->left = next;
|
||||
else if (_comp(n->value.first, value.first))
|
||||
n->right = next;
|
||||
}
|
||||
next->up = n;
|
||||
_size++;
|
||||
|
||||
_balance(n);
|
||||
return (ft::make_pair(iterator(next, _sentinel), true));
|
||||
}
|
||||
MP_TPL typename MP::iterator MP::
|
||||
insert(iterator hint, const value_type& value) {
|
||||
|
||||
(void)hint;
|
||||
return insert(value).first;
|
||||
}
|
||||
MP_TPL template < typename InputIt > void MP::
|
||||
insert(InputIt first, InputIt last) {
|
||||
|
||||
for (; first != last; first++)
|
||||
insert(*first);
|
||||
}
|
||||
// erase -------------------------------------
|
||||
// https://www.geeksforgeeks.org/binary-search-tree-set-2-delete
|
||||
MP_TPL void MP::
|
||||
erase(iterator pos) {
|
||||
|
||||
node<value_type>* n = pos.get_node();
|
||||
node<value_type>* replace = NULL;
|
||||
|
||||
if (n->left && n->right)
|
||||
{
|
||||
replace = n->right->min();
|
||||
|
||||
replace->left = n->left;
|
||||
replace->left->up = replace;
|
||||
if (replace->up != n)
|
||||
{
|
||||
replace->up->left = replace->right;
|
||||
if (replace->right != NULL)
|
||||
replace->right->up = replace->up;
|
||||
replace->right = n->right;
|
||||
replace->right->up = replace;
|
||||
}
|
||||
}
|
||||
else if (n->left)
|
||||
replace = n->left;
|
||||
else if (n->right)
|
||||
replace = n->right;
|
||||
else
|
||||
replace = NULL;
|
||||
|
||||
// share parents from n to replace
|
||||
if (n == _root)
|
||||
{
|
||||
_root = replace;
|
||||
_sentinel->child = _root;
|
||||
}
|
||||
else if (n == n->up->left)
|
||||
n->up->left = replace;
|
||||
else
|
||||
n->up->right = replace;
|
||||
if (replace != NULL)
|
||||
replace->up = n->up;
|
||||
|
||||
_allocator_node.destroy(n);
|
||||
_allocator_node.deallocate(n, 1);
|
||||
_size--;
|
||||
|
||||
_balance(replace);
|
||||
}
|
||||
MP_TPL void MP::
|
||||
erase(iterator first, iterator last) {
|
||||
|
||||
while (first != last)
|
||||
erase(first++);
|
||||
}
|
||||
MP_TPL typename MP::size_type MP::
|
||||
erase(const Key& key) {
|
||||
|
||||
iterator pos;
|
||||
|
||||
pos = find(key);
|
||||
if (pos == end())
|
||||
return (0);
|
||||
erase(pos);
|
||||
return (1);
|
||||
}
|
||||
// swap --------------------------------------
|
||||
MP_TPL void MP::
|
||||
swap(map& other) {
|
||||
|
||||
node<value_type>* tmp_root = _root;
|
||||
sentinel<value_type>* tmp_sentinel = _sentinel;
|
||||
size_type tmp_size = _size;
|
||||
|
||||
_root = other._root;
|
||||
_sentinel = other._sentinel;
|
||||
_size = other._size;
|
||||
|
||||
other._root = tmp_root;
|
||||
other._sentinel = tmp_sentinel;
|
||||
other._size = tmp_size;
|
||||
}
|
||||
// clear -------------------------------------
|
||||
MP_TPL void MP::
|
||||
clear() { erase(begin(), end()); }
|
||||
|
||||
|
||||
/*************
|
||||
* observers :
|
||||
*************/
|
||||
// key_comp ----------------------------------
|
||||
MP_TPL typename MP::key_compare MP::
|
||||
key_comp() const { return (value_compare(_comp).comp); }
|
||||
// value_comp --------------------------------
|
||||
MP_TPL typename MP::value_compare MP::
|
||||
value_comp() const { return (value_compare(_comp)); }
|
||||
|
||||
|
||||
/**************
|
||||
* operations :
|
||||
**************/
|
||||
// find --------------------------------------
|
||||
MP_TPL typename MP::iterator MP::
|
||||
find(const Key& key) {
|
||||
|
||||
node<value_type>* n = _root;
|
||||
|
||||
while (n)
|
||||
{
|
||||
if (_comp(key, n->value.first))
|
||||
n = n->left;
|
||||
else if (_comp(n->value.first, key))
|
||||
n = n->right;
|
||||
else
|
||||
return (iterator(n, _sentinel));
|
||||
}
|
||||
return (end());
|
||||
}
|
||||
MP_TPL typename MP::const_iterator MP::
|
||||
find(const Key& key) const {
|
||||
|
||||
node<value_type>* n = _root;
|
||||
|
||||
while (n)
|
||||
{
|
||||
if (_comp(key, n->value.first))
|
||||
n = n->left;
|
||||
else if (_comp(n->value.first, key))
|
||||
n = n->right;
|
||||
else
|
||||
return (const_iterator(n, _sentinel));
|
||||
}
|
||||
return (end());
|
||||
}
|
||||
// count -------------------------------------
|
||||
MP_TPL typename MP::size_type MP::
|
||||
count(const Key& key) const {
|
||||
|
||||
if (find(key) != end())
|
||||
return (1);
|
||||
else
|
||||
return (0);
|
||||
}
|
||||
// lower_bound -------------------------------
|
||||
MP_TPL typename MP::iterator MP::
|
||||
lower_bound (const key_type& k) {
|
||||
|
||||
iterator it = begin();
|
||||
iterator it_end = end();
|
||||
|
||||
while (it != it_end)
|
||||
{
|
||||
if (_comp(it->first, k) == false)
|
||||
return (it);
|
||||
++it;
|
||||
}
|
||||
return (it_end);
|
||||
}
|
||||
MP_TPL typename MP::const_iterator MP::
|
||||
lower_bound (const key_type& k) const {
|
||||
|
||||
const_iterator it = begin();
|
||||
const_iterator it_end = end();
|
||||
|
||||
while (it != it_end)
|
||||
{
|
||||
if (_comp(it->first, k) == false)
|
||||
return (it);
|
||||
++it;
|
||||
}
|
||||
return (it_end);
|
||||
}
|
||||
// upper_bound -------------------------------
|
||||
MP_TPL typename MP::iterator MP::
|
||||
upper_bound (const key_type& k) {
|
||||
|
||||
iterator it = begin();
|
||||
iterator it_end = end();
|
||||
|
||||
while (it != it_end)
|
||||
{
|
||||
if (_comp(k, it->first))
|
||||
return (it);
|
||||
++it;
|
||||
}
|
||||
return (it_end);
|
||||
}
|
||||
MP_TPL typename MP::const_iterator MP::
|
||||
upper_bound (const key_type& k) const {
|
||||
|
||||
const_iterator it = begin();
|
||||
const_iterator it_end = end();
|
||||
|
||||
while (it != it_end)
|
||||
{
|
||||
if (_comp(k, it->first))
|
||||
return (it);
|
||||
++it;
|
||||
}
|
||||
return (it_end);
|
||||
}
|
||||
// equal_range -------------------------------
|
||||
MP_TPL pair<typename MP::const_iterator, typename MP::const_iterator> MP::
|
||||
equal_range (const key_type& k) const {
|
||||
|
||||
return ft::make_pair( lower_bound(k), upper_bound(k) );
|
||||
}
|
||||
MP_TPL pair<typename MP::iterator, typename MP::iterator> MP::
|
||||
equal_range (const key_type& k) {
|
||||
|
||||
return ft::make_pair( lower_bound(k), upper_bound(k) );
|
||||
}
|
||||
|
||||
|
||||
/*************
|
||||
* allocator :
|
||||
*************/
|
||||
// get_allocator -----------------------------
|
||||
MP_TPL typename MP::allocator_type MP::
|
||||
get_allocator() const { return (_allocator); }
|
||||
|
||||
|
||||
/*********************
|
||||
* private functions :
|
||||
*********************/
|
||||
MP_TPL void MP::
|
||||
_balance(node<value_type>* n) {
|
||||
|
||||
node<value_type>* old_n;
|
||||
node<value_type>* parent = NULL;
|
||||
|
||||
while (n)
|
||||
{
|
||||
n->height = _compute_height(n);
|
||||
|
||||
if (_balance_factor(n) > 1) // Left Heavy
|
||||
{
|
||||
parent = n->up;
|
||||
if (_balance_factor(n->left) < 0) // Left-Right Case (BF == -1)
|
||||
n->left = _rotate_left(n->left);
|
||||
// Left-Left Case
|
||||
n = _rotate_right(n);
|
||||
old_n = n->right;
|
||||
}
|
||||
else if (_balance_factor(n) < -1) // Right Heavy
|
||||
{
|
||||
parent = n->up;
|
||||
if (_balance_factor(n->right) > 0) // Right-Left Case (BF == 1)
|
||||
n->right = _rotate_right(n->right);
|
||||
// Right-Right Case
|
||||
n = _rotate_left(n);
|
||||
old_n = n->left;
|
||||
}
|
||||
|
||||
if (parent)
|
||||
{
|
||||
if (parent->left == old_n)
|
||||
parent->left = n;
|
||||
else
|
||||
parent->right = n;
|
||||
parent = NULL;
|
||||
}
|
||||
|
||||
n = n->up;
|
||||
}
|
||||
}
|
||||
MP_TPL short MP::
|
||||
_compute_height(node<value_type>* n) {
|
||||
|
||||
if (n->left && n->right)
|
||||
return std::max(n->left->height, n->right->height) + 1;
|
||||
else if (n->left)
|
||||
return n->left->height + 1;
|
||||
else if (n->right)
|
||||
return n->right->height + 1;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
MP_TPL short MP::
|
||||
_balance_factor(node<value_type>* n) {
|
||||
|
||||
if (n->left && n->right)
|
||||
return n->left->height - n->right->height;
|
||||
else if (n->left)
|
||||
return n->left->height;
|
||||
else if (n->right)
|
||||
return (-(n->right->height));
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
MP_TPL node<typename MP::value_type>* MP::
|
||||
_rotate_left(node<value_type>* n) {
|
||||
|
||||
node<value_type>* ori_right = n->right;
|
||||
|
||||
ori_right->up = n->up;
|
||||
n->up = ori_right;
|
||||
|
||||
n->right = ori_right->left;
|
||||
if (n->right != NULL)
|
||||
n->right->up = n;
|
||||
ori_right->left = n;
|
||||
|
||||
n->height = _compute_height(n);
|
||||
ori_right->height = _compute_height(ori_right);
|
||||
|
||||
if (n == _root)
|
||||
{
|
||||
_root = ori_right;
|
||||
_sentinel->child = _root;
|
||||
}
|
||||
|
||||
return ori_right;
|
||||
}
|
||||
MP_TPL node<typename MP::value_type>* MP::
|
||||
_rotate_right(node<value_type>* n) {
|
||||
|
||||
node<value_type>* ori_left = n->left;
|
||||
|
||||
ori_left->up = n->up;
|
||||
n->up = ori_left;
|
||||
|
||||
n->left = ori_left->right;
|
||||
if (n->left != NULL)
|
||||
n->left->up = n;
|
||||
ori_left->right = n;
|
||||
|
||||
n->height = _compute_height(n);
|
||||
ori_left->height = _compute_height(ori_left);
|
||||
|
||||
if (n == _root)
|
||||
{
|
||||
_root = ori_left;
|
||||
_sentinel->child = _root;
|
||||
}
|
||||
|
||||
return ori_left;
|
||||
}
|
||||
|
||||
|
||||
/************************
|
||||
* non-member functions :
|
||||
************************/
|
||||
// operator == -------------------------------
|
||||
MP_TPL bool operator== (const MP& lhs, const MP& rhs) {
|
||||
|
||||
if (lhs.size() != rhs.size())
|
||||
return false;
|
||||
return ft::equal(lhs.begin(), lhs.end(), rhs.begin());
|
||||
}
|
||||
// operator < --------------------------------
|
||||
MP_TPL bool operator< (const MP& lhs, const MP& rhs) {
|
||||
|
||||
return ft::lexicographical_compare(
|
||||
lhs.begin(),
|
||||
lhs.end(),
|
||||
rhs.begin(),
|
||||
rhs.end()
|
||||
);
|
||||
}
|
||||
// operator != -------------------------------
|
||||
MP_TPL bool operator!= (const MP& lhs, const MP& rhs) {
|
||||
return !(lhs == rhs); }
|
||||
// operator <= -------------------------------
|
||||
MP_TPL bool operator<= (const MP& lhs, const MP& rhs) {
|
||||
return !(lhs > rhs); }
|
||||
// operator > --------------------------------
|
||||
MP_TPL bool operator> (const MP& lhs, const MP& rhs) {
|
||||
return (rhs < lhs); }
|
||||
// operator >= -------------------------------
|
||||
MP_TPL bool operator>= (const MP& lhs, const MP& rhs) {
|
||||
return !(lhs < rhs); }
|
||||
// swap (map) -----------------------------
|
||||
MP_TPL void swap(MP& lhs, MP& rhs) {
|
||||
lhs.swap(rhs); }
|
||||
|
||||
|
||||
} // namespace ft
|
||||
|
||||
#undef MP
|
||||
#undef MP_TPL
|
||||
|
||||
72
templates/stack.tpp
Normal file
72
templates/stack.tpp
Normal file
@@ -0,0 +1,72 @@
|
||||
|
||||
#define ST_TPL template <class T, class Container>
|
||||
#define ST stack<T, Container>
|
||||
|
||||
namespace ft {
|
||||
|
||||
|
||||
/************
|
||||
* copliens :
|
||||
************/
|
||||
// constructors ------------------------------
|
||||
ST_TPL ST::
|
||||
stack(const container_type& cont)
|
||||
: c(cont) {}
|
||||
|
||||
|
||||
/**********************
|
||||
* overload functions :
|
||||
**********************/
|
||||
// empty -------------------------------------
|
||||
ST_TPL bool ST::
|
||||
empty() const { return c.empty(); }
|
||||
// size --------------------------------------
|
||||
ST_TPL typename ST::size_type ST::
|
||||
size() const { return c.size(); }
|
||||
// top ---------------------------------------
|
||||
ST_TPL typename ST::value_type& ST::
|
||||
top() { return c.back(); }
|
||||
ST_TPL const typename ST::value_type& ST::
|
||||
top() const { return c.back(); }
|
||||
// push --------------------------------------
|
||||
ST_TPL void ST::
|
||||
push(const value_type& value) { c.push_back(value); }
|
||||
// pop ---------------------------------------
|
||||
ST_TPL void ST::
|
||||
pop() { c.pop_back(); }
|
||||
|
||||
|
||||
/************************
|
||||
* non-member functions :
|
||||
************************/
|
||||
// operator == -------------------------------
|
||||
ST_TPL bool
|
||||
operator==(const stack<T, Container>& lhs, const stack<T, Container>& rhs)
|
||||
{ return lhs.c == rhs.c; }
|
||||
// operator != -------------------------------
|
||||
ST_TPL bool
|
||||
operator!=(const stack<T, Container>& lhs, const stack<T, Container>& rhs)
|
||||
{ return lhs.c != rhs.c; }
|
||||
// operator < --------------------------------
|
||||
ST_TPL bool
|
||||
operator<(const stack<T, Container>& lhs, const stack<T, Container>& rhs)
|
||||
{ return lhs.c < rhs.c; }
|
||||
// operator > --------------------------------
|
||||
ST_TPL bool
|
||||
operator>(const stack<T, Container>& lhs, const stack<T, Container>& rhs)
|
||||
{ return lhs.c > rhs.c; }
|
||||
// operator <= -------------------------------
|
||||
ST_TPL bool
|
||||
operator<=(const stack<T, Container>& lhs, const stack<T, Container>& rhs)
|
||||
{ return lhs.c <= rhs.c; }
|
||||
// operator >= -------------------------------
|
||||
ST_TPL bool
|
||||
operator>=(const stack<T, Container>& lhs, const stack<T, Container>& rhs)
|
||||
{ return lhs.c >= rhs.c; }
|
||||
|
||||
|
||||
} // namespace ft
|
||||
|
||||
#undef VT
|
||||
#undef VT_TPL
|
||||
|
||||
497
templates/vector.tpp
Normal file
497
templates/vector.tpp
Normal file
@@ -0,0 +1,497 @@
|
||||
|
||||
#define VT_TPL template <class T, class Allocator>
|
||||
#define VT vector<T, Allocator>
|
||||
|
||||
namespace ft {
|
||||
|
||||
|
||||
/*********************************************
|
||||
* COPLIENS
|
||||
*********************************************/
|
||||
// constructors ------------------------------
|
||||
VT_TPL VT::
|
||||
vector( const Allocator & alloc )
|
||||
: _size(0)
|
||||
, _capacity(0)
|
||||
, _mem_ptr(NULL)
|
||||
, _allocator(alloc) {
|
||||
|
||||
return;
|
||||
}
|
||||
VT_TPL VT::
|
||||
vector( size_type n, const T & val, const Allocator & alloc )
|
||||
: _size(0)
|
||||
, _capacity(0)
|
||||
, _mem_ptr(NULL)
|
||||
, _allocator(alloc) {
|
||||
|
||||
assign(n, val);
|
||||
return;
|
||||
}
|
||||
VT_TPL template <class InputIterator> VT::
|
||||
vector(InputIterator first, InputIterator last, const Allocator & alloc)
|
||||
: _size(0)
|
||||
, _capacity(0)
|
||||
, _mem_ptr(NULL)
|
||||
, _allocator(alloc) {
|
||||
|
||||
assign(first, last);
|
||||
return;
|
||||
}
|
||||
// copy constructor --------------------------
|
||||
VT_TPL VT::
|
||||
vector( vector const & src )
|
||||
: _size(0)
|
||||
, _capacity(0)
|
||||
, _mem_ptr(NULL)
|
||||
, _allocator(src._allocator) {
|
||||
|
||||
*this = src;
|
||||
return;
|
||||
}
|
||||
// destructors -------------------------------
|
||||
VT_TPL VT::
|
||||
~vector() {
|
||||
|
||||
clear();
|
||||
_allocator.deallocate(_mem_ptr, _capacity);
|
||||
return;
|
||||
}
|
||||
// operator= ---------------------------------
|
||||
VT_TPL VT & VT::
|
||||
operator=( vector const & rhs ) {
|
||||
|
||||
vector new_vector;
|
||||
|
||||
if ( this != &rhs )
|
||||
{
|
||||
new_vector.reserve(_capacity);
|
||||
new_vector.assign(rhs.begin(), rhs.end());
|
||||
swap(new_vector);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************
|
||||
* iterators :
|
||||
*************/
|
||||
// begin -------------------------------------
|
||||
VT_TPL typename VT::iterator VT::
|
||||
begin() { return _mem_ptr; }
|
||||
VT_TPL typename VT::const_iterator VT::
|
||||
begin() const { return _mem_ptr; }
|
||||
// end ---------------------------------------
|
||||
VT_TPL typename VT::iterator VT::
|
||||
end() { return &_mem_ptr[_size]; }
|
||||
VT_TPL typename VT::const_iterator VT::
|
||||
end() const { return &_mem_ptr[_size]; }
|
||||
// rbegin ------------------------------------
|
||||
VT_TPL typename VT::reverse_iterator VT::
|
||||
rbegin() { return reverse_iterator(end()); }
|
||||
VT_TPL typename VT::const_reverse_iterator VT::
|
||||
rbegin() const { return const_reverse_iterator(end()); }
|
||||
// rend --------------------------------------
|
||||
VT_TPL typename VT::reverse_iterator VT::
|
||||
rend() { return reverse_iterator(begin()); }
|
||||
VT_TPL typename VT::const_reverse_iterator VT::
|
||||
rend() const { return const_reverse_iterator(begin()); }
|
||||
|
||||
|
||||
|
||||
/************
|
||||
* capacity :
|
||||
************/
|
||||
// size --------------------------------------
|
||||
VT_TPL typename VT::size_type VT::
|
||||
size( ) const { return _size; }
|
||||
// max_size ----------------------------------
|
||||
VT_TPL typename VT::size_type VT::
|
||||
max_size() const { return (_allocator.max_size()); }
|
||||
// resize ------------------------------------
|
||||
VT_TPL void VT::
|
||||
resize(size_type n, value_type val) {
|
||||
|
||||
if (n > _size)
|
||||
{
|
||||
if (n > _capacity)
|
||||
_increment_capacity(n);
|
||||
while (_size != n)
|
||||
{
|
||||
_allocator.construct(&_mem_ptr[_size], val);
|
||||
++_size;
|
||||
}
|
||||
}
|
||||
else if (n < _size)
|
||||
{
|
||||
while (_size != n)
|
||||
_allocator.destroy(&_mem_ptr[--_size]);
|
||||
}
|
||||
}
|
||||
// capacity ----------------------------------
|
||||
VT_TPL typename VT::size_type VT::
|
||||
capacity() const { return _capacity; }
|
||||
// empty -------------------------------------
|
||||
VT_TPL bool VT::
|
||||
empty() const { return (_size == 0); }
|
||||
// reserve -----------------------------------
|
||||
VT_TPL void VT::
|
||||
reserve( size_type new_cap ) {
|
||||
|
||||
value_type * tmp_ptr;
|
||||
value_type * old_ptr = _mem_ptr;
|
||||
iterator first = begin();
|
||||
iterator last = end();
|
||||
|
||||
if (new_cap > _allocator.max_size())
|
||||
throw std::length_error("reserve: new_cap > max_size");
|
||||
if (_capacity == _allocator.max_size())
|
||||
throw std::length_error("reserve: capacity == max_size");
|
||||
if (new_cap <= _capacity)
|
||||
return ;
|
||||
|
||||
_capacity = new_cap;
|
||||
tmp_ptr = _allocator.allocate(new_cap);
|
||||
|
||||
_mem_ptr = tmp_ptr;
|
||||
if (old_ptr)
|
||||
{
|
||||
_size = 0;
|
||||
assign(first, last);
|
||||
_destroy(begin(), end());
|
||||
_allocator.deallocate(old_ptr, _capacity);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/******************
|
||||
* element access :
|
||||
******************/
|
||||
// operator[] --------------------------------
|
||||
VT_TPL typename VT::reference VT::
|
||||
operator[](size_type n) { return _mem_ptr[n]; }
|
||||
VT_TPL typename VT::const_reference VT::
|
||||
operator[](size_type n) const { return _mem_ptr[n]; }
|
||||
// at ----------------------------------------
|
||||
VT_TPL typename VT::reference VT::
|
||||
at(size_type n) {
|
||||
|
||||
if (n >= _size)
|
||||
throw std::out_of_range("vector out of range");
|
||||
return (_mem_ptr[n]);
|
||||
}
|
||||
VT_TPL typename VT::const_reference VT::
|
||||
at(size_type n) const {
|
||||
|
||||
if (n >= _size)
|
||||
throw std::out_of_range("vector out of range");
|
||||
return (_mem_ptr[n]);
|
||||
}
|
||||
// front -------------------------------------
|
||||
VT_TPL typename VT::reference VT::
|
||||
front() { return (*_mem_ptr); }
|
||||
VT_TPL typename VT::const_reference VT::
|
||||
front() const { return (*_mem_ptr); }
|
||||
// back --------------------------------------
|
||||
VT_TPL typename VT::reference VT::
|
||||
back() { return (_mem_ptr[_size - 1]); }
|
||||
VT_TPL typename VT::const_reference VT::
|
||||
back() const { return (_mem_ptr[_size - 1]); }
|
||||
|
||||
|
||||
|
||||
/*************
|
||||
* modifiers :
|
||||
*************/
|
||||
// assign ------------------------------------
|
||||
VT_TPL template <class InputIterator>
|
||||
typename enable_if< !is_integral<InputIterator>::value,void >::type VT::
|
||||
assign( InputIterator first, InputIterator last) {
|
||||
|
||||
InputIterator tmp = first;
|
||||
unsigned int range = 0;
|
||||
|
||||
clear();
|
||||
|
||||
while (tmp++ != last)
|
||||
range++;
|
||||
if (range >= _capacity)
|
||||
_increment_capacity(range);
|
||||
while (first != last)
|
||||
{
|
||||
_allocator.construct(&_mem_ptr[_size], *first);
|
||||
first++;
|
||||
_size++;
|
||||
}
|
||||
}
|
||||
VT_TPL void VT::
|
||||
assign( size_type n, const T & val ) {
|
||||
|
||||
if (n > _allocator.max_size())
|
||||
throw std::length_error("assign: n > max_size");
|
||||
|
||||
value_type * tmp_ptr;
|
||||
|
||||
_destroy(begin(), end());
|
||||
if (n > _capacity)
|
||||
{
|
||||
_capacity = n;
|
||||
tmp_ptr = _allocator.allocate(n);
|
||||
if (_mem_ptr)
|
||||
_allocator.deallocate(_mem_ptr, _capacity);
|
||||
_mem_ptr = tmp_ptr;
|
||||
}
|
||||
_size = n;
|
||||
while (n)
|
||||
_allocator.construct(&_mem_ptr[--n], val);
|
||||
}
|
||||
// push_back ---------------------------------
|
||||
VT_TPL void VT::
|
||||
push_back( const value_type & element ) {
|
||||
|
||||
if (_size >= _capacity)
|
||||
_increment_capacity(1);
|
||||
_allocator.construct(&_mem_ptr[_size], element);
|
||||
_size++;
|
||||
}
|
||||
// pop_back ----------------------------------
|
||||
VT_TPL void VT::
|
||||
pop_back() { _allocator.destroy(end() - 1); _size--; }
|
||||
// insert ------------------------------------
|
||||
VT_TPL typename VT::iterator VT::
|
||||
insert(iterator position, const value_type& val) {
|
||||
|
||||
difference_type distance;
|
||||
iterator it;
|
||||
|
||||
if (_size + 1 > _capacity)
|
||||
{
|
||||
distance = position - begin();
|
||||
_increment_capacity(1);
|
||||
position = begin() + distance;
|
||||
}
|
||||
it = end();
|
||||
if (position != it)
|
||||
{
|
||||
_allocator.construct(it, *(it - 1));
|
||||
while (it-- != position)
|
||||
*(it + 1) = *it;
|
||||
_allocator.destroy(position);
|
||||
}
|
||||
_allocator.construct(position, val);
|
||||
_size++;
|
||||
return (position);
|
||||
}
|
||||
VT_TPL void VT::
|
||||
insert(iterator position, size_type n, const value_type& val) {
|
||||
|
||||
difference_type distance;
|
||||
iterator it_end;
|
||||
iterator it;
|
||||
|
||||
if (_size + n > _capacity)
|
||||
{
|
||||
distance = position - begin();
|
||||
_increment_capacity(n);
|
||||
position = begin() + distance;
|
||||
}
|
||||
|
||||
it_end = end();
|
||||
if (position != it_end)
|
||||
{
|
||||
it = it_end;
|
||||
while (it + n != it_end && it != position)
|
||||
{
|
||||
it--;
|
||||
_allocator.construct(it + n, *it);
|
||||
}
|
||||
while (it != position)
|
||||
{
|
||||
it--;
|
||||
*(it + n) = *it;
|
||||
}
|
||||
_destroy(position, std::min(position + n, it_end));
|
||||
}
|
||||
|
||||
for (size_type i = 0; i < n; i++, position++)
|
||||
_allocator.construct(position, val);
|
||||
_size += n;
|
||||
}
|
||||
VT_TPL template <class InputIterator>
|
||||
typename enable_if< !is_integral<InputIterator>::value,void >::type VT::
|
||||
insert(iterator position, InputIterator first, InputIterator last) {
|
||||
|
||||
difference_type dist;
|
||||
difference_type n;
|
||||
iterator it_end;
|
||||
iterator it;
|
||||
|
||||
n = std::distance(first, last);
|
||||
if (_size + n > _capacity)
|
||||
{
|
||||
dist = position - begin();
|
||||
_increment_capacity(n);
|
||||
position = begin() + dist;
|
||||
}
|
||||
|
||||
it_end = end();
|
||||
if (position != it_end)
|
||||
{
|
||||
it = it_end;
|
||||
while (it + n != it_end && it != position)
|
||||
{
|
||||
it--;
|
||||
_allocator.construct(it + n, *it);
|
||||
}
|
||||
while (it != position)
|
||||
{
|
||||
it--;
|
||||
*(it + n) = *it;
|
||||
}
|
||||
_destroy(position, std::min(position + n, it_end));
|
||||
}
|
||||
|
||||
while (first != last)
|
||||
{
|
||||
_allocator.construct(position, *first);
|
||||
++position;
|
||||
++first;
|
||||
}
|
||||
|
||||
_size += n;
|
||||
}
|
||||
// erase -------------------------------------
|
||||
VT_TPL typename VT::iterator VT::
|
||||
erase(iterator position) {
|
||||
|
||||
iterator i = position;
|
||||
iterator it_end = end() - 1;
|
||||
|
||||
while (i != it_end)
|
||||
{
|
||||
*i = *(i + 1);
|
||||
++i;
|
||||
}
|
||||
_allocator.destroy(it_end);
|
||||
_size -= 1;
|
||||
return (position);
|
||||
}
|
||||
VT_TPL typename VT::iterator VT::
|
||||
erase(iterator first, iterator last) {
|
||||
|
||||
iterator it_end = end();
|
||||
difference_type diff = std::distance(first, last);
|
||||
|
||||
if (diff <= 0)
|
||||
return (first);
|
||||
|
||||
it_end = end();
|
||||
while (last != it_end)
|
||||
{
|
||||
*first = *last;
|
||||
first++;
|
||||
last++;
|
||||
}
|
||||
_destroy(it_end - diff, it_end);
|
||||
_size -= diff;
|
||||
|
||||
return (first);
|
||||
}
|
||||
// swap --------------------------------------
|
||||
VT_TPL void VT::
|
||||
swap(vector& x) {
|
||||
|
||||
T* tmp_mem_ptr;
|
||||
size_type tmp_size;
|
||||
size_type tmp_capacity;
|
||||
|
||||
tmp_mem_ptr = x._mem_ptr;
|
||||
tmp_size = x._size;
|
||||
tmp_capacity = x._capacity;
|
||||
|
||||
x._mem_ptr = _mem_ptr;
|
||||
x._size = _size;
|
||||
x._capacity = _capacity;
|
||||
|
||||
_mem_ptr = tmp_mem_ptr;
|
||||
_size = tmp_size;
|
||||
_capacity = tmp_capacity;
|
||||
}
|
||||
// clear -------------------------------------
|
||||
VT_TPL void VT::
|
||||
clear() { _destroy(begin(), end()); _size = 0; }
|
||||
|
||||
|
||||
|
||||
/*************
|
||||
* allocator :
|
||||
*************/
|
||||
// get_allocator -----------------------------
|
||||
VT_TPL typename VT::allocator_type VT::
|
||||
get_allocator() const { return (_allocator); }
|
||||
|
||||
|
||||
|
||||
/*********************************************
|
||||
* PRIVATE MEMBER FUNCTIONS
|
||||
*********************************************/
|
||||
VT_TPL void VT::
|
||||
_destroy(iterator first, iterator last) {
|
||||
|
||||
while (first != last)
|
||||
{
|
||||
_allocator.destroy(first);
|
||||
first++;
|
||||
}
|
||||
}
|
||||
VT_TPL void VT::
|
||||
_increment_capacity(size_type n) {
|
||||
|
||||
size_type res;
|
||||
|
||||
res = std::max(_size * 2, n);
|
||||
reserve(std::min(res, _allocator.max_size()));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/************************
|
||||
* non-member functions :
|
||||
************************/
|
||||
// operator == -------------------------------
|
||||
VT_TPL bool
|
||||
operator== (const VT & lhs, const VT & rhs) {
|
||||
|
||||
if (lhs.size() != rhs.size())
|
||||
return false;
|
||||
return ft::equal(lhs.begin(), lhs.end(), rhs.begin());
|
||||
}
|
||||
// operator < --------------------------------
|
||||
VT_TPL bool
|
||||
operator< (const VT & lhs, const VT & rhs) {
|
||||
|
||||
return ft::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
|
||||
}
|
||||
// operator != -------------------------------
|
||||
VT_TPL bool
|
||||
operator!= (const VT & lhs, const VT & rhs) { return !(lhs == rhs); }
|
||||
// operator <= -------------------------------
|
||||
VT_TPL bool
|
||||
operator<= (const VT & lhs, const VT & rhs) { return !(lhs > rhs); }
|
||||
// operator > --------------------------------
|
||||
VT_TPL bool
|
||||
operator> (const VT & lhs, const VT & rhs) { return (rhs < lhs); }
|
||||
// operator >= -------------------------------
|
||||
VT_TPL bool
|
||||
operator>= (const VT & lhs, const VT & rhs) { return !(lhs < rhs); }
|
||||
// swap (vector) -------------------------------
|
||||
VT_TPL void
|
||||
swap (VT & lhs, VT & rhs) { lhs.swap(rhs); }
|
||||
|
||||
} // namespace ft
|
||||
|
||||
#undef VT
|
||||
#undef VT_TPL
|
||||
|
||||
84
tests/includes/main.hpp
Normal file
84
tests/includes/main.hpp
Normal file
@@ -0,0 +1,84 @@
|
||||
#ifndef MAIN_HPP
|
||||
# define MAIN_HPP
|
||||
|
||||
#include "colors.h"
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <iomanip> // std::setw()
|
||||
#include <vector>
|
||||
|
||||
#include "tests_structs.hpp"
|
||||
|
||||
|
||||
// global variables
|
||||
// ***************************************
|
||||
std::vector< std::vector<A_test*> > test_list;
|
||||
std::vector< mystruct* > mem_list;
|
||||
|
||||
|
||||
// prototypes
|
||||
// *********************************************
|
||||
// vectors
|
||||
void tests_vector_constructor();
|
||||
void tests_vector_operator_assignation();
|
||||
void tests_vector_begin();
|
||||
void tests_vector_end();
|
||||
void tests_vector_rbegin();
|
||||
void tests_vector_rend();
|
||||
void tests_vector_size();
|
||||
void tests_vector_max_size();
|
||||
void tests_vector_resize();
|
||||
void tests_vector_capacity();
|
||||
void tests_vector_empty();
|
||||
void tests_vector_reserve();
|
||||
void tests_vector_operator_access();
|
||||
void tests_vector_at();
|
||||
void tests_vector_front();
|
||||
void tests_vector_back();
|
||||
void tests_vector_assign();
|
||||
void tests_vector_push_back();
|
||||
void tests_vector_pop_back();
|
||||
void tests_vector_insert();
|
||||
void tests_vector_erase();
|
||||
void tests_vector_swap();
|
||||
void tests_vector_clear();
|
||||
void tests_vector_get_allocator();
|
||||
void tests_vector_relational_operators();
|
||||
void tests_vector_swap_non_member();
|
||||
void tests_vector_reverse_iterators();
|
||||
// map
|
||||
void tests_map_simple();
|
||||
void tests_map_constructor();
|
||||
void tests_map_operator_assignation();
|
||||
void tests_map_begin();
|
||||
void tests_map_end();
|
||||
void tests_map_rbegin();
|
||||
void tests_map_rend();
|
||||
void tests_map_empty();
|
||||
void tests_map_size();
|
||||
void tests_map_max_size();
|
||||
void tests_map_operator_access();
|
||||
void tests_map_insert();
|
||||
void tests_map_erase();
|
||||
void tests_map_swap();
|
||||
void tests_map_clear();
|
||||
void tests_map_key_comp();
|
||||
void tests_map_value_comp();
|
||||
void tests_map_find();
|
||||
void tests_map_count();
|
||||
void tests_map_lower_bound();
|
||||
void tests_map_upper_bound();
|
||||
void tests_map_equal_range();
|
||||
void tests_map_get_allocator();
|
||||
void tests_map_relational_operators();
|
||||
void tests_map_swap_non_member();
|
||||
// stack
|
||||
void tests_stack_constructor();
|
||||
void tests_stack_empty();
|
||||
void tests_stack_size();
|
||||
void tests_stack_top();
|
||||
void tests_stack_push();
|
||||
void tests_stack_pop();
|
||||
|
||||
#endif
|
||||
|
||||
33
tests/includes/tests_map.hpp
Normal file
33
tests/includes/tests_map.hpp
Normal file
@@ -0,0 +1,33 @@
|
||||
#ifndef TESTS_MAP_HPP
|
||||
# define TESTS_MAP_HPP
|
||||
|
||||
#include "tests_utils.hpp"
|
||||
|
||||
|
||||
// toogle between test ft and stl
|
||||
// *************************
|
||||
#ifdef STL
|
||||
namespace ft = std;
|
||||
#else
|
||||
#include "map.hpp"
|
||||
#include "reverse_iterator.hpp"
|
||||
#endif
|
||||
|
||||
|
||||
// templates print
|
||||
// *****************************************
|
||||
template <class T, class U>
|
||||
void print(ft::map<T, U>& mp, std::string name) {
|
||||
|
||||
int i = 0;
|
||||
typename ft::map<T, U>::iterator it;
|
||||
typename ft::map<T, U>::iterator it_end = mp.end();
|
||||
|
||||
std::cout << "\n" << name << ":(map)\n";
|
||||
for (it = mp.begin(); it != it_end; ++it, i++)
|
||||
std::cout << "[" << i << "]" << it->first << ":" << it->second << " ";
|
||||
std::cout << "\nsize:" << mp.size() << "\n";
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
28
tests/includes/tests_stack.hpp
Normal file
28
tests/includes/tests_stack.hpp
Normal file
@@ -0,0 +1,28 @@
|
||||
#ifndef TESTS_STACK_HPP
|
||||
# define TESTS_STACK_HPP
|
||||
|
||||
#include "tests_utils.hpp"
|
||||
|
||||
|
||||
// toogle between test ft and stl
|
||||
// *************************
|
||||
#ifdef STL
|
||||
namespace ft = std;
|
||||
#else
|
||||
#include "stack.hpp"
|
||||
#endif
|
||||
|
||||
|
||||
// templates print
|
||||
// *****************************************
|
||||
template <class T, class cont>
|
||||
void print(ft::stack<T,cont>& st, std::string name) {
|
||||
|
||||
std::cout << "\n" << name << ":(map)\n";
|
||||
for (int i = st.size(); i > 0 ; i--, st.pop())
|
||||
std::cout << "[" << i << "]" << st.top() << " ";
|
||||
std::cout << "\nsize:" << st.size() << "\n";
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
24
tests/includes/tests_structs.hpp
Normal file
24
tests/includes/tests_structs.hpp
Normal file
@@ -0,0 +1,24 @@
|
||||
#ifndef TESTS_STRUCTS_HPP
|
||||
# define TESTS_STRUCTS_HPP
|
||||
|
||||
// abstract class test -----------------------
|
||||
struct A_test
|
||||
{
|
||||
virtual ~A_test(){};
|
||||
std::string title;
|
||||
std::string type;
|
||||
virtual void func() = 0;
|
||||
};
|
||||
// mystruct ----------------------------------
|
||||
struct mystruct {
|
||||
public:
|
||||
mystruct(int data = 0);
|
||||
~mystruct();
|
||||
int * get_data() const;
|
||||
private:
|
||||
int * _val;
|
||||
};
|
||||
std::ostream & operator<<(std::ostream & o, mystruct const * rhs);
|
||||
|
||||
#endif
|
||||
|
||||
170
tests/includes/tests_utils.hpp
Normal file
170
tests/includes/tests_utils.hpp
Normal file
@@ -0,0 +1,170 @@
|
||||
|
||||
#ifndef TESTS_UTILS_HPP
|
||||
# define TESTS_UTILS_HPP
|
||||
|
||||
|
||||
#include "colors.h"
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <iomanip> // std::setw()
|
||||
#include <iterator> // std::reverse_iterator
|
||||
#include <utility> // std::make_pair
|
||||
#include <sstream> // std::stringstream
|
||||
#include <deque>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <stack>
|
||||
|
||||
#include "tests_structs.hpp"
|
||||
|
||||
|
||||
// defines
|
||||
// ****************************************
|
||||
# define TITLE(s) std::cout << "\n" B_PURPLE #s RESET "\n\n";
|
||||
# define VAL(n) val<T>(n)
|
||||
# define VALT(n) val<T>(n)
|
||||
# define VALU(n) val<U>(n)
|
||||
# define TOI(n) toi<T>(n)
|
||||
# define PRINT(n) print<>(n, #n);
|
||||
# define DELETE delete_structs();
|
||||
# define AVOID_MYSTRUCT(T) if (is_mystruct_type<T>::value) {return;}
|
||||
|
||||
|
||||
// prototypes
|
||||
// *********************************************
|
||||
void add_to_list(std::string title, std::string type, A_test* test);
|
||||
void delete_structs();
|
||||
|
||||
|
||||
// global variables
|
||||
// ***************************************
|
||||
extern std::vector< std::vector<A_test*> > test_list;
|
||||
extern std::vector< mystruct* > mem_list;
|
||||
|
||||
|
||||
// adding each test to the list
|
||||
// ***************************
|
||||
#define TEST_S(f_name) TEST_V(f_name)
|
||||
|
||||
/*
|
||||
*/
|
||||
|
||||
#define TEST_V(f_name) \
|
||||
template <class T> struct s_ ## f_name : public A_test\
|
||||
{ void func(); };\
|
||||
void f_name () {\
|
||||
add_to_list("", "", NULL);\
|
||||
add_to_list(#f_name, "int", new(s_ ## f_name <int>));\
|
||||
add_to_list(#f_name, "char", new(s_ ## f_name <char>));\
|
||||
add_to_list(#f_name, "std::string", new(s_ ## f_name <std::string>));\
|
||||
add_to_list(#f_name, "mystruct*", new(s_ ## f_name <mystruct*>));\
|
||||
}\
|
||||
template <class T>\
|
||||
void s_ ## f_name <T>::func()
|
||||
|
||||
#define TEST_M(f_name) \
|
||||
template <class T, class U> struct s_ ## f_name : public A_test\
|
||||
{ void func(); };\
|
||||
void f_name () {\
|
||||
add_to_list("", "", NULL);\
|
||||
add_to_list(#f_name, "char, int", new(s_ ## f_name <char, int>));\
|
||||
add_to_list(#f_name, "char, char", new(s_ ## f_name <char, char>));\
|
||||
add_to_list(#f_name, "char, std::string", new(s_ ## f_name <char, std::string>));\
|
||||
add_to_list(#f_name, "char, mystruct*", new(s_ ## f_name <char, mystruct*>));\
|
||||
add_to_list(#f_name, "int, int", new(s_ ## f_name <int, int>));\
|
||||
add_to_list(#f_name, "int, char", new(s_ ## f_name <int, char>));\
|
||||
add_to_list(#f_name, "int, std::string", new(s_ ## f_name <int, std::string>));\
|
||||
add_to_list(#f_name, "int, mystruct*", new(s_ ## f_name <int, mystruct*>));\
|
||||
}\
|
||||
template <class T, class U>\
|
||||
void s_ ## f_name <T, U>::func()
|
||||
/*
|
||||
*/
|
||||
|
||||
|
||||
// templates get value
|
||||
// *************************************
|
||||
template <class T> struct is_mystruct_type
|
||||
{
|
||||
typedef char yes[1];
|
||||
typedef yes no[2];
|
||||
static T type;
|
||||
|
||||
static yes& test(mystruct*);
|
||||
template <class C> static no& test(C);
|
||||
static const bool value = sizeof(test(type)) == sizeof(yes);
|
||||
};
|
||||
// specialization in header, make it inline :
|
||||
// https://stackoverflow.com/questions/63529059/c-specialized-method-templates-produce-multiple-definition-errors
|
||||
template <class T>
|
||||
T val(int n) { (void)n; return (T()); }
|
||||
template <>
|
||||
inline int val(int n) { return (n); }
|
||||
template <>
|
||||
inline char val(int n) {
|
||||
|
||||
if (n <= 126 && n >= 33)
|
||||
return n;
|
||||
return (n % 94 + 33);
|
||||
}
|
||||
template <>
|
||||
inline std::string val(int n) {
|
||||
|
||||
std::string str;
|
||||
std::stringstream stream;
|
||||
|
||||
stream << n;
|
||||
stream >> str;
|
||||
stream.clear();
|
||||
return (str);
|
||||
}
|
||||
template <>
|
||||
inline mystruct* val(int n) {
|
||||
|
||||
mystruct *s = new mystruct(n);
|
||||
mem_list.push_back(s);
|
||||
return ( s );
|
||||
}
|
||||
template <class T>
|
||||
T val(std::string str) { (void)str; return (T()); }
|
||||
template <>
|
||||
inline int val(std::string str) { int i = str[0]; return (val<int>(i)); }
|
||||
template <>
|
||||
inline char val(std::string str) { int i = str[0]; return (val<char>(i)); }
|
||||
template <>
|
||||
inline std::string val(std::string str) { return (str); }
|
||||
template <>
|
||||
inline mystruct* val(std::string str) { int i = str[0]; return (val<mystruct*>(i)); }
|
||||
|
||||
|
||||
// templates to value
|
||||
// **************************************
|
||||
template <class T>
|
||||
int toi(T t) {(void)t; return (0);
|
||||
}
|
||||
template <>
|
||||
inline int toi(int i) {return (i);
|
||||
}
|
||||
template <>
|
||||
inline int toi(char c) {return (c);
|
||||
}
|
||||
template <>
|
||||
inline int toi(std::string str) {
|
||||
|
||||
int i;
|
||||
std::stringstream stream;
|
||||
|
||||
stream << str;
|
||||
stream >> i;
|
||||
stream.clear();
|
||||
return (i);
|
||||
}
|
||||
template <>
|
||||
inline int toi(mystruct* s) {
|
||||
|
||||
return ( s->get_data()[0] );
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
33
tests/includes/tests_vector.hpp
Normal file
33
tests/includes/tests_vector.hpp
Normal file
@@ -0,0 +1,33 @@
|
||||
#ifndef TESTS_VECTOR_HPP
|
||||
# define TESTS_VECTOR_HPP
|
||||
|
||||
#include "tests_utils.hpp"
|
||||
|
||||
|
||||
// toogle between test ft and stl
|
||||
// *************************
|
||||
#ifdef STL
|
||||
namespace ft = std;
|
||||
#else
|
||||
#include "vector.hpp"
|
||||
#include "reverse_iterator.hpp"
|
||||
#endif
|
||||
|
||||
|
||||
// templates print
|
||||
// *****************************************
|
||||
template <class T>
|
||||
void print(ft::vector<T>& vec, std::string name) {
|
||||
|
||||
int i = 0;
|
||||
typename ft::vector<T>::iterator it;
|
||||
typename ft::vector<T>::iterator it_end = vec.end();
|
||||
|
||||
std::cout << "\n" << name << ":(vector)\n";
|
||||
for (it = vec.begin(); it != it_end; ++it, i++)
|
||||
std::cout << "[" << i << "]" << *it << " ";
|
||||
std::cout << "\nsize:" << vec.size() << " capacty:" << vec.capacity() << "\n";
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
90
tests/main.cpp
Normal file
90
tests/main.cpp
Normal file
@@ -0,0 +1,90 @@
|
||||
|
||||
#include "main.hpp"
|
||||
|
||||
int main() {
|
||||
|
||||
// VECTOR
|
||||
tests_vector_constructor();
|
||||
tests_vector_operator_assignation();
|
||||
tests_vector_begin();
|
||||
tests_vector_end();
|
||||
tests_vector_rbegin();
|
||||
tests_vector_rend();
|
||||
tests_vector_size();
|
||||
tests_vector_max_size();
|
||||
tests_vector_resize();
|
||||
tests_vector_capacity();
|
||||
tests_vector_empty();
|
||||
tests_vector_reserve();
|
||||
tests_vector_operator_access();
|
||||
tests_vector_at();
|
||||
tests_vector_front();
|
||||
tests_vector_back();
|
||||
tests_vector_assign();
|
||||
tests_vector_push_back();
|
||||
tests_vector_pop_back();
|
||||
tests_vector_insert();
|
||||
tests_vector_erase();
|
||||
tests_vector_swap();
|
||||
tests_vector_clear();
|
||||
tests_vector_get_allocator();
|
||||
tests_vector_swap_non_member();
|
||||
tests_vector_reverse_iterators();
|
||||
tests_vector_relational_operators();
|
||||
|
||||
// MAP
|
||||
tests_map_simple();
|
||||
tests_map_constructor();
|
||||
tests_map_operator_assignation();
|
||||
tests_map_begin();
|
||||
tests_map_end();
|
||||
tests_map_rbegin();
|
||||
tests_map_rend();
|
||||
tests_map_empty();
|
||||
tests_map_size();
|
||||
tests_map_max_size();
|
||||
tests_map_operator_access();
|
||||
tests_map_insert();
|
||||
tests_map_erase();
|
||||
tests_map_swap();
|
||||
tests_map_clear();
|
||||
tests_map_key_comp();
|
||||
tests_map_value_comp();
|
||||
tests_map_find();
|
||||
tests_map_count();
|
||||
tests_map_lower_bound();
|
||||
tests_map_upper_bound();
|
||||
tests_map_equal_range();
|
||||
tests_map_get_allocator();
|
||||
tests_map_swap_non_member();
|
||||
tests_map_relational_operators();
|
||||
|
||||
// STACK
|
||||
tests_stack_constructor();
|
||||
tests_stack_empty();
|
||||
tests_stack_size();
|
||||
tests_stack_top();
|
||||
tests_stack_push();
|
||||
tests_stack_pop();
|
||||
|
||||
// execute tests and print them :
|
||||
int size = test_list.size();
|
||||
int sub_size;
|
||||
for(int i = 0; i < size; i++)
|
||||
{
|
||||
std::cout << "\n" B_YELLOW "[" << i + 1 << "/" << size << "] "
|
||||
<< test_list[i][0]->title << RESET << "\n";
|
||||
sub_size = test_list[i].size();
|
||||
for (int j = 0; j < sub_size; j++)
|
||||
{
|
||||
std::cout << "\n" << B_CYAN << "-- " << test_list[i][j]->type
|
||||
<< " --" << RESET "\n";
|
||||
test_list[i][j]->func();
|
||||
delete test_list[i][j];
|
||||
}
|
||||
}
|
||||
std::cout << "\n";
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <deque>
|
||||
@@ -87,7 +88,7 @@ int main(int argc, char** argv) {
|
||||
{
|
||||
//NORMAL ! :P
|
||||
}
|
||||
|
||||
|
||||
for (int i = 0; i < COUNT; ++i)
|
||||
{
|
||||
map_int.insert(ft::make_pair(rand(), rand()));
|
||||
@@ -114,3 +115,4 @@ int main(int argc, char** argv) {
|
||||
std::cout << std::endl;
|
||||
return (0);
|
||||
}
|
||||
|
||||
741
tests/other_mains/main_map_1.cpp
Normal file
741
tests/other_mains/main_map_1.cpp
Normal file
@@ -0,0 +1,741 @@
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <iomanip> // std::setw()
|
||||
#include <iterator> // std::reverse_iterator
|
||||
#include <utility> // std::make_pair
|
||||
#include <sstream> // std::stringstream
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
// toogle ft in stl
|
||||
#ifdef STL
|
||||
namespace ft = std;
|
||||
#else
|
||||
#include "map.hpp"
|
||||
#include "reverse_iterator.hpp"
|
||||
#endif
|
||||
|
||||
// defines
|
||||
# define TEST_M(s) template <class T, class U> void s ()
|
||||
# define TITLE(s) std::cout << "\n" B_PURPLE #s RESET "\n\n";
|
||||
# define VALT(n) val<T>(n)
|
||||
# define VALU(n) val<U>(n)
|
||||
# define TOI(n) toi<T>(n)
|
||||
# define PRINT(n) print<>(n, #n);
|
||||
# define DELETE delete_structs();
|
||||
|
||||
// colors
|
||||
# define GRAY "\e[0;30m"
|
||||
# define RED "\e[0;31m"
|
||||
# define GREEN "\e[0;32m"
|
||||
# define YELLOW "\e[0;33m"
|
||||
# define BLUE "\e[0;34m"
|
||||
# define PURPLE "\e[0;35m"
|
||||
# define CYAN "\e[0;36m"
|
||||
# define WHITE "\e[0;37m"
|
||||
|
||||
# define B_GRAY "\e[1;30m"
|
||||
# define B_RED "\e[1;31m"
|
||||
# define B_GREEN "\e[1;32m"
|
||||
# define B_YELLOW "\e[1;33m"
|
||||
# define B_BLUE "\e[1;34m"
|
||||
# define B_PURPLE "\e[1;35m"
|
||||
# define B_CYAN "\e[1;36m"
|
||||
# define B_WHITE "\e[1;37m"
|
||||
|
||||
# define RESET "\e[0m"
|
||||
|
||||
// mystruct declaration
|
||||
struct mystruct {
|
||||
public:
|
||||
mystruct(int data = 0);
|
||||
~mystruct();
|
||||
int * get_data() const;
|
||||
private:
|
||||
int * _val;
|
||||
};
|
||||
std::ostream & operator<<(std::ostream & o, mystruct const * rhs);
|
||||
|
||||
// mystruct definition
|
||||
mystruct::mystruct(int data)
|
||||
{_val = new int[2]; _val[0] = data; _val[1] = data;}
|
||||
mystruct::~mystruct()
|
||||
{delete[] _val;}
|
||||
int * mystruct::get_data() const
|
||||
{return _val;}
|
||||
std::ostream & operator<<(std::ostream & o, mystruct const * rhs) {
|
||||
if (rhs != NULL)
|
||||
o << (*rhs).get_data()[0] << "," << (*rhs).get_data()[1];
|
||||
else
|
||||
o << "NULL";
|
||||
return (o);
|
||||
}
|
||||
|
||||
// global variable for mem gestion of mystruct
|
||||
std::vector< mystruct* > mem_list;
|
||||
|
||||
// template print function
|
||||
template <class T, class U>
|
||||
void print(ft::map<T, U> mp, std::string name) {
|
||||
|
||||
int i = 0;
|
||||
typename ft::map<T, U>::iterator it;
|
||||
typename ft::map<T, U>::iterator it_end = mp.end();
|
||||
|
||||
std::cout << "\n" << name << ":(map)\n";
|
||||
for (it = mp.begin(); it != it_end; ++it, i++)
|
||||
std::cout << "[" << i << "]" << it->first << ":" << it->second << " ";
|
||||
std::cout << "\nsize:" << mp.size() << "\n";
|
||||
}
|
||||
|
||||
// template val() for instanciation of values for types :
|
||||
// int, char, std::string, and mystruct*
|
||||
template <class T>
|
||||
T val(int n) { (void)n; return (T()); }
|
||||
template <>
|
||||
inline int val(int n) { return (n); }
|
||||
template <>
|
||||
inline char val(int n) {
|
||||
|
||||
if (n <= 126 && n >= 33)
|
||||
return n;
|
||||
return (n % 94 + 33);
|
||||
}
|
||||
template <>
|
||||
inline std::string val(int n) {
|
||||
|
||||
std::string str;
|
||||
std::stringstream stream;
|
||||
|
||||
stream << n;
|
||||
stream >> str;
|
||||
stream.clear();
|
||||
return (str);
|
||||
}
|
||||
template <>
|
||||
inline mystruct* val(int n) {
|
||||
|
||||
mystruct *s = new mystruct(n);
|
||||
mem_list.push_back(s);
|
||||
return ( s );
|
||||
}
|
||||
template <class T>
|
||||
T val(std::string str) { (void)str; return (T()); }
|
||||
template <>
|
||||
inline int val(std::string str) { int i = str[0]; return (val<int>(i)); }
|
||||
template <>
|
||||
inline char val(std::string str) { int i = str[0]; return (val<char>(i)); }
|
||||
template <>
|
||||
inline std::string val(std::string str) { return (str); }
|
||||
template <>
|
||||
inline mystruct* val(std::string str) { int i = str[0]; return (val<mystruct*>(i)); }
|
||||
|
||||
// delete function for mem gestion of mystruct*
|
||||
void delete_structs() {
|
||||
|
||||
std::vector<mystruct*>::iterator it;
|
||||
std::vector<mystruct*>::iterator it_end = mem_list.end();
|
||||
|
||||
for (it = mem_list.begin(); it != it_end; ++it)
|
||||
delete *it;
|
||||
mem_list.clear();
|
||||
}
|
||||
|
||||
// all tests
|
||||
TEST_M(tests_map_operator_assignation)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference)
|
||||
|
||||
ft::map<T,U> first;
|
||||
ft::map<T,U> second;
|
||||
|
||||
first[VALT('x')]=VALU(8);
|
||||
first[VALT('y')]=VALU(16);
|
||||
first[VALT('z')]=VALU(32);
|
||||
|
||||
PRINT(first)
|
||||
PRINT(second)
|
||||
|
||||
second=first; // second now contains 3 ints
|
||||
first=ft::map<T,U>(); // and first is now empty
|
||||
|
||||
std::cout << "Size of first: " << first.size() << '\n';
|
||||
std::cout << "Size of second: " << second.size() << '\n';
|
||||
|
||||
PRINT(first)
|
||||
PRINT(second)
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_M(tests_map_begin)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference)
|
||||
|
||||
ft::map<T,U> mymap;
|
||||
|
||||
mymap[VALT('b')] = VALU(100);
|
||||
mymap[VALT('a')] = VALU(200);
|
||||
mymap[VALT('c')] = VALU(300);
|
||||
|
||||
PRINT(mymap)
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_M(tests_map_end)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference)
|
||||
|
||||
ft::map<T,U> mymap;
|
||||
|
||||
mymap[VALT('b')] = VALU(100);
|
||||
mymap[VALT('a')] = VALU(200);
|
||||
mymap[VALT('c')] = VALU(300);
|
||||
|
||||
PRINT(mymap)
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_M(tests_map_rbegin)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference)
|
||||
|
||||
ft::map<T,U> mymap;
|
||||
|
||||
mymap[VALT('x')] = VALU(100);
|
||||
mymap[VALT('y')] = VALU(200);
|
||||
mymap[VALT('z')] = VALU(300);
|
||||
|
||||
// show content:
|
||||
typename ft::map<T,U>::reverse_iterator rit;
|
||||
for (rit=mymap.rbegin(); rit!=mymap.rend(); ++rit)
|
||||
std::cout << rit->first << " => " << rit->second << '\n';
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_M(tests_map_rend)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference)
|
||||
|
||||
ft::map<T,U> mymap;
|
||||
|
||||
mymap[VALT('x')] = VALU(100);
|
||||
mymap[VALT('y')] = VALU(200);
|
||||
mymap[VALT('z')] = VALU(300);
|
||||
|
||||
// show content:
|
||||
typename ft::map<T,U>::reverse_iterator rit;
|
||||
for (rit=mymap.rbegin(); rit!=mymap.rend(); ++rit)
|
||||
std::cout << rit->first << " => " << rit->second << '\n';
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_M(tests_map_empty)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference)
|
||||
|
||||
ft::map<T,U> mymap;
|
||||
|
||||
mymap[VALT('a')]=VALU(10);
|
||||
mymap[VALT('b')]=VALU(20);
|
||||
mymap[VALT('c')]=VALU(30);
|
||||
|
||||
while (!mymap.empty())
|
||||
{
|
||||
std::cout << mymap.begin()->first << " => " << mymap.begin()->second << '\n';
|
||||
mymap.erase(mymap.begin());
|
||||
}
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_M(tests_map_size)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference)
|
||||
|
||||
ft::map<T,U> mymap;
|
||||
mymap[VALT('a')]=VALU(101);
|
||||
mymap[VALT('b')]=VALU(202);
|
||||
mymap[VALT('c')]=VALU(302);
|
||||
|
||||
std::cout << "mymap.size() is " << mymap.size() << '\n';
|
||||
|
||||
PRINT(mymap)
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_M(tests_map_max_size)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference)
|
||||
|
||||
int i;
|
||||
std::map<T,U> mymap;
|
||||
|
||||
if (mymap.max_size()>1000)
|
||||
{
|
||||
for (i=0; i<1000; i++) mymap[i]=VALU(0);
|
||||
std::cout << "The map contains 1000 elements.\n";
|
||||
}
|
||||
else std::cout << "The map could not hold 1000 elements.\n";
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_M(tests_map_operator_access)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference)
|
||||
|
||||
ft::map<T,U> mymap;
|
||||
|
||||
mymap[VALT('a')]=VALU("An element");
|
||||
mymap[VALT('b')]=VALU("another element");
|
||||
mymap[VALT('c')]=mymap[VALT('b')];
|
||||
|
||||
std::cout << "mymap['a'] is " << mymap[VALT('a')] << '\n';
|
||||
std::cout << "mymap['b'] is " << mymap[VALT('b')] << '\n';
|
||||
std::cout << "mymap['c'] is " << mymap[VALT('c')] << '\n';
|
||||
std::cout << "mymap['d'] is " << mymap[VALT('d')] << '\n';
|
||||
|
||||
std::cout << "mymap now contains " << mymap.size() << " elements.\n";
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_M(tests_map_insert)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference)
|
||||
|
||||
ft::map<T,U> mymap;
|
||||
|
||||
// first insert function version (single parameter):
|
||||
mymap.insert ( ft::pair<T,U>(VALT('a'),VALU(100)) );
|
||||
mymap.insert ( ft::pair<T,U>(VALT('z'),VALU(200)) );
|
||||
|
||||
ft::pair<typename ft::map<T,U>::iterator, bool> ret;
|
||||
ret = mymap.insert ( ft::pair<T,U>(VALT('z'),VALU(500)) );
|
||||
if (ret.second==false) {
|
||||
std::cout << "element 'z' already existed";
|
||||
std::cout << " with a value of " << ret.first->second << '\n';
|
||||
}
|
||||
|
||||
|
||||
// second insert function version (with hint position):
|
||||
typename ft::map<T,U>::iterator it = mymap.begin();
|
||||
mymap.insert (it, ft::pair<T,U>(VALT('b'),VALU(300))); // max efficiency inserting
|
||||
mymap.insert (it, ft::pair<T,U>(VALT('c'),VALU(400))); // no max efficiency inserting
|
||||
|
||||
// third insert function version (range insertion):
|
||||
ft::map<T,U> anothermap;
|
||||
anothermap.insert(mymap.begin(),mymap.find('c'));
|
||||
|
||||
PRINT(mymap)
|
||||
PRINT(anothermap)
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_M(tests_map_erase)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference)
|
||||
|
||||
ft::map<T,U> mymap;
|
||||
typename ft::map<T,U>::iterator it;
|
||||
|
||||
// insert some values:
|
||||
mymap[VALT('a')]=VALU(10);
|
||||
mymap[VALT('b')]=VALU(20);
|
||||
mymap[VALT('c')]=VALU(30);
|
||||
mymap[VALT('d')]=VALU(40);
|
||||
mymap[VALT('e')]=VALU(50);
|
||||
mymap[VALT('f')]=VALU(60);
|
||||
|
||||
it=mymap.find(VALT('b'));
|
||||
mymap.erase (it); // erasing by iterator
|
||||
|
||||
mymap.erase (VALT('c')); // erasing by key
|
||||
|
||||
it=mymap.find (VALT('e'));
|
||||
mymap.erase ( it, mymap.end() ); // erasing by range
|
||||
|
||||
PRINT(mymap)
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_M(tests_map_swap)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference)
|
||||
|
||||
ft::map<T,U> foo,bar;
|
||||
|
||||
foo[VALT('x')]=VALU(100);
|
||||
foo[VALT('y')]=VALU(200);
|
||||
|
||||
bar[VALT('a')]=VALU(11);
|
||||
bar[VALT('b')]=VALU(22);
|
||||
bar[VALT('c')]=VALU(33);
|
||||
|
||||
foo.swap(bar);
|
||||
|
||||
PRINT(foo)
|
||||
PRINT(bar)
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_M(tests_map_clear)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference)
|
||||
|
||||
ft::map<T,U> mymap;
|
||||
|
||||
mymap[VALT('x')]=VALU(100);
|
||||
mymap[VALT('y')]=VALU(200);
|
||||
mymap[VALT('z')]=VALU(300);
|
||||
|
||||
PRINT(mymap)
|
||||
|
||||
mymap.clear();
|
||||
mymap[VALT('a')]=VALU(1101);
|
||||
mymap[VALT('b')]=VALU(2202);
|
||||
|
||||
PRINT(mymap)
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_M(tests_map_key_comp)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference)
|
||||
|
||||
ft::map<T,U> mymap;
|
||||
|
||||
typename ft::map<T,U>::key_compare mycomp = mymap.key_comp();
|
||||
|
||||
mymap[VALT('a')]=VALU(100);
|
||||
mymap[VALT('b')]=VALU(200);
|
||||
mymap[VALT('c')]=VALU(300);
|
||||
|
||||
std::cout << "mymap contains:\n";
|
||||
|
||||
T highest = mymap.rbegin()->first; // key value of last element
|
||||
|
||||
typename ft::map<T,U>::iterator it = mymap.begin();
|
||||
do {
|
||||
std::cout << it->first << " => " << it->second << '\n';
|
||||
} while ( mycomp((*it++).first, highest) );
|
||||
|
||||
std::cout << '\n';
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_M(tests_map_value_comp)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference)
|
||||
|
||||
ft::map<T,U> mymap;
|
||||
|
||||
mymap[VALT('x')]=VALU(1001);
|
||||
mymap[VALT('y')]=VALU(2002);
|
||||
mymap[VALT('z')]=VALU(3003);
|
||||
|
||||
std::cout << "mymap contains:\n";
|
||||
|
||||
ft::pair<T,U> highest = *mymap.rbegin(); // last element
|
||||
|
||||
typename ft::map<T,U>::iterator it = mymap.begin();
|
||||
do {
|
||||
std::cout << it->first << " => " << it->second << '\n';
|
||||
} while ( mymap.value_comp()(*it++, highest) );
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_M(tests_map_find)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference)
|
||||
|
||||
ft::map<T,U> mymap;
|
||||
typename ft::map<T,U>::iterator it;
|
||||
|
||||
mymap[VALT('a')]=VALU(50);
|
||||
mymap[VALT('b')]=VALU(100);
|
||||
mymap[VALT('c')]=VALU(150);
|
||||
mymap[VALT('d')]=VALU(200);
|
||||
|
||||
it = mymap.find(VALT('b'));
|
||||
if (it != mymap.end())
|
||||
mymap.erase (it);
|
||||
|
||||
// print content:
|
||||
std::cout << "elements in mymap:" << '\n';
|
||||
std::cout << "a => " << mymap.find(VALT('a'))->second << '\n';
|
||||
std::cout << "c => " << mymap.find(VALT('c'))->second << '\n';
|
||||
std::cout << "d => " << mymap.find(VALT('d'))->second << '\n';
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_M(tests_map_count)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference)
|
||||
|
||||
ft::map<T,U> mymap;
|
||||
T c;
|
||||
|
||||
mymap [VALT('a')]=VALU(101);
|
||||
mymap [VALT('c')]=VALU(202);
|
||||
mymap [VALT('f')]=VALU(303);
|
||||
|
||||
// to do this test with T as a 'string' or 'mystruct*' we should add overload
|
||||
for (c=VALT('a'); c<VALT('h'); c++)
|
||||
{
|
||||
std::cout << c;
|
||||
if (mymap.count(c)>0)
|
||||
std::cout << " is an element of mymap.\n";
|
||||
else
|
||||
std::cout << " is not an element of mymap.\n";
|
||||
}
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_M(tests_map_lower_bound)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference)
|
||||
|
||||
ft::map<T,U> mymap;
|
||||
typename ft::map<T,U>::iterator itlow,itup;
|
||||
|
||||
mymap[VALT('a')]=VALU(20);
|
||||
mymap[VALT('b')]=VALU(40);
|
||||
mymap[VALT('c')]=VALU(60);
|
||||
mymap[VALT('d')]=VALU(80);
|
||||
mymap[VALT('e')]=VALU(100);
|
||||
|
||||
itlow=mymap.lower_bound (VALT('b')); // itlow points to b
|
||||
itup=mymap.upper_bound (VALT('d')); // itup points to e (not d!)
|
||||
|
||||
mymap.erase(itlow,itup); // erases [itlow,itup)
|
||||
|
||||
PRINT(mymap)
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_M(tests_map_upper_bound)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference)
|
||||
|
||||
ft::map<T,U> mymap;
|
||||
typename ft::map<T,U>::iterator itlow,itup;
|
||||
|
||||
mymap[VALT('a')]=VALU(20);
|
||||
mymap[VALT('b')]=VALU(40);
|
||||
mymap[VALT('c')]=VALU(60);
|
||||
mymap[VALT('d')]=VALU(80);
|
||||
mymap[VALT('e')]=VALU(100);
|
||||
|
||||
itlow=mymap.lower_bound (VALT('b')); // itlow points to b
|
||||
itup=mymap.upper_bound (VALT('d')); // itup points to e (not d!)
|
||||
|
||||
mymap.erase(itlow,itup); // erases [itlow,itup)
|
||||
|
||||
PRINT(mymap)
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_M(tests_map_equal_range)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference)
|
||||
|
||||
ft::map<T,U> mymap;
|
||||
|
||||
mymap[VALT('a')]=VALU(10);
|
||||
mymap[VALT('b')]=VALU(20);
|
||||
mymap[VALT('c')]=VALU(30);
|
||||
|
||||
ft::pair<typename ft::map<T,U>::iterator,typename ft::map<T,U>::iterator> ret;
|
||||
ret = mymap.equal_range(VALT('b'));
|
||||
|
||||
std::cout << "lower bound points to: ";
|
||||
std::cout << ret.first->first << " => " << ret.first->second << '\n';
|
||||
|
||||
std::cout << "upper bound points to: ";
|
||||
std::cout << ret.second->first << " => " << ret.second->second << '\n';
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_M(tests_map_get_allocator)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference)
|
||||
|
||||
int psize;
|
||||
ft::map<T,U> mymap;
|
||||
ft::pair<const T,U>* p;
|
||||
|
||||
// allocate an array of 5 elements using mymap's allocator:
|
||||
p=mymap.get_allocator().allocate(5);
|
||||
|
||||
// assign some values to array
|
||||
psize = sizeof(typename ft::map<T,U>::value_type)*5;
|
||||
|
||||
std::cout << "The allocated array has a size of " << psize << " bytes.\n";
|
||||
|
||||
mymap.get_allocator().deallocate(p,5);
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_M(tests_map_relational_operators)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference)
|
||||
|
||||
ft::map<T,U> alice;
|
||||
ft::map<T,U> bob;
|
||||
ft::map<T,U> eve;
|
||||
(void)alice;
|
||||
(void)bob;
|
||||
(void)eve;
|
||||
|
||||
alice[VALT(1)]=VALU('a');
|
||||
alice[VALT(2)]=VALU('b');
|
||||
alice[VALT(3)]=VALU('c');
|
||||
|
||||
bob[VALT(7)]=VALU('Z');
|
||||
bob[VALT(8)]=VALU('Y');
|
||||
bob[VALT(9)]=VALU('X');
|
||||
bob[VALT(10)]=VALU('W');
|
||||
|
||||
eve[VALT(1)]=VALU('a');
|
||||
eve[VALT(2)]=VALU('b');
|
||||
eve[VALT(3)]=VALU('c');
|
||||
|
||||
std::cout << std::boolalpha;
|
||||
|
||||
// Compare non equal containers
|
||||
std::cout << "alice == bob returns " << (alice == bob) << '\n';
|
||||
std::cout << "alice != bob returns " << (alice != bob) << '\n';
|
||||
std::cout << "alice < bob returns " << (alice < bob) << '\n';
|
||||
std::cout << "alice <= bob returns " << (alice <= bob) << '\n';
|
||||
std::cout << "alice > bob returns " << (alice > bob) << '\n';
|
||||
std::cout << "alice >= bob returns " << (alice >= bob) << '\n';
|
||||
|
||||
std::cout << '\n';
|
||||
|
||||
// Compare equal containers
|
||||
std::cout << "alice == eve returns " << (alice == eve) << '\n';
|
||||
std::cout << "alice != eve returns " << (alice != eve) << '\n';
|
||||
std::cout << "alice < eve returns " << (alice < eve) << '\n';
|
||||
std::cout << "alice <= eve returns " << (alice <= eve) << '\n';
|
||||
std::cout << "alice > eve returns " << (alice > eve) << '\n';
|
||||
std::cout << "alice >= eve returns " << (alice >= eve) << '\n';
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
|
||||
TEST_M(tests_map_swap_non_member)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference)
|
||||
|
||||
ft::map<T, U> alice;
|
||||
ft::map<T, U> bob;
|
||||
|
||||
alice[VALT(1)]=VALU('a');
|
||||
alice[VALT(2)]=VALU('b');
|
||||
alice[VALT(3)]=VALU('c');
|
||||
|
||||
bob[VALT(7)]=VALU('Z');
|
||||
bob[VALT(8)]=VALU('Y');
|
||||
bob[VALT(9)]=VALU('X');
|
||||
bob[VALT(10)]=VALU('W');
|
||||
|
||||
// Print state before swap
|
||||
PRINT(alice)
|
||||
PRINT(bob)
|
||||
|
||||
std::cout << "-- SWAP\n";
|
||||
std::swap(alice, bob);
|
||||
|
||||
// Print state after swap
|
||||
PRINT(alice)
|
||||
PRINT(bob)
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
template <class T, class U>
|
||||
void call_tests() {
|
||||
|
||||
tests_map_operator_assignation<T,U>();
|
||||
tests_map_begin<T,U>();
|
||||
tests_map_end<T,U>();
|
||||
tests_map_rbegin<T,U>();
|
||||
tests_map_rend<T,U>();
|
||||
tests_map_empty<T,U>();
|
||||
tests_map_size<T,U>();
|
||||
tests_map_max_size<T,U>();
|
||||
tests_map_operator_access<T,U>();
|
||||
tests_map_insert<T,U>();
|
||||
tests_map_erase<T,U>();
|
||||
tests_map_swap<T,U>();
|
||||
tests_map_clear<T,U>();
|
||||
tests_map_key_comp<T,U>();
|
||||
tests_map_value_comp<T,U>();
|
||||
tests_map_find<T,U>();
|
||||
tests_map_count<T,U>();
|
||||
tests_map_lower_bound<T,U>();
|
||||
tests_map_upper_bound<T,U>();
|
||||
tests_map_equal_range<T,U>();
|
||||
tests_map_get_allocator<T,U>();
|
||||
tests_map_relational_operators<T,U>();
|
||||
tests_map_swap_non_member<T,U>();
|
||||
}
|
||||
|
||||
int main() {
|
||||
|
||||
call_tests<char,int>();
|
||||
call_tests<char,char>();
|
||||
call_tests<char,std::string>();
|
||||
call_tests<char,mystruct*>();
|
||||
call_tests<int,int>();
|
||||
call_tests<int,char>();
|
||||
call_tests<int,std::string>();
|
||||
call_tests<int,mystruct*>();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
862
tests/other_mains/main_map_2.cpp
Normal file
862
tests/other_mains/main_map_2.cpp
Normal file
@@ -0,0 +1,862 @@
|
||||
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <iomanip> // std::setw()
|
||||
#include <iterator> // std::reverse_iterator
|
||||
#include <utility> // std::make_pair
|
||||
#include <sstream> // std::stringstream
|
||||
#include <vector>
|
||||
|
||||
|
||||
// toogle between test ft and stl
|
||||
// *************************
|
||||
#include <map>
|
||||
#ifdef STL
|
||||
namespace ft = std;
|
||||
#else
|
||||
#include "vector.hpp"
|
||||
#include "map.hpp"
|
||||
#include "reverse_iterator.hpp"
|
||||
#endif
|
||||
|
||||
|
||||
// colors
|
||||
// *************************************************
|
||||
# define GRAY "\e[0;30m"
|
||||
# define RED "\e[0;31m"
|
||||
# define GREEN "\e[0;32m"
|
||||
# define YELLOW "\e[0;33m"
|
||||
# define BLUE "\e[0;34m"
|
||||
# define PURPLE "\e[0;35m"
|
||||
# define CYAN "\e[0;36m"
|
||||
# define WHITE "\e[0;37m"
|
||||
|
||||
# define B_GRAY "\e[1;30m"
|
||||
# define B_RED "\e[1;31m"
|
||||
# define B_GREEN "\e[1;32m"
|
||||
# define B_YELLOW "\e[1;33m"
|
||||
# define B_BLUE "\e[1;34m"
|
||||
# define B_PURPLE "\e[1;35m"
|
||||
# define B_CYAN "\e[1;36m"
|
||||
# define B_WHITE "\e[1;37m"
|
||||
|
||||
# define RESET "\e[0m"
|
||||
|
||||
|
||||
// defines
|
||||
// ****************************************
|
||||
# define TITLE(s) std::cout << "\n" B_PURPLE #s RESET "\n\n";
|
||||
# define VAL(n) val<T>(n)
|
||||
# define VALT(n) val<T>(n)
|
||||
# define VALU(n) val<U>(n)
|
||||
# define TOI(n) toi<T>(n)
|
||||
# define PRINT(n) print<>(n, #n);
|
||||
# define DELETE delete_structs();
|
||||
|
||||
|
||||
// adding each test to the list
|
||||
// ***************************
|
||||
#define TEST_V(f_name) \
|
||||
template <class T> struct s_ ## f_name : public A_test\
|
||||
{ void func(); };\
|
||||
void f_name () {\
|
||||
add_to_list("", "", NULL);\
|
||||
add_to_list(#f_name, "int", new(s_ ## f_name <int>));\
|
||||
add_to_list(#f_name, "char", new(s_ ## f_name <char>));\
|
||||
add_to_list(#f_name, "std::string", new(s_ ## f_name <std::string>));\
|
||||
add_to_list(#f_name, "mystruct*", new(s_ ## f_name <mystruct*>));\
|
||||
}\
|
||||
template <class T>\
|
||||
void s_ ## f_name <T>::func()
|
||||
|
||||
#define TEST_M(f_name) \
|
||||
template <class T, class U> struct s_ ## f_name : public A_test\
|
||||
{ void func(); };\
|
||||
void f_name () {\
|
||||
add_to_list("", "", NULL);\
|
||||
add_to_list(#f_name, "char, int", new(s_ ## f_name <char, int>));\
|
||||
add_to_list(#f_name, "char, char", new(s_ ## f_name <char, char>));\
|
||||
add_to_list(#f_name, "char, std::string", new(s_ ## f_name <char, std::string>));\
|
||||
add_to_list(#f_name, "char, mystruct*", new(s_ ## f_name <char, mystruct*>));\
|
||||
add_to_list(#f_name, "int, int", new(s_ ## f_name <int, int>));\
|
||||
add_to_list(#f_name, "int, char", new(s_ ## f_name <int, char>));\
|
||||
add_to_list(#f_name, "int, std::string", new(s_ ## f_name <int, std::string>));\
|
||||
add_to_list(#f_name, "int, mystruct*", new(s_ ## f_name <int, mystruct*>));\
|
||||
}\
|
||||
template <class T, class U>\
|
||||
void s_ ## f_name <T, U>::func()
|
||||
|
||||
|
||||
// structures
|
||||
// *********************************************
|
||||
struct A_test
|
||||
{
|
||||
virtual ~A_test(){};
|
||||
std::string title;
|
||||
std::string type;
|
||||
virtual void func() = 0;
|
||||
};
|
||||
|
||||
struct mystruct {
|
||||
public:
|
||||
mystruct(int data = 0)
|
||||
{_val = new int[2]; _val[0] = data; _val[1] = data;}
|
||||
~mystruct()
|
||||
{delete[] _val;}
|
||||
int * get_data() const
|
||||
{return _val;}
|
||||
private:
|
||||
int * _val;
|
||||
};
|
||||
std::ostream & operator<<(std::ostream & o, mystruct const * rhs) {
|
||||
if (rhs != NULL)
|
||||
o << (*rhs).get_data()[0] << "," << (*rhs).get_data()[1];
|
||||
else
|
||||
o << "NULL";
|
||||
return (o);
|
||||
}
|
||||
|
||||
|
||||
// global variables
|
||||
// ***************************************
|
||||
std::vector< std::vector<A_test*> > test_list;
|
||||
std::vector< mystruct* > mem_list;
|
||||
|
||||
|
||||
// functions utiles
|
||||
// ***************************************
|
||||
void add_to_list(std::string title, std::string type, A_test* test) {
|
||||
|
||||
std::vector<A_test*> test_sub_list;
|
||||
std::vector< std::vector<A_test*> >::iterator it;
|
||||
|
||||
// title != NULL for the first element
|
||||
if (test == NULL)
|
||||
{
|
||||
test_list.push_back(test_sub_list);
|
||||
return;
|
||||
}
|
||||
|
||||
test->title = title;
|
||||
test->type = type;
|
||||
it = test_list.end() - 1;
|
||||
(*it).push_back(test);
|
||||
}
|
||||
void delete_structs() {
|
||||
|
||||
std::vector<mystruct*>::iterator it;
|
||||
std::vector<mystruct*>::iterator it_end = mem_list.end();
|
||||
|
||||
for (it = mem_list.begin(); it != it_end; ++it)
|
||||
delete *it;
|
||||
mem_list.clear();
|
||||
}
|
||||
|
||||
|
||||
// templates print
|
||||
// *****************************************
|
||||
template <class T>
|
||||
void print(ft::vector<T> vec, std::string name) {
|
||||
|
||||
int i = 0;
|
||||
typename ft::vector<T>::iterator it;
|
||||
typename ft::vector<T>::iterator it_end = vec.end();
|
||||
|
||||
std::cout << "\n" << name << ":(vector)\n";
|
||||
for (it = vec.begin(); it != it_end; ++it, i++)
|
||||
std::cout << "[" << i << "]" << *it << " ";
|
||||
std::cout << "\nsize:" << vec.size() << " capacty:" << vec.capacity() << "\n";
|
||||
}
|
||||
template <class T, class U>
|
||||
void print(ft::map<T, U> mp, std::string name) {
|
||||
|
||||
int i = 0;
|
||||
typename ft::map<T, U>::iterator it;
|
||||
typename ft::map<T, U>::iterator it_end = mp.end();
|
||||
|
||||
std::cout << "\n" << name << ":(map)\n";
|
||||
for (it = mp.begin(); it != it_end; ++it, i++)
|
||||
std::cout << "[" << i << "]" << it->first << ":" << it->second << " ";
|
||||
std::cout << "\nsize:" << mp.size() << "\n";
|
||||
}
|
||||
|
||||
// templates get value
|
||||
// *************************************
|
||||
// specialization in header, make it inline :
|
||||
// https://stackoverflow.com/questions/63529059/c-specialized-method-templates-produce-multiple-definition-errors
|
||||
template <class T>
|
||||
T val(int n) { (void)n; return (T()); }
|
||||
template <>
|
||||
inline int val(int n) { return (n); }
|
||||
template <>
|
||||
inline char val(int n) {
|
||||
|
||||
if (n <= 126 && n >= 33)
|
||||
return n;
|
||||
return (n % 94 + 33);
|
||||
}
|
||||
template <>
|
||||
inline std::string val(int n) {
|
||||
|
||||
std::string str;
|
||||
std::stringstream stream;
|
||||
|
||||
stream << n;
|
||||
stream >> str;
|
||||
stream.clear();
|
||||
return (str);
|
||||
}
|
||||
template <>
|
||||
inline mystruct* val(int n) {
|
||||
|
||||
mystruct *s = new mystruct(n);
|
||||
mem_list.push_back(s);
|
||||
return ( s );
|
||||
}
|
||||
template <class T>
|
||||
T val(std::string str) { (void)str; return (T()); }
|
||||
template <>
|
||||
inline int val(std::string str) { int i = str[0]; return (val<int>(i)); }
|
||||
template <>
|
||||
inline char val(std::string str) { int i = str[0]; return (val<char>(i)); }
|
||||
template <>
|
||||
inline std::string val(std::string str) { return (str); }
|
||||
template <>
|
||||
inline mystruct* val(std::string str) { int i = str[0]; return (val<mystruct*>(i)); }
|
||||
|
||||
|
||||
// templates to value
|
||||
// **************************************
|
||||
template <class T>
|
||||
int toi(T t) {(void)t; return (0);
|
||||
}
|
||||
template <>
|
||||
inline int toi(int i) {return (i);
|
||||
}
|
||||
template <>
|
||||
inline int toi(char c) {return (c);
|
||||
}
|
||||
template <>
|
||||
inline int toi(std::string str) {
|
||||
|
||||
int i;
|
||||
std::stringstream stream;
|
||||
|
||||
stream << str;
|
||||
stream >> i;
|
||||
stream.clear();
|
||||
return (i);
|
||||
}
|
||||
template <>
|
||||
inline int toi(mystruct* s) {
|
||||
|
||||
return ( s->get_data()[0] );
|
||||
}
|
||||
|
||||
|
||||
// tests functions
|
||||
// *****************************************
|
||||
TEST_M(tests_map_operator_assignation)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference)
|
||||
|
||||
ft::map<T,U> first;
|
||||
ft::map<T,U> second;
|
||||
|
||||
first[VALT('x')]=VALU(8);
|
||||
first[VALT('y')]=VALU(16);
|
||||
first[VALT('z')]=VALU(32);
|
||||
|
||||
PRINT(first)
|
||||
PRINT(second)
|
||||
|
||||
second=first; // second now contains 3 ints
|
||||
first=ft::map<T,U>(); // and first is now empty
|
||||
|
||||
std::cout << "Size of first: " << first.size() << '\n';
|
||||
std::cout << "Size of second: " << second.size() << '\n';
|
||||
|
||||
PRINT(first)
|
||||
PRINT(second)
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_M(tests_map_begin)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference)
|
||||
|
||||
ft::map<T,U> mymap;
|
||||
|
||||
mymap[VALT('b')] = VALU(100);
|
||||
mymap[VALT('a')] = VALU(200);
|
||||
mymap[VALT('c')] = VALU(300);
|
||||
|
||||
PRINT(mymap)
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_M(tests_map_end)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference)
|
||||
|
||||
ft::map<T,U> mymap;
|
||||
|
||||
mymap[VALT('b')] = VALU(100);
|
||||
mymap[VALT('a')] = VALU(200);
|
||||
mymap[VALT('c')] = VALU(300);
|
||||
|
||||
PRINT(mymap)
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_M(tests_map_rbegin)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference)
|
||||
|
||||
ft::map<T,U> mymap;
|
||||
|
||||
mymap[VALT('x')] = VALU(100);
|
||||
mymap[VALT('y')] = VALU(200);
|
||||
mymap[VALT('z')] = VALU(300);
|
||||
|
||||
// show content:
|
||||
typename ft::map<T,U>::reverse_iterator rit;
|
||||
for (rit=mymap.rbegin(); rit!=mymap.rend(); ++rit)
|
||||
std::cout << rit->first << " => " << rit->second << '\n';
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_M(tests_map_rend)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference)
|
||||
|
||||
ft::map<T,U> mymap;
|
||||
|
||||
mymap[VALT('x')] = VALU(100);
|
||||
mymap[VALT('y')] = VALU(200);
|
||||
mymap[VALT('z')] = VALU(300);
|
||||
|
||||
// show content:
|
||||
typename ft::map<T,U>::reverse_iterator rit;
|
||||
for (rit=mymap.rbegin(); rit!=mymap.rend(); ++rit)
|
||||
std::cout << rit->first << " => " << rit->second << '\n';
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_M(tests_map_empty)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference)
|
||||
|
||||
ft::map<T,U> mymap;
|
||||
|
||||
mymap[VALT('a')]=VALU(10);
|
||||
mymap[VALT('b')]=VALU(20);
|
||||
mymap[VALT('c')]=VALU(30);
|
||||
|
||||
while (!mymap.empty())
|
||||
{
|
||||
std::cout << mymap.begin()->first << " => " << mymap.begin()->second << '\n';
|
||||
mymap.erase(mymap.begin());
|
||||
}
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_M(tests_map_size)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference)
|
||||
|
||||
ft::map<T,U> mymap;
|
||||
mymap[VALT('a')]=VALU(101);
|
||||
mymap[VALT('b')]=VALU(202);
|
||||
mymap[VALT('c')]=VALU(302);
|
||||
|
||||
std::cout << "mymap.size() is " << mymap.size() << '\n';
|
||||
|
||||
PRINT(mymap)
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_M(tests_map_max_size)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference)
|
||||
|
||||
int i;
|
||||
std::map<T,U> mymap;
|
||||
|
||||
if (mymap.max_size()>1000)
|
||||
{
|
||||
for (i=0; i<1000; i++) mymap[i]=VALU(0);
|
||||
std::cout << "The map contains 1000 elements.\n";
|
||||
}
|
||||
else std::cout << "The map could not hold 1000 elements.\n";
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_M(tests_map_operator_access)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference)
|
||||
|
||||
ft::map<T,U> mymap;
|
||||
|
||||
mymap[VALT('a')]=VALU("An element");
|
||||
mymap[VALT('b')]=VALU("another element");
|
||||
mymap[VALT('c')]=mymap[VAL('b')];
|
||||
|
||||
std::cout << "mymap['a'] is " << mymap[VALT('a')] << '\n';
|
||||
std::cout << "mymap['b'] is " << mymap[VALT('b')] << '\n';
|
||||
std::cout << "mymap['c'] is " << mymap[VALT('c')] << '\n';
|
||||
std::cout << "mymap['d'] is " << mymap[VALT('d')] << '\n';
|
||||
|
||||
std::cout << "mymap now contains " << mymap.size() << " elements.\n";
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_M(tests_map_insert)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference)
|
||||
|
||||
ft::map<T,U> mymap;
|
||||
|
||||
// first insert function version (single parameter):
|
||||
mymap.insert ( ft::pair<T,U>(VALT('a'),VALU(100)) );
|
||||
mymap.insert ( ft::pair<T,U>(VALT('z'),VALU(200)) );
|
||||
|
||||
ft::pair<typename ft::map<T,U>::iterator, bool> ret;
|
||||
ret = mymap.insert ( ft::pair<T,U>(VALT('z'),VALU(500)) );
|
||||
if (ret.second==false) {
|
||||
std::cout << "element 'z' already existed";
|
||||
std::cout << " with a value of " << ret.first->second << '\n';
|
||||
}
|
||||
|
||||
|
||||
// second insert function version (with hint position):
|
||||
typename ft::map<T,U>::iterator it = mymap.begin();
|
||||
mymap.insert (it, ft::pair<T,U>(VALT('b'),VALU(300))); // max efficiency inserting
|
||||
mymap.insert (it, ft::pair<T,U>(VALT('c'),VALU(400))); // no max efficiency inserting
|
||||
|
||||
// third insert function version (range insertion):
|
||||
ft::map<T,U> anothermap;
|
||||
anothermap.insert(mymap.begin(),mymap.find('c'));
|
||||
|
||||
PRINT(mymap)
|
||||
PRINT(anothermap)
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_M(tests_map_erase)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference)
|
||||
|
||||
ft::map<T,U> mymap;
|
||||
typename ft::map<T,U>::iterator it;
|
||||
|
||||
// insert some values:
|
||||
mymap[VALT('a')]=VALU(10);
|
||||
mymap[VALT('b')]=VALU(20);
|
||||
mymap[VALT('c')]=VALU(30);
|
||||
mymap[VALT('d')]=VALU(40);
|
||||
mymap[VALT('e')]=VALU(50);
|
||||
mymap[VALT('f')]=VALU(60);
|
||||
|
||||
it=mymap.find(VALT('b'));
|
||||
mymap.erase (it); // erasing by iterator
|
||||
|
||||
mymap.erase (VALT('c')); // erasing by key
|
||||
|
||||
it=mymap.find (VALT('e'));
|
||||
mymap.erase ( it, mymap.end() ); // erasing by range
|
||||
|
||||
PRINT(mymap)
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_M(tests_map_swap)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference)
|
||||
|
||||
ft::map<T,U> foo,bar;
|
||||
|
||||
foo[VALT('x')]=VALU(100);
|
||||
foo[VALT('y')]=VALU(200);
|
||||
|
||||
bar[VALT('a')]=VALU(11);
|
||||
bar[VALT('b')]=VALU(22);
|
||||
bar[VALT('c')]=VALU(33);
|
||||
|
||||
foo.swap(bar);
|
||||
|
||||
PRINT(foo)
|
||||
PRINT(bar)
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_M(tests_map_clear)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference)
|
||||
|
||||
ft::map<T,U> mymap;
|
||||
|
||||
mymap[VALT('x')]=VALU(100);
|
||||
mymap[VALT('y')]=VALU(200);
|
||||
mymap[VALT('z')]=VALU(300);
|
||||
|
||||
PRINT(mymap)
|
||||
|
||||
mymap.clear();
|
||||
mymap[VALT('a')]=VALU(1101);
|
||||
mymap[VALT('b')]=VALU(2202);
|
||||
|
||||
PRINT(mymap)
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_M(tests_map_key_comp)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference)
|
||||
|
||||
ft::map<T,U> mymap;
|
||||
|
||||
typename ft::map<T,U>::key_compare mycomp = mymap.key_comp();
|
||||
|
||||
mymap[VALT('a')]=VALU(100);
|
||||
mymap[VALT('b')]=VALU(200);
|
||||
mymap[VALT('c')]=VALU(300);
|
||||
|
||||
std::cout << "mymap contains:\n";
|
||||
|
||||
T highest = mymap.rbegin()->first; // key value of last element
|
||||
|
||||
typename ft::map<T,U>::iterator it = mymap.begin();
|
||||
do {
|
||||
std::cout << it->first << " => " << it->second << '\n';
|
||||
} while ( mycomp((*it++).first, highest) );
|
||||
|
||||
std::cout << '\n';
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_M(tests_map_value_comp)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference)
|
||||
|
||||
ft::map<T,U> mymap;
|
||||
|
||||
mymap[VALT('x')]=VALU(1001);
|
||||
mymap[VALT('y')]=VALU(2002);
|
||||
mymap[VALT('z')]=VALU(3003);
|
||||
|
||||
std::cout << "mymap contains:\n";
|
||||
|
||||
ft::pair<T,U> highest = *mymap.rbegin(); // last element
|
||||
|
||||
typename ft::map<T,U>::iterator it = mymap.begin();
|
||||
do {
|
||||
std::cout << it->first << " => " << it->second << '\n';
|
||||
} while ( mymap.value_comp()(*it++, highest) );
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_M(tests_map_find)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference)
|
||||
|
||||
ft::map<T,U> mymap;
|
||||
typename ft::map<T,U>::iterator it;
|
||||
|
||||
mymap[VALT('a')]=VALU(50);
|
||||
mymap[VALT('b')]=VALU(100);
|
||||
mymap[VALT('c')]=VALU(150);
|
||||
mymap[VALT('d')]=VALU(200);
|
||||
|
||||
it = mymap.find(VALT('b'));
|
||||
if (it != mymap.end())
|
||||
mymap.erase (it);
|
||||
|
||||
// print content:
|
||||
std::cout << "elements in mymap:" << '\n';
|
||||
std::cout << "a => " << mymap.find(VALT('a'))->second << '\n';
|
||||
std::cout << "c => " << mymap.find(VALT('c'))->second << '\n';
|
||||
std::cout << "d => " << mymap.find(VALT('d'))->second << '\n';
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_M(tests_map_count)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference)
|
||||
|
||||
ft::map<T,U> mymap;
|
||||
T c;
|
||||
|
||||
mymap [VALT('a')]=VALU(101);
|
||||
mymap [VALT('c')]=VALU(202);
|
||||
mymap [VALT('f')]=VALU(303);
|
||||
|
||||
// to do this test with T as a 'string' or 'mystruct*' we should add overload
|
||||
for (c=VALT('a'); c<VALT('h'); c++)
|
||||
{
|
||||
std::cout << c;
|
||||
if (mymap.count(c)>0)
|
||||
std::cout << " is an element of mymap.\n";
|
||||
else
|
||||
std::cout << " is not an element of mymap.\n";
|
||||
}
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_M(tests_map_lower_bound)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference)
|
||||
|
||||
ft::map<T,U> mymap;
|
||||
typename ft::map<T,U>::iterator itlow,itup;
|
||||
|
||||
mymap[VALT('a')]=VALU(20);
|
||||
mymap[VALT('b')]=VALU(40);
|
||||
mymap[VALT('c')]=VALU(60);
|
||||
mymap[VALT('d')]=VALU(80);
|
||||
mymap[VALT('e')]=VALU(100);
|
||||
|
||||
itlow=mymap.lower_bound (VALT('b')); // itlow points to b
|
||||
itup=mymap.upper_bound (VALT('d')); // itup points to e (not d!)
|
||||
|
||||
mymap.erase(itlow,itup); // erases [itlow,itup)
|
||||
|
||||
PRINT(mymap)
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_M(tests_map_upper_bound)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference)
|
||||
|
||||
ft::map<T,U> mymap;
|
||||
typename ft::map<T,U>::iterator itlow,itup;
|
||||
|
||||
mymap[VALT('a')]=VALU(20);
|
||||
mymap[VALT('b')]=VALU(40);
|
||||
mymap[VALT('c')]=VALU(60);
|
||||
mymap[VALT('d')]=VALU(80);
|
||||
mymap[VALT('e')]=VALU(100);
|
||||
|
||||
itlow=mymap.lower_bound (VALT('b')); // itlow points to b
|
||||
itup=mymap.upper_bound (VALT('d')); // itup points to e (not d!)
|
||||
|
||||
mymap.erase(itlow,itup); // erases [itlow,itup)
|
||||
|
||||
PRINT(mymap)
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_M(tests_map_equal_range)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference)
|
||||
|
||||
ft::map<T,U> mymap;
|
||||
|
||||
mymap[VALT('a')]=VALU(10);
|
||||
mymap[VALT('b')]=VALU(20);
|
||||
mymap[VALT('c')]=VALU(30);
|
||||
|
||||
ft::pair<typename ft::map<T,U>::iterator,typename ft::map<T,U>::iterator> ret;
|
||||
ret = mymap.equal_range(VALT('b'));
|
||||
|
||||
std::cout << "lower bound points to: ";
|
||||
std::cout << ret.first->first << " => " << ret.first->second << '\n';
|
||||
|
||||
std::cout << "upper bound points to: ";
|
||||
std::cout << ret.second->first << " => " << ret.second->second << '\n';
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_M(tests_map_get_allocator)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference)
|
||||
|
||||
int psize;
|
||||
ft::map<T,U> mymap;
|
||||
ft::pair<const T,U>* p;
|
||||
|
||||
// allocate an array of 5 elements using mymap's allocator:
|
||||
p=mymap.get_allocator().allocate(5);
|
||||
|
||||
// assign some values to array
|
||||
psize = sizeof(typename ft::map<T,U>::value_type)*5;
|
||||
|
||||
std::cout << "The allocated array has a size of " << psize << " bytes.\n";
|
||||
|
||||
mymap.get_allocator().deallocate(p,5);
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_M(tests_map_relational_operators)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference)
|
||||
|
||||
ft::map<T,U> alice;
|
||||
ft::map<T,U> bob;
|
||||
ft::map<T,U> eve;
|
||||
(void)alice;
|
||||
(void)bob;
|
||||
(void)eve;
|
||||
|
||||
alice[VALT(1)]=VALU('a');
|
||||
alice[VALT(2)]=VALU('b');
|
||||
alice[VALT(3)]=VALU('c');
|
||||
|
||||
bob[VALT(7)]=VALU('Z');
|
||||
bob[VALT(8)]=VALU('Y');
|
||||
bob[VALT(9)]=VALU('X');
|
||||
bob[VALT(10)]=VALU('W');
|
||||
|
||||
eve[VALT(1)]=VALU('a');
|
||||
eve[VALT(2)]=VALU('b');
|
||||
eve[VALT(3)]=VALU('c');
|
||||
|
||||
std::cout << std::boolalpha;
|
||||
|
||||
// Compare non equal containers
|
||||
std::cout << "alice == bob returns " << (alice == bob) << '\n';
|
||||
std::cout << "alice != bob returns " << (alice != bob) << '\n';
|
||||
std::cout << "alice < bob returns " << (alice < bob) << '\n';
|
||||
std::cout << "alice <= bob returns " << (alice <= bob) << '\n';
|
||||
std::cout << "alice > bob returns " << (alice > bob) << '\n';
|
||||
std::cout << "alice >= bob returns " << (alice >= bob) << '\n';
|
||||
|
||||
std::cout << '\n';
|
||||
|
||||
// Compare equal containers
|
||||
std::cout << "alice == eve returns " << (alice == eve) << '\n';
|
||||
std::cout << "alice != eve returns " << (alice != eve) << '\n';
|
||||
std::cout << "alice < eve returns " << (alice < eve) << '\n';
|
||||
std::cout << "alice <= eve returns " << (alice <= eve) << '\n';
|
||||
std::cout << "alice > eve returns " << (alice > eve) << '\n';
|
||||
std::cout << "alice >= eve returns " << (alice >= eve) << '\n';
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
|
||||
TEST_M(tests_map_swap_non_member)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference)
|
||||
|
||||
ft::map<T, U> alice;
|
||||
ft::map<T, U> bob;
|
||||
|
||||
alice[VALT(1)]=VALU('a');
|
||||
alice[VALT(2)]=VALU('b');
|
||||
alice[VALT(3)]=VALU('c');
|
||||
|
||||
bob[VALT(7)]=VALU('Z');
|
||||
bob[VALT(8)]=VALU('Y');
|
||||
bob[VALT(9)]=VALU('X');
|
||||
bob[VALT(10)]=VALU('W');
|
||||
|
||||
// Print state before swap
|
||||
PRINT(alice)
|
||||
PRINT(bob)
|
||||
|
||||
std::cout << "-- SWAP\n";
|
||||
std::swap(alice, bob);
|
||||
|
||||
// Print state after swap
|
||||
PRINT(alice)
|
||||
PRINT(bob)
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
|
||||
int main() {
|
||||
|
||||
tests_map_operator_assignation();
|
||||
tests_map_begin();
|
||||
tests_map_end();
|
||||
tests_map_rbegin();
|
||||
tests_map_rend();
|
||||
tests_map_empty();
|
||||
tests_map_size();
|
||||
tests_map_max_size();
|
||||
tests_map_operator_access();
|
||||
tests_map_insert();
|
||||
tests_map_erase();
|
||||
tests_map_swap();
|
||||
tests_map_clear();
|
||||
tests_map_key_comp();
|
||||
tests_map_value_comp();
|
||||
tests_map_find();
|
||||
tests_map_count();
|
||||
tests_map_lower_bound();
|
||||
tests_map_upper_bound();
|
||||
tests_map_equal_range();
|
||||
tests_map_get_allocator();
|
||||
tests_map_relational_operators();
|
||||
tests_map_swap_non_member();
|
||||
|
||||
|
||||
// execute tests and print them :
|
||||
int size = test_list.size();
|
||||
int sub_size;
|
||||
for(int i = 0; i < size; i++)
|
||||
{
|
||||
std::cout << "\n" B_YELLOW "[" << i + 1 << "/" << size << "] "
|
||||
<< test_list[i][0]->title << RESET << "\n";
|
||||
sub_size = test_list[i].size();
|
||||
for (int j = 0; j < sub_size; j++)
|
||||
{
|
||||
std::cout << "\n" << B_CYAN << "-- " << test_list[i][j]->type
|
||||
<< " --" << RESET "\n";
|
||||
test_list[i][j]->func();
|
||||
delete test_list[i][j];
|
||||
}
|
||||
}
|
||||
std::cout << "\n";
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
187
tests/other_mains/main_stack_1.cpp
Normal file
187
tests/other_mains/main_stack_1.cpp
Normal file
@@ -0,0 +1,187 @@
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <iomanip> // std::setw()
|
||||
#include <iterator> // std::reverse_iterator
|
||||
#include <utility> // std::make_pair
|
||||
#include <sstream> // std::stringstream
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <stack>
|
||||
|
||||
// toogle ft in stl
|
||||
#ifdef STL
|
||||
namespace ft = std;
|
||||
#else
|
||||
#include "vector.hpp"
|
||||
#include "map.hpp"
|
||||
#include "stack.hpp"
|
||||
#include "reverse_iterator.hpp"
|
||||
#endif
|
||||
|
||||
// defines
|
||||
# define TEST(s) template <class T> void s ()
|
||||
# define TITLE(s) std::cout << "\n" B_PURPLE #s RESET "\n\n";
|
||||
# define VAL(n) val<T>(n)
|
||||
# define TOI(n) toi<T>(n)
|
||||
# define PRINT(n) print<>(n, #n);
|
||||
# define DELETE delete_structs();
|
||||
|
||||
// colors
|
||||
# define GRAY "\e[0;30m"
|
||||
# define RED "\e[0;31m"
|
||||
# define GREEN "\e[0;32m"
|
||||
# define YELLOW "\e[0;33m"
|
||||
# define BLUE "\e[0;34m"
|
||||
# define PURPLE "\e[0;35m"
|
||||
# define CYAN "\e[0;36m"
|
||||
# define WHITE "\e[0;37m"
|
||||
|
||||
# define B_GRAY "\e[1;30m"
|
||||
# define B_RED "\e[1;31m"
|
||||
# define B_GREEN "\e[1;32m"
|
||||
# define B_YELLOW "\e[1;33m"
|
||||
# define B_BLUE "\e[1;34m"
|
||||
# define B_PURPLE "\e[1;35m"
|
||||
# define B_CYAN "\e[1;36m"
|
||||
# define B_WHITE "\e[1;37m"
|
||||
|
||||
# define RESET "\e[0m"
|
||||
|
||||
// mystruct declaration
|
||||
struct mystruct {
|
||||
public:
|
||||
mystruct(int data = 0);
|
||||
~mystruct();
|
||||
int * get_data() const;
|
||||
private:
|
||||
int * _val;
|
||||
};
|
||||
std::ostream & operator<<(std::ostream & o, mystruct const * rhs);
|
||||
|
||||
// mystruct definition
|
||||
mystruct::mystruct(int data)
|
||||
{_val = new int[2]; _val[0] = data; _val[1] = data;}
|
||||
mystruct::~mystruct()
|
||||
{delete[] _val;}
|
||||
int * mystruct::get_data() const
|
||||
{return _val;}
|
||||
std::ostream & operator<<(std::ostream & o, mystruct const * rhs) {
|
||||
if (rhs != NULL)
|
||||
o << (*rhs).get_data()[0] << "," << (*rhs).get_data()[1];
|
||||
else
|
||||
o << "NULL";
|
||||
return (o);
|
||||
}
|
||||
|
||||
// global variable for mem gestion of mystruct
|
||||
std::vector< mystruct* > mem_list;
|
||||
|
||||
// template print function
|
||||
template <class T, class cont>
|
||||
void print(ft::stack<T,cont>& st, std::string name) {
|
||||
|
||||
std::cout << "\n" << name << ":(map)\n";
|
||||
for (int i = st.size(); i > 0 ; i--, st.pop())
|
||||
std::cout << "[" << i << "]" << st.top() << " ";
|
||||
std::cout << "\nsize:" << st.size() << "\n";
|
||||
}
|
||||
|
||||
// template val() for instanciation of values for types :
|
||||
// int, char, std::string, and mystruct*
|
||||
template <class T>
|
||||
T val(int n) { (void)n; return (T()); }
|
||||
template <>
|
||||
inline int val(int n) { return (n); }
|
||||
template <>
|
||||
inline char val(int n) {
|
||||
|
||||
if (n <= 126 && n >= 33)
|
||||
return n;
|
||||
return (n % 94 + 33);
|
||||
}
|
||||
template <>
|
||||
inline std::string val(int n) {
|
||||
|
||||
std::string str;
|
||||
std::stringstream stream;
|
||||
|
||||
stream << n;
|
||||
stream >> str;
|
||||
stream.clear();
|
||||
return (str);
|
||||
}
|
||||
template <>
|
||||
inline mystruct* val(int n) {
|
||||
|
||||
mystruct *s = new mystruct(n);
|
||||
mem_list.push_back(s);
|
||||
return ( s );
|
||||
}
|
||||
template <class T>
|
||||
T val(std::string str) { (void)str; return (T()); }
|
||||
template <>
|
||||
inline int val(std::string str) { int i = str[0]; return (val<int>(i)); }
|
||||
template <>
|
||||
inline char val(std::string str) { int i = str[0]; return (val<char>(i)); }
|
||||
template <>
|
||||
inline std::string val(std::string str) { return (str); }
|
||||
template <>
|
||||
inline mystruct* val(std::string str) { int i = str[0]; return (val<mystruct*>(i)); }
|
||||
|
||||
// delete function for mem gestion of mystruct*
|
||||
void delete_structs() {
|
||||
|
||||
std::vector<mystruct*>::iterator it;
|
||||
std::vector<mystruct*>::iterator it_end = mem_list.end();
|
||||
|
||||
for (it = mem_list.begin(); it != it_end; ++it)
|
||||
delete *it;
|
||||
mem_list.clear();
|
||||
}
|
||||
|
||||
// all tests
|
||||
TEST(tests_stack_constructor)
|
||||
{
|
||||
// title
|
||||
TITLE(simple test)
|
||||
|
||||
std::deque<T> mydeque (3,VAL(100)); // deque with 3 elements
|
||||
std::vector<T> myvector (2,VAL(200)); // vector with 2 elements
|
||||
|
||||
ft::stack<T> first; // empty stack
|
||||
ft::stack<T> second (mydeque); // stack initialized to copy of deque
|
||||
|
||||
// ft::stack< T,std::vector<T> > third; // empty stack using vector
|
||||
// ft::stack< T,std::vector<T> > fourth (myvector);
|
||||
//
|
||||
// std::cout << "size of first: " << first.size() << '\n';
|
||||
// std::cout << "size of second: " << second.size() << '\n';
|
||||
// std::cout << "size of third: " << third.size() << '\n';
|
||||
// std::cout << "size of fourth: " << fourth.size() << '\n';
|
||||
//
|
||||
// PRINT(first)
|
||||
// PRINT(second)
|
||||
// PRINT(third)
|
||||
// PRINT(fourth)
|
||||
//
|
||||
// DELETE
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void call_tests() {
|
||||
|
||||
tests_stack_constructor<T>();
|
||||
}
|
||||
|
||||
int main() {
|
||||
|
||||
call_tests<int>();
|
||||
// call_tests<char>();
|
||||
// call_tests<std::string>();
|
||||
// call_tests<mystruct*>();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
19
tests/test.sh
Normal file
19
tests/test.sh
Normal file
@@ -0,0 +1,19 @@
|
||||
#!/bin/bash
|
||||
# cd $(dirname $0)
|
||||
|
||||
TEST_DIR=$(dirname $0)
|
||||
OUTPUT_STL="output_stl.log"
|
||||
OUTPUT_FT="output_ft.log"
|
||||
|
||||
#make -j > /dev/null
|
||||
make -j
|
||||
|
||||
echo -e "\nstl :"
|
||||
time ./containers_stl > tests/$OUTPUT_STL
|
||||
|
||||
echo -e "\nft :"
|
||||
time ./containers_ft > tests/$OUTPUT_FT
|
||||
|
||||
diff --context=0 --color=always tests/$OUTPUT_STL tests/$OUTPUT_FT
|
||||
|
||||
#/bin/rm $TEST_DIR/$OUTPUT_STL $TEST_DIR/$OUTPUT_FT
|
||||
50
tests/tests_definitions.cpp
Normal file
50
tests/tests_definitions.cpp
Normal file
@@ -0,0 +1,50 @@
|
||||
|
||||
#include "tests_utils.hpp"
|
||||
|
||||
|
||||
// functions
|
||||
// **********************************************
|
||||
void add_to_list(std::string title, std::string type, A_test* test) {
|
||||
|
||||
std::vector<A_test*> test_sub_list;
|
||||
std::vector< std::vector<A_test*> >::iterator it;
|
||||
|
||||
// title != NULL for the first element
|
||||
if (test == NULL)
|
||||
{
|
||||
test_list.push_back(test_sub_list);
|
||||
return;
|
||||
}
|
||||
|
||||
test->title = title;
|
||||
test->type = type;
|
||||
it = test_list.end() - 1;
|
||||
(*it).push_back(test);
|
||||
}
|
||||
void delete_structs() {
|
||||
|
||||
std::vector<mystruct*>::iterator it;
|
||||
std::vector<mystruct*>::iterator it_end = mem_list.end();
|
||||
|
||||
for (it = mem_list.begin(); it != it_end; ++it)
|
||||
delete *it;
|
||||
mem_list.clear();
|
||||
}
|
||||
|
||||
|
||||
// mystruct
|
||||
// ***********************************************
|
||||
mystruct::mystruct(int data)
|
||||
{_val = new int[2]; _val[0] = data; _val[1] = data;}
|
||||
mystruct::~mystruct()
|
||||
{delete[] _val;}
|
||||
int * mystruct::get_data() const
|
||||
{return _val;}
|
||||
std::ostream & operator<<(std::ostream & o, mystruct const * rhs) {
|
||||
if (rhs != NULL)
|
||||
o << (*rhs).get_data()[0] << "," << (*rhs).get_data()[1];
|
||||
else
|
||||
o << "NULL";
|
||||
return (o);
|
||||
}
|
||||
|
||||
739
tests/tests_map.cpp
Normal file
739
tests/tests_map.cpp
Normal file
@@ -0,0 +1,739 @@
|
||||
|
||||
#include "tests_map.hpp"
|
||||
|
||||
|
||||
/**/ // UTILS for some tests
|
||||
/**/ bool fncomp (char lhs, char rhs) {return lhs<rhs;}
|
||||
/**/
|
||||
/**/ struct classcomp {
|
||||
/**/ bool operator() (const char& lhs, const char& rhs) const
|
||||
/**/ {return lhs<rhs;}
|
||||
/**/ };
|
||||
/**/ ///////////////////////
|
||||
|
||||
TEST_M(tests_map_simple)
|
||||
{
|
||||
// title
|
||||
TITLE(simple test)
|
||||
|
||||
typename ft::map<T, U> mp;
|
||||
typename std::map<T, U>::iterator it;
|
||||
|
||||
mp[VALT('a')] = VALU(10);
|
||||
|
||||
PRINT(mp)
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_M(tests_map_constructor)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference)
|
||||
|
||||
ft::map<T,U> first;
|
||||
|
||||
first[VALT('a')]=VALU(10);
|
||||
first[VALT('b')]=VALU(30);
|
||||
first[VALT('c')]=VALU(50);
|
||||
first[VALT('d')]=VALU(70);
|
||||
|
||||
ft::map<T,U> second (first.begin(),first.end());
|
||||
|
||||
ft::map<T,U> third (second);
|
||||
|
||||
ft::map<T,U,classcomp> fourth; // class as Compare
|
||||
|
||||
bool(*fn_pt)(char,char) = fncomp;
|
||||
ft::map<T,U,bool(*)(char,char)> fifth (fn_pt); // function pointer as Compare
|
||||
|
||||
PRINT(first)
|
||||
PRINT(second)
|
||||
PRINT(third)
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_M(tests_map_operator_assignation)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference)
|
||||
|
||||
ft::map<T,U> first;
|
||||
ft::map<T,U> second;
|
||||
|
||||
first[VALT('x')]=VALU(8);
|
||||
first[VALT('y')]=VALU(16);
|
||||
first[VALT('z')]=VALU(32);
|
||||
|
||||
PRINT(first)
|
||||
PRINT(second)
|
||||
|
||||
second=first; // second now contains 3 ints
|
||||
first=ft::map<T,U>(); // and first is now empty
|
||||
|
||||
std::cout << "Size of first: " << first.size() << '\n';
|
||||
std::cout << "Size of second: " << second.size() << '\n';
|
||||
|
||||
PRINT(first)
|
||||
PRINT(second)
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_M(tests_map_begin)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference)
|
||||
|
||||
ft::map<T,U> mymap;
|
||||
|
||||
mymap[VALT('b')] = VALU(100);
|
||||
mymap[VALT('a')] = VALU(200);
|
||||
mymap[VALT('c')] = VALU(300);
|
||||
|
||||
PRINT(mymap)
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_M(tests_map_end)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference)
|
||||
|
||||
ft::map<T,U> mymap;
|
||||
|
||||
mymap[VALT('b')] = VALU(100);
|
||||
mymap[VALT('a')] = VALU(200);
|
||||
mymap[VALT('c')] = VALU(300);
|
||||
|
||||
PRINT(mymap)
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_M(tests_map_rbegin)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference)
|
||||
|
||||
ft::map<T,U> mymap;
|
||||
|
||||
mymap[VALT('x')] = VALU(100);
|
||||
mymap[VALT('y')] = VALU(200);
|
||||
mymap[VALT('z')] = VALU(300);
|
||||
|
||||
// show content:
|
||||
typename ft::map<T,U>::reverse_iterator rit;
|
||||
for (rit=mymap.rbegin(); rit!=mymap.rend(); ++rit)
|
||||
std::cout << rit->first << " => " << rit->second << '\n';
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_M(tests_map_rend)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference)
|
||||
|
||||
ft::map<T,U> mymap;
|
||||
|
||||
mymap[VALT('x')] = VALU(100);
|
||||
mymap[VALT('y')] = VALU(200);
|
||||
mymap[VALT('z')] = VALU(300);
|
||||
|
||||
// show content:
|
||||
typename ft::map<T,U>::reverse_iterator rit;
|
||||
for (rit=mymap.rbegin(); rit!=mymap.rend(); ++rit)
|
||||
std::cout << rit->first << " => " << rit->second << '\n';
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_M(tests_map_empty)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference)
|
||||
|
||||
ft::map<T,U> mymap;
|
||||
|
||||
mymap[VALT('a')]=VALU(10);
|
||||
mymap[VALT('b')]=VALU(20);
|
||||
mymap[VALT('c')]=VALU(30);
|
||||
|
||||
while (!mymap.empty())
|
||||
{
|
||||
std::cout << mymap.begin()->first << " => " << mymap.begin()->second << '\n';
|
||||
mymap.erase(mymap.begin());
|
||||
}
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_M(tests_map_size)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference)
|
||||
|
||||
ft::map<T,U> mymap;
|
||||
mymap[VALT('a')]=VALU(101);
|
||||
mymap[VALT('b')]=VALU(202);
|
||||
mymap[VALT('c')]=VALU(302);
|
||||
|
||||
std::cout << "mymap.size() is " << mymap.size() << '\n';
|
||||
|
||||
PRINT(mymap)
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_M(tests_map_max_size)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference)
|
||||
|
||||
int i;
|
||||
std::map<T,U> mymap;
|
||||
|
||||
if (mymap.max_size()>1000)
|
||||
{
|
||||
for (i=0; i<1000; i++) mymap[i]=VALU(0);
|
||||
std::cout << "The map contains 1000 elements.\n";
|
||||
}
|
||||
else std::cout << "The map could not hold 1000 elements.\n";
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_M(tests_map_operator_access)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference)
|
||||
|
||||
ft::map<T,U> mymap;
|
||||
|
||||
mymap[VALT('a')]=VALU("An element");
|
||||
mymap[VALT('b')]=VALU("another element");
|
||||
mymap[VALT('c')]=mymap[VAL('b')];
|
||||
|
||||
std::cout << "mymap['a'] is " << mymap[VALT('a')] << '\n';
|
||||
std::cout << "mymap['b'] is " << mymap[VALT('b')] << '\n';
|
||||
std::cout << "mymap['c'] is " << mymap[VALT('c')] << '\n';
|
||||
std::cout << "mymap['d'] is " << mymap[VALT('d')] << '\n';
|
||||
|
||||
std::cout << "mymap now contains " << mymap.size() << " elements.\n";
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_M(tests_map_insert)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference)
|
||||
|
||||
ft::map<T,U> mymap;
|
||||
|
||||
// first insert function version (single parameter):
|
||||
mymap.insert ( ft::pair<T,U>(VALT('a'),VALU(100)) );
|
||||
mymap.insert ( ft::pair<T,U>(VALT('z'),VALU(200)) );
|
||||
|
||||
ft::pair<typename ft::map<T,U>::iterator, bool> ret;
|
||||
ret = mymap.insert ( ft::pair<T,U>(VALT('z'),VALU(500)) );
|
||||
if (ret.second==false) {
|
||||
std::cout << "element 'z' already existed";
|
||||
std::cout << " with a value of " << ret.first->second << '\n';
|
||||
}
|
||||
|
||||
|
||||
// second insert function version (with hint position):
|
||||
typename ft::map<T,U>::iterator it = mymap.begin();
|
||||
mymap.insert (it, ft::pair<T,U>(VALT('b'),VALU(300))); // max efficiency inserting
|
||||
mymap.insert (it, ft::pair<T,U>(VALT('c'),VALU(400))); // no max efficiency inserting
|
||||
|
||||
// third insert function version (range insertion):
|
||||
ft::map<T,U> anothermap;
|
||||
anothermap.insert(mymap.begin(),mymap.find('c'));
|
||||
|
||||
PRINT(mymap)
|
||||
PRINT(anothermap)
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_M(tests_map_erase)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference)
|
||||
|
||||
ft::map<T,U> mymap;
|
||||
typename ft::map<T,U>::iterator it;
|
||||
|
||||
// insert some values:
|
||||
mymap[VALT('a')]=VALU(10);
|
||||
mymap[VALT('b')]=VALU(20);
|
||||
mymap[VALT('c')]=VALU(30);
|
||||
mymap[VALT('d')]=VALU(40);
|
||||
mymap[VALT('e')]=VALU(50);
|
||||
mymap[VALT('f')]=VALU(60);
|
||||
|
||||
it=mymap.find(VALT('b'));
|
||||
mymap.erase (it); // erasing by iterator
|
||||
|
||||
mymap.erase (VALT('c')); // erasing by key
|
||||
|
||||
it=mymap.find (VALT('e'));
|
||||
mymap.erase ( it, mymap.end() ); // erasing by range
|
||||
|
||||
PRINT(mymap)
|
||||
|
||||
|
||||
// title
|
||||
TITLE(more complexe tree)
|
||||
|
||||
mymap[VALT('b')]=VALU(20);
|
||||
mymap[VALT('c')]=VALU(30);
|
||||
mymap[VALT('e')]=VALU(50);
|
||||
mymap[VALT('g')]=VALU(24);
|
||||
mymap[VALT('h')]=VALU(64);
|
||||
mymap[VALT('i')]=VALU(52);
|
||||
mymap[VALT('j')]=VALU(14);
|
||||
mymap[VALT('k')]=VALU(12);
|
||||
mymap[VALT('l')]=VALU(46);
|
||||
mymap[VALT('m')]=VALU(37);
|
||||
mymap[VALT('n')]=VALU(31);
|
||||
mymap[VALT('o')]=VALU(58);
|
||||
mymap[VALT('p')]=VALU(18);
|
||||
mymap[VALT('q')]=VALU(25);
|
||||
mymap[VALT('r')]=VALU(36);
|
||||
mymap[VALT('s')]=VALU(43);
|
||||
mymap[VALT('t')]=VALU(49);
|
||||
mymap[VALT('u')]=VALU(21);
|
||||
mymap[VALT('v')]=VALU(55);
|
||||
mymap[VALT('w')]=VALU(33);
|
||||
mymap[VALT('x')]=VALU(44);
|
||||
mymap[VALT('y')]=VALU(11);
|
||||
mymap[VALT('z')]=VALU(22);
|
||||
|
||||
mymap.erase (VALT('a'));
|
||||
mymap[VALT('a')]=VALU(10);
|
||||
mymap.erase (VALT('b'));
|
||||
mymap[VALT('b')]=VALU(20);
|
||||
mymap.erase (VALT('c'));
|
||||
mymap[VALT('c')]=VALU(30);
|
||||
mymap.erase (VALT('d'));
|
||||
mymap[VALT('d')]=VALU(40);
|
||||
mymap.erase (VALT('e'));
|
||||
mymap[VALT('e')]=VALU(50);
|
||||
mymap.erase (VALT('f'));
|
||||
mymap[VALT('f')]=VALU(60);
|
||||
mymap.erase (VALT('g'));
|
||||
mymap[VALT('g')]=VALU(24);
|
||||
mymap.erase (VALT('h'));
|
||||
mymap[VALT('h')]=VALU(64);
|
||||
mymap.erase (VALT('i'));
|
||||
mymap[VALT('i')]=VALU(52);
|
||||
mymap.erase (VALT('j'));
|
||||
mymap[VALT('j')]=VALU(14);
|
||||
mymap.erase (VALT('k'));
|
||||
mymap[VALT('k')]=VALU(12);
|
||||
mymap.erase (VALT('l'));
|
||||
mymap[VALT('l')]=VALU(46);
|
||||
mymap.erase (VALT('m'));
|
||||
mymap[VALT('m')]=VALU(37);
|
||||
mymap.erase (VALT('n'));
|
||||
mymap[VALT('n')]=VALU(31);
|
||||
mymap.erase (VALT('o'));
|
||||
mymap[VALT('o')]=VALU(58);
|
||||
mymap.erase (VALT('p'));
|
||||
mymap[VALT('p')]=VALU(18);
|
||||
mymap.erase (VALT('q'));
|
||||
mymap[VALT('q')]=VALU(25);
|
||||
mymap.erase (VALT('r'));
|
||||
mymap[VALT('r')]=VALU(36);
|
||||
mymap.erase (VALT('s'));
|
||||
mymap[VALT('s')]=VALU(43);
|
||||
mymap.erase (VALT('t'));
|
||||
mymap[VALT('t')]=VALU(49);
|
||||
mymap.erase (VALT('u'));
|
||||
mymap[VALT('u')]=VALU(21);
|
||||
mymap.erase (VALT('v'));
|
||||
mymap[VALT('v')]=VALU(55);
|
||||
mymap.erase (VALT('w'));
|
||||
mymap[VALT('w')]=VALU(33);
|
||||
mymap.erase (VALT('x'));
|
||||
mymap[VALT('x')]=VALU(44);
|
||||
mymap.erase (VALT('y'));
|
||||
mymap[VALT('y')]=VALU(11);
|
||||
mymap.erase (VALT('z'));
|
||||
mymap[VALT('z')]=VALU(22);
|
||||
|
||||
PRINT(mymap)
|
||||
|
||||
|
||||
// title
|
||||
TITLE(erasing entire tree)
|
||||
|
||||
mymap.erase (VALT('a'));
|
||||
mymap.erase (VALT('b'));
|
||||
mymap.erase (VALT('c'));
|
||||
mymap.erase (VALT('d'));
|
||||
mymap.erase (VALT('e'));
|
||||
mymap.erase (VALT('f'));
|
||||
mymap.erase (VALT('g'));
|
||||
mymap.erase (VALT('h'));
|
||||
mymap.erase (VALT('i'));
|
||||
mymap.erase (VALT('j'));
|
||||
mymap.erase (VALT('k'));
|
||||
mymap.erase (VALT('l'));
|
||||
mymap.erase (VALT('m'));
|
||||
mymap.erase (VALT('n'));
|
||||
mymap.erase (VALT('o'));
|
||||
mymap.erase (VALT('p'));
|
||||
mymap.erase (VALT('q'));
|
||||
mymap.erase (VALT('r'));
|
||||
mymap.erase (VALT('s'));
|
||||
mymap.erase (VALT('t'));
|
||||
mymap.erase (VALT('u'));
|
||||
mymap.erase (VALT('v'));
|
||||
mymap.erase (VALT('w'));
|
||||
mymap.erase (VALT('x'));
|
||||
mymap.erase (VALT('y'));
|
||||
mymap.erase (VALT('z'));
|
||||
|
||||
PRINT(mymap)
|
||||
|
||||
|
||||
// title
|
||||
TITLE(big tree)
|
||||
|
||||
int i;
|
||||
for (i = 0; i < 10000; i++)
|
||||
mymap[VALT(i)]=VALU(i);
|
||||
while (i)
|
||||
mymap.erase (VAL(i--));
|
||||
|
||||
PRINT(mymap)
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_M(tests_map_swap)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference)
|
||||
|
||||
ft::map<T,U> foo,bar;
|
||||
|
||||
foo[VALT('x')]=VALU(100);
|
||||
foo[VALT('y')]=VALU(200);
|
||||
|
||||
bar[VALT('a')]=VALU(11);
|
||||
bar[VALT('b')]=VALU(22);
|
||||
bar[VALT('c')]=VALU(33);
|
||||
|
||||
foo.swap(bar);
|
||||
|
||||
PRINT(foo)
|
||||
PRINT(bar)
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_M(tests_map_clear)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference)
|
||||
|
||||
ft::map<T,U> mymap;
|
||||
|
||||
mymap[VALT('x')]=VALU(100);
|
||||
mymap[VALT('y')]=VALU(200);
|
||||
mymap[VALT('z')]=VALU(300);
|
||||
|
||||
PRINT(mymap)
|
||||
|
||||
mymap.clear();
|
||||
mymap[VALT('a')]=VALU(1101);
|
||||
mymap[VALT('b')]=VALU(2202);
|
||||
|
||||
PRINT(mymap)
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_M(tests_map_key_comp)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference)
|
||||
|
||||
ft::map<T,U> mymap;
|
||||
|
||||
typename ft::map<T,U>::key_compare mycomp = mymap.key_comp();
|
||||
|
||||
mymap[VALT('a')]=VALU(100);
|
||||
mymap[VALT('b')]=VALU(200);
|
||||
mymap[VALT('c')]=VALU(300);
|
||||
|
||||
std::cout << "mymap contains:\n";
|
||||
|
||||
T highest = mymap.rbegin()->first; // key value of last element
|
||||
|
||||
typename ft::map<T,U>::iterator it = mymap.begin();
|
||||
do {
|
||||
std::cout << it->first << " => " << it->second << '\n';
|
||||
} while ( mycomp((*it++).first, highest) );
|
||||
|
||||
std::cout << '\n';
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_M(tests_map_value_comp)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference)
|
||||
|
||||
ft::map<T,U> mymap;
|
||||
|
||||
mymap[VALT('x')]=VALU(1001);
|
||||
mymap[VALT('y')]=VALU(2002);
|
||||
mymap[VALT('z')]=VALU(3003);
|
||||
|
||||
std::cout << "mymap contains:\n";
|
||||
|
||||
ft::pair<T,U> highest = *mymap.rbegin(); // last element
|
||||
|
||||
typename ft::map<T,U>::iterator it = mymap.begin();
|
||||
do {
|
||||
std::cout << it->first << " => " << it->second << '\n';
|
||||
} while ( mymap.value_comp()(*it++, highest) );
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_M(tests_map_find)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference)
|
||||
|
||||
ft::map<T,U> mymap;
|
||||
typename ft::map<T,U>::iterator it;
|
||||
|
||||
mymap[VALT('a')]=VALU(50);
|
||||
mymap[VALT('b')]=VALU(100);
|
||||
mymap[VALT('c')]=VALU(150);
|
||||
mymap[VALT('d')]=VALU(200);
|
||||
|
||||
it = mymap.find(VALT('b'));
|
||||
if (it != mymap.end())
|
||||
mymap.erase (it);
|
||||
|
||||
// print content:
|
||||
std::cout << "elements in mymap:" << '\n';
|
||||
std::cout << "a => " << mymap.find(VALT('a'))->second << '\n';
|
||||
std::cout << "c => " << mymap.find(VALT('c'))->second << '\n';
|
||||
std::cout << "d => " << mymap.find(VALT('d'))->second << '\n';
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_M(tests_map_count)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference)
|
||||
|
||||
ft::map<T,U> mymap;
|
||||
T c;
|
||||
|
||||
mymap [VALT('a')]=VALU(101);
|
||||
mymap [VALT('c')]=VALU(202);
|
||||
mymap [VALT('f')]=VALU(303);
|
||||
|
||||
// to do this test with T as a 'string' or 'mystruct*' we should add overload
|
||||
for (c=VALT('a'); c<VALT('h'); c++)
|
||||
{
|
||||
std::cout << c;
|
||||
if (mymap.count(c)>0)
|
||||
std::cout << " is an element of mymap.\n";
|
||||
else
|
||||
std::cout << " is not an element of mymap.\n";
|
||||
}
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_M(tests_map_lower_bound)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference)
|
||||
|
||||
ft::map<T,U> mymap;
|
||||
typename ft::map<T,U>::iterator itlow,itup;
|
||||
|
||||
mymap[VALT('a')]=VALU(20);
|
||||
mymap[VALT('b')]=VALU(40);
|
||||
mymap[VALT('c')]=VALU(60);
|
||||
mymap[VALT('d')]=VALU(80);
|
||||
mymap[VALT('e')]=VALU(100);
|
||||
|
||||
itlow=mymap.lower_bound (VALT('b')); // itlow points to b
|
||||
itup=mymap.upper_bound (VALT('d')); // itup points to e (not d!)
|
||||
|
||||
mymap.erase(itlow,itup); // erases [itlow,itup)
|
||||
|
||||
PRINT(mymap)
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_M(tests_map_upper_bound)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference)
|
||||
|
||||
ft::map<T,U> mymap;
|
||||
typename ft::map<T,U>::iterator itlow,itup;
|
||||
|
||||
mymap[VALT('a')]=VALU(20);
|
||||
mymap[VALT('b')]=VALU(40);
|
||||
mymap[VALT('c')]=VALU(60);
|
||||
mymap[VALT('d')]=VALU(80);
|
||||
mymap[VALT('e')]=VALU(100);
|
||||
|
||||
itlow=mymap.lower_bound (VALT('b')); // itlow points to b
|
||||
itup=mymap.upper_bound (VALT('d')); // itup points to e (not d!)
|
||||
|
||||
mymap.erase(itlow,itup); // erases [itlow,itup)
|
||||
|
||||
PRINT(mymap)
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_M(tests_map_equal_range)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference)
|
||||
|
||||
ft::map<T,U> mymap;
|
||||
|
||||
mymap[VALT('a')]=VALU(10);
|
||||
mymap[VALT('b')]=VALU(20);
|
||||
mymap[VALT('c')]=VALU(30);
|
||||
|
||||
ft::pair<typename ft::map<T,U>::iterator,typename ft::map<T,U>::iterator> ret;
|
||||
ret = mymap.equal_range(VALT('b'));
|
||||
|
||||
std::cout << "lower bound points to: ";
|
||||
std::cout << ret.first->first << " => " << ret.first->second << '\n';
|
||||
|
||||
std::cout << "upper bound points to: ";
|
||||
std::cout << ret.second->first << " => " << ret.second->second << '\n';
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_M(tests_map_get_allocator)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference)
|
||||
|
||||
int psize;
|
||||
ft::map<T,U> mymap;
|
||||
ft::pair<const T,U>* p;
|
||||
|
||||
// allocate an array of 5 elements using mymap's allocator:
|
||||
p=mymap.get_allocator().allocate(5);
|
||||
|
||||
// assign some values to array
|
||||
psize = sizeof(typename ft::map<T,U>::value_type)*5;
|
||||
|
||||
std::cout << "The allocated array has a size of " << psize << " bytes.\n";
|
||||
|
||||
mymap.get_allocator().deallocate(p,5);
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_M(tests_map_relational_operators)
|
||||
{
|
||||
AVOID_MYSTRUCT(U)
|
||||
// title
|
||||
TITLE(cplusplus.com reference)
|
||||
|
||||
ft::map<T,U> alice;
|
||||
ft::map<T,U> bob;
|
||||
ft::map<T,U> eve;
|
||||
(void)alice;
|
||||
(void)bob;
|
||||
(void)eve;
|
||||
|
||||
alice[VALT(1)]=VALU('a');
|
||||
alice[VALT(2)]=VALU('b');
|
||||
alice[VALT(3)]=VALU('c');
|
||||
|
||||
bob[VALT(7)]=VALU('Z');
|
||||
bob[VALT(8)]=VALU('Y');
|
||||
bob[VALT(9)]=VALU('X');
|
||||
bob[VALT(10)]=VALU('W');
|
||||
|
||||
eve[VALT(1)]=VALU('a');
|
||||
eve[VALT(2)]=VALU('b');
|
||||
eve[VALT(3)]=VALU('c');
|
||||
|
||||
std::cout << std::boolalpha;
|
||||
|
||||
// Compare non equal containers
|
||||
std::cout << "alice == bob returns " << (alice == bob) << '\n';
|
||||
std::cout << "alice != bob returns " << (alice != bob) << '\n';
|
||||
std::cout << "alice < bob returns " << (alice < bob) << '\n';
|
||||
std::cout << "alice <= bob returns " << (alice <= bob) << '\n';
|
||||
std::cout << "alice > bob returns " << (alice > bob) << '\n';
|
||||
std::cout << "alice >= bob returns " << (alice >= bob) << '\n';
|
||||
|
||||
std::cout << '\n';
|
||||
|
||||
// Compare equal containers
|
||||
std::cout << "alice == eve returns " << (alice == eve) << '\n';
|
||||
std::cout << "alice != eve returns " << (alice != eve) << '\n';
|
||||
std::cout << "alice < eve returns " << (alice < eve) << '\n';
|
||||
std::cout << "alice <= eve returns " << (alice <= eve) << '\n';
|
||||
std::cout << "alice > eve returns " << (alice > eve) << '\n';
|
||||
std::cout << "alice >= eve returns " << (alice >= eve) << '\n';
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
|
||||
TEST_M(tests_map_swap_non_member)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference)
|
||||
|
||||
ft::map<T, U> alice;
|
||||
ft::map<T, U> bob;
|
||||
|
||||
alice[VALT(1)]=VALU('a');
|
||||
alice[VALT(2)]=VALU('b');
|
||||
alice[VALT(3)]=VALU('c');
|
||||
|
||||
bob[VALT(7)]=VALU('Z');
|
||||
bob[VALT(8)]=VALU('Y');
|
||||
bob[VALT(9)]=VALU('X');
|
||||
bob[VALT(10)]=VALU('W');
|
||||
|
||||
// Print state before swap
|
||||
PRINT(alice)
|
||||
PRINT(bob)
|
||||
|
||||
std::cout << "-- SWAP\n";
|
||||
std::swap(alice, bob);
|
||||
|
||||
// Print state after swap
|
||||
PRINT(alice)
|
||||
PRINT(bob)
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
135
tests/tests_stack.cpp
Normal file
135
tests/tests_stack.cpp
Normal file
@@ -0,0 +1,135 @@
|
||||
|
||||
#include "tests_stack.hpp"
|
||||
|
||||
#ifdef STL
|
||||
#define DEQ_VEC deque
|
||||
#else
|
||||
#define DEQ_VEC vector
|
||||
#endif
|
||||
|
||||
TEST_S(tests_stack_constructor)
|
||||
{
|
||||
// title
|
||||
TITLE(simple test)
|
||||
|
||||
ft::DEQ_VEC<T> mycont (2,VAL(200)); // ft::vector/stl::deque with 2 elements
|
||||
ft::vector<T> myvector (2,VAL(200)); // vector with 2 elements
|
||||
|
||||
ft::stack<T> first; // empty stack
|
||||
ft::stack<T> second (mycont); // stack initialized to copy of vector
|
||||
|
||||
ft::stack< T,ft::vector<T> > third; // empty stack using vector
|
||||
ft::stack< T,ft::vector<T> > fourth (myvector);
|
||||
|
||||
std::cout << "size of first: " << first.size() << '\n';
|
||||
std::cout << "size of second: " << second.size() << '\n';
|
||||
std::cout << "size of third: " << third.size() << '\n';
|
||||
std::cout << "size of fourth: " << fourth.size() << '\n';
|
||||
|
||||
PRINT(first)
|
||||
PRINT(second)
|
||||
PRINT(third)
|
||||
PRINT(fourth)
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_S(tests_stack_empty)
|
||||
{
|
||||
// title
|
||||
TITLE(simple test)
|
||||
|
||||
ft::stack<T> mystack;
|
||||
int sum (0);
|
||||
|
||||
for (int i=1;i<=10;i++) mystack.push(VAL(i));
|
||||
|
||||
while (!mystack.empty())
|
||||
{
|
||||
sum += TOI(mystack.top());
|
||||
mystack.pop();
|
||||
}
|
||||
|
||||
std::cout << "total: " << sum << '\n';
|
||||
|
||||
PRINT(mystack)
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_S(tests_stack_size)
|
||||
{
|
||||
// title
|
||||
TITLE(simple test)
|
||||
|
||||
ft::stack<T> myints;
|
||||
std::cout << "0. size: " << myints.size() << '\n';
|
||||
|
||||
for (int i=0; i<5; i++) myints.push(VAL(i));
|
||||
std::cout << "1. size: " << myints.size() << '\n';
|
||||
|
||||
myints.pop();
|
||||
std::cout << "2. size: " << myints.size() << '\n';
|
||||
|
||||
PRINT(myints)
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_S(tests_stack_top)
|
||||
{
|
||||
// title
|
||||
TITLE(simple test)
|
||||
|
||||
ft::stack<T> mystack;
|
||||
|
||||
mystack.push(VAL(10));
|
||||
std::cout << "mystack.top() is now " << mystack.top() << '\n';
|
||||
mystack.push(VAL(20));
|
||||
std::cout << "mystack.top() is now " << mystack.top() << '\n';
|
||||
mystack.push(VAL(-12));
|
||||
std::cout << "mystack.top() is now " << mystack.top() << '\n';
|
||||
mystack.push(VAL(26));
|
||||
std::cout << "mystack.top() is now " << mystack.top() << '\n';
|
||||
|
||||
// mystack.top() -= VAL(5);
|
||||
|
||||
|
||||
PRINT(mystack)
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_S(tests_stack_push)
|
||||
{
|
||||
// title
|
||||
TITLE(simple test)
|
||||
|
||||
ft::stack<T> mystack;
|
||||
|
||||
for (int i=0; i<5; ++i) mystack.push(VAL(i));
|
||||
|
||||
PRINT(mystack)
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_S(tests_stack_pop)
|
||||
{
|
||||
// title
|
||||
TITLE(simple test)
|
||||
|
||||
ft::stack<T> mystack;
|
||||
|
||||
for (int i=0; i<5; ++i) mystack.push(VAL(i));
|
||||
|
||||
std::cout << "Popping out elements...";
|
||||
while (!mystack.empty())
|
||||
{
|
||||
std::cout << ' ' << mystack.top();
|
||||
mystack.pop();
|
||||
}
|
||||
std::cout << '\n';
|
||||
|
||||
DELETE
|
||||
}
|
||||
874
tests/tests_vector.cpp
Normal file
874
tests/tests_vector.cpp
Normal file
@@ -0,0 +1,874 @@
|
||||
|
||||
#include "tests_vector.hpp"
|
||||
|
||||
|
||||
TEST_V(tests_vector_constructor)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference)
|
||||
|
||||
// constructors used in the same order as described above:
|
||||
ft::vector<T> first; // empty vector of ints
|
||||
ft::vector<T> second (4,VAL(100)); // four ints with value 100
|
||||
ft::vector<T> third (second.begin(),second.end()); // iterating through second
|
||||
ft::vector<T> fourth (third); // a copy of third
|
||||
|
||||
// the iterator constructor can also be used to construct from arrays:
|
||||
T myints[] = {VAL(16),VAL(2),VAL(77),VAL(29)};
|
||||
ft::vector<T> fifth (myints, myints + sizeof(myints) / sizeof(T) );
|
||||
|
||||
PRINT(fifth);
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_V(tests_vector_operator_assignation)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference)
|
||||
|
||||
ft::vector<T> foo (3,VAL(0));
|
||||
ft::vector<T> bar (5,VAL(0));
|
||||
|
||||
bar = foo;
|
||||
foo = ft::vector<T>();
|
||||
|
||||
std::cout << "Size of foo: " << int(foo.size()) << '\n';
|
||||
std::cout << "Size of bar: " << int(bar.size()) << '\n';
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_V(tests_vector_begin)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference :)
|
||||
|
||||
ft::vector<T> myvector;
|
||||
for (int i=1; i<=5; i++) myvector.push_back(VAL(i));
|
||||
|
||||
PRINT(myvector);
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_V(tests_vector_end)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference :)
|
||||
|
||||
ft::vector<T> myvector;
|
||||
for (int i=1; i<=5; i++) myvector.push_back(VAL(i));
|
||||
|
||||
PRINT(myvector);
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_V(tests_vector_rbegin)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference :)
|
||||
|
||||
ft::vector<T> myvector (5);
|
||||
|
||||
int i=0;
|
||||
|
||||
typename ft::vector<T>::reverse_iterator rit = myvector.rbegin();
|
||||
for (; rit!= myvector.rend(); ++rit)
|
||||
*rit = VAL(++i);
|
||||
|
||||
PRINT(myvector);
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_V(tests_vector_rend)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference :)
|
||||
|
||||
ft::vector<T> myvector (5); // 5 default-constructed Ts
|
||||
|
||||
typename ft::vector<T>::reverse_iterator rit = myvector.rbegin();
|
||||
|
||||
int i=0;
|
||||
for (rit = myvector.rbegin(); rit!= myvector.rend(); ++rit)
|
||||
*rit = VAL(++i);
|
||||
|
||||
PRINT(myvector);
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_V(tests_vector_size)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference :)
|
||||
|
||||
ft::vector<T> myarr;
|
||||
std::cout << "0. size: " << myarr.size() << '\n';
|
||||
|
||||
for (int i=0; i<10; i++) myarr.push_back(VAL(i));
|
||||
std::cout << "1. size: " << myarr.size() << '\n';
|
||||
|
||||
myarr.insert (myarr.end(),10,VAL(100));
|
||||
std::cout << "2. size: " << myarr.size() << '\n';
|
||||
|
||||
myarr.pop_back();
|
||||
std::cout << "3. size: " << myarr.size() << '\n';
|
||||
|
||||
PRINT(myarr);
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_V(tests_vector_max_size)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference :)
|
||||
|
||||
ft::vector<T> myvector;
|
||||
|
||||
// set some content in the vector:
|
||||
for (int i=0; i<100; i++) myvector.push_back(VAL(i));
|
||||
|
||||
std::cout << "size: " << myvector.size() << "\n";
|
||||
std::cout << "capacity: " << myvector.capacity() << "\n";
|
||||
std::cout << "max_size: " << myvector.max_size() << "\n";
|
||||
|
||||
PRINT(myvector);
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_V(tests_vector_resize)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference :)
|
||||
|
||||
ft::vector<T> myvector;
|
||||
|
||||
// set some initial content:
|
||||
for (int i = 1; i < 10; i++) myvector.push_back(VAL(i));
|
||||
|
||||
myvector.resize(5);
|
||||
myvector.resize(8,VAL(100));
|
||||
myvector.resize(12);
|
||||
|
||||
PRINT(myvector);
|
||||
|
||||
|
||||
// title
|
||||
TITLE(test size and capacity 1 :)
|
||||
|
||||
ft::vector<T> vector2;
|
||||
|
||||
std::cout << "size: " << vector2.size() << " - capacity: " << vector2.capacity() << "\n\n";
|
||||
|
||||
std::cout << "assign(10, 1)\n";
|
||||
vector2.assign(10, VAL(1));
|
||||
PRINT(vector2);
|
||||
|
||||
std::cout << "\n";
|
||||
|
||||
std::cout << "resize(15)\n";
|
||||
vector2.resize(15);
|
||||
PRINT(vector2);
|
||||
|
||||
std::cout << "\n";
|
||||
|
||||
std::cout << "resize(10)\n";
|
||||
vector2.resize(10);
|
||||
PRINT(vector2);
|
||||
|
||||
std::cout << "\n";
|
||||
|
||||
std::cout << "resize(19)\n";
|
||||
vector2.resize(19);
|
||||
PRINT(vector2);
|
||||
|
||||
std::cout << "\n";
|
||||
|
||||
std::cout << "resize(20)\n";
|
||||
vector2.resize(20);
|
||||
PRINT(vector2);
|
||||
|
||||
std::cout << "\n";
|
||||
|
||||
std::cout << "resize(21)\n";
|
||||
vector2.resize(21);
|
||||
PRINT(vector2);
|
||||
|
||||
std::cout << "\n";
|
||||
|
||||
|
||||
// title
|
||||
TITLE(test size and capacity 2 :)
|
||||
|
||||
ft::vector<T> vector3;
|
||||
|
||||
std::cout << "size: " << vector3.size() << " - capacity: " << vector3.capacity() << "\n\n";
|
||||
|
||||
std::cout << "assign(10, 1)\n";
|
||||
vector3.assign(10, VAL(1));
|
||||
PRINT(vector3);
|
||||
|
||||
std::cout << "\n";
|
||||
|
||||
std::cout << "resize(21)\n";
|
||||
vector3.resize(21);
|
||||
PRINT(vector3);
|
||||
|
||||
std::cout << "\n";
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_V(tests_vector_capacity)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference :)
|
||||
|
||||
ft::vector<T> myvector;
|
||||
|
||||
// set some content in the vector:
|
||||
for (int i=0; i<100; i++) myvector.push_back(VAL(i));
|
||||
|
||||
std::cout << "size: " << (int) myvector.size() << '\n';
|
||||
std::cout << "capacity: " << (int) myvector.capacity() << '\n';
|
||||
std::cout << "max_size: " << (int) myvector.max_size() << '\n';
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_V(tests_vector_empty)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference :)
|
||||
|
||||
ft::vector<T> myvector;
|
||||
int sum (0);
|
||||
|
||||
for (int i=1;i<=10;i++) myvector.push_back(VAL(i));
|
||||
|
||||
while (!myvector.empty())
|
||||
{
|
||||
sum+=TOI(myvector.back());
|
||||
myvector.pop_back();
|
||||
}
|
||||
|
||||
std::cout << "total: " << sum << '\n';
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_V(tests_vector_reserve)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference :)
|
||||
|
||||
typename ft::vector<T>::size_type sz;
|
||||
ft::vector<T> foo;
|
||||
|
||||
sz = foo.capacity();
|
||||
std::cout << "making foo grow:\n";
|
||||
for (int i=0; i<100; ++i) {
|
||||
foo.push_back(VAL(i));
|
||||
if (sz!=foo.capacity()) {
|
||||
sz = foo.capacity();
|
||||
std::cout << "capacity changed: " << sz << '\n';
|
||||
}
|
||||
}
|
||||
|
||||
ft::vector<T> bar;
|
||||
|
||||
sz = bar.capacity();
|
||||
bar.reserve(100); // this is the only difference with foo above
|
||||
std::cout << "making bar grow:\n";
|
||||
for (int i=0; i<100; ++i) {
|
||||
bar.push_back(VAL(i));
|
||||
if (sz!=bar.capacity()) {
|
||||
sz = bar.capacity();
|
||||
std::cout << "capacity changed: " << sz << '\n';
|
||||
}
|
||||
}
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_V(tests_vector_operator_access)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference :)
|
||||
|
||||
ft::vector<T> myvector (10); // 10 zero-initialized elements
|
||||
typename ft::vector<T>::size_type sz = myvector.size();
|
||||
|
||||
// assign some values:
|
||||
for (unsigned i=0; i<sz; i++) myvector[i]=VAL(i);
|
||||
|
||||
// reverse vector using operator[]:
|
||||
for (unsigned i=0; i<sz/2; i++)
|
||||
{
|
||||
T temp;
|
||||
temp = myvector[sz-1-i];
|
||||
myvector[sz-1-i]=myvector[i];
|
||||
myvector[i]=temp;
|
||||
}
|
||||
|
||||
PRINT(myvector)
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_V(tests_vector_at)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference :)
|
||||
|
||||
ft::vector<T> myvector (10); // 10 zero-initialized ints
|
||||
|
||||
// assign some values:
|
||||
for (unsigned i=0; i<myvector.size(); i++)
|
||||
myvector.at(i)=VAL(i);
|
||||
|
||||
PRINT(myvector)
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_V(tests_vector_front)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference :)
|
||||
|
||||
ft::vector<T> myvector;
|
||||
|
||||
myvector.push_back(VAL(78));
|
||||
myvector.push_back(VAL(16));
|
||||
|
||||
// now front equals 78, and back 16
|
||||
|
||||
//myvector.front() -= myvector.back();
|
||||
|
||||
std::cout << "myvector.front() is now " << myvector.front() << '\n';
|
||||
|
||||
PRINT(myvector)
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_V(tests_vector_back)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference :)
|
||||
|
||||
ft::vector<T> myvector;
|
||||
|
||||
myvector.push_back(VAL(78));
|
||||
myvector.push_back(VAL(16));
|
||||
|
||||
// now front equals 78, and back 16
|
||||
|
||||
// myvector.front() -= myvector.back();
|
||||
std::cout << "myvector.front() is now " << myvector.front() << '\n';
|
||||
PRINT(myvector)
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_V(tests_vector_assign)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference :)
|
||||
|
||||
ft::vector<T> first;
|
||||
ft::vector<T> second;
|
||||
ft::vector<T> third;
|
||||
|
||||
first.assign (7,VAL(100)); // 7 ints with a value of 100
|
||||
|
||||
typename ft::vector<T>::iterator it;
|
||||
it=first.begin()+1;
|
||||
|
||||
second.assign (it,first.end()-1); // the 5 central values of first
|
||||
|
||||
T myints[] = {VAL(1776),VAL(7),VAL(4)};
|
||||
third.assign (myints,myints+3); // assigning from array.
|
||||
|
||||
std::cout << "Size of first: " << int (first.size()) << '\n';
|
||||
std::cout << "Size of second: " << int (second.size()) << '\n';
|
||||
std::cout << "Size of third: " << int (third.size()) << '\n';
|
||||
|
||||
// title
|
||||
TITLE(capacity tests of assignation :)
|
||||
|
||||
ft::vector<T> myvector;
|
||||
|
||||
std::cout << "capacity before assignation : " << myvector.capacity() << "\n";
|
||||
|
||||
std::cout << "\nassign 1\n";
|
||||
myvector.assign(1, VAL(12));
|
||||
PRINT(myvector)
|
||||
|
||||
std::cout << "\nassign 3\n";
|
||||
myvector.assign(3, VAL(12));
|
||||
PRINT(myvector)
|
||||
|
||||
std::cout << "\nassign 7268\n";
|
||||
myvector.assign(7268, VAL(12));
|
||||
PRINT(myvector)
|
||||
|
||||
|
||||
// title
|
||||
TITLE(tests of iterators :)
|
||||
|
||||
ft::vector<T> int_vector_1;
|
||||
ft::vector<T> int_vector_2;
|
||||
ft::vector<T> int_vector_3;
|
||||
ft::vector<T> it_vector;
|
||||
|
||||
std::cout << "\nassign 1\n";
|
||||
int_vector_1.assign(1, VAL(12));
|
||||
it_vector.assign(int_vector_1.begin(), int_vector_1.end());
|
||||
PRINT(it_vector)
|
||||
|
||||
std::cout << "\nassign 0\n";
|
||||
int_vector_2.assign(1, VAL(6));
|
||||
it_vector.assign(int_vector_2.begin(), int_vector_2.end() - 1);
|
||||
PRINT(it_vector)
|
||||
|
||||
std::cout << "\nassign 266 - 13 - 172 = 81\n";
|
||||
int_vector_3.assign(266, VAL(1));
|
||||
it_vector.assign(int_vector_3.begin() + 13, int_vector_3.end() - 172);
|
||||
PRINT(it_vector)
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_V(tests_vector_push_back)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference :)
|
||||
|
||||
ft::vector<T> myvector;
|
||||
|
||||
int myint[] = {12434, -2432, 12, 5345, 23, 0, -4, 387, 8432, -934723, 1};
|
||||
int size = sizeof(myint) / sizeof(myint[0]);
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
myvector.push_back(VAL(myint[i]));
|
||||
std::cout << "[capacity : "
|
||||
<< std::setw(2) << myvector.capacity() << "] "
|
||||
<< myvector[i] << "\n";
|
||||
}
|
||||
PRINT(myvector)
|
||||
|
||||
// title
|
||||
TITLE(big push back :)
|
||||
|
||||
for (int i = 0; i < 72363; i++)
|
||||
{
|
||||
myvector.push_back(VAL(9));
|
||||
std::cout << "[" << i
|
||||
<< ":" << myvector.capacity() << "] ";
|
||||
}
|
||||
std::cout << " -> size : " << myvector.size() << " , capacity :" << myvector.capacity() << "\n";
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_V(tests_vector_pop_back)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference :)
|
||||
|
||||
ft::vector<T> myvector;
|
||||
|
||||
int sum (0);
|
||||
|
||||
myvector.push_back (VAL(100));
|
||||
myvector.push_back (VAL(200));
|
||||
myvector.push_back (VAL(300));
|
||||
|
||||
while (!myvector.empty())
|
||||
{
|
||||
sum+=TOI(myvector.back());
|
||||
myvector.pop_back();
|
||||
}
|
||||
|
||||
std::cout << "The elements of myvector add up to " << sum << '\n';
|
||||
|
||||
|
||||
// title
|
||||
TITLE(check state :)
|
||||
|
||||
std::cout << "size : " << myvector.size() << '\n';
|
||||
std::cout << "capacity : " << myvector.capacity() << '\n';
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_V(tests_vector_insert)
|
||||
{
|
||||
typename ft::vector<T>::iterator it;
|
||||
|
||||
// title
|
||||
TITLE(cplusplus.com reference :)
|
||||
|
||||
ft::vector<T> myvector (3,VAL(100));
|
||||
|
||||
it = myvector.begin();
|
||||
it = myvector.insert ( it , VAL(200) );
|
||||
myvector.insert (it,2,VAL(300));
|
||||
|
||||
ft::vector<T> anothervector (2,VAL(400));
|
||||
it = myvector.begin();
|
||||
myvector.insert (it+2,anothervector.begin(),anothervector.end());
|
||||
|
||||
T myarray [] = { VAL(501),VAL(502),VAL(503) };
|
||||
myvector.insert (myvector.begin(), myarray, myarray+3);
|
||||
|
||||
PRINT(myvector)
|
||||
|
||||
// title
|
||||
TITLE(tests positions on insert(pos, value) :)
|
||||
|
||||
ft::vector<T> myvector2 (3,VAL(100));
|
||||
|
||||
it = myvector2.begin();
|
||||
std::cout << "size:" << myvector2.size() << " capacity:" << myvector2.capacity() << "\n";
|
||||
myvector2.insert ( it , VAL(200) );
|
||||
PRINT(myvector2)
|
||||
|
||||
ft::vector<T> myvector3 (3,VAL(100));
|
||||
|
||||
it = myvector3.end();
|
||||
std::cout << "\nsize:" << myvector3.size() << " capacity:" << myvector3.capacity() << "\n";
|
||||
myvector3.insert ( it , VAL(200) );
|
||||
PRINT(myvector3)
|
||||
|
||||
ft::vector<T> myvector4 (3,VAL(100));
|
||||
|
||||
it = myvector4.begin() + 2;
|
||||
std::cout << "\nsize:" << myvector3.size() << " capacity:" << myvector3.capacity() << "\n";
|
||||
myvector4.insert ( it , VAL(200) );
|
||||
PRINT(myvector4)
|
||||
|
||||
|
||||
// title
|
||||
TITLE(tests insert(pos, size, value) :)
|
||||
|
||||
ft::vector<T> myvector5;
|
||||
|
||||
for (int i = 1; i <= 5; i++)
|
||||
myvector5.push_back(VAL(i * 100));
|
||||
|
||||
it = myvector5.begin() + 1;
|
||||
myvector5.insert ( it , VAL(150) );
|
||||
|
||||
it = myvector5.end();
|
||||
myvector5.insert (it,2,VAL(600));
|
||||
|
||||
it = myvector5.end() - 2;
|
||||
myvector5.insert (it,2,VAL(550));
|
||||
|
||||
PRINT(myvector5)
|
||||
|
||||
|
||||
// title
|
||||
TITLE(tests insert(pos, first, last) :)
|
||||
|
||||
ft::vector<T> myvector6;
|
||||
|
||||
myvector6.assign(5, VAL(42));
|
||||
|
||||
it = myvector6.begin() + 2;
|
||||
myvector6.insert ( it, myvector5.begin() + 3, myvector5.end() - 2 );
|
||||
PRINT(myvector6)
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_V(tests_vector_erase)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference :)
|
||||
|
||||
ft::vector<T> myvector;
|
||||
|
||||
// set some values (from 1 to 10)
|
||||
for (int i=1; i<=10; i++) myvector.push_back(VAL(i));
|
||||
|
||||
// erase the 6th element
|
||||
myvector.erase (myvector.begin()+5);
|
||||
|
||||
// erase the first 3 elements:
|
||||
myvector.erase (myvector.begin(),myvector.begin()+3);
|
||||
|
||||
PRINT(myvector)
|
||||
|
||||
// title
|
||||
TITLE(test iterator bigger or equal :)
|
||||
ft::vector<T> vector2;
|
||||
|
||||
for (int i=1; i<=100; i++) vector2.push_back(VAL(i));
|
||||
PRINT(vector2)
|
||||
|
||||
std::cout << "\nerase pos(7,36) :\n";
|
||||
vector2.erase(vector2.begin() + 7, vector2.begin() + 36);
|
||||
PRINT(vector2)
|
||||
|
||||
std::cout << "\nerase pos(46,54) :\n";
|
||||
vector2.erase(vector2.begin() + 46, vector2.begin() + 54);
|
||||
PRINT(vector2)
|
||||
|
||||
std::cout << "\nerase pos(7,7) :\n";
|
||||
vector2.erase(vector2.begin() + 7, vector2.begin() + 7);
|
||||
PRINT(vector2)
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_V(tests_vector_swap)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference :)
|
||||
|
||||
ft::vector<T> foo (3,VAL(100)); // three ints with a value of 100
|
||||
ft::vector<T> bar (5,VAL(200)); // five ints with a value of 200
|
||||
|
||||
typename ft::vector<T>::iterator it1 = foo.begin();
|
||||
typename ft::vector<T>::iterator it2 = bar.begin();
|
||||
|
||||
std::cout << "it1:" << *it1 << " - it2:" << *it2 << "\n";
|
||||
std::cout << "foo.begin():" << *(foo.begin()) << " - bar.begin():" << *(bar.begin()) << "\n";
|
||||
|
||||
foo.swap(bar);
|
||||
|
||||
std::cout << "swap\n";
|
||||
|
||||
std::cout << "it1:" << *it1 << " - it2:" << *it2 << "\n";
|
||||
std::cout << "foo.begin():" << *(foo.begin()) << " - bar.begin():" << *(bar.begin()) << "\n";
|
||||
|
||||
PRINT(foo)
|
||||
|
||||
PRINT(bar)
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_V(tests_vector_clear)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference :)
|
||||
|
||||
ft::vector<T> myvector;
|
||||
myvector.push_back (VAL(100));
|
||||
myvector.push_back (VAL(200));
|
||||
myvector.push_back (VAL(300));
|
||||
|
||||
PRINT(myvector)
|
||||
|
||||
myvector.clear();
|
||||
myvector.push_back (VAL(1101));
|
||||
myvector.push_back (VAL(2202));
|
||||
|
||||
PRINT(myvector)
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_V(tests_vector_get_allocator)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference :)
|
||||
|
||||
ft::vector<T> myvector;
|
||||
T * p;
|
||||
unsigned int i;
|
||||
|
||||
// allocate an array with space for 5 elements using vector's allocator:
|
||||
p = myvector.get_allocator().allocate(5);
|
||||
|
||||
// construct values in-place on the array:
|
||||
for (i=0; i<5; i++) myvector.get_allocator().construct(&p[i],VAL(i));
|
||||
|
||||
std::cout << "The allocated array contains:";
|
||||
for (i=0; i<5; i++) std::cout << ' ' << p[i];
|
||||
std::cout << '\n';
|
||||
|
||||
// destroy and deallocate:
|
||||
for (i=0; i<5; i++) myvector.get_allocator().destroy(&p[i]);
|
||||
myvector.get_allocator().deallocate(p,5);
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_V(tests_vector_relational_operators)
|
||||
{
|
||||
AVOID_MYSTRUCT(T)
|
||||
// title
|
||||
TITLE(cplusplus.com reference :)
|
||||
|
||||
ft::vector<T> foo (3,VAL(100)); // three ints with a value of 100
|
||||
ft::vector<T> bar (2,VAL(200)); // two ints with a value of 200
|
||||
|
||||
if (foo==bar) std::cout << "foo and bar are equal\n";
|
||||
if (foo!=bar) std::cout << "foo and bar are not equal\n";
|
||||
if (foo< bar) std::cout << "foo is less than bar\n";
|
||||
if (foo> bar) std::cout << "foo is greater than bar\n";
|
||||
if (foo<=bar) std::cout << "foo is less than or equal to bar\n";
|
||||
if (foo>=bar) std::cout << "foo is greater than or equal to bar\n";
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_V(tests_vector_swap_non_member)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference :)
|
||||
|
||||
ft::vector<T> foo (3,VAL(100)); // three ints with a value of 100
|
||||
ft::vector<T> bar (5,VAL(200)); // five ints with a value of 200
|
||||
|
||||
foo.swap(bar);
|
||||
|
||||
PRINT(foo)
|
||||
|
||||
PRINT(bar)
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
TEST_V(tests_vector_reverse_iterators)
|
||||
{
|
||||
// title
|
||||
TITLE(cplusplus.com reference)
|
||||
TITLE(::constructor ::operator* ::operator++(val))
|
||||
|
||||
ft::vector<T> myvector;
|
||||
for (int i=0; i<10; i++) myvector.push_back(VAL(i));
|
||||
typedef typename ft::vector<T>::iterator iter_type;
|
||||
// ? 0 1 2 3 4 5 6 7 8 9 ?
|
||||
iter_type from (myvector.begin()); // ^
|
||||
iter_type until (myvector.end()); // ^
|
||||
ft::reverse_iterator<iter_type> rev_until (from); // ^
|
||||
ft::reverse_iterator<iter_type> rev_from (until); // ^
|
||||
|
||||
std::cout << "myvector:";
|
||||
while (rev_from != rev_until)
|
||||
std::cout << ' ' << *rev_from++;
|
||||
std::cout << '\n';
|
||||
|
||||
|
||||
// title
|
||||
TITLE(::operator++)
|
||||
|
||||
std::cout << "myvector:";
|
||||
while (rev_from != rev_until) {
|
||||
std::cout << ' ' << *rev_from;
|
||||
++rev_from;
|
||||
}
|
||||
std::cout << '\n';
|
||||
|
||||
|
||||
// title
|
||||
TITLE(::base)
|
||||
|
||||
ft::reverse_iterator<iter_type> rev_end (myvector.begin());
|
||||
ft::reverse_iterator<iter_type> rev_begin (myvector.end());
|
||||
std::cout << "myvector:";
|
||||
for (iter_type it = rev_end.base(); it != rev_begin.base(); ++it)
|
||||
std::cout << ' ' << *it;
|
||||
std::cout << '\n';
|
||||
|
||||
|
||||
// title
|
||||
TITLE(::operator+)
|
||||
|
||||
ft::reverse_iterator<iter_type> rev_it_add;
|
||||
rev_it_add = myvector.rbegin() +3;
|
||||
std::cout << "The fourth element from the end is: " << *rev_it_add << '\n';
|
||||
|
||||
|
||||
// title
|
||||
TITLE(::operator+=)
|
||||
|
||||
ft::reverse_iterator<iter_type> rev_it_add_equal = myvector.rbegin();
|
||||
rev_it_add_equal += 2;
|
||||
std::cout << "The third element from the end is: " << *rev_it_add_equal << '\n';
|
||||
|
||||
|
||||
// title
|
||||
TITLE(::operator-)
|
||||
|
||||
ft::reverse_iterator<iter_type> rev_it_minus;
|
||||
rev_it_minus = myvector.rend() - 3;
|
||||
std::cout << "myvector.rend()-3 points to: " << *rev_it_minus << '\n';
|
||||
|
||||
|
||||
// title
|
||||
TITLE(::operator--)
|
||||
|
||||
ft::reverse_iterator<iter_type> rev_it_minus_minus = rev_begin;
|
||||
while ( rev_it_minus_minus != rev_end )
|
||||
std::cout << *rev_it_minus_minus++ << ' ';
|
||||
std::cout << '\n';
|
||||
|
||||
while ( rev_it_minus_minus != rev_begin )
|
||||
std::cout << *(--rev_it_minus_minus) << ' ';
|
||||
std::cout << '\n';
|
||||
|
||||
|
||||
// title
|
||||
TITLE(::operator-=)
|
||||
|
||||
ft::reverse_iterator<iter_type> rev_it_minus_equal = myvector.rend();
|
||||
rev_it_minus_equal -= 4;
|
||||
std::cout << "rev_it_minus_equal now points to: " << *rev_it_minus_equal << '\n';
|
||||
|
||||
|
||||
// title
|
||||
TITLE(::operator->)
|
||||
|
||||
std::map<int,std::string> numbers;
|
||||
numbers.insert (std::make_pair(1,"one"));
|
||||
numbers.insert (std::make_pair(2,"two"));
|
||||
numbers.insert (std::make_pair(3,"three"));
|
||||
|
||||
typedef std::map<int,std::string>::iterator map_iter;
|
||||
ft::reverse_iterator<map_iter> rev_map_end (numbers.begin());
|
||||
ft::reverse_iterator<map_iter> rev_map_ite (numbers.end());
|
||||
|
||||
for ( ; rev_map_ite != rev_map_end ; ++rev_map_ite )
|
||||
std::cout << rev_map_ite->first << ' ' << rev_map_ite->second << '\n';
|
||||
|
||||
|
||||
// title
|
||||
TITLE(::operator[])
|
||||
|
||||
ft::reverse_iterator<iter_type> rev_it_at = myvector.rbegin();
|
||||
std::cout << "The fourth element from the end is: " << rev_it_at[3] << '\n';
|
||||
|
||||
|
||||
// title
|
||||
TITLE(::operator- non-member)
|
||||
|
||||
ft::reverse_iterator<typename ft::vector<T>::iterator> rev_it_from,rev_it_until;
|
||||
rev_it_from = myvector.rbegin();
|
||||
rev_it_until = myvector.rend();
|
||||
std::cout << "myvector has " << (rev_it_until-rev_it_from) << " elements.\n";
|
||||
|
||||
|
||||
// title
|
||||
TITLE(::operator+ non-member)
|
||||
|
||||
ft::reverse_iterator<iter_type> rev_it_n_memb;
|
||||
rev_it_n_memb = 3 + myvector.rbegin();
|
||||
std::cout << "The fourth element from the end is: " << *rev_it_n_memb << '\n';
|
||||
|
||||
DELETE
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user