#include #include #include #include #include #include #include "util/util.h" #include "param/long_bits.h" using namespace std; bool is_zero(const char c){return c == '0';} bool is_one(const char c){return c == '1';} bool is_two(const char c){return c == '2';} class LongBitsTestSuite : public Test::Suite{ protected: typedef LongBits<> longbits_t; typedef LongBits longbits_char_t; typedef LongBits longbits_short_t; typedef LongBits longbits_int_t; typedef LongBits longbits_long_t; stringstream src; longbits_t *longbits; longbits_char_t *longbits_char; longbits_short_t *longbits_short; longbits_int_t *longbits_int; longbits_long_t *longbits_long; public: LongBitsTestSuite(){ TEST_ADD(LongBitsTestSuite::test_inspect); TEST_ADD(LongBitsTestSuite::test_append); TEST_ADD(LongBitsTestSuite::test_bitshift); TEST_ADD(LongBitsTestSuite::test_not); TEST_ADD(LongBitsTestSuite::test_or); TEST_ADD(LongBitsTestSuite::test_and); TEST_ADD(LongBitsTestSuite::test_xor); TEST_ADD(LongBitsTestSuite::test_reverse_in_storage); } protected: long make_bits(stringstream &ss, int num_of_bits) const { long l(0), mask(0x1); for(int i(0); i < num_of_bits; i++, mask <<= 1){ if(rand() % 2 == 0){ ss << '0'; }else{ ss << '1'; l |= mask; } } return l; } virtual void setup(){ cout << endl; rand_init(0); src.str(""); // 軽く作っておく int num_of_bits(sizeof(long) * 8); long l(make_bits(src, num_of_bits)); longbits = new longbits_t((longbits_t::storage_t *)&l, num_of_bits); #define NEW(type) \ longbits_ ## type = new longbits_ ## type ## _t((type *)&l, num_of_bits); NEW(char); NEW(short); NEW(int); NEW(long); #undef NEW } virtual void tear_down(){ delete longbits; delete longbits_char; delete longbits_short; delete longbits_int; delete longbits_long; cout << endl; } template void raw_out(const LongBits &bits){ stringstream ss; ss << dec << bits; // hex cout << "raw_out: " << ss.str() << endl; } template bool is_equal(const string &s, const LongBits &bits){ stringstream bits_ss; bits_ss << dec << bits; string bits_s(bits_ss.str()); // 空白の除去 bits_s = bits_s.substr(0, distance(bits_s.begin(), remove(bits_s.begin(), bits_s.end(), ' '))); bool b((s.length() == bits.size()) && (s.compare(bits_s) == 0)); if(!b){ cout << endl << s << endl << bits_s << endl; } return b; } template bool is_equal(const stringstream &ss, const LongBits &bits){ return is_equal(ss.str(), bits); } private: void test_inspect(){ #define PERFORM(target_p) \ raw_out(*target_p); \ TEST_ASSERT(is_equal(src, *target_p)); PERFORM(longbits); PERFORM(longbits_char); PERFORM(longbits_short); PERFORM(longbits_int); PERFORM(longbits_long); #undef PERFORM } void test_append(){ cout << "append:" << endl; for(int i(0); i < 1000; i++){ long l[4]; int num_of_bits(rand() % (sizeof(l) * 8)); cout << i << "(" << src.str().size() << "+" << num_of_bits << ") "; for(int remain(num_of_bits), j(0); remain > 0; remain -= (sizeof(l[0]) * 8), j++){ l[j] = make_bits(src, remain > (sizeof(l[0]) * 8) ? (sizeof(l[0]) * 8) : remain); } longbits->append((longbits_t::storage_t *)l, num_of_bits); #define APPEND(type) \ (longbits_ ## type)->append((type *)l, num_of_bits); APPEND(char); APPEND(short); APPEND(int); APPEND(long); #undef APPEND TEST_ASSERT(is_equal(src, *longbits)); TEST_ASSERT(is_equal(src, *longbits_char)); TEST_ASSERT(is_equal(src, *longbits_short)); TEST_ASSERT(is_equal(src, *longbits_int)); TEST_ASSERT(is_equal(src, *longbits_long)); } } void test_bitshift(){ cout << "<<:" << endl; for(int i(0); i <= longbits->size(); i++){ cout << i << " "; string s(src.str().substr(i)); TEST_ASSERT(is_equal(s, (*longbits) << i)); TEST_ASSERT(is_equal(s, (*longbits_char) << i)); TEST_ASSERT(is_equal(s, (*longbits_short) << i)); TEST_ASSERT(is_equal(s, (*longbits_int) << i)); TEST_ASSERT(is_equal(s, (*longbits_long) << i)); } cout << endl << ">>:" << endl; for(int i(0); i <= longbits->size(); i++){ cout << i << " "; string s(src.str().substr(0, longbits->size() - i)); TEST_ASSERT(is_equal(s, (*longbits) >> i)); TEST_ASSERT(is_equal(s, (*longbits_char) >> i)); TEST_ASSERT(is_equal(s, (*longbits_short) >> i)); TEST_ASSERT(is_equal(s, (*longbits_int) >> i)); TEST_ASSERT(is_equal(s, (*longbits_long) >> i)); } cout << endl << "<< >>:" << endl; for(int i(0); i <= longbits->size() / 2; i++){ cout << i << " "; string s(src.str().substr(i).substr(0, longbits->size() - i * 2)); TEST_ASSERT(is_equal(s, ((*longbits) << i) >> i)); TEST_ASSERT(is_equal(s, ((*longbits_char) << i) >> i)); TEST_ASSERT(is_equal(s, ((*longbits_short) << i) >> i)); TEST_ASSERT(is_equal(s, ((*longbits_int) << i) >> i)); TEST_ASSERT(is_equal(s, ((*longbits_long) << i) >> i)); } cout << endl; } void test_not(){ string str_not(src.str()); replace_if(str_not.begin(), str_not.end(), is_zero, '2'); replace_if(str_not.begin(), str_not.end(), is_one, '0'); replace_if(str_not.begin(), str_not.end(), is_two, '1'); TEST_ASSERT(is_equal(str_not, ~(*longbits))); TEST_ASSERT(is_equal(str_not, ~(*longbits_char))); TEST_ASSERT(is_equal(str_not, ~(*longbits_short))); TEST_ASSERT(is_equal(str_not, ~(*longbits_int))); TEST_ASSERT(is_equal(str_not, ~(*longbits_long))); } void test_or(){ cout << ((*longbits) | (*longbits)) << endl; } void test_and(){ cout << ((*longbits) & (*longbits)) << endl; } void test_xor(){ cout << ~((*longbits) ^ (*longbits)) << endl; } void test_reverse_in_storage(){ cout << src.str() << endl; cout << (*longbits).reverse_in_storage() << endl; cout << (*longbits_char).reverse_in_storage() << endl; cout << (*longbits_short).reverse_in_storage() << endl; cout << (*longbits_int).reverse_in_storage() << endl; cout << (*longbits_long).reverse_in_storage() << endl; } }; bool run_tests(){ LongBitsTestSuite test_suits; Test::TextOutput output(Test::TextOutput::Verbose); return test_suits.run(output, false); // Note the 'false' parameter } int main(){run_tests();return 0;}