aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/containers/bitseq/readonly_bitvector.h
blob: 8612739c3f70f1713694cc525f4fb5a6b9a5ad7a (plain) (blame)
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_;
};