// Copyright 2018 The Fuchsia Authors
//
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT
#pragma once

//
// Fuchsia Fixed-point Library (FFL):
//
// An efficient header-only multi-precision fixed point math library with well-
// defined rounding.
//

#include <type_traits>

#include <ffl/expression.h>
#include <ffl/fixed_format.h>
#include <ffl/utility.h>

namespace ffl {

// Represents a fixed-point value using the given integer base type |Integer|
// and the given number of fractional bits |FractionalBits|. This type supports
// standard arithmetic operations and comparisons between the same type, fixed-
// point types with different precision/resolution, and integer values.
//
// Arithmetic operations are not immediately computed. Instead, arithmetic
// expressions involving fixed-point types are assembled into intermediate
// expression trees (via the Expression template type) that capture operands and
// order of operations. The value of the expression tree is evaluated when it is
// assigned to a fixed-point variable. Using this approach the precision and
// resolution of intermediate values are selected at compile time, based on the
// final precision and resolution of the destination variable.
//
// See README.md for a more detailed discussion of fixed-point arithmetic,
// rounding, precision, and resolution in this library.
//
template <typename Integer, size_t FractionalBits>
class Fixed {
public:
    // Alias of the FixedFormat type describing traits and low-level operations
    // on the fixed-point representation of this type.
    using Format = FixedFormat<Integer, FractionalBits>;

    // Fixed is default constructible without a default value, which is the same
    // as for plain integer types. This is permitted in constexpr contexts as
    // long as the underling integer member |value_| is initialized before use.
    constexpr Fixed() = default;

    // Fixed is copy constructible and assignable.
    constexpr Fixed(const Fixed&) = default;
    constexpr Fixed& operator=(const Fixed&) = default;

    // Explicit conversion from an integer value. The value is saturated to fit
    // within the integer precision defined by Format::IntegerBits.
    explicit constexpr Fixed(Integer value)
        : Fixed{ToExpression<Integer>{value}} {}

    // Implicit conversion from an intermediate expression. The value is rounded
    // and saturated to fit within the precision and resolution of this type, if
    // necessary.
    template <Operation Op, typename... Args>
    constexpr Fixed(Expression<Op, Args...> expression)
        : value_{Format::Saturate(Format::Convert(expression.Evaluate(Format{})))} {}

    // Assignment from an intermediate expression. The value is rounded and
    // saturated to fit within the precision and resolution of this type, if
    // necessary.
    template <Operation Op, typename... Args>
    constexpr Fixed& operator=(Expression<Op, Args...> expression) {
        return *this = Fixed{expression};
    }

    // Implicit conversion from an intermediate value of the same format.
    constexpr Fixed(Value<Format> value)
        : value_{Format::Saturate(value)} {}

    // Assignment from an intermediate value of the same format.
    constexpr Fixed& operator=(Value<Format> value) {
        return *this = Fixed{value};
    }

    // Returns the raw fixed-point value as the underling integer type.
    constexpr Integer raw_value() const { return value_; }

    // Returns the fixed-point value as an intermediate value type.
    constexpr Value<Format> value() const { return Value<Format>{value_}; }

    // Returns the closest integer value greater-than or equal-to this fixed-
    // point value.
    constexpr Integer Ceiling() const {
        using Intermediate = typename Format::Intermediate;
        const Intermediate value = value_;
        const Intermediate power = Format::Power;
        const Intermediate saturated_value = Format::Saturate(value + Format::FractionalMask);
        return static_cast<Integer>(saturated_value / power);
    }

    // Returns the closest integer value less-than or equal-to this fixed-point
    // value.
    constexpr Integer Floor() const {
        using Intermediate = typename Format::Intermediate;
        const Intermediate power = Format::Power;
        const Intermediate value = value_ & Format::IntegralMask;
        return static_cast<Integer>(value / power);
    }

    // Returns the rounded value of this fixed-point value as an integer.
    constexpr Integer Round() const {
        using Intermediate = typename Format::Intermediate;
        const Intermediate power = Format::Power;
        const Intermediate rounded_value = Format::Round(value_);
        return Format::Saturate(static_cast<Intermediate>(rounded_value / power));
    }

    // Returns the fractional component of this fixed-point value.
    constexpr Fixed Fraction() const {
        return *this - Fixed{Floor()};
    }

    // Relational operators for same-typed values.
    constexpr bool operator<(Fixed other) const { return value_ < other.value_; }
    constexpr bool operator>(Fixed other) const { return value_ > other.value_; }
    constexpr bool operator<=(Fixed other) const { return value_ <= other.value_; }
    constexpr bool operator>=(Fixed other) const { return value_ >= other.value_; }
    constexpr bool operator==(Fixed other) const { return value_ == other.value_; }
    constexpr bool operator!=(Fixed other) const { return value_ != other.value_; }

