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