//
// Copyright 2015 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.
//
// bitset_utils:
//   Bitset-related helper classes, such as a fast iterator to scan for set bits.
//

#ifndef COMMON_BITSETITERATOR_H_
#define COMMON_BITSETITERATOR_H_

#include <stdint.h>

#include <bitset>

#include "common/angleutils.h"
#include "common/debug.h"
#include "common/mathutil.h"
#include "common/platform.h"

namespace angle
{

template <size_t N, typename BitsT>
class BitSetT final
{
  public:
    class Reference final
    {
      public:
        ~Reference() {}
        Reference &operator=(bool x)
        {
            mParent->set(mBit, x);
            return *this;
        }
        operator bool() const { return mParent->test(mBit); }

      private:
        friend class BitSetT;

        Reference(BitSetT *parent, std::size_t bit) : mParent(parent), mBit(bit) {}

        BitSetT *mParent;
        std::size_t mBit;
    };

    class Iterator final
    {
      public:
        Iterator(const BitSetT &bits);
        Iterator &operator++();

        bool operator==(const Iterator &other) const;
        bool operator!=(const Iterator &other) const;
        std::size_t operator*() const;

      private:
        std::size_t getNextBit();

        BitSetT mBitsCopy;
        std::size_t mCurrentBit;
    };

    BitSetT();
    BitSetT(BitsT value);
    ~BitSetT();

    BitSetT(const BitSetT &other);
    BitSetT &operator=(const BitSetT &other);

    bool operator==(const BitSetT &other) const;
    bool operator!=(const BitSetT &other) const;

    constexpr bool operator[](std::size_t pos) const;
    Reference operator[](std::size_t pos) { return Reference(this, pos); }

    bool test(std::size_t pos) const;

    bool all() const;
    bool any() const;
    bool none() const;
    std::size_t count() const;

    constexpr std::size_t size() const { return N; }

    BitSetT &operator&=(const BitSetT &other);
    BitSetT &operator|=(const BitSetT &other);
    BitSetT &operator^=(const BitSetT &other);
    BitSetT operator~() const;

    BitSetT operator<<(std::size_t pos) const;
    BitSetT &operator<<=(std::size_t pos);
    BitSetT operator>>(std::size_t pos) const;
    BitSetT &operator>>=(std::size_t pos);

    BitSetT &set();
    BitSetT &set(std::size_t pos, bool value = true);

    BitSetT &reset();
    BitSetT &reset(std::size_t pos);

    BitSetT &flip();
    BitSetT &flip(std::size_t pos);

    unsigned long to_ulong() const { return static_cast<unsigned long>(mBits); }
    BitsT bits() const { return mBits; }

    Iterator begin() const { return Iterator(*this); }
    Iterator end() const { return Iterator(BitSetT()); }

  private:
    constexpr static BitsT Bit(std::size_t x) { return (static_cast<BitsT>(1) << x); }
    constexpr static BitsT Mask(std::size_t x) { return ((Bit(x - 1) - 1) << 1) + 1; }

    BitsT mBits;
};

template <size_t N>
class IterableBitSet : public std::bitset<N>
{
  public:
    IterableBitSet() {}
    IterableBitSet(const std::bitset<N> &implicitBitSet) : std::bitset<N>(implicitBitSet) {}

    class Iterator final
    {
      public:
        Iterator(const std::bitset<N> &bits);
        Iterator &operator++();

        bool operator==(const Iterator &other) const;
        bool operator!=(const Iterator &other) const;
        unsigned long operator*() const { return mCurrentBit; }

      private:
        unsigned long getNextBit();

        static constexpr size_t BitsPerWord = sizeof(uint32_t) * 8;
        std::bitset<N> mBits;
        unsigned long mCurrentBit;
        unsigned long mOffset;
    };

