#include #include #include // std::setw() #include // std::reverse_iterator #include // std::make_pair #include // std::stringstream #include #include // toogle ft in stl #ifdef STL namespace ft = std; #else #include "map.hpp" #include "reverse_iterator.hpp" #endif // defines # define TEST_M(s) template void s () # define TITLE(s) std::cout << "\n" B_PURPLE #s RESET "\n\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(); // 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 void print(ft::map mp, std::string name) { int i = 0; typename ft::map::iterator it; typename ft::map::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 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)); } // delete function for mem gestion of mystruct* 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(); } // all tests TEST_M(tests_map_operator_assignation) { // title TITLE(cplusplus.com reference) ft::map first; ft::map 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(); // 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 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 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 mymap; mymap[VALT('x')] = VALU(100); mymap[VALT('y')] = VALU(200); mymap[VALT('z')] = VALU(300); // show content: typename ft::map::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 mymap; mymap[VALT('x')] = VALU(100); mymap[VALT('y')] = VALU(200); mymap[VALT('z')] = VALU(300); // show content: typename ft::map::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 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 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 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 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 mymap; // first insert function version (single parameter): mymap.insert ( ft::pair(VALT('a'),VALU(100)) ); mymap.insert ( ft::pair(VALT('z'),VALU(200)) ); ft::pair::iterator, bool> ret; ret = mymap.insert ( ft::pair(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::iterator it = mymap.begin(); mymap.insert (it, ft::pair(VALT('b'),VALU(300))); // max efficiency inserting mymap.insert (it, ft::pair(VALT('c'),VALU(400))); // no max efficiency inserting // third insert function version (range insertion): ft::map 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 mymap; typename ft::map::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 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 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 mymap; typename ft::map::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::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 mymap; mymap[VALT('x')]=VALU(1001); mymap[VALT('y')]=VALU(2002); mymap[VALT('z')]=VALU(3003); std::cout << "mymap contains:\n"; ft::pair highest = *mymap.rbegin(); // last element typename ft::map::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 mymap; typename ft::map::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 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'); c0) 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 mymap; typename ft::map::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 mymap; typename ft::map::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 mymap; mymap[VALT('a')]=VALU(10); mymap[VALT('b')]=VALU(20); mymap[VALT('c')]=VALU(30); ft::pair::iterator,typename ft::map::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 mymap; ft::pair* 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::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 alice; ft::map bob; ft::map 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 alice; ft::map 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 void call_tests() { 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(); } int main() { call_tests(); call_tests(); call_tests(); call_tests(); call_tests(); call_tests(); call_tests(); call_tests(); return 0; }