#ifndef TESTS_UTILS_HPP # define TESTS_UTILS_HPP #include "colors.h" #include #include #include // std::setw() #include // std::reverse_iterator #include // std::make_pair #include // std::stringstream #include #include #include #include #include "tests_structs.hpp" // defines // **************************************** # define TITLE(s) std::cout << "\n" B_PURPLE #s RESET "\n\n"; # define VAL(n) val(n) # define VALT(n) val(n) # define VALU(n) val(n) # define TOI(n) toi(n) # define PRINT(n) print<>(n, #n); # define DELETE delete_structs(); # define DISALLOW_MYSTRUCT allow_mystruct = 0; // prototypes // ********************************************* void add_to_list(std::string title, std::string type, A_test* test); void delete_structs(); // global variables // *************************************** extern std::vector< std::vector > test_list; extern std::vector< mystruct* > mem_list; // adding each test to the list // *************************** #define TEST_S(f_name) TEST_V(f_name) /* */ #define TEST_V(f_name) \ template struct s_ ## f_name : public A_test\ { void func(); };\ void f_name () {\ add_to_list("", "", NULL);\ add_to_list(#f_name, "int", new(s_ ## f_name ));\ add_to_list(#f_name, "char", new(s_ ## f_name ));\ add_to_list(#f_name, "std::string", new(s_ ## f_name ));\ if (allow_mystruct)\ add_to_list(#f_name, "mystruct*", new(s_ ## f_name ));\ allow_mystruct = 1;\ }\ template \ void s_ ## f_name ::func() #define TEST_M(f_name) \ template struct s_ ## f_name : public A_test\ { void func(); };\ void f_name () {\ add_to_list("", "", NULL);\ add_to_list(#f_name, "char, int", new(s_ ## f_name ));\ add_to_list(#f_name, "char, char", new(s_ ## f_name ));\ add_to_list(#f_name, "char, std::string", new(s_ ## f_name ));\ add_to_list(#f_name, "int, int", new(s_ ## f_name ));\ add_to_list(#f_name, "int, char", new(s_ ## f_name ));\ add_to_list(#f_name, "int, std::string", new(s_ ## f_name ));\ }\ template \ void s_ ## f_name ::func() /* add_to_list(#f_name, "char, mystruct*", new(s_ ## f_name ));\ add_to_list(#f_name, "int, mystruct*", new(s_ ## f_name ));\ */ // templates get value // ************************************* // specialization in header, make it inline : // https://stackoverflow.com/questions/63529059/c-specialized-method-templates-produce-multiple-definition-errors template T val(int n) { (void)n; return (T()); } template <> inline int val(int n) { return (n); } template <> inline char val(int n) { if (n <= 126 && n >= 33) return n; return (n % 94 + 33); } template <> inline std::string val(int n) { std::string str; std::stringstream stream; stream << n; stream >> str; stream.clear(); return (str); } template <> inline mystruct* val(int n) { mystruct *s = new mystruct(n); mem_list.push_back(s); return ( s ); } template T val(std::string str) { (void)str; return (T()); } template <> inline int val(std::string str) { int i = str[0]; return (val(i)); } template <> inline char val(std::string str) { int i = str[0]; return (val(i)); } template <> inline std::string val(std::string str) { return (str); } template <> inline mystruct* val(std::string str) { int i = str[0]; return (val(i)); } // templates to value // ************************************** template int toi(T t) {(void)t; return (0); } template <> inline int toi(int i) {return (i); } template <> inline int toi(char c) {return (c); } template <> inline int toi(std::string str) { int i; std::stringstream stream; stream << str; stream >> i; stream.clear(); return (i); } template <> inline int toi(mystruct* s) { return ( s->get_data()[0] ); } #endif