// Copyright (C) 2005 Davis E. King (davis@dlib.net) // License: Boost Software License See LICENSE.txt for the full license. #include <sstream> #include <string> #include <cstdlib> #include <ctime> #include <dlib/hash_table.h> #include <dlib/binary_search_tree.h> #include <dlib/static_map.h> #include "tester.h" namespace { using namespace test; using namespace std; using namespace dlib; logger dlog("test.static_map"); template < typename map > void static_map_kernel_test ( ) /*! requires - map is an implementation of static_map/static_map_kernel_abstract.h and is instantiated to map int to int ensures - runs tests on map for compliance with the specs !*/ { print_spinner(); srand(static_cast<unsigned int>(time(0))); typedef binary_search_tree<int,int>::kernel_2a_c bst; typedef hash_table<int,int>::kernel_1a_c ht; const unsigned long table_4_max_size = 100; const unsigned long tree_max_size = 50000; ht table_4(4); ht table_8(8); bst tree; ht table_4b(4); ht table_8b(8); bst treeb; // just do the following to make sure operator[] doesn't hang // under some instances { int g = 1, h = 1; treeb.add(g,h); map test; map test2; DLIB_TEST(test.size() == 0); DLIB_TEST(test.at_start()); DLIB_TEST(test.current_element_valid() == false); DLIB_TEST(test.move_next() == false); DLIB_TEST(test.current_element_valid() == false); DLIB_TEST(test.at_start() == false); swap(test,test2); DLIB_TEST(test2.at_start() == false); DLIB_TEST(test.at_start() == true); swap(test,test2); DLIB_TEST(test.at_start() == false); DLIB_TEST(test.size() == 0); DLIB_TEST(test[1] == 0); DLIB_TEST(test[2] == 0); DLIB_TEST(test[3] == 0); DLIB_TEST(test[0] == 0); test.load(treeb); DLIB_TEST(test.at_start()); DLIB_TEST(test[1] != 0); DLIB_TEST(test[2] == 0); DLIB_TEST(test[3] == 0); DLIB_TEST(test[0] == 0); test2.clear(); swap(test2,test); DLIB_TEST(test2[1] != 0); DLIB_TEST(test2[2] == 0); DLIB_TEST(test2[3] == 0); DLIB_TEST(test2[0] == 0); DLIB_TEST(test[1] == 0); DLIB_TEST(test[2] == 0); DLIB_TEST(test[3] == 0); DLIB_TEST(test[0] == 0); DLIB_TEST(treeb.size() == 0); treeb.clear(); } for (unsigned long i = 0; i < table_4_max_size; ++i) { int a = ::rand()&0xFF; int b = a + 1; int ab = a; int bb = b; table_4.add(a,b); table_4b.add(ab,bb); } for (unsigned long i = 0; i < table_4_max_size; ++i) { int a = ::rand()&0xF; int b = a + 1; int ab = a; int bb = b; table_8.add(a,b); table_8b.add(ab,bb); } for (unsigned long i = 0; i < tree_max_size; ++i) { int a = ::rand()&0xFFF; int b = a + 1; int ab = a; int bb = b; tree.add(a,b); treeb.add(ab,bb); } map m_4; m_4.load(table_4); map m_8; m_8.load(table_8); map m_t; m_t.load(tree); map e; e.load(table_4); DLIB_TEST(e.size() == 0); DLIB_TEST(e.at_start() == true); DLIB_TEST(e.current_element_valid() == false); DLIB_TEST(e.move_next() == false); DLIB_TEST(e.at_start() == false); DLIB_TEST(e.current_element_valid() == false); DLIB_TEST(m_4.size() == table_4b.size()); DLIB_TEST(m_8.size() == table_8b.size()); DLIB_TEST(m_t.size() == treeb.size()); DLIB_TEST(m_4.at_start() == true); DLIB_TEST(m_8.at_start() == true); DLIB_TEST(m_t.at_start() == true); DLIB_TEST(m_4.current_element_valid() == false); DLIB_TEST(m_8.current_element_valid() == false); DLIB_TEST(m_t.current_element_valid() == false); DLIB_TEST(m_4.move_next() == true); DLIB_TEST(m_4.at_start() == false); DLIB_TEST(m_4.current_element_valid() == true); DLIB_TEST(m_8.move_next() == true); DLIB_TEST(m_8.at_start() == false); DLIB_TEST(m_8.current_element_valid() == true); DLIB_TEST(m_t.move_next() == true); DLIB_TEST(m_t.at_start() == false); DLIB_TEST(m_t.current_element_valid() == true); m_4.reset(); m_8.reset(); m_t.reset(); while (m_4.move_next()) { DLIB_TEST( table_4b[m_4.element().key()] != 0); DLIB_TEST( *table_4b[m_4.element().key()] == m_4.element().value()); } // serialize the state of m_4, then clear m_4, then // load the state back into m_4. ostringstream sout; serialize(m_4,sout); DLIB_TEST(m_4.at_start() == true); istringstream sin(sout.str()); m_4.clear(); deserialize(m_4,sin); DLIB_TEST(m_4.at_start() == true); while (table_4b.move_next()) { DLIB_TEST( m_4[table_4b.element().key()] != 0); DLIB_TEST( *m_4[table_4b.element().key()] == table_4b.element().value()); } // serialize the state of m_8, then clear m_8, then // load the state back into m_8. sout.str(""); serialize(m_8,sout); DLIB_TEST(m_8.at_start() == true); sin.str(sout.str()); m_8.clear(); deserialize(m_8,sin); DLIB_TEST(m_8.at_start() == true); while (m_8.move_next()) { DLIB_TEST( table_8b[m_8.element().key()] != 0); DLIB_TEST( *table_8b[m_8.element().key()] == m_8.element().value()); } while (table_8b.move_next()) { DLIB_TEST( m_8[table_8b.element().key()] != 0); DLIB_TEST( *m_8[table_8b.element().key()] == table_8b.element().value()); } while (m_t.move_next()) { DLIB_TEST( treeb[m_t.element().key()] != 0); DLIB_TEST( *treeb[m_t.element().key()] == m_t.element().value()); } // make sure operator[] doesn't hang for (int l = 1; l < 10000; ++l) { DLIB_TEST(m_t[l+0xFFF] == 0); } while (treeb.move_next()) { DLIB_TEST( m_t[treeb.element().key()] != 0); DLIB_TEST( *m_t[treeb.element().key()] == treeb.element().value()); } m_4.reset(); m_8.reset(); m_t.reset(); int last = 0; while (m_4.move_next()) { DLIB_TEST(last <= m_4.element().key()); DLIB_TEST(m_4.element().key() + 1 == m_4.element().value()); last = m_4.element().key(); } last = 0; while (m_8.move_next()) { DLIB_TEST(last <= m_8.element().key()); DLIB_TEST(m_8.element().key() + 1 == m_8.element().value()); last = m_8.element().key(); } last = 0; while (m_t.move_next()) { DLIB_TEST(last <= m_t.element().key()); DLIB_TEST(m_t.element().key() + 1 == m_t.element().value()); last = m_t.element().key(); } // this is just to test swap m_4.swap(m_8); m_4.reset(); table_4b.reset(); while (m_8.move_next()) { DLIB_TEST( table_4b[m_8.element().key()] != 0); DLIB_TEST( *table_4b[m_8.element().key()] == m_8.element().value()); } while (table_4b.move_next()) { DLIB_TEST( m_8[table_4b.element().key()] != 0); DLIB_TEST( *m_8[table_4b.element().key()] == table_4b.element().value()); } } class static_map_tester : public tester { public: static_map_tester ( ) : tester ("test_static_map", "Runs tests on the static_map component.") {} void perform_test ( ) { dlog << LINFO << "testing kernel_1a"; static_map_kernel_test<static_map<int,int>::kernel_1a> (); dlog << LINFO << "testing kernel_1a_c"; static_map_kernel_test<static_map<int,int>::kernel_1a_c>(); } } a; }