//
// Copyright 2002 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//

// mathutil.h: Math and bit manipulation functions.

#ifndef COMMON_MATHUTIL_H_
#define COMMON_MATHUTIL_H_

#include <math.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#include <array>
#include <limits>
#include <ostream>

#include <anglebase/numerics/safe_math.h>

#include "common/debug.h"
#include "common/platform.h"
#include "common/span.h"
#include "common/span_util.h"

namespace angle
{
using base::CheckedNumeric;
using base::IsValueInRangeForNumericType;
}  // namespace angle

namespace gl
{

const unsigned int Float32One   = 0x3F800000;
const unsigned short Float16One = 0x3C00;

template <typename T>
inline constexpr bool isPow2(T x)
{
    static_assert(std::is_integral<T>::value, "isPow2 must be called on an integer type.");
    return (x & (x - 1)) == 0 && (x != 0);
}

template <typename T>
inline constexpr int log2(T x)
{
    static_assert(std::is_integral<T>::value, "log2 must be called on an integer type.");
    int r = 0;
    while ((x >> r) > 1)
    {
        r++;
    }
    return r;
}

inline unsigned int ceilPow2(unsigned int x)
{
    if (x != 0)
    {
        x--;
    }
    x |= x >> 1;
    x |= x >> 2;
    x |= x >> 4;
    x |= x >> 8;
    x |= x >> 16;
    x++;

    return x;
}

template <typename DestT, typename SrcT>
inline DestT clampCast(SrcT value)
{
    // For floating-point types with denormalization, min returns the minimum positive normalized
    // value. To find the value that has no values less than it, use numeric_limits::lowest.
    constexpr const long double destLo =
        static_cast<long double>(std::numeric_limits<DestT>::lowest());
    constexpr const long double destHi =
        static_cast<long double>(std::numeric_limits<DestT>::max());
    constexpr const long double srcLo =
        static_cast<long double>(std::numeric_limits<SrcT>::lowest());
    constexpr long double srcHi = static_cast<long double>(std::numeric_limits<SrcT>::max());

    if (destHi < srcHi)
    {
        DestT destMax = std::numeric_limits<DestT>::max();
        if (value >= static_cast<SrcT>(destMax))
        {
            return destMax;
        }
    }

    if (destLo > srcLo)
    {
        DestT destLow = std::numeric_limits<DestT>::lowest();
        if (value <= static_cast<SrcT>(destLow))
        {
            return destLow;
        }
    }

    return static_cast<DestT>(value);
}

// Specialize clampCast for bool->int conversion to avoid MSVS 2015 performance warning when the max
// value is casted to the source type.
template <>
inline unsigned int clampCast(bool value)
{
    return static_cast<unsigned int>(value);
}

template <>
inline int clampCast(bool value)
{
    return static_cast<int>(value);
}

template <typename T, typename MIN, typename MAX>
inline T clamp(T x, MIN min, MAX max)
{
    // Since NaNs fail all comparison tests, a NaN value will default to min
    return x > min ? (x > max ? max : x) : min;
}

template <typename T>
inline bool isOutsideOfBounds(T value, T min, T max)
{
    // Since NaNs fail all comparison tests, a NaN value will return true (out of bounds).
    return !(value >= min && value <= max);
}

template <typename T>
T clampForBitCount(T value, size_t bitCount)
{
    static_assert(std::numeric_limits<T>::is_integer, "T must be an integer.");

    if (bitCount == 0)
    {
        constexpr T kZero = 0;
        return kZero;
    }
    ASSERT(bitCount <= sizeof(T) * 8);

    constexpr bool kIsSigned = std::numeric_limits<T>::is_signed;
    ASSERT((bitCount > 1) || !kIsSigned);

    T min = 0;
    T max = 0;
    if (bitCount == sizeof(T) * 8)
    {
        min = std::numeric_limits<T>::min();
        max = std::numeric_limits<T>::max();
    }
    else
    {
        constexpr T kOne = 1;
        min              = (kIsSigned) ? -1 * (kOne << (bitCount - 1)) : 0;
        max              = (kIsSigned) ? (kOne << (bitCount - 1)) - 1 : (kOne << bitCount) - 1;
    }

    return gl::clamp(value, min, max);
}

inline float clamp01(float x)
{
    return clamp(x, 0.0f, 1.0f);
}

template <const int n>
inline unsigned int unorm(float x)
{
    const unsigned int max = 0xFFFFFFFF >> (32 - n);

    if (x > 1)
    {
        return max;
    }
    else if (x < 0)
    {
        return 0;
    }
    else
    {
        return (unsigned int)(max * x + 0.5f);
    }
}

template <typename destType, typename sourceType>
destType bitCast(const sourceType &source)
{
    size_t copySize = std::min(sizeof(destType), sizeof(sourceType));
    destType output;
    angle::SpanMemcpy(angle::byte_span_from_ref(output).first(copySize),
                      angle::byte_span_from_ref(source).first(copySize));
    return output;
}

template <typename DestT, typename SrcT>
DestT unsafe_int_to_pointer_cast(SrcT src)
{
    return reinterpret_cast<DestT>(static_cast<uintptr_t>(src));
}

template <typename DestT, typename SrcT>
DestT unsafe_pointer_to_int_cast(SrcT src)
{
    return static_cast<DestT>(reinterpret_cast<uintptr_t>(src));
}

// https://stackoverflow.com/a/37581284
template <typename T>
static constexpr double normalize(T value)
{
    return value < 0 ? -static_cast<double>(value) / std::numeric_limits<T>::min()
                     : static_cast<double>(value) / std::numeric_limits<T>::max();
}

inline unsigned short float32ToFloat16(float fp32)
{
    unsigned int fp32i = bitCast<unsigned int>(fp32);
    unsigned int sign  = (fp32i & 0x80000000) >> 16;
    unsigned int abs   = fp32i & 0x7FFFFFFF;

    if (abs > 0x7F800000)
    {  // NaN
        return 0x7FFF;
    }
    else if (abs > 0x47FFEFFF)
    {  // Infinity
        return static_cast<uint16_t>(sign | 0x7C00);
    }
    else if (abs < 0x38800000)  // Denormal
    {
        unsigned int mantissa = (abs & 0x007FFFFF) | 0x00800000;
        int e                 = 113 - (abs >> 23);

        if (e < 24)
        {
            abs = mantissa >> e;
        }
        else
        {
            abs = 0;
        }

        return static_cast<unsigned short>(sign | (abs + 0x00000FFF + ((abs >> 13) & 1)) >> 13);
    }
    else
    {
        return static_cast<unsigned short>(
            sign | (abs + 0xC8000000 + 0x00000FFF + ((abs >> 13) & 1)) >> 13);
    }
}

float float16ToFloat32(unsigned short h);

unsigned int convertRGBFloatsTo999E5(float red, float green, float blue);
void convert999E5toRGBFloats(unsigned int input, float *red, float *green, float *blue);

inline unsigned short float32ToFloat11(float fp32)
{
    const unsigned int float32MantissaMask     = 0x7FFFFF;
    const unsigned int float32ExponentMask     = 0x7F800000;
    const unsigned int float32SignMask         = 0x80000000;
    const unsigned int float32ValueMask        = ~float32SignMask;
    const unsigned int float32ExponentFirstBit = 23;
    const unsigned int float32ExponentBias     = 127;

    const unsigned short float11Max          = 0x7BF;
    const unsigned short float11MantissaMask = 0x3F;
    const unsigned short float11ExponentMask = 0x7C0;
    const unsigned short float11BitMask      = 0x7FF;
    const unsigned int float11ExponentBias   = 14;

    const unsigned int float32Maxfloat11       = 0x477E0000;
    const unsigned int float32MinNormfloat11   = 0x38800000;
    const unsigned int float32MinDenormfloat11 = 0x35000080;

    const unsigned int float32Bits = bitCast<unsigned int>(fp32);
    const bool float32Sign         = (float32Bits & float32SignMask) == float32SignMask;

    unsigned int float32Val = float32Bits & float32ValueMask;

    if ((float32Val & float32ExponentMask) == float32ExponentMask)
    {
        // INF or NAN
        if ((float32Val & float32MantissaMask) != 0)
        {
            return float11ExponentMask |
                   (((float32Val >> 17) | (float32Val >> 11) | (float32Val >> 6) | (float32Val)) &
                    float11MantissaMask);
        }
        else if (float32Sign)
        {
            // -INF is clamped to 0 since float11 is positive only
            return 0;
        }
        else
        {
            return float11ExponentMask;
        }
    }
    else if (float32Sign)
    {
        // float11 is positive only, so clamp to zero
        return 0;
    }
    else if (float32Val > float32Maxfloat11)
    {
        // The number is too large to be represented as a float11, set to max
        return float11Max;
    }
    else if (float32Val < float32MinDenormfloat11)
    {
        // The number is too small to be represented as a denormalized float11, set to 0
        return 0;
    }
    else
    {
        if (float32Val < float32MinNormfloat11)
        {
            // The number is too small to be represented as a normalized float11
            // Convert it to a denormalized value.
            const unsigned int shift = (float32ExponentBias - float11ExponentBias) -
                                       (float32Val >> float32ExponentFirstBit);
            ASSERT(shift < 32);
            float32Val =
                ((1 << float32ExponentFirstBit) | (float32Val & float32MantissaMask)) >> shift;
        }
        else
        {
            // Rebias the exponent to represent the value as a normalized float11
            float32Val += 0xC8000000;
        }

        return ((float32Val + 0xFFFF + ((float32Val >> 17) & 1)) >> 17) & float11BitMask;
    }
}

inline unsigned short float32ToFloat10(float fp32)
{
    const unsigned int float32MantissaMask     = 0x7FFFFF;
    const unsigned int float32ExponentMask     = 0x7F800000;
    const unsigned int float32SignMask         = 0x80000000;
    const unsigned int float32ValueMask        = ~float32SignMask;
    const unsigned int float32ExponentFirstBit = 23;
    const unsigned int float32ExponentBias     = 127;

    const unsigned short float10Max          = 0x3DF;
    const unsigned short float10MantissaMask = 0x1F;
    const unsigned short float10ExponentMask = 0x3E0;
    const unsigned short float10BitMask      = 0x3FF;
    const unsigned int float10ExponentBias   = 14;

    const unsigned int float32Maxfloat10       = 0x477C0000;
    const unsigned int float32MinNormfloat10   = 0x38800000;
    const unsigned int float32MinDenormfloat10 = 0x35800040;

    const unsigned int float32Bits = bitCast<unsigned int>(fp32);
    const bool float32Sign         = (float32Bits & float32SignMask) == float32SignMask;

    unsigned int float32Val = float32Bits & float32ValueMask;

    if ((float32Val & float32ExponentMask) == float32ExponentMask)
    {
        // INF or NAN
        if ((float32Val & float32MantissaMask) != 0)
        {
            return float10ExponentMask |
                   (((float32Val >> 18) | (float32Val >> 13) | (float32Val >> 3) | (float32Val)) &
                    float10MantissaMask);
        }
        else if (float32Sign)
        {
            // -INF is clamped to 0 since float10 is positive only
            return 0;
        }
        else
        {
            return float10ExponentMask;
        }
    }
    else if (float32Sign)
    {
        // float10 is positive only, so clamp to zero
        return 0;
    }
    else if (float32Val > float32Maxfloat10)
    {
        // The number is too large to be represented as a float10, set to max
        return float10Max;
    }
    else if (float32Val < float32MinDenormfloat10)
    {
        // The number is too small to be represented as a denormalized float10, set to 0
        return 0;
    }
    else
    {
        if (float32Val < float32MinNormfloat10)
        {
            // The number is too small to be represented as a normalized float10
            // Convert it to a denormalized value.
            const unsigned int shift = (float32ExponentBias - float10ExponentBias) -
                                       (float32Val >> float32ExponentFirstBit);
            ASSERT(shift < 32);
            float32Val =
                ((1 << float32ExponentFirstBit) | (float32Val & float32MantissaMask)) >> shift;
        }
        else
        {
            // Rebias the exponent to represent the value as a normalized float10
            float32Val += 0xC8000000;
        }

        return ((float32Val + 0x1FFFF + ((float32Val >> 18) & 1)) >> 18) & float10BitMask;
    }
}

inline float float11ToFloat32(unsigned short fp11)
{
    unsigned short exponent = (fp11 >> 6) & 0x1F;
    unsigned short mantissa = fp11 & 0x3F;

    if (exponent == 0x1F)
    {
        // INF or NAN
        return bitCast<float>(0x7f800000 | (mantissa << 17));
    }
    else
    {
        if (exponent != 0)
        {
            // normalized
        }
        else if (mantissa != 0)
        {
            // The value is denormalized
            exponent = 1;

            do
            {
                exponent--;
                mantissa <<= 1;
            } while ((mantissa & 0x40) == 0);

            mantissa = mantissa & 0x3F;
        }
        else  // The value is zero
        {
            exponent = static_cast<unsigned short>(-112);
        }

        return bitCast<float>(((exponent + 112) << 23) | (mantissa << 17));
    }
}

inline float float10ToFloat32(unsigned short fp10)
{
    unsigned short exponent = (fp10 >> 5) & 0x1F;
    unsigned short mantissa = fp10 & 0x1F;

    if (exponent == 0x1F)
    {
        // INF or NAN
        return bitCast<float>(0x7f800000 | (mantissa << 17));
    }
    else
    {
        if (exponent != 0)
        {
            // normalized
        }
        else if (mantissa != 0)
        {
            // The value is denormalized
            exponent = 1;

            do
            {
                exponent--;
                mantissa <<= 1;
            } while ((mantissa & 0x20) == 0);

            mantissa = mantissa & 0x1F;
        }
        else  // The value is zero
        {
            exponent = static_cast<unsigned short>(-112);
        }

        return bitCast<float>(((exponent + 112) << 23) | (mantissa << 18));
    }
}

// Converts to and from float and 16.16 fixed point format.
inline float ConvertFixedToFloat(int32_t fixedInput)
{
    return static_cast<float>(fixedInput) / 65536.0f;
}

inline uint32_t ConvertFloatToFixed(float floatInput)
{
    static constexpr uint32_t kHighest = 32767 * 65536 + 65535;
    static constexpr uint32_t kLowest  = static_cast<uint32_t>(-32768 * 65536 + 65535);

    if (floatInput > 32767.65535)
    {
        return kHighest;
    }
    else if (floatInput < -32768.65535)
    {
        return kLowest;
    }
    else
    {
        return static_cast<uint32_t>(floatInput * 65536);
    }
}

template <typename T>
inline float normalizedToFloat(T input)
{
    static_assert(std::numeric_limits<T>::is_integer, "T must be an integer.");

    if constexpr (sizeof(T) > 2)
    {
        // float has only a 23 bit mantissa, so we need to do the calculation in double precision
        constexpr double inverseMax = 1.0 / std::numeric_limits<T>::max();
        if constexpr (std::is_signed<T>::value)
        {
            static_assert(static_cast<float>(std::numeric_limits<T>::min() * inverseMax) == -1.0f);
        }
        return static_cast<float>(input * inverseMax);
    }
    else
    {
        constexpr float inverseMax = 1.0f / std::numeric_limits<T>::max();
        if constexpr (std::is_signed<T>::value)
        {
            // If the input is signed and equals to the type's min value, the multiplication result
            // would be less than -1. This step is not needed for int32_t because the difference is
            // not representable with single-precision floats in that case. For the best codegen,
            // std::max with the first constant parameter must be used here.
            return std::max(-1.0f, input * inverseMax);
        }
        return input * inverseMax;
    }
}

template <unsigned int inputBitCount, typename T>
inline float normalizedToFloat(T input)
{
    static_assert(std::numeric_limits<T>::is_integer, "T must be an integer.");
    static_assert(inputBitCount > 0u && inputBitCount < 32u);
    if constexpr (std::is_signed<T>::value)
    {
        static_assert(inputBitCount > 1 && inputBitCount < sizeof(T) * 8 - 1);
    }
    else
    {
        static_assert(inputBitCount < sizeof(T) * 8);
    }

    // Account for the sign bit
    constexpr uint32_t effectiveBitCount =
        std::is_unsigned<T>::value ? inputBitCount : inputBitCount - 1u;

    constexpr T maxValue = static_cast<T>((1u << effectiveBitCount) - 1u);

    // Ensure that the input value fits in the declared number of bits.
    ASSERT(input <= maxValue);
    if constexpr (std::is_signed<T>::value)
    {
        ASSERT(input >= -maxValue - 1);
    }

    if constexpr (effectiveBitCount > 23)
    {
        // float has only a 23 bit mantissa, so we need to do the calculation in double precision
        constexpr double inverseMax = 1.0 / maxValue;
        if constexpr (std::is_signed<T>::value)
        {
            if constexpr (effectiveBitCount < 25)
            {
                return std::max(-1.0f, static_cast<float>(input * inverseMax));
            }
            else
            {
                static_assert(static_cast<float>((-maxValue - 1) * inverseMax) == -1.0f);
            }
        }
        return static_cast<float>(input * inverseMax);
    }
    else
    {
        constexpr float inverseMax = 1.0f / maxValue;
        if constexpr (std::is_signed<T>::value)
        {
            return std::max(-1.0f, input * inverseMax);
        }
        return input * inverseMax;
    }
}

template <typename T, typename R>
inline R roundToNearest(T input)
{
    static_assert(std::is_floating_point<T>::value);
    static_assert(std::numeric_limits<R>::is_integer);
#if defined(__aarch64__) || defined(_M_ARM64)
    // On armv8, this expression is compiled to a dedicated round-to-nearest instruction
    return static_cast<R>(std::round(input));
#else
    static_assert(0.49999997f < 0.5f);
    static_assert(0.49999997f + 0.5f == 1.0f);
    static_assert(0.49999999999999994 < 0.5);
    static_assert(0.49999999999999994 + 0.5 == 1.0);
    constexpr T bias = sizeof(T) == 8 ? 0.49999999999999994 : 0.49999997f;
    return static_cast<R>(input + (std::is_signed<R>::value ? std::copysign(bias, input) : bias));
#endif
}

template <typename T>
inline T floatToNormalized(float input)
{
    if constexpr (sizeof(T) > 2)
    {
        // float has only a 23 bit mantissa, so we need to do the calculation in double precision
        return roundToNearest<double, T>(std::numeric_limits<T>::max() *
                                         static_cast<double>(input));
    }
    else
    {
        return roundToNearest<float, T>(std::numeric_limits<T>::max() * input);
    }
}

template <unsigned int outputBitCount, typename T>
inline T floatToNormalized(float input)
{
    static_assert(outputBitCount < (sizeof(T) * 8), "T must have more bits than outputBitCount.");
    static_assert(outputBitCount > (std::is_unsigned<T>::value ? 0 : 1),
                  "outputBitCount must be at least 1 not counting the sign bit.");
    constexpr unsigned int bits = std::is_unsigned<T>::value ? outputBitCount : outputBitCount - 1;

    if (bits > 23)
    {
        // float has only a 23 bit mantissa, so we need to do the calculation in double precision
        return roundToNearest<double, T>(((1 << bits) - 1) * static_cast<double>(input));
    }
    else
    {
        return roundToNearest<float, T>(((1 << bits) - 1) * input);
    }
}

template <unsigned int inputBitCount, unsigned int inputBitStart, typename T>
inline T getShiftedData(T input)
{
    static_assert(inputBitCount + inputBitStart <= (sizeof(T) * 8),
                  "T must have at least as many bits as inputBitCount + inputBitStart.");
    const T mask = (1 << inputBitCount) - 1;
    return (input >> inputBitStart) & mask;
}

template <unsigned int inputBitCount, unsigned int inputBitStart, typename T>
inline T shiftData(T input)
{
    static_assert(inputBitCount + inputBitStart <= (sizeof(T) * 8),
                  "T must have at least as many bits as inputBitCount + inputBitStart.");
    const T mask = (1 << inputBitCount) - 1;
    return (input & mask) << inputBitStart;
}

inline unsigned int CountLeadingZeros(uint32_t x)
{
    // Use binary search to find the amount of leading zeros.
    unsigned int zeros = 32u;
    uint32_t y;

    y = x >> 16u;
    if (y != 0)
    {
        zeros = zeros - 16u;
        x     = y;
    }
    y = x >> 8u;
    if (y != 0)
    {
        zeros = zeros - 8u;
        x     = y;
    }
    y = x >> 4u;
    if (y != 0)
    {
        zeros = zeros - 4u;
        x     = y;
    }
    y = x >> 2u;
    if (y != 0)
    {
        zeros = zeros - 2u;
        x     = y;
    }
    y = x >> 1u;
    if (y != 0)
    {
        return zeros - 2u;
    }
    return zeros - x;
}

inline unsigned char average(unsigned char a, unsigned char b)
{
    return ((a ^ b) >> 1) + (a & b);
}

inline signed char average(signed char a, signed char b)
{
    return ((short)a + (short)b) / 2;
}

inline unsigned short average(unsigned short a, unsigned short b)
{
    return ((a ^ b) >> 1) + (a & b);
}

inline signed short average(signed short a, signed short b)
{
    return ((int)a + (int)b) / 2;
}

inline unsigned int average(unsigned int a, unsigned int b)
{
    return ((a ^ b) >> 1) + (a & b);
}

inline int average(int a, int b)
{
    long long average = (static_cast<long long>(a) + static_cast<long long>(b)) / 2LL;
    return static_cast<int>(average);
}

inline float average(float a, float b)
{
    return (a + b) * 0.5f;
}

inline unsigned short averageHalfFloat(unsigned short a, unsigned short b)
{
    return float32ToFloat16((float16ToFloat32(a) + float16ToFloat32(b)) * 0.5f);
}

inline unsigned int averageFloat11(unsigned int a, unsigned int b)
{
    return float32ToFloat11((float11ToFloat32(static_cast<unsigned short>(a)) +
                             float11ToFloat32(static_cast<unsigned short>(b))) *
                            0.5f);
}

inline unsigned int averageFloat10(unsigned int a, unsigned int b)
{
    return float32ToFloat10((float10ToFloat32(static_cast<unsigned short>(a)) +
                             float10ToFloat32(static_cast<unsigned short>(b))) *
                            0.5f);
}

template <typename T>
class Range
{
  public:
    Range() {}
    Range(T lo, T hi) : mLow(lo), mHigh(hi) {}

