1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
|
#pragma once
#include "bitvector.h"
#include "traits.h"
#include <util/memory/blob.h>
#include <cstring>
template <typename T>
class TReadonlyBitVector {
public:
using TWord = T;
using TTraits = TBitSeqTraits<TWord>;
TReadonlyBitVector()
: Size_()
, Data_()
{
}
explicit TReadonlyBitVector(const TBitVector<T>& vector)
: Size_(vector.Size_)
, Data_(vector.Data_.data())
{
}
bool Test(ui64 pos) const {
return TTraits::Test(Data_, pos, Size_);
}
TWord Get(ui64 pos, ui8 width, TWord mask) const {
return TTraits::Get(Data_, pos, width, mask, Size_);
}
TWord Get(ui64 pos, ui8 width) const {
return Get(pos, width, TTraits::ElemMask(width));
}
ui64 Size() const {
return Size_;
}
const T* Data() const {
return Data_;
}
static void SaveForReadonlyAccess(IOutputStream* out, const TBitVector<T>& bv) {
::Save(out, bv.Size_);
::Save(out, static_cast<ui64>(bv.Data_.size()));
::SavePodArray(out, bv.Data_.data(), bv.Data_.size());
}
virtual TBlob LoadFromBlob(const TBlob& blob) {
size_t read = 0;
auto cursor = [&]() { return blob.AsUnsignedCharPtr() + read; };
auto readToPtr = [&](auto* ptr) {
memcpy(ptr, cursor(), sizeof(*ptr));
read += sizeof(*ptr);
};
readToPtr(&Size_);
ui64 wordCount{};
readToPtr(&wordCount);
Data_ = reinterpret_cast<const T*>(cursor());
read += wordCount * sizeof(T);
return blob.SubBlob(read, blob.Size());
}
private:
ui64 Size_;
const T* Data_;
};
|