1/*
2 *  keyed_vector.h
3 *  Android
4 *
5 *  Created on 11/18/05.
6 *  Copyright 2005 The Android Open Source Project
7 *
8 */
9
10#ifndef ANDROID_KEYED_VECTOR_H
11#define ANDROID_KEYED_VECTOR_H
12
13#include <assert.h>
14#include <stdint.h>
15#include <sys/types.h>
16
17#include "tinyutils/SortedVector.h"
18#include "tinyutils/TypeHelpers.h"
19
20// ---------------------------------------------------------------------------
21
22namespace android {
23
24template <typename KEY, typename VALUE>
25class KeyedVector
26{
27public:
28    typedef KEY    key_type;
29    typedef VALUE  value_type;
30
31    inline                  KeyedVector();
32
33    /*
34     * empty the vector
35     */
36
37    inline  void            clear()                     { mVector.clear(); }
38
39    /*!
40     * vector stats
41     */
42
43    //! returns number of items in the vector
44    inline  size_t          size() const                { return mVector.size(); }
45    //! returns wether or not the vector is empty
46    inline  bool            isEmpty() const             { return mVector.isEmpty(); }
47    //! returns how many items can be stored without reallocating the backing store
48    inline  size_t          capacity() const            { return mVector.capacity(); }
49    //! setst the capacity. capacity can never be reduced less than size()
50    inline ssize_t          setCapacity(size_t size)    { return mVector.setCapacity(size); }
51
52    /*!
53     * accessors
54     */
55            const VALUE&    valueFor(const KEY& key) const;
56            const VALUE&    valueAt(size_t index) const;
57            const KEY&      keyAt(size_t index) const;
58            ssize_t         indexOfKey(const KEY& key) const;
59
60    /*!
61     * modifing the array
62     */
63
64            VALUE&          editValueFor(const KEY& key);
65            VALUE&          editValueAt(size_t index);
66
67            /*!
68             * add/insert/replace items
69             */
70
71            ssize_t         add(const KEY& key, const VALUE& item);
72            ssize_t         replaceValueFor(const KEY& key, const VALUE& item);
73            ssize_t         replaceValueAt(size_t index, const VALUE& item);
74
75    /*!
76     * remove items
77     */
78
79            ssize_t         removeItem(const KEY& key);
80            ssize_t         removeItemsAt(size_t index, size_t count = 1);
81
82private:
83            SortedVector< key_value_pair_t<KEY, VALUE> >    mVector;
84};
85
86// ---------------------------------------------------------------------------
87
88/**
89 * Variation of KeyedVector that holds a default value to return when
90 * valueFor() is called with a key that doesn't exist.
91 */
92template <typename KEY, typename VALUE>
93class DefaultKeyedVector : public KeyedVector<KEY, VALUE>
94{
95public:
96    inline                  DefaultKeyedVector(const VALUE& defValue = VALUE());
97            const VALUE&    valueFor(const KEY& key) const;
98
99private:
100            VALUE                                           mDefault;
101};
102
103// ---------------------------------------------------------------------------
104
105template<typename KEY, typename VALUE> inline
106KeyedVector<KEY,VALUE>::KeyedVector()
107{
108}
109
110template<typename KEY, typename VALUE> inline
111ssize_t KeyedVector<KEY,VALUE>::indexOfKey(const KEY& key) const {
112    return mVector.indexOf( key_value_pair_t<KEY,VALUE>(key) );
113}
114
115template<typename KEY, typename VALUE> inline
116const VALUE& KeyedVector<KEY,VALUE>::valueFor(const KEY& key) const {
117    ssize_t i = indexOfKey(key);
118    assert(i>=0);
119    return mVector.itemAt(i).value;
120}
121
122template<typename KEY, typename VALUE> inline
123const VALUE& KeyedVector<KEY,VALUE>::valueAt(size_t index) const {
124    return mVector.itemAt(index).value;
125}
126
127template<typename KEY, typename VALUE> inline
128const KEY& KeyedVector<KEY,VALUE>::keyAt(size_t index) const {
129    return mVector.itemAt(index).key;
130}
131
132template<typename KEY, typename VALUE> inline
133VALUE& KeyedVector<KEY,VALUE>::editValueFor(const KEY& key) {
134    ssize_t i = indexOfKey(key);
135    assert(i>=0);
136    return mVector.editItemAt(i).value;
137}
138
139template<typename KEY, typename VALUE> inline
140VALUE& KeyedVector<KEY,VALUE>::editValueAt(size_t index) {
141    return mVector.editItemAt(index).value;
142}
143
144template<typename KEY, typename VALUE> inline
145ssize_t KeyedVector<KEY,VALUE>::add(const KEY& key, const VALUE& value) {
146    return mVector.add( key_value_pair_t<KEY,VALUE>(key, value) );
147}
148
149template<typename KEY, typename VALUE> inline
150ssize_t KeyedVector<KEY,VALUE>::replaceValueFor(const KEY& key, const VALUE& value) {
151    key_value_pair_t<KEY,VALUE> pair(key, value);
152    mVector.remove(pair);
153    return mVector.add(pair);
154}
155
156template<typename KEY, typename VALUE> inline
157ssize_t KeyedVector<KEY,VALUE>::replaceValueAt(size_t index, const VALUE& item) {
158    if (index<size()) {
159        mVector.editValueAt(index).value = item;
160        return index;
161    }
162    return BAD_INDEX;
163}
164
165template<typename KEY, typename VALUE> inline
166ssize_t KeyedVector<KEY,VALUE>::removeItem(const KEY& key) {
167    return mVector.remove(key_value_pair_t<KEY,VALUE>(key));
168}
169
170template<typename KEY, typename VALUE> inline
171ssize_t KeyedVector<KEY, VALUE>::removeItemsAt(size_t index, size_t count) {
172    return mVector.removeItemsAt(index, count);
173}
174
175// ---------------------------------------------------------------------------
176
177template<typename KEY, typename VALUE> inline
178DefaultKeyedVector<KEY,VALUE>::DefaultKeyedVector(const VALUE& defValue)
179    : mDefault(defValue)
180{
181}
182
183template<typename KEY, typename VALUE> inline
184const VALUE& DefaultKeyedVector<KEY,VALUE>::valueFor(const KEY& key) const {
185    ssize_t i = indexOfKey(key);
186    return i >= 0 ? KeyedVector<KEY,VALUE>::valueAt(i) : mDefault;
187}
188
189}; // namespace android
190
191// ---------------------------------------------------------------------------
192
193#endif // ANDROID_KEYED_VECTOR_H
194