#ifndef TESTS_UTILS_HPP # define TESTS_UTILS_HPP #include "colors.h" #include #include #include // std::setw() #include // std::reverse_iterator #include // std::make_pair #include // std::stringstream // toogle between test ft and stl // ************************* #include #include #ifdef STL namespace ft = std; #else #include "vector.hpp" #include "reverse_iterator.hpp" #endif // defines // **************************************** # define TITLE(s) std::cout << "\n" B_PURPLE #s RESET "\n\n"; # define VAL(n) val(n) # define VALT(n) val(n) # define VALU(n) val(n) # define TOI(n) toi(n) # define PRINT(n) print(n); # define DELETE delete_structs(); // prototypes // ********************************************* struct A_test { virtual ~A_test(){}; std::string title; std::string type; virtual void func() = 0; }; struct mystruct { public: mystruct(int data = 0); ~mystruct(); int * get_data() const; private: int * _val; }; std::ostream & operator<<(std::ostream & o, mystruct const * rhs); void add_to_list(std::string title, std::string type, A_test* test); void delete_structs(); // global variables // *************************************** extern std::vector< std::vector > test_list; extern std::vector< mystruct* > mem_list; // adding each test to the list // *************************** #define TEST_V(f_name) \ template struct s_ ## f_name : public A_test\ { void func(); };\ void f_name () {\ add_to_list(#f_name, "int", new(s_ ## f_name ));\ add_to_list("", "char", new(s_ ## f_name ));\ add_to_list("", "std::string", new(s_ ## f_name ));\ add_to_list("", "mystruct*", new(s_ ## f_name ));\ }\ template \ void s_ ## f_name ::func() #define TEST_M(f_name) \ template struct s_ ## f_name : public A_test\ { void func(); };\ void f_name () {\ add_to_list(#f_name, "int, int", new(s_ ## f_name ));\ add_to_list("", "char, int", new(s_ ## f_name ));\ add_to_list("", "std::string, int", new(s_ ## f_name ));\ add_to_list("", "mystruct*, int", new(s_ ## f_name ));\ }\ template \ void s_ ## f_name ::func() // templates print // ***************************************** template void print(ft::vector vec) { int i = 0; typename ft::vector::iterator it; typename ft::vector::iterator it_end = vec.end(); for (it = vec.begin(); it != it_end; ++it, i++) std::cout << "[" << i << "]" << *it << " "; std::cout << "\nsize:" << vec.size() << " capacty:" << vec.capacity() << "\n"; } template void print(ft::map ma) { int i = 0; typename ft::map::iterator it; typename ft::map::iterator it_end = ma.end(); for (it = ma.begin(); it != it_end; ++it, i++) std::cout << "[" << i << "]" << it->first << ":" << it->second << " "; std::cout << "\nsize:" << ma.size() << "\n"; } // templates get value // ************************************* // specialization in header, make it inline : // https://stackoverflow.com/questions/63529059/c-specialized-method-templates-produce-multiple-definition-errors template T val(int n) {(void)n; return (T()); } template <> inline int val(int n) {return (n); } template <> inline char val(int n) {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 ); } // templates to value // ************************************** template int toi(T t) {(void)t; return (0); } template <> inline int toi(int i) {return (i); } template <> inline int toi(char c) {return (c); } template <> inline int toi(std::string str) { int i; std::stringstream stream; stream << str; stream >> i; stream.clear(); return (i); } template <> inline int toi(mystruct* s) { return ( s->get_data()[0] ); } #endif