    bool operator==(const Range<T> &other) const
    {
        return mLow == other.mLow && mHigh == other.mHigh;
    }

    T length() const { return (empty() ? 0 : (mHigh - mLow)); }

    bool intersects(const Range<T> &other) const
    {
        if (mLow <= other.mLow)
        {
            return other.mLow < mHigh;
        }
        else
        {
            return mLow < other.mHigh;
        }
    }

    bool intersectsOrContinuous(const Range<T> &other) const
    {
        ASSERT(!empty());
        ASSERT(!other.empty());
        if (mLow <= other.mLow)
        {
            return mHigh >= other.mLow;
        }
        else
        {
            return mLow <= other.mHigh;
        }
    }

    void merge(const Range<T> &other)
    {
        if (mLow > other.mLow)
        {
            mLow = other.mLow;
        }

        if (mHigh < other.mHigh)
        {
            mHigh = other.mHigh;
        }
    }

    // Assumes that end is non-inclusive.. for example, extending to 5 will make "end" 6.
    void extend(T value)
    {
        mLow  = value < mLow ? value : mLow;
        mHigh = value >= mHigh ? (value + 1) : mHigh;
    }

    bool empty() const { return mHigh <= mLow; }

    bool contains(T value) const { return value >= mLow && value < mHigh; }

