/*

    bitmask.h

    variable-size bit masks

    5.10.2001

    Copyright (C) 2001 by Josef Pelikan, MFF UK Prague
        http://cgg.ms.mff.cuni.cz/~pepca/

    VUCAKO Bench is Open Source software (see http://www.opensource.org/
    for description what Open Source is); you may distributed it and/or
    modify it under the terms of GNU General Public License as published
    by the Free Software Foundation; either version 2, or (at your option)
    any later version.

    This program is distributed in the hope that it will be useful, but
    WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    General Public License for more details.

    A copy of the GNU General Public License is available as
    `/usr/doc/copyright/GPL' in the Debian GNU/Linux distribution or on
    the World Wide Web at http://www.gnu.org/copyleft/gpl.html.  You can
    also obtain it by writing to the Free Software Foundation, Inc., 59
    Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/

#ifndef _BITMASK_H
#define _BITMASK_H

//-----------------------------------------------------------
//  CBitMask object:

#define MaskEnd     0x7FFFFFFF          // for getFirst() a getNext()

class CBitMask {

public:

    byte *mask;                         // bit mask (one bit per value)
    int allocMask;                      // number of allocated BYTES

    int min, max;                       // bit mask range ( (max-min)/8 <= allocMask )

        // construction / descruction:

    CBitMask ();
    CBitMask ( const CBitMask *b );

    void assign ( const CBitMask *b );

    virtual CBitMask *clone () const;
        // clones the actual object instance

    virtual ~CBitMask ();

        // access:

    void set ( int value, bool flag );
        // sets one flag value

    void on ( int value );
    void off ( int value );

    void assert ( int value );
        // prepares the mask array to hold the given value

    void setUnsafe ( int value, bool flag )
    {
        value -= min;
        if ( flag ) mask[value>>3] |= 1 << (value & 7);
        else        mask[value>>3] &= ~(1 << (value & 7));
    }

    void range ( int from, int len, bool flag );
        // sets the given range

    bool get ( int value ) const
        // gets one flag value
    {
        if ( value < min || value >= max ) return false;
        value -= min;
        return( (mask[value>>3] & (1<<(value & 7))) != 0 );
    }

    bool getUnsafe ( int value ) const
    {
        value -= min;
        return( (mask[value>>3] & (1<<(value & 7))) != 0 );
    }

    void empty ();
        // (re)initializes the mask

    int card () const;
        // bit-mask cardinality

        // iterator:

    int getFirst () const;
        // returns the first bit or MaskEnd

    int getNext ( int i ) const;
        // returns the next bit or MaskEnd

    int getLast () const;
        // returns the last bit or MaskEnd

        // set operations were removed in 1.008

    };

#endif
