124 lines
2.7 KiB
C
124 lines
2.7 KiB
C
|
/*
|
||
|
* This file Copyright (C) 2009 Charles Kerr <charles@transmissionbt.com>
|
||
|
*
|
||
|
* This file is licensed by the GPL version 2. Works owned by the
|
||
|
* Transmission project are granted a special exemption to clause 2(b)
|
||
|
* so that the bulk of its code can remain under the MIT license.
|
||
|
* This exemption does not extend to derived works not owned by
|
||
|
* the Transmission project.
|
||
|
*
|
||
|
* $Id:$
|
||
|
*/
|
||
|
|
||
|
#ifndef __TRANSMISSION__
|
||
|
#error only libtransmission should #include this header.
|
||
|
#endif
|
||
|
|
||
|
#ifndef TR_BITSET_H
|
||
|
#define TR_BITSET_H 1
|
||
|
|
||
|
#include "transmission.h"
|
||
|
#include "bitfield.h"
|
||
|
|
||
|
/** This like a tr_bitfield, but supports haveAll and haveNone */
|
||
|
typedef struct tr_bitset
|
||
|
{
|
||
|
tr_bool haveAll;
|
||
|
tr_bool haveNone;
|
||
|
tr_bitfield bitfield;
|
||
|
}
|
||
|
tr_bitset;
|
||
|
|
||
|
static TR_INLINE void
|
||
|
tr_bitsetConstructor( tr_bitset * b, int size )
|
||
|
{
|
||
|
tr_bitfieldConstruct( &b->bitfield, size );
|
||
|
}
|
||
|
|
||
|
static TR_INLINE void
|
||
|
tr_bitsetDestructor( tr_bitset * b )
|
||
|
{
|
||
|
tr_bitfieldDestruct( &b->bitfield );
|
||
|
}
|
||
|
|
||
|
static TR_INLINE void
|
||
|
tr_bitsetReserve( tr_bitset * b, size_t size )
|
||
|
{
|
||
|
if( b->bitfield.bitCount < size )
|
||
|
{
|
||
|
tr_bitfieldDestruct( &b->bitfield );
|
||
|
tr_bitfieldConstruct( &b->bitfield, size );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static TR_INLINE tr_bool
|
||
|
tr_bitsetHasFast( const tr_bitset * b, const size_t nth )
|
||
|
{
|
||
|
if( b->haveAll ) return TRUE;
|
||
|
if( b->haveNone ) return FALSE;
|
||
|
return tr_bitfieldHasFast( &b->bitfield, nth );
|
||
|
}
|
||
|
|
||
|
static TR_INLINE tr_bool
|
||
|
tr_bitsetHas( const tr_bitset * b, const size_t nth )
|
||
|
{
|
||
|
if( b->haveAll ) return TRUE;
|
||
|
if( b->haveNone ) return FALSE;
|
||
|
return tr_bitfieldHas( &b->bitfield, nth );
|
||
|
}
|
||
|
|
||
|
static TR_INLINE void
|
||
|
tr_bitsetOr( tr_bitfield * a, const tr_bitset * b )
|
||
|
{
|
||
|
if( b->haveAll )
|
||
|
tr_bitfieldAddRange( a, 0, a->bitCount );
|
||
|
else if( !b->haveNone )
|
||
|
tr_bitfieldOr( a, &b->bitfield );
|
||
|
}
|
||
|
|
||
|
/* set 'a' to all the flags that were in 'a' but not 'b' */
|
||
|
static TR_INLINE void
|
||
|
tr_bitsetDifference( tr_bitfield * a, const tr_bitset * b )
|
||
|
{
|
||
|
if( b->haveAll )
|
||
|
tr_bitfieldClear( a );
|
||
|
else if( !b->haveNone )
|
||
|
tr_bitfieldDifference( a, &b->bitfield );
|
||
|
}
|
||
|
|
||
|
static TR_INLINE double
|
||
|
tr_bitsetPercent( const tr_bitset * b )
|
||
|
{
|
||
|
if( b->haveAll ) return 1.0;
|
||
|
if( b->haveNone ) return 0.0;
|
||
|
if( b->bitfield.bitCount == 0 ) return 0.0;
|
||
|
return tr_bitfieldCountTrueBits( &b->bitfield ) / (double)b->bitfield.bitCount;
|
||
|
}
|
||
|
|
||
|
static TR_INLINE void
|
||
|
tr_bitsetSetHaveAll( tr_bitset * b )
|
||
|
{
|
||
|
b->haveAll = 1;
|
||
|
b->haveNone = 0;
|
||
|
}
|
||
|
|
||
|
static TR_INLINE void
|
||
|
tr_bitsetSetHaveNone( tr_bitset * b )
|
||
|
{
|
||
|
b->haveAll = 0;
|
||
|
b->haveNone = 1;
|
||
|
}
|
||
|
|
||
|
static TR_INLINE int
|
||
|
tr_bitsetAdd( tr_bitset * b, int i )
|
||
|
{
|
||
|
int ret = 0;
|
||
|
if( !b->haveAll ) {
|
||
|
b->haveNone = 0;
|
||
|
ret = tr_bitfieldAdd( &b->bitfield, i );
|
||
|
}
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
#endif
|