aboutsummaryrefslogtreecommitdiffstats
path: root/util/memory/tempbuf.h
blob: 2cc3ebe86760a03de3f9852ed5cee67978de94fc (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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#pragma once

#include <util/system/defaults.h>
#include <util/generic/ptr.h>

/*
 * This is really fast buffer for temporary data.
 * For small sizes it works almost fast as pure alloca()
 * (by using perthreaded list of free blocks),
 * for big sizes it works as fast as malloc()/operator new()/...
 */
class TTempBuf {
public:
    /*
     * we do not want many friends for this class :)
     */
    class TImpl;

    TTempBuf();
    TTempBuf(size_t len);
    TTempBuf(const TTempBuf& b) noexcept;
    TTempBuf(TTempBuf&& b) noexcept;
    ~TTempBuf();

    TTempBuf& operator=(const TTempBuf& b) noexcept;
    TTempBuf& operator=(TTempBuf&& b) noexcept;

    Y_PURE_FUNCTION char* Data() noexcept;

    Y_PURE_FUNCTION const char* Data() const noexcept;

    Y_PURE_FUNCTION char* Current() noexcept;

    Y_PURE_FUNCTION const char* Current() const noexcept;

    Y_PURE_FUNCTION size_t Size() const noexcept;

    Y_PURE_FUNCTION size_t Filled() const noexcept;

    Y_PURE_FUNCTION size_t Left() const noexcept;

    void Reset() noexcept;
    void SetPos(size_t off);
    char* Proceed(size_t off);
    void Append(const void* data, size_t len);

    Y_PURE_FUNCTION bool IsNull() const noexcept;

private:
    TIntrusivePtr<TImpl> Impl_;
};

template <typename T>
class TTempArray: private TTempBuf {
private:
    static T* TypedPointer(char* pointer) noexcept {
        return reinterpret_cast<T*>(pointer);
    }
    static const T* TypedPointer(const char* pointer) noexcept {
        return reinterpret_cast<const T*>(pointer);
    }
    static constexpr size_t RawSize(const size_t size) noexcept { 
        return size * sizeof(T);
    }
    static constexpr size_t TypedSize(const size_t size) noexcept { 
        return size / sizeof(T);
    }

public:
    TTempArray() = default;

    TTempArray(size_t len)
        : TTempBuf(RawSize(len))
    {
    }

    T* Data() noexcept {
        return TypedPointer(TTempBuf::Data());
    }

    const T* Data() const noexcept {
        return TypedPointer(TTempBuf::Data());
    }

    T* Current() noexcept {
        return TypedPointer(TTempBuf::Current());
    }

    const T* Current() const noexcept {
        return TypedPointer(TTempBuf::Current());
    }

    size_t Size() const noexcept {
        return TypedSize(TTempBuf::Size());
    }
    size_t Filled() const noexcept {
        return TypedSize(TTempBuf::Filled());
    }

    T* Proceed(size_t off) {
        return (T*)TTempBuf::Proceed(RawSize(off));
    }
};