P4C
The P4 Compiler
Loading...
Searching...
No Matches
map.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_MAP_H_
18#define LIB_MAP_H_
19
20#include <iterator>
21#include <optional>
22
23namespace P4 {
24
27template <typename Map, typename Key>
28typename Map::mapped_type get(const Map &m, const Key &key) {
29 auto it = m.find(key);
30 return it != m.end() ? it->second : typename Map::mapped_type{};
31}
32template <class Map, typename Key, typename Value>
33typename Map::mapped_type get(const Map &m, const Key &key, Value &&def) {
34 using M = typename Map::mapped_type;
35 auto it = m.find(key);
36 return it != m.end() ? it->second : static_cast<M>(std::forward<Value>(def));
37}
38
41template <typename Map, typename Key>
42const typename Map::mapped_type *getref(const Map &m, const Key &key) {
43 auto it = m.find(key);
44 return it != m.end() ? &it->second : nullptr;
45}
46
47template <typename Map, typename Key>
48typename Map::mapped_type *getref(Map &m, const Key &key) {
49 auto it = m.find(key);
50 return it != m.end() ? &it->second : nullptr;
51}
52
53// Given a map and a key, return a optional<V> if the key exists and None if the
54// key does not exist in the map.
55template <class Map, typename Key>
56std::optional<typename Map::mapped_type> get_optional(const Map &m, const Key &key) {
57 auto it = m.find(key);
58 if (it != m.end()) return std::optional<typename Map::mapped_type>(it->second);
59
60 return {};
61}
62
63template <typename Map, typename Key>
64typename Map::mapped_type get(const Map *m, const Key &key) {
65 return m ? get(*m, key) : typename Map::mapped_type{};
66}
67
68template <class Map, typename Key, typename Value>
69typename Map::mapped_type get(const Map *m, const Key &key, Value &&def) {
70 return m ? get(*m, key, std::forward(def)) : typename Map::mapped_type{};
71}
72
73template <typename Map, typename Key>
74const typename Map::mapped_type *getref(const Map *m, const Key &key) {
75 return m ? getref(*m, key) : nullptr;
76}
77
78template <typename Map, typename Key>
79typename Map::mapped_type *getref(Map *m, const Key &key) {
80 return m ? getref(*m, key) : nullptr;
81}
82
83/* iterate over the keys in a map */
84template <class PairIter>
85class IterKeys {
86 class iterator {
87 PairIter it;
88
89 public:
90 using iterator_category = typename std::iterator_traits<PairIter>::iterator_category;
91 using value_type = typename std::iterator_traits<PairIter>::value_type::first_type;
92 using difference_type = typename std::iterator_traits<PairIter>::difference_type;
93 using pointer = decltype(&it->first);
94 using reference = decltype(*&it->first);
95
96 explicit iterator(PairIter i) : it(i) {}
97 iterator &operator++() {
98 ++it;
99 return *this;
100 }
101 iterator &operator--() {
102 --it;
103 return *this;
104 }
105 iterator operator++(int) {
106 auto copy = *this;
107 ++it;
108 return copy;
109 }
110 iterator operator--(int) {
111 auto copy = *this;
112 --it;
113 return copy;
114 }
115 bool operator==(const iterator &i) const { return it == i.it; }
116 bool operator!=(const iterator &i) const { return it != i.it; }
117 reference operator*() const { return it->first; }
118 pointer operator->() const { return &it->first; }
119 } b, e;
120
121 public:
122 template <class U>
123 explicit IterKeys(U &map) : b(map.begin()), e(map.end()) {}
124 IterKeys(PairIter b, PairIter e) : b(b), e(e) {}
125 iterator begin() const { return b; }
126 iterator end() const { return e; }
127};
128
129template <class Map>
132}
133
134template <class Map>
135IterKeys<typename Map::const_iterator> Keys(const Map &m) {
136 return IterKeys<typename Map::const_iterator>(m);
137}
138
139template <class PairIter>
140IterKeys<PairIter> Keys(std::pair<PairIter, PairIter> range) {
141 return IterKeys<PairIter>(range.first, range.second);
142}
143
144/* iterate over the values in a map */
145template <class PairIter>
147 class iterator {
148 PairIter it;
149
150 public:
151 using iterator_category = typename std::iterator_traits<PairIter>::iterator_category;
152 using value_type = typename std::iterator_traits<PairIter>::value_type::second_type;
153 using difference_type = typename std::iterator_traits<PairIter>::difference_type;
154 using pointer = decltype(&it->second);
155 using reference = decltype(*&it->second);
156
157 explicit iterator(PairIter i) : it(i) {}
158 iterator &operator++() {
159 ++it;
160 return *this;
161 }
162 iterator &operator--() {
163 --it;
164 return *this;
165 }
166 iterator operator++(int) {
167 auto copy = *this;
168 ++it;
169 return copy;
170 }
171 iterator operator--(int) {
172 auto copy = *this;
173 --it;
174 return copy;
175 }
176 bool operator==(const iterator &i) const { return it == i.it; }
177 bool operator!=(const iterator &i) const { return it != i.it; }
178 reference operator*() const { return it->second; }
179 pointer operator->() const { return &it->second; }
180 } b, e;
181
182 public:
183 using value_type = typename std::iterator_traits<PairIter>::value_type::second_type;
184
185 template <class U>
186 explicit IterValues(U &map) : b(map.begin()), e(map.end()) {}
187 IterValues(PairIter b, PairIter e) : b(b), e(e) {}
188 iterator begin() const { return b; }
189 iterator end() const { return e; }
190};
191
192template <class Map>
195}
196
197template <class Map>
198IterValues<typename Map::const_iterator> Values(const Map &m) {
199 return IterValues<typename Map::const_iterator>(m);
200}
201
202template <class PairIter>
203IterValues<PairIter> Values(std::pair<PairIter, PairIter> range) {
204 return IterValues<PairIter>(range.first, range.second);
205}
206
207/* iterate over the values for a single key in a multimap */
208template <class M>
210 M &map;
211 typename M::key_type key;
212 class iterator {
213 using MapIt = decltype(map.begin());
214
215 const MapForKey &self;
216 MapIt it;
217
218 public:
219 using iterator_category = std::forward_iterator_tag;
220 using value_type = typename M::value_type;
221 using difference_type = typename std::iterator_traits<MapIt>::difference_type;
222 using pointer = decltype(&it->second);
223 using reference = decltype(*&it->second);
224
225 iterator(const MapForKey &s, MapIt i) : self(s), it(std::move(i)) {}
226 iterator &operator++() {
227 if (++it != self.map.end() && it->first != self.key) it = self.map.end();
228 return *this;
229 }
230 iterator operator++(int) {
231 auto copy = *this;
232 ++*this;
233 return copy;
234 }
235 bool operator==(const iterator &i) const { return it == i.it; }
236 bool operator!=(const iterator &i) const { return it != i.it; }
237 reference operator*() const { return it->second; }
238 pointer operator->() const { return &it->second; }
239 };
240
241 public:
242 MapForKey(M &m, typename M::key_type k) : map(m), key(k) {}
243 iterator begin() const { return iterator(*this, map.find(key)); }
244 iterator end() const { return iterator(*this, map.end()); }
245};
246
247template <class M>
248MapForKey<M> ValuesForKey(M &m, typename M::key_type k) {
249 return MapForKey<M>(m, k);
250}
251
252} // namespace P4
253
254#endif /* LIB_MAP_H_ */
Definition map.h:85
Definition map.h:146
Definition map.h:209
TODO: this is not really specific to BMV2, it should reside somewhere else.
Definition applyOptionsPragmas.cpp:24