10 #ifndef EIGEN_CXX11_TENSOR_TENSOR_UINT128_H 11 #define EIGEN_CXX11_TENSOR_TENSOR_UINT128_H 19 static const uint64_t value = n;
20 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
operator uint64_t()
const {
return n; }
22 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE static_val() { }
25 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE static_val(
const T& v) {
26 EIGEN_UNUSED_VARIABLE(v);
32 template <
typename HIGH = u
int64_t,
typename LOW = u
int64_t>
38 template<
typename OTHER_HIGH,
typename OTHER_LOW>
39 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
40 TensorUInt128(
const TensorUInt128<OTHER_HIGH, OTHER_LOW>& other) : high(other.high), low(other.low) {
41 EIGEN_STATIC_ASSERT(
sizeof(OTHER_HIGH) <=
sizeof(HIGH), YOU_MADE_A_PROGRAMMING_MISTAKE);
42 EIGEN_STATIC_ASSERT(
sizeof(OTHER_LOW) <=
sizeof(LOW), YOU_MADE_A_PROGRAMMING_MISTAKE);
45 template<
typename OTHER_HIGH,
typename OTHER_LOW>
46 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
47 TensorUInt128& operator = (
const TensorUInt128<OTHER_HIGH, OTHER_LOW>& other) {
48 EIGEN_STATIC_ASSERT(
sizeof(OTHER_HIGH) <=
sizeof(HIGH), YOU_MADE_A_PROGRAMMING_MISTAKE);
49 EIGEN_STATIC_ASSERT(
sizeof(OTHER_LOW) <=
sizeof(LOW), YOU_MADE_A_PROGRAMMING_MISTAKE);
56 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
57 explicit TensorUInt128(
const T& x) : high(0), low(x) {
58 eigen_assert((
static_cast<typename conditional<sizeof(T) == 8, uint64_t, uint32_t>::type
>(x) <= NumTraits<uint64_t>::highest()));
62 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
63 TensorUInt128(HIGH y, LOW x) : high(y), low(x) { }
65 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
operator LOW()
const {
68 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE LOW lower()
const {
71 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE HIGH upper()
const {
77 template <
typename HL,
typename LL,
typename HR,
typename LR>
78 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
79 bool operator == (
const TensorUInt128<HL, LL>& lhs,
const TensorUInt128<HR, LR>& rhs)
81 return (lhs.high == rhs.high) & (lhs.low == rhs.low);
84 template <
typename HL,
typename LL,
typename HR,
typename LR>
85 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
86 bool operator != (
const TensorUInt128<HL, LL>& lhs,
const TensorUInt128<HR, LR>& rhs)
88 return (lhs.high != rhs.high) | (lhs.low != rhs.low);
91 template <
typename HL,
typename LL,
typename HR,
typename LR>
92 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
93 bool operator >= (
const TensorUInt128<HL, LL>& lhs,
const TensorUInt128<HR, LR>& rhs)
95 if (lhs.high != rhs.high) {
96 return lhs.high > rhs.high;
98 return lhs.low >= rhs.low;
101 template <
typename HL,
typename LL,
typename HR,
typename LR>
102 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
103 bool operator < (const TensorUInt128<HL, LL>& lhs,
const TensorUInt128<HR, LR>& rhs)
105 if (lhs.high != rhs.high) {
106 return lhs.high < rhs.high;
108 return lhs.low < rhs.low;
111 template <
typename HL,
typename LL,
typename HR,
typename LR>
112 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
113 TensorUInt128<uint64_t, uint64_t> operator + (
const TensorUInt128<HL, LL>& lhs,
const TensorUInt128<HR, LR>& rhs)
115 TensorUInt128<uint64_t, uint64_t> result(lhs.high + rhs.high, lhs.low + rhs.low);
116 if (result.low < rhs.low) {
122 template <
typename HL,
typename LL,
typename HR,
typename LR>
123 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
124 TensorUInt128<uint64_t, uint64_t> operator - (
const TensorUInt128<HL, LL>& lhs,
const TensorUInt128<HR, LR>& rhs)
126 TensorUInt128<uint64_t, uint64_t> result(lhs.high - rhs.high, lhs.low - rhs.low);
127 if (result.low > lhs.low) {
134 template <
typename HL,
typename LL,
typename HR,
typename LR>
135 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
136 TensorUInt128<uint64_t, uint64_t>
operator * (
const TensorUInt128<HL, LL>& lhs,
const TensorUInt128<HR, LR>& rhs)
149 const uint64_t LOW = 0x00000000FFFFFFFFLL;
150 const uint64_t HIGH = 0xFFFFFFFF00000000LL;
152 uint64_t d = lhs.low & LOW;
153 uint64_t c = (lhs.low & HIGH) >> 32LL;
154 uint64_t b = lhs.high & LOW;
155 uint64_t a = (lhs.high & HIGH) >> 32LL;
157 uint64_t h = rhs.low & LOW;
158 uint64_t g = (rhs.low & HIGH) >> 32LL;
159 uint64_t f = rhs.high & LOW;
160 uint64_t e = (rhs.high & HIGH) >> 32LL;
163 uint64_t acc = d * h;
164 uint64_t low = acc & LOW;
168 uint64_t acc2 = acc + c * h;
176 low |= (acc << 32LL);
180 acc2 = (acc >> 32LL) | (carry << 32LL);
195 uint64_t high = acc & LOW;
198 acc2 = (acc >> 32LL) | (carry << 32LL);
204 high |= (acc2 << 32LL);
206 return TensorUInt128<uint64_t, uint64_t>(high, low);
209 template <
typename HL,
typename LL,
typename HR,
typename LR>
210 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
211 TensorUInt128<uint64_t, uint64_t> operator / (
const TensorUInt128<HL, LL>& lhs,
const TensorUInt128<HR, LR>& rhs)
213 if (rhs == TensorUInt128<static_val<0>, static_val<1> >(1)) {
214 return TensorUInt128<uint64_t, uint64_t>(lhs.high, lhs.low);
215 }
else if (lhs < rhs) {
216 return TensorUInt128<uint64_t, uint64_t>(0);
219 TensorUInt128<uint64_t, uint64_t> power2(1);
220 TensorUInt128<uint64_t, uint64_t> d(rhs);
221 TensorUInt128<uint64_t, uint64_t> tmp(lhs - d);
225 power2 = power2 + power2;
228 tmp = TensorUInt128<uint64_t, uint64_t>(lhs.high, lhs.low);
229 TensorUInt128<uint64_t, uint64_t> result(0);
230 while (power2 != TensorUInt128<static_val<0>, static_val<0> >(0)) {
233 result = result + power2;
236 power2 = TensorUInt128<uint64_t, uint64_t>(power2.high >> 1, (power2.low >> 1) | (power2.high << 63));
237 d = TensorUInt128<uint64_t, uint64_t>(d.high >> 1, (d.low >> 1) | (d.high << 63));
249 #endif // EIGEN_CXX11_TENSOR_TENSOR_UINT128_H Namespace containing all symbols from the Eigen library.
const Product< SparseDerived, PermDerived, AliasFreeProduct > operator*(const SparseMatrixBase< SparseDerived > &matrix, const PermutationBase< PermDerived > &perm)