P4C
The P4 Compiler
Loading...
Searching...
No Matches
symbitmatrix.h
1/*
2 * SPDX-FileCopyrightText: 2013 Barefoot Networks, Inc.
3 * Copyright 2013-present Barefoot Networks, Inc.
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 */
7
8#ifndef LIB_SYMBITMATRIX_H_
9#define LIB_SYMBITMATRIX_H_
10
11#include "bitvec.h"
12
13namespace P4 {
14
15/* A symmetric bit matrix, held in a bit vector. We only store a triangular submatrix which
16 * is used for both halves, so modifying one bit modifies both sides, keeping the matrix
17 * always symmetric. Iterating over the matrix only iterates over the lower triangle */
18class SymBitMatrix : private bitvec {
19 public:
20 nonconst_bitref operator()(unsigned r, unsigned c) {
21 if (r < c) std::swap(r, c);
22 return bitvec::operator[]((r * r + r) / 2 + c);
23 }
24 bool operator()(unsigned r, unsigned c) const {
25 if (r < c) std::swap(r, c);
26 return bitvec::operator[]((r * r + r) / 2 + c);
27 }
28 unsigned size() const {
29 if (empty()) return 0;
30 unsigned m = *max();
31 unsigned r = 1;
32 while ((r * r + r) / 2 <= m) r++;
33 return r;
34 }
35 using bitvec::clear;
36 using bitvec::empty;
37 using bitvec::operator bool;
38
39 private:
40 using bitvec::operator|=;
41 template <class T>
42 class rowref {
43 friend class SymBitMatrix;
44 T &self;
45 unsigned row;
46 rowref(T &s, unsigned r) : self(s), row(r) {}
47
48 public:
49 rowref(const rowref &) = default;
50 rowref(rowref &&) = default;
51 explicit operator bool() const {
52 if (row < bits_per_unit) {
53 if (self.getrange((row * row + row) / 2, row + 1) != 0) return true;
54 } else {
55 if (self.getslice((row * row + row) / 2, row + 1)) return true;
56 }
57 const auto size = self.size();
58 for (auto c = row + 1; c < size; ++c)
59 if (self(row, c)) return true;
60 return false;
61 }
62 operator bitvec() const {
63 auto rv = self.getslice((row * row + row) / 2, row + 1);
64 const auto size = self.size();
65 for (auto c = row + 1; c < size; ++c)
66 if (self(row, c)) rv[c] = 1;
67 return rv;
68 }
69 };
70 class nonconst_rowref : public rowref<SymBitMatrix> {
71 public:
72 friend class SymBitMatrix;
73 using rowref<SymBitMatrix>::rowref;
74 void operator|=(bitvec a) const {
75 for (size_t v : a) {
76 self(row, v) = 1;
77 }
78 }
79 nonconst_bitref operator[](unsigned col) const { return self(row, col); }
80 };
81 class const_rowref : public rowref<const SymBitMatrix> {
82 public:
83 friend class SymBitMatrix;
84 using rowref<const SymBitMatrix>::rowref;
85 bool operator[](unsigned col) const { return self(row, col); }
86 };
87
88 public:
89 nonconst_rowref operator[](unsigned r) { return nonconst_rowref(*this, r); }
90 const_rowref operator[](unsigned r) const { return const_rowref(*this, r); }
91
92 bool operator==(const SymBitMatrix &a) const { return bitvec::operator==(a); }
93 bool operator!=(const SymBitMatrix &a) const { return bitvec::operator!=(a); }
94 bool operator|=(const SymBitMatrix &a) { return bitvec::operator|=(a); }
95};
96
97} // namespace P4
98
99#endif /* LIB_SYMBITMATRIX_H_ */
Definition symbitmatrix.h:18
Definition bitvec.h:175
TODO: this is not really specific to BMV2, it should reside somewhere else.
Definition applyOptionsPragmas.cpp:13