Template for endianness-free code, data always packed as BIG-Endian It's been a while since I've been properly grilled about my code.

I had this Idea which should probably never make it into production code but still I couldn't find anything seriously wrong with it at a glance...

All your comments are welcome.

#ifndef BITFIELDMEMBER_H
#define BITFIELDMEMBER_H

/************************************************************************
 * This is for creating Endianness-free bit-fields.
 * The values are always packed as big-endian.
 * When used for arithmetics/comparison, the values are read in the
 * proper endianness for the current CPU mode.
 *
 * Note: The fields can overlap if you want
 */

template&lt;int firstBit, int bitSize&gt;
struct BitFieldMember
{
    typedef BitFieldMember&lt;firstBit, bitSize&gt; self_t;
    typedef unsigned char uchar;
    enum {
        lastBit = firstBit + bitSize - 1,
        mask = (1 &lt;&lt; bitSize) - 1
    };
    uchar *selfArray()
    {
        return reinterpret_cast&lt;uchar *&gt;(this);
    }
    const uchar *selfArray() const
    {
        return reinterpret_cast&lt;const uchar *&gt;(this);
    }

    /* used to read data from the field */
    /* will also work with all the operators that work with integral types */
    inline operator unsigned() const
    {
        const uchar *arr = selfArray();
        const uchar *p = arr + firstBit / 8;
        int i = 8 - (firstBit &amp; 7);
        unsigned ret = 0;
        ret |= *p;
        while (i &lt; bitSize)
        {
            ret &lt;&lt;= 8;
            ret |= *(++p);
            i += 8;
        }
        return ((ret &gt;&gt; (7 - (lastBit &amp; 7))) &amp; mask);
    }

    /* used to assign a value into the field */
    inline self_t&amp; operator=(unsigned m)
    {
        uchar *arr = selfArray();
        m &amp;= mask;
        unsigned wmask = ~(mask &lt;&lt; (7 - (lastBit &amp; 7)));
        m &lt;&lt;= (7 - (lastBit &amp; 7));
        uchar *p = arr + lastBit / 8;
        int i = (lastBit &amp; 7) + 1;
        (*p &amp;= wmask) |= m;
        while (i &lt; bitSize)
        {
            m &gt;&gt;= 8;
            wmask &gt;&gt;= 8;
            (*(--p) &amp;= wmask) |= m;
            i += 8;
        }
        return *this;
    }

    inline self_t&amp; operator+=(unsigned m)
    {
        *this = *this + m;
        return *this;
    }

    inline self_t&amp; operator-=(unsigned m)
    {
        *this = *this - m;
        return *this;
    }

    inline self_t&amp; operator*=(unsigned m)
    {
        *this = *this * m;
        return *this;
    }

    inline self_t&amp; operator/=(unsigned m)
    {
        *this = *this / m;
        return *this;
    }

    inline self_t&amp; operator%=(unsigned m)
    {
        *this = *this % m;
        return *this;
    }

    inline self_t&amp; operator&lt;&lt;=(unsigned m)
    {
        *this = *this &lt;&lt; m;
        return *this;
    }

    inline self_t&amp; operator&gt;&gt;=(unsigned m)
    {
        *this = *this &gt;&gt; m;
        return *this;
    }

    inline self_t&amp; operator|=(unsigned m)
    {
        *this = *this | m;
        return *this;
    }

    inline self_t&amp; operator&amp;=(unsigned m)
    {
        *this = *this &amp; m;
        return *this;
    }

    inline self_t&amp; operator^=(unsigned m)
    {
        *this = *this ^ m;
        return *this;
    }

};
#endif


Usage example:

union header
{
    unsigned char arr[2];       // space allocation, 2 bytes (16 bits)

    BitFieldMember&lt;0, 4&gt; m1;     // first 4 bits
    BitFieldMember&lt;4, 5&gt; m2;     // The following 5 bits
    BitFieldMember&lt;9, 6&gt; m3;     // The following 6 bits, total 16 bits
};

int main()
{
    header a;
    memset(a.arr, 0, sizeof(a.arr));
    a.m1 = rand();
    a.m3 = a.m1;
    a.m2 = ~a.m1;
    return 0;
}


This sometimes wouldn't work for fields that are larger than 24 bits... the shifting may trim the most significant bits.
Your code is good, except for two methods : operator unsigned() const and self_t&amp; operator=(unsigned m). They are too complex, and by just looking at them, it is far from clear what they are doing.

First, you can add new values to your enum :

enum {
    lastBit = firstBit + bitSize - 1,
    mask = (1 &lt;&lt; bitSize) - 1,
    firstBitIndex = 8 - (firstBit &amp; 7),                         // change to proper name
    nameThisValueProperly = (7 - (lastBit &amp; 7)) &amp; mask,         // change to proper name
};


First modify your operator unsigned() const to this :

inline operator unsigned() const
{
    const uchar *arr = selfArray();
    const uchar *p = arr + firstBit / 8;

    unsigned result = CalculateSomeValue( p );

    return (result &gt;&gt; nameThisValueProperly );
}

// name this method properly
inline unsigned CalculateSomeValue( const uchar *p ) const
{
    int i = firstBitIndex;
    unsigned result = *p;

    while (i &lt; bitSize)
    {
        result &lt;&lt;= 8;
        result |= *(++p);
        i += 8;
    }

    return result;
}


Of course, you need to put proper names both for enum values and method names, so when someone looks into this code says "Aha, that is what is is doing". This way, you can easy increase code clarity.

Also, by making method smaller, you can easily test them.

More about this method, you can read in Clean code by Robert Martin.

You can do something similar for the self_t&amp; operator=(unsigned m). Break it up, until you find it clean.