commit 77de9119efbee9e65f0b50fc8b9315b6fb0910fb
parent d16656919753438a57a32f9ad6ba972c25d66b11
Author: Sebastiano Tronto <sebastiano@tronto.net>
Date: Fri, 20 Mar 2026 17:59:56 +0100
Added support for _BitInt (available in clang)
Diffstat:
| A | bitint_wrapper.h | | | 50 | ++++++++++++++++++++++++++++++++++++++++++++++++++ |
| M | test | | | 18 | ++++++++++++++++++ |
2 files changed, 68 insertions(+), 0 deletions(-)
diff --git a/bitint_wrapper.h b/bitint_wrapper.h
@@ -0,0 +1,50 @@
+#ifndef BITINT_WRAPPER_H
+#define BITINT_WRAPPER_H
+
+#include <cstdio>
+#include <iostream>
+
+// Wrapper class for _BitInt(N) (port of the C23 feature, compiler
+// extension for C++ available in Clang and maybe GCC). This is needed
+// because operator<< is not defined on _BitInt(N), apparently.
+
+template<uint64_t N = 128>
+class BitInt {
+public:
+ _BitInt(N) x;
+
+ constexpr BitInt() : x{_BitInt(N)(0)} {}
+ constexpr BitInt(int n) : x{_BitInt(N)(n)} {}
+ constexpr BitInt(long long n) : x{_BitInt(N)(n)} {}
+ constexpr BitInt(_BitInt(N) n) : x{n} {}
+ constexpr auto operator<=>(const BitInt& b) const { return x <=> b.x; }
+ constexpr bool operator==(const BitInt& b) const = default;
+ constexpr BitInt operator+(const BitInt& b) const { return x + b.x; }
+ constexpr BitInt operator-(const BitInt& b) const { return x - b.x; }
+ constexpr BitInt operator*(const BitInt& b) const { return x * b.x; }
+ constexpr BitInt operator/(const BitInt& b) const { return x / b.x; }
+ constexpr BitInt operator%(const BitInt& b) const { return x % b.x; }
+ constexpr BitInt operator-() const { return -x; }
+ constexpr BitInt operator+=(const BitInt& b) { return *this = *this + b; }
+ constexpr BitInt operator-=(const BitInt& b) { return *this = *this - b; }
+ constexpr BitInt operator*=(const BitInt& b) { return *this = *this * b; }
+ constexpr BitInt operator/=(const BitInt& b) { return *this = *this / b; }
+ constexpr BitInt operator%=(const BitInt& b) { return *this = *this % b; }
+
+ friend std::ostream& operator<<(std::ostream& os, const BitInt<N>& b) {
+ if (b > 0) {
+ std::string s;
+ auto bb = b;
+ while (bb != 0) {
+ char c = (bb.x % 10) + '0';
+ s = c + s;
+ bb /= 10;
+ }
+ return os << s;
+ } else if (b < 0) {
+ return os << "-" << -b;
+ } else return os << "0";
+ }
+};
+
+#endif
diff --git a/test b/test
@@ -12,6 +12,10 @@ exit 0
#include "zmodn.h"
#include "bigint.h"
+#if defined(__clang__) && __clang_major__ >= 16
+#include "bitint_wrapper.h"
+#endif
+
#include <concepts>
#include <functional>
#include <iostream>
@@ -479,6 +483,20 @@ public:
assert_equal(inv.value().toint(), expected);
}
},
+#if defined(__clang__) && __clang_major__ >= 16
+{
+ .name = "Zmod with BitInt",
+ .f = []() {
+ constexpr BitInt N{1000000000000LL}; // 1e12
+ BitInt a{600000000000LL}; // 6e11
+ BitInt b{700000000000LL}; // 7e11
+ BitInt c{300000000000LL}; // 3e11
+
+ Zmod<N> a_modN(a), b_modN(b), c_modN(c);
+ assert_equal(a_modN + b_modN, c_modN);
+ }
+},
+#endif
/*
{
.name = "This does not compile",