module artemisd.utils.ext;

import std.bitmanip;
import core.bitop;
import std.algorithm;

auto isEmpty(BitArray ba)
{
    for(auto i=0; i<ba.dim(); ++i)
        if( ba.ptr[i] )
            return false;

    return true;
}

auto nextSetBit(BitArray ba, size_t index)
{
    auto u = index / ba.bitsPerSizeT;
    if( u >= ba.dim() ) return -1;

    auto d = (index+1)%ba.bitsPerSizeT;
    auto b = d > 0 ? ba.ptr[u] & (0xffffffff<<d) : 0;
    while(true)
    {
        if( b )
        {
            return u*ba.bitsPerSizeT + bsf(b);
        }

        if( ++u >= ba.dim() )
            return -1;

        b = ba.ptr[u];
    }
}

bool intersects(BitArray set1, BitArray set2) {
    auto dim = min(set1.dim(), set2.dim());
    for(auto i=0; i<dim; ++i)
    {
        if( (set1.ptr[i] & set2.ptr[i]) != 0 )
            return true;
    }
    return false;
}

auto ref getWithDefault(K,V)(ref V[K] aa, K key, lazy V defValue)
{
    auto p = key in aa;
    return p ? *p : (aa[key] = defValue());
}