これは、非常に単純な静的サイズのビット ベクトルの実装です。ヘッダーに依存しているため、機能するには C++11 が必要です<cstdint>
が、このヘッダーは C99 機能に基づいているため、かなり一般的に見られます。ピンチでは、C<stdint.h>
ヘッダーを使用して、代わりにグローバル名前空間の型を使用することができます。
注:これはオンザフライで入力されたものであり、まったくテストされていません。私はそれがコンパイルされることさえ確認しませんでした。そのため、エラーが発生する可能性があります。
#include <cstdint> // ::std::uint64_t type
#include <cstddef> // ::std::size_t type
#include <algorithm>
class my_bitvector_base {
protected:
class bitref { // Prevent this class from being used anywhere else.
public:
bitref(::std::uint64_t &an_int, ::std::uint64_t mask)
: an_int_(an_int), mask_(mask)
{
}
const bitref &operator =(bool val) {
if (val) {
an_int_ |= mask_;
} else {
an_int_ &= ~mask_;
}
return *this;
}
const bitref &operator =(const bitref &br) {
return this->operator =(bool(br));
}
operator bool() const {
return ((an_int_ & mask_) != 0) ? true : false;
}
private:
::std::uint64_t &an_int_;
::std::uint64_t mask_;
};
};
template < ::std::size_t Size >
class my_bitvector : public my_bitvector_base {
private:
static constexpr ::std::size_t numints = ((Size + 63) / 64);
public:
my_bitvector() { ::std::fill(array, array + numints, 0); }
bool operator [](::std::size_t bitnum) const {
const ::std::size_t bytenum = bit / 64;
bitnum = bitnum % 64;
return ((ints_[bytenum] & (::std::uint64_t(1) << bitnum)) != 0) ? true : false;
}
bitref operator[](::std::size_t bitnum) {
const ::std::size_t bytenum = bit / 64;
bitnum = bitnum % 64;
::std::uint64_t mask = ::std::uint64_t(1) << bitnum;
return bitref(ints_[bytenum], mask);
}
private:
::std::uint64_t ints_[numints];
};
// Example uses
void test()
{
my_bitvector<70> bits; // A 70 bit long bit vector initialized to all false
bits[1] = true; // Set bit 1 to true
bool abit = bits[1]; // abit should be true.
abit = bits[69]; // abit should be false.
}
すべてmy_bitvector_base
は、一種のプライベート タイプを作成することです。であるため、派生クラスのインターフェイスまたは実装でprotected
言及できますが、他のコンテキストで言及することはできません。これにより、人々がbitref
. これは重要です。実際には、C++ 標準委員会が配列要素への代入などを実装していないためbitref
、結果への代入を許可するためだけに存在するからです。operator []
operator []=
ご覧のとおり、ビット ベクトルは基本的にビットの配列です。手の込んだビット ベクトルは、すべて true または false に初期化されたビットの「無限」配列をシミュレートします。これは、設定された最後のビットとその前のすべてのビットを追跡することによって行われます。その後、少し要求すると、初期化された値が返されます。
優れたビット ベクトルはoperator &
、ビット操作操作に関して非常に大きな符号なし整数のように動作するように、その他のそのような機能も実装します。