    // Compound assignment operators.
    template <typename T, typename Enabled = EnableIfUnaryExpression<T>>
    constexpr Fixed& operator+=(T expression) {
        *this = *this + expression;
        return *this;
    }
    template <typename T, typename Enabled = EnableIfUnaryExpression<T>>
    constexpr Fixed& operator-=(T expression) {
        *this = *this - expression;
        return *this;
    }
    template <typename T, typename Enabled = EnableIfUnaryExpression<T>>
    constexpr Fixed& operator*=(T expression) {
        *this = *this * expression;
        return *this;
    }
    template <typename T, typename Enabled = EnableIfUnaryExpression<T>>
    constexpr Fixed& operator/=(T expression) {
        *this = *this / expression;
        return *this;
    }

private:
    Integer value_;
};

// Utility to round an expression to the given Integer.
template <typename Integer, typename T, typename Enabled = EnableIfUnaryExpression<T>>
inline constexpr auto Round(T expression) {
    const Fixed<Integer, 0> value{ToExpression<T>{expression}};
    return value.Round();
}

// Utility to create an Expression node from an integer value.
template <typename Integer, typename Enabled = std::enable_if_t<std::is_integral_v<Integer>>>
inline constexpr auto FromInteger(Integer value) {
    return ToExpression<Integer>{value};
}

// Utility to create an Expression node from an integer ratio. May be used to
// initialize a Fixed variable from a ratio.
template <typename Integer, typename Enabled = std::enable_if_t<std::is_integral_v<Integer>>>
inline constexpr auto FromRatio(Integer numerator, Integer denominator) {
    return DivisionExpression<Integer, Integer>{numerator, denominator};
}

// Utility to coerce an expression to the given resolution.
template <size_t FractionalBits, typename T>
inline constexpr auto ToResolution(T expression) {
    return ResolutionExpression<FractionalBits, T>{Init{}, expression};
}

// Utility to create a value Expression from a raw integer value already in the
// fixed-point format with the given number of fractional bits.
template <size_t FractionalBits, typename Integer>
inline constexpr auto FromRaw(Integer value) {
    return ValueExpression<Integer, FractionalBits>{value};
}

// Relational operators. Note that relational operators convert to the format
// with the least precision before comparison. This means that comparing with
// an integer directly is different than comparing with an integer converted to
// the same fixed-point type, due to rounding in the former.
//
// For example,
//
//  constexpr Fixed<int32_t, 1> value{FromRatio(1, 2)};
//  constexpr bool compare_a = value > 0;
//  constexpr bool compare_b = value > Fixed<int32_t, 1>{0};
//
//  static_assert(compare_a != compare_b, "");
//
// In the former case, compare_a expresses whether the value rounds to greater
// than zero. Whereas, in the latter case, compare_b expresses whether the value
// is greater than zero, even fractionally. Because this library uses convergent
// rounding these comparisons do not always yield the same result.
//
template <typename Left, typename Right,
          typename Enabled = EnableIfComparisonExpression<Left, Right>>
inline constexpr bool operator<(Left left, Right right) {
    using Traits = ComparisonTraits<Left, Right>;
    return Traits::Left(left) < Traits::Right(right);
}
template <typename Left, typename Right,
          typename Enabled = EnableIfComparisonExpression<Left, Right>>
inline constexpr bool operator>(Left left, Right right) {
    using Traits = ComparisonTraits<Left, Right>;
    return Traits::Left(left) > Traits::Right(right);
}
template <typename Left, typename Right,
          typename Enabled = EnableIfComparisonExpression<Left, Right>>
inline constexpr bool operator<=(Left left, Right right) {
    using Traits = ComparisonTraits<Left, Right>;
    return Traits::Left(left) <= Traits::Right(right);
}
template <typename Left, typename Right,
          typename Enabled = EnableIfComparisonExpression<Left, Right>>
inline constexpr bool operator>=(Left left, Right right) {
    using Traits = ComparisonTraits<Left, Right>;
    return Traits::Left(left) >= Traits::Right(right);
}
template <typename Left, typename Right,
          typename Enabled = EnableIfComparisonExpression<Left, Right>>
inline constexpr bool operator==(Left left, Right right) {
    using Traits = ComparisonTraits<Left, Right>;
    return Traits::Left(left) == Traits::Right(right);
}
template <typename Left, typename Right,
          typename Enabled = EnableIfComparisonExpression<Left, Right>>
inline constexpr bool operator!=(Left left, Right right) {
    using Traits = ComparisonTraits<Left, Right>;
    return Traits::Left(left) != Traits::Right(right);
}

// Arithmetic operators. These operators accept any combination of Fixed,
// integer, and Expression (excluding integer/integer which is handled by the
// language). The return type and value captures the operation and operands as
// an Expression for later evaluation. Evaluation is performed when the
// Expression tree is assigned to a Fixed variable. This can be composed in
// multiple stages and assignments.
//
// Example:
//
//     const int32_t value = ...;
//     cosnt int32_t offset = ...;
//
//     const auto quotient = FromRatio(value, 3);
//     const Fixed<int32_t, 1> low_precision = quotient;
//     const Fixed<int64_t, 10> high_precision = quotient;
//
//     const auto with_offset = quotient + ToResolution<10>(offset);
//     const Fixed<int64_t, 10> high_precision_with_offset = with_offset;
//
template <typename Left, typename Right,
          typename Enabled = EnableIfBinaryExpression<Left, Right>>
inline constexpr auto operator+(Left left, Right right) {
    return AdditionExpression<Left, Right>{left, right};
}
template <typename T, typename Enabled = EnableIfUnaryExpression<T>>
inline constexpr auto operator-(T value) {
    return NegationExpression<T>{Init{}, value};
}
template <typename Left, typename Right,
          typename Enabled = EnableIfBinaryExpression<Left, Right>>
inline constexpr auto operator-(Left left, Right right) {
    return SubtractionExpression<Left, Right>{left, right};
}
template <typename Left, typename Right,
          typename Enabled = EnableIfBinaryExpression<Left, Right>>
inline constexpr auto operator*(Left left, Right right) {
    return MultiplicationExpression<Left, Right>{left, right};
}
template <typename Left, typename Right,
          typename Enabled = EnableIfBinaryExpression<Left, Right>>
inline constexpr auto operator/(Left left, Right right) {
    return DivisionExpression<Left, Right>{left, right};
}

} // namespace ffl
