Added a generic Vector implementation.
git-svn-id: file:///srv/svn/repos/haiku/trunk/current@3744 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
c4de095cd1
commit
eaf9864cde
762
headers/private/kernel/util/Vector.h
Normal file
762
headers/private/kernel/util/Vector.h
Normal file
@ -0,0 +1,762 @@
|
||||
// Vector.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_H
|
||||
#define _VECTOR_H
|
||||
|
||||
#include <new>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <SupportDefs.h>
|
||||
|
||||
template<typename Value> class VectorIterator;
|
||||
|
||||
// for convenience
|
||||
#define _VECTOR_TEMPLATE_LIST template<typename Value>
|
||||
#define _VECTOR_CLASS_NAME Vector<Value>
|
||||
|
||||
/*!
|
||||
\class Vector
|
||||
\brief A generic vector implementation.
|
||||
*/
|
||||
template<typename Value>
|
||||
class Vector {
|
||||
public:
|
||||
typedef VectorIterator<Value> Iterator;
|
||||
typedef VectorIterator<const Value> ConstIterator;
|
||||
|
||||
private:
|
||||
static const size_t kDefaultChunkSize = 10;
|
||||
static const size_t kMaximalChunkSize = 1024 * 1024;
|
||||
|
||||
public:
|
||||
Vector(size_t chunkSize = kDefaultChunkSize);
|
||||
~Vector();
|
||||
|
||||
status_t PushFront(const Value &value);
|
||||
status_t PushBack(const Value &value);
|
||||
|
||||
void PopFront();
|
||||
void PopBack();
|
||||
|
||||
status_t Insert(const Value &value, int32 index);
|
||||
status_t Insert(const Value &value, const Iterator &iterator);
|
||||
|
||||
int32 Remove(const Value &value);
|
||||
Iterator Erase(int32 index);
|
||||
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;
|
||||
inline Iterator IteratorForIndex(int32 index);
|
||||
inline ConstIterator IteratorForIndex(int32 index) const;
|
||||
|
||||
inline const Value &ElementAt(int32 index) const;
|
||||
inline Value &ElementAt(int32 index);
|
||||
|
||||
int32 IndexOf(const Value &value, int32 start = 0) const;
|
||||
Iterator Find(const Value &value, const Iterator &start = Begin());
|
||||
ConstIterator Find(const Value &value,
|
||||
const ConstIterator &start = Begin()) const;
|
||||
|
||||
inline Value &operator[](int32 index);
|
||||
inline const Value &operator[](int32 index) const;
|
||||
|
||||
// debugging
|
||||
int32 GetCapacity() const { return fCapacity; }
|
||||
|
||||
private:
|
||||
inline static void _MoveItems(Value *values, int32 offset, int32 count);
|
||||
bool _Resize(size_t count);
|
||||
inline int32 _IteratorIndex(const Iterator &iterator) const;
|
||||
inline int32 _IteratorIndex(const ConstIterator &iterator) const;
|
||||
|
||||
private:
|
||||
size_t fCapacity;
|
||||
size_t fChunkSize;
|
||||
int32 fItemCount;
|
||||
Value *fItems;
|
||||
};
|
||||
|
||||
|
||||
// VectorIterator
|
||||
template<typename Value>
|
||||
class VectorIterator {
|
||||
private:
|
||||
typedef VectorIterator<Value> Iterator;
|
||||
|
||||
public:
|
||||
inline VectorIterator<Value>(const Iterator &other)
|
||||
: fElement(other.fElement)
|
||||
{
|
||||
}
|
||||
|
||||
inline Iterator &operator++()
|
||||
{
|
||||
if (fElement)
|
||||
++fElement;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Iterator operator++(int)
|
||||
{
|
||||
Iterator it(*this);
|
||||
++*this;
|
||||
return it;
|
||||
}
|
||||
|
||||
inline Iterator &operator--()
|
||||
{
|
||||
if (fElement)
|
||||
--fElement;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Iterator operator--(int)
|
||||
{
|
||||
Iterator it(*this);
|
||||
--*this;
|
||||
return it;
|
||||
}
|
||||
|
||||
inline Iterator &operator=(const Iterator &other)
|
||||
{
|
||||
fElement = other.fElement;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
inline bool operator==(const Iterator &other) const
|
||||
{
|
||||
return (fElement == other.fElement);
|
||||
}
|
||||
|
||||
inline bool operator!=(const Iterator &other) const
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
inline Value &operator*() const
|
||||
{
|
||||
return *fElement;
|
||||
}
|
||||
|
||||
inline Value *operator->() const
|
||||
{
|
||||
return fElement;
|
||||
}
|
||||
|
||||
inline operator bool() const
|
||||
{
|
||||
return fElement;
|
||||
}
|
||||
|
||||
// private
|
||||
public:
|
||||
inline VectorIterator<Value>(Value *element = NULL)
|
||||
: fElement(element)
|
||||
{
|
||||
}
|
||||
|
||||
inline Value *Element() const
|
||||
{
|
||||
return fElement;
|
||||
}
|
||||
|
||||
protected:
|
||||
Value *fElement;
|
||||
};
|
||||
|
||||
|
||||
// Vector
|
||||
|
||||
// constructor
|
||||
/*! \brief Creates an empty vector.
|
||||
\param chunkSize The granularity for the vector's capacity, i.e. the
|
||||
minimal number of elements the capacity grows or shrinks when
|
||||
necessary.
|
||||
*/
|
||||
_VECTOR_TEMPLATE_LIST
|
||||
_VECTOR_CLASS_NAME::Vector(size_t chunkSize)
|
||||
: fCapacity(0),
|
||||
fChunkSize(chunkSize),
|
||||
fItemCount(0),
|
||||
fItems(NULL)
|
||||
{
|
||||
if (fChunkSize == 0 || fChunkSize > kMaximalChunkSize)
|
||||
fChunkSize = kDefaultChunkSize;
|
||||
_Resize(0);
|
||||
}
|
||||
|
||||
// destructor
|
||||
/*! \brief Frees all resources associated with the object.
|
||||
|
||||
The contained elements are destroyed. Note, that, if the element
|
||||
type is a pointer type, only the pointer is destroyed, not the object
|
||||
it points to.
|
||||
*/
|
||||
_VECTOR_TEMPLATE_LIST
|
||||
_VECTOR_CLASS_NAME::~Vector()
|
||||
{
|
||||
MakeEmpty();
|
||||
free(fItems);
|
||||
}
|
||||
|
||||
// PushFront
|
||||
/*! \brief Inserts a copy of the supplied value at the beginning of the
|
||||
vector.
|
||||
\param value The element to be inserted.
|
||||
\return
|
||||
- \c B_OK: Everything went fine.
|
||||
- \c B_NO_MEMORY: Insufficient memory for this operation.
|
||||
*/
|
||||
_VECTOR_TEMPLATE_LIST
|
||||
status_t
|
||||
_VECTOR_CLASS_NAME::PushFront(const Value &value)
|
||||
{
|
||||
return Insert(value, 0);
|
||||
}
|
||||
|
||||
// PushBack
|
||||
/*! \brief Inserts a copy of the supplied value at the end of the vector.
|
||||
\param value The element to be inserted.
|
||||
\return
|
||||
- \c B_OK: Everything went fine.
|
||||
- \c B_NO_MEMORY: Insufficient memory for this operation.
|
||||
*/
|
||||
_VECTOR_TEMPLATE_LIST
|
||||
status_t
|
||||
_VECTOR_CLASS_NAME::PushBack(const Value &value)
|
||||
{
|
||||
return Insert(value, fItemCount);
|
||||
}
|
||||
|
||||
// PopFront
|
||||
/*! \brief Removes the first element of the vector.
|
||||
|
||||
Invocation on an empty vector is harmless.
|
||||
*/
|
||||
_VECTOR_TEMPLATE_LIST
|
||||
void
|
||||
_VECTOR_CLASS_NAME::PopFront()
|
||||
{
|
||||
if (fItemCount > 0)
|
||||
Erase(0);
|
||||
}
|
||||
|
||||
// PopBack
|
||||
/*! \brief Removes the last element of the vector.
|
||||
|
||||
Invocation on an empty vector is harmless.
|
||||
*/
|
||||
_VECTOR_TEMPLATE_LIST
|
||||
void
|
||||
_VECTOR_CLASS_NAME::PopBack()
|
||||
{
|
||||
if (fItemCount > 0)
|
||||
Erase(fItemCount - 1);
|
||||
}
|
||||
|
||||
// _MoveItems
|
||||
/*! \brief Moves elements within an array.
|
||||
\param items The elements to be moved.
|
||||
\param offset The index to which the elements shall be moved. May be
|
||||
negative.
|
||||
\param count The number of elements to be moved.
|
||||
*/
|
||||
_VECTOR_TEMPLATE_LIST
|
||||
inline
|
||||
void
|
||||
_VECTOR_CLASS_NAME::_MoveItems(Value* items, int32 offset, int32 count)
|
||||
{
|
||||
if (count > 0 && offset != 0)
|
||||
memmove(items + offset, items, count * sizeof(Value));
|
||||
}
|
||||
|
||||
// Insert
|
||||
/*! \brief Inserts a copy of the the supplied value at the given index.
|
||||
\param value The value to be inserted.
|
||||
\param index The index at which to insert the new element. It must
|
||||
hold: 0 <= \a index <= Count().
|
||||
\return
|
||||
- \c B_OK: Everything went fine.
|
||||
- \c B_BAD_VALUE: \a index is out of range.
|
||||
- \c B_NO_MEMORY: Insufficient memory for this operation.
|
||||
*/
|
||||
_VECTOR_TEMPLATE_LIST
|
||||
status_t
|
||||
_VECTOR_CLASS_NAME::Insert(const Value &value, int32 index)
|
||||
{
|
||||
if (index < 0 || index > fItemCount)
|
||||
return B_BAD_VALUE;
|
||||
if (!_Resize(fItemCount + 1))
|
||||
return B_NO_MEMORY;
|
||||
_MoveItems(fItems + index, 1, fItemCount - index - 1);
|
||||
new(fItems + index) Value(value);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
// Insert
|
||||
/*! \brief Inserts a copy of the the supplied value at the given position.
|
||||
\param value The value to be inserted.
|
||||
\param iterator An iterator specifying the position at which to insert
|
||||
the new element.
|
||||
\return
|
||||
- \c B_OK: Everything went fine.
|
||||
- \c B_BAD_VALUE: \a iterator is is invalid.
|
||||
- \c B_NO_MEMORY: Insufficient memory for this operation.
|
||||
*/
|
||||
_VECTOR_TEMPLATE_LIST
|
||||
status_t
|
||||
_VECTOR_CLASS_NAME::Insert(const Value &value, const Iterator &iterator)
|
||||
{
|
||||
int32 index = _IteratorIndex(iterator);
|
||||
if (index >= 0)
|
||||
return Insert(value, index);
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
|
||||
// Remove
|
||||
/*! \brief Removes all elements of the supplied value.
|
||||
\param value The value of the elements to be removed.
|
||||
\return The number of removed occurrences.
|
||||
*/
|
||||
_VECTOR_TEMPLATE_LIST
|
||||
int32
|
||||
_VECTOR_CLASS_NAME::Remove(const Value &value)
|
||||
{
|
||||
int32 count = 0;
|
||||
for (int32 i = fItemCount - 1; i >= 0; i--) {
|
||||
if (ElementAt(i) == value) {
|
||||
Erase(i);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
// Erase
|
||||
/*! \brief Removes the element at the given index.
|
||||
\param index The position of the element to be removed.
|
||||
\return An iterator referring to the element now being located at index
|
||||
\a index (End(), if it was the last element that has been
|
||||
removed), or Null(), if \a index was out of range.
|
||||
*/
|
||||
_VECTOR_TEMPLATE_LIST
|
||||
_VECTOR_CLASS_NAME::Iterator
|
||||
_VECTOR_CLASS_NAME::Erase(int32 index)
|
||||
{
|
||||
if (index >= 0 && index < fItemCount) {
|
||||
fItems[index].~Value();
|
||||
_MoveItems(fItems + index + 1, -1, fItemCount - index - 1);
|
||||
_Resize(fItemCount - 1);
|
||||
return Iterator(fItems + index);
|
||||
}
|
||||
return Null();
|
||||
}
|
||||
|
||||
// Erase
|
||||
/*! \brief Removes the element at the given position.
|
||||
\param iterator An iterator referring to the element to be removed.
|
||||
\return An iterator referring to the element 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_TEMPLATE_LIST
|
||||
_VECTOR_CLASS_NAME::Iterator
|
||||
_VECTOR_CLASS_NAME::Erase(const Iterator &iterator)
|
||||
{
|
||||
int32 index = _IteratorIndex(iterator);
|
||||
if (index >= 0 && index < fItemCount)
|
||||
return Erase(index);
|
||||
return Null();
|
||||
}
|
||||
|
||||
// Count
|
||||
/*! \brief Returns the number of elements the vector contains.
|
||||
\return The number of elements the vector contains.
|
||||
*/
|
||||
_VECTOR_TEMPLATE_LIST
|
||||
inline
|
||||
int32
|
||||
_VECTOR_CLASS_NAME::Count() const
|
||||
{
|
||||
return fItemCount;
|
||||
}
|
||||
|
||||
// IsEmpty
|
||||
/*! \brief Returns whether the vector is empty.
|
||||
\return \c true, if the vector is empty, \c false otherwise.
|
||||
*/
|
||||
_VECTOR_TEMPLATE_LIST
|
||||
inline
|
||||
bool
|
||||
_VECTOR_CLASS_NAME::IsEmpty() const
|
||||
{
|
||||
return (fItemCount == 0);
|
||||
}
|
||||
|
||||
// MakeEmpty
|
||||
/*! \brief Removes all elements of the vector.
|
||||
*/
|
||||
_VECTOR_TEMPLATE_LIST
|
||||
void
|
||||
_VECTOR_CLASS_NAME::MakeEmpty()
|
||||
{
|
||||
for (int32 i = 0; i < fItemCount; i++)
|
||||
fItems[i].~Value();
|
||||
_Resize(0);
|
||||
}
|
||||
|
||||
// Begin
|
||||
/*! \brief Returns an iterator referring to the beginning of the vector.
|
||||
|
||||
If the vector is not empty, Begin() refers to its first element,
|
||||
otherwise it is equal to End() and must not be dereference!
|
||||
|
||||
\return An iterator referring to the beginning of the vector.
|
||||
*/
|
||||
_VECTOR_TEMPLATE_LIST
|
||||
inline
|
||||
_VECTOR_CLASS_NAME::Iterator
|
||||
_VECTOR_CLASS_NAME::Begin()
|
||||
{
|
||||
return Iterator(fItems);
|
||||
}
|
||||
|
||||
// Begin
|
||||
/*! \brief Returns an iterator referring to the beginning of the vector.
|
||||
|
||||
If the vector is not empty, Begin() refers to its first element,
|
||||
otherwise it is equal to End() and must not be dereference!
|
||||
|
||||
\return An iterator referring to the beginning of the vector.
|
||||
*/
|
||||
_VECTOR_TEMPLATE_LIST
|
||||
inline
|
||||
_VECTOR_CLASS_NAME::ConstIterator
|
||||
_VECTOR_CLASS_NAME::Begin() const
|
||||
{
|
||||
return ConstIterator(fItems);
|
||||
}
|
||||
|
||||
// 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_TEMPLATE_LIST
|
||||
inline
|
||||
_VECTOR_CLASS_NAME::Iterator
|
||||
_VECTOR_CLASS_NAME::Null()
|
||||
{
|
||||
return Iterator(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_TEMPLATE_LIST
|
||||
inline
|
||||
_VECTOR_CLASS_NAME::ConstIterator
|
||||
_VECTOR_CLASS_NAME::Null() const
|
||||
{
|
||||
return ConstIterator(NULL);
|
||||
}
|
||||
|
||||
// End
|
||||
/*! \brief Returns an iterator referring to the end of the vector.
|
||||
|
||||
The position identified by End() is the one succeeding the last
|
||||
element, i.e. it must not be dereferenced!
|
||||
|
||||
\return An iterator referring to the end of the vector.
|
||||
*/
|
||||
_VECTOR_TEMPLATE_LIST
|
||||
inline
|
||||
_VECTOR_CLASS_NAME::Iterator
|
||||
_VECTOR_CLASS_NAME::End()
|
||||
{
|
||||
return Iterator(fItems + fItemCount);
|
||||
}
|
||||
|
||||
// End
|
||||
/*! \brief Returns an iterator referring to the end of the vector.
|
||||
|
||||
The position identified by End() is the one succeeding the last
|
||||
element, i.e. it must not be dereferenced!
|
||||
|
||||
\return An iterator referring to the end of the vector.
|
||||
*/
|
||||
_VECTOR_TEMPLATE_LIST
|
||||
inline
|
||||
_VECTOR_CLASS_NAME::ConstIterator
|
||||
_VECTOR_CLASS_NAME::End() const
|
||||
{
|
||||
return ConstIterator(fItems + fItemCount);
|
||||
}
|
||||
|
||||
// IteratorForIndex
|
||||
/*! \brief Returns an iterator for a given index.
|
||||
\return An iterator referring to the same element as \a index, or
|
||||
End(), if \a index is out of range.
|
||||
*/
|
||||
_VECTOR_TEMPLATE_LIST
|
||||
inline
|
||||
_VECTOR_CLASS_NAME::Iterator
|
||||
_VECTOR_CLASS_NAME::IteratorForIndex(int32 index)
|
||||
{
|
||||
if (index >= 0 && index <= fItemCount)
|
||||
return Iterator(fItems + index);
|
||||
return End();
|
||||
}
|
||||
|
||||
// IteratorForIndex
|
||||
/*! \brief Returns an iterator for a given index.
|
||||
\return An iterator referring to the same element as \a index, or
|
||||
End(), if \a index is out of range.
|
||||
*/
|
||||
_VECTOR_TEMPLATE_LIST
|
||||
inline
|
||||
_VECTOR_CLASS_NAME::ConstIterator
|
||||
_VECTOR_CLASS_NAME::IteratorForIndex(int32 index) const
|
||||
{
|
||||
if (index >= 0 && index <= fItemCount)
|
||||
return ConstIterator(fItems + index);
|
||||
return End();
|
||||
}
|
||||
|
||||
// ElementAt
|
||||
/*! \brief Returns the element at a given index.
|
||||
\param index The index identifying the element to be returned.
|
||||
\return The element identified by the given index.
|
||||
*/
|
||||
_VECTOR_TEMPLATE_LIST
|
||||
inline
|
||||
const Value &
|
||||
_VECTOR_CLASS_NAME::ElementAt(int32 index) const
|
||||
{
|
||||
if (index >= 0 && index < fItemCount)
|
||||
return fItems[index];
|
||||
// Return the 0th element by default. Unless the allocation failed, there
|
||||
// is always a 0th element -- uninitialized perhaps.
|
||||
return fItems[0];
|
||||
}
|
||||
|
||||
// ElementAt
|
||||
/*! \brief Returns the element at a given index.
|
||||
\param index The index identifying the element to be returned.
|
||||
\return The element identified by the given index.
|
||||
*/
|
||||
_VECTOR_TEMPLATE_LIST
|
||||
inline
|
||||
Value &
|
||||
_VECTOR_CLASS_NAME::ElementAt(int32 index)
|
||||
{
|
||||
if (index >= 0 && index < fItemCount)
|
||||
return fItems[index];
|
||||
// Return the 0th element by default. Unless the allocation failed, there
|
||||
// is always a 0th element -- uninitialized perhaps.
|
||||
return fItems[0];
|
||||
}
|
||||
|
||||
// IndexOf
|
||||
/*! \brief Returns the index of the next element with the specified value.
|
||||
\param value The value of the element to be found.
|
||||
\param start The index at which to be started to search for the element.
|
||||
\return The index of the found element, or \c -1, if no further element
|
||||
with the given value could be found or \a index is out of range.
|
||||
*/
|
||||
_VECTOR_TEMPLATE_LIST
|
||||
int32
|
||||
_VECTOR_CLASS_NAME::IndexOf(const Value &value, int32 start) const
|
||||
{
|
||||
if (start >= 0) {
|
||||
for (int32 i = start; i < fItemCount; i++) {
|
||||
if (fItems[i] == value)
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Find
|
||||
/*! \brief Returns an iterator referring to the of the next element with the
|
||||
specified value.
|
||||
\param value The value of the element to be found.
|
||||
\param start And iterator specifying where to start searching for the
|
||||
element.
|
||||
\return An iterator referring to the found element, or End(), if no
|
||||
further with the given value could be found or \a start was
|
||||
invalid.
|
||||
*/
|
||||
_VECTOR_TEMPLATE_LIST
|
||||
_VECTOR_CLASS_NAME::Iterator
|
||||
_VECTOR_CLASS_NAME::Find(const Value &value, const Iterator &start)
|
||||
{
|
||||
int32 index = IndexOf(value, _IteratorIndex(start));
|
||||
if (index >= 0)
|
||||
return Iterator(fItems + index);
|
||||
return End();
|
||||
}
|
||||
|
||||
// Find
|
||||
/*! \brief Returns an iterator referring to the of the next element with the
|
||||
specified value.
|
||||
\param value The value of the element to be found.
|
||||
\param start And iterator specifying where to start searching for the
|
||||
element.
|
||||
\return An iterator referring to the found element, or End(), if no
|
||||
further with the given value could be found or \a start was
|
||||
invalid.
|
||||
*/
|
||||
_VECTOR_TEMPLATE_LIST
|
||||
_VECTOR_CLASS_NAME::ConstIterator
|
||||
_VECTOR_CLASS_NAME::Find(const Value &value, const ConstIterator &start) const
|
||||
{
|
||||
int32 index = IndexOf(value, _IteratorIndex(start));
|
||||
if (index >= 0)
|
||||
return ConstIterator(fItems + index);
|
||||
return End();
|
||||
}
|
||||
|
||||
// []
|
||||
/*! \brief Semantically equivalent to ElementAt().
|
||||
*/
|
||||
_VECTOR_TEMPLATE_LIST
|
||||
inline
|
||||
Value &
|
||||
_VECTOR_CLASS_NAME::operator[](int32 index)
|
||||
{
|
||||
return ElementAt(index);
|
||||
}
|
||||
|
||||
// []
|
||||
/*! \brief Semantically equivalent to ElementAt().
|
||||
*/
|
||||
_VECTOR_TEMPLATE_LIST
|
||||
inline
|
||||
const Value &
|
||||
_VECTOR_CLASS_NAME::operator[](int32 index) const
|
||||
{
|
||||
return ElementAt(index);
|
||||
}
|
||||
|
||||
// _Resize
|
||||
/*! \brief Resizes the vector.
|
||||
|
||||
The internal element array will be grown or shrunk to the next multiple
|
||||
of \a fChunkSize >= \a count, but no less than \a fChunkSize.
|
||||
|
||||
Also adjusts \a fItemCount according to the supplied \a count, but does
|
||||
not invoke a destructor or constructor on any element.
|
||||
|
||||
\param count The number of element.
|
||||
\return \c true, if everything went fine, \c false, if the memory
|
||||
allocation failed.
|
||||
*/
|
||||
_VECTOR_TEMPLATE_LIST
|
||||
bool
|
||||
_VECTOR_CLASS_NAME::_Resize(size_t count)
|
||||
{
|
||||
bool result = true;
|
||||
// calculate the new capacity
|
||||
int32 newSize = count;
|
||||
if (newSize <= 0)
|
||||
newSize = 1;
|
||||
newSize = ((newSize - 1) / fChunkSize + 1) * fChunkSize;
|
||||
// resize if necessary
|
||||
if ((size_t)newSize != fCapacity) {
|
||||
Value* newItems = (Value*)realloc(fItems, newSize * sizeof(Value));
|
||||
if (newItems) {
|
||||
fItems = newItems;
|
||||
fCapacity = newSize;
|
||||
} else
|
||||
result = false;
|
||||
}
|
||||
if (result)
|
||||
fItemCount = count;
|
||||
return result;
|
||||
}
|
||||
|
||||
// _IteratorIndex
|
||||
/*! \brief Returns index of the element the supplied iterator refers to.
|
||||
\return The index of the element the supplied iterator refers to, or
|
||||
\c -1, if the iterator is invalid (End() is considered valid
|
||||
here, and Count() is returned).
|
||||
*/
|
||||
_VECTOR_TEMPLATE_LIST
|
||||
inline
|
||||
int32
|
||||
_VECTOR_CLASS_NAME::_IteratorIndex(const Iterator &iterator) const
|
||||
{
|
||||
if (iterator.Element()) {
|
||||
int32 index = iterator.Element() - fItems;
|
||||
if (index >= 0 && index <= fItemCount)
|
||||
return index;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
// _IteratorIndex
|
||||
/*! \brief Returns index of the element the supplied iterator refers to.
|
||||
\return The index of the element the supplied iterator refers to, or
|
||||
\c -1, if the iterator is invalid (End() is considered valid
|
||||
here, and Count() is returned).
|
||||
*/
|
||||
_VECTOR_TEMPLATE_LIST
|
||||
inline
|
||||
int32
|
||||
_VECTOR_CLASS_NAME::_IteratorIndex(const ConstIterator &iterator) const
|
||||
{
|
||||
if (iterator.Element()) {
|
||||
int32 index = iterator.Element() - fItems;
|
||||
if (index >= 0 && index <= fItemCount)
|
||||
return index;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
#endif // _VECTOR_H
|
Loading…
Reference in New Issue
Block a user