    Iterator begin() const { return Iterator(*this); }
    Iterator end() const { return Iterator(std::bitset<N>(0)); }
};

template <size_t N>
IterableBitSet<N>::Iterator::Iterator(const std::bitset<N> &bitset)
    : mBits(bitset), mCurrentBit(0), mOffset(0)
{
    if (mBits.any())
    {
        mCurrentBit = getNextBit();
    }
    else
    {
        mOffset = static_cast<unsigned long>(rx::roundUp(N, BitsPerWord));
    }
}

template <size_t N>
typename IterableBitSet<N>::Iterator &IterableBitSet<N>::Iterator::operator++()
{
    ASSERT(mBits.any());
    mBits.set(mCurrentBit - mOffset, 0);
    mCurrentBit = getNextBit();
    return *this;
}

template <size_t N>
bool IterableBitSet<N>::Iterator::operator==(const Iterator &other) const
{
    return mOffset == other.mOffset && mBits == other.mBits;
}

template <size_t N>
bool IterableBitSet<N>::Iterator::operator!=(const Iterator &other) const
{
    return !(*this == other);
}

template <size_t N>
unsigned long IterableBitSet<N>::Iterator::getNextBit()
{
    // TODO(jmadill): Use 64-bit scan when possible.
    static constexpr std::bitset<N> wordMask(std::numeric_limits<uint32_t>::max());

    while (mOffset < N)
    {
        uint32_t wordBits = static_cast<uint32_t>((mBits & wordMask).to_ulong());
        if (wordBits != 0)
        {
            return gl::ScanForward(wordBits) + mOffset;
        }

        mBits >>= BitsPerWord;
        mOffset += BitsPerWord;
    }
    return 0;
}

template <size_t N, typename BitsT>
BitSetT<N, BitsT>::BitSetT() : mBits(0)
{
    static_assert(N > 0, "Bitset type cannot support zero bits.");
    static_assert(N <= sizeof(BitsT) * 8, "Bitset type cannot support a size this large.");
}

template <size_t N, typename BitsT>
BitSetT<N, BitsT>::BitSetT(BitsT value) : mBits(value & Mask(N))
{
}

template <size_t N, typename BitsT>
BitSetT<N, BitsT>::~BitSetT()
{
}

template <size_t N, typename BitsT>
BitSetT<N, BitsT>::BitSetT(const BitSetT &other) : mBits(other.mBits)
{
}

template <size_t N, typename BitsT>
BitSetT<N, BitsT> &BitSetT<N, BitsT>::operator=(const BitSetT &other)
{
    mBits = other.mBits;
    return *this;
}

template <size_t N, typename BitsT>
bool BitSetT<N, BitsT>::operator==(const BitSetT &other) const
{
    return mBits == other.mBits;
}

template <size_t N, typename BitsT>
bool BitSetT<N, BitsT>::operator!=(const BitSetT &other) const
{
    return mBits != other.mBits;
}

template <size_t N, typename BitsT>
constexpr bool BitSetT<N, BitsT>::operator[](std::size_t pos) const
{
    return test(pos);
}

template <size_t N, typename BitsT>
bool BitSetT<N, BitsT>::test(std::size_t pos) const
{
    return (mBits & Bit(pos)) != 0;
}

template <size_t N, typename BitsT>
bool BitSetT<N, BitsT>::all() const
{
    ASSERT(mBits == (mBits & Mask(N)));
    return mBits == Mask(N);
}

template <size_t N, typename BitsT>
bool BitSetT<N, BitsT>::any() const
{
    ASSERT(mBits == (mBits & Mask(N)));
    return (mBits != 0);
}

template <size_t N, typename BitsT>
bool BitSetT<N, BitsT>::none() const
{
    ASSERT(mBits == (mBits & Mask(N)));
    return (mBits == 0);
}

template <size_t N, typename BitsT>
std::size_t BitSetT<N, BitsT>::count() const
{
    return gl::BitCount(mBits);
}

template <size_t N, typename BitsT>
BitSetT<N, BitsT> &BitSetT<N, BitsT>::operator&=(const BitSetT &other)
{
    mBits &= other.mBits;
    return *this;
}

template <size_t N, typename BitsT>
BitSetT<N, BitsT> &BitSetT<N, BitsT>::operator|=(const BitSetT &other)
{
    mBits |= other.mBits;
    return *this;
}

template <size_t N, typename BitsT>
BitSetT<N, BitsT> &BitSetT<N, BitsT>::operator^=(const BitSetT &other)
{
    mBits = (mBits ^ other.mBits) & Mask(N);
    return *this;
}

template <size_t N, typename BitsT>
BitSetT<N, BitsT> BitSetT<N, BitsT>::operator~() const
{
    return BitSetT<N, BitsT>(~mBits & Mask(N));
}

template <size_t N, typename BitsT>
BitSetT<N, BitsT> BitSetT<N, BitsT>::operator<<(std::size_t pos) const
{
    return BitSetT<N, BitsT>((mBits << pos) & Mask(N));
}

template <size_t N, typename BitsT>
BitSetT<N, BitsT> &BitSetT<N, BitsT>::operator<<=(std::size_t pos)
{
    mBits = (mBits << pos & Mask(N));
    return *this;
}

template <size_t N, typename BitsT>
BitSetT<N, BitsT> BitSetT<N, BitsT>::operator>>(std::size_t pos) const
{
    return BitSetT<N, BitsT>(mBits >> pos);
}

template <size_t N, typename BitsT>
BitSetT<N, BitsT> &BitSetT<N, BitsT>::operator>>=(std::size_t pos)
{
    mBits = ((mBits >> pos) & Mask(N));
    return *this;
}

template <size_t N, typename BitsT>
BitSetT<N, BitsT> &BitSetT<N, BitsT>::set()
{
    mBits = Mask(N);
    return *this;
}

template <size_t N, typename BitsT>
BitSetT<N, BitsT> &BitSetT<N, BitsT>::set(std::size_t pos, bool value)
{
    if (value)
    {
        mBits |= Bit(pos);
    }
    else
    {
        reset(pos);
    }
    return *this;
}

template <size_t N, typename BitsT>
BitSetT<N, BitsT> &BitSetT<N, BitsT>::reset()
{
    mBits = 0;
    return *this;
}

template <size_t N, typename BitsT>
BitSetT<N, BitsT> &BitSetT<N, BitsT>::reset(std::size_t pos)
{
    mBits &= ~Bit(pos);
    return *this;
}

template <size_t N, typename BitsT>
BitSetT<N, BitsT> &BitSetT<N, BitsT>::flip()
{
    mBits ^= Mask(N);
    return *this;
}

template <size_t N, typename BitsT>
BitSetT<N, BitsT> &BitSetT<N, BitsT>::flip(std::size_t pos)
{
    mBits ^= Bit(pos);
    return *this;
}

template <size_t N, typename BitsT>
BitSetT<N, BitsT>::Iterator::Iterator(const BitSetT &bits) : mBitsCopy(bits), mCurrentBit(0)
{
    if (bits.any())
    {
        mCurrentBit = getNextBit();
    }
}

template <size_t N, typename BitsT>
typename BitSetT<N, BitsT>::Iterator &BitSetT<N, BitsT>::Iterator::operator++()
{
    ASSERT(mBitsCopy.any());
    mBitsCopy.reset(mCurrentBit);
    mCurrentBit = getNextBit();
    return *this;
}

template <size_t N, typename BitsT>
bool BitSetT<N, BitsT>::Iterator::operator==(const Iterator &other) const
{
    return mBitsCopy == other.mBitsCopy;
}

template <size_t N, typename BitsT>
bool BitSetT<N, BitsT>::Iterator::operator!=(const Iterator &other) const
{
    return !(*this == other);
}

template <size_t N, typename BitsT>
std::size_t BitSetT<N, BitsT>::Iterator::operator*() const
{
    return mCurrentBit;
}

template <size_t N, typename BitsT>
std::size_t BitSetT<N, BitsT>::Iterator::getNextBit()
{
    if (mBitsCopy.none())
    {
        return 0;
    }

    return gl::ScanForward(mBitsCopy.mBits);
}

template <size_t N>
using BitSet32 = BitSetT<N, uint32_t>;

// ScanForward for 64-bits requires a 64-bit implementation.
#if defined(ANGLE_X64_CPU)
template <size_t N>
using BitSet64 = BitSetT<N, uint64_t>;
#endif  // defined(ANGLE_X64_CPU)

namespace priv
{

template <size_t N, typename T>
using EnableIfBitsFit = typename std::enable_if<N <= sizeof(T) * 8>::type;

template <size_t N, typename Enable = void>
struct GetBitSet
{
    using Type = IterableBitSet<N>;
};

// Prefer 64-bit bitsets on 64-bit CPUs. They seem faster than 32-bit.
#if defined(ANGLE_X64_CPU)
template <size_t N>
struct GetBitSet<N, EnableIfBitsFit<N, uint64_t>>
{
    using Type = BitSet64<N>;
};
#else
template <size_t N>
struct GetBitSet<N, EnableIfBitsFit<N, uint32_t>>
{
    using Type = BitSet32<N>;
};
#endif  // defined(ANGLE_X64_CPU)

}  // namespace priv

template <size_t N>
using BitSet = typename priv::GetBitSet<N>::Type;

}  // angle

template <size_t N, typename BitsT>
inline angle::BitSetT<N, BitsT> operator&(const angle::BitSetT<N, BitsT> &lhs,
                                          const angle::BitSetT<N, BitsT> &rhs)
{
    return angle::BitSetT<N, BitsT>(lhs.bits() & rhs.bits());
}

template <size_t N, typename BitsT>
inline angle::BitSetT<N, BitsT> operator|(const angle::BitSetT<N, BitsT> &lhs,
                                          const angle::BitSetT<N, BitsT> &rhs)
{
    return angle::BitSetT<N, BitsT>(lhs.bits() | rhs.bits());
}

template <size_t N, typename BitsT>
inline angle::BitSetT<N, BitsT> operator^(const angle::BitSetT<N, BitsT> &lhs,
                                          const angle::BitSetT<N, BitsT> &rhs)
{
    return angle::BitSetT<N, BitsT>(lhs.bits() ^ rhs.bits());
}

#endif  // COMMON_BITSETITERATOR_H_
