Konzeptionsfrage zu Bitsetähnlichem Typ
-
Hey Leute,
ich wollte als Übung den Datentyp "Bitset" aus der STL nachprogrammieren.
Das Konzept sieht in etwa so aus:template<size_t N> class mein_bitset { //array allokieren, das mindestens N bits halten kann size_t bits[ N/(sizeof(size_t)*CHAR_BIT) + (N%CHAR_BIT) ? 1 : 0 ]; };Auf einzelne Bits zuzugreifen und Operatoren zu überladen wie ODER oder UND sind kein Problem. Allerdings habe ich Probleme, den Shift Operator effizient zu implementieren.
Theoretisch könnte man ja ein temporäres Array erstellen, und dann bit für bit dieses nach dem Vorbild des Originalen (je nachdem, wie geshiftet wird) bestücken. Ich frage mich aber, ob das nicht irgendwie performanter geht.
Mein erster Gedanke war memmove, allerdings würde das ja leicht die array-grenzen überschreiben. Zudem können ja nur bytes verschoben werden. Dadurch könnte ein Shift um 1 nicht realisiert werden.
Mein nächster Gedanke war es, "Pufferbytes" einzufügen.class mein_bitset { //Ein Puffer-size_t am Anfang, eins am Ende size_t bits[ N/(sizeof(size_t)*CHAR_BIT) + (N%CHAR_BIT) ? 3 : 2 ]; size_t start; size_t end; };Hier vergrößere ich das Array um 2 size_t's. Der Sinn ist Folgender: Sollte das Bitset um eins nach links geshiftet werden, "zeigt" start nicht mehr auf das erste Bit vom 2. size_t, sondern auf das letzte bit des ersten (Puffer-)size_t's. Das ganze ist dann aber deutlich aufwändiger zu implementieren.
Wie würdet ihr so ein Problem lösen? Gibt es einen anderen Weg, den Shift Operator performant zu implementieren? Ich freue mich über alle Anregungen

-
Habs jetzt nicht überprüft, sollte aber klappen:
template <int N> mein_bitset<N> mein_bitset<N>::left_shift(unsigned int shifts) const { const static int array_size = N/(sizeof(size_t)*CHAR_BIT) + (N%CHAR_BIT) ? 1 : 0; //gehoert eigentlich in die Klasse... const int overlap = sizeof(size_t)*CHAR_BIT - shifts; mein_bitset<N> tmp; for (size_t i = 0; i < array_size-1; ++i) { tmp.bits[i] = bits[i] << shifts + bits[i+1] >> overlap; } tmp.bits[array_size-1] = bits[array_size-1] << shifts; return tmp; } template <int N> mein_bitset<N> operator<< (mein_bitset<N> const& lhs, unsigned int rhs) { return lhs.left_shift(rhs); }
-
Perfekt! Nach Genau so etwas hatte ich gesucht. Danke
