Added a Vector based map implementation.
git-svn-id: file:///srv/svn/repos/haiku/trunk/current@3793 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
92ec26a3be
commit
7e65f8eb29
71
headers/private/kernel/util/KernelUtilsOrder.h
Normal file
71
headers/private/kernel/util/KernelUtilsOrder.h
Normal file
@ -0,0 +1,71 @@
|
||||
// KernelUtilsOrders.h
|
||||
//
|
||||
// Copyright (c) 2003, Ingo Weinhold (bonefish@cs.tu-berlin.de)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
// Except as contained in this notice, the name of a copyright holder shall
|
||||
// not be used in advertising or otherwise to promote the sale, use or other
|
||||
// dealings in this Software without prior written authorization of the
|
||||
// copyright holder.
|
||||
|
||||
#ifndef _KERNEL_UTILS_ORDERS_H
|
||||
#define _KERNEL_UTILS_ORDERS_H
|
||||
|
||||
namespace KernelUtilsOrder {
|
||||
|
||||
// Ascending
|
||||
/*! \brief A compare function object implying and ascending order.
|
||||
|
||||
The < operator must be defined on the template argument type.
|
||||
*/
|
||||
template<typename Value>
|
||||
class Ascending {
|
||||
public:
|
||||
inline int operator()(const Value &a, const Value &b) const
|
||||
{
|
||||
if (a < b)
|
||||
return -1;
|
||||
else if (b < a)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
// Descending
|
||||
/*! \brief A compare function object implying and descending order.
|
||||
|
||||
The < operator must be defined on the template argument type.
|
||||
*/
|
||||
template<typename Value>
|
||||
class Descending {
|
||||
public:
|
||||
inline int operator()(const Value &a, const Value &b) const
|
||||
{
|
||||
if (a < b)
|
||||
return -1;
|
||||
else if (b < a)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace KernelUtilsOrder
|
||||
|
||||
#endif // _KERNEL_UTILS_ORDERS_H
|
741
headers/private/kernel/util/VectorMap.h
Normal file
741
headers/private/kernel/util/VectorMap.h
Normal file
@ -0,0 +1,741 @@
|
||||
// VectorMap.h
|
||||
//
|
||||
// Copyright (c) 2003, Ingo Weinhold (bonefish@cs.tu-berlin.de)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
// Except as contained in this notice, the name of a copyright holder shall
|
||||
// not be used in advertising or otherwise to promote the sale, use or other
|
||||
// dealings in this Software without prior written authorization of the
|
||||
// copyright holder.
|
||||
|
||||
#ifndef _VECTOR_MAP_H
|
||||
#define _VECTOR_MAP_H
|
||||
|
||||
#include <new>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <SupportDefs.h>
|
||||
|
||||
#include <KernelUtilsOrder.h>
|
||||
#include <Vector.h>
|
||||
|
||||
namespace VectorMapEntryStrategy {
|
||||
// Pair
|
||||
template<typename Key, typename Value,
|
||||
typename KeyOrder = KernelUtilsOrder::Ascending<Key> > class Pair;
|
||||
}
|
||||
|
||||
template<typename Entry, typename Parent, typename EntryIterator>
|
||||
class VectorMapIterator;
|
||||
template<typename _Key, typename _Value, typename Entry, typename Parent>
|
||||
class VectorMapEntry;
|
||||
|
||||
// for convenience
|
||||
#define _VECTOR_MAP_TEMPLATE_LIST template<typename Key, typename Value, \
|
||||
typename EntryStrategy>
|
||||
#define _VECTOR_MAP_CLASS_NAME VectorMap<Key, Value, EntryStrategy>
|
||||
|
||||
/*!
|
||||
\class VectorMap
|
||||
\brief A generic vector-based map implementation.
|
||||
|
||||
The map entries are ordered according to the supplied
|
||||
compare function object. Default is ascending order.
|
||||
|
||||
Note that VectorMap::Entry is not the same class as EntryStrategy::Entry.
|
||||
It is light-weight class, an object of which is returned when a iterator
|
||||
is dereferenced. It features a Key() and a Value() method returning
|
||||
references to the entry's key/value. This allows EntryStrategy::Entry
|
||||
to be an arbitrary class, not needing to implement a certain interface.
|
||||
*/
|
||||
template<typename Key, typename Value,
|
||||
typename EntryStrategy = VectorMapEntryStrategy::Pair<Key, Value> >
|
||||
class VectorMap {
|
||||
private:
|
||||
typedef _VECTOR_MAP_CLASS_NAME Class;
|
||||
typedef typename EntryStrategy::Entry _Entry;
|
||||
typedef Vector<_Entry> ElementVector;
|
||||
|
||||
public:
|
||||
typedef VectorMapEntry<Key, Value, _Entry, Class> Entry;
|
||||
typedef VectorMapEntry<Key, const Value, const _Entry, const Class>
|
||||
ConstEntry;
|
||||
typedef VectorMapIterator<Entry, Class, ElementVector::Iterator>
|
||||
Iterator;
|
||||
typedef VectorMapIterator<ConstEntry, const Class,
|
||||
ElementVector::ConstIterator> ConstIterator;
|
||||
|
||||
private:
|
||||
static const size_t kDefaultChunkSize = 10;
|
||||
static const size_t kMaximalChunkSize = 1024 * 1024;
|
||||
|
||||
public:
|
||||
VectorMap(size_t chunkSize = kDefaultChunkSize);
|
||||
// TODO: Copy constructor, assignment operator.
|
||||
~VectorMap();
|
||||
|
||||
status_t Insert(const Key &key, const Value &value);
|
||||
status_t Put(const Key &key, const Value &value);
|
||||
Value &Get(const Key &key);
|
||||
const Value &Get(const Key &key) const;
|
||||
|
||||
int32 Remove(const Key &key);
|
||||
Iterator Erase(const Iterator &iterator);
|
||||
|
||||
inline int32 Count() const;
|
||||
inline bool IsEmpty() const;
|
||||
void MakeEmpty();
|
||||
|
||||
inline Iterator Begin();
|
||||
inline ConstIterator Begin() const;
|
||||
inline Iterator End();
|
||||
inline ConstIterator End() const;
|
||||
inline Iterator Null();
|
||||
inline ConstIterator Null() const;
|
||||
|
||||
Iterator Find(const Key &key);
|
||||
ConstIterator Find(const Key &key) const;
|
||||
Iterator FindClose(const Key &key, bool less);
|
||||
ConstIterator FindClose(const Key &key, bool less) const;
|
||||
|
||||
private:
|
||||
int32 _FindInsertionIndex(const Key &key, bool &exists) const;
|
||||
|
||||
private:
|
||||
friend class Entry;
|
||||
friend class ConstEntry;
|
||||
|
||||
ElementVector fElements;
|
||||
EntryStrategy fEntryStrategy;
|
||||
};
|
||||
|
||||
|
||||
// VectorMapEntry
|
||||
template<typename _Key, typename _Value, typename Entry, typename Parent>
|
||||
class VectorMapEntry {
|
||||
private:
|
||||
typedef VectorMapEntry<_Key, _Value, Entry, Parent> Class;
|
||||
|
||||
public:
|
||||
VectorMapEntry()
|
||||
: fParent(NULL), fEntry(NULL) {}
|
||||
|
||||
inline const _Key &Key() const
|
||||
{
|
||||
return fParent->fEntryStrategy.GetKey(*fEntry);
|
||||
}
|
||||
|
||||
inline _Value &Value() const
|
||||
{
|
||||
return fParent->fEntryStrategy.GetValue(*fEntry);
|
||||
}
|
||||
|
||||
inline const Class *operator->() const
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
// private
|
||||
public:
|
||||
VectorMapEntry(Parent *parent, Entry *entry)
|
||||
: fParent(parent), fEntry(entry) {}
|
||||
|
||||
private:
|
||||
const Parent *fParent;
|
||||
Entry *fEntry;
|
||||
};
|
||||
|
||||
|
||||
// VectorMapIterator
|
||||
template<typename Entry, typename Parent, typename EntryIterator>
|
||||
class VectorMapIterator {
|
||||
private:
|
||||
typedef VectorMapIterator<Entry, Parent, EntryIterator> Iterator;
|
||||
|
||||
public:
|
||||
inline VectorMapIterator<Entry, Parent, EntryIterator>()
|
||||
: fParent(NULL),
|
||||
fIterator()
|
||||
{
|
||||
}
|
||||
|
||||
inline VectorMapIterator<Entry, Parent, EntryIterator>(
|
||||
const Iterator &other)
|
||||
: fParent(other.fParent),
|
||||
fIterator(other.fIterator)
|
||||
{
|
||||
}
|
||||
|
||||
inline Iterator &operator++()
|
||||
{
|
||||
++fIterator;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Iterator operator++(int)
|
||||
{
|
||||
Iterator it(*this);
|
||||
++*this;
|
||||
return it;
|
||||
}
|
||||
|
||||
inline Iterator &operator--()
|
||||
{
|
||||
--fIterator;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Iterator operator--(int)
|
||||
{
|
||||
Iterator it(*this);
|
||||
--*this;
|
||||
return it;
|
||||
}
|
||||
|
||||
inline Iterator &operator=(const Iterator &other)
|
||||
{
|
||||
fParent = other.fParent;
|
||||
fIterator = other.fIterator;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline bool operator==(const Iterator &other) const
|
||||
{
|
||||
return (fParent == other.fParent && fIterator == other.fIterator);
|
||||
}
|
||||
|
||||
inline bool operator!=(const Iterator &other) const
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
inline Entry operator*() const
|
||||
{
|
||||
return Entry(fParent, &*fIterator);
|
||||
}
|
||||
|
||||
inline Entry operator->() const
|
||||
{
|
||||
return Entry(fParent, &*fIterator);
|
||||
}
|
||||
|
||||
inline operator bool() const
|
||||
{
|
||||
return fIterator;
|
||||
}
|
||||
|
||||
// private
|
||||
public:
|
||||
inline VectorMapIterator<Entry, Parent, EntryIterator>(Parent *parent,
|
||||
const EntryIterator &iterator)
|
||||
: fParent(parent),
|
||||
fIterator(iterator)
|
||||
{
|
||||
}
|
||||
|
||||
inline EntryIterator &GetIterator()
|
||||
{
|
||||
return fIterator;
|
||||
}
|
||||
|
||||
inline const EntryIterator &GetIterator() const
|
||||
{
|
||||
return fIterator;
|
||||
}
|
||||
|
||||
protected:
|
||||
Parent *fParent;
|
||||
EntryIterator fIterator;
|
||||
};
|
||||
|
||||
|
||||
// VectorMap
|
||||
|
||||
// constructor
|
||||
/*! \brief Creates an empty map.
|
||||
\param chunkSize The granularity for the underlying vector's capacity,
|
||||
i.e. the minimal number of elements the capacity grows or shrinks
|
||||
when necessary.
|
||||
*/
|
||||
_VECTOR_MAP_TEMPLATE_LIST
|
||||
_VECTOR_MAP_CLASS_NAME::VectorMap(size_t chunkSize)
|
||||
: fElements(chunkSize)
|
||||
{
|
||||
}
|
||||
|
||||
// destructor
|
||||
/*! \brief Frees all resources associated with the object.
|
||||
|
||||
The contained keys and values are destroyed. Note, that for pointer
|
||||
types only the pointer is destroyed, not the object it points to.
|
||||
*/
|
||||
_VECTOR_MAP_TEMPLATE_LIST
|
||||
_VECTOR_MAP_CLASS_NAME::~VectorMap()
|
||||
{
|
||||
}
|
||||
|
||||
// Insert
|
||||
/*! \brief Associates a key with a value.
|
||||
|
||||
If there is already a value associated with the key, the old entry
|
||||
is replaced.
|
||||
|
||||
\param key The key to which a value shall be associated.
|
||||
\param value The value to be associated with the key.
|
||||
\return
|
||||
- \c B_OK: Everything went fine.
|
||||
- \c B_NO_MEMORY: Insufficient memory for this operation.
|
||||
- \c B_BAD_VALUE: The map's EntryStrategy requires some special
|
||||
relationship between key and value, that \a key and \a value haven't
|
||||
(doesn't apply to the default strategy).
|
||||
*/
|
||||
_VECTOR_MAP_TEMPLATE_LIST
|
||||
status_t
|
||||
_VECTOR_MAP_CLASS_NAME::Insert(const Key &key, const Value &value)
|
||||
{
|
||||
if (!fEntryStrategy.AreCompatible(key, value))
|
||||
return B_BAD_VALUE;
|
||||
bool exists = false;
|
||||
int32 index = _FindInsertionIndex(key, exists);
|
||||
if (exists) {
|
||||
fElements[index] = fEntryStrategy.MakeEntry(key, value);
|
||||
return B_OK;
|
||||
}
|
||||
return fElements.Insert(fEntryStrategy.MakeEntry(key, value), index);
|
||||
}
|
||||
|
||||
// Put
|
||||
/*! \brief Equivalent to Insert().
|
||||
*/
|
||||
_VECTOR_MAP_TEMPLATE_LIST
|
||||
inline
|
||||
status_t
|
||||
_VECTOR_MAP_CLASS_NAME::Put(const Key &key, const Value &value)
|
||||
{
|
||||
return Insert(key, value);
|
||||
}
|
||||
|
||||
// Get
|
||||
/*! \brief Returns the value associated with a given key.
|
||||
|
||||
\note Invoking this method for a key not know to the map is dangerous!
|
||||
The behavior is unspecified. It may even crash.
|
||||
|
||||
\param key The key to be looked up.
|
||||
\return The value associated with \a key.
|
||||
*/
|
||||
_VECTOR_MAP_TEMPLATE_LIST
|
||||
Value &
|
||||
_VECTOR_MAP_CLASS_NAME::Get(const Key &key)
|
||||
{
|
||||
bool exists = false;
|
||||
int32 index = _FindInsertionIndex(key, exists);
|
||||
if (!exists)
|
||||
return fEntryStrategy.GetValue(fElements[0]);
|
||||
return fEntryStrategy.GetValue(fElements[index]);
|
||||
}
|
||||
|
||||
// Get
|
||||
/*! \brief Returns the value associated with a given key.
|
||||
|
||||
\note Invoking this method for a key not know to the map is dangerous!
|
||||
The behavior is unspecified. It may even crash.
|
||||
|
||||
\param key The key to be looked up.
|
||||
\return The value associated with \a key.
|
||||
*/
|
||||
_VECTOR_MAP_TEMPLATE_LIST
|
||||
const Value &
|
||||
_VECTOR_MAP_CLASS_NAME::Get(const Key &key) const
|
||||
{
|
||||
bool exists = false;
|
||||
int32 index = _FindInsertionIndex(key, exists);
|
||||
if (!exists)
|
||||
return fEntryStrategy.GetValue(fElements[0]);
|
||||
return fEntryStrategy.GetValue(fElements[index]);
|
||||
}
|
||||
|
||||
// Remove
|
||||
/*! \brief Removes the entry with the supplied key.
|
||||
\param key The key to be removed.
|
||||
\return The number of removed occurrences, i.e. \c 1, if the map
|
||||
contained an entry with that key, \c 0 otherwise.
|
||||
*/
|
||||
_VECTOR_MAP_TEMPLATE_LIST
|
||||
int32
|
||||
_VECTOR_MAP_CLASS_NAME::Remove(const Key &key)
|
||||
{
|
||||
bool exists = false;
|
||||
int32 index = _FindInsertionIndex(key, exists);
|
||||
if (!exists)
|
||||
return 0;
|
||||
fElements.Erase(index);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Erase
|
||||
/*! \brief Removes the entry at the given position.
|
||||
\param iterator An iterator referring to the entry to be removed.
|
||||
\return An iterator referring to the entry succeeding the removed
|
||||
one (End(), if it was the last element that has been
|
||||
removed), or Null(), if \a iterator was an invalid iterator
|
||||
(in this case including End()).
|
||||
*/
|
||||
_VECTOR_MAP_TEMPLATE_LIST
|
||||
_VECTOR_MAP_CLASS_NAME::Iterator
|
||||
_VECTOR_MAP_CLASS_NAME::Erase(const Iterator &iterator)
|
||||
{
|
||||
return Iterator(this, fElements.Erase(iterator.GetIterator()));
|
||||
}
|
||||
|
||||
// Count
|
||||
/*! \brief Returns the number of entry the map contains.
|
||||
\return The number of entries the map contains.
|
||||
*/
|
||||
_VECTOR_MAP_TEMPLATE_LIST
|
||||
inline
|
||||
int32
|
||||
_VECTOR_MAP_CLASS_NAME::Count() const
|
||||
{
|
||||
return fElements.Count();
|
||||
}
|
||||
|
||||
// IsEmpty
|
||||
/*! \brief Returns whether the map is empty.
|
||||
\return \c true, if the map is empty, \c false otherwise.
|
||||
*/
|
||||
_VECTOR_MAP_TEMPLATE_LIST
|
||||
inline
|
||||
bool
|
||||
_VECTOR_MAP_CLASS_NAME::IsEmpty() const
|
||||
{
|
||||
return fElements.IsEmpty();
|
||||
}
|
||||
|
||||
// MakeEmpty
|
||||
/*! \brief Removes all entries from the map.
|
||||
*/
|
||||
_VECTOR_MAP_TEMPLATE_LIST
|
||||
void
|
||||
_VECTOR_MAP_CLASS_NAME::MakeEmpty()
|
||||
{
|
||||
fElements.MakeEmpty();
|
||||
}
|
||||
|
||||
// Begin
|
||||
/*! \brief Returns an iterator referring to the beginning of the map.
|
||||
|
||||
If the map is not empty, Begin() refers to its first entry,
|
||||
otherwise it is equal to End() and must not be dereferenced!
|
||||
|
||||
\return An iterator referring to the beginning of the map.
|
||||
*/
|
||||
_VECTOR_MAP_TEMPLATE_LIST
|
||||
inline
|
||||
_VECTOR_MAP_CLASS_NAME::Iterator
|
||||
_VECTOR_MAP_CLASS_NAME::Begin()
|
||||
{
|
||||
return Iterator(this, fElements.Begin());
|
||||
}
|
||||
|
||||
// Begin
|
||||
/*! \brief Returns an iterator referring to the beginning of the map.
|
||||
|
||||
If the map is not empty, Begin() refers to its first entry,
|
||||
otherwise it is equal to End() and must not be dereferenced!
|
||||
|
||||
\return An iterator referring to the beginning of the map.
|
||||
*/
|
||||
_VECTOR_MAP_TEMPLATE_LIST
|
||||
inline
|
||||
_VECTOR_MAP_CLASS_NAME::ConstIterator
|
||||
_VECTOR_MAP_CLASS_NAME::Begin() const
|
||||
{
|
||||
return ConstIterator(this, fElements.Begin());
|
||||
}
|
||||
|
||||
// End
|
||||
/*! \brief Returns an iterator referring to the end of the map.
|
||||
|
||||
The position identified by End() is the one succeeding the last
|
||||
entry, i.e. it must not be dereferenced!
|
||||
|
||||
\return An iterator referring to the end of the map.
|
||||
*/
|
||||
_VECTOR_MAP_TEMPLATE_LIST
|
||||
inline
|
||||
_VECTOR_MAP_CLASS_NAME::Iterator
|
||||
_VECTOR_MAP_CLASS_NAME::End()
|
||||
{
|
||||
return Iterator(this, fElements.End());
|
||||
}
|
||||
|
||||
// End
|
||||
/*! \brief Returns an iterator referring to the end of the map.
|
||||
|
||||
The position identified by End() is the one succeeding the last
|
||||
entry, i.e. it must not be dereferenced!
|
||||
|
||||
\return An iterator referring to the end of the map.
|
||||
*/
|
||||
_VECTOR_MAP_TEMPLATE_LIST
|
||||
inline
|
||||
_VECTOR_MAP_CLASS_NAME::ConstIterator
|
||||
_VECTOR_MAP_CLASS_NAME::End() const
|
||||
{
|
||||
return ConstIterator(this, fElements.End());
|
||||
}
|
||||
|
||||
// Null
|
||||
/*! \brief Returns an invalid iterator.
|
||||
|
||||
Null() is used as a return value, if something went wrong. It must
|
||||
neither be incremented or decremented nor dereferenced!
|
||||
|
||||
\return An invalid iterator.
|
||||
*/
|
||||
_VECTOR_MAP_TEMPLATE_LIST
|
||||
inline
|
||||
_VECTOR_MAP_CLASS_NAME::Iterator
|
||||
_VECTOR_MAP_CLASS_NAME::Null()
|
||||
{
|
||||
return Iterator(this, fElements.Null());
|
||||
}
|
||||
|
||||
// Null
|
||||
/*! \brief Returns an invalid iterator.
|
||||
|
||||
Null() is used as a return value, if something went wrong. It must
|
||||
neither be incremented or decremented nor dereferenced!
|
||||
|
||||
\return An invalid iterator.
|
||||
*/
|
||||
_VECTOR_MAP_TEMPLATE_LIST
|
||||
inline
|
||||
_VECTOR_MAP_CLASS_NAME::ConstIterator
|
||||
_VECTOR_MAP_CLASS_NAME::Null() const
|
||||
{
|
||||
return ConstIterator(this, fElements.Null());
|
||||
}
|
||||
|
||||
// Find
|
||||
/*! \brief Returns an iterator referring to the entry with the
|
||||
specified key.
|
||||
\param key The key of the entry to be found.
|
||||
\return An iterator referring to the found entry, or End(), if the
|
||||
map doesn't contain any entry with the given value.
|
||||
*/
|
||||
_VECTOR_MAP_TEMPLATE_LIST
|
||||
_VECTOR_MAP_CLASS_NAME::Iterator
|
||||
_VECTOR_MAP_CLASS_NAME::Find(const Key &key)
|
||||
{
|
||||
bool exists = false;
|
||||
int32 index = _FindInsertionIndex(key, exists);
|
||||
if (!exists)
|
||||
return End();
|
||||
return Iterator(this, fElements.IteratorForIndex(index));
|
||||
}
|
||||
|
||||
// Find
|
||||
/*! \brief Returns an iterator referring to the entry with the
|
||||
specified key.
|
||||
\param key The key of the entry to be found.
|
||||
\return An iterator referring to the found entry, or End(), if the
|
||||
map doesn't contain any entry with the given value.
|
||||
*/
|
||||
_VECTOR_MAP_TEMPLATE_LIST
|
||||
_VECTOR_MAP_CLASS_NAME::ConstIterator
|
||||
_VECTOR_MAP_CLASS_NAME::Find(const Key &key) const
|
||||
{
|
||||
bool exists = false;
|
||||
int32 index = _FindInsertionIndex(key, exists);
|
||||
if (!exists)
|
||||
return End();
|
||||
return ConstIterator(this, fElements.IteratorForIndex(index));
|
||||
}
|
||||
|
||||
// FindClose
|
||||
/*! \brief Returns an iterator referring to the entry with a key closest
|
||||
to the specified one.
|
||||
|
||||
If the map contains an entry with the specified key, an iterator
|
||||
to it is returned. Otherwise \a less indicates whether an iterator to
|
||||
the entry with an directly smaller or greater key shall be returned.
|
||||
|
||||
If \a less is \c true and the first entry in the map has a greater
|
||||
key than the specified one, End() is returned. Similarly, when \a less
|
||||
is \c false and the last entry's key is smaller. Find() invoked on an
|
||||
empty map always returns End().
|
||||
|
||||
Note, that the key order used for the set is specified as template
|
||||
argument to the class. Default is ascending order. Descending order
|
||||
inverts the meaning of \a less, i.e. if \c true, greater values will
|
||||
be returned, since they are smaller ones according to the order.
|
||||
|
||||
\param value The key of the entry to be found.
|
||||
\return An iterator referring to the found entry, or End(), if the
|
||||
map doesn't contain any entry with the given key or a close
|
||||
one according to \a less.
|
||||
*/
|
||||
_VECTOR_MAP_TEMPLATE_LIST
|
||||
_VECTOR_MAP_CLASS_NAME::Iterator
|
||||
_VECTOR_MAP_CLASS_NAME::FindClose(const Key &key, bool less)
|
||||
{
|
||||
bool exists = false;
|
||||
int32 index = _FindInsertionIndex(key, exists);
|
||||
// If not found, the index _FindInsertionIndex() returns will point to
|
||||
// an element with a greater value or to End(). So, no special handling
|
||||
// is needed for !less.
|
||||
if (exists || !less)
|
||||
return Iterator(this, fElements.IteratorForIndex(index));
|
||||
// An element with a smaller value is desired. The previous one (if any)
|
||||
// will do.
|
||||
if (index > 0)
|
||||
return Iterator(this, fElements.IteratorForIndex(index - 1));
|
||||
return End();
|
||||
}
|
||||
|
||||
// FindClose
|
||||
/*! \brief Returns an iterator referring to the entry with a key closest
|
||||
to the specified one.
|
||||
|
||||
If the map contains an entry with the specified key, an iterator
|
||||
to it is returned. Otherwise \a less indicates whether an iterator to
|
||||
the entry with an directly smaller or greater key shall be returned.
|
||||
|
||||
If \a less is \c true and the first entry in the map has a greater
|
||||
key than the specified one, End() is returned. Similarly, when \a less
|
||||
is \c false and the last entry's key is smaller. Find() invoked on an
|
||||
empty map always returns End().
|
||||
|
||||
Note, that the key order used for the set is specified as template
|
||||
argument to the class. Default is ascending order. Descending order
|
||||
inverts the meaning of \a less, i.e. if \c true, greater values will
|
||||
be returned, since they are smaller ones according to the order.
|
||||
|
||||
\param value The key of the entry to be found.
|
||||
\return An iterator referring to the found entry, or End(), if the
|
||||
map doesn't contain any entry with the given key or a close
|
||||
one according to \a less.
|
||||
*/
|
||||
_VECTOR_MAP_TEMPLATE_LIST
|
||||
_VECTOR_MAP_CLASS_NAME::ConstIterator
|
||||
_VECTOR_MAP_CLASS_NAME::FindClose(const Key &key, bool less) const
|
||||
{
|
||||
bool exists = false;
|
||||
int32 index = _FindInsertionIndex(key, exists);
|
||||
// If not found, the index _FindInsertionIndex() returns will point to
|
||||
// an element with a greater value or to End(). So, no special handling
|
||||
// is needed for !less.
|
||||
if (exists || !less)
|
||||
return ConstIterator(this, fElements.IteratorForIndex(index));
|
||||
// An element with a smaller value is desired. The previous one (if any)
|
||||
// will do.
|
||||
if (index > 0)
|
||||
return ConstIterator(this, fElements.IteratorForIndex(index - 1));
|
||||
return End();
|
||||
}
|
||||
|
||||
// _FindInsertionIndex
|
||||
/*! \brief Finds the index at which the entry with the supplied key is
|
||||
located or at which it would need to be inserted.
|
||||
\param key The key.
|
||||
\param exists Is set to \c true, if the map does already contain an
|
||||
entry with that key, to \c false otherwise.
|
||||
\return The index at which the entry with the supplied key is
|
||||
located or at which it would need to be inserted.
|
||||
*/
|
||||
_VECTOR_MAP_TEMPLATE_LIST
|
||||
int32
|
||||
_VECTOR_MAP_CLASS_NAME::_FindInsertionIndex(const Key &key,
|
||||
bool &exists) const
|
||||
{
|
||||
// binary search
|
||||
int32 lower = 0;
|
||||
int32 upper = Count();
|
||||
while (lower < upper) {
|
||||
int32 mid = (lower + upper) / 2;
|
||||
int cmp = fEntryStrategy.Compare(fEntryStrategy.GetKey(fElements[mid]),
|
||||
key);
|
||||
if (cmp < 0)
|
||||
lower = mid + 1;
|
||||
else
|
||||
upper = mid;
|
||||
}
|
||||
exists = (lower < Count() && fEntryStrategy.Compare(key,
|
||||
fEntryStrategy.GetKey(fElements[lower])) == 0);
|
||||
return lower;
|
||||
}
|
||||
|
||||
|
||||
// entry strategies
|
||||
|
||||
namespace VectorMapEntryStrategy {
|
||||
|
||||
template<typename Key, typename Value, typename KeyOrder>
|
||||
class Pair {
|
||||
public:
|
||||
class Entry {
|
||||
public:
|
||||
Entry(const Key &key, const Value &value)
|
||||
: key(key), value(value) {}
|
||||
|
||||
Key key;
|
||||
Value value;
|
||||
};
|
||||
|
||||
inline const Key &GetKey(const Entry &entry) const
|
||||
{
|
||||
return entry.key;
|
||||
}
|
||||
|
||||
inline const Value &GetValue(const Entry &entry) const
|
||||
{
|
||||
return entry.value;
|
||||
}
|
||||
|
||||
inline Value &GetValue(Entry &entry) const
|
||||
{
|
||||
return entry.value;
|
||||
}
|
||||
|
||||
inline Entry MakeEntry(const Key &key, const Value &value) const
|
||||
{
|
||||
return Entry(key, value);
|
||||
}
|
||||
|
||||
inline bool AreCompatible(const Key &, const Value &) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
inline int Compare(const Key &a, const Key &b) const
|
||||
{
|
||||
return fCompare(a, b);
|
||||
}
|
||||
|
||||
private:
|
||||
KeyOrder fCompare;
|
||||
};
|
||||
|
||||
} // VectorMapEntryStrategy
|
||||
|
||||
#endif // _VECTOR_MAP_H
|
Loading…
x
Reference in New Issue
Block a user