165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn/*
265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * Copyright (C) 2011 The Android Open Source Project
365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn *
465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * Licensed under the Apache License, Version 2.0 (the "License");
565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * you may not use this file except in compliance with the License.
665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * You may obtain a copy of the License at
765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn *
865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn *      http://www.apache.org/licenses/LICENSE-2.0
965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn *
1065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * Unless required by applicable law or agreed to in writing, software
1165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * distributed under the License is distributed on an "AS IS" BASIS,
1265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * See the License for the specific language governing permissions and
1465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * limitations under the License.
1565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn */
1665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
1765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn#ifndef ANDROID_FILTERFW_FILTERPACKS_BASE_UTILITIES_H
1865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn#define ANDROID_FILTERFW_FILTERPACKS_BASE_UTILITIES_H
1965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
2065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn#include <set>
2165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn#include <utility>
2265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
2365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennnamespace android {
2465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennnamespace filterfw {
2565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
2665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// Convenience Macro to make copy constructor and assignment operator private
2765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// (thereby disallowing copying and assigning).
2865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
2965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  TypeName(const TypeName&);               \
3065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  void operator=(const TypeName&)
3165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
3265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// A macro to disallow all the implicit constructors, namely the
3365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// default constructor, copy constructor and operator= functions.
3465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn#define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \
3565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  TypeName();                                    \
3665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  DISALLOW_COPY_AND_ASSIGN(TypeName)
3765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
3865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// STLDeleteContainerPointers()
3965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn//  For a range within a container of pointers, calls delete
4065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn//  (non-array version) on these pointers.
4165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// NOTE: for these three functions, we could just implement a DeleteObject
4265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// functor and then call for_each() on the range and functor, but this
4365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// requires us to pull in all of algorithm.h, which seems expensive.
4465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// For hash_[multi]set, it is important that this deletes behind the iterator
4565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// because the hash_set may call the hash function on the iterator when it is
4665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// advanced, which could result in the hash function trying to deference a
4765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// stale pointer.
4865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renntemplate <class ForwardIterator>
4965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennvoid STLDeleteContainerPointers(ForwardIterator begin,
5065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                                ForwardIterator end) {
5165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  while (begin != end) {
5265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    ForwardIterator temp = begin;
5365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    ++begin;
5465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    delete *temp;
5565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  }
5665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}
5765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
5865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// Given an STL container consisting of (key, value) pairs, STLDeleteValues
5965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// deletes all the "value" components and clears the container.  Does nothing
6065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// in the case it's given a NULL pointer.
6165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renntemplate <class T>
6265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennvoid STLDeleteValues(T *v) {
6365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  if (!v) return;
6465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  for (typename T::iterator i = v->begin(); i != v->end(); ++i) {
6565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    delete i->second;
6665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  }
6765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  v->clear();
6865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}
6965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
7065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// Perform a lookup in a map or hash_map.
7165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// If the key is present a const pointer to the associated value is returned,
7265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// otherwise a NULL pointer is returned.
7365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renntemplate <class Collection>
7465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennconst typename Collection::value_type::second_type*
7565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius RennFindOrNull(const Collection& collection,
7665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn           const typename Collection::value_type::first_type& key) {
7765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  typename Collection::const_iterator it = collection.find(key);
7865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  if (it == collection.end()) {
7965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    return 0;
8065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  }
8165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  return &it->second;
8265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}
8365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
8465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// A simple class that gives checklist functionality: There are essemtially two
8565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// operations defined on a CheckList:
8665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn//  - Adding a new (unchecked) item.
8765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn//  - Checking off an item.
8865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// When checking off the last remaining item CheckItem() returns true.
8965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renntemplate<typename T>
9065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennclass CheckList {
9165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  public:
9265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    // Add a new unchecked item. Does nothing if item is already in checklist.
9365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    void AddItem(const T& item);
9465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
9565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    // Check off an item in the checklist. Returns true if all items have been
9665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    // checked.
9765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    bool CheckItem(const T& item);
9865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
9965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    // Clear the checklist.
10065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    void Clear() {
10165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn      items_.clear();
10265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    }
10365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
10465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  private:
10565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    std::set<T> items_;
10665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn};
10765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
10865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renntemplate<typename T>
10965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennvoid CheckList<T>::AddItem(const T& item) {
11065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  if (!ContainsKey(items_, item))
11165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    items_.insert(item);
11265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}
11365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
11465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renntemplate<typename T>
11565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennbool CheckList<T>::CheckItem(const T& item) {
11665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  typename std::set<T>::iterator iter = items_.find(item);
11765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  if (iter != items_.end())
11865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    items_.erase(iter);
11965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  return items_.empty();
12065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}
12165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
12265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// Perform a lookup in a map or hash_map whose values are pointers.
12365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// If the key is present a const pointer to the associated value is returned,
12465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// otherwise a NULL pointer is returned.
12565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// This function does not distinguish between a missing key and a key mapped
12665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// to a NULL value.
12765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renntemplate <class Collection>
12865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennconst typename Collection::value_type::second_type
12965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius RennFindPtrOrNull(const Collection& collection,
13065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn              const typename Collection::value_type::first_type& key) {
13165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  typename Collection::const_iterator it = collection.find(key);
13265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  if (it == collection.end()) {
13365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    return 0;
13465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  }
13565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  return it->second;
13665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}
13765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
13865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// Test to see if a set, map, hash_set or hash_map contains a particular key.
13965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// Returns true if the key is in the collection.
14065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renntemplate <typename Collection, typename Key>
14165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennbool ContainsKey(const Collection& collection, const Key& key) {
14265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  return collection.find(key) != collection.end();
14365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}
14465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
14565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// Insert a new key and value into a map or hash_map.
14665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// If the key is not present in the map the key and value are
14765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// inserted, otherwise nothing happens. True indicates that an insert
14865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// took place, false indicates the key was already present.
14965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renntemplate <class Collection, class Key, class Value>
15065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennbool InsertIfNotPresent(Collection * const collection,
15165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                        const Key& key, const Value& value) {
15265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  std::pair<typename Collection::iterator, bool> ret =
15365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    collection->insert(typename Collection::value_type(key, value));
15465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  return ret.second;
15565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}
15665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
15765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn} // namespace filterfw
15865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn} // namespace android
15965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
16065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn#endif // ANDROID_FILTERFW_FILTERPACKS_BASE_UTILITIES_H
161