/*
 * Copyright (c) 2017 ARM Limited.
 *
 * SPDX-License-Identifier: MIT
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to
 * deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
#ifndef __ARM_COMPUTE_TEST_VALIDATION_FIXEDPOINT_H__
#define __ARM_COMPUTE_TEST_VALIDATION_FIXEDPOINT_H__

#include "Utils.h"

#include <cassert>
#include <cstdint>
#include <cstdlib>
#include <limits>
#include <string>
#include <type_traits>

namespace arm_compute
{
namespace test
{
namespace fixed_point_arithmetic
{
namespace detail
{
// Forward declare structs
struct functions;
template <typename T>
struct constant_expr;
}

/** Fixed point traits */
namespace traits
{
// Promote types
// *INDENT-OFF*
// clang-format off
template <typename T> struct promote { };
template <> struct promote<uint8_t> { using type = uint16_t; };
template <> struct promote<int8_t> { using type = int16_t; };
template <> struct promote<uint16_t> { using type = uint32_t; };
template <> struct promote<int16_t> { using type = int32_t; };
template <> struct promote<uint32_t> { using type = uint64_t; };
template <> struct promote<int32_t> { using type = int64_t; };
template <> struct promote<uint64_t> { using type = uint64_t; };
template <> struct promote<int64_t> { using type = int64_t; };
// clang-format on
// *INDENT-ON*
}

/** Strongly typed enum class representing the overflow policy */
enum class OverflowPolicy
{
    WRAP,    /**< Wrap policy */
    SATURATE /**< Saturate policy */
};
/** Strongly typed enum class representing the rounding policy */
enum class RoundingPolicy
{
    TO_ZERO,        /**< Round to zero policy */
    TO_NEAREST_EVEN /**< Round to nearest even policy */
};

/** Arbitrary fixed-point arithmetic class */
template <typename T>
class fixed_point
{
public:
    // Static Checks
    static_assert(std::is_integral<T>::value, "Type is not an integer");

    // Friends
    friend struct detail::functions;
    friend struct detail::constant_expr<T>;

    /** Constructor (from different fixed point type)
     *
     * @param[in] val Fixed point
     * @param[in] p   Fixed point precision
     */
    template <typename U>
    fixed_point(fixed_point<U> val, uint8_t p)
        : _value(0), _fixed_point_position(p)
    {
        assert(p > 0 && p < std::numeric_limits<T>::digits);
        T v = 0;

        if(std::numeric_limits<T>::digits < std::numeric_limits<U>::digits)
        {
            val.rescale(p);
            v = detail::constant_expr<T>::saturate_cast(val.raw());
        }
        else
        {
            auto v_cast = static_cast<fixed_point<T>>(val);
            v_cast.rescale(p);
            v = v_cast.raw();
        }
        _value = static_cast<T>(v);
    }
    /** Constructor (from integer)
     *
     * @param[in] val    Integer value to be represented as fixed point
     * @param[in] p      Fixed point precision
     * @param[in] is_raw If true val is a raw fixed point value else an integer
     */
    template <typename U, typename = typename std::enable_if<std::is_integral<U>::value>::type>
    fixed_point(U val, uint8_t p, bool is_raw = false)
        : _value(val << p), _fixed_point_position(p)
    {
        if(is_raw)
        {
            _value = val;
        }
    }
    /** Constructor (from float)
     *
     * @param[in] val Float value to be represented as fixed point
     * @param[in] p   Fixed point precision
     */
    fixed_point(float val, uint8_t p)
        : _value(detail::constant_expr<T>::to_fixed(val, p)), _fixed_point_position(p)
    {
        assert(p > 0 && p < std::numeric_limits<T>::digits);
    }
    /** Constructor (from float string)
     *
     * @param[in] str Float string to be represented as fixed point
     * @param[in] p   Fixed point precision
     */
    fixed_point(std::string str, uint8_t p)
        : _value(detail::constant_expr<T>::to_fixed(arm_compute::test::cpp11::stof(str), p)), _fixed_point_position(p)
    {
        assert(p > 0 && p < std::numeric_limits<T>::digits);
    }
    /** Default copy constructor */
    fixed_point &operator=(const fixed_point &) = default;
    /** Default move constructor */
    fixed_point &operator=(fixed_point &&) = default;
    /** Default copy assignment operator */
    fixed_point(const fixed_point &) = default;
    /** Default move assignment operator */
    fixed_point(fixed_point &&) = default;

