forked from include-what-you-use/include-what-you-use
-
Notifications
You must be signed in to change notification settings - Fork 0
/
iwyu_stl_util.h
140 lines (121 loc) · 4.57 KB
/
iwyu_stl_util.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
//===--- iwyu_stl_util.h - STL-like utilities for include-what-you-use ----===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// Utilities that make it easier to work with STL.
#ifndef INCLUDE_WHAT_YOU_USE_IWYU_STL_UTIL_H_
#define INCLUDE_WHAT_YOU_USE_IWYU_STL_UTIL_H_
// TODO: IWYU can't see the use of std::find in uninstantiated template.
#include <algorithm> // IWYU pragma: keep
#include <map> // for map, multimap
#include <set> // for set
#include <vector> // for vector
namespace include_what_you_use {
using std::map;
using std::set;
using std::vector;
// Returns true if the associative container (e.g. set or map)
// contains the given key.
template <class AssociativeContainer>
bool ContainsKey(const AssociativeContainer& container,
const typename AssociativeContainer::key_type& key) {
return container.find(key) != container.end();
}
// Returns true if the container contains the given value.
template <class Container>
bool ContainsValue(const Container& container,
const typename Container::value_type& value) {
return (std::find(container.begin(), container.end(), value)
!= container.end());
}
// For maps, we also let you check if the key exists with the given value.
template <class Container, typename K, typename V>
bool ContainsKeyValue(const Container& container,
const K& key, const V& value) {
for (typename Container::const_iterator it = container.lower_bound(key),
end = container.upper_bound(key); it != end; ++it) {
if (it->second == value)
return true;
}
return false;
}
// Returns true if the associative container contains any key in the
// given set.
template <class AssociativeContainer>
bool ContainsAnyKey(
const AssociativeContainer& container,
const set<typename AssociativeContainer::key_type>& keys) {
for (const auto& key : keys) {
if (ContainsKey(container, key))
return true;
}
return false;
}
// Returns a_map[key] if key is in a_map; otherwise returns default_value.
template <class Map>
const typename Map::mapped_type& GetOrDefault(
const Map& a_map, const typename Map::key_type& key,
const typename Map::mapped_type& default_value) {
if (ContainsKey(a_map, key))
return a_map.find(key)->second;
return default_value;
}
// Returns a pointer to (*a_map)[key] if key is in *a_map; otherwise
// returns nullptr.
template <typename K, typename V>
const V* FindInMap(const map<K, V>* a_map, const K& key) {
const typename map<K, V>::const_iterator it = a_map->find(key);
return it == a_map->end() ? nullptr : &it->second;
}
template <typename K, typename V>
V* FindInMap(map<K, V>* a_map, const K& key) {
const typename map<K, V>::iterator it = a_map->find(key);
return it == a_map->end() ? nullptr : &it->second;
}
// Removes all elements in source from target.
template <class SourceContainer, class TargetContainer>
void RemoveAllFrom(const SourceContainer& source, TargetContainer* target) {
for (typename SourceContainer::const_iterator it = source.begin();
it != source.end(); ++it) {
target->erase(*it);
}
}
// Inserts all elements from source into target.
template <class SourceContainer, class TargetContainer>
void InsertAllInto(const SourceContainer& source, TargetContainer* target) {
target->insert(source.begin(), source.end());
}
// Appends all elements from source to the end of target. The target
// type must support inserting a range at the end, which probably
// means it's a vector.
template <class TargetContainer, class SourceContainer>
void Extend(TargetContainer* target, const SourceContainer& source) {
target->insert(target->end(), source.begin(), source.end());
}
// Returns the union of the two given sets.
template <typename T>
set<T> Union(const set<T>& lhs, const set<T>& rhs) {
set<T> retval(lhs);
InsertAllInto(rhs, &retval);
return retval;
}
// Returns a vector v with all duplicates removed, but order otherwise
// maintained.
template <typename T>
vector<T> GetUniqueEntries(const vector<T>& v) {
set<T> seen;
vector<T> retval;
for (typename vector<T>::const_iterator it = v.begin(); it != v.end(); ++it) {
if (!ContainsKey(seen, *it)) {
retval.push_back(*it);
seen.insert(*it);
}
}
return retval;
}
} // namespace include_what_you_use
#endif // INCLUDE_WHAT_YOU_USE_IWYU_STL_UTIL_H_