CUtlVector: Difference between revisions

From Valve Developer Community
Jump to navigation Jump to search
m (Added Tier1 category)
(nice! did some cleanup/wikifying)
Line 1: Line 1:
A '''CUtlVector''' is a templated, array-like container to which you can add and remove elements at any position. Code can be found in '''public/tier1/utlvector.h'''.
{{toc-right}}
 
A '''CUtlVector''' is Source's equivalent of the [[W:Vector (C++)|C++ Vector]] type. It can be thought of as an array of dynamic length. Code can be found in '''public/tier1/utlvector.h'''.
 
For detailed discussion of the pros and cons of vectors, [[W:Vector (C++)|see Wikipedia]].


{{warning|Vector elements can be moved around in memory, so never keep pointers to elements in the vector.}}
{{warning|Vector elements can be moved around in memory, so never keep pointers to elements in the vector.}}


= Accessing elements =
== Accessing elements ==
== Simple access ==
 
You can use array-style or use a method for index access:
You can use array-style or use a method for index access:


// Initialize vector
<source lang=cpp>
CUtlVector<CBaseEntity> vectorList;
// Initialize vector for given type
CUtlVector<CBaseEntity*> vectorList;
// Do population here
// Access vector
vectorList[ 0 ]->entindex();
vectorList.Element( 0 )->entindex();


You can also access the head and tail:
// (Populate vector here)


vectorList.Head();
// Access vector
vectorList.Tail();
vectorList[ 0 ]->entindex();
vectorList.Element( 0 )->entindex();
</source>


== Getting bounds ==
You can also access the head (first element) and tail (last element):
For loops, you can use the <code>Count()</code> method.
{{Warning|There is also a <code>Size()</code> method, but it is '''deprecated'''.}}


For individual elements, you can use the <code>IsValidIndex( int i )</code> method.
<source lang=cpp>
vectorList.Head();
vectorList.Tail();
</source>


Handy methods for assertions may be:
=== Finding bounds ===
* <code>EnsureCapacity( int num )</code> makes sure we have enough memory allocated to store a requested number of elements.
* <code>EnsureCount( int num )</code> makes sure we have at least this many elements.


= Adding elements =
; <code>Count()</code>
: The total number of items in the vector. (There is also a <code>Size()</code> method, but it is deprecated.)
; <code>IsValidIndex( [[int]] i )</code>
: Self-explanatory.
; <code>EnsureCapacity( int num )</code>
: Makes sure we have enough memory allocated to store a requested number of elements.
; <code>EnsureCount( int num )</code>
: Makes sure we have at least this many elements.
 
== Adding elements ==
There are several methods for adding individual elements, multiple elements as well as other CUtlVectors:
There are several methods for adding individual elements, multiple elements as well as other CUtlVectors:


== Single elements ==
Singly:


* <code>AddToHead( const T& src )</code> puts the element first in the list.
; <code>AddToHead( const T& src )</code>
* <code>AddToTail( const T& src )</code> puts the element last in the list.
; <code>AddToTail( const T& src )</code>
* <code>InsertBefore( int elem, const T& src )</code> puts the element before a certain index.
: Adds the element to the start or end of the list.
* <code>InsertAfter( int elem, const T& src )</code> puts the element after a certain index.
; <code>InsertBefore( int elem, const T& src )</code>
; <code>InsertAfter( int elem, const T& src )</code>
: Puts the element before or after a certain index.


== Multiple elements ==
In batches:


* <code>AddMultipleToTail( int num, const T *pToCopy )</code> adds several elements to the end of the list.
; <code>AddMultipleToTail( int num, const T *pToCopy )</code>
* <code>InsertMultipleBefore( int elem, int num, const T *pToInsert )</code> adds several elements before a valid index position except the head (which is always 0).
: Adds several elements to the end of the list.
* <code>AddVectorToTail( CUtlVector const &src )</code> adds another CUtlVector to the tail.
; <code>InsertMultipleBefore( int elem, int num, const T *pToInsert )</code>
: Adds several elements before a valid index position except the head (which is always 0).
; <code>AddVectorToTail( CUtlVector const &src )</code>
: Adds another CUtlVector to the tail.


= Searching elements =
== Searching elements ==
{{Note|If you want an automatically sorting list, have a look at [[CUtlSortVector]]. }}


{{tip|If you want an automatically sorting list, have a look at [[CUtlSortVector]]. }}


{{Note|To search for an element, your type must have implemented the &#61;&#61; operator. }}
To search for an element, your type must have implemented the <code>==</code> operator.
* The <code>Find()</code> method allows you to search through the CUtlVector.
* <code>HasElement()</code> allows you to check if the vector contains a certain element.
* With <code>FindAndRemove()</code>, you can easily remove elements from the vector.


= Removing elements =
; <code>Find()</code>
: Searches the vector {{todo|For what?}}
; <code>HasElement(T&)</code>
: Check if the vector contains the given element.
; <code>FindAndRemove()</code>
: Self-explanatory
 
== Removing elements ==
When you remove an element, its destructor is called and the vector is reordered.
When you remove an element, its destructor is called and the vector is reordered.


== Single elements ==
Singly:
* You can use <code>FindAndRemove()</code> (see above).
* <code>Remove( int elem )</code> calls the destructor of the element at the given position and shifts all elements left.
* <code>FastRemove( int elem )</code> is similar to <code>Remove()</code>, but just does a memcpy to accomodate for the removed element.


== Multiple elements ==
; <code>FindAndRemove()</code>
* <code>RemoveMultiple( int elem, int num )</code> removes <code>num</code> elements starting at position <code>elem</code>. Actual removal of elements is done in a right-to-left manner.
: See above.
* <code>RemoveAll()</code> clears the entire vector.
; <code>Remove( int elem )</code>
: Calls the destructor of the element at the given position and shifts all elements left.
; <code>FastRemove( int elem )</code>
: Similar to <code>Remove()</code>, but just does a memcpy to accomodate for the removed element.


= Copying =
In batches:


== From array ==
; <code>RemoveMultiple( int elem, int num )</code>
* <code>CopyArray( const T *pArray, int size )</code> copies <code>size</code> elements of the given array into the vector, possibly overwriting elements. Always starts from index 0.
: Removes <code>num</code> elements starting at position <code>elem</code>. Actual removal of elements is done in a right-to-left manner.
; <code>RemoveAll()</code>
: Clears the entire vector.


== Swap with other CUtlVector ==
== Copying ==
* <code>Swap( CUtlVector< T, A > &vec )</code> simply swaps the vector with the given one.


= Memory deallocation =
; <code>CopyArray( const T *pArray, int size )</code>
* <code>Purge()</code> calls <code>RemoveAll()</code> and purges the allocated memory.
: Copies <code>size</code> elements of the given array into the vector, possibly overwriting elements. Always starts from index 0.
* <code>PurgeAndDeleteElements()</code> first <code><span style="color:blue;">delete</span></code>'s all elements and then calls <code>Purge()</code>.
; <code>Swap( CUtlVector< T, A > &vec )</code>
: Simply swaps the vector with the given one.


== Deallocating ==
; <code>Purge()</code>
: Calls <code>RemoveAll()</code> and purges the allocated memory.
; <code>PurgeAndDeleteElements()</code>
: First <code><span style="color:blue;">delete</span></code>'s all elements and then calls <code>Purge()</code>.


 
== Sorting ==
= Sorting a CUtlVector =
The class has a Sort method that takes a predicate, like so:
The class has a Sort method that takes a predicate, like so:


// Sort vector by predicate
<source lang=cpp>
vectorList.Sort( predicateFunction );
// Sort vector by predicate
vectorList.Sort( predicateFunction );
</source>


In this case, the predicate must be of the type <code>int (__cdecl *)(const CBaseEntity *, const CBaseEntity *)</code>:
In this case, the predicate must be of the type <code>int (__cdecl *)(const CBaseEntity *, const CBaseEntity *)</code>:


static int __cdecl predicateFunction( const CBaseEntity *a, const CBaseEntity *b )
<source lang=cpp>
{
static int __cdecl predicateFunction( const CBaseEntity *a, const CBaseEntity *b )
int valueA = a->entindex();
{
int valueB = b->entindex();
int valueA = a->entindex();
int valueB = b->entindex();
if( valueA < valueB )
 
return -1;
if( valueA < valueB )
else if( valueA == valueB )
return -1;
return 0;
else if( valueA == valueB )
else return 1;
return 0;
else return 1;
  }
  }
</source>


{{Note|This function needs to be defined before the method it is called in.}}
This function needs to be defined before the method it is called in.


[[Category:Tier1]]
[[Category:Tier1]]
[[Category:Classes]]

Revision as of 15:04, 2 March 2011

A CUtlVector is Source's equivalent of the C++ Vector type. It can be thought of as an array of dynamic length. Code can be found in public/tier1/utlvector.h.

For detailed discussion of the pros and cons of vectors, see Wikipedia.

Warning.pngWarning:Vector elements can be moved around in memory, so never keep pointers to elements in the vector.

Accessing elements

You can use array-style or use a method for index access:

// Initialize vector for given type
CUtlVector<CBaseEntity*> vectorList;

// (Populate vector here)

// Access vector 
vectorList[ 0 ]->entindex();
vectorList.Element( 0 )->entindex();

You can also access the head (first element) and tail (last element):

vectorList.Head();
vectorList.Tail();

Finding bounds

Count()
The total number of items in the vector. (There is also a Size() method, but it is deprecated.)
IsValidIndex( int i )
Self-explanatory.
EnsureCapacity( int num )
Makes sure we have enough memory allocated to store a requested number of elements.
EnsureCount( int num )
Makes sure we have at least this many elements.

Adding elements

There are several methods for adding individual elements, multiple elements as well as other CUtlVectors:

Singly:

AddToHead( const T& src )
AddToTail( const T& src )
Adds the element to the start or end of the list.
InsertBefore( int elem, const T& src )
InsertAfter( int elem, const T& src )
Puts the element before or after a certain index.

In batches:

AddMultipleToTail( int num, const T *pToCopy )
Adds several elements to the end of the list.
InsertMultipleBefore( int elem, int num, const T *pToInsert )
Adds several elements before a valid index position except the head (which is always 0).
AddVectorToTail( CUtlVector const &src )
Adds another CUtlVector to the tail.

Searching elements

Tip.pngTip:If you want an automatically sorting list, have a look at CUtlSortVector.

To search for an element, your type must have implemented the == operator.

Find()
Searches the vector
Todo: For what?
HasElement(T&)
Check if the vector contains the given element.
FindAndRemove()
Self-explanatory

Removing elements

When you remove an element, its destructor is called and the vector is reordered.

Singly:

FindAndRemove()
See above.
Remove( int elem )
Calls the destructor of the element at the given position and shifts all elements left.
FastRemove( int elem )
Similar to Remove(), but just does a memcpy to accomodate for the removed element.

In batches:

RemoveMultiple( int elem, int num )
Removes num elements starting at position elem. Actual removal of elements is done in a right-to-left manner.
RemoveAll()
Clears the entire vector.

Copying

CopyArray( const T *pArray, int size )
Copies size elements of the given array into the vector, possibly overwriting elements. Always starts from index 0.
Swap( CUtlVector< T, A > &vec )
Simply swaps the vector with the given one.

Deallocating

Purge()
Calls RemoveAll() and purges the allocated memory.
PurgeAndDeleteElements()
First delete's all elements and then calls Purge().

Sorting

The class has a Sort method that takes a predicate, like so:

// Sort vector by predicate
vectorList.Sort( predicateFunction );

In this case, the predicate must be of the type int (__cdecl *)(const CBaseEntity *, const CBaseEntity *):

static int __cdecl predicateFunction( const CBaseEntity *a, const CBaseEntity *b )
{
	int valueA = a->entindex();
	int valueB = b->entindex();

	if( valueA < valueB )
		return -1;
	else if( valueA == valueB )
		return 0;
	else return 1;
 }

This function needs to be defined before the method it is called in.