// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2015 Benoit Steiner <benoit.steiner.goog@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.

#ifndef EIGEN_CXX11_TENSOR_TENSOR_UINT128_H
#define EIGEN_CXX11_TENSOR_TENSOR_UINT128_H

namespace Eigen {
namespace internal {


template <uint64_t n>
struct static_val {
  static const uint64_t value = n;
  EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE operator uint64_t() const { return n; }

  EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE static_val() { }

  template <typename T>
  EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE static_val(const T& v) {
    eigen_assert(v == n);
  }
};


template <typename HIGH = uint64_t, typename LOW = uint64_t>
struct TensorUInt128
{
  HIGH high;
  LOW low;

  template<typename OTHER_HIGH, typename OTHER_LOW>
  EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
  TensorUInt128(const TensorUInt128<OTHER_HIGH, OTHER_LOW>& other) : high(other.high), low(other.low) {
    EIGEN_STATIC_ASSERT(sizeof(OTHER_HIGH) <= sizeof(HIGH), YOU_MADE_A_PROGRAMMING_MISTAKE);
    EIGEN_STATIC_ASSERT(sizeof(OTHER_LOW) <= sizeof(LOW), YOU_MADE_A_PROGRAMMING_MISTAKE);
  }

  template<typename OTHER_HIGH, typename OTHER_LOW>
  EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
  TensorUInt128& operator = (const TensorUInt128<OTHER_HIGH, OTHER_LOW>& other) {
    EIGEN_STATIC_ASSERT(sizeof(OTHER_HIGH) <= sizeof(HIGH), YOU_MADE_A_PROGRAMMING_MISTAKE);
    EIGEN_STATIC_ASSERT(sizeof(OTHER_LOW) <= sizeof(LOW), YOU_MADE_A_PROGRAMMING_MISTAKE);
    high = other.high;
    low = other.low;
    return *this;
  }

  template<typename T>
  EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
  explicit TensorUInt128(const T& x) : high(0), low(x) {
    eigen_assert((static_cast<typename conditional<sizeof(T) == 8, uint64_t, uint32_t>::type>(x) <= NumTraits<uint64_t>::highest()));
    eigen_assert(x >= 0);
  }

  EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
  TensorUInt128(HIGH y, LOW x) : high(y), low(x) { }

  EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE operator LOW() const {
    return low;
  }
  EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE LOW lower() const {
    return low;
  }
  EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE HIGH upper() const {
    return high;
  }
};


template <typename HL, typename LL, typename HR, typename LR>
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
bool operator == (const TensorUInt128<HL, LL>& lhs, const TensorUInt128<HR, LR>& rhs)
{
  return (lhs.high == rhs.high) & (lhs.low == rhs.low);
}

template <typename HL, typename LL, typename HR, typename LR>
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
bool operator != (const TensorUInt128<HL, LL>& lhs, const TensorUInt128<HR, LR>& rhs)
{
  return (lhs.high != rhs.high) | (lhs.low != rhs.low);
}

template <typename HL, typename LL, typename HR, typename LR>
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
bool operator >= (const TensorUInt128<HL, LL>& lhs, const TensorUInt128<HR, LR>& rhs)
{
  if (lhs.high != rhs.high) {
    return lhs.high > rhs.high;
  }
  return lhs.low >= rhs.low;
}

template <typename HL, typename LL, typename HR, typename LR>
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
bool operator < (const TensorUInt128<HL, LL>& lhs, const TensorUInt128<HR, LR>& rhs)
{
  if (lhs.high != rhs.high) {
    return lhs.high < rhs.high;
  }
  return lhs.low < rhs.low;
}

template <typename HL, typename LL, typename HR, typename LR>
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
TensorUInt128<uint64_t, uint64_t> operator + (const TensorUInt128<HL, LL>& lhs, const TensorUInt128<HR, LR>& rhs)
{
  TensorUInt128<uint64_t, uint64_t> result(lhs.high + rhs.high, lhs.low + rhs.low);
  if (result.low < rhs.low) {
    result.high += 1;
  }
  return result;
}

template <typename HL, typename LL, typename HR, typename LR>
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
TensorUInt128<uint64_t, uint64_t> operator - (const TensorUInt128<HL, LL>& lhs, const TensorUInt128<HR, LR>& rhs)
{
  TensorUInt128<uint64_t, uint64_t> result(lhs.high - rhs.high, lhs.low - rhs.low);
  if (result.low > lhs.low) {
    result.high -= 1;
  }
  return result;
}


template <typename HL, typename LL, typename HR, typename LR>
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
TensorUInt128<uint64_t, uint64_t> operator * (const TensorUInt128<HL, LL>& lhs, const TensorUInt128<HR, LR>& rhs)
{
  // Split each 128-bit integer into 4 32-bit integers, and then do the
  // multiplications by hand as follow:
  //   lhs      a  b  c  d
  //   rhs      e  f  g  h
  //           -----------
  //           ah bh ch dh
  //           bg cg dg
  //           cf df
  //           de
  // The result is stored in 2 64bit integers, high and low.

  const uint64_t LOW = 0x00000000FFFFFFFFLL;
  const uint64_t HIGH = 0xFFFFFFFF00000000LL;

  uint64_t d = lhs.low & LOW;
  uint64_t c = (lhs.low & HIGH) >> 32LL;
  uint64_t b = lhs.high & LOW;
  uint64_t a = (lhs.high & HIGH) >> 32LL;

  uint64_t h = rhs.low & LOW;
  uint64_t g = (rhs.low & HIGH) >> 32LL;
  uint64_t f = rhs.high & LOW;
  uint64_t e = (rhs.high & HIGH) >> 32LL;

  // Compute the low 32 bits of low
  uint64_t acc = d * h;
  uint64_t low = acc & LOW;
  //  Compute the high 32 bits of low. Add a carry every time we wrap around
  acc >>= 32LL;
  uint64_t carry = 0;
  uint64_t acc2 = acc + c * h;
  if (acc2 < acc) {
    carry++;
  }
  acc = acc2 + d * g;
  if (acc < acc2) {
    carry++;
  }
  low |= (acc << 32LL);

  // Carry forward the high bits of acc to initiate the computation of the
  // low 32 bits of high
  acc2 = (acc >> 32LL) | (carry << 32LL);
  carry = 0;

  acc = acc2 + b * h;
  if (acc < acc2) {
    carry++;
  }
  acc2 = acc + c * g;
  if (acc2 < acc) {
    carry++;
  }
  acc = acc2 + d * f;
  if (acc < acc2) {
    carry++;
  }
  uint64_t high = acc & LOW;

  // Start to compute the high 32 bits of high.
  acc2 = (acc >> 32LL) | (carry << 32LL);

  acc = acc2 + a * h;
  acc2 = acc + b * g;
  acc = acc2 + c * f;
  acc2 = acc + d * e;
  high |= (acc2 << 32LL);

  return TensorUInt128<uint64_t, uint64_t>(high, low);
}

template <typename HL, typename LL, typename HR, typename LR>
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
TensorUInt128<uint64_t, uint64_t> operator / (const TensorUInt128<HL, LL>& lhs, const TensorUInt128<HR, LR>& rhs)
{
  if (rhs == TensorUInt128<static_val<0>, static_val<1> >(1)) {
    return TensorUInt128<uint64_t, uint64_t>(lhs.high, lhs.low);
  } else if (lhs < rhs) {
    return TensorUInt128<uint64_t, uint64_t>(0);
  } else {
    // calculate the biggest power of 2 times rhs that's less than or equal to lhs
    TensorUInt128<uint64_t, uint64_t> power2(1);
    TensorUInt128<uint64_t, uint64_t> d(rhs);
    TensorUInt128<uint64_t, uint64_t> tmp(lhs - d);
    while (lhs >= d) {
      tmp = tmp - d;
      d = d + d;
      power2 = power2 + power2;
    }

    tmp = TensorUInt128<uint64_t, uint64_t>(lhs.high, lhs.low);
    TensorUInt128<uint64_t, uint64_t> result(0);
    while (power2 != TensorUInt128<static_val<0>, static_val<0> >(0)) {
      if (tmp >= d) {
        tmp = tmp - d;
        result = result + power2;
      }
      // Shift right
      power2 = TensorUInt128<uint64_t, uint64_t>(power2.high >> 1, (power2.low >> 1) | (power2.high << 63));
      d = TensorUInt128<uint64_t, uint64_t>(d.high >> 1, (d.low >> 1) | (d.high << 63));
    }

    return result;
  }
}


}  // namespace internal
}  // namespace Eigen


#endif  // EIGEN_CXX11_TENSOR_TENSOR_UINT128_H
