test (2735B)
1 #if 0 2 3 cc=${CC:-g++} 4 bin="$(mktemp)" 5 ${cc} -x c++ -std=c++20 -o "$bin" "$(realpath $0)" 6 "$bin" 7 8 exit 0 9 #endif 10 11 #include "zmodn.h" 12 #include <concepts> 13 #include <functional> 14 #include <iostream> 15 #include <optional> 16 17 template<typename S, typename T> 18 requires std::convertible_to<S, T> || std::convertible_to<T, S> 19 void assert_equal(S actual, T expected) { 20 if (actual != expected) { 21 std::cout << "Error!" << std::endl; 22 std::cout << "Expected: " << expected << std::endl; 23 std::cout << "But got: " << actual << std::endl; 24 exit(1); 25 } 26 } 27 28 class Test { 29 public: 30 std::string name; 31 std::function<void()> f; 32 } tests[] = { 33 { 34 .name = "Constructor 2 mod 3", 35 .f = []() { 36 Zmod<3> two = Zmod<3>(2); 37 assert_equal(two.toint(), INT64_C(2)); 38 } 39 }, 40 { 41 .name = "Constructor -7 mod 3", 42 .f = []() { 43 Zmod<3> z = -7; 44 assert_equal(z, Zmod<3>(2)); 45 } 46 }, 47 { 48 .name = "1+1 mod 2", 49 .f = []() { 50 auto oneplusone = Zmod<2>(1) + Zmod<2>(1); 51 assert_equal(oneplusone, Zmod<2>(0)); 52 } 53 }, 54 { 55 .name = "2 -= 5 (mod 4)", 56 .f = []() { 57 Zmod<4> z = 2; 58 auto diff = (z -= 5); 59 assert_equal(z, Zmod<4>(1)); 60 assert_equal(diff, Zmod<4>(1)); 61 } 62 }, 63 { 64 .name = "Inverse of 0 mod 2", 65 .f = []() { 66 Zmod<2> z = 0; 67 auto inv = z.inverse(); 68 assert_equal(inv.has_value(), false); 69 } 70 }, 71 { 72 .name = "Inverse of 1 mod 2", 73 .f = []() { 74 Zmod<2> z = 1; 75 auto inv = z.inverse(); 76 assert_equal(inv.has_value(), true); 77 assert_equal(inv.value(), Zmod<2>(1)); 78 } 79 }, 80 { 81 .name = "Inverse of 5 mod 7", 82 .f = []() { 83 Zmod<7> z = 5; 84 auto inv = z.inverse(); 85 assert_equal(inv.has_value(), true); 86 assert_equal(inv.value(), Zmod<7>(3)); 87 } 88 }, 89 { 90 .name = "Inverse of 4 mod 12", 91 .f = []() { 92 Zmod<12> z = 4; 93 auto inv = z.inverse(); 94 assert_equal(inv.has_value(), false); 95 } 96 }, 97 { 98 .name = "4 / 7 (mod 12)", 99 .f = []() { 100 Zmod<12> n = 4; 101 Zmod<12> d = 7; 102 auto inv = n / d; 103 assert_equal(inv.has_value(), true); 104 assert_equal(inv.value(), Zmod<12>(4)); 105 } 106 }, 107 { 108 .name = "4 /= 7 (mod 12)", 109 .f = []() { 110 Zmod<12> n = 4; 111 Zmod<12> d = 7; 112 auto inv = (n /= d); 113 assert_equal(inv.has_value(), true); 114 assert_equal(inv.value(), Zmod<12>(4)); 115 assert_equal(n, Zmod<12>(4)); 116 } 117 }, 118 { 119 .name = "Multiplication overflow", 120 .f = []() { 121 Zmod<10> n = 8; 122 Zmod<10> m = 9; 123 auto prod = m * n; 124 assert_equal(prod.toint(), 2); 125 } 126 }, 127 { 128 .name = "Multiplication and assignment overflow", 129 .f = []() { 130 Zmod<10> n = 8; 131 Zmod<10> m = 9; 132 n *= m; 133 assert_equal(n.toint(), 2); 134 } 135 }, 136 { 137 .name = "2^12 mod 154", 138 .f = []() { 139 Zmod<154> b = 2; 140 auto p = b ^ 12; 141 assert_equal(p, 92); 142 } 143 }, 144 }; 145 146 int main() { 147 for (auto t : tests) { 148 std::cout << t.name << ": "; 149 t.f(); 150 std::cout << "OK" << std::endl; 151 } 152 std::cout << "All tests passed" << std::endl; 153 return 0; 154 }