// Based on:
// https://www.youtube.com/watch?v=TYqbgvHfxjM
// https://stackoverflow.com/questions/31726191/is-there-a-portable-alternative-to-c-bitfields
// https://stackoverflow.com/questions/1392059/algorithm-to-generate-bit-mask

#include <iostream>
#include <stdint.h>

template<typename T, uint8_t START, uint8_t SIZE>
struct Bits
{   
    Bits()
    {
        static_assert(SIZE != 0, "Bitfield SIZE must be > 0!");
		static_assert(START < sizeof(T) * 8, "START exceeds number of bits of the chosen typename T!");
    }
    
    Bits& operator =(T v)
    {
        // mask creation for v : https://stackoverflow.com/questions/1392059/algorithm-to-generate-bit-mask
        _raw = ((v & ((1ULL << SIZE)-1)) << START) ;
        return *this;
    }
    
    operator T() const
    {
        return _raw >> START;
    }
    
    T operator ()() const
    {
        return _raw;
    }
    
    private:
    T _raw;
};


int main()
{
    uint8_t d = 0;
    Bits<uint8_t, 2,2> bitField;
    
    
    std::cout << "out 1" << std::endl;
    std::cout << +bitField << std::endl;
    
    bitField = 3;
    
    std::cout << +bitField << std::endl;
    
    bitField = 5;
    
    std::cout << +bitField << std::endl;
    std::cout << +bitField() << std::endl;
    std::cout << "done!" << std::endl;
    
    uint8_t mask;
    uint8_t param = 3;
    mask = (1 << param) - 1;
    std::cout << +mask << std::endl;
    
    

    return 0;
}
