#ifndef LBITFIELD_H
#define LBITFIELD_H

#define LBITFIELD_LSB_T(type, mask)                ((type)((mask) & ~((mask) - 1)))
/* Установка поля по битовой маске */
#define LBITFIELD_SET_T(type, mask, val)           ((mask) & (((type)val) * LBITFIELD_LSB_T(type, mask)))
/* Извлечение значения поля из слова по битовой маске */
#define LBITFIELD_GET_T(type, word, mask)          ((((type)word) / LBITFIELD_LSB_T(type, mask)) & ((mask) / LBITFIELD_LSB_T(type, mask)))
/* Замена в слове поля по битовой маске заданным значением */
#define LBITFIELD_UPD_T(type, word, mask, val)     ((word) = ((type)(word) & (type)~(mask)) \
                                                      | (type)LBITFIELD_SET_T(type, mask, val))

#ifndef LBITFIELD_BASETYPE
    #define LBITFIELD_BASETYPE unsigned
#endif

/* Вычисление позиции по битовой маске, т.е. младшего значащего бита в ненулевом числе
 * = pow(2, n), где n - количество нулевых младших разрядов */
#define LBITFIELD_LSB(mask)                ((LBITFIELD_BASETYPE)((mask) & ~((mask) - 1)))

/* Установка поля по битовой маске */
#define LBITFIELD_SET(mask, val)           ((mask) & (((LBITFIELD_BASETYPE)val) * LBITFIELD_LSB(mask)))
/* Извлечение значения поля из слова по битовой маске */
#define LBITFIELD_GET(word, mask)          ((((LBITFIELD_BASETYPE)word) / LBITFIELD_LSB(mask)) & ((mask) / LBITFIELD_LSB(mask)))
/* Замена в слове поля по битовой маске заданным значением */
#define LBITFIELD_UPD(word, mask, val)     ((word) = ((LBITFIELD_BASETYPE)(word) & (LBITFIELD_BASETYPE)~(mask)) \
                                                      | (LBITFIELD_BASETYPE)LBITFIELD_SET(mask, val))




#endif // LBITFIELDS_H
