1 /*
2 * Copyright (C) 2022 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #pragma once
18
19 #include <algorithm>
20 #include <map>
21 #include <set>
22 #include <vector>
23
24 namespace aidl::android::hardware::audio::core {
25
26 // Return whether all the elements in the vector are unique.
27 template <typename T>
all_unique(const std::vector<T> & v)28 bool all_unique(const std::vector<T>& v) {
29 return std::set<T>(v.begin(), v.end()).size() == v.size();
30 }
31
32 // Erase all the specified elements from a map.
33 template <typename C, typename V>
erase_all(C & c,const V & keys)34 auto erase_all(C& c, const V& keys) {
35 auto oldSize = c.size();
36 for (auto& k : keys) {
37 c.erase(k);
38 }
39 return oldSize - c.size();
40 }
41
42 // Erase all the elements in the container that satisfy the provided predicate.
43 template <typename C, typename P>
erase_if(C & c,P pred)44 auto erase_if(C& c, P pred) {
45 auto oldSize = c.size();
46 for (auto it = c.begin(); it != c.end();) {
47 if (pred(*it)) {
48 it = c.erase(it);
49 } else {
50 ++it;
51 }
52 }
53 return oldSize - c.size();
54 }
55
56 // Erase all the elements in the map that have specified values.
57 template <typename C, typename V>
erase_all_values(C & c,const V & values)58 auto erase_all_values(C& c, const V& values) {
59 return erase_if(c, [values](const auto& pair) { return values.count(pair.second) != 0; });
60 }
61
62 // Return non-zero count of elements for any of the provided keys.
63 template <typename M, typename V>
count_any(const M & m,const V & keys)64 size_t count_any(const M& m, const V& keys) {
65 for (auto& k : keys) {
66 if (size_t c = m.count(k); c != 0) return c;
67 }
68 return 0;
69 }
70
71 // Assuming that M is a map whose values have an 'id' field,
72 // find an element with the specified id.
73 template <typename M>
findById(M & m,int32_t id)74 auto findById(M& m, int32_t id) {
75 return std::find_if(m.begin(), m.end(), [&](const auto& p) { return p.second.id == id; });
76 }
77
78 // Assuming that the vector contains elements with an 'id' field,
79 // find an element with the specified id.
80 template <typename T>
findById(std::vector<T> & v,int32_t id)81 auto findById(std::vector<T>& v, int32_t id) {
82 return std::find_if(v.begin(), v.end(), [&](const auto& e) { return e.id == id; });
83 }
84
85 // Return elements from the vector that have specified ids, also
86 // optionally return which ids were not found.
87 template <typename T>
88 std::vector<T*> selectByIds(std::vector<T>& v, const std::vector<int32_t>& ids,
89 std::vector<int32_t>* missingIds = nullptr) {
90 std::vector<T*> result;
91 std::set<int32_t> idsSet(ids.begin(), ids.end());
92 for (size_t i = 0; i < v.size(); ++i) {
93 T& e = v[i];
94 if (idsSet.count(e.id) != 0) {
95 result.push_back(&v[i]);
96 idsSet.erase(e.id);
97 }
98 }
99 if (missingIds) {
100 *missingIds = std::vector(idsSet.begin(), idsSet.end());
101 }
102 return result;
103 }
104
105 // Assuming that M is a map whose keys' type is K and values' type is V,
106 // return the corresponding value of the given key from the map or default
107 // value if the key is not found.
108 template <typename M, typename K, typename V>
findValueOrDefault(const M & m,const K & key,V defaultValue)109 auto findValueOrDefault(const M& m, const K& key, V defaultValue) {
110 auto it = m.find(key);
111 return it == m.end() ? defaultValue : it->second;
112 }
113
114 // Assuming that M is a map whose keys' type is K, return the given key if it
115 // is found from the map or default value.
116 template <typename M, typename K>
findKeyOrDefault(const M & m,const K & key,K defaultValue)117 auto findKeyOrDefault(const M& m, const K& key, K defaultValue) {
118 auto it = m.find(key);
119 return it == m.end() ? defaultValue : key;
120 }
121
122 } // namespace aidl::android::hardware::audio::core
123