Posts tagged ‘bitset’

Typ std::bitset i flagi logiczne

2010-05-27 15:52

Napiszę dzisiaj o nierzadko zapominanej klasie z biblioteki standardowej C++, czyli o tytułowym zbiorze bitówstd::bitset. Działania na pojedynczych bitach nie są raczej czymś, co wykonujemy codziennie, ale zdarzają się sytuacje, gdy stanowią one najrozsądniejsze rozwiązanie w danej chwili. Takim typowym przypadkiem jest zbiór flag logicznych: kilku opcji działających jak przełączniki, których możliwą wartością jest tylko true albo false. Wszelkie API doskonale zna takie konstrukcje, czego przykładem może być metoda Clear urządzenia DirectX:

  1. dev->Clear (0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,
  2.     D3DCOLOR_XRGB(0, 255, 0), 1.0f, 0);

D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER jest właśnie kombinacją flag bitowych, a dwie występujące tu stałe zostały odpowiednio zdefiniowane, by dało się je łączyć operatorem sumy bitowej |.

Używając std::bitset możemy nieco uprościć obsługę takich opcji. Zamiast deklarowania specjalnych wartości, możemy użyć zwykłego enuma, np.:

  1. enum FontStyle { Bold, Italic, Underline, FontStylesCount };

bitset jest wtedy łatwy w użyciu:

  1. void FormatText(const std::string& text,
  2.     const std::bitset<FontStylesCount>& style)
  3. {
  4.     if (style.any())  // czy jakikolwiek bit został ustawiony
  5.     {
  6.         // sprawdzenie poszczególnych flag
  7.         if (style[Bold]) { /* ... */ }
  8.         if (style[Italic]) { /* ... */ }
  9.         if (style[Underline]) { /* ... */ }
  10.     }
  11. }

Zachowana jest przy tym “kompatybilność wsteczna” w stosunku do ręcznie definiowanych stałych, jeśli chcielibyśmy z nich korzystać:

  1. #define OPT(x) (1<<(x))
  2. FormatText ("Hello World!", OPT(Bold) | OPT(Italic));&#91;/cpp]
  3. lub jeżeli jakieś zewnętrzne API, w którym programujemy, korzysta z wartości bitowych zapisywanych w typach liczbowych:
  4. &#91;cpp]std::bitset<32> lp = lParam;
  5. lp.set(30).reset(31);
  6. SendMessage (hWnd, WM_KEYDOWN, VK_UP, lp.to_ulong());

Na koniec wspomnę tylko, że aby korzystać z klasy bitset do tych lub innych zastosowań, należy wpierw dołączyć standardowy nagłówek o nazwie… bitset :)

Tags: , ,
Author: Xion, posted under Programming » 4 comments
 


© 2023 Karol Kuczmarski "Xion". Layout by Urszulka. Powered by WordPress with QuickLaTeX.com.