    class Iterator final
    {
      public:
        Iterator(T value) : mCurrent(value) {}

        Iterator &operator++()
        {
            mCurrent++;
            return *this;
        }
        bool operator==(const Iterator &other) const { return mCurrent == other.mCurrent; }
        bool operator!=(const Iterator &other) const { return mCurrent != other.mCurrent; }
        T operator*() const { return mCurrent; }

      private:
        T mCurrent;
    };

    Iterator begin() const { return Iterator(mLow); }

    Iterator end() const { return Iterator(mHigh); }

    T low() const { return mLow; }
    T high() const { return mHigh; }

    void invalidate()
    {
        mLow  = std::numeric_limits<T>::max();
        mHigh = std::numeric_limits<T>::min();
    }

  private:
    T mLow;
    T mHigh;
};

typedef Range<int> RangeI;
typedef Range<unsigned int> RangeUI;
static_assert(std::is_trivially_copyable<RangeUI>(),
              "RangeUI should be trivial copyable so that we can memcpy");

// Inclusive vertex index range [start(), end()].
struct IndexRange
{
    struct Undefined
    {};
    IndexRange(Undefined) {}
    IndexRange() = default;
    IndexRange(uint32_t start, uint32_t end)
        : mStart(start), mEnd(end), mCount(static_cast<uint64_t>(end - start) + 1)
    {
        ASSERT(start <= end);
    }
    bool isEmpty() const { return mCount == 0; }
    uint32_t start() const
    {
        ASSERT(!isEmpty());
        return mStart;
    }
    uint32_t end() const
    {
        ASSERT(!isEmpty());
        return mEnd;
    }

