aocpp/zmod/include/zmod.hpp
Eric Mertens 8f772d85b2 201718
2022-11-18 14:50:42 -08:00

69 lines
1.4 KiB
C++

#ifndef ZMOD_HPP_
#define ZMOD_HPP_
#include <iostream>
#include <gmpxx.h>
namespace zmod {
template <unsigned long Mod>
class ZMod {
mpz_class value;
public:
ZMod() : value {} {}
ZMod(long value) : ZMod{mpz_class{value}} {}
ZMod(mpz_class value) {
mpz_mod_ui(this->value.get_mpz_t(), value.get_mpz_t(), Mod);
}
auto operator+(ZMod const& rhs) const -> ZMod {
return {value + rhs.value};
}
auto operator+=(ZMod const& rhs) -> ZMod & {
value += rhs.value;
mpz_mod_ui(this->value.get_mpz_t(), value.get_mpz_t(), Mod);
return *this;
}
auto operator-() const -> ZMod {
return {-value};
}
auto operator-(ZMod const& rhs) const -> ZMod {
return {value - rhs.value};
}
auto operator-=(ZMod const& rhs) -> ZMod & {
value -= rhs.value;
mpz_mod_ui(value.get_mpz_t(), value.get_mpz_t(), Mod);
return *this;
}
auto operator*(ZMod const& rhs) const -> ZMod {
return {value * rhs.value};
}
auto operator*=(ZMod const& rhs) -> ZMod & {
value -= rhs.value;
mpz_mod_ui(value.get_mpz_t(), value.get_mpz_t(), Mod);
return *this;
}
auto inverse() const -> ZMod {
mpz_class m{Mod};
ZMod result;
mpz_invert(result.value.get_mpz_t(), value.get_mpz_t(), m.get_mpz_t());
return result;
}
auto friend operator<<(std::ostream & out, ZMod<Mod> const& x) -> std::ostream & {
return out << x.value.get_ui();
}
};
}
#endif