/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef SkBitSet_DEFINED
#define SkBitSet_DEFINED

#include "SkTemplates.h"

#include <vector>

class SkBitSet {
public:
    explicit SkBitSet(int numberOfBits) {
        SkASSERT(numberOfBits >= 0);
        fDwordCount = (numberOfBits + 31) / 32;  // Round up size to 32-bit boundary.
        if (fDwordCount > 0) {
            fBitData.reset((uint32_t*)sk_calloc_throw(fDwordCount * sizeof(uint32_t)));
        }
    }

    /** Set the value of the index-th bit to true.  */
    void set(int index) {
        uint32_t mask = 1 << (index & 31);
        uint32_t* chunk = this->internalGet(index);
        SkASSERT(chunk);
        *chunk |= mask;
    }

    template<typename T>
    void setAll(T* array, int len) {
        static_assert(std::is_integral<T>::value, "T is integral");
        for (int i = 0; i < len; ++i) {
            this->set(static_cast<int>(array[i]));
        }
    }

    bool has(int index) const {
        const uint32_t* chunk = this->internalGet(index);
        uint32_t mask = 1 << (index & 31);
        return chunk && SkToBool(*chunk & mask);
    }

    /** Export indices of set bits to T array. */
    template<typename T>
    void exportTo(std::vector<T>* array) const {
        static_assert(std::is_integral<T>::value, "T is integral");
        SkASSERT(array);
        uint32_t* data = reinterpret_cast<uint32_t*>(fBitData.get());
        for (unsigned int i = 0; i < fDwordCount; ++i) {
            uint32_t value = data[i];
            if (value) {  // There are set bits
                unsigned int index = i * 32;
                for (unsigned int j = 0; j < 32; ++j) {
                    if (0x1 & (value >> j)) {
                        array->push_back(index + j);
                    }
                }
            }
        }
    }

private:
    std::unique_ptr<uint32_t, SkFunctionWrapper<void, void, sk_free>> fBitData;
    size_t fDwordCount;  // Dword (32-bit) count of the bitset.

    uint32_t* internalGet(int index) const {
        size_t internalIndex = index / 32;
        if (internalIndex >= fDwordCount) {
            return nullptr;
        }
        return fBitData.get() + internalIndex;
    }
};


#endif