    // Number of vertices in the range.
    uint64_t vertexCount() const { return mCount; }

  private:
    uint32_t mStart{0};
    uint32_t mEnd{0};

    // Since the range is inclusive, mCount == 0 indicates an empty range
    uint64_t mCount{0};
};

inline bool operator==(const IndexRange &a, const IndexRange &b)
{
    return a.vertexCount() == b.vertexCount() &&
           ((a.vertexCount() == 0) || (a.start() == b.start()));
}

std::ostream &operator<<(std::ostream &s, const IndexRange &a);

// Combine a floating-point value representing a mantissa (x) and an integer exponent (exp) into a
// floating-point value. As in GLSL ldexp() built-in.
inline float Ldexp(float x, int exp)
{
    if (exp > 128)
    {
        return std::numeric_limits<float>::infinity();
    }
    if (exp < -126)
    {
        return 0.0f;
    }
    double result = static_cast<double>(x) * std::pow(2.0, static_cast<double>(exp));
    return static_cast<float>(result);
}

// First, both normalized floating-point values are converted into 16-bit integer values.
// Then, the results are packed into the returned 32-bit unsigned integer.
// The first float value will be written to the least significant bits of the output;
// the last float value will be written to the most significant bits.
// The conversion of each value to fixed point is done as follows :
// packSnorm2x16 : round(clamp(c, -1, +1) * 32767.0)
inline uint32_t packSnorm2x16(float f1, float f2)
{
    int16_t leastSignificantBits = static_cast<int16_t>(roundf(clamp(f1, -1.0f, 1.0f) * 32767.0f));
    int16_t mostSignificantBits  = static_cast<int16_t>(roundf(clamp(f2, -1.0f, 1.0f) * 32767.0f));
    return static_cast<uint32_t>(mostSignificantBits) << 16 |
           (static_cast<uint32_t>(leastSignificantBits) & 0xFFFF);
}

// First, unpacks a single 32-bit unsigned integer u into a pair of 16-bit unsigned integers. Then,
// each component is converted to a normalized floating-point value to generate the returned two
// float values. The first float value will be extracted from the least significant bits of the
// input; the last float value will be extracted from the most-significant bits. The conversion for
// unpacked fixed-point value to floating point is done as follows: unpackSnorm2x16 : clamp(f /
// 32767.0, -1, +1)
inline void unpackSnorm2x16(uint32_t u, float *f1, float *f2)
{
    int16_t leastSignificantBits = static_cast<int16_t>(u & 0xFFFF);
    int16_t mostSignificantBits  = static_cast<int16_t>(u >> 16);
    *f1 = clamp(static_cast<float>(leastSignificantBits) / 32767.0f, -1.0f, 1.0f);
    *f2 = clamp(static_cast<float>(mostSignificantBits) / 32767.0f, -1.0f, 1.0f);
}

// First, both normalized floating-point values are converted into 16-bit integer values.
// Then, the results are packed into the returned 32-bit unsigned integer.
// The first float value will be written to the least significant bits of the output;
// the last float value will be written to the most significant bits.
// The conversion of each value to fixed point is done as follows:
// packUnorm2x16 : round(clamp(c, 0, +1) * 65535.0)
inline uint32_t packUnorm2x16(float f1, float f2)
{
    uint16_t leastSignificantBits = static_cast<uint16_t>(roundf(clamp(f1, 0.0f, 1.0f) * 65535.0f));
    uint16_t mostSignificantBits  = static_cast<uint16_t>(roundf(clamp(f2, 0.0f, 1.0f) * 65535.0f));
    return static_cast<uint32_t>(mostSignificantBits) << 16 |
           static_cast<uint32_t>(leastSignificantBits);
}

// First, unpacks a single 32-bit unsigned integer u into a pair of 16-bit unsigned integers. Then,
// each component is converted to a normalized floating-point value to generate the returned two
// float values. The first float value will be extracted from the least significant bits of the
// input; the last float value will be extracted from the most-significant bits. The conversion for
// unpacked fixed-point value to floating point is done as follows: unpackUnorm2x16 : f / 65535.0
inline void unpackUnorm2x16(uint32_t u, float *f1, float *f2)
{
    uint16_t leastSignificantBits = static_cast<uint16_t>(u & 0xFFFF);
    uint16_t mostSignificantBits  = static_cast<uint16_t>(u >> 16);
    *f1                           = static_cast<float>(leastSignificantBits) / 65535.0f;
    *f2                           = static_cast<float>(mostSignificantBits) / 65535.0f;
}

// Helper functions intended to be used only here.
namespace priv
{

inline uint8_t ToPackedUnorm8(float f)
{
    return static_cast<uint8_t>(roundf(clamp(f, 0.0f, 1.0f) * 255.0f));
}

inline int8_t ToPackedSnorm8(float f)
{
    return static_cast<int8_t>(roundf(clamp(f, -1.0f, 1.0f) * 127.0f));
}

}  // namespace priv

// Packs 4 normalized unsigned floating-point values to a single 32-bit unsigned integer. Works
// similarly to packUnorm2x16. The floats are clamped to the range 0.0 to 1.0, and written to the
// unsigned integer starting from the least significant bits.
inline uint32_t PackUnorm4x8(float f1, float f2, float f3, float f4)
{
    return static_cast<uint32_t>(priv::ToPackedUnorm8(f1)) |
           (static_cast<uint32_t>(priv::ToPackedUnorm8(f2)) << 8) |
           (static_cast<uint32_t>(priv::ToPackedUnorm8(f3)) << 16) |
           (static_cast<uint32_t>(priv::ToPackedUnorm8(f4)) << 24);
}

// Unpacks 4 normalized unsigned floating-point values from a single 32-bit unsigned integer into f.
// Works similarly to unpackUnorm2x16. The floats are unpacked starting from the least significant
// bits.
inline void UnpackUnorm4x8(uint32_t u, angle::Span<float, 4> f)
{
    for (int i = 0; i < 4; ++i)
    {
        int shift    = i * 8;
        uint8_t bits = static_cast<uint8_t>((u >> shift) & 0xFF);
        f[i]         = static_cast<float>(bits) / 255.0f;
    }
}

// Packs 4 normalized signed floating-point values to a single 32-bit unsigned integer. The floats
// are clamped to the range -1.0 to 1.0, and written to the unsigned integer starting from the least
// significant bits.
inline uint32_t PackSnorm4x8(float f1, float f2, float f3, float f4)
{
    return (static_cast<uint32_t>(priv::ToPackedSnorm8(f1)) & 0xFF) |
           ((static_cast<uint32_t>(priv::ToPackedSnorm8(f2)) & 0xFF) << 8) |
           ((static_cast<uint32_t>(priv::ToPackedSnorm8(f3)) & 0xFF) << 16) |
           ((static_cast<uint32_t>(priv::ToPackedSnorm8(f4)) & 0xFF) << 24);
}

// Unpacks 4 normalized signed floating-point values from a single 32-bit unsigned integer into f.
// Works similarly to unpackSnorm2x16. The floats are unpacked starting from the least significant
// bits, and clamped to the range -1.0 to 1.0.
inline void UnpackSnorm4x8(uint32_t u, angle::Span<float, 4> f)
{
    for (int i = 0; i < 4; ++i)
    {
        int shift   = i * 8;
        int8_t bits = static_cast<int8_t>((u >> shift) & 0xFF);
        f[i]        = clamp(static_cast<float>(bits) / 127.0f, -1.0f, 1.0f);
    }
}

// Returns an unsigned integer obtained by converting the two floating-point values to the 16-bit
// floating-point representation found in the OpenGL ES Specification, and then packing these
// two 16-bit integers into a 32-bit unsigned integer.
// f1: The 16 least-significant bits of the result;
// f2: The 16 most-significant bits.
inline uint32_t packHalf2x16(float f1, float f2)
{
    uint16_t leastSignificantBits = static_cast<uint16_t>(float32ToFloat16(f1));
    uint16_t mostSignificantBits  = static_cast<uint16_t>(float32ToFloat16(f2));
    return static_cast<uint32_t>(mostSignificantBits) << 16 |
           static_cast<uint32_t>(leastSignificantBits);
}

// Returns two floating-point values obtained by unpacking a 32-bit unsigned integer into a pair of
// 16-bit values, interpreting those values as 16-bit floating-point numbers according to the OpenGL
// ES Specification, and converting them to 32-bit floating-point values. The first float value is
// obtained from the 16 least-significant bits of u; the second component is obtained from the 16
// most-significant bits of u.
inline void unpackHalf2x16(uint32_t u, float *f1, float *f2)
{
    uint16_t leastSignificantBits = static_cast<uint16_t>(u & 0xFFFF);
    uint16_t mostSignificantBits  = static_cast<uint16_t>(u >> 16);

    *f1 = float16ToFloat32(leastSignificantBits);
    *f2 = float16ToFloat32(mostSignificantBits);
}

inline float sRGBToLinear(uint8_t srgbValue)
{
    float value = srgbValue / 255.0f;
    if (value <= 0.04045f)
    {
        value = value / 12.92f;
    }
    else
    {
        value = std::pow((value + 0.055f) / 1.055f, 2.4f);
    }
    ASSERT(value >= 0.0f && value <= 1.0f);
    return value;
}

inline uint8_t linearToSRGB(float value)
{
    ASSERT(value >= 0.0f && value <= 1.0f);
    if (value < 0.0031308f)
    {
        value = value * 12.92f;
    }
    else
    {
        value = std::pow(value, 0.41666f) * 1.055f - 0.055f;
    }
    return static_cast<uint8_t>(value * 255.0f + 0.5f);
}

// Reverse the order of the bits.
inline uint32_t BitfieldReverse(uint32_t value)
{
    // TODO(oetuaho@nvidia.com): Optimize this if needed. There don't seem to be compiler intrinsics
    // for this, and right now it's not used in performance-critical paths.
    uint32_t result = 0u;
    for (size_t j = 0u; j < 32u; ++j)
    {
        result |= (((value >> j) & 1u) << (31u - j));
    }
    return result;
}

// Count the 1 bits.
#if defined(_MSC_VER) && !defined(__clang__)
#    if defined(_M_IX86) || defined(_M_X64)
namespace priv
{
// Check POPCNT instruction support and cache the result.
// https://docs.microsoft.com/en-us/cpp/intrinsics/popcnt16-popcnt-popcnt64#remarks
static const bool kHasPopcnt = [] {
    int info[4];
    __cpuid(&info[0], 1);
    return static_cast<bool>(info[2] & 0x800000);
}();
}  // namespace priv

// Polyfills for x86/x64 CPUs without POPCNT.
// https://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel
inline int BitCountPolyfill(uint32_t bits)
{
    bits = bits - ((bits >> 1) & 0x55555555);
    bits = (bits & 0x33333333) + ((bits >> 2) & 0x33333333);
    bits = ((bits + (bits >> 4) & 0x0F0F0F0F) * 0x01010101) >> 24;
    return static_cast<int>(bits);
}

inline int BitCountPolyfill(uint64_t bits)
{
    bits = bits - ((bits >> 1) & 0x5555555555555555ull);
    bits = (bits & 0x3333333333333333ull) + ((bits >> 2) & 0x3333333333333333ull);
    bits = ((bits + (bits >> 4) & 0x0F0F0F0F0F0F0F0Full) * 0x0101010101010101ull) >> 56;
    return static_cast<int>(bits);
}

inline int BitCount(uint32_t bits)
{
    if (priv::kHasPopcnt)
    {
        return static_cast<int>(__popcnt(bits));
    }
    return BitCountPolyfill(bits);
}

inline int BitCount(uint64_t bits)
{
    if (priv::kHasPopcnt)
    {
#        if defined(_M_X64)
        return static_cast<int>(__popcnt64(bits));
#        else   // x86
        return static_cast<int>(__popcnt(static_cast<uint32_t>(bits >> 32)) +
                                __popcnt(static_cast<uint32_t>(bits)));
#        endif  // defined(_M_X64)
    }
    return BitCountPolyfill(bits);
}

#    elif defined(_M_ARM) || defined(_M_ARM64)

// MSVC's _CountOneBits* intrinsics are not defined for ARM64, moreover they do not use dedicated
// NEON instructions.

inline int BitCount(uint32_t bits)
{
    // cast bits to 8x8 datatype and use VCNT on it
    const uint8x8_t vsum = vcnt_u8(vcreate_u8(static_cast<uint64_t>(bits)));

    // pairwise sums: 8x8 -> 16x4 -> 32x2
    return static_cast<int>(vget_lane_u32(vpaddl_u16(vpaddl_u8(vsum)), 0));
}

inline int BitCount(uint64_t bits)
{
    // cast bits to 8x8 datatype and use VCNT on it
    const uint8x8_t vsum = vcnt_u8(vcreate_u8(bits));

    // pairwise sums: 8x8 -> 16x4 -> 32x2 -> 64x1
    return static_cast<int>(vget_lane_u64(vpaddl_u32(vpaddl_u16(vpaddl_u8(vsum))), 0));
}
#    endif  // defined(_M_IX86) || defined(_M_X64)
#endif      // defined(_MSC_VER) && !defined(__clang__)

#if defined(ANGLE_PLATFORM_POSIX) || defined(__clang__) || defined(__GNUC__)
inline int BitCount(uint32_t bits)
{
    return __builtin_popcount(bits);
}

inline int BitCount(uint64_t bits)
{
    return __builtin_popcountll(bits);
}
#endif  // defined(ANGLE_PLATFORM_POSIX) || defined(__clang__) || defined(__GNUC__)

inline int BitCount(uint8_t bits)
{
    return BitCount(static_cast<uint32_t>(bits));
}

inline int BitCount(uint16_t bits)
{
    return BitCount(static_cast<uint32_t>(bits));
}

#if defined(ANGLE_PLATFORM_WINDOWS)
// Return the index of the least significant bit set. Indexing is such that bit 0 is the least
// significant bit. Implemented for different bit widths on different platforms.
inline unsigned long ScanForward(uint32_t bits)
{
    ASSERT(bits != 0u);
    unsigned long firstBitIndex = 0ul;
    unsigned char ret           = _BitScanForward(&firstBitIndex, bits);
    ASSERT(ret != 0u);
    return firstBitIndex;
}

inline unsigned long ScanForward(uint64_t bits)
{
    ASSERT(bits != 0u);
    unsigned long firstBitIndex = 0ul;
#    if defined(ANGLE_IS_64_BIT_CPU)
    unsigned char ret = _BitScanForward64(&firstBitIndex, bits);
#    else
    unsigned char ret;
    if (static_cast<uint32_t>(bits) == 0)
    {
        ret = _BitScanForward(&firstBitIndex, static_cast<uint32_t>(bits >> 32));
        firstBitIndex += 32ul;
    }
    else
    {
        ret = _BitScanForward(&firstBitIndex, static_cast<uint32_t>(bits));
    }
#    endif  // defined(ANGLE_IS_64_BIT_CPU)
    ASSERT(ret != 0u);
    return firstBitIndex;
}

// Return the index of the most significant bit set. Indexing is such that bit 0 is the least
// significant bit.
inline unsigned long ScanReverse(uint32_t bits)
{
    ASSERT(bits != 0u);
    unsigned long lastBitIndex = 0ul;
    unsigned char ret          = _BitScanReverse(&lastBitIndex, bits);
    ASSERT(ret != 0u);
    return lastBitIndex;
}

inline unsigned long ScanReverse(uint64_t bits)
{
    ASSERT(bits != 0u);
    unsigned long lastBitIndex = 0ul;
#    if defined(ANGLE_IS_64_BIT_CPU)
    unsigned char ret = _BitScanReverse64(&lastBitIndex, bits);
#    else
    unsigned char ret;
    if (static_cast<uint32_t>(bits >> 32) == 0)
    {
        ret = _BitScanReverse(&lastBitIndex, static_cast<uint32_t>(bits));
    }
    else
    {
        ret = _BitScanReverse(&lastBitIndex, static_cast<uint32_t>(bits >> 32));
        lastBitIndex += 32ul;
    }
#    endif  // defined(ANGLE_IS_64_BIT_CPU)
    ASSERT(ret != 0u);
    return lastBitIndex;
}
#endif  // defined(ANGLE_PLATFORM_WINDOWS)

#if defined(ANGLE_PLATFORM_POSIX)
inline unsigned long ScanForward(uint32_t bits)
{
    ASSERT(bits != 0u);
    return static_cast<unsigned long>(__builtin_ctz(bits));
}

inline unsigned long ScanForward(uint64_t bits)
{
    ASSERT(bits != 0u);
#    if defined(ANGLE_IS_64_BIT_CPU)
    return static_cast<unsigned long>(__builtin_ctzll(bits));
#    else
    return static_cast<unsigned long>(static_cast<uint32_t>(bits) == 0
                                          ? __builtin_ctz(static_cast<uint32_t>(bits >> 32)) + 32
                                          : __builtin_ctz(static_cast<uint32_t>(bits)));
#    endif  // defined(ANGLE_IS_64_BIT_CPU)
}

inline unsigned long ScanReverse(uint32_t bits)
{
    ASSERT(bits != 0u);
    return static_cast<unsigned long>(sizeof(uint32_t) * CHAR_BIT - 1 - __builtin_clz(bits));
}

inline unsigned long ScanReverse(uint64_t bits)
{
    ASSERT(bits != 0u);
#    if defined(ANGLE_IS_64_BIT_CPU)
    return static_cast<unsigned long>(sizeof(uint64_t) * CHAR_BIT - 1 - __builtin_clzll(bits));
#    else
    if (static_cast<uint32_t>(bits >> 32) == 0)
    {
        return sizeof(uint32_t) * CHAR_BIT - 1 - __builtin_clz(static_cast<uint32_t>(bits));
    }
    else
    {
        return sizeof(uint32_t) * CHAR_BIT - 1 - __builtin_clz(static_cast<uint32_t>(bits >> 32)) +
               32;
    }
#    endif  // defined(ANGLE_IS_64_BIT_CPU)
}
#endif  // defined(ANGLE_PLATFORM_POSIX)

inline unsigned long ScanForward(uint8_t bits)
{
    return ScanForward(static_cast<uint32_t>(bits));
}

inline unsigned long ScanForward(uint16_t bits)
{
    return ScanForward(static_cast<uint32_t>(bits));
}

inline unsigned long ScanReverse(uint8_t bits)
{
    return ScanReverse(static_cast<uint32_t>(bits));
}

inline unsigned long ScanReverse(uint16_t bits)
{
    return ScanReverse(static_cast<uint32_t>(bits));
}

// Returns -1 on 0, otherwise the index of the least significant 1 bit as in GLSL.
template <typename T>
int FindLSB(T bits)
{
    static_assert(std::is_integral<T>::value, "must be integral type.");
    if (bits == 0u)
    {
        return -1;
    }
    else
    {
        return static_cast<int>(ScanForward(bits));
    }
}

// Returns -1 on 0, otherwise the index of the most significant 1 bit as in GLSL.
template <typename T>
int FindMSB(T bits)
{
    static_assert(std::is_integral<T>::value, "must be integral type.");
    if (bits == 0u)
    {
        return -1;
    }
    else
    {
        return static_cast<int>(ScanReverse(bits));
    }
}

// Returns whether the argument is Not a Number.
// IEEE 754 single precision NaN representation: Exponent(8 bits) - 255, Mantissa(23 bits) -
// non-zero.
inline bool isNaN(float f)
{
    // Exponent mask: ((1u << 8) - 1u) << 23 = 0x7f800000u
    // Mantissa mask: ((1u << 23) - 1u) = 0x7fffffu
    return ((bitCast<uint32_t>(f) & 0x7f800000u) == 0x7f800000u) &&
           (bitCast<uint32_t>(f) & 0x7fffffu);
}

// Returns whether the argument is infinity.
// IEEE 754 single precision infinity representation: Exponent(8 bits) - 255, Mantissa(23 bits) -
// zero.
inline bool isInf(float f)
{
    // Exponent mask: ((1u << 8) - 1u) << 23 = 0x7f800000u
    // Mantissa mask: ((1u << 23) - 1u) = 0x7fffffu
    return ((bitCast<uint32_t>(f) & 0x7f800000u) == 0x7f800000u) &&
           !(bitCast<uint32_t>(f) & 0x7fffffu);
}

namespace priv
{
template <unsigned int N, unsigned int R>
struct iSquareRoot
{
    static constexpr unsigned int solve()
    {
        return (R * R > N)
                   ? 0
                   : ((R * R == N) ? R : static_cast<unsigned int>(iSquareRoot<N, R + 1>::value));
    }
    enum Result
    {
        value = iSquareRoot::solve()
    };
};

template <unsigned int N>
struct iSquareRoot<N, N>
{
    enum result
    {
        value = N
    };
};

}  // namespace priv

template <unsigned int N>
constexpr unsigned int iSquareRoot()
{
    return priv::iSquareRoot<N, 1>::value;
}

// Sum, difference and multiplication operations for signed ints that wrap on 32-bit overflow.
//
// Unsigned types are defined to do arithmetic modulo 2^n in C++. For signed types, overflow
// behavior is undefined.

template <typename T>
inline T WrappingSum(T lhs, T rhs)
{
    uint32_t lhsUnsigned = static_cast<uint32_t>(lhs);
    uint32_t rhsUnsigned = static_cast<uint32_t>(rhs);
    return static_cast<T>(lhsUnsigned + rhsUnsigned);
}

template <typename T>
inline T WrappingDiff(T lhs, T rhs)
{
    uint32_t lhsUnsigned = static_cast<uint32_t>(lhs);
    uint32_t rhsUnsigned = static_cast<uint32_t>(rhs);
    return static_cast<T>(lhsUnsigned - rhsUnsigned);
}

inline int32_t WrappingMul(int32_t lhs, int32_t rhs)
{
    int64_t lhsWide = static_cast<int64_t>(lhs);
    int64_t rhsWide = static_cast<int64_t>(rhs);
    // The multiplication is guaranteed not to overflow.
    int64_t resultWide = lhsWide * rhsWide;
    // Implement the desired wrapping behavior by masking out the high-order 32 bits.
    resultWide = resultWide & 0xffffffffLL;
    // Casting to a narrower signed type is fine since the casted value is representable in the
    // narrower type.
    return static_cast<int32_t>(resultWide);
}

inline float scaleScreenDimensionToNdc(float dimensionScreen, float viewportDimension)
{
    return 2.0f * dimensionScreen / viewportDimension;
}

inline float scaleScreenCoordinateToNdc(float coordinateScreen, float viewportDimension)
{
    float halfShifted = coordinateScreen / viewportDimension;
    return 2.0f * (halfShifted - 0.5f);
}

}  // namespace gl

