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 141 142 143 144 145 146 147 148 149 150
|
//===--- 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_
#include <algorithm> // for find
#include <map> // for map, multimap
#include <set> // for set
#include <vector> // for vector
namespace include_what_you_use {
using std::map;
using std::multimap;
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;
}
// Returns all values associated with the given key in the multimap.
template <typename K, typename V>
vector<V> FindInMultiMap(const multimap<K, V>& a_multimap, const K& key) {
vector<V> retval;
for (typename multimap<K, V>::const_iterator it = a_multimap.lower_bound(key),
end = a_multimap.upper_bound(key); it != end; ++it) {
retval.push_back(it->second);
}
return retval;
}
// 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_
|