/* * Copyright (C) 2005 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef ANDROID_KEYED_VECTOR_H #define ANDROID_KEYED_VECTOR_H #include #include #include #include #include #include #include // --------------------------------------------------------------------------- namespace android { template class KeyedVector { public: typedef KEY key_type; typedef VALUE value_type; inline KeyedVector(); /* * empty the vector */ inline void clear() { mVector.clear(); } /*! * vector stats */ //! returns number of items in the vector inline size_t size() const { return mVector.size(); } //! returns whether or not the vector is empty inline bool isEmpty() const { return mVector.isEmpty(); } //! returns how many items can be stored without reallocating the backing store inline size_t capacity() const { return mVector.capacity(); } //! sets the capacity. capacity can never be reduced less than size() inline ssize_t setCapacity(size_t size) { return mVector.setCapacity(size); } // returns true if the arguments is known to be identical to this vector inline bool isIdenticalTo(const KeyedVector& rhs) const; /*! * accessors */ const VALUE& valueFor(const KEY& key) const; const VALUE& valueAt(size_t index) const; const KEY& keyAt(size_t index) const; ssize_t indexOfKey(const KEY& key) const; const VALUE& operator[] (size_t index) const; /*! * modifying the array */ VALUE& editValueFor(const KEY& key); VALUE& editValueAt(size_t index); /*! * add/insert/replace items */ ssize_t add(const KEY& key, const VALUE& item); ssize_t replaceValueFor(const KEY& key, const VALUE& item); ssize_t replaceValueAt(size_t index, const VALUE& item); /*! * remove items */ ssize_t removeItem(const KEY& key); ssize_t removeItemsAt(size_t index, size_t count = 1); private: SortedVector< key_value_pair_t > mVector; }; // KeyedVector can be trivially moved using memcpy() because its // underlying SortedVector can be trivially moved. template struct trait_trivial_move > { enum { value = trait_trivial_move > >::value }; }; // --------------------------------------------------------------------------- /** * Variation of KeyedVector that holds a default value to return when * valueFor() is called with a key that doesn't exist. */ template class DefaultKeyedVector : public KeyedVector { public: inline DefaultKeyedVector(const VALUE& defValue = VALUE()); const VALUE& valueFor(const KEY& key) const; private: VALUE mDefault; }; // --------------------------------------------------------------------------- template inline KeyedVector::KeyedVector() { } template inline bool KeyedVector::isIdenticalTo(const KeyedVector& rhs) const { return mVector.array() == rhs.mVector.array(); } template inline ssize_t KeyedVector::indexOfKey(const KEY& key) const { return mVector.indexOf( key_value_pair_t(key) ); } template inline const VALUE& KeyedVector::valueFor(const KEY& key) const { ssize_t i = this->indexOfKey(key); LOG_ALWAYS_FATAL_IF(i<0, "%s: key not found", __PRETTY_FUNCTION__); return mVector.itemAt(i).value; } template inline const VALUE& KeyedVector::valueAt(size_t index) const { return mVector.itemAt(index).value; } template inline const VALUE& KeyedVector::operator[] (size_t index) const { return valueAt(index); } template inline const KEY& KeyedVector::keyAt(size_t index) const { return mVector.itemAt(index).key; } template inline VALUE& KeyedVector::editValueFor(const KEY& key) { ssize_t i = this->indexOfKey(key); LOG_ALWAYS_FATAL_IF(i<0, "%s: key not found", __PRETTY_FUNCTION__); return mVector.editItemAt(i).value; } template inline VALUE& KeyedVector::editValueAt(size_t index) { return mVector.editItemAt(index).value; } template inline ssize_t KeyedVector::add(const KEY& key, const VALUE& value) { return mVector.add( key_value_pair_t(key, value) ); } template inline ssize_t KeyedVector::replaceValueFor(const KEY& key, const VALUE& value) { key_value_pair_t pair(key, value); mVector.remove(pair); return mVector.add(pair); } template inline ssize_t KeyedVector::replaceValueAt(size_t index, const VALUE& item) { if (index inline ssize_t KeyedVector::removeItem(const KEY& key) { return mVector.remove(key_value_pair_t(key)); } template inline ssize_t KeyedVector::removeItemsAt(size_t index, size_t count) { return mVector.removeItemsAt(index, count); } // --------------------------------------------------------------------------- template inline DefaultKeyedVector::DefaultKeyedVector(const VALUE& defValue) : mDefault(defValue) { } template inline const VALUE& DefaultKeyedVector::valueFor(const KEY& key) const { ssize_t i = this->indexOfKey(key); return i >= 0 ? KeyedVector::valueAt(i) : mDefault; } }; // namespace android // --------------------------------------------------------------------------- #endif // ANDROID_KEYED_VECTOR_H