1 /*
2  * Copyright (C) 2011 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 #ifndef ANDROID_FILTERFW_FILTERPACKS_BASE_UTILITIES_H
18 #define ANDROID_FILTERFW_FILTERPACKS_BASE_UTILITIES_H
19 
20 #include <set>
21 #include <utility>
22 
23 namespace android {
24 namespace filterfw {
25 
26 // Convenience Macro to make copy constructor and assignment operator private
27 // (thereby disallowing copying and assigning).
28 #define DISALLOW_COPY_AND_ASSIGN(TypeName) \
29   TypeName(const TypeName&);               \
30   void operator=(const TypeName&)
31 
32 // A macro to disallow all the implicit constructors, namely the
33 // default constructor, copy constructor and operator= functions.
34 #define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \
35   TypeName();                                    \
36   DISALLOW_COPY_AND_ASSIGN(TypeName)
37 
38 // STLDeleteContainerPointers()
39 //  For a range within a container of pointers, calls delete
40 //  (non-array version) on these pointers.
41 // NOTE: for these three functions, we could just implement a DeleteObject
42 // functor and then call for_each() on the range and functor, but this
43 // requires us to pull in all of algorithm.h, which seems expensive.
44 // For hash_[multi]set, it is important that this deletes behind the iterator
45 // because the hash_set may call the hash function on the iterator when it is
46 // advanced, which could result in the hash function trying to deference a
47 // stale pointer.
48 template <class ForwardIterator>
STLDeleteContainerPointers(ForwardIterator begin,ForwardIterator end)49 void STLDeleteContainerPointers(ForwardIterator begin,
50                                 ForwardIterator end) {
51   while (begin != end) {
52     ForwardIterator temp = begin;
53     ++begin;
54     delete *temp;
55   }
56 }
57 
58 // Given an STL container consisting of (key, value) pairs, STLDeleteValues
59 // deletes all the "value" components and clears the container.  Does nothing
60 // in the case it's given a NULL pointer.
61 template <class T>
STLDeleteValues(T * v)62 void STLDeleteValues(T *v) {
63   if (!v) return;
64   for (typename T::iterator i = v->begin(); i != v->end(); ++i) {
65     delete i->second;
66   }
67   v->clear();
68 }
69 
70 // Perform a lookup in a map or hash_map.
71 // If the key is present a const pointer to the associated value is returned,
72 // otherwise a NULL pointer is returned.
73 template <class Collection>
74 const typename Collection::value_type::second_type*
FindOrNull(const Collection & collection,const typename Collection::value_type::first_type & key)75 FindOrNull(const Collection& collection,
76            const typename Collection::value_type::first_type& key) {
77   typename Collection::const_iterator it = collection.find(key);
78   if (it == collection.end()) {
79     return 0;
80   }
81   return &it->second;
82 }
83 
84 // A simple class that gives checklist functionality: There are essemtially two
85 // operations defined on a CheckList:
86 //  - Adding a new (unchecked) item.
87 //  - Checking off an item.
88 // When checking off the last remaining item CheckItem() returns true.
89 template<typename T>
90 class CheckList {
91   public:
92     // Add a new unchecked item. Does nothing if item is already in checklist.
93     void AddItem(const T& item);
94 
95     // Check off an item in the checklist. Returns true if all items have been
96     // checked.
97     bool CheckItem(const T& item);
98 
99     // Clear the checklist.
Clear()100     void Clear() {
101       items_.clear();
102     }
103 
104   private:
105     std::set<T> items_;
106 };
107 
108 template<typename T>
AddItem(const T & item)109 void CheckList<T>::AddItem(const T& item) {
110   if (!ContainsKey(items_, item))
111     items_.insert(item);
112 }
113 
114 template<typename T>
CheckItem(const T & item)115 bool CheckList<T>::CheckItem(const T& item) {
116   typename std::set<T>::iterator iter = items_.find(item);
117   if (iter != items_.end())
118     items_.erase(iter);
119   return items_.empty();
120 }
121 
122 // Perform a lookup in a map or hash_map whose values are pointers.
123 // If the key is present a const pointer to the associated value is returned,
124 // otherwise a NULL pointer is returned.
125 // This function does not distinguish between a missing key and a key mapped
126 // to a NULL value.
127 template <class Collection>
128 const typename Collection::value_type::second_type
FindPtrOrNull(const Collection & collection,const typename Collection::value_type::first_type & key)129 FindPtrOrNull(const Collection& collection,
130               const typename Collection::value_type::first_type& key) {
131   typename Collection::const_iterator it = collection.find(key);
132   if (it == collection.end()) {
133     return 0;
134   }
135   return it->second;
136 }
137 
138 // Test to see if a set, map, hash_set or hash_map contains a particular key.
139 // Returns true if the key is in the collection.
140 template <typename Collection, typename Key>
ContainsKey(const Collection & collection,const Key & key)141 bool ContainsKey(const Collection& collection, const Key& key) {
142   return collection.find(key) != collection.end();
143 }
144 
145 // Insert a new key and value into a map or hash_map.
146 // If the key is not present in the map the key and value are
147 // inserted, otherwise nothing happens. True indicates that an insert
148 // took place, false indicates the key was already present.
149 template <class Collection, class Key, class Value>
InsertIfNotPresent(Collection * const collection,const Key & key,const Value & value)150 bool InsertIfNotPresent(Collection * const collection,
151                         const Key& key, const Value& value) {
152   std::pair<typename Collection::iterator, bool> ret =
153     collection->insert(typename Collection::value_type(key, value));
154   return ret.second;
155 }
156 
157 } // namespace filterfw
158 } // namespace android
159 
160 #endif // ANDROID_FILTERFW_FILTERPACKS_BASE_UTILITIES_H
161