#include "bitwise.hpp" #include "std.hpp" #include "tap.hpp" //----------------------------------------------------------------------------- static void test_rotate (cruft::TAP::logger &tap) { tap.expect_eq (cruft::rotatel (uint8_t (0x0F), 0), 0x0Fu, "rotate-left u8"); tap.expect_eq (cruft::rotatel (uint8_t (0x0F), 4), 0xF0u, "rotate-left u8"); tap.expect_eq (cruft::rotatel (uint8_t (0xF0), 4), 0x0Fu, "rotate-left u8"); tap.expect_eq (cruft::rotater (uint8_t (0x0F), 0), 0x0Fu, "rotate-right u8"); tap.expect_eq (cruft::rotater (uint8_t (0x0F), 4), 0xF0u, "rotate-right u8"); tap.expect_eq (cruft::rotater (uint8_t (0xF0), 4), 0x0Fu, "rotate-right u8"); tap.expect_eq (cruft::rotatel (uint16_t (0xABCD), 0), 0xABCDu, "rotate-left u16"); tap.expect_eq (cruft::rotatel (uint16_t (0xABCD), 4), 0xBCDAu, "rotate-left u16"); tap.expect_eq (cruft::rotatel (uint16_t (0xABCD), 8), 0xCDABu, "rotate-left u16"); tap.expect_eq (cruft::rotatel (uint16_t (0xABCD), 12), 0xDABCu, "rotate-left u16"); tap.expect_eq (cruft::rotater (uint16_t (0xABCD), 0), 0xABCDu, "rotate-right u16"); tap.expect_eq (cruft::rotater (uint16_t (0xABCD), 4), 0xDABCu, "rotate-right u16"); tap.expect_eq (cruft::rotater (uint16_t (0xABCD), 8), 0xCDABu, "rotate-right u16"); tap.expect_eq (cruft::rotater (uint16_t (0xABCD), 12), 0xBCDAu, "rotate-right u16"); tap.expect_eq (cruft::rotatel (uint32_t (0x12345670), 12), 0x45670123u, "rotate-left u32"); tap.expect_eq (cruft::rotater (uint32_t (0x12345670), 12), 0x67012345u, "rotate-right u32"); tap.expect_eq (cruft::rotatel (uint64_t (0x1234567890ABCDEF), 12), 0x4567890ABCDEF123u, "rotate-left u64"); tap.expect_eq (cruft::rotater (uint64_t (0x1234567890ABCDEF), 12), 0xDEF1234567890ABCu, "rotate-right u64"); } //----------------------------------------------------------------------------- void test_reverse (cruft::TAP::logger &tap) { size_t matches = 0; for (unsigned i = 0; i < 256; ++i) { auto first = cruft::reverse (i); auto last = cruft::reverse (first); if (last == i) matches++; } tap.expect_eq (matches, 256u, "exhaustive 8 bit reverse"); } //----------------------------------------------------------------------------- void test_bitfield (cruft::TAP::logger &tap) { union { /// * lo is set to 1 and hi is set to 0 to establish bit ordering /// * mid pattern tests behaviour across byte boundaries u16 raw = 0b0111'0011'0000'0001; // | |mid^---^ | // highest^ | lowest^ // high^--^ cruft::bitfield lowest; cruft::bitfield highest; cruft::bitfield high; cruft::bitfield mid; }; tap.expect_eq (lowest, u16 { 0b1}, "bitfield lowest bit"); tap.expect_eq (highest, u16 { 0b0}, "bitfield highest bit"); tap.expect_eq (high, u16 {0b0111}, "bitfield high bits"); tap.expect_eq (mid, u16 {0b1100}, "bitfield byte boundary bits"); } //----------------------------------------------------------------------------- int main (int, char**) { cruft::TAP::logger tap; test_rotate (tap); test_reverse (tap); test_bitfield (tap); tap.expect_eq (cruft::ctz (0b11110000u), 4u, "count-trailing-zero trivial test"); return tap.status (); }