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