Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.189.193.172] |
|
Сообщ.
#1
,
|
|
|
Если кому надо, класс для работы с битовыми полями:
template <typename T, UINT32 LSB, UINT32 MSB> class CBitField { enum { MASK = ((1<<(MSB - LSB + 1))-1) }; enum { UMASK = (-1) ^ MASK << LSB }; T m_field; public: operator T() const { return (m_field>>LSB) & MASK; } template <typename U> T operator = (U val) { m_field &= UMASK; m_field |= (static_cast<T>(val) & MASK) << LSB; return *this; } }; Шаблонный параметр T определяет тип, в котором выделяется битовое поле. LSB - младший бит в поле, MSB - старший бит. Используется следующим образом: union UToneType { CBitField<UINT16, 0, 3> energy; CBitField<UINT16,13,13> reuse; CBitField<UINT16,14,14> report; CBitField<UINT16,15,15> cyclic; UINT16 packet; UToneType(UINT16 init_value=0): packet(init_value) {} }; Работа с полным пакетом осуществляется через packet. Предупреждение: при попытке засунуть битовое поле в функцию с шаболонным параметром, оператор T() вызывать вручную или указывать тип T непосредственно, т.к. компилятор в шаблонный параметр будет подставлять класс CBitField<....>, а не тип в битовом поле. Например, код: template <typename T> void LOG_print(T value) { printf("%x\n",value); } int main() { UToneType uTone; uTone.packet = 0xAAAA; LOG_print(uTone.energy); LOG_print(static_cast<UINT16>(uTone.energy)); LOG_print<UINT16>(uTone.energy); return 0; } выведет Цитата aaaa a a |
Сообщ.
#2
,
|
|
|
Вообще-то использовать типы вроде UINT32 - не очень хорошая мысль. Лучше заменить на unsigned. Не должен один простой отдельностоящий класс тянуть за собой другие необязательные/специфичные библиотеки/заголовочные файлы. Тем более ради всего-лишь одного-единственного примитивного определения.
|
Сообщ.
#3
,
|
|
|
Я специально не стал приаттачивать заголовочный файл. Пусть каждый, кому это понадобится, пропишет типы, которые определены у него. В то же время, тип unsigned не есть платформонезависимый, и, при переносе проекта, скажем, с 16-разрядной платформы на 32-разрядную, могут возникнуть проблемы.
|
Сообщ.
#4
,
|
|
|
Ага
Цитата T m_field; Цитата А не сдвинуть ли мне 32-разрядную переменную на пару миллионов бит вправо? return (m_field>>LSB) & MASK; |
Сообщ.
#5
,
|
|
|
Цитата trainer @ Я не возражаю Сдвиг у нас не циклический, поэтому и получим 0 на выходе.А не сдвинуть ли мне 32-разрядную переменную на пару миллионов бит вправо? З.Ы. не для кривых рук делалось. |
Сообщ.
#6
,
|
|
|
Цитата Rikkie @ Не факт.Сдвиг у нас не циклический, поэтому и получим 0 на выходе. Один компилятор/процессор может ничего не делать, а другой - сдвинуть на 1000000%32=0 бит вправо. |