int main(int argc, char *argv[]) { int test = argc > 1 ? atoi(argv[1]) : 0; bool verbose = argc > 2; bool veryVerbose = argc > 3; bool veryVeryVerbose = argc > 4; bool veryVeryVeryVerbose = argc > 5; (void)veryVeryVeryVerbose; // suppress warning printf("TEST " __FILE__ " CASE %d\n", test); switch (test) { case 0: case 7: { // -------------------------------------------------------------------- // USAGE EXAMPLE // The hashing algorithm can be used to create more powerful // components such as functors that can be used to power hash tables. // // Concerns: //: 1 The usage example provided in the component header file compiles, //: links, and runs as shown. // // Plan: //: 1 Incorporate usage example from header into test driver (C-1) // // Testing: // USAGE EXAMPLE // -------------------------------------------------------------------- if (verbose) printf("USAGE EXAMPLE\n" "=============\n"); // Then, we want to actually use our hash table on 'Future' objects. We create // an array of 'Future's based on data that was originally from some external // source: Future futures[] = { Future("Swiss Franc", 'F', 2014), Future("US Dollar", 'G', 2015), Future("Canadian Dollar", 'Z', 2014), Future("British Pound", 'M', 2015), Future("Deutsche Mark", 'X', 2016), Future("Eurodollar", 'Q', 2017)}; enum { NUM_FUTURES = sizeof futures / sizeof *futures }; // Next, we create our HashTable 'hashTable'. We pass the functor that we // defined above as the second argument: HashTable<Future, HashFuture> hashTable(futures, NUM_FUTURES); // Now, we verify that each element in our array registers with count: for ( int i = 0; i < 6; ++i) { ASSERT(hashTable.contains(futures[i])); } // Finally, we verify that futures not in our original array are correctly // identified as not being in the set: ASSERT(!hashTable.contains(Future("French Franc", 'N', 2019))); ASSERT(!hashTable.contains(Future("Swiss Franc", 'X', 2014))); ASSERT(!hashTable.contains(Future("US Dollar", 'F', 2014))); } break; case 6: { // -------------------------------------------------------------------- // TESTING BDE TYPE TRAITS // The class is bitwise movable and should have a trait that // indicates that. // // Concerns: //: 1 The class is marked as 'IsBitwiseMoveable'. // // Plan: //: 1 ASSERT the presence of the trait using the 'bslalg::HasTrait' //: metafunction. (C-1) // // Testing: // Trait IsBitwiseMoveable // -------------------------------------------------------------------- if (verbose) printf("\nTESTING BDE TYPE TRAITS" "\n=======================\n"); if (verbose) printf("ASSERT the presence of the trait using the" " 'bslalg::HasTrait' metafunction. (C-1)\n"); { ASSERT(bslmf::IsBitwiseMoveable<SpookyHashAlgorithm>::value); } } break; case 5: { // -------------------------------------------------------------------- // TESTING 'k_SEED_LENGTH' // The class is a seeded algorithm and should expose a // 'k_SEED_LENGTH' enum. // // Concerns: //: 1 'k_SEED_LENGTH' is publicly accessible. //: //: 2 'k_SEED_LENGTH' is set to 16. // // Plan: //: 1 Access 'k_SEED_LENGTH' and ASSERT it is equal to the expected //: value. (C-1,2) // // Testing: // enum { k_SEED_LENGTH = 16 }; // -------------------------------------------------------------------- if (verbose) printf("\nTESTING 'k_SEED_LENGTH'" "\n=======================\n"); if (verbose) printf("Access 'k_SEED_LENGTH' and ASSERT it is equal to" " the expected value. (C-1,2)\n"); { ASSERT(16 == SpookyHashAlgorithm::k_SEED_LENGTH); } } break; case 4: { // -------------------------------------------------------------------- // TESTING 'result_type' TYPEDEF // Verify that the class offers the result_type typedef that needs to // be exposed by all 'bslh' hashing algorithms // // Concerns: //: 1 The typedef 'result_type' is publicly accessible and an alias for //: 'bsls::Types::Uint64'. //: //: 2 'computeHash()' returns 'result_type' // // Plan: //: 1 ASSERT the typedef is accessible and is the correct type using //: 'bslmf::IsSame'. (C-1) //: //: 2 Declare the expected signature of 'computeHash()' and then assign //: to it. If it compiles, the test passes. (C-2) // // Testing: // typedef bsls::Types::Uint64 result_type; // -------------------------------------------------------------------- if (verbose) printf("\nTESTING 'result_type' TYPEDEF" "\n=============================\n"); if (verbose) printf("ASSERT the typedef is accessible and is the" " correct type using 'bslmf::IsSame'. (C-1)\n"); { ASSERT((bslmf::IsSame<bsls::Types::Uint64, Obj::result_type>::VALUE)); } if (verbose) printf("Declare the expected signature of 'computeHash()'" " and then assign to it. If it compiles, the test" " passes. (C-2)\n"); { Obj::result_type (Obj::*expectedSignature) (); expectedSignature = &Obj::computeHash; (void)expectedSignature; } } break; case 3: { // -------------------------------------------------------------------- // TESTING TESTING 'operator()' AND 'computeHash()' // Verify the class provides an overload for the function call // operator that can be called with some bytes and a length. Verify // that calling 'operator()' will permute the algorithm's internal // state as specified by SpookyHash. Verify that 'computeHash()' // returns the final value specified by the canonical spooky hash // implementation. // // Concerns: //: 1 The function call operator is callable. //: //: 2 Given the same bytes, the function call operator will permute the //: internal state of the algorithm in the same way, regardless of //: whether the bytes are passed in all at once or in pieces. //: //: 3 Byte sequences passed in to 'operator()' with a length of 0 will //: not contribute to the final hash //: //: 4 'computeHash()' and returns the appropriate value //: according to the SpookyHash specification. //: //: 5 'operator()' does a BSLS_ASSERT for null pointers. // // Plan: //: 1 Insert various lengths of c-strings into the algorithm both all //: at once and char by char using 'operator()'. Assert that the //: algorithm produces the same result in both cases. (C-1,2) //: //: 2 Hash c-strings all at once and with multiple calls to //: 'operator()' with length 0. Assert that both methods of hashing //: c-strings produce the same values.(C-3) //: //: 3 Check the output of 'computeHash()' against the expected results //: from a known good version of the algorithm. (C-4) //: //: 4 Call 'operator()' with a null pointer. (C-5) // // Testing: // void operator()(void const* key, size_t len); // result_type computeHash(); // -------------------------------------------------------------------- if (verbose) printf( "\nTESTING TESTING 'operator()' AND 'computeHash()'" "\n================================================\n"); static const struct { int d_line; const char d_value [21]; bsls::Types::Uint64 d_expectedHash; } DATA[] = { #ifdef BSLS_PLATFORM_IS_LITTLE_ENDIAN // LINE DATA HASH { L_, "1", 7002407594712107506ULL,}, { L_, "12", 16818667202782586754ULL,}, { L_, "123", 14962907208936606339ULL,}, { L_, "1234", 13841264755844795919ULL,}, { L_, "12345", 4217007344502432836ULL,}, { L_, "123456", 15406725965008216808ULL,}, { L_, "1234567", 9451242472090273442ULL,}, { L_, "12345678", 10759732512414454861ULL,}, { L_, "123456789", 972485933408677714ULL,}, { L_, "1234567890", 5673121172557267903ULL,}, { L_, "12345678901", 13862553145028760004ULL,}, { L_, "123456789012", 15680761296024743980ULL,}, { L_, "1234567890123", 9130538754397985015ULL,}, { L_, "12345678901234", 18108216297703361154ULL,}, { L_, "123456789012345", 14690529358019617166ULL,}, { L_, "1234567890123456", 10018078431842207320ULL,}, { L_, "12345678901234567", 18401305144349413810ULL,}, { L_, "123456789012345678", 16182063539957820126ULL,}, { L_, "1234567890123456789", 16302264721124054926ULL,}, { L_, "12345678901234567890", 7953951658377832965ULL,}, #else // LINE DATA HASH { L_, "1", 7002407594712107506ULL,}, { L_, "12", 16818667202782586754ULL,}, { L_, "123", 14962907208936606339ULL,}, { L_, "1234", 6699426530780107312ULL,}, { L_, "12345", 8676331252213764608ULL,}, { L_, "123456", 4550369474379901410ULL,}, { L_, "1234567", 16791262952135217002ULL,}, { L_, "12345678", 16425013147235105742ULL,}, { L_, "123456789", 5214485795892544707ULL,}, { L_, "1234567890", 12261113520408985235ULL,}, { L_, "12345678901", 2168166662679930866ULL,}, { L_, "123456789012", 12754308552622014786ULL,}, { L_, "1234567890123", 14297370022220374180ULL,}, { L_, "12345678901234", 16893477830408992202ULL,}, { L_, "123456789012345", 9435207994519636836ULL,}, { L_, "1234567890123456", 9862342523424011374ULL,}, { L_, "12345678901234567", 1788935288602307262ULL,}, { L_, "123456789012345678", 4717428848732367803ULL,}, { L_, "1234567890123456789", 17814078940325658812ULL,}, { L_, "12345678901234567890", 10441832432953046058ULL,}, #endif }; const int NUM_DATA = sizeof DATA / sizeof *DATA; if (verbose) printf("Insert various lengths of c-strings into the" " algorithm both all at once and char by char" " using 'operator()'. Assert that the algorithm" " produces the same result in both cases. (C-1,2)" "\n"); { for (int i = 0; i != NUM_DATA; ++i) { const int LINE = DATA[i].d_line; const char *VALUE = DATA[i].d_value; if (veryVerbose) printf("Hashing: %s\n", VALUE); Obj contiguousHash; Obj dispirateHash; contiguousHash(VALUE, strlen(VALUE)); for (unsigned int j = 0; j < strlen(VALUE); ++j){ if (veryVeryVerbose) printf("Hashing by char: %c\n", VALUE[j]); dispirateHash(&VALUE[j], sizeof(char)); } LOOP_ASSERT(LINE, contiguousHash.computeHash() == dispirateHash.computeHash()); } } if (verbose) printf("Hash c-strings all at once and with multiple" " calls to 'operator()' with length 0. Assert" " that both methods of hashing c-strings produce" " the same values.(C-3)\n"); { for (int i = 0; i != NUM_DATA; ++i) { const int LINE = DATA[i].d_line; const char *VALUE = DATA[i].d_value; if (veryVerbose) printf("Hashing: %s\n", VALUE); Obj contiguousHash; Obj dispirateHash; contiguousHash(VALUE, strlen(VALUE)); for (unsigned int j = 0; j < strlen(VALUE); ++j){ if (veryVeryVerbose) printf("Hashing by char: %c\n", VALUE[j]); dispirateHash(&VALUE[j], sizeof(char)); dispirateHash(VALUE, 0); } LOOP_ASSERT(LINE, contiguousHash.computeHash() == dispirateHash.computeHash()); } } if (verbose) printf("Check the output of 'computeHash()' against the" " expected results from a known good version of" " the algorithm. (C-4)\n"); { for (int i = 0; i != NUM_DATA; ++i) { const int LINE = DATA[i].d_line; const char *VALUE = DATA[i].d_value; const unsigned long long HASH = DATA[i].d_expectedHash; if (veryVerbose) printf("Hashing: %s, Expecting: %llu\n", VALUE, HASH); Obj hash; hash(VALUE, strlen(VALUE)); LOOP_ASSERT(LINE, hash.computeHash() == HASH); } } if (verbose) printf("Call 'operator()' with null pointers. (C-5)\n"); { const char data[5] = {'a', 'b', 'c', 'd', 'e'}; bsls::AssertTestHandlerGuard guard; ASSERT_FAIL(Obj().operator()( 0, 5)); ASSERT_PASS(Obj().operator()(data, 5)); } } break; case 2: { // -------------------------------------------------------------------- // TESTING CREATORS // Ensure that the implicit destructor as well as the explicit // default and parameterized constructors are publicly callable. // Verify that the algorithm can be instantiated with or without a // seed. Note that a null pointer is not tested here, because there // is no way to perform a BSLS_ASSERT before dereferenceing the // pointer (without a performance penalty). // // Concerns: //: 1 Objects can be created using the default constructor. //: //: 2 Objects can be created using the parameterized constructor. //: //: 3 Objects can be destroyed. // // Plan: //: 1 Create a default constructed 'SpookyHashAlgorithm' and allow it //: to leave scope to be destroyed. (C-1,3) //: //: 2 Call the parameterized constructor with a seed. (C-2) // // Testing: // SpookyHashAlgorithm(); // SpookyHashAlgorithm(const char *seed); // ~SpookyHashAlgorithm(); // -------------------------------------------------------------------- if (verbose) printf("\nTESTING CREATORS" "\n================\n"); if (verbose) printf("Create a default constructed" " 'SpookyHashAlgorithm' and allow it to leave" " scope to be destroyed. (C-1,3)\n"); { Obj alg1; } if (verbose) printf("Call the parameterized constructor with a seed." " (C-2)\n"); { Uint64 array[2] = {0,0}; Obj alg1(reinterpret_cast<const char *>(array)); } } break; case 1: { // -------------------------------------------------------------------- // BREATHING TEST // This case exercises (but does not fully test) basic functionality. // // Concerns: //: 1 The class is sufficiently functional to enable comprehensive //: testing in subsequent test cases. // // Plan: //: 1 Create an instance of 'bsl::SpookyHashAlgorithm'. (C-1) //: //: 2 Verify different hashes are produced for different c-strings. //: (C-1) //: //: 3 Verify the same hashes are produced for the same c-strings. (C-1) //: //: 4 Verify different hashes are produced for different 'int's. (C-1) //: //: 5 Verify the same hashes are produced for the same 'int's. (C-1) // // Testing: // BREATHING TEST // -------------------------------------------------------------------- if (verbose) printf("\nBREATHING TEST" "\n==============\n"); if (verbose) printf("Instantiate 'bsl::SpookyHashAlgorithm'\n"); { SpookyHashAlgorithm hashAlg; } if (verbose) printf("Verify different hashes are produced for" " different c-strings.\n"); { SpookyHashAlgorithm hashAlg1; SpookyHashAlgorithm hashAlg2; const char * str1 = "Hello World"; const char * str2 = "Goodbye World"; hashAlg1(str1, strlen(str1)); hashAlg2(str2, strlen(str2)); ASSERT(hashAlg1.computeHash() != hashAlg2.computeHash()); } if (verbose) printf("Verify the same hashes are produced for the same" " c-strings.\n"); { SpookyHashAlgorithm hashAlg1; SpookyHashAlgorithm hashAlg2; const char * str1 = "Hello World"; const char * str2 = "Hello World"; hashAlg1(str1, strlen(str1)); hashAlg2(str2, strlen(str2)); ASSERT(hashAlg1.computeHash() == hashAlg2.computeHash()); } if (verbose) printf("Verify different hashes are produced for" " different 'int's.\n"); { SpookyHashAlgorithm hashAlg1; SpookyHashAlgorithm hashAlg2; int int1 = 123456; int int2 = 654321; hashAlg1(&int1, sizeof(int)); hashAlg2(&int2, sizeof(int)); ASSERT(hashAlg1.computeHash() != hashAlg2.computeHash()); } if (verbose) printf("Verify the same hashes are produced for the same" " 'int's.\n"); { SpookyHashAlgorithm hashAlg1; SpookyHashAlgorithm hashAlg2; int int1 = 123456; int int2 = 123456; hashAlg1(&int1, sizeof(int)); hashAlg2(&int2, sizeof(int)); ASSERT(hashAlg1.computeHash() == hashAlg2.computeHash()); } } break; default: { fprintf(stderr, "WARNING: CASE `%d' NOT FOUND.\n", test); testStatus = -1; } } return testStatus; }
int main(int argc, char *argv[]) { int test = argc > 1 ? atoi(argv[1]) : 0; bool verbose = argc > 2; bool veryVerbose = argc > 3; bool veryVeryVerbose = argc > 4; // bool veryVeryVeryVerbose = argc > 5; printf("TEST " __FILE__ " CASE %d\n", test); switch (test) { case 0: case 5: { // -------------------------------------------------------------------- // USAGE EXAMPLE // The hashing algorithm can be used to create more powerful // components such as functors that can be used to power hash tables. // // Concerns: //: 1 The usage example provided in the component header file compiles, //: links, and runs as shown. // // Plan: //: 1 Incorporate usage example from header into test driver (C-1) // // Testing: // USAGE EXAMPLE // -------------------------------------------------------------------- if (verbose) printf("USAGE EXAMPLE\n" "=============\n"); // Then, we want to actually use our hash table on 'Future' objects. We // create an array of 'Future's based on data that was originally from some // external source: Future futures[] = { Future("Swiss Franc", 'F', 2014), Future("US Dollar", 'G', 2015), Future("Canadian Dollar", 'Z', 2014), Future("British Pound", 'M', 2015), Future("Deutsche Mark", 'X', 2016), Future("Eurodollar", 'Q', 2017)}; enum { NUM_FUTURES = sizeof futures / sizeof *futures }; // Next, we create our HashTable 'hashTable'. We pass the functor that we // defined above as the second argument: HashTable<Future, HashFuture> hashTable(futures, NUM_FUTURES); // Now, we verify that each element in our array registers with count: for ( int i = 0; i < 6; ++i) { ASSERT(hashTable.contains(futures[i])); } // Finally, we verify that futures not in our original array are correctly // identified as not being in the set: ASSERT(!hashTable.contains(Future("French Franc", 'N', 2019))); ASSERT(!hashTable.contains(Future("Swiss Franc", 'X', 2014))); ASSERT(!hashTable.contains(Future("US Dollar", 'F', 2014))); } break; case 4: { // -------------------------------------------------------------------- // TESTING 'result_type' TYPEDEF // Verify that the class offers the result_type typedef that needs to // be exposed by all 'bslh' hashing algorithms // // Concerns: //: 1 The typedef 'result_type' is publicly accessible and an alias for //: 'bslh::SpookyHashAlgorithm::result_type'. //: //: 2 'computeHash()' returns 'result_type' // // Plan: //: 1 ASSERT the typedef is accessible and is the correct type using //: 'bslmf::IsSame'. (C-1) //: //: 2 Declare the expected signature of 'computeHash()' and then assign //: to it. If it compiles, the test passes. (C-2) // // Testing: // typedef InternalHashAlgorithm::result_type result_type; // -------------------------------------------------------------------- if (verbose) printf("\nTESTING 'result_type' TYPEDEF" "\n=============================\n"); if (verbose) printf("ASSERT the typedef is accessible and is the" " correct type using 'bslmf::IsSame'. (C-1)\n"); { ASSERT((bslmf::IsSame<Obj::result_type, SpookyHashAlgorithm::result_type>::VALUE)); } if (verbose) printf("Declare the expected signature of 'computeHash()'" " and then assign to it. If it compiles, the test" " passes. (C-2)\n"); { Obj::result_type (Obj::*expectedSignature) (); expectedSignature = &Obj::computeHash; } } break; case 3: { // -------------------------------------------------------------------- // TESTING 'operator()' AND 'computeHash()' // Verify the class provides an overload for the function call // operator that can be called with some bytes and a length. Verify // that calling 'operator()' will permute the algorithm's internal // state as specified by the underlying hashing algorithm // (bslh::SpookyHashAlgorithm). Verify that 'computeHash()' returns // the final value specified by the canonical implementation of the // underlying hashing algorithm. // // Concerns: //: 1 The function call operator is callable. //: //: 2 The 'computeHash()' function is callable. //: //: 3 The output of calling 'operator()' and then 'computeHash()' //: matches the output of the underlying hashing algorithm. //: //: 4 'operator()' does a BSLS_ASSERT for null pointers. // // Plan: //: 1 Hash a number of values with 'bslh::DefaultHashAlgorithm' and //: 'bslh::SpookyHashAlgorithm' and verify that the outputs match. //: (C-1,2,3) //: //: 2 Call 'operator()' with a null pointer. (C-4) // // Testing: // void operator()(void const* key, size_t len); // result_type computeHash(); // -------------------------------------------------------------------- if (verbose) printf( "\nTESTING 'operator()' AND 'computeHash()'" "\n========================================\n"); static const struct { int d_line; const char d_value [21]; } DATA[] = { // LINE DATA { L_, "1",}, { L_, "12",}, { L_, "123",}, { L_, "1234",}, { L_, "12345",}, { L_, "123456",}, { L_, "1234567",}, { L_, "12345678",}, { L_, "123456789",}, { L_, "1234567890",}, { L_, "12345678901",}, { L_, "123456789012",}, { L_, "1234567890123",}, { L_, "12345678901234",}, { L_, "123456789012345",}, { L_, "1234567890123456",}, { L_, "12345678901234567",}, { L_, "123456789012345678",}, { L_, "1234567890123456789",}, { L_, "12345678901234567890",}, }; const int NUM_DATA = sizeof DATA / sizeof *DATA; if (verbose) printf("Hash a number of values with" " 'bslh::DefaultHashAlgorithm' and" " 'bslh::SpookyHashAlgorithm' and verify that the" " outputs match. (C-1,2,3)\n"); { for (int i = 0; i != NUM_DATA; ++i) { const int LINE = DATA[i].d_line; const char *VALUE = DATA[i].d_value; if (veryVerbose) printf("Hashing: %s\n with" " 'bslh::DefaultHashAlgorithm' and" " 'bslh::SpookyHashAlgorithm'", VALUE); Obj contiguousHash; Obj dispirateHash; SpookyHashAlgorithm cannonicalHashAlgorithm; cannonicalHashAlgorithm(VALUE, strlen(VALUE)); contiguousHash(VALUE, strlen(VALUE)); for (unsigned int j = 0; j < strlen(VALUE); ++j){ if (veryVeryVerbose) printf("Hashing by char: %c\n", VALUE[j]); dispirateHash(&VALUE[j], sizeof(char)); } SpookyHashAlgorithm::result_type hash = cannonicalHashAlgorithm.computeHash(); LOOP_ASSERT(LINE, hash == contiguousHash.computeHash()); LOOP_ASSERT(LINE, hash == dispirateHash.computeHash()); } } if (verbose) printf("Call 'operator()' with null pointers. (C-4)\n"); { const char data[5] = {'a', 'b', 'c', 'd', 'e'}; bsls::AssertFailureHandlerGuard g(bsls::AssertTest::failTestDriver); ASSERT_FAIL(Obj()( 0, 5)); ASSERT_PASS(Obj()(data, 5)); } } break; case 2: { // -------------------------------------------------------------------- // TESTING CREATORS // Ensure that the implicit destructor and the explicit default // constructor are publicly callable. // // Concerns: //: 1 Objects can be created using the parameterized constructor. //: //: 2 Objects can be destroyed. // // Plan: //: 1 Create a default constructed 'DefaultHashAlgorithm' and allow it //: to leave scope to be destroyed. (C-1,2) // // Testing: // DefaultHashAlgorithm(); // ~DefaultHashAlgorithm(); // -------------------------------------------------------------------- if (verbose) printf("\nTESTING CREATORS" "\n================\n"); if (verbose) printf("Create a default constructed" " 'DefaultHashAlgorithm' and allow it to leave" " scope to be destroyed. (C-1,2)\n"); { Obj alg1; } } break; case 1: { // -------------------------------------------------------------------- // BREATHING TEST // This case exercises (but does not fully test) basic functionality. // // Concerns: //: 1 The class is sufficiently functional to enable comprehensive //: testing in subsequent test cases. // // Plan: //: 1 Create an instance of 'bsl::DefaultHashAlgorithm'. (C-1) //: //: 2 Verify different hashes are produced for different c-strings. //: (C-1) //: //: 3 Verify the same hashes are produced for the same c-strings. (C-1) //: //: 4 Verify different hashes are produced for different 'int's. (C-1) //: //: 5 Verify the same hashes are produced for the same 'int's. (C-1) // // Testing: // BREATHING TEST // -------------------------------------------------------------------- if (verbose) printf("\nBREATHING TEST" "\n==============\n"); if (verbose) printf("Instantiate 'bsl::DefaultHashAlgorithm'\n"); { Obj hashAlg; } if (verbose) printf("Verify different hashes are produced for" " different c-strings.\n"); { Obj hashAlg1; Obj hashAlg2; const char * str1 = "Hello World"; const char * str2 = "Goodbye World"; hashAlg1(str1, strlen(str1)); hashAlg2(str2, strlen(str2)); ASSERT(hashAlg1.computeHash() != hashAlg2.computeHash()); } if (verbose) printf("Verify the same hashes are produced for the same" " c-strings.\n"); { Obj hashAlg1; Obj hashAlg2; const char * str1 = "Hello World"; const char * str2 = "Hello World"; hashAlg1(str1, strlen(str1)); hashAlg2(str2, strlen(str2)); ASSERT(hashAlg1.computeHash() == hashAlg2.computeHash()); } if (verbose) printf("Verify different hashes are produced for" " different 'int's.\n"); { Obj hashAlg1; Obj hashAlg2; int int1 = 123456; int int2 = 654321; hashAlg1(&int1, sizeof(int)); hashAlg2(&int2, sizeof(int)); ASSERT(hashAlg1.computeHash() != hashAlg2.computeHash()); } if (verbose) printf("Verify the same hashes are produced for the same" " 'int's.\n"); { Obj hashAlg1; Obj hashAlg2; int int1 = 123456; int int2 = 123456; hashAlg1(&int1, sizeof(int)); hashAlg2(&int2, sizeof(int)); ASSERT(hashAlg1.computeHash() == hashAlg2.computeHash()); } } break; default: { fprintf(stderr, "WARNING: CASE `%d' NOT FOUND.\n", test); testStatus = -1; } } if (testStatus > 0) { fprintf(stderr, "Error, non-zero test status = %d.\n", testStatus); } return testStatus; }