    /** Float conversion operator
     *
     * @return Float representation of fixed point
     */
    operator float() const
    {
        return detail::constant_expr<T>::to_float(_value, _fixed_point_position);
    }
    /** Integer conversion operator
     *
     * @return Integer representation of fixed point
     */
    template <typename U, typename = typename std::enable_if<std::is_integral<T>::value>::type>
    operator U() const
    {
        return detail::constant_expr<T>::to_int(_value, _fixed_point_position);
    }
    /** Convert to different fixed point of different type but same precision
     *
     * @note Down-conversion might fail.
     */
    template <typename U>
    operator fixed_point<U>()
    {
        U val = static_cast<U>(_value);
        if(std::numeric_limits<U>::digits < std::numeric_limits<T>::digits)
        {
            val = detail::constant_expr<U>::saturate_cast(_value);
        }
        return fixed_point<U>(val, _fixed_point_position, true);
    }

    /** Arithmetic += assignment operator
     *
     * @param[in] rhs Fixed point operand
     *
     * @return Reference to this fixed point
     */
    template <typename U>
    fixed_point<T> &operator+=(const fixed_point<U> &rhs)
    {
        fixed_point<T> val(rhs, _fixed_point_position);
        _value += val.raw();
        return *this;
    }
    /** Arithmetic -= assignment operator
     *
     * @param[in] rhs Fixed point operand
     *
     * @return Reference to this fixed point
     */
    template <typename U>
    fixed_point<T> &operator-=(const fixed_point<U> &rhs)
    {
        fixed_point<T> val(rhs, _fixed_point_position);
        _value -= val.raw();
        return *this;
    }

    /** Raw value accessor
     *
     * @return Raw fixed point value
     */
    T raw() const
    {
        return _value;
    }
    /** Precision accessor
     *
     * @return Precision of fixed point
     */
    uint8_t precision() const
    {
        return _fixed_point_position;
    }
    /** Rescale a fixed point to a new precision
     *
     * @param[in] p New fixed point precision
     */
    void rescale(uint8_t p)
    {
        assert(p > 0 && p < std::numeric_limits<T>::digits);

        if(p > _fixed_point_position)
        {
            _value <<= (p - _fixed_point_position);
        }
        else if(p < _fixed_point_position)
        {
            _value >>= (_fixed_point_position - p);
        }

        _fixed_point_position = p;
    }

private:
    T       _value;                /**< Fixed point raw value */
    uint8_t _fixed_point_position; /**< Fixed point precision */
};

namespace detail
{
/** Count the number of leading zero bits in the given value.
 *
 * @param[in] value Input value.
 *
 * @return Number of leading zero bits.
 */
template <typename T>
constexpr int clz(T value)
{
    using unsigned_T = typename std::make_unsigned<T>::type;
    // __builtin_clz is available for int. Need to correct reported number to
    // match the original type.
    return __builtin_clz(value) - (32 - std::numeric_limits<unsigned_T>::digits);
}

template <typename T>
struct constant_expr
{
    /** Calculate representation of 1 in fixed point given a fixed point precision
     *
     * @param[in] p Fixed point precision
     *
     * @return Representation of value 1 in fixed point.
     */
    static constexpr T fixed_one(uint8_t p)
    {
        return (1 << p);
    }
    /** Calculate fixed point precision step given a fixed point precision
     *
     * @param[in] p Fixed point precision
     *
     * @return Fixed point precision step
     */
    static constexpr float fixed_step(uint8_t p)
    {
        return (1.0f / static_cast<float>(1 << p));
    }

