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