bmv2
Designing your own switch target with bmv2
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 
37 namespace bm {
38 
43 class 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_
bm::FieldList
Definition: field_lists.h:43
bytecontainer.h
bm::ByteContainer
Definition: bytecontainer.h:39
bm::FieldList::contains_field
bool contains_field(header_id_t header, int field_offset) const
Definition: field_lists.h:88