├── .compile_log.sh ├── README.md ├── includes.hpp ├── infinite_monkey.sh ├── monkey.sh ├── setup.sh └── srcs ├── common.hpp ├── fifodiff.cpp ├── input_iterator.hpp ├── logger.hpp ├── main.cpp ├── test_map.hpp ├── test_stack.hpp └── test_vector.hpp /.compile_log.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ "$1" != "ft" -a "$1" != "std" ] 4 | then 5 | echo "Usage: $( basename $0 ) " >&2 6 | echo "example: $( basename $0 ) ft" >&2 7 | exit 1 8 | fi 9 | 10 | if [ ! -e log/log.cpp ] 11 | then 12 | echo "no log to compile" >&2 13 | fi 14 | 15 | . .setup 16 | 17 | for i in "${INCLUDE_DIRECTORIES[@]}" 18 | do 19 | CFLAGS+=" -I"$i 20 | done 21 | 22 | echo "🐒 compiling..." 23 | clang++ $CFLAGS -D NAMESPACE=$1 -I. -I srcs log/log.cpp -o bin/log_$1 || exit 24 | echo "🐒 bin/log_$1 generated" -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ft_containers_monkey_tester (personal project) 2 | 3 | ![monke](https://upload.wikimedia.org/wikipedia/commons/f/f1/Monkey-typing.jpg) 4 | 5 | This repo is a tester based on the [fuzzing](https://en.wikipedia.org/wiki/Fuzzing) technique for the 42 ft_containers project. The tester generate two programs (std and ft) with a certain amount of random test in both then compare the two outputs 6 | 7 | ## monkey.sh 8 | 9 | monkey.sh will launch the tester, execute a thousand test and do a diff on the two outputs 10 | 11 | (⚠️ when correcting a ft_containers, please use the infinite_monkey.sh script which is more efficient) 12 | 13 | ## infinite_monkey.sh 14 | 15 | infinite_monkey.sh will launch the tester, execute an inifinity of test then return. the fifodiff program present in srcs is used for the comparison of the two output streams 16 | 17 | ## usage 18 | 19 | just clone the repo wherever you want and execute one of the scripts `./[monkey.sh|infinite_monkey.sh[] ` (you may have to setup your includes name in includes.hpp) 20 | -------------------------------------------------------------------------------- /includes.hpp: -------------------------------------------------------------------------------- 1 | #ifdef MONKEY_MAP 2 | #include "pair.hpp" 3 | #include "map.hpp" 4 | #endif 5 | #ifdef MONKEY_VECTOR 6 | #include "vector.hpp" 7 | #endif 8 | #ifdef MONKEY_STACK 9 | #include "stack.hpp" 10 | #endif -------------------------------------------------------------------------------- /infinite_monkey.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "This command is deprecated! please use \"./monkey.sh -i\"" >&2 4 | echo "(press enter...)" >&2 5 | read VOID 6 | ./monkey.sh -i $@ -------------------------------------------------------------------------------- /monkey.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -- $(getopt "ifsauvh" $@) 4 | MODE="" 5 | FILTER="cat" 6 | CFLAGS="" 7 | RECOMPILE="no" 8 | for arg in $@ 9 | do 10 | shift 11 | [ $arg == "-i" ] && MODE=infinite_ RECOMPILE=yes 12 | [ $arg == "-f" ] && MODE=full 13 | [ $arg == "-s" ] && FILTER="tail -n50" 14 | [ $arg == "-a" ] && CFLAGS+=" -fsanitize=address" RECOMPILE=yes 15 | [ $arg == "-u" ] && CFLAGS+=" -fsanitize=undefined" RECOMPILE=yes 16 | [ $arg == "-v" ] && VALGRIND="yes" RECOMPILE=yes 17 | [ $arg == "-h" ] && { echo "Usage: $( basename $0 ) [-i] []"; echo " -i toggle infinite mode" ; exit 0 ; } 18 | [ $arg == "--" ] && { break; } 19 | done 20 | 21 | set -- $(echo $@) 22 | 23 | if [ "$MODE" == full ] 24 | then 25 | $0 -a map 26 | $0 -f map 27 | $0 -v map 28 | $0 -a vector 29 | $0 -f vector 30 | $0 -v vector 31 | $0 -a stack 32 | $0 -f stack 33 | $0 -v stack 34 | exit 35 | fi 36 | 37 | if [ "$1" != "vector" -a "$1" != "stack" -a "$1" != "map" -a "$1" != "set" ] 38 | then 39 | echo "Usage: $( basename $0 ) [-i] []" >&2 40 | exit 1 41 | fi 42 | 43 | C=$1 44 | shift 45 | 46 | [ ! -e .setup ] && ./setup.sh 47 | 48 | . .setup 49 | 50 | for i in "${INCLUDE_DIRECTORIES[@]}" 51 | do 52 | CFLAGS+=" -I"$i 53 | done 54 | 55 | check_last_change() 56 | { 57 | ret=0 58 | for file in $( find $INCLUDE_DIRECTORIES . -maxdepth 1 | grep '.hpp\|.hpp') 59 | do 60 | tmp="$(stat -c "%Y" $file )" 61 | : $(( ret = tmp > ret ? tmp : ret )) 62 | done 63 | echo $ret 64 | } 65 | 66 | if [ "$VALGRIND" != "yes" ] && [ ! -x bin/fifodiff ] || [ "$(stat -c %Y srcs/fifodiff.cpp)" -ge "$(stat -c %Y bin/fifodiff)" ] 67 | then 68 | echo "🐒 compiling fifodiff..." 69 | clang++ $CFLAGS -D BEFORE_SIZE=-1 srcs/fifodiff.cpp -o bin/fifodiff || exit 70 | fi 71 | 72 | if [ "$VALGRIND" != "yes" ] && [ "$MODE" == "infinite_" ] 73 | then 74 | CFLAGS+=" -D NTEST=-1" 75 | elif [ "$CPP_LOGGING" == "y" ] 76 | then 77 | CFLAGS+=" -D CPP_LOGGING" 78 | fi 79 | 80 | if [ "$VALGRIND" != "yes" ] && [ $RECOMPILE == "yes" ] || [ ! -x bin/"$MODE"std_containers_$C ] || [ "$(stat -c %Y srcs/main.cpp)" -ge "$(stat -c %Y bin/"$MODE"std_containers_$C)" ] 81 | then 82 | echo "🐒 compiling std... " 83 | clang++ $CFLAGS -D NAMESPACE=std -D MONKEY_$(echo $C | tr 'a-z' 'A-Z') srcs/main.cpp -o bin/"$MODE"std_containers_$C || exit 84 | fi 85 | 86 | if [ $RECOMPILE == "yes" ] || [ ! -x bin/"$MODE"ft_containers_$C ] || [ "$(check_last_change)" -ge "$(stat -c %Y bin/"$MODE"ft_containers_$C)" -o "$(stat -c %Y srcs/main.cpp)" -ge "$(stat -c %Y bin/"$MODE"ft_containers_$C)" ] 87 | then 88 | echo "🐒 compiling ft... " 89 | clang++ $CFLAGS -D NAMESPACE=ft -D MONKEY_$(echo $C | tr 'a-z' 'A-Z') srcs/main.cpp -o bin/"$MODE"ft_containers_$C || exit 90 | fi 91 | 92 | if [ "$VALGRIND" = "yes" ] 93 | then 94 | valgrind ./bin/"$MODE"ft_containers_$C $@ 95 | exit 96 | fi 97 | 98 | rm .std_$C .ft_$C 2>/dev/null 99 | mkfifo .std_$C .ft_$C 100 | trap "pkill -9 fifodiff; rm .std .ft 2>/dev/null" INT 101 | echo "🐒 running... " 102 | ./bin/"$MODE"std_containers_$C $@ >> .std_$C | ./bin/"$MODE"ft_containers_$C $@ >> .ft_$C | ./bin/fifodiff .std_$C .ft_$C | $FILTER 103 | rm .std_$C .ft_$C 2>/dev/null 104 | -------------------------------------------------------------------------------- /setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | prompt_yn() 4 | { 5 | while true 6 | do 7 | read answer 8 | [ "$answer" = "y" ] || [ "$answer" = "Y" ] && return 0 9 | [ "$answer" = "n" ] || [ "$answer" = "N" ] || [ -z "$answer" ] && return 1 10 | done 11 | } 12 | rm bin/* 2>/dev/null 13 | mkdir -p bin 14 | mkdir -p log 15 | if [ -f .setup ] 16 | then 17 | . .setup 18 | echo "Please enter the list of your sources directories separated by spaces (or nothing to keep current config):" 19 | else 20 | echo "Please enter the list of your sources directories separated by spaces:" 21 | fi 22 | read dirs 23 | echo -n "Would you like to use the awesome cpp logging feature (y/N)? " 24 | CPP_LOGGING=n 25 | if prompt_yn 26 | then 27 | CPP_LOGGING=y 28 | echo "When using monkey.sh the tester will generate a file containing" 29 | echo "cpp instructions to reproduce the same run without randomness" 30 | echo "which allow you to easily use gdb or any other debugger\n" 31 | echo "Use compile_log.sh to compile the generated file\n" 32 | [ ! -f compile_log.sh ] && cp .compile_log.sh compile_log.sh 33 | else 34 | [ -f compile_log.sh ] && rm compile_log.sh 35 | fi 36 | 37 | [ -n "$dirs" ] && INCLUDE_DIRECTORIES="$dirs" 38 | 39 | cat >.setup < 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include "logger.hpp" 17 | #include 18 | 19 | extern class logger logger; 20 | 21 | 22 | namespace monkey 23 | { 24 | template 25 | void print_full_vect(const C &v, const std::string &name) { 26 | logger.log("monkey::print_full_vect(" + name + ", \"" + name + "\");"); 27 | logger.log("empty: " + SSTR(v.empty())); 28 | logger.log("size: " + SSTR(v.size())); 29 | logger.log("content:"); 30 | for (typename C::const_iterator i = v.begin(); i != v.end(); i++) 31 | logger.log(" [" + SSTR(*i) + "]"); 32 | logger.log("reverse content:"); 33 | for (typename C::const_reverse_iterator i = v.rbegin(); i != v.rend(); i++) 34 | logger.log(" [" + SSTR(*i) + "]"); 35 | } 36 | 37 | template 38 | it add_iterator(it i, int n) { 39 | while (n > 0) { 40 | ++i; 41 | n--; 42 | } 43 | return (i); 44 | } 45 | 46 | template 47 | unsigned int distance(InputIt first, InputIt last) 48 | { 49 | unsigned int ret = 0; 50 | 51 | for (;first != last; ++first) 52 | ++ret; 53 | return(ret); 54 | } 55 | 56 | 57 | template 58 | typename T::iterator get_itn(T &c, int r, typename T::iterator min, std::forward_iterator_tag) 59 | { 60 | typename T::iterator ret = min; 61 | int pos = 0; 62 | unsigned long int m = c.size(); 63 | for (typename T::iterator it = min; it != c.end(); it++, m--); 64 | if (c.size() != m) 65 | pos = r % (c.size() - m); 66 | for (int i = 0; i < pos; i++) 67 | ret++; 68 | return (ret); 69 | } 70 | 71 | template 72 | typename T::iterator get_itn(T &c, int r, typename T::iterator min, std::random_access_iterator_tag) 73 | { 74 | if (min == c.end()) 75 | return (c.end()); 76 | return (min + (c.end() - min) % r); 77 | } 78 | 79 | /** 80 | * @def get an iterator at a random position of the container c after min based on the random number r 81 | * @param c the container to get the iterator from 82 | * @param r a random number 83 | * @param min the returned iterator is guaranteed to be min or after min 84 | */ 85 | template 86 | typename T::iterator get_itn(T &c, int r, typename T::iterator min) 87 | { 88 | return (get_itn(c, r, min, typename std::iterator_traits::iterator_category())); 89 | } 90 | 91 | /** 92 | * @def get an iterator at a random position of the container c based on the random number r 93 | * @param c the container to get the iterator from 94 | * @param r a random number 95 | */ 96 | template 97 | typename T::iterator get_itn(T &c, int r) 98 | { 99 | return (get_itn(c, r, c.begin())); 100 | } 101 | 102 | template 103 | T get_value() { 104 | return (T()); 105 | } 106 | 107 | template<> 108 | std::string get_value() { 109 | std::string default_val[] = { "", "amigo de la tornada", "amigo de pepito", 110 | "hola amigo", "un", "dos", "atencion", "un dos tres quatro", "la pantera"}; 111 | if (!(std::rand() % 3)) 112 | return (std::string(default_val[std::rand() % 8])); 113 | std::string ret = ""; 114 | for (int i = 0; i < 5; ++i) 115 | ret += (std::rand() % 26) + 'a'; 116 | return (ret); 117 | } 118 | 119 | template class P> 120 | void print_full_map(const C &m,const std::string &name) { 121 | logger.log("monkey::print_full_map(" + name + ", \"" + name + "\");"); 122 | 123 | logger.log("empty: " + SSTR(m.empty())); 124 | logger.log("size: " + SSTR(m.size())); 125 | logger.log("content:"); 126 | for (typename C::const_iterator i = m.begin(); i != m.end(); i++) 127 | logger.log(" [" + SSTR(i->first) + "] -> [" + SSTR(i->second) + "]"); 128 | logger.log("reverse content:"); 129 | for (typename C::const_reverse_iterator i = m.rbegin(); i != m.rend(); i++) 130 | logger.log(" [" + SSTR(i->first) + "] -> [" + SSTR(i->second) + "]"); 131 | } 132 | } 133 | 134 | #endif //FT_CONTAINERS_MONKEY_TESTER_COMMON_HPP 135 | -------------------------------------------------------------------------------- /srcs/fifodiff.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by jgiron on 12/4/21. 3 | // 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #ifndef BUFFER_SIZE 14 | #define BUFFER_SIZE 1 15 | #endif 16 | #ifndef BEFORE_SIZE 17 | # define BEFORE_SIZE -1 18 | #endif 19 | bool stop = false; 20 | 21 | void handler(int) 22 | { 23 | stop = true; 24 | } 25 | 26 | int main(int argc, char **argv) 27 | { 28 | char buf1[BUFFER_SIZE + 1]; 29 | char buf2[BUFFER_SIZE + 1]; 30 | int fd1, fd2; 31 | int ret1 = 1, ret2 = 1; 32 | std::deque d1, d2; 33 | std::deque before; 34 | int pos = 0; 35 | 36 | signal(SIGTERM, &handler); 37 | buf1[BUFFER_SIZE] = 0; 38 | buf2[BUFFER_SIZE] = 0; 39 | if (argc == 3) 40 | { 41 | if ((fd1 = open(argv[1], O_RDONLY | O_NONBLOCK)) == -1 || (fd2 = open(argv[2], O_RDONLY | O_NONBLOCK)) == -1) 42 | { 43 | perror("open"); 44 | return (1); 45 | } 46 | std::cout << "\033[32m"; 47 | while ( !(ret1 <= 0 && ret2 <= 0 && stop)) 48 | { 49 | ret1 = read(fd1, buf1, BUFFER_SIZE); 50 | if (ret1 == -1 && errno != EAGAIN) 51 | { 52 | perror("fifodiff"); 53 | return 1; 54 | } 55 | ret2 = read(fd2, buf2, BUFFER_SIZE); 56 | if (ret2 == -1 && errno != EAGAIN) 57 | { 58 | perror("fifodiff"); 59 | return 1; 60 | } 61 | // std::cout << ret1 << " " << ret2 << std::endl; 62 | for (int i = 0; i < ret1; i++) 63 | d1.push_back(buf1[i]); 64 | for (int i = 0; i < ret2; i++) 65 | d2.push_back(buf2[i]); 66 | while (!d2.empty() && !d1.empty()) { 67 | if (d1.front() == d2.front()) { 68 | if (d1.front() == 3) { 69 | std::cout << std::endl << "\033[0m🐒 no diff detected" << std::endl; 70 | return (0); 71 | } 72 | #if BEFORE_SIZE > 0 73 | before.push_back(d1.front()); 74 | if (before.size() > BEFORE_SIZE) 75 | before.pop_front(); 76 | #else 77 | std::cout << d1.front(); 78 | #endif 79 | d1.pop_front(); 80 | d2.pop_front(); 81 | pos++; 82 | } 83 | else 84 | { 85 | if ((d2.size() >= 100 && d1.size() >= 100)) { 86 | std::cout << std::endl << "\033[0m🐒 files differ!!! (pos: " << pos << ")" << std::endl; 87 | #if BEFORE_SIZE > 0 88 | std::cout << "context:" << std::endl; 89 | for (std::deque::size_type i = 0; i < BEFORE_SIZE && i < before.size(); i++) 90 | std::cout << before[i]; 91 | std::cout << std::endl; 92 | std::cout << "===================================================== "; 93 | #endif 94 | std::cout << "\033[0m" << argv[1] << ":" << std::endl; 95 | std::cout << "\033[31m"; 96 | for (std::deque::size_type i = 0; i < 200 && i < d1.size(); i++) 97 | std::cout << d1[i]; 98 | std::cout << std::endl; 99 | std::cout << "\033[0m"; 100 | std::cout << argv[2] << ":" << std::endl; 101 | std::cout << "\033[31m"; 102 | for (std::deque::size_type i = 0; i < 200 && i < d1.size(); i++) 103 | std::cout << d2[i]; 104 | std::cout << std::endl; 105 | return (1); 106 | } 107 | break; 108 | } 109 | } 110 | } 111 | if (ret1 != ret2) 112 | return (1); 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /srcs/input_iterator.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by joachim on 3/9/22. 3 | // 4 | 5 | #ifndef FT_CONTAINERS_MONKEY_TESTER_INPUT_ITERATOR_HPP 6 | # define FT_CONTAINERS_MONKEY_TESTER_INPUT_ITERATOR_HPP 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | /** 13 | * this class downgrade any iterator satisfying the input iterator 14 | * requirement to the most basic input iterator 15 | * @tparam base_it the iterator to downgrade 16 | * @warning an incrementation invalidate all copies 17 | */ 18 | template 19 | class input_iterator 20 | { 21 | base_it it; 22 | bool valid; 23 | public: 24 | typedef typename std::iterator_traits::value_type value_type; 25 | typedef typename std::iterator_traits::pointer pointer; 26 | typedef typename std::iterator_traits::reference reference; 27 | typedef typename std::iterator_traits::difference_type difference_type; 28 | typedef typename std::input_iterator_tag iterator_category; 29 | std::set equivalents; 30 | input_iterator() : it(), valid(true), equivalents() {} 31 | input_iterator(const base_it it) : it(it), valid(true), equivalents() {} 32 | input_iterator(const input_iterator &src) : it(src.it), valid(src.valid), equivalents(src.equivalents) { 33 | if (valid) 34 | { 35 | this->equivalents.insert((input_iterator *)&src); 36 | for (typename std::set::iterator i = this->equivalents.begin(); 37 | i != this->equivalents.end(); i++) 38 | (*i)->equivalents.insert(this); 39 | } 40 | } 41 | ~input_iterator() 42 | { 43 | for (typename std::set::iterator i = this->equivalents.begin(); i != this->equivalents.end(); i++) 44 | (*i)->equivalents.erase(this); 45 | this->equivalents.clear(); 46 | } 47 | input_iterator &operator=(input_iterator const & src) { 48 | for (typename std::set::iterator i = this->equivalents.begin(); i != this->equivalents.end(); i++) 49 | (*i)->equivalents.erase(this); 50 | this->equivalents.clear(); 51 | this->it = src.it; 52 | this->valid = src.valid; 53 | if (valid) { 54 | this->equivalents.insert(&src); 55 | for (typename std::set::iterator i = this->equivalents.begin(); i != this->equivalents.end(); i++) 56 | (*i)->equivalents.insert(this); 57 | } 58 | } 59 | class invalid_inputit : public std::exception 60 | { 61 | const char * what() const throw() 62 | { 63 | return ("an invalidated input iterator was used"); 64 | } 65 | }; 66 | friend bool operator==(input_iterator const &l, input_iterator const &r){ 67 | return (l.it == r.it); 68 | } 69 | friend bool operator!=(input_iterator const &l, input_iterator const &r){ 70 | return (l.it != r.it); 71 | } 72 | const typename std::iterator_traits::value_type &operator*() const { 73 | if (!this->valid) 74 | throw invalid_inputit(); 75 | return (*it); 76 | } 77 | const typename std::iterator_traits::pointer operator->() const { 78 | if (!this->valid) 79 | throw invalid_inputit(); 80 | return (&*it); 81 | } 82 | input_iterator &operator++() { 83 | if (!this->valid) 84 | throw invalid_inputit(); 85 | for (typename std::set::iterator i = this->equivalents.begin(); i != this->equivalents.end(); i++) 86 | { 87 | (*i)->valid = false; 88 | (*i)->equivalents.clear(); 89 | } 90 | this->equivalents.clear(); 91 | ++(this->it); 92 | return(*this); 93 | } 94 | input_iterator operator++(int) { 95 | if (!this->valid) 96 | throw invalid_inputit(); 97 | input_iterator ret(*this); 98 | ++(*this); 99 | return(ret); 100 | } 101 | }; 102 | 103 | #endif //FT_CONTAINERS_MONKEY_TESTER_INPUT_ITERATOR_HPP 104 | -------------------------------------------------------------------------------- /srcs/logger.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by joachim on 3/8/22. 3 | // 4 | 5 | #ifndef FT_CONTAINERS_MONKEY_TESTER_LOGGER_HPP 6 | #define FT_CONTAINERS_MONKEY_TESTER_LOGGER_HPP 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #ifndef CPP_LOG_PATH 14 | # define CPP_LOG_PATH "./log" 15 | #endif 16 | 17 | /** 18 | * convert any variable with "<<" overload to string using ostringstream 19 | */ 20 | #ifndef SSTR 21 | # define SSTR( x ) (static_cast< std::ostringstream & >( ( std::ostringstream() << std::dec << (x) ) ).str()) 22 | #endif 23 | /** 24 | * this logger is used both for printing the outputs of the 25 | * program and generate the cpp file containing the tests 26 | * performed by the tester 27 | */ 28 | class logger 29 | { 30 | public: 31 | std::ofstream file; 32 | int block_depth; 33 | bool log_cpp; 34 | bool raw; 35 | size_t line; 36 | 37 | logger() : block_depth(0), log_cpp(false), raw(false), line(0) {} 38 | ~logger() 39 | { 40 | if (log_cpp) 41 | file.close(); 42 | } 43 | 44 | enum e_log_type { 45 | NONE, 46 | OUTPUT, 47 | TITLE, 48 | CPP, 49 | CPP_LOG, 50 | ERROR, 51 | BREAKPOINT 52 | }; 53 | 54 | /** 55 | * open a file for cpp logging 56 | * @param path path to the file 57 | */ 58 | void open(std::string const &path) 59 | { 60 | file.open(path.data()); 61 | if (!file.is_open()) 62 | throw std::runtime_error("can't open file"); 63 | else 64 | this->log_cpp = true; 65 | } 66 | 67 | typedef enum e_log_type t_log_type; 68 | /** 69 | * log a line without various mode, default behaviour is to print the line in stdout 70 | * @tparam mode one of logger::e_log_type 71 | * @param s the line to write 72 | * @return the number of characters wrote 73 | */ 74 | template 75 | int log(std::string const &s){ 76 | std::cout << s << "\n"; 77 | return (s.length() + 1); 78 | }; 79 | 80 | std::string put_indent(int n) 81 | { 82 | std::string out; 83 | for (int i = 0; i < n; i++) 84 | out += "\t"; 85 | return out; 86 | } 87 | 88 | /** 89 | * insert one line of c++ in the cpp file with block management 90 | * @param s the line to insert 91 | * @return the number of characters inserted 92 | */ 93 | template <> 94 | int log(std::string const &s){ 95 | if (!log_cpp) 96 | return (0); 97 | std::string out; 98 | int pos = this->file.tellp(); 99 | 100 | pos -= (2 * block_depth + ((block_depth - 1) * block_depth) / 2); 101 | this->file.seekp(pos); 102 | out += put_indent(block_depth); 103 | out += s; 104 | out += "\n"; 105 | this->line += std::count(out.begin(), out.end(), '\n'); 106 | for (int i = block_depth - 1; i >= 0; i--) 107 | { 108 | out += put_indent(i ); 109 | out += "}\n"; 110 | } 111 | 112 | file << out; 113 | file.flush(); 114 | return (out.length()); 115 | }; 116 | 117 | /** 118 | * put one line in stderr 119 | * @param s the line to insert 120 | * @return the number of characters wrote 121 | */ 122 | template <> 123 | int log(std::string const &s){ 124 | std::cerr << s << "\n"; 125 | return (s.length() + 1); 126 | }; 127 | 128 | /** 129 | * output one line in stdout and put an instruction for printing this line in the cpp file 130 | * @param s the line to insert 131 | * @return the number of characters inserted in the cpp file 132 | */ 133 | template <> 134 | int log(std::string const &s){ 135 | this->log(s); 136 | return (this->log("\"" + s + "\"")); 137 | }; 138 | 139 | /** 140 | * put an instruction for printing a line in the cpp file 141 | * @param s the line to print 142 | * @return the number of characters wrote in the cpp file 143 | */ 144 | template <> 145 | int log(std::string const &s){ 146 | if (!log_cpp) 147 | return (0); 148 | return (this->log("logger.log(" + s + ");")); //BOOM!!! logger-ception BITCH! 149 | }; 150 | 151 | /** 152 | * equivalent of logger::log() with title formating if the logger is not set to raw 153 | * @param s the line to insert 154 | * @return the number of characters inserted in the cpp file 155 | */ 156 | template <> 157 | int log(std::string const &s){ 158 | int ret; 159 | if (!raw) 160 | ret = this->log<OUTPUT>("\033[1m" + s + "\033[0m"); 161 | else 162 | ret = this->log<OUTPUT>(s); 163 | return (ret); 164 | }; 165 | 166 | template <> 167 | int log<BREAKPOINT>(std::string const &) 168 | { 169 | if (!log_cpp) 170 | return (0); 171 | this->log<NONE>("[GDB]===================================> br log.cpp:" + SSTR(this->line + 1)); 172 | return (this->log<CPP>("std::cout << \"[GDB]===================================> br \" << __FILE_NAME__ << \":\" << __LINE__ << std::endl;")); 173 | } 174 | 175 | /** 176 | * create a new block in the cpp file and place the plot in it 177 | * @warning a block must be ended by a call to pop_block() 178 | */ 179 | void create_block() 180 | { 181 | if (!log_cpp) 182 | return ; 183 | this->log<CPP>("{"); 184 | this->log<CPP>("}"); 185 | this->line--; 186 | this->block_depth++; 187 | } 188 | 189 | /** 190 | * pop the plot out of a block 191 | */ 192 | void pop_block() 193 | { 194 | if (!log_cpp) 195 | return ; 196 | if (this->block_depth > 0) 197 | { 198 | this->block_depth--; 199 | this->line++; 200 | } 201 | } 202 | 203 | /** 204 | * create a function in the cpp file 205 | * @param proto the prototype of the function 206 | * @warning a function must be ended by a call to pop_block() 207 | */ 208 | void create_function(std::string const &proto) 209 | { 210 | if (!log_cpp) 211 | return ; 212 | this->log<CPP>(proto); 213 | this->create_block(); 214 | } 215 | 216 | /** 217 | * set a typedef in the cpp file 218 | */ 219 | void set_typedef(std::string const &value, std::string const &define) 220 | { 221 | if (!log_cpp) 222 | return ; 223 | this->log<CPP>("typedef " + value + " " + define + ";"); 224 | } 225 | 226 | /** 227 | * insert a define in the cpp file 228 | * @param protect whether or not the define should be protected 229 | */ 230 | void define(std::string const &define, std::string const &value, bool protect = true) 231 | { 232 | if (!log_cpp) 233 | return ; 234 | if (protect) 235 | this->log<CPP>("#ifndef " + define); 236 | this->log<CPP>("# define " + define + " " + value); 237 | if (protect) 238 | this->log<CPP>("#endif"); 239 | } 240 | /** 241 | * create an include in the cpp file 242 | * @param file the file to include 243 | */ 244 | void include(const std::string &file) 245 | { 246 | if (!log_cpp) 247 | return ; 248 | this->log<CPP>("#include <" + file + ">"); 249 | } 250 | 251 | void init_cpp() 252 | { 253 | if (!log_cpp) 254 | return ; 255 | 256 | #ifdef MONKEY_MAP 257 | this->define("MONKEY_MAP", ""); 258 | #endif 259 | #ifdef MONKEY_VECTOR 260 | this->define("MONKEY_VECTOR", ""); 261 | #endif 262 | #ifdef MONKEY_STACK 263 | this->define("MONKEY_STACK", ""); 264 | #endif 265 | this->include("string"); 266 | this->include("iostream"); 267 | this->include("map"); 268 | this->include("set"); 269 | this->include("vector"); 270 | this->include("stack"); 271 | this->include("utility"); 272 | this->log<CPP>("#ifndef SSTR"); 273 | this->log<CPP>("# define SSTR( x ) (static_cast< std::ostringstream & >( ( std::ostringstream() << std::dec << (x) ) ).str())"); 274 | this->log<CPP>("#endif"); 275 | } 276 | }; 277 | 278 | #endif //FT_CONTAINERS_MONKEY_TESTER_LOGGER_HPP 279 | -------------------------------------------------------------------------------- /srcs/main.cpp: -------------------------------------------------------------------------------- 1 | #define DEBUG 2 | #ifdef MONKEY_MAP 3 | # include "test_map.hpp" 4 | #endif 5 | #ifdef MONKEY_VECTOR 6 | # include "test_vector.hpp" 7 | #endif 8 | #ifdef MONKEY_STACK 9 | # include "test_stack.hpp" 10 | #endif 11 | #include "../includes.hpp" 12 | #include <string> 13 | #include <iostream> 14 | #include <map> 15 | #include <vector> 16 | #include <stack> 17 | #include <unistd.h> 18 | #include <cstdlib> 19 | #include <sys/time.h> 20 | #include "logger.hpp" 21 | #ifndef NAMESPACE 22 | # define NAMESPACE ft 23 | #endif 24 | #ifndef NTEST 25 | # define NTEST 1000 26 | #endif 27 | #ifndef CPP_LOG_PATH 28 | # define CPP_LOG_PATH "./log/" 29 | #endif 30 | #define STR_EXPAND(tok) #tok 31 | #define STR(tok) STR_EXPAND(tok) 32 | 33 | class logger logger; 34 | 35 | int main(int argc, char **argv) 36 | { 37 | int seed = 42; 38 | int ret = 0; 39 | 40 | if (argc == 2) 41 | seed = atoi(argv[1]); 42 | #ifdef CPP_LOGGING 43 | if (NTEST != -1) { 44 | logger.open(std::string(CPP_LOG_PATH) + "/log.cpp" ); 45 | logger.raw = true; 46 | } 47 | #endif 48 | logger.init_cpp(); 49 | logger.define("NAMESPACE", "ft"); 50 | logger.define("_P", "NAMESPACE::pair"); 51 | logger.include("includes.hpp"); 52 | logger.include("input_iterator.hpp"); 53 | logger.include("common.hpp"); 54 | logger.log<logger::CPP>("class logger logger;"); 55 | logger.create_function("int main()"); 56 | #ifdef MONKEY_MAP 57 | logger.set_typedef("NAMESPACE::map<std::string, std::string>", "C"); 58 | test_map<NAMESPACE::map<std::string, std::string, monkey_map::my_compare>, NAMESPACE::pair>(seed); 59 | #endif 60 | #ifdef MONKEY_VECTOR 61 | logger.set_typedef("NAMESPACE::vector<std::string>", "C"); 62 | test_vector<NAMESPACE::vector<std::string> >(seed); 63 | #endif 64 | #ifdef MONKEY_STACK 65 | logger.set_typedef("NAMESPACE::stack<std::string>", "C"); 66 | test_stack<NAMESPACE::stack<std::string> >(seed); 67 | #endif 68 | logger.pop_block(); 69 | if (!isatty(1)) 70 | logger.log<logger::NONE>("\3"); 71 | return ret; 72 | } 73 | -------------------------------------------------------------------------------- /srcs/test_map.hpp: -------------------------------------------------------------------------------- 1 | #include "../includes.hpp" 2 | #include "common.hpp" 3 | #include <iostream> 4 | #include <map> 5 | #include <set> 6 | #include <cstdlib> 7 | #include <iterator> 8 | #include <string> 9 | #include <climits> 10 | #include "logger.hpp" 11 | #include <sstream> 12 | #include "input_iterator.hpp" 13 | #ifndef NTEST 14 | # define NTEST 1000 15 | #endif 16 | 17 | extern class logger logger; 18 | 19 | namespace monkey_map { 20 | 21 | /** 22 | * this class is given in template argument to the tested map in order to check if 23 | * key_compare is used for comparisons 24 | */ 25 | class my_compare { 26 | public: 27 | my_compare(){} 28 | std::string reverse(std::string s) const 29 | { 30 | long int i = 0; 31 | long int j = s.length() - 1; 32 | char swap; 33 | while (i < j) 34 | { 35 | swap = s[i]; 36 | s[i] = s[j]; 37 | s[j] = swap; 38 | ++i; 39 | --j; 40 | } 41 | return (s); 42 | } 43 | bool operator()(const std::string &l, const std::string &r) const 44 | { 45 | return (reverse(l) > reverse(r)); 46 | } 47 | }; 48 | 49 | template<class C, template<class, class> class P> 50 | void test_clear(const std::string &n1, C &m1, const std::string &, C &) { 51 | logger.log<logger::TITLE>("test_clear:"); 52 | logger.create_block(); 53 | logger.log<logger::CPP>("C m3(" + n1 + ");"); 54 | C m3(m1); 55 | logger.log<logger::CPP>(n1 + ".clear();"); 56 | m1.clear(); 57 | monkey::print_full_map<C, P>(m3, "m3"); 58 | logger.log<logger::CPP>("m3.clear();"); 59 | m3.clear(); 60 | logger.pop_block(); 61 | } 62 | 63 | template<class C, template<class, class> class P> 64 | void test_copy_construct_equal(const std::string &n1, C &m1, const std::string &n2, C &m2) { 65 | logger.log<logger::TITLE>("test_copy_construct_equal:"); 66 | 67 | logger.create_block(); 68 | logger.log<logger::CPP>("C m3(" + n1 + ");"); 69 | C v3(m1); 70 | logger.log<logger::CPP>(n1 + " = " + n2 + ";"); 71 | m1 = m2; 72 | logger.log<logger::CPP>(n2 + " = m3;"); 73 | m2 = v3; 74 | logger.pop_block(); 75 | } 76 | 77 | template<class C, template<class, class> class P> 78 | void test_construct(const std::string &n1, C &m1, const std::string &, C &) { 79 | logger.log<logger::TITLE>("test_construct:"); 80 | logger.create_block(); 81 | const std::set<typename C::value_type> s(m1.begin(), m1.end()); 82 | logger.log<logger::CPP>("std::set<C::value_type> set(" + n1 + ".begin(), " + n1 + ".end());"); 83 | m1 = C( input_iterator<typename std::set<typename C::value_type>::iterator>(s.begin()), input_iterator<typename std::set<typename C::value_type>::iterator>(s.end())); 84 | logger.log<logger::CPP>( n1 + " = C( input_iterator<std::set<C::value_type>::iterator>(set.begin()), input_iterator<std::set<C::value_type>::iterator>(set.end()));"); 85 | logger.pop_block(); 86 | } 87 | 88 | template<class C, template<class, class> class P> 89 | void test_operator_index(const std::string &n1, C &m1, const std::string &, C &) { 90 | logger.log<logger::TITLE>("test_operator_index:"); 91 | std::string key; 92 | std::string val; 93 | 94 | for (int i = 0; i < 5; i++) { 95 | key = monkey::get_value<typename C::mapped_type>(); 96 | val = monkey::get_value<typename C::mapped_type>(); 97 | m1[key] = val; 98 | logger.log<logger::CPP>(n1 + "[\"" + key +"\"] = \"" + val + "\";"); 99 | 100 | key = monkey::get_value<typename C::mapped_type>(); 101 | logger.log<logger::CPP>("std::cout << " + n1 + "[\"" + key +"\"] << std::endl;"); 102 | std::cout << m1[key] << std::endl; 103 | } 104 | // monkey::print_full_map<C, P>(m1); 105 | // monkey::print_full_map<C, P>(m2); 106 | } 107 | 108 | template<class C, template<class, class> class P> 109 | void test_insert(const std::string &n1, C &m1, const std::string &n2, C &m2) { 110 | logger.log<logger::TITLE>("test_insert:"); 111 | P<typename C::iterator, bool> pair_it_bool; 112 | P<typename C::key_type, typename C::mapped_type> val; 113 | typename C::iterator it1; 114 | typename C::iterator it2; 115 | unsigned int rand; 116 | std::string key; 117 | std::string value; 118 | 119 | for (int i = 0; i < 5; i++) { 120 | 121 | switch (std::rand() % 3) { 122 | case (0): 123 | logger.log<logger::TITLE>("insert value_type:"); 124 | key = monkey::get_value<typename C::key_type>(); 125 | value = monkey::get_value<typename C::mapped_type>(); 126 | val = NAMESPACE::make_pair(key, value); 127 | logger.log<logger::CPP>("val = _P<C::key_type, C::mapped_type>(\"" + key + "\", \"" + value + "\");"); 128 | logger.log<logger::CPP>("pair_it_bool = " + n1 + ".insert(val);"); 129 | pair_it_bool = m1.insert(val); 130 | logger.log<logger::NONE>("ret = " + SSTR(pair_it_bool.first->first) + " " + SSTR(pair_it_bool.second)); 131 | logger.log<logger::CPP_LOG>("\"ret = \" + SSTR(pair_it_bool.first->first) + SSTR(pair_it_bool.second)"); 132 | break; 133 | case (1): 134 | logger.log<logger::TITLE>("insert range:" ); 135 | rand = std::rand(); 136 | it1 = monkey::get_itn(m1, rand); 137 | rand = std::rand(); 138 | it2 = monkey::get_itn(m1, rand, it1); 139 | logger.log<logger::CPP>("it1 = monkey::get_itn(" + n1 + ", " + SSTR(rand) + ");"); 140 | logger.log<logger::CPP>("it2 = monkey::get_itn(" + n1 + ", " + SSTR(rand) + ", it1);"); 141 | logger.log<logger::CPP>(n2 + ".insert(input_iterator<C::iterator>(it1), input_iterator<C::iterator>(it2));"); 142 | m2.insert(input_iterator<typename C::iterator>(it1), input_iterator<typename C::iterator>(it2)); 143 | break; 144 | case (2): 145 | logger.log<logger::TITLE>("insert hint:" ); 146 | rand = std::rand(); 147 | it1 = monkey::get_itn(m1, rand); 148 | logger.log<logger::CPP>("it1 = monkey::get_itn(" + n1 + ", " + SSTR(rand) + ");"); 149 | key = monkey::get_value<typename C::key_type>(); 150 | value = monkey::get_value<typename C::mapped_type>(); 151 | val = NAMESPACE::make_pair(key, value); 152 | logger.log<logger::CPP>("val = _P<C::key_type, C::mapped_type>(\"" + key + "\", \"" + value + "\");"); 153 | logger.log<logger::CPP>("it1 = " + n1 + ".insert(it1, val);"); 154 | it1 = m1.insert(it1, val); 155 | logger.log<logger::NONE>("ret = " + SSTR(it1->first) + " " + SSTR(it1->second)); 156 | logger.log<logger::CPP_LOG>("\"ret = \" + SSTR(it1->first) + SSTR(it1->second)"); 157 | break; 158 | } 159 | } 160 | monkey::print_full_map<C, P>(m1, n1); 161 | } 162 | 163 | template<class C, template<class, class> class P> 164 | void test_erase(const std::string &n1, C &m1, const std::string &, C &) { 165 | typename C::mapped_type val; 166 | typename C::iterator it1; 167 | typename C::iterator it2; 168 | int rand; 169 | int ret; 170 | 171 | logger.log<logger::TITLE>("test_erase:" ); 172 | for (int i = 0; i < 5; i++) { 173 | switch (std::rand() % 3) { 174 | case (0): 175 | if (!m1.empty()) { 176 | logger.log<logger::TITLE>("erase it:" ); 177 | rand = std::rand(); 178 | it1 = monkey::get_itn(m1, rand); 179 | logger.template log<logger::CPP>("it1 = monkey::get_itn(" + n1 + ", " + SSTR(rand) + ");"); 180 | m1.erase(it1); 181 | logger.template log<logger::CPP>("if (!" +n1 + ".empty())"); 182 | logger.create_block(); 183 | logger.template log<logger::CPP>(n1 + ".erase(it1);"); 184 | logger.pop_block(); 185 | } 186 | break; 187 | case (1): 188 | if (!m1.empty()) { 189 | logger.log<logger::TITLE>("erase key_type:" ); 190 | val = monkey::get_value<typename C::key_type>(); 191 | ret = m1.erase(val); 192 | logger.log<logger::CPP>("ret = " + n1 + ".erase(\"" + val + "\");"); 193 | logger.log<logger::CPP_LOG>("\"ret = \" + SSTR(ret)"); 194 | logger.log<logger::NONE>("ret = " + SSTR(ret)); 195 | } 196 | break; 197 | case (2): 198 | logger.log<logger::TITLE>("erase range:" ); 199 | rand = std::rand(); 200 | it1 = monkey::get_itn(m1, rand); 201 | logger.log<logger::CPP>("it1 = monkey::get_itn(" + n1 + ", " + SSTR(rand) + ");"); 202 | rand = std::rand(); 203 | it2 = monkey::get_itn(m1, rand, it1); 204 | logger.log<logger::CPP>("it2 = monkey::get_itn(" + n1 + ", " + SSTR(rand) + ", it1);"); 205 | m1.erase(it1, it2); 206 | logger.log<logger::CPP>(n1 + ".erase(it1, it2);"); 207 | } 208 | } 209 | } 210 | 211 | template<class C, template<class, class> class P> 212 | void test_count(const std::string &n1, C &m1, const std::string &, C &) { 213 | std::string key = monkey::get_value<typename C::mapped_type>(); 214 | logger.log<logger::TITLE>("test_count: [" + SSTR(key) + "]" ); 215 | logger.log<logger::CPP>("ret = " + n1 + ".count(\"" + key + "\");"); 216 | int ret = m1.count(key); 217 | logger.log<logger::CPP_LOG>("\"ret = \" + SSTR(ret)"); 218 | logger.log<logger::NONE>("ret = " + SSTR(ret)); 219 | } 220 | 221 | template<class C, template<class, class> class P> 222 | void test_find(const std::string &n1, C &m1, const std::string &, C &) { 223 | std::string key = monkey::get_value<typename C::mapped_type>(); 224 | logger.log<logger::TITLE>("test_find: [" + SSTR(key) + "]"); 225 | 226 | logger.log<logger::CPP>("it1 = " + n1 + ".find(\"" + key + "\");"); 227 | typename C::iterator ret = m1.find(key); 228 | 229 | logger.template log<logger::CPP>("if (it1 != " + n1 + ".end())"); 230 | logger.create_block(); 231 | logger.template log<logger::CPP_LOG>("\"ret = \" + SSTR(it1->first)"); 232 | logger.pop_block(); 233 | if (ret != m1.end()) 234 | std::cout << ret->first << std::endl; 235 | } 236 | 237 | template<class C, template<class, class> class P> 238 | void test_equal_range(const std::string &n1, C &m1, const std::string &, C &) { 239 | std::string key = monkey::get_value<typename C::mapped_type>(); 240 | logger.log<logger::TITLE>("test_equal_range: [" + SSTR(key) + "]" ); 241 | P<typename C::iterator, typename C::iterator> ret = m1.equal_range(key); 242 | logger.template log<logger::CPP>("range = " + n1 + ".equal_range(\"" + key + "\");"); 243 | logger.template log<logger::CPP>("if (range.first != " + n1 + ".end())"); 244 | logger.create_block(); 245 | logger.template log<logger::CPP_LOG>("\"ret1 = \" + SSTR(range.first->first)"); 246 | logger.pop_block(); 247 | logger.template log<logger::CPP>("if (range.second != " + n1 + ".end())"); 248 | logger.create_block(); 249 | logger.template log<logger::CPP_LOG>("\"ret1 = \" + SSTR(range.second->first)"); 250 | logger.pop_block(); 251 | if (ret.first != m1.end()) 252 | std::cout << ret.first->first << std::endl; 253 | if (ret.second != m1.end()) 254 | std::cout << ret.second->first << std::endl; 255 | } 256 | 257 | template<class C, template<class, class> class P> 258 | void test_upper_bound(const std::string &n1, C &m1, const std::string &, C &) { 259 | std::string key = monkey::get_value<typename C::mapped_type>(); 260 | logger.log<logger::TITLE>("test_upper_bound: [" + SSTR(key) + "]" ); 261 | 262 | typename C::iterator ret = m1.upper_bound(key); 263 | logger.log<logger::CPP>("it1 = " + n1 + ".upper_bound(\"" + key + "\");"); 264 | logger.template log<logger::CPP>("if (it1 != " + n1 + ".end())"); 265 | logger.create_block(); 266 | logger.template log<logger::CPP_LOG>("\"ret1 = \" + SSTR(it1->first)"); 267 | logger.pop_block(); 268 | if (ret != m1.end()) 269 | std::cout << ret->first << std::endl; 270 | } 271 | 272 | template<class C, template<class, class> class P> 273 | void test_lower_bound(const std::string &n1, C &m1, const std::string &, C &) { 274 | std::string key = monkey::get_value<typename C::mapped_type>(); 275 | logger.log<logger::TITLE>("test_lower_bound: [" + SSTR(key) + "]"); 276 | 277 | typename C::iterator ret = m1.lower_bound(key); 278 | logger.log<logger::CPP>("it1 = " + n1 + ".lower_bound(\"" + key + "\");"); 279 | logger.template log<logger::CPP>("if (it1 != " + n1 + ".end())"); 280 | logger.create_block(); 281 | logger.template log<logger::CPP_LOG>("\"ret1 = \" + SSTR(it1->first)"); 282 | logger.pop_block(); 283 | if (ret != m1.end()) 284 | std::cout << ret->first << std::endl; 285 | } 286 | 287 | template<class C, template<class, class> class P> 288 | void test_swap(const std::string &n1, C &m1, const std::string &n2, C &m2) { 289 | logger.log<logger::TITLE>("test_swap:"); 290 | logger.log<logger::CPP>(n1 + ".swap(" + n2 + ");"); 291 | m1.swap(m2); 292 | } 293 | 294 | template<class C, template<class, class> class P> 295 | void test_stdswap(const std::string &n1, C &m1, const std::string &n2, C &m2) { 296 | logger.log<logger::TITLE>("test_stdswap:"); 297 | logger.log<logger::CPP>("std::swap(" + n1 + ", " + n2 + ");"); 298 | std::swap(m1, m2); 299 | } 300 | 301 | template<class C, template<class, class> class P> 302 | void test_comparison(const std::string &n1, C &m1, const std::string &n2, C &m2) { 303 | logger.log<logger::TITLE>("test_comparison:"); 304 | 305 | logger.log<logger::NONE>(n1 + " < " + n2 + ": " + SSTR(m1 < m2)); 306 | logger.log<logger::NONE>(n1 + " > " + n2 + ": " + SSTR(m1 > m2)); 307 | logger.log<logger::NONE>(n1 + " <= " + n2 + ": " + SSTR(m1 <= m2)); 308 | logger.log<logger::NONE>(n1 + " >= " + n2 + ": " + SSTR(m1 >= m2)); 309 | logger.log<logger::NONE>(n1 + " == " + n2 + ": " + SSTR(m1 == m2)); 310 | logger.log<logger::NONE>(n1 + " != " + n2 + ": " + SSTR(m1 != m2)); 311 | 312 | logger.log<logger::CPP_LOG>("\"" + n1 + " < " + n2 + ": \" + SSTR( " + n1 + " < " + n2 + ")"); 313 | logger.log<logger::CPP_LOG>("\"" + n1 + " > " + n2 + ": \" + SSTR( " + n1 + " > " + n2 + ")"); 314 | logger.log<logger::CPP_LOG>("\"" + n1 + " <= " + n2 + ": \" + SSTR( " + n1 + " <= " + n2 + ")"); 315 | logger.log<logger::CPP_LOG>("\"" + n1 + " >= " + n2 + ": \" + SSTR( " + n1 + " >= " + n2 + ")"); 316 | logger.log<logger::CPP_LOG>("\"" + n1 + " == " + n2 + ": \" + SSTR( " + n1 + " == " + n2 + ")"); 317 | logger.log<logger::CPP_LOG>("\"" + n1 + " != " + n2 + ": \" + SSTR( " + n1 + " != " + n2 + ")"); 318 | } 319 | } 320 | template<class C, template<class, class> class P> 321 | void test_map(int seed) { 322 | std::srand(seed); 323 | void (*array[])(const std::string &, C &,const std::string &,C &) = { 324 | &monkey_map::test_construct<C, P>, 325 | &monkey_map::test_copy_construct_equal<C, P>, 326 | &monkey_map::test_operator_index<C, P>, 327 | &monkey_map::test_clear<C, P>, 328 | &monkey_map::test_insert<C, P>, 329 | &monkey_map::test_count<C, P>, 330 | &monkey_map::test_find<C, P>, 331 | &monkey_map::test_equal_range<C, P>, 332 | &monkey_map::test_upper_bound<C, P>, 333 | &monkey_map::test_lower_bound<C, P>, 334 | &monkey_map::test_erase<C, P>, 335 | &monkey_map::test_swap<C, P>, 336 | &monkey_map::test_stdswap<C, P>, 337 | &monkey_map::test_comparison<C, P> 338 | }; 339 | 340 | C m1; logger.log<logger::CPP>("C m1;"); 341 | C m2; logger.log<logger::CPP>("C m2;"); 342 | logger.log<logger::CPP>("int ret;"); 343 | logger.log<logger::CPP>("C::iterator it1;"); 344 | logger.log<logger::CPP>("input_iterator<C::iterator> inputit1;"); 345 | logger.log<logger::CPP>("C::iterator it2;"); 346 | logger.log<logger::CPP>("input_iterator<C::iterator> inputit2;"); 347 | logger.log<logger::CPP>("_P<C::iterator, bool> pair_it_bool;"); 348 | logger.log<logger::CPP>("_P<C::iterator, C::iterator> range;"); 349 | logger.log<logger::CPP>("_P<C::key_type, C::mapped_type> val;"); 350 | for (int i = 0; NTEST == -1 || i < NTEST; i++) { 351 | if (!logger.log<logger::BREAKPOINT>("")) 352 | logger.log<logger::NONE>("========================================"); 353 | 354 | int rand = std::rand() % sizeof(array) / sizeof(void (*)(C &, C &)); 355 | if (std::rand() % 2) 356 | array[rand]("m1", m1,"m2", m2); 357 | else 358 | array[rand]("m2", m2,"m1", m1); 359 | logger.log<logger::TITLE>("printing m1:"); 360 | monkey::print_full_map<C, P>(m1, "m1"); 361 | logger.log<logger::TITLE>("printing m2:"); 362 | monkey::print_full_map<C, P>(m2, "m2"); 363 | 364 | } 365 | } 366 | -------------------------------------------------------------------------------- /srcs/test_stack.hpp: -------------------------------------------------------------------------------- 1 | #include "../includes.hpp" 2 | #include <vector> 3 | #include <iostream> 4 | #include <set> 5 | #include <cstdlib> 6 | #include <string> 7 | #include <climits> 8 | #ifndef NTEST 9 | # define NTEST 1000 10 | #endif 11 | 12 | namespace monkey_stack { 13 | template<typename T> 14 | T get_value() { 15 | return (T()); 16 | } 17 | 18 | template<> 19 | std::string get_value<std::string>() { 20 | std::string default_val[] = {"hola amigo", "amigo de la tornada", "amigo de pepito", 21 | "", "un", "dos", "atencion", "un dos tres quatro", "la pantera"}; 22 | if (!(std::rand() % 4)) 23 | return (std::string(default_val[std::rand() % 8])); 24 | std::string ret = ""; 25 | for (int i = 0; i < 5; ++i) 26 | ret += (std::rand() % 26) + 'a'; 27 | return (ret); 28 | } 29 | 30 | template<class C> 31 | void print_full_stack(const C &s) { 32 | std::cout << "empty: " << s.empty() << std::endl; 33 | std::cout << "size: " << s.size() << std::endl; 34 | if (!s.empty()) 35 | std::cout << "top: " << s.top() << std::endl; 36 | } 37 | 38 | template<class C> 39 | void test_copy_construct_equal(C &s1, C &s2) { 40 | std::cout << "test_copy_construct_equal:" << std::endl; 41 | 42 | C v3(s1); 43 | print_full_stack<C>(s1); 44 | print_full_stack<C>(s2); 45 | print_full_stack<C>(v3); 46 | v3 = s1; 47 | print_full_stack<C>(s1); 48 | print_full_stack<C>(s2); 49 | print_full_stack<C>(v3); 50 | s1 = v3; 51 | s1 = s2; 52 | s2 = v3; 53 | v3 = C(v3); 54 | print_full_stack<C>(s1); 55 | print_full_stack<C>(s2); 56 | print_full_stack<C>(v3); 57 | v3 = C(s1); 58 | } 59 | 60 | template<class C> 61 | void test_construct(C &s1, C &) { 62 | switch (std::rand() % 5) { 63 | case 0: 64 | std::cout << "test_construct:" << std::endl; 65 | const typename C::container_type v(std::rand() % 20, get_value<typename C::value_type>()); 66 | s1 = C(v); 67 | print_full_stack<C>(s1); 68 | break; 69 | } 70 | } 71 | template<class C> 72 | void test_push(C &s1, C &) { 73 | std::cout << "test_push:" << std::endl; 74 | 75 | s1.push(get_value<typename C::value_type>()); 76 | } 77 | 78 | template<class C> 79 | void test_pop(C &s1, C &) { 80 | std::cout << "test_pop:" << std::endl; 81 | 82 | if (!s1.empty()) 83 | s1.pop(); 84 | } 85 | 86 | template<class C> 87 | void test_comparison(C &s1, C &s2) { 88 | std::cout << "test_comparison:" << std::endl; 89 | 90 | std::cout << "s1 < s2: " << (s1 < s2) << std::endl; 91 | std::cout << "s1 > s2: " << (s1 > s2) << std::endl; 92 | std::cout << "s1 <= s2: " << (s1 <= s2) << std::endl; 93 | std::cout << "s1 >= s2: " << (s1 >= s2) << std::endl; 94 | std::cout << "s1 == s2: " << (s1 == s2) << std::endl; 95 | std::cout << "s1 != s2: " << (s1 != s2) << std::endl; 96 | } 97 | } 98 | template<class C> 99 | void test_stack(int seed) { 100 | std::srand(seed); 101 | void (*array[])(C &,C &) = { 102 | &monkey_stack::test_construct<C>, 103 | &monkey_stack::test_copy_construct_equal<C>, 104 | &monkey_stack::test_push<C>, 105 | &monkey_stack::test_pop<C>, 106 | &monkey_stack::test_comparison<C> 107 | }; 108 | C s1; 109 | C s2; 110 | for (int i = 0; NTEST == -1 || i < NTEST; i++) { 111 | int rand = std::rand() % sizeof(array) / sizeof(void (*)(C &, C &)); 112 | if (std::rand() % 2) 113 | array[rand](s1, s2); 114 | else 115 | array[rand](s2, s1); 116 | monkey_stack::print_full_stack<C>(s1); 117 | monkey_stack::print_full_stack<C>(s2); 118 | std::cout << "========================================" << std::endl; 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /srcs/test_vector.hpp: -------------------------------------------------------------------------------- 1 | 2 | #include "../includes.hpp" 3 | #include <iostream> 4 | #include <vector> 5 | #include <set> 6 | #include <cstdlib> 7 | #include "logger.hpp" 8 | #include <string> 9 | #include <climits> 10 | #include "input_iterator.hpp" 11 | #include <sstream> 12 | #include <iostream> 13 | #include "common.hpp" 14 | #ifndef NTEST 15 | # define NTEST 1000 16 | #endif 17 | 18 | extern class logger logger; 19 | 20 | namespace monkey_vector { 21 | 22 | template<typename T> 23 | T get_value() { 24 | return (T()); 25 | } 26 | 27 | template<> 28 | std::string get_value<std::string>() { 29 | std::string default_val[] = { "", "amigo de la tornada", "amigo de pepito", 30 | "hola amigo", "un", "dos", "atencion", "un dos tres quatro", "la pantera"}; 31 | return (std::string(default_val[std::rand() % 8])); 32 | } 33 | 34 | template<> 35 | int get_value<int>() { 36 | return (int(std::rand() % UINT_MAX)); 37 | } 38 | 39 | template<class C> 40 | void print_full_vect(const C &v, const std::string &name) { 41 | logger.log<logger::CPP>("monkey::print_full_vect<C>(" + name + ", \"" + name + "\");"); 42 | 43 | logger.log<logger::NONE>("empty: " + SSTR(v.empty())); 44 | logger.log<logger::NONE>("size: " + SSTR(v.size())); 45 | logger.log<logger::NONE>("content:"); 46 | for (typename C::const_iterator i = v.begin(); i != v.end(); i++) 47 | logger.log<logger::NONE>(" [" + SSTR(*i) + "]"); 48 | logger.log<logger::NONE>("reverse content:"); 49 | for (typename C::const_reverse_iterator i = v.rbegin(); i != v.rend(); i++) 50 | logger.log<logger::NONE>(" [" + SSTR(*i) + "]"); 51 | } 52 | 53 | template<class C> 54 | void test_clear(const std::string &n1, C &v1, const std::string &, C &) { 55 | logger.log<logger::TITLE>("test_clear:"); 56 | logger.create_block(); 57 | logger.log<logger::CPP>("C v3(" + n1 + ");"); 58 | C v3(v1); 59 | print_full_vect(v1, n1); 60 | logger.log<logger::CPP>(n1 + ".clear();"); 61 | v1.clear(); 62 | print_full_vect(v3, "v3"); 63 | logger.log<logger::CPP>("v3.clear();"); 64 | v3.clear(); 65 | logger.pop_block(); 66 | } 67 | 68 | template<class C> 69 | void test_copy_construct_equal(const std::string &n1, C &v1, const std::string &n2, C &v2) { 70 | logger.log<logger::TITLE>("test_copy_construct_equal:"); 71 | 72 | logger.create_block(); 73 | logger.log<logger::CPP>("C v3(" + n1 + ");"); 74 | C v3(v1); 75 | logger.log<logger::CPP>(n1 + " = " + n2 + ";"); 76 | v1 = v2; 77 | logger.log<logger::CPP>(n2 + " = v3;"); 78 | v2 = v3; 79 | logger.pop_block(); 80 | } 81 | 82 | template<class C> 83 | void test_construct(const std::string &n1, C &v1, const std::string &, C &) { 84 | unsigned long int rand; 85 | typename C::value_type val; 86 | switch (std::rand() % 10) { 87 | case 0: 88 | logger.log<logger::TITLE>("test_construct: count"); 89 | rand = std::rand() % 20; 90 | val = get_value<typename C::value_type>(); 91 | v1 = C(rand, val); 92 | logger.log<logger::CPP>(n1 + " = C(" + SSTR(rand) + ", \"" + val + "\");"); 93 | break; 94 | case 1: 95 | logger.log<logger::TITLE>("test_construct: range"); 96 | logger.create_block(); 97 | logger.log<logger::CPP>("const std::set<C::value_type> s(" + n1 + ".begin(), " + n1 + ".end());"); 98 | const std::set<typename C::value_type> s(v1.begin(), v1.end()); 99 | logger.log<logger::CPP>(n1 + " = C(s.begin(), s.end());"); 100 | v1 = C(s.begin(), s.end()); 101 | logger.pop_block(); 102 | break; 103 | } 104 | } 105 | 106 | template<class C> 107 | void test_assign(const std::string &n1, C &v1, const std::string &, C &) { 108 | unsigned long int rand; 109 | typename C::value_type val; 110 | switch (std::rand() % 10) { 111 | case 0: 112 | logger.log<logger::TITLE>("test_assign: count"); 113 | rand = std::rand() % 20; 114 | val = get_value<typename C::value_type>(); 115 | v1.assign(rand, val); 116 | logger.log<logger::CPP>(n1 + ".assign(" + SSTR(rand) + ", \"" + val + "\");"); 117 | break; 118 | case 1: 119 | logger.log<logger::TITLE>("test_assign: range"); 120 | logger.create_block(); 121 | logger.log<logger::CPP>("const std::set<C::value_type> s(" + n1 + ".begin(), " + n1 + ".end());"); 122 | const std::set<typename C::value_type> s(v1.begin(), v1.end()); 123 | logger.log<logger::CPP>(n1 + ".assign(s.begin(), s.end());"); 124 | v1.assign(s.begin(), s.end()); 125 | logger.pop_block(); 126 | break; 127 | } 128 | } 129 | 130 | template<class C> 131 | void test_at(const std::string &n1, C &v1, const std::string &n2, C &v2) { 132 | unsigned long int rand; 133 | typename C::value_type val; 134 | for (int i = 0; i < 5; i++) { 135 | try { 136 | logger.log<logger::TITLE>("test_at: "); 137 | logger.log<logger::CPP>("try"); 138 | logger.create_block(); 139 | if (!v1.empty()) 140 | { 141 | rand = std::rand(); 142 | val = get_value<typename C::value_type>(); 143 | v1.at((int) rand % v1.size()) = val; 144 | logger.log<logger::CPP>(n1 +".at(" + SSTR(rand) + " % " + n1 + ".size()) = \"" + SSTR(val) + "\";"); 145 | } 146 | if (!v2.empty()) 147 | { 148 | rand = std::rand(); 149 | logger.log<logger::NONE>(v2.at((int) rand % v2.size())); 150 | logger.log<logger::CPP_LOG>(n2 + ".at(" + SSTR(rand) + " % " + n2 +".size())"); 151 | } 152 | rand = std::rand(); 153 | logger.log<logger::NONE>(v1.at((int) rand)); 154 | logger.log<logger::CPP_LOG>(n1 + ".at((unsigned int) " + SSTR(rand) + ")"); 155 | rand = std::rand(); 156 | logger.log<logger::NONE>(v2.at((int) rand)); 157 | logger.log<logger::CPP_LOG>(n2 + ".at((unsigned int) " + SSTR(rand) + ")"); 158 | logger.pop_block(); 159 | logger.log<logger::CPP>("catch (std::out_of_range &e)"); 160 | logger.create_block(); 161 | logger.log<logger::CPP_LOG>("\"out_of_range catched\""); 162 | logger.pop_block(); 163 | } 164 | catch (std::out_of_range &e) { 165 | logger.pop_block(); 166 | logger.log<logger::CPP>("catch (std::out_of_range &e)"); 167 | logger.create_block(); 168 | logger.log<logger::CPP_LOG>("\"out_of_range catched\""); 169 | logger.pop_block(); 170 | logger.log<logger::NONE>("out_of_range catched"); 171 | } 172 | } 173 | } 174 | 175 | template<class C> 176 | void test_operator_index(const std::string &n1, C &v1, const std::string &n2, C &v2) { 177 | unsigned int rand; 178 | typename C::value_type val; 179 | logger.log<logger::TITLE>("test_operator_index:"); 180 | for (int i = 0; i < 5; i++) { 181 | rand = std::rand(); 182 | val = get_value<typename C::value_type>(); 183 | if (!v1.empty()) 184 | { 185 | v1[(int) rand % v1.size()] = val; 186 | logger.log<logger::CPP>(n1 + "[(int) " + SSTR(rand) + " % " + n1 + ".size()] = \"" + SSTR(val) + "\";"); 187 | } 188 | rand = std::rand(); 189 | if (!v2.empty()) 190 | { 191 | logger.log<logger::NONE>(SSTR(v2[(int) rand % v2.size()])); 192 | logger.log<logger::CPP_LOG>(n2 + "[(int) " + SSTR(rand) + " % " + n2 + ".size()]" ); 193 | } 194 | } 195 | } 196 | 197 | template<class C> 198 | void test_insert(const std::string &n1, C &v1, const std::string &n2, C &v2) { 199 | typename C::iterator it1; 200 | typename C::iterator it2; 201 | typename C::iterator it3; 202 | unsigned int rand; 203 | typename C::value_type val; 204 | 205 | if (std::rand() % 50 == 1) 206 | { 207 | val = get_value<typename C::value_type>(); 208 | v1.insert(v1.begin(), 0, ""); // yeah you must pass this one 209 | logger.log<logger::CPP>(n1 + ".insert(" + n1 + ".begin(), 0, \"\" );"); 210 | } 211 | 212 | for (int i = 0; i < 5; i++) { 213 | rand = std::rand(); 214 | it1 = monkey::get_itn(v1, rand); 215 | logger.log<logger::CPP>("it1 = monkey::get_itn(" + n1 + ", " + SSTR(rand) + ");"); 216 | try { 217 | logger.log<logger::CPP>("try"); 218 | logger.create_block(); 219 | switch (std::rand() % 3) { 220 | val = get_value<typename C::value_type>(); 221 | case (0): 222 | logger.log<logger::TITLE>("test_insert value"); 223 | logger.log<logger::CPP_LOG>("*" + n1 + ".insert(it1, \"" + val + "\")"); 224 | logger.log<logger::NONE>("ret = " + SSTR(*v1.insert(it1, val))); 225 | break; 226 | case (1): 227 | logger.log<logger::TITLE>("test_insert range"); 228 | rand = std::rand(); 229 | it2 = monkey::get_itn(v2, rand); 230 | logger.log<logger::CPP>("it2 = monkey::get_itn(" + n2 + ", " + SSTR(rand) + ");"); 231 | rand = std::rand(); 232 | it3 = monkey::get_itn(v2, rand, it2); 233 | logger.log<logger::CPP>("it3 = monkey::get_itn(" + n2 + ", " + SSTR(rand) + ", it2);"); 234 | v1.insert(it1, input_iterator<typename C::iterator>(it2), 235 | input_iterator<typename C::iterator>(it3)); 236 | logger.log<logger::CPP>(n1 + ".insert(it1, input_iterator<C::iterator>(it2), input_iterator<C::iterator>(it3));"); 237 | break; 238 | case (2): 239 | logger.log<logger::TITLE>("test_insert count"); 240 | rand = std::rand(); 241 | logger.log<logger::CPP>(n1 + ".insert(it1, (int)" + SSTR(rand % 5) + ", \"" + SSTR(val) + "\" );"); 242 | v1.insert(it1, rand % 5, val); 243 | } 244 | logger.pop_block(); 245 | logger.log<logger::CPP>("catch (std::out_of_range &e)"); 246 | logger.create_block(); 247 | logger.log<logger::CPP_LOG>("e.what()"); 248 | logger.pop_block(); 249 | } 250 | catch (std::exception &e) { 251 | std::cout << e.what() << std::endl; 252 | } 253 | } 254 | } 255 | 256 | template<class C> 257 | void test_erase(const std::string &n1, C &v1, const std::string &, C &) { 258 | unsigned int rand; 259 | typename C::iterator it1; 260 | typename C::iterator it2; 261 | for (int i = 0; i < 5; i++) { 262 | rand = std::rand(); 263 | it1 = monkey::get_itn(v1, rand); 264 | logger.log<logger::CPP>("it1 = monkey::get_itn(" + n1 + ", " + SSTR(rand) + ");"); 265 | switch (std::rand() % 3) { 266 | case (0): 267 | if (it1 == v1.end()) 268 | break; 269 | logger.log<logger::TITLE>("test_erase it"); 270 | it1 = v1.erase(it1); 271 | logger.log<logger::CPP>("it1 = " + n1 + "erase(it1);"); 272 | if (it1 < v1.end()) 273 | { 274 | logger.log<logger::CPP_LOG>("*it1"); 275 | logger.log<logger::NONE>(*it1); 276 | } 277 | break; 278 | case (2): 279 | logger.log<logger::TITLE>("test_erase range"); 280 | rand = std::rand(); 281 | it2 = monkey::get_itn(v1, rand, it1); 282 | logger.log<logger::CPP>("it2 = monkey::get_itn(" + n1 + ", " + SSTR(rand) + ", it1);"); 283 | v1.erase(it1, it2); 284 | logger.log<logger::CPP>(n1 + ".erase(it1, it2);"); 285 | } 286 | 287 | } 288 | } 289 | 290 | template<class C> 291 | void test_push_back(const std::string &n1, C &v1, const std::string &, C &) { 292 | logger.log<logger::TITLE>("test_push_back:"); 293 | typename C::value_type val = get_value<typename C::value_type>(); 294 | v1.push_back(val); 295 | logger.log<logger::CPP>(n1 + ".push_back(\"" + SSTR(val) + "\");"); 296 | } 297 | 298 | template<class C> 299 | void test_pop_back(const std::string &n1, C &v1, const std::string &, C &) { 300 | logger.log<logger::TITLE>("test_pop_back:"); 301 | 302 | if (!v1.empty()) { 303 | v1.pop_back(); 304 | logger.log<logger::CPP>(n1 + ".pop_back();"); 305 | } 306 | } 307 | 308 | template<class C> 309 | void test_resize(const std::string &n1, C &v1, const std::string &, C &) { 310 | logger.log<logger::TITLE>("test_resize:"); 311 | typename C::value_type val = get_value<typename C::value_type>(); 312 | int new_size = std::rand() % (v1.empty() ? 10 : (2 * v1.size())); 313 | v1.resize(new_size, val); 314 | logger.log<logger::CPP>(n1 + ".resize(" + SSTR(new_size) + ", \"" + SSTR(val) + "\");"); 315 | 316 | } 317 | 318 | template<class C> 319 | void test_swap(const std::string &n1, C &v1, const std::string &n2, C &v2) { 320 | logger.log<logger::TITLE>("test_swap:"); 321 | logger.log<logger::CPP>(n1 + ".swap(" + n2 + ");"); 322 | v1.swap(v2); 323 | } 324 | 325 | template<class C> 326 | void test_stdswap(const std::string &n1, C &v1, const std::string &n2, C &v2) { 327 | logger.log<logger::TITLE>("test_stdswap:"); 328 | logger.log<logger::CPP>("std::swap(" + n1 + ", " + n2 + ");"); 329 | std::swap(v1, v2); 330 | } 331 | 332 | template<class C> 333 | void test_comparison(const std::string &n1, C &v1, const std::string &n2, C &v2) { 334 | logger.log<logger::TITLE>("test_comparison:"); 335 | 336 | logger.log<logger::NONE>(n1 + " < " + n2 + ": " + SSTR(v1 < v2)); 337 | logger.log<logger::NONE>(n1 + " > " + n2 + ": " + SSTR(v1 > v2)); 338 | logger.log<logger::NONE>(n1 + " <= " + n2 + ": " + SSTR(v1 <= v2)); 339 | logger.log<logger::NONE>(n1 + " >= " + n2 + ": " + SSTR(v1 >= v2)); 340 | logger.log<logger::NONE>(n1 + " == " + n2 + ": " + SSTR(v1 == v2)); 341 | logger.log<logger::NONE>(n1 + " != " + n2 + ": " + SSTR(v1 != v2)); 342 | 343 | logger.log<logger::CPP_LOG>("\"" + n1 + " < " + n2 + ": \" + SSTR( " + n1 + " < " + n2 + ")"); 344 | logger.log<logger::CPP_LOG>("\"" + n1 + " > " + n2 + ": \" + SSTR( " + n1 + " > " + n2 + ")"); 345 | logger.log<logger::CPP_LOG>("\"" + n1 + " <= " + n2 + ": \" + SSTR( " + n1 + " <= " + n2 + ")"); 346 | logger.log<logger::CPP_LOG>("\"" + n1 + " >= " + n2 + ": \" + SSTR( " + n1 + " >= " + n2 + ")"); 347 | logger.log<logger::CPP_LOG>("\"" + n1 + " == " + n2 + ": \" + SSTR( " + n1 + " == " + n2 + ")"); 348 | logger.log<logger::CPP_LOG>("\"" + n1 + " != " + n2 + ": \" + SSTR( " + n1 + " != " + n2 + ")"); 349 | } 350 | } 351 | 352 | template <class C> 353 | void test_vector(int seed) 354 | { 355 | std::srand(seed); 356 | void (*array[])(const std::string &, C &, const std::string &, C &) = { 357 | &monkey_vector::test_assign, 358 | &monkey_vector::test_construct, 359 | &monkey_vector::test_copy_construct_equal, 360 | &monkey_vector::test_at, 361 | &monkey_vector::test_operator_index, 362 | &monkey_vector::test_clear, 363 | &monkey_vector::test_insert, 364 | &monkey_vector::test_erase, 365 | &monkey_vector::test_pop_back, 366 | &monkey_vector::test_push_back, 367 | &monkey_vector::test_resize, 368 | &monkey_vector::test_swap, 369 | &monkey_vector::test_stdswap, 370 | &monkey_vector::test_comparison 371 | }; 372 | 373 | C v1; 374 | C v2; 375 | logger.log<logger::CPP>("C v1;"); 376 | logger.log<logger::CPP>("C v2;"); 377 | logger.log<logger::CPP>("C::iterator it1;"); 378 | logger.log<logger::CPP>("C::iterator it2;"); 379 | logger.log<logger::CPP>("C::iterator it3;"); 380 | for (int i = 0; NTEST == -1 || i < NTEST; i++) 381 | { 382 | if (!logger.log<logger::BREAKPOINT>("")) 383 | logger.log<logger::NONE>("========================================"); 384 | int rand = std::rand() % sizeof(array) / sizeof (void (*)(C &, C &)); 385 | if (std::rand() % 2) 386 | array[rand]("v1", v1, "v2", v2); 387 | else 388 | array[rand]("v2", v2, "v1", v1); 389 | logger.log<logger::TITLE>("printing v1:"); 390 | monkey_vector::print_full_vect(v1, "v1"); 391 | logger.log<logger::TITLE>("printing v2:"); 392 | monkey_vector::print_full_vect(v2, "v2"); 393 | } 394 | } 395 | --------------------------------------------------------------------------------