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