2

I'm putting together a bitarray class for a GA thing I'm working on. I'm wondering if there's a better way to do the make my [] operator do assignments than what I came up with. Right now, I have the non-const version of the operator returning a secret 'bitsetter' class by value, which seems a bit excessive. I certainly can't return a bit by reference, but I'm wondering if there's a better (ie., more concise, efficient) way. Thanks in advance. Pardon my throw 0. Totally a placeholder ;)

class bitsetter
{
public:
    short ind;
    unsigned char *l;

    bitsetter & operator=(int val)
    {
        int vs = 1<<ind;
        if( val==0 ) {
            vs = ~vs;
            *l = *l & vs;
        }
        else
        {
            *l = *l | vs;
        }
        return *this;
    }


    int value() const
    {
        return ((*l)>>ind)&1;
    }

    friend std::ostream & operator << ( std::ostream & out, bitsetter const & b )
    {
        out << b.value();
        return out;
    }

    operator int () { return value(); }
};

class bitarray
{
public:
    unsigned char *bits;
    int size;

    bitarray(size_t size)
    {
        this->size = size;
        int bsize = (size%8==0)?((size+8)>>3):(size>>3);
        bits = new unsigned char[bsize];
        for(int i=0; i<size>>3; ++i)
            bits[i] = (unsigned char)0;        
    }

    ~bitarray()
    {
        delete [] bits;
    }

    int operator[](int ind) const
    {
        if( ind >= 0 && ind < size )
            return (bits[ind/8] >> (ind%8))&1;
        else
            return 0;
    }

    bitsetter operator[](int ind)
    {
        if( ind >= 0 && ind < size )
        {
            bitsetter b;
            b.l = &bits[ind/8];
            b.ind = ind%8;
            return b;
        }
        else
            throw 0;
    }
};
1
  • 1
    Seems fine to me. From what I recall, this is the approach recommended in Stroustrup. Commented Aug 24, 2012 at 20:33

1 Answer 1

2

This is the standard approach, it's called a proxy. Note that it's usually defined within the class itself:

class bitfield
{
public:
    class bit
    { };
};

Additionally, it's kept a little more "safe":

class bitfield
{
public:
    class bit
    {
    public:
        // your public stuff
    private:
        bit(short ind, unsigned char* l) :
        ind(ind), l(l)
        {}

        short ind;
        unsigned char* l;

        friend class bitfield;
    };

    bit operator[](int ind)
    {
        if (ind >= 0 && ind < size)
        {
            return bit(&bits[ind/8], ind % 8);
        }
        else
            throw std::out_of_range();
    }
};

So that people only get to see the public interface of bit, and cannot conjure up their own.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.