summaryrefslogtreecommitdiff
path: root/include/egg/prim/eggBuffer.h
blob: 49be786232ef24f664afd21716d36caef854c9c2 (plain)
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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#ifndef EGG_BUFFER_H
#define EGG_BUFFER_H

#include "common.h"
#include "egg/core/eggHeap.h"
#include "egg/prim/eggAssert.h"

namespace EGG {

template <typename T>
class TBuffer {
public:
    class iterator {
    public:
        iterator(TBuffer *pBuffer, int index) : mBuffer(pBuffer), mIndex(index) {}

        int get_index() const {
            return mIndex;
        }

        iterator &operator++() {
            mIndex++;
            return *this;
        }

        T &operator*() {
            return (*mBuffer)(mIndex);
        }

        friend bool operator==(const iterator &rLhs, const iterator &rRhs) {
            return rLhs.mBuffer == rRhs.mBuffer && rLhs.mIndex == rRhs.mIndex;
        }
        friend bool operator!=(const iterator &rLhs, const iterator &rRhs) {
            return !(rLhs == rRhs);
        }

    private:
        TBuffer *mBuffer; // at 0x0
        int mIndex;       // at 0x4
    };

public:
    TBuffer() : mSize(0), mBuffer(NULL) {}

    virtual ~TBuffer() {
        if (mBuffer == NULL) {
            return;
        }

        delete[] mBuffer;
        mBuffer = NULL;
    } // at 0x8

    virtual void allocate(int size, int align = 0); // at 0xC

    virtual void allocate(int size, Heap *pHeap, int align = 0); // at 0x10

    virtual void onAllocate(Heap * /* pHeap */) {} // at 0x14
    virtual void errRangeOver() const {}           // at 0x18

    T &operator()(int i) {
        checkRange(i);
        return mBuffer[i];
    }
    const T &operator()(int i) const {
        checkRange(i);
        return mBuffer[i];
    }

    T &get(int i) {
        checkRange(i);
        return mBuffer[i];
    }
    const T &get(int i) const {
        checkRange(i);
        return mBuffer[i];
    }

    int getSize() const {
        return mSize;
    }
    int size() const {
        return mSize;
    }

    iterator begin() {
        return iterator(this, 0);
    }
    iterator end() {
        return iterator(this, getSize());
    }

private:
    void flush() {}

    void checkRange(int i) const {
        if (!isRangeValid(i)) {
            errRangeOver();
#line 174
            EGG_ASSERT_MSG(false, "TBuffer::checkRange %d (0<=x<%d)\n", i, mSize);
        }
    }

    bool isRangeValid(int i) const {
        return 0 <= i && i < mSize;
    }

private:
    int mSize;  // at 0x4
    T *mBuffer; // at 0x8
};

template <typename T>
void TBuffer<T>::allocate(int size, int) {
    mSize = size;
    mBuffer = new T[size];
    onAllocate(nullptr);
}
template <typename T>
void TBuffer<T>::allocate(int size, Heap *pHeap, int) {
    mSize = size;

    if (pHeap == NULL) {
        pHeap = Heap::getCurrentHeap();
    }

    mBuffer = new (pHeap) T[mSize];

    flush();
    onAllocate(pHeap);
}

} // namespace EGG

#endif