make operator.hpp and move power into it

dev
MITSUNARI Shigeo 9 years ago
parent 1ee475b88a
commit cf4c1b2fed
  1. 49
      include/mcl/fp.hpp
  2. 77
      include/mcl/operator.hpp
  3. 31
      include/mcl/util.hpp

@ -27,6 +27,7 @@
#include <cybozu/hash.hpp>
#include <mcl/op.hpp>
#include <mcl/util.hpp>
#include <mcl/operator.hpp>
namespace mcl {
@ -52,8 +53,9 @@ int64_t getInt64(bool *pb, fp::Block& b, const fp::Op& op);
} // mcl::fp
template<class tag = FpTag, size_t maxBitSize = MCL_MAX_OP_BIT_SIZE>
class FpT {
class FpT : public fp::Operator<FpT<tag, maxBitSize> > {
typedef fp::Unit Unit;
typedef fp::Operator<FpT<tag, maxBitSize> > Operator;
static const size_t maxSize = (maxBitSize + fp::UnitBitSize - 1) / fp::UnitBitSize;
static fp::Op op_;
template<class tag2, size_t maxBitSize2> friend class FpT;
@ -311,28 +313,6 @@ public:
static inline void inv(FpT& y, const FpT& x) { op_.fp_invOp(y.v_, x.v_, op_); }
static inline void neg(FpT& y, const FpT& x) { op_.fp_neg(y.v_, x.v_); }
static inline void sqr(FpT& y, const FpT& x) { op_.fp_sqr(y.v_, x.v_); }
static inline void div(FpT& z, const FpT& x, const FpT& y)
{
FpT rev;
inv(rev, y);
mul(z, x, rev);
}
template<class tag2, size_t maxBitSize2>
static inline void power(FpT& z, const FpT& x, const FpT<tag2, maxBitSize2>& y)
{
fp::Block b;
y.getBlock(b);
powerArray(z, x, b.p, b.n, false);
}
static inline void power(FpT& z, const FpT& x, int y)
{
const Unit u = abs(y);
powerArray(z, x, &u, 1, y < 0);
}
static inline void power(FpT& z, const FpT& x, const mpz_class& y)
{
powerArray(z, x, Gmp::getUnit(y), abs(y.get_mpz_t()->_mp_size), y < 0);
}
bool isZero() const { return op_.fp_isZero(v_); }
bool isOne() const { return fp::isEqualArray(v_, op_.oneRep, op_.N); }
/*
@ -365,15 +345,6 @@ public:
static inline size_t getModBitLen() { return op_.bitSize; }
bool operator==(const FpT& rhs) const { return fp::isEqualArray(v_, rhs.v_, op_.N); }
bool operator!=(const FpT& rhs) const { return !operator==(rhs); }
inline friend FpT operator+(const FpT& x, const FpT& y) { FpT z; add(z, x, y); return z; }
inline friend FpT operator-(const FpT& x, const FpT& y) { FpT z; sub(z, x, y); return z; }
inline friend FpT operator*(const FpT& x, const FpT& y) { FpT z; mul(z, x, y); return z; }
inline friend FpT operator/(const FpT& x, const FpT& y) { FpT z; div(z, x, y); return z; }
FpT& operator+=(const FpT& x) { add(*this, *this, x); return *this; }
FpT& operator-=(const FpT& x) { sub(*this, *this, x); return *this; }
FpT& operator*=(const FpT& x) { mul(*this, *this, x); return *this; }
FpT& operator/=(const FpT& x) { div(*this, *this, x); return *this; }
FpT operator-() const { FpT x; neg(x, *this); return x; }
friend inline std::ostream& operator<<(std::ostream& os, const FpT& self)
{
const std::ios_base::fmtflags f = os.flags();
@ -430,20 +401,6 @@ public:
}
void normalize() {} // dummy method
private:
static inline void powerArray(FpT& z, const FpT& x, const Unit *y, size_t yn, bool isNegative)
{
FpT tmp;
const FpT *px = &x;
if (&z == &x) {
tmp = x;
px = &tmp;
}
z = 1;
fp::powerGeneric(z, *px, y, yn, mul, sqr);
if (isNegative) {
FpT::inv(z, z);
}
}
/*
wrapper function for generic p
add(z, x, y)

@ -0,0 +1,77 @@
#pragma once
/**
@file
@brief operator class
@author MITSUNARI Shigeo(@herumi)
@license modified new BSD license
http://opensource.org/licenses/BSD-3-Clause
*/
#include <mcl/op.hpp>
#include <mcl/util.hpp>
#ifdef _MSC_VER
#ifndef MCL_FORCE_INLINE
#define MCL_FORCE_INLINE __forceinline
#endif
#pragma warning(push)
#pragma warning(disable : 4714)
#else
#ifndef MCL_FORCE_INLINE
#define MCL_FORCE_INLINE __attribute__((always_inline))
#endif
#endif
namespace mcl { namespace fp {
template<class T>
struct Empty {};
/*
T must have add, sub, mul, inv, neg
*/
template<class T, class E = Empty<T> >
struct Operator : E {
template<class S> MCL_FORCE_INLINE T& operator+=(const S& rhs) { T::add(static_cast<T&>(*this), static_cast<const T&>(*this), rhs); return static_cast<T&>(*this); }
template<class S> MCL_FORCE_INLINE T& operator-=(const S& rhs) { T::sub(static_cast<T&>(*this), static_cast<const T&>(*this), rhs); return static_cast<T&>(*this); }
template<class S> friend MCL_FORCE_INLINE T operator+(const T& a, const S& b) { T c; T::add(c, a, b); return c; }
template<class S> friend MCL_FORCE_INLINE T operator-(const T& a, const S& b) { T c; T::sub(c, a, b); return c; }
template<class S> MCL_FORCE_INLINE T& operator*=(const S& rhs) { T::mul(static_cast<T&>(*this), static_cast<const T&>(*this), rhs); return static_cast<T&>(*this); }
template<class S> friend MCL_FORCE_INLINE T operator*(const T& a, const S& b) { T c; T::mul(c, a, b); return c; }
MCL_FORCE_INLINE T& operator/=(const T& rhs) { T c; T::inv(c, rhs); T::mul(static_cast<T&>(*this), static_cast<const T&>(*this), c); return static_cast<T&>(*this); }
friend MCL_FORCE_INLINE void div(const T& z, const T& x, const T& y) { T t; T::inv(t, y); T::mul(z, x, t); }
friend MCL_FORCE_INLINE T operator/(const T& a, const T& b) { T c; T::inv(c, b); T::mul(c, c, a); return c; }
MCL_FORCE_INLINE T operator-() const { T c; T::neg(c, static_cast<const T&>(*this)); return c; }
template<class tag2, size_t maxBitSize2, template<class _tag, size_t _maxBitSize> class FpT>
static inline void power(T& z, const T& x, const FpT<tag2, maxBitSize2>& y)
{
fp::Block b;
y.getBlock(b);
powerArray(z, x, b.p, b.n, false);
}
static inline void power(T& z, const T& x, int y)
{
const Unit u = abs(y);
powerArray(z, x, &u, 1, y < 0);
}
static inline void power(T& z, const T& x, const mpz_class& y)
{
powerArray(z, x, Gmp::getUnit(y), abs(y.get_mpz_t()->_mp_size), y < 0);
}
private:
static inline void powerArray(T& z, const T& x, const Unit *y, size_t yn, bool isNegative)
{
T tmp;
const T *px = &x;
if (&z == &x) {
tmp = x;
px = &tmp;
}
z = 1;
fp::powerGeneric(z, *px, y, yn, T::mul, T::sqr);
if (isNegative) {
T::inv(z, z);
}
}
};
} } // mcl::fp

@ -14,17 +14,6 @@
#pragma warning(disable : 4456)
#pragma warning(disable : 4459)
#endif
#ifdef _MSC_VER
#ifndef MCL_FORCE_INLINE
#define MCL_FORCE_INLINE __forceinline
#endif
#pragma warning(push)
#pragma warning(disable : 4714)
#else
#ifndef MCL_FORCE_INLINE
#define MCL_FORCE_INLINE __attribute__((always_inline))
#endif
#endif
namespace mcl { namespace fp {
@ -267,26 +256,6 @@ void powerGeneric(G& out, const G& x, const T *y, size_t n, void mul(G&, const G
#endif
}
template<class T>
struct Empty {};
/*
T must have add, sub, mul, inv, neg
*/
template<class T, class E = Empty<T> >
struct Operator : E {
template<class S> MCL_FORCE_INLINE T& operator+=(const S& rhs) { T::add(static_cast<T&>(*this), static_cast<const T&>(*this), rhs); return static_cast<T&>(*this); }
template<class S> MCL_FORCE_INLINE T& operator-=(const S& rhs) { T::sub(static_cast<T&>(*this), static_cast<const T&>(*this), rhs); return static_cast<T&>(*this); }
template<class S> friend MCL_FORCE_INLINE T operator+(const T& a, const S& b) { T c; T::add(c, a, b); return c; }
template<class S> friend MCL_FORCE_INLINE T operator-(const T& a, const S& b) { T c; T::sub(c, a, b); return c; }
template<class S> MCL_FORCE_INLINE T& operator*=(const S& rhs) { T::mul(static_cast<T&>(*this), static_cast<const T&>(*this), rhs); return static_cast<T&>(*this); }
template<class S> friend MCL_FORCE_INLINE T operator*(const T& a, const S& b) { T c; T::mul(c, a, b); return c; }
MCL_FORCE_INLINE T& operator/=(const T& rhs) { T c; T::inv(c, rhs); T::mul(static_cast<T&>(*this), static_cast<const T&>(*this), c); return static_cast<T&>(*this); }
friend MCL_FORCE_INLINE void div(const T& z, const T& x, const T& y) { T t; T::inv(t, y); T::mul(z, x, t); }
friend MCL_FORCE_INLINE T operator/(const T& a, const T& b) { T c; T::inv(c, b); T::mul(c, c, a); return c; }
MCL_FORCE_INLINE T operator-() const { T c; T::neg(c, static_cast<const T&>(*this)); return c; }
};
} } // mcl::fp
#ifdef _MSC_VER

Loading…
Cancel
Save