namespace rx
{

template <typename T>
T roundUp(const T value, const T alignment)
{
    auto temp = value + alignment - static_cast<T>(1);
    return temp - temp % alignment;
}

template <typename T>
constexpr T roundUpPow2(const T value, const T alignment)
{
    ASSERT(gl::isPow2(alignment));
    return (value + (alignment - 1)) & ~(alignment - 1);
}

template <typename T>
constexpr T roundDownPow2(const T value, const T alignment)
{
    ASSERT(gl::isPow2(alignment));
    return value & ~(alignment - 1);
}

template <typename T>
angle::CheckedNumeric<T> CheckedRoundUpPow2(const T value, const T alignment)
{
    ASSERT(gl::isPow2(alignment));
    angle::CheckedNumeric<T> checkedValue(value);
    angle::CheckedNumeric<T> checkedAlignment(alignment);
    return (checkedValue + checkedAlignment - 1) & ~(checkedAlignment - 1);
}

template <typename T>
angle::CheckedNumeric<T> CheckedRoundUp(const T value, const T alignment)
{
    angle::CheckedNumeric<T> checkedValue(value);
    angle::CheckedNumeric<T> checkedAlignment(alignment);
    return roundUp(checkedValue, checkedAlignment);
}

inline constexpr unsigned int UnsignedCeilDivide(unsigned int value, unsigned int divisor)
{
    unsigned int divided = value / divisor;
    return (divided + ((value % divisor == 0) ? 0 : 1));
}

inline constexpr uint64_t UnsignedCeilDivide64(uint64_t value, uint64_t divisor)
{
    uint64_t divided = value / divisor;
    return (divided + ((value % divisor == 0) ? 0 : 1));
}

#if defined(__has_builtin)
#    define ANGLE_HAS_BUILTIN(x) __has_builtin(x)
#else
#    define ANGLE_HAS_BUILTIN(x) 0
#endif

#if defined(_MSC_VER)

#    define ANGLE_ROTL(x, y) _rotl(x, y)
#    define ANGLE_ROTL64(x, y) _rotl64(x, y)
#    define ANGLE_ROTR16(x, y) _rotr16(x, y)

#elif defined(__clang__) && ANGLE_HAS_BUILTIN(__builtin_rotateleft32) && \
    ANGLE_HAS_BUILTIN(__builtin_rotateleft64) && ANGLE_HAS_BUILTIN(__builtin_rotateright16)

#    define ANGLE_ROTL(x, y) __builtin_rotateleft32(x, y)
#    define ANGLE_ROTL64(x, y) __builtin_rotateleft64(x, y)
#    define ANGLE_ROTR16(x, y) __builtin_rotateright16(x, y)

#else

inline uint32_t RotL(uint32_t x, int8_t r)
{
    return (x << r) | (x >> (32 - r));
}

inline uint64_t RotL64(uint64_t x, int8_t r)
{
    return (x << r) | (x >> (64 - r));
}

inline uint16_t RotR16(uint16_t x, int8_t r)
{
    return (x >> r) | (x << (16 - r));
}

#    define ANGLE_ROTL(x, y) ::rx::RotL(x, y)
#    define ANGLE_ROTL64(x, y) ::rx::RotL64(x, y)
#    define ANGLE_ROTR16(x, y) ::rx::RotR16(x, y)

#endif  // defined(_MSC_VER)

}  // namespace rx

#endif  // COMMON_MATHUTIL_H_
