From 94745ca8a9b1bbe2053f5fce33260d5316bd27a9 Mon Sep 17 00:00:00 2001 From: hugogogo Date: Sat, 18 Jun 2022 17:58:14 +0200 Subject: [PATCH] resolve template specialization with inline keyword --- Makefile | 22 +- headers/tests.hpp | 132 ------------ .../includes/main.hpp | 48 ++--- .../A_test.hpp => tests/includes/tests_A.hpp | 4 +- tests/includes/tests_mystruct.hpp | 21 ++ .../tests_templates.tpp} | 47 +---- {headers => tests/includes}/tests_utils.hpp | 192 ++++++++---------- tests/main.cpp | 8 +- tests/tests_definitions.cpp | 54 +++++ tests/tests_mystruct.cpp | 19 ++ tests/tests_vector.cpp | 2 +- 11 files changed, 222 insertions(+), 327 deletions(-) delete mode 100644 headers/tests.hpp rename headers/tests_proto.hpp => tests/includes/main.hpp (65%) rename headers/A_test.hpp => tests/includes/tests_A.hpp (76%) create mode 100644 tests/includes/tests_mystruct.hpp rename tests/{tests_utils.cpp => includes/tests_templates.tpp} (53%) rename {headers => tests/includes}/tests_utils.hpp (58%) create mode 100644 tests/tests_definitions.cpp create mode 100644 tests/tests_mystruct.cpp diff --git a/Makefile b/Makefile index 3853e3e..4892a68 100644 --- a/Makefile +++ b/Makefile @@ -32,7 +32,7 @@ RESET = "\e[0m" NAME = containers -CC = clang++ +CC = g++ EXT = cpp CFLAGS = -Wall -Wextra -Werror $(INCLUDES) @@ -44,22 +44,22 @@ VPATH = $(D_SRCS) LIBS = F_INCLUDES = $(HEADERS:%=$(D_HEADERS)/%) \ - $(TEMPLATES:%=$(D_TEMPLATES)/%) + $(TEMPLATES:%=$(D_TEMPLATES)/%) \ + $(TESTS:%=$(D_TESTS)/%) INCLUDES = -I$(D_HEADERS) \ - -I$(D_TEMPLATES) + -I$(D_TEMPLATES) \ + -I$(D_TESTS) D_SRCS = ./tests #SRCS = main42.cpp SRCS = main.cpp \ - tests_vector.cpp - -# tests_map.cpp + tests_definitions.cpp \ + \ + tests_vector.cpp \ + tests_map.cpp D_HEADERS = ./headers HEADERS = colors.h \ - tests_utils.hpp \ - tests_proto.hpp \ - A_test.hpp \ \ enable_if.hpp \ iterator_traits.hpp \ @@ -72,6 +72,10 @@ HEADERS = colors.h \ D_TEMPLATES = ./templates TEMPLATES = vector.tpp +D_TESTS = ./tests/includes +TESTS = main.hpp \ + tests_utils.hpp + D_OBJS = builds OBJS = $(SRCS:%.$(EXT)=$(D_OBJS)/%.o) diff --git a/headers/tests.hpp b/headers/tests.hpp deleted file mode 100644 index 1ec119e..0000000 --- a/headers/tests.hpp +++ /dev/null @@ -1,132 +0,0 @@ -#ifndef TESTS_HPP -# define TESTS_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 - - -// global variables -// *************************************** -std::vector< std::vector > test_list; -std::vector mem_list; - - - -// global functions -// *************************************** -void add_to_list(std::string s, A_test* s1, A_test* s2, A_test* s3, A_test* s4); - - -// struct for tests -// *************************************** -struct mystruct { -public: - mystruct(int data = 0); - ~mystruct(); - int * get_data() const; -private: - int * _val; -}; -std::ostream & operator<<(std::ostream & o, mystruct const * rhs); - - -// adding each test to the list -// *************************** -#define TEST(f_name) \ - template struct s_ ## f_name : public A_test\ - { void func(); };\ - void f_name ()\ - { add_to_list(\ - #f_name,\ - new(s_ ## f_name ),\ - new(s_ ## f_name ),\ - new(s_ ## f_name ),\ - new(s_ ## f_name )\ - );}\ - template \ - void s_ ## f_name ::func() - - -// defines -// **************************************** -# define TITLE(s) std::cout << "\n" B_PURPLE #s RESET "\n\n"; -# define VAL(n) val(n) -# define TOI(n) toi(n) -# define PRINT(n) print_vector(n); -# define DELETE delete_structs(); - - -// 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(); -#endif - diff --git a/headers/tests_proto.hpp b/tests/includes/main.hpp similarity index 65% rename from headers/tests_proto.hpp rename to tests/includes/main.hpp index 9485930..42a0876 100644 --- a/headers/tests_proto.hpp +++ b/tests/includes/main.hpp @@ -1,34 +1,23 @@ -#ifndef TESTS_PROTO_HPP -# define TESTS_PROTO_HPP +#ifndef MAIN_HPP +# define MAIN_HPP +#include "colors.h" +#include +#include +#include // std::setw() #include -#include "A_test.hpp" - -// ************************************ -// global declarations -std::vector< std::vector > test_list; -void add_to_list(std::string s, A_test* s1, A_test* s2, A_test* s3, A_test* s4) { - - std::vector test_sub_list; - - s1->title = s; - s2->title = s; - s3->title = s; - s4->title = s; - s1->type = "int"; - s2->type = "char"; - s3->type = "std::string"; - s4->type = "mystruct"; - test_sub_list.push_back(s1); - test_sub_list.push_back(s2); - test_sub_list.push_back(s3); - test_sub_list.push_back(s4); - test_list.push_back(test_sub_list); -} +#include "tests_utils.hpp" -// ************************************** -// prototypes vector +// global variables +// *************************************** +std::vector< std::vector > test_list; +std::vector< mystruct* > mem_list; + + +// prototypes +// ********************************************* +// vectors void tests_vector_constructor(); void tests_vector_operator_assignation(); void tests_vector_begin(); @@ -56,10 +45,7 @@ void tests_vector_get_allocator(); void tests_vector_relational_operators(); void tests_vector_swap_non_member(); void tests_vector_reverse_iterators(); - - -// ***************************************** -// prototypes map +// map void tests_map_simple(); //void tests_map_constructor(); //void tests_map_operator_assignation(); diff --git a/headers/A_test.hpp b/tests/includes/tests_A.hpp similarity index 76% rename from headers/A_test.hpp rename to tests/includes/tests_A.hpp index f7e774f..5f38488 100644 --- a/headers/A_test.hpp +++ b/tests/includes/tests_A.hpp @@ -1,5 +1,5 @@ -#ifndef A_TEST_HPP -# define A_TEST_HPP +#ifndef TESTS_A_HPP +# define TESTS_A_HPP #include diff --git a/tests/includes/tests_mystruct.hpp b/tests/includes/tests_mystruct.hpp new file mode 100644 index 0000000..8f2883a --- /dev/null +++ b/tests/includes/tests_mystruct.hpp @@ -0,0 +1,21 @@ +#ifndef TESTS_MYSTRUCT_HPP +# define TESTS_MYSTRUCT_HPP + +#include + +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 + diff --git a/tests/tests_utils.cpp b/tests/includes/tests_templates.tpp similarity index 53% rename from tests/tests_utils.cpp rename to tests/includes/tests_templates.tpp index 427d86a..442378d 100644 --- a/tests/tests_utils.cpp +++ b/tests/includes/tests_templates.tpp @@ -1,35 +1,8 @@ -#include "tests.hpp" - -void add_to_list(std::string s, A_test* s1, A_test* s2, A_test* s3, A_test* s4) { - - std::vector test_sub_list; - - s1->title = s; - s2->title = s; - s3->title = s; - s4->title = s; - s1->type = "int"; - s2->type = "char"; - s3->type = "std::string"; - s4->type = "mystruct"; - test_sub_list.push_back(s1); - test_sub_list.push_back(s2); - test_sub_list.push_back(s3); - test_sub_list.push_back(s4); - test_list.push_back(test_sub_list); -} - -void delete_structs() { - - std::vector::iterator it; - std::vector::iterator it_end = mem_list.end(); - - for (it = mem_list.begin(); it != it_end; ++it) - delete *it; - mem_list.clear(); -} +#include "tests_utils.hpp" +// print vector +// ******************************************** template void print_vector(ft::vector vec) { @@ -42,20 +15,6 @@ template std::cout << "\nsize:" << vec.size() << " capacty:" << vec.capacity() << "\n"; } -// 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); -} - - // get a value // ********************************************* template diff --git a/headers/tests_utils.hpp b/tests/includes/tests_utils.hpp similarity index 58% rename from headers/tests_utils.hpp rename to tests/includes/tests_utils.hpp index 3c01673..8aefeaa 100644 --- a/headers/tests_utils.hpp +++ b/tests/includes/tests_utils.hpp @@ -1,22 +1,21 @@ + #ifndef TESTS_UTILS_HPP # define TESTS_UTILS_HPP + #include "colors.h" -#include "A_test.hpp" #include #include #include // std::setw() #include // std::reverse_iterator #include // std::make_pair -#include // std::map #include // std::stringstream -#include -#include - // toogle between test ft and stl // ************************* +#include +#include #ifdef STL namespace ft = std; #else @@ -25,31 +24,41 @@ #endif -// struct for tests -// *************************************** +// defines +// **************************************** +# define TITLE(s) std::cout << "\n" B_PURPLE #s RESET "\n\n"; +# define VAL(n) val(n) +# define TOI(n) toi(n) +# define PRINT(n) print_vector(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) {_val = new int[2]; _val[0] = data; _val[1] = data;} - ~mystruct() {delete[] _val;} - int * get_data() const {return _val;} + mystruct(int data = 0); + ~mystruct(); + int * get_data() const; private: int * _val; }; -//extern std::ostream & operator<<(std::ostream & o, mystruct const & rhs); -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); -} +std::ostream & operator<<(std::ostream & o, mystruct const * rhs); +void add_to_list(std::string s, A_test* s1, A_test* s2, A_test* s3, A_test* s4); +void delete_structs(); -// global declarations -// ************************************ -extern std::vector test_list; -extern void add_to_list(std::string s, A_test* s1, A_test* s2, A_test* s3, A_test* s4); -std::vector mem_list; +// global variables +// *************************************** +extern std::vector< std::vector > test_list; +extern std::vector< mystruct* > mem_list; // adding each test to the list @@ -69,77 +78,8 @@ std::vector mem_list; void s_ ## f_name ::func() -// defines -// **************************************** -# define TITLE(s) std::cout << "\n" B_PURPLE #s RESET "\n\n"; -# define VAL(n) val(n) -# define TOI(n) toi(n) -# define PRINT(n) print_vector(n); -# define DELETE delete_structs(); - - -// get a value -// ********************************************* -template - T val(int n) {(void)n; return (T()); -} -template <> - int val(int n) {return (n); -} -template <> - char val(int n) {return (n % 94 + 33); -} -template <> - std::string val(int n) { - - std::string str; - std::stringstream stream; - - stream << n; - stream >> str; - stream.clear(); - return (str); -} -template <> - mystruct* val(int n) { - - mystruct *s = new mystruct(n); - mem_list.push_back(s); - return ( s ); -} - - -// convert a value +// templates print // ***************************************** -template - int toi(T t) {(void)t; return (0); -} -template <> - int toi(int i) {return (i); -} -template <> - int toi(char c) {return (c); -} -template <> - int toi(std::string str) { - - int i; - std::stringstream stream; - - stream << str; - stream >> i; - stream.clear(); - return (i); -} -template <> - int toi(mystruct* s) { - - return ( s->get_data()[0] ); -} - - -// get a value -// ********************************************* template void print_vector(ft::vector vec) { @@ -152,17 +92,65 @@ template std::cout << "\nsize:" << vec.size() << " capacty:" << vec.capacity() << "\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) { -// delete vector elements -// ********************************** -void delete_structs() { - - std::vector::iterator it; - std::vector::iterator it_end = mem_list.end(); + std::string str; + std::stringstream stream; - for (it = mem_list.begin(); it != it_end; ++it) - delete *it; - mem_list.clear(); + 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] ); } diff --git a/tests/main.cpp b/tests/main.cpp index ca6944f..59d518a 100644 --- a/tests/main.cpp +++ b/tests/main.cpp @@ -1,9 +1,5 @@ -#include -#include -#include // std::setw() -#include "colors.h" -#include "A_test.hpp" -//#include "tests_proto.hpp" + +#include "main.hpp" int main() { diff --git a/tests/tests_definitions.cpp b/tests/tests_definitions.cpp new file mode 100644 index 0000000..6f278ea --- /dev/null +++ b/tests/tests_definitions.cpp @@ -0,0 +1,54 @@ + +#include "tests_utils.hpp" + + +// functions +// ********************************************** +void add_to_list(std::string s, A_test* s1, A_test* s2, A_test* s3, A_test* s4) { + + std::vector test_sub_list; + + s1->title = s; + s2->title = s; + s3->title = s; + s4->title = s; + s1->type = "int"; + s2->type = "char"; + s3->type = "std::string"; + s4->type = "mystruct"; + test_sub_list.push_back(s1); + test_sub_list.push_back(s2); + test_sub_list.push_back(s3); + test_sub_list.push_back(s4); + test_list.push_back(test_sub_list); +} +void delete_structs() { + + std::vector::iterator it; + std::vector::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); +} + diff --git a/tests/tests_mystruct.cpp b/tests/tests_mystruct.cpp new file mode 100644 index 0000000..22f488d --- /dev/null +++ b/tests/tests_mystruct.cpp @@ -0,0 +1,19 @@ + +#include "tests_mystruct.hpp" + +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); +} diff --git a/tests/tests_vector.cpp b/tests/tests_vector.cpp index 5ca40fe..6bc1f02 100644 --- a/tests/tests_vector.cpp +++ b/tests/tests_vector.cpp @@ -11,7 +11,7 @@ TEST(tests_vector_constructor) // constructors used in the same order as described above: ft::vector first; // empty vector of ints - ft::vector second (4,VAL(100)); // four ints with value 100 + ft::vector second (4,VAL(100)); // four ints with value 100 ft::vector third (second.begin(),second.end()); // iterating through second ft::vector fourth (third); // a copy of third