    /** Convert a fixed point value to float given its precision.
     *
     * @param[in] val Fixed point value
     * @param[in] p   Fixed point precision
     *
     * @return Float representation of the fixed point number
     */
    static constexpr float to_float(T val, uint8_t p)
    {
        return static_cast<float>(val * fixed_step(p));
    }
    /** Convert a fixed point value to integer given its precision.
     *
     * @param[in] val Fixed point value
     * @param[in] p   Fixed point precision
     *
     * @return Integer of the fixed point number
     */
    static constexpr T to_int(T val, uint8_t p)
    {
        return val >> p;
    }
    /** Convert a single precision floating point value to a fixed point representation given its precision.
     *
     * @param[in] val Floating point value
     * @param[in] p   Fixed point precision
     *
     * @return The raw fixed point representation
     */
    static constexpr T to_fixed(float val, uint8_t p)
    {
        return static_cast<T>(val * fixed_one(p) + ((val >= 0) ? 0.5 : -0.5));
    }
    /** Clamp value between two ranges
     *
     * @param[in] val Value to clamp
     * @param[in] min Minimum value to clamp to
     * @param[in] max Maximum value to clamp to
     *
     * @return clamped value
     */
    static constexpr T clamp(T val, T min, T max)
    {
        return std::min(std::max(val, min), max);
    }
    /** Saturate given number
     *
     * @param[in] val Value to saturate
     *
     * @return Saturated value
     */
    template <typename U>
    static constexpr T saturate_cast(U val)
    {
        return static_cast<T>(std::min<U>(std::max<U>(val, static_cast<U>(std::numeric_limits<T>::min())), static_cast<U>(std::numeric_limits<T>::max())));
    }
};
struct functions
{
    /** Output stream operator
     *
     * @param[in] s Output stream
     * @param[in] x Fixed point value
     *
     * @return Reference output to updated stream
     */
    template <typename T, typename U, typename traits>
    static std::basic_ostream<T, traits> &write(std::basic_ostream<T, traits> &s, fixed_point<U> &x)
    {
        return s << static_cast<float>(x);
    }
    /** Signbit of a fixed point number.
     *
     * @param[in] x Fixed point number
     *
     * @return True if negative else false.
     */
    template <typename T>
    static bool signbit(fixed_point<T> x)
    {
        return ((x._value >> std::numeric_limits<T>::digits) != 0);
    }
    /** Checks if two fixed point numbers are equal
     *
     * @param[in] x First fixed point operand
     * @param[in] y Second fixed point operand
     *
     * @return True if fixed points are equal else false
     */
    template <typename T>
    static bool isequal(fixed_point<T> x, fixed_point<T> y)
    {
        uint8_t p = std::min(x._fixed_point_position, y._fixed_point_position);
        x.rescale(p);
        y.rescale(p);
        return (x._value == y._value);
    }
    /** Checks if two fixed point number are not equal
     *
     * @param[in] x First fixed point operand
     * @param[in] y Second fixed point operand
     *
     * @return True if fixed points are not equal else false
     */
    template <typename T>
    static bool isnotequal(fixed_point<T> x, fixed_point<T> y)
    {
        return !isequal(x, y);
    }
    /** Checks if one fixed point is greater than the other
     *
     * @param[in] x First fixed point operand
     * @param[in] y Second fixed point operand
     *
     * @return True if fixed point is greater than other
     */
    template <typename T>
    static bool isgreater(fixed_point<T> x, fixed_point<T> y)
    {
        uint8_t p = std::min(x._fixed_point_position, y._fixed_point_position);
        x.rescale(p);
        y.rescale(p);
        return (x._value > y._value);
    }
    /** Checks if one fixed point is greater or equal than the other
     *
     * @param[in] x First fixed point operand
     * @param[in] y Second fixed point operand
     *
     * @return True if fixed point is greater or equal than other
     */
    template <typename T>
    static bool isgreaterequal(fixed_point<T> x, fixed_point<T> y)
    {
        uint8_t p = std::min(x._fixed_point_position, y._fixed_point_position);
        x.rescale(p);
        y.rescale(p);
        return (x._value >= y._value);
    }
    /** Checks if one fixed point is less than the other
     *
     * @param[in] x First fixed point operand
     * @param[in] y Second fixed point operand
     *
     * @return True if fixed point is less than other
     */
    template <typename T>
    static bool isless(fixed_point<T> x, fixed_point<T> y)
    {
        uint8_t p = std::min(x._fixed_point_position, y._fixed_point_position);
        x.rescale(p);
        y.rescale(p);
        return (x._value < y._value);
    }
    /** Checks if one fixed point is less or equal than the other
     *
     * @param[in] x First fixed point operand
     * @param[in] y Second fixed point operand
     *
     * @return True if fixed point is less or equal than other
     */
    template <typename T>
    static bool islessequal(fixed_point<T> x, fixed_point<T> y)
    {
        uint8_t p = std::min(x._fixed_point_position, y._fixed_point_position);
        x.rescale(p);
        y.rescale(p);
        return (x._value <= y._value);
    }
    /** Checks if one fixed point is less or greater than the other
     *
     * @param[in] x First fixed point operand
     * @param[in] y Second fixed point operand
     *
     * @return True if fixed point is less or greater than other
     */
    template <typename T>
    static bool islessgreater(fixed_point<T> x, fixed_point<T> y)
    {
        return isnotequal(x, y);
    }
    /** Clamp fixed point to specific range.
     *
     * @param[in] x   Fixed point operand
     * @param[in] min Minimum value to clamp to
     * @param[in] max Maximum value to clamp to
     *
     * @return Clamped result
     */
    template <typename T>
    static fixed_point<T> clamp(fixed_point<T> x, T min, T max)
    {
        return fixed_point<T>(constant_expr<T>::clamp(x._value, min, max), x._fixed_point_position, true);
    }
    /** Negate number
     *
     * @param[in] x Fixed point operand
     *
     * @return Negated fixed point result
     */
    template <OverflowPolicy OP = OverflowPolicy::SATURATE, typename T>
    static fixed_point<T> negate(fixed_point<T> x)
    {
        using promoted_T = typename traits::promote<T>::type;
        promoted_T val   = -x._value;
        if(OP == OverflowPolicy::SATURATE)
        {
            val = constant_expr<T>::saturate_cast(val);
        }
        return fixed_point<T>(static_cast<T>(val), x._fixed_point_position, true);
    }
    /** Perform addition among two fixed point numbers
     *
     * @param[in] x First fixed point operand
     * @param[in] y Second fixed point operand
     *
     * @return Result fixed point with precision equal to minimum precision of both operands
     */
    template <OverflowPolicy OP = OverflowPolicy::SATURATE, typename T>
    static fixed_point<T> add(fixed_point<T> x, fixed_point<T> y)
    {
        uint8_t p = std::min(x._fixed_point_position, y._fixed_point_position);
        x.rescale(p);
        y.rescale(p);
        if(OP == OverflowPolicy::SATURATE)
        {
            using type = typename traits::promote<T>::type;
            type val   = static_cast<type>(x._value) + static_cast<type>(y._value);
            val        = constant_expr<T>::saturate_cast(val);
            return fixed_point<T>(static_cast<T>(val), p, true);
        }
        else
        {
            return fixed_point<T>(x._value + y._value, p, true);
        }
    }
    /** Perform subtraction among two fixed point numbers
     *
     * @param[in] x First fixed point operand
     * @param[in] y Second fixed point operand
     *
     * @return Result fixed point with precision equal to minimum precision of both operands
     */
    template <OverflowPolicy OP = OverflowPolicy::SATURATE, typename T>
    static fixed_point<T> sub(fixed_point<T> x, fixed_point<T> y)
    {
        uint8_t p = std::min(x._fixed_point_position, y._fixed_point_position);
        x.rescale(p);
        y.rescale(p);
        if(OP == OverflowPolicy::SATURATE)
        {
            using type = typename traits::promote<T>::type;
            type val   = static_cast<type>(x._value) - static_cast<type>(y._value);
            val        = constant_expr<T>::saturate_cast(val);
            return fixed_point<T>(static_cast<T>(val), p, true);
        }
        else
        {
            return fixed_point<T>(x._value - y._value, p, true);
        }
    }
    /** Perform multiplication among two fixed point numbers
     *
     * @param[in] x First fixed point operand
     * @param[in] y Second fixed point operand
     *
     * @return Result fixed point with precision equal to minimum precision of both operands
     */
    template <OverflowPolicy OP = OverflowPolicy::SATURATE, typename T>
    static fixed_point<T> mul(fixed_point<T> x, fixed_point<T> y)
    {
        using promoted_T        = typename traits::promote<T>::type;
        uint8_t    p_min        = std::min(x._fixed_point_position, y._fixed_point_position);
        uint8_t    p_max        = std::max(x._fixed_point_position, y._fixed_point_position);
        promoted_T round_factor = (1 << (p_max - 1));
        promoted_T val          = ((static_cast<promoted_T>(x._value) * static_cast<promoted_T>(y._value)) + round_factor) >> p_max;
        if(OP == OverflowPolicy::SATURATE)
        {
            val = constant_expr<T>::saturate_cast(val);
        }
        return fixed_point<T>(static_cast<T>(val), p_min, true);
    }
    /** Perform division among two fixed point numbers
     *
     * @param[in] x First fixed point operand
     * @param[in] y Second fixed point operand
     *
     * @return Result fixed point with precision equal to minimum precision of both operands
     */
    template <OverflowPolicy OP = OverflowPolicy::SATURATE, typename T>
    static fixed_point<T> div(fixed_point<T> x, fixed_point<T> y)
    {
        using promoted_T = typename traits::promote<T>::type;
        uint8_t    p     = std::min(x._fixed_point_position, y._fixed_point_position);
        promoted_T denom = static_cast<promoted_T>(y._value);
        if(denom != 0)
        {
            promoted_T val = (static_cast<promoted_T>(x._value) << std::max(x._fixed_point_position, y._fixed_point_position)) / denom;
            if(OP == OverflowPolicy::SATURATE)
            {
                val = constant_expr<T>::saturate_cast(val);
            }
            return fixed_point<T>(static_cast<T>(val), p, true);
        }
        else
        {
            T val = (x._value < 0) ? std::numeric_limits<T>::min() : std::numeric_limits<T>::max();
            return fixed_point<T>(val, p, true);
        }
    }
    /** Shift left
     *
     * @param[in] x     Fixed point operand
     * @param[in] shift Shift value
     *
     * @return Shifted value
     */
    template <OverflowPolicy OP = OverflowPolicy::SATURATE, typename T>
    static fixed_point<T> shift_left(fixed_point<T> x, size_t shift)
    {
        using promoted_T = typename traits::promote<T>::type;
        promoted_T val   = static_cast<promoted_T>(x._value) << shift;
        if(OP == OverflowPolicy::SATURATE)
        {
            val = constant_expr<T>::saturate_cast(val);
        }
        return fixed_point<T>(static_cast<T>(val), x._fixed_point_position, true);
    }
    /** Shift right
     *
     * @param[in] x     Fixed point operand
     * @param[in] shift Shift value
     *
     * @return Shifted value
     */
    template <typename T>
    static fixed_point<T> shift_right(fixed_point<T> x, size_t shift)
    {
        return fixed_point<T>(x._value >> shift, x._fixed_point_position, true);
    }
    /** Calculate absolute value
     *
     * @param[in] x Fixed point operand
     *
     * @return Absolute value of operand
     */
    template <typename T>
    static fixed_point<T> abs(fixed_point<T> x)
    {
        using promoted_T = typename traits::promote<T>::type;
        T val            = (x._value < 0) ? constant_expr<T>::saturate_cast(-static_cast<promoted_T>(x._value)) : x._value;
        return fixed_point<T>(val, x._fixed_point_position, true);
    }
    /** Calculate the logarithm of a fixed point number
     *
     * @param[in] x Fixed point operand
     *
     * @return Logarithm value of operand
     */
    template <typename T>
    static fixed_point<T> log(fixed_point<T> x)
    {
        uint8_t p         = x._fixed_point_position;
        auto    const_one = fixed_point<T>(static_cast<T>(1), p);

        // Logarithm of 1 is zero and logarithm of negative values is not defined in R, so return 0.
        // Also, log(x) == -log(1/x) for 0 < x < 1.
        if(isequal(x, const_one) || islessequal(x, fixed_point<T>(static_cast<T>(0), p)))
        {
            return fixed_point<T>(static_cast<T>(0), p, true);
        }
        else if(isless(x, const_one))
        {
            return mul(log(div(const_one, x)), fixed_point<T>(-1, p));
        }

        // Remove even powers of 2
        T shift_val = 31 - __builtin_clz(x._value >> p);
        x           = shift_right(x, shift_val);
        x           = sub(x, const_one);

        // Constants
        auto ln2 = fixed_point<T>(0.6931471, p);
        auto A   = fixed_point<T>(1.4384189, p);
        auto B   = fixed_point<T>(-0.67719, p);
        auto C   = fixed_point<T>(0.3218538, p);
        auto D   = fixed_point<T>(-0.0832229, p);

        // Polynomial expansion
        auto sum = add(mul(x, D), C);
        sum      = add(mul(x, sum), B);
        sum      = add(mul(x, sum), A);
        sum      = mul(x, sum);

        return mul(add(sum, fixed_point<T>(static_cast<T>(shift_val), p)), ln2);
    }
    /** Calculate the exponential of a fixed point number.
     *
     * exp(x) = exp(floor(x)) * exp(x - floor(x))
     *        = pow(2, floor(x) / ln(2)) * exp(x - floor(x))
     *        = exp(x - floor(x)) << (floor(x) / ln(2))
     *
     * @param[in] x Fixed point operand
     *
     * @return Exponential value of operand
     */
    template <typename T>
    static fixed_point<T> exp(fixed_point<T> x)
    {
        uint8_t p = x._fixed_point_position;
        // Constants
        auto const_one = fixed_point<T>(1, p);
        auto ln2       = fixed_point<T>(0.6931471, p);
        auto inv_ln2   = fixed_point<T>(1.442695, p);
        auto A         = fixed_point<T>(0.9978546, p);
        auto B         = fixed_point<T>(0.4994721, p);
        auto C         = fixed_point<T>(0.1763723, p);
        auto D         = fixed_point<T>(0.0435108, p);

        T scaled_int_part = detail::constant_expr<T>::to_int(mul(x, inv_ln2)._value, p);

        // Polynomial expansion
        auto frac_part = sub(x, mul(ln2, fixed_point<T>(scaled_int_part, p)));
        auto taylor    = add(mul(frac_part, D), C);
        taylor         = add(mul(frac_part, taylor), B);
        taylor         = add(mul(frac_part, taylor), A);
        taylor         = mul(frac_part, taylor);
        taylor         = add(taylor, const_one);

        // Saturate value
        if(static_cast<T>(clz(taylor.raw())) <= scaled_int_part)
        {
            return fixed_point<T>(std::numeric_limits<T>::max(), p, true);
        }

        return (scaled_int_part < 0) ? shift_right(taylor, -scaled_int_part) : shift_left(taylor, scaled_int_part);
    }
    /** Calculate the inverse square root of a fixed point number
     *
     * @param[in] x Fixed point operand
     *
     * @return Inverse square root value of operand
     */
    template <typename T>
    static fixed_point<T> inv_sqrt(fixed_point<T> x)
    {
        const uint8_t p     = x._fixed_point_position;
        int8_t        shift = std::numeric_limits<T>::digits - (p + detail::clz(x._value));

        shift += std::numeric_limits<T>::is_signed ? 1 : 0;

        const auto           three_half = fixed_point<T>(1.5f, p);
        fixed_point<T>       a          = shift < 0 ? shift_left(x, -shift) : shift_right(x, shift);
        const fixed_point<T> x_half     = shift_right(a, 1);

        // We need three iterations to find the result
        for(int i = 0; i < 3; ++i)
        {
            a = mul(a, sub(three_half, mul(x_half, mul(a, a))));
        }

        return (shift < 0) ? shift_left(a, -shift >> 1) : shift_right(a, shift >> 1);
    }
    /** Calculate the hyperbolic tangent of a fixed point number
     *
     * @param[in] x Fixed point operand
     *
     * @return Hyperbolic tangent of the operand
     */
    template <typename T>
    static fixed_point<T> tanh(fixed_point<T> x)
    {
        uint8_t p = x._fixed_point_position;
        // Constants
        auto const_one = fixed_point<T>(1, p);
        auto const_two = fixed_point<T>(2, p);

        auto exp2x = exp(const_two * x);
        auto num   = exp2x - const_one;
        auto den   = exp2x + const_one;
        auto tanh  = num / den;

        return tanh;
    }
    /** Calculate the a-th power of a fixed point number.
     *
     *  The power is computed as x^a = e^(log(x) * a)
     *
     * @param[in] x Fixed point operand
     * @param[in] a Fixed point exponent
     *
     * @return a-th power of the operand
     */
    template <typename T>
    static fixed_point<T> pow(fixed_point<T> x, fixed_point<T> a)
    {
        return exp(log(x) * a);
    }
};

template <typename T>
bool operator==(const fixed_point<T> &lhs, const fixed_point<T> &rhs)
{
    return functions::isequal(lhs, rhs);
}
template <typename T>
bool operator!=(const fixed_point<T> &lhs, const fixed_point<T> &rhs)
{
    return !operator==(lhs, rhs);
}
template <typename T>
bool operator<(const fixed_point<T> &lhs, const fixed_point<T> &rhs)
{
    return functions::isless(lhs, rhs);
}
template <typename T>
bool operator>(const fixed_point<T> &lhs, const fixed_point<T> &rhs)
{
    return operator<(rhs, lhs);
}
template <typename T>
bool operator<=(const fixed_point<T> &lhs, const fixed_point<T> &rhs)
{
    return !operator>(lhs, rhs);
}
template <typename T>
bool operator>=(const fixed_point<T> &lhs, const fixed_point<T> &rhs)
{
    return !operator<(lhs, rhs);
}
template <typename T>
fixed_point<T> operator+(const fixed_point<T> &lhs, const fixed_point<T> &rhs)
{
    return functions::add(lhs, rhs);
}
template <typename T>
fixed_point<T> operator-(const fixed_point<T> &lhs, const fixed_point<T> &rhs)
{
    return functions::sub(lhs, rhs);
}
template <typename T>
fixed_point<T> operator-(const fixed_point<T> &rhs)
{
    return functions::negate(rhs);
}
template <typename T>
fixed_point<T> operator*(fixed_point<T> x, fixed_point<T> y)
{
    return functions::mul(x, y);
}
template <typename T>
fixed_point<T> operator/(fixed_point<T> x, fixed_point<T> y)
{
    return functions::div(x, y);
}
template <typename T>
fixed_point<T> operator>>(fixed_point<T> x, size_t shift)
{
    return functions::shift_right(x, shift);
}
template <typename T>
fixed_point<T> operator<<(fixed_point<T> x, size_t shift)
{
    return functions::shift_left(x, shift);
}
template <typename T, typename U, typename traits>
std::basic_ostream<T, traits> &operator<<(std::basic_ostream<T, traits> &s, fixed_point<U> x)
{
    return functions::write(s, x);
}
template <typename T>
inline fixed_point<T> min(fixed_point<T> x, fixed_point<T> y)
{
    return x > y ? y : x;
}
template <typename T>
inline fixed_point<T> max(fixed_point<T> x, fixed_point<T> y)
{
    return x > y ? x : y;
}
template <OverflowPolicy OP = OverflowPolicy::SATURATE, typename T>
inline fixed_point<T> add(fixed_point<T> x, fixed_point<T> y)
{
    return functions::add<OP>(x, y);
}
template <OverflowPolicy OP = OverflowPolicy::SATURATE, typename T>
inline fixed_point<T> sub(fixed_point<T> x, fixed_point<T> y)
{
    return functions::sub<OP>(x, y);
}
template <OverflowPolicy OP = OverflowPolicy::SATURATE, typename T>
inline fixed_point<T> mul(fixed_point<T> x, fixed_point<T> y)
{
    return functions::mul<OP>(x, y);
}
template <typename T>
inline fixed_point<T> div(fixed_point<T> x, fixed_point<T> y)
{
    return functions::div(x, y);
}
template <typename T>
inline fixed_point<T> abs(fixed_point<T> x)
{
    return functions::abs(x);
}
template <typename T>
inline fixed_point<T> clamp(fixed_point<T> x, T min, T max)
{
    return functions::clamp(x, min, max);
}
template <typename T>
inline fixed_point<T> exp(fixed_point<T> x)
{
    return functions::exp(x);
}
template <typename T>
inline fixed_point<T> log(fixed_point<T> x)
{
    return functions::log(x);
}
template <typename T>
inline fixed_point<T> inv_sqrt(fixed_point<T> x)
{
    return functions::inv_sqrt(x);
}
template <typename T>
inline fixed_point<T> tanh(fixed_point<T> x)
{
    return functions::tanh(x);
}
template <typename T>
inline fixed_point<T> pow(fixed_point<T> x, fixed_point<T> a)
{
    return functions::pow(x, a);
}
} // namespace detail

// Expose operators
using detail::operator==;
using detail::operator!=;
using detail::operator<;
using detail::operator>;
using detail::operator<=;
using detail::operator>=;
using detail::operator+;
using detail::operator-;
using detail::operator*;
using detail::operator/;
using detail::operator>>;
using detail::operator<<;

// Expose additional functions
using detail::min;
using detail::max;
using detail::add;
using detail::sub;
using detail::mul;
using detail::div;
using detail::abs;
using detail::clamp;
using detail::exp;
using detail::log;
using detail::inv_sqrt;
using detail::tanh;
using detail::pow;
// TODO: floor
// TODO: ceil
// TODO: sqrt
} // namespace fixed_point_arithmetic
} // namespace test
} // namespace arm_compute
#endif /*__ARM_COMPUTE_TEST_VALIDATION_FIXEDPOINT_H__ */
