I was trying to make a bitfield substitute. The primary motive is to have something that can be easily serialized / deserialized. So I created a bitfield class.
template <typename T, size_t ...SIZES>
struct BitField {
using Type = T;
template <size_t I>
void set (T v)
{
...
}
template <size_t I>
T get ()
{
...
}
T value_;
};
So a bitfiled can be created like below:
BitField<uint16_t, 4, 3, 9> field; // creates a 4bit, 3bit and 9bit field in a uint16_t
But there is no nice way to set and get the field. With the above interface, we get and set each field by index.
field.get<0>()
field.set<0>(10)
I wanted to give it a easy syntax, like a variable access and assignment. And I am not clear how I can do it. I created a Field class. The idea is to make a union :
struct Mpls {
using BF = BitField<uint32_t, 20, 3, 1, 8>;
union Label {
BF _bf;
Field<0, BF> _label; // this will act like a variable
Field<1, BF> _exp;
Field<2, BF> _eos;
Field<3, BF> _ttl;
} label;
};
The Field class is defined as below. But I don't know if this is strictly legal?
template <size_t I, typename BF>
struct Field {
using Type = typename BF::Type;
void operator = (Type v)
{
// typecast 'this' to 'BitField class' and here is where I have doubt if this is okay.
((BF *)this)->template set<I>(v);
}
operator Type()
{
return ((BF *)this)->template get<I>();
}
};
I can set the fields like this.
mpls.label._ttl = 0xff;
This works. But is it okay to do this?
Aucun commentaire:
Enregistrer un commentaire