//
// 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 <limits>
#include <ostream>
#include "common/unsafe_buffers.h"

#include <anglebase/numerics/safe_math.h>

#include "common/debug.h"
#include "common/platform.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>
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_UNSAFE_TODO(memcpy(&output, &source, 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)
{
    uint8_t bits[4];
    bits[0]         = priv::ToPackedUnorm8(f1);
    bits[1]         = priv::ToPackedUnorm8(f2);
    bits[2]         = priv::ToPackedUnorm8(f3);
    bits[3]         = priv::ToPackedUnorm8(f4);
    uint32_t result = 0u;
    for (int i = 0; i < 4; ++i)
    {
        int shift = i * 8;
        result |= (static_cast<uint32_t>(ANGLE_UNSAFE_TODO(bits[i])) << shift);
    }
    return result;
}

// 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, float *f)
{
    for (int i = 0; i < 4; ++i)
    {
        int shift    = i * 8;
        uint8_t bits = static_cast<uint8_t>((u >> shift) & 0xFF);
        ANGLE_UNSAFE_TODO(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)
{
    int8_t bits[4];
    bits[0]         = priv::ToPackedSnorm8(f1);
    bits[1]         = priv::ToPackedSnorm8(f2);
    bits[2]         = priv::ToPackedSnorm8(f3);
    bits[3]         = priv::ToPackedSnorm8(f4);
    uint32_t result = 0u;
    for (int i = 0; i < 4; ++i)
    {
        int shift = i * 8;
        result |= ((static_cast<uint32_t>(ANGLE_UNSAFE_TODO(bits[i])) & 0xFF) << shift);
    }
    return result;
}

// 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, float *f)
{
    for (int i = 0; i < 4; ++i)
    {
        int shift   = i * 8;
        int8_t bits = static_cast<int8_t>((u >> shift) & 0xFF);
        ANGLE_UNSAFE_TODO(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_
