P4C
The P4 Compiler
Loading...
Searching...
No Matches
symbitmatrix.h
1/*
2Copyright 2013-present Barefoot Networks, Inc.
3
4Licensed under the Apache License, Version 2.0 (the "License");
5you may not use this file except in compliance with the License.
6You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10Unless required by applicable law or agreed to in writing, software
11distributed under the License is distributed on an "AS IS" BASIS,
12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13See the License for the specific language governing permissions and
14limitations under the License.
15*/
16
17#ifndef LIB_SYMBITMATRIX_H_
18#define LIB_SYMBITMATRIX_H_
19
20#include "bitvec.h"
21
22namespace P4 {
23
24/* A symmetric bit matrix, held in a bit vector. We only store a triangular submatrix which
25 * is used for both halves, so modifying one bit modifies both sides, keeping the matrix
26 * always symmetric. Iterating over the matrix only iterates over the lower triangle */
27class SymBitMatrix : private bitvec {
28 public:
29 nonconst_bitref operator()(unsigned r, unsigned c) {
30 if (r < c) std::swap(r, c);
31 return bitvec::operator[]((r * r + r) / 2 + c);
32 }
33 bool operator()(unsigned r, unsigned c) const {
34 if (r < c) std::swap(r, c);
35 return bitvec::operator[]((r * r + r) / 2 + c);
36 }
37 unsigned size() const {
38 if (empty()) return 0;
39 unsigned m = *max();
40 unsigned r = 1;
41 while ((r * r + r) / 2 <= m) r++;
42 return r;
43 }
44 using bitvec::clear;
45 using bitvec::empty;
46 using bitvec::operator bool;
47
48 private:
49 using bitvec::operator|=;
50 template <class T>
51 class rowref {
52 friend class SymBitMatrix;
53 T &self;
54 unsigned row;
55 rowref(T &s, unsigned r) : self(s), row(r) {}
56
57 public:
58 rowref(const rowref &) = default;
59 rowref(rowref &&) = default;
60 explicit operator bool() const {
61 if (row < bits_per_unit) {
62 if (self.getrange((row * row + row) / 2, row + 1) != 0) return true;
63 } else {
64 if (self.getslice((row * row + row) / 2, row + 1)) return true;
65 }
66 const auto size = self.size();
67 for (auto c = row + 1; c < size; ++c)
68 if (self(row, c)) return true;
69 return false;
70 }
71 operator bitvec() const {
72 auto rv = self.getslice((row * row + row) / 2, row + 1);
73 const auto size = self.size();
74 for (auto c = row + 1; c < size; ++c)
75 if (self(row, c)) rv[c] = 1;
76 return rv;
77 }
78 };
79 class nonconst_rowref : public rowref<SymBitMatrix> {
80 public:
81 friend class SymBitMatrix;
82 using rowref<SymBitMatrix>::rowref;
83 void operator|=(bitvec a) const {
84 for (size_t v : a) {
85 self(row, v) = 1;
86 }
87 }
88 nonconst_bitref operator[](unsigned col) const { return self(row, col); }
89 };
90 class const_rowref : public rowref<const SymBitMatrix> {
91 public:
92 friend class SymBitMatrix;
93 using rowref<const SymBitMatrix>::rowref;
94 bool operator[](unsigned col) const { return self(row, col); }
95 };
96
97 public:
98 nonconst_rowref operator[](unsigned r) { return nonconst_rowref(*this, r); }
99 const_rowref operator[](unsigned r) const { return const_rowref(*this, r); }
100
101 bool operator==(const SymBitMatrix &a) const { return bitvec::operator==(a); }
102 bool operator!=(const SymBitMatrix &a) const { return bitvec::operator!=(a); }
103 bool operator|=(const SymBitMatrix &a) { return bitvec::operator|=(a); }
104};
105
106} // namespace P4
107
108#endif /* LIB_SYMBITMATRIX_H_ */
Definition symbitmatrix.h:27
Definition bitvec.h:175
Definition bitvec.h:120
TODO: this is not really specific to BMV2, it should reside somewhere else.
Definition applyOptionsPragmas.cpp:24