bmv2
Designing your own switch target with bmv2
Loading...
Searching...
No Matches
field_lists.h
Go to the documentation of this file.
1/* Copyright 2013-present Barefoot Networks, Inc.
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16/*
17 * Antonin Bas (antonin@barefootnetworks.com)
18 *
19 */
20
22
23#ifndef BM_BM_SIM_FIELD_LISTS_H_
24#define BM_BM_SIM_FIELD_LISTS_H_
25
26#include <utility> // for pair<>
27#include <vector>
28#include <unordered_set>
29#include <string>
30
31#include <boost/functional/hash.hpp>
32#include <boost/variant.hpp>
33
34#include "phv_forward.h"
35#include "bytecontainer.h"
36
37namespace bm {
38
43class FieldList {
44 public:
45 struct field_t {
46 header_id_t header;
47 int offset;
48
49 bool operator==(const field_t& other) const {
50 return header == other.header && offset == other.offset;
51 }
52 bool operator!=(const field_t& other) const {
53 return !(*this == other);
54 }
55 };
56
57 struct constant_t {
58 ByteContainer value;
59 size_t bitwidth;
60
61 bool operator==(const constant_t& other) const {
62 return value == other.value;
63 }
64 bool operator!=(const constant_t& other) const {
65 return !(*this == other);
66 }
67 };
68
69 struct FieldListVisitor : boost::static_visitor<> {
70 void operator()(const field_t &) { }
71 void operator()(const constant_t &) { }
72 };
73
74 public:
75 void push_back_field(header_id_t header, int field_offset) {
76 field_t f = {header, field_offset};
77 fields.push_back(field_list_member_t(f));
78 fields_set.insert(f);
79 }
80
81 void push_back_constant(const std::string &hexstr, size_t bitwidth) {
82 constant_t c = {ByteContainer(hexstr), bitwidth};
83 fields.push_back(field_list_member_t(c));
84 }
85
88 bool contains_field(header_id_t header, int field_offset) const {
89 auto it = fields_set.find({header, field_offset});
90 return it != fields_set.end();
91 }
92
93 template <typename T>
94 // NOLINTNEXTLINE(runtime/references)
95 void visit(T &visitor) {
96 static_assert(std::is_base_of<FieldListVisitor, T>::value,
97 "Invalid visitor, must inherit from from FieldListVisitor");
98 std::for_each(fields.begin(), fields.end(), boost::apply_visitor(visitor));
99 }
100
101 void copy_fields_between_phvs(PHV *dst, const PHV *src) {
102 struct CopyFieldsVisitor : FieldListVisitor {
103 CopyFieldsVisitor(PHV *dst, const PHV *src)
104 : dst(dst), src(src) {}
105 PHV *dst;
106 const PHV *src;
107
108 void operator()(const field_t &f) {
109 dst->get_field(f.header, f.offset)
110 .set(src->get_field(f.header, f.offset));
111 }
112 void operator()(const constant_t &) { }
113 };
114
115 CopyFieldsVisitor v(dst, src);
116 visit(v);
117 }
118
119 private:
120 using field_list_member_t = boost::variant<field_t, constant_t>;
121
122 struct FieldKeyHash {
123 std::size_t operator()(const field_t& f) const {
124 std::size_t seed = 0;
125 boost::hash_combine(seed, f.header);
126 boost::hash_combine(seed, f.offset);
127 return seed;
128 }
129 };
130
131 private:
132 std::vector<field_list_member_t> fields{};
133 std::unordered_set<field_t, FieldKeyHash> fields_set{};
134};
135
136} // namespace bm
137
138#endif // BM_BM_SIM_FIELD_LISTS_H_
Definition bytecontainer.h:39
Definition field_lists.h:43
bool contains_field(header_id_t header, int field_offset) const
Definition field_lists.h:88