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
23namespace android {
24namespace 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.
48template <class ForwardIterator>
49void 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.
61template <class T>
62void 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.
73template <class Collection>
74const typename Collection::value_type::second_type*
75FindOrNull(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.
89template<typename T>
90class 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.
100    void Clear() {
101      items_.clear();
102    }
103
104  private:
105    std::set<T> items_;
106};
107
108template<typename T>
109void CheckList<T>::AddItem(const T& item) {
110  if (!ContainsKey(items_, item))
111    items_.insert(item);
112}
113
114template<typename T>
115bool 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.
127template <class Collection>
128const typename Collection::value_type::second_type
129FindPtrOrNull(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.
140template <typename Collection, typename Key>
141bool 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.
149template <class Collection, class Key, class Value>
150bool 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