P4C
The P4 Compiler
Loading...
Searching...
No Matches
bf-asm/alloc.h
1#ifndef BACKENDS_TOFINO_BF_ASM_ALLOC_H_
2#define BACKENDS_TOFINO_BF_ASM_ALLOC_H_
3
4#include <stdlib.h>
5
6#include <stdexcept>
7#include <tuple>
8#include <utility>
9
10namespace BFN {
11
12template <class T>
13class Alloc1Dbase {
14 int size_;
15 T *data;
16 Alloc1Dbase() = delete;
17 Alloc1Dbase(const Alloc1Dbase &) = delete;
18 Alloc1Dbase &operator=(const Alloc1Dbase &) = delete;
19 Alloc1Dbase &operator=(Alloc1Dbase &&) = delete;
20
21 public:
22 explicit Alloc1Dbase(int sz) : size_(sz) { data = sz ? new T[sz]{} : nullptr; }
23 Alloc1Dbase(Alloc1Dbase &&a) noexcept : size_(a.size_), data(a.data) { a.data = 0; }
24 virtual ~Alloc1Dbase() { delete[] data; }
25
26 typedef T *iterator;
27 typedef T *const_iterator;
28 T &operator[](int i) {
29 if (i < 0 || i >= size_) throw std::out_of_range("Alloc1D");
30 return data[i];
31 }
32 const T &operator[](int i) const {
33 if (i < 0 || i >= size_) throw std::out_of_range("Alloc1D");
34 return data[i];
35 }
36 bool operator==(const Alloc1Dbase<T> &t) const {
37 return std::equal(data, data + size_, t.data, t.data + t.size_);
38 }
39 bool operator!=(const Alloc1Dbase<T> &t) const { return !(*this == t); }
40
41 int size() const { return size_; }
42 void clear() { std::fill(data, data + size_, T()); }
43 T *begin() { return data; }
44 T *end() { return data + size_; }
45};
46
47template <class T, int S>
48class Alloc1D : public Alloc1Dbase<T> {
49 public:
50 Alloc1D() : Alloc1Dbase<T>(S) {}
51 Alloc1Dbase<T> &base() { return *this; }
52 bool operator!=(const Alloc1D<T, S> &t) const { return Alloc1Dbase<T>::operator!=(t); }
53};
54
55template <class T>
56class Alloc3Dbase;
57
58template <class T>
59class Alloc2Dbase {
60 int nrows, ncols;
61 T *data;
62 template <class U>
63 class rowref {
64 U *row;
65 int ncols;
66 friend class Alloc2Dbase;
67 friend class Alloc3Dbase<U>;
68 rowref(U *r, int c) : row(r), ncols(c) {}
69
70 public:
71 typedef U *iterator;
72 typedef const U *const_iterator;
73 U &operator[](int i) const {
74 if (i < 0 || i >= ncols) throw std::out_of_range("Alloc2D");
75 return row[i];
76 }
77 U *begin() const { return row; }
78 U *end() const { return row + ncols; }
79 };
80 Alloc2Dbase() = delete;
81 Alloc2Dbase(const Alloc2Dbase &) = delete;
82 Alloc2Dbase &operator=(const Alloc2Dbase &) = delete;
83 Alloc2Dbase &operator=(Alloc2Dbase &&) = delete;
84 friend class Alloc3Dbase<T>;
85
86 public:
87 Alloc2Dbase(int r, int c) : nrows(r), ncols(c) {
88 size_t sz = r * c;
89 data = sz ? new T[sz]{} : nullptr;
90 }
91 Alloc2Dbase(Alloc2Dbase &&a) noexcept : nrows(a.nrows), ncols(a.ncols), data(a.data) {
92 a.data = 0;
93 }
94 virtual ~Alloc2Dbase() { delete[] data; }
95
96 rowref<T> operator[](int i) {
97 if (i < 0 || i >= nrows) throw std::out_of_range("Alloc2D");
98 return {data + i * ncols, ncols};
99 }
100 rowref<const T> operator[](int i) const {
101 if (i < 0 || i >= nrows) throw std::out_of_range("Alloc2D");
102 return {data + i * ncols, ncols};
103 }
104 T &at(int i, int j) {
105 if (i < 0 || i >= nrows || j < 0 || j >= ncols) throw std::out_of_range("Alloc2D");
106 return data[i * ncols + j];
107 }
108 const T &at(int i, int j) const {
109 if (i < 0 || i >= nrows || j < 0 || j >= ncols) throw std::out_of_range("Alloc2D");
110 return data[i * ncols + j];
111 }
112 T &operator[](std::pair<int, int> i) {
113 if (i.first < 0 || i.first >= nrows || i.second < 0 || i.second >= ncols)
114 throw std::out_of_range("Alloc2D");
115 return data[i.first * ncols + i.second];
116 }
117 const T &operator[](std::pair<int, int> i) const {
118 if (i.first < 0 || i.first >= nrows || i.second < 0 || i.second >= ncols)
119 throw std::out_of_range("Alloc2D");
120 return data[i.first * ncols + i.second];
121 }
122 bool operator==(const Alloc2Dbase<T> &t) const {
123 int sz = nrows * ncols;
124 if (nrows != t.nrows || ncols != t.ncols) return false;
125 return std::equal(data, data + sz, t.data);
126 }
127 bool operator!=(const Alloc2Dbase<T> &t) const { return !(*this == t); }
128
129 int rows() const { return nrows; }
130 int cols() const { return ncols; }
131 void clear() { std::fill(data, data + nrows * ncols, T()); }
132};
133
134template <class T, int R, int C>
135class Alloc2D : public Alloc2Dbase<T> {
136 public:
137 Alloc2D() : Alloc2Dbase<T>(R, C) {}
138 Alloc2Dbase<T> &base() { return *this; }
139};
140
141template <class T>
142class Alloc3Dbase {
143 int nmats, nrows, ncols;
144 T *data;
145 template <class U>
146 class matref {
147 U *matrix;
148 int nrows, ncols;
149 friend class Alloc3Dbase;
150
151 public:
152 typename Alloc2Dbase<T>::template rowref<U> operator[](int i) const {
153 if (i < 0 || i >= nrows) throw std::out_of_range("Alloc3D");
154 return {matrix + i * ncols, ncols};
155 }
156 U &operator[](std::pair<int, int> i) const {
157 if (i.first < 0 || i.first >= nrows || i.second < 0 || i.second >= ncols)
158 throw std::out_of_range("Alloc3D");
159 return matrix[i.first * ncols + i.second];
160 }
161 };
162 Alloc3Dbase() = delete;
163 Alloc3Dbase(const Alloc3Dbase &) = delete;
164 Alloc3Dbase &operator=(const Alloc3Dbase &) = delete;
165 Alloc3Dbase &operator=(Alloc3Dbase &&) = delete;
166
167 public:
168 Alloc3Dbase(int m, int r, int c) : nmats(m), nrows(r), ncols(c) {
169 size_t sz = m * r * c;
170 data = sz ? new T[sz]{} : nullptr;
171 }
172 Alloc3Dbase(Alloc3Dbase &&a) noexcept
173 : nmats(a.nmats), nrows(a.nrows), ncols(a.ncols), data(a.data) {
174 a.data = 0;
175 }
176 virtual ~Alloc3Dbase() { delete[] data; }
177
178 matref<T> operator[](int i) {
179 if (i < 0 || i >= nmats) throw std::out_of_range("Alloc3D");
180 return {data + i * nrows * ncols, nrows, ncols};
181 }
182 matref<const T> operator[](int i) const {
183 if (i < 0 || i >= nmats) throw std::out_of_range("Alloc3D");
184 return {data + i * nrows * ncols, nrows, ncols};
185 }
186 T &at(int i, int j, int k) {
187 if (i < 0 || i >= nmats || j < 0 || j >= nrows || k < 0 || k >= ncols)
188 throw std::out_of_range("Alloc3D");
189 return data[i * nrows * ncols + j * ncols + k];
190 }
191 const T &at(int i, int j, int k) const {
192 if (i < 0 || i >= nmats || j < 0 || j >= nrows || k < 0 || k >= ncols)
193 throw std::out_of_range("Alloc3D");
194 return data[i * nrows * ncols + j * ncols + k];
195 }
196 T &operator[](std::tuple<int, int, int> i) {
197 if (std::get<0>(i) < 0 || std::get<0>(i) >= nmats || std::get<1>(i) < 0 ||
198 std::get<1>(i) >= nrows || std::get<2>(i) < 0 || std::get<2>(i) >= ncols)
199 throw std::out_of_range("Alloc3D");
200 return data[std::get<0>(i) * nrows * ncols + std::get<1>(i) * ncols + std::get<2>(i)];
201 }
202 const T &operator[](std::tuple<int, int, int> i) const {
203 if (std::get<0>(i) < 0 || std::get<0>(i) >= nmats || std::get<1>(i) < 0 ||
204 std::get<1>(i) >= nrows || std::get<2>(i) < 0 || std::get<2>(i) >= ncols)
205 throw std::out_of_range("Alloc3D");
206 return data[std::get<0>(i) * nrows * ncols + std::get<1>(i) * ncols + std::get<2>(i)];
207 }
208 bool operator==(const Alloc3Dbase<T> &t) const {
209 int sz = nmats * nrows * ncols;
210 if (nmats != t.nmats || nrows != t.nrows || ncols != t.ncols) return false;
211 return std::equal(data, data + sz, t.data);
212 }
213 bool operator!=(const Alloc3Dbase<T> &t) const { return !(*this == t); }
214
215 int matrixes() const { return nmats; }
216 int rows() const { return nrows; }
217 int cols() const { return ncols; }
218 void clear() { std::fill(data, data + nmats * nrows * ncols, T()); }
219};
220
221template <class T, int B, int R, int C>
222class Alloc3D : public Alloc3Dbase<T> {
223 public:
224 Alloc3D() : Alloc3Dbase<T>(B, R, C) {}
225 Alloc3Dbase<T> &base() { return *this; }
226};
227
228} // namespace BFN
229
230#endif /* BACKENDS_TOFINO_BF_ASM_ALLOC_H_ */
Definition bf-asm/alloc.h:59
Definition bf-p4c/common/alloc.h:160
The namespace encapsulating Barefoot/Intel-specific stuff.
Definition bf-asm/alloc.h:10