You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
725 lines
21 KiB
725 lines
21 KiB
/****************************************************************************
|
|
**
|
|
** QValueVector class documentation
|
|
**
|
|
** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved.
|
|
**
|
|
** This file is part of the TQt GUI Toolkit.
|
|
**
|
|
** This file may be used under the terms of the GNU General
|
|
** Public License versions 2.0 or 3.0 as published by the Free
|
|
** Software Foundation and appearing in the files LICENSE.GPL2
|
|
** and LICENSE.GPL3 included in the packaging of this file.
|
|
** Alternatively you may (at your option) use any later version
|
|
** of the GNU General Public License if such license has been
|
|
** publicly approved by Trolltech ASA (or its successors, if any)
|
|
** and the KDE Free TQt Foundation.
|
|
**
|
|
** Please review the following information to ensure GNU General
|
|
** Public Licensing requirements will be met:
|
|
** http://trolltech.com/products/qt/licenses/licensing/opensource/.
|
|
** If you are unsure which license is appropriate for your use, please
|
|
** review the following information:
|
|
** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
|
|
** or contact the sales department at sales@trolltech.com.
|
|
**
|
|
** This file may be used under the terms of the Q Public License as
|
|
** defined by Trolltech ASA and appearing in the file LICENSE.QPL
|
|
** included in the packaging of this file. Licensees holding valid Qt
|
|
** Commercial licenses may use this file in accordance with the Qt
|
|
** Commercial License Agreement provided with the Software.
|
|
**
|
|
** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
|
|
** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
|
|
** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
|
|
** herein.
|
|
**
|
|
**********************************************************************/
|
|
|
|
|
|
/*****************************************************************************
|
|
QValueVector documentation
|
|
*****************************************************************************/
|
|
|
|
/*!
|
|
\class QValueVector ntqvaluevector.h
|
|
\brief The QValueVector class is a value-based template class that provides a dynamic array.
|
|
|
|
\ingroup qtl
|
|
\ingroup tools
|
|
\ingroup shared
|
|
\mainclass
|
|
\reentrant
|
|
|
|
QValueVector is a TQt implementation of an STL-like vector
|
|
container. It can be used in your application if the standard \c
|
|
vector is not available for your target platforms. QValueVector is
|
|
part of the \link ntqtl.html TQt Template Library\endlink.
|
|
|
|
QValueVector\<T\> defines a template instance to create a vector
|
|
of values that all have the class T. QValueVector does not store
|
|
pointers to the members of the vector; it holds a copy of every
|
|
member. QValueVector is said to be value based; in contrast,
|
|
QPtrList and QDict are pointer based.
|
|
|
|
QValueVector contains and manages a collection of objects of type
|
|
T and provides random access iterators that allow the contained
|
|
objects to be addressed. QValueVector owns the contained
|
|
elements. For more relaxed ownership semantics, see QPtrCollection
|
|
and friends, which are pointer-based containers.
|
|
|
|
QValueVector provides good performance if you append or remove
|
|
elements from the end of the vector. If you insert or remove
|
|
elements from anywhere but the end, performance is very bad. The
|
|
reason for this is that elements must to be copied into new
|
|
positions.
|
|
|
|
Some classes cannot be used within a QValueVector: for example,
|
|
all classes derived from QObject and thus all classes that
|
|
implement widgets. Only values can be used in a QValueVector. To
|
|
qualify as a value the class must provide:
|
|
\list
|
|
\i a copy constructor;
|
|
\i an assignment operator;
|
|
\i a default constructor, i.e., a constructor that does not take any arguments.
|
|
\endlist
|
|
|
|
Note that C++ defaults to field-by-field assignment operators and
|
|
copy constructors if no explicit version is supplied. In many
|
|
cases this is sufficient.
|
|
|
|
QValueVector uses an STL-like syntax to manipulate and address the
|
|
objects it contains. See \link ntqtl.html this document\endlink for
|
|
more information.
|
|
|
|
Example:
|
|
\code
|
|
#include <ntqvaluevector.h>
|
|
#include <ntqstring.h>
|
|
#include <stdio.h>
|
|
|
|
class Employee
|
|
{
|
|
public:
|
|
Employee(): s(0) {}
|
|
Employee( const QString& name, int salary )
|
|
: n( name ), s( salary )
|
|
{ }
|
|
|
|
QString name() const { return n; }
|
|
int salary() const { return s; }
|
|
void setSalary( int salary ) { s = salary; }
|
|
private:
|
|
QString n;
|
|
int s;
|
|
};
|
|
|
|
int main()
|
|
{
|
|
typedef QValueVector<Employee> EmployeeVector;
|
|
EmployeeVector vec( 3 ); // vector of 3 Employees
|
|
|
|
vec[0] = Employee( "Bill", 50000 );
|
|
vec[1] = Employee( "Steve", 80000 );
|
|
vec[2] = Employee( "Ron", 60000 );
|
|
|
|
Employee joe( "Joe", 50000 );
|
|
vec.push_back( joe ); // vector expands to accommodate 4 Employees
|
|
joe.setSalary( 70000 );
|
|
|
|
EmployeeVector::iterator it;
|
|
for( it = vec.begin(); it != vec.end(); ++it )
|
|
printf( "%s earns %d\n", (*it).name().latin1(), (*it).salary() );
|
|
|
|
return 0;
|
|
}
|
|
\endcode
|
|
|
|
Program output:
|
|
\code
|
|
Bill earns 50000
|
|
Steve earns 80000
|
|
Ron earns 60000
|
|
Joe earns 50000
|
|
\endcode
|
|
|
|
As you can see, the most recent change to Joe's salary did not
|
|
affect the value in the vector because the vector created a copy
|
|
of Joe's entry.
|
|
|
|
Many TQt functions return const value vectors; to iterate over
|
|
these you should make a copy and iterate over the copy.
|
|
|
|
There are several ways to find items in the vector. The begin()
|
|
and end() functions return iterators to the beginning and end of
|
|
the vector. The advantage of getting an iterator is that you can
|
|
move forward or backward from this position by
|
|
incrementing/decrementing the iterator. The iterator returned by
|
|
end() points to the element which is one past the last element in
|
|
the container. The past-the-end iterator is still associated with
|
|
the vector it belongs to, however it is \e not dereferenceable;
|
|
operator*() will not return a well-defined value. If the vector is
|
|
empty(), the iterator returned by begin() will equal the iterator
|
|
returned by end().
|
|
|
|
The fastest way to access an element of a vector is by using
|
|
operator[]. This function provides random access and will return
|
|
a reference to the element located at the specified index. Thus,
|
|
you can access every element directly, in constant time, providing
|
|
you know the location of the element. It is undefined to access
|
|
an element that does not exist (your application will probably
|
|
crash). For example:
|
|
|
|
\code
|
|
QValueVector<int> vec1; // an empty vector
|
|
vec1[10] = 4; // WARNING: undefined, probably a crash
|
|
|
|
QValueVector<QString> vec2(25); // initialize with 25 elements
|
|
vec2[10] = "Dave"; // OK
|
|
\endcode
|
|
|
|
Whenever inserting, removing or referencing elements in a vector,
|
|
always make sure you are referring to valid positions. For
|
|
example:
|
|
|
|
\code
|
|
void func( QValueVector<int>& vec )
|
|
{
|
|
if ( vec.size() > 10 ) {
|
|
vec[9] = 99; // OK
|
|
}
|
|
};
|
|
\endcode
|
|
|
|
The iterators provided by vector are random access iterators,
|
|
therefore you can use them with many generic algorithms, for
|
|
example, algorithms provided by the STL or the \link ntqtl.html
|
|
QTL\endlink.
|
|
|
|
Another way to find an element in the vector is by using the
|
|
std::find() or \link ntqtl.html#qFind tqFind()\endlink algorithms.
|
|
For example:
|
|
|
|
\code
|
|
QValueVector<int> vec;
|
|
...
|
|
QValueVector<int>::const_iterator it = tqFind( vec.begin(), vec.end(), 3 );
|
|
if ( it != vector.end() )
|
|
// 'it' points to the found element
|
|
\endcode
|
|
|
|
It is safe to have multiple iterators on the vector at the same
|
|
time. Since QValueVector manages memory dynamically, all iterators
|
|
can become invalid if a memory reallocation occurs. For example,
|
|
if some member of the vector is removed, iterators that point to
|
|
the removed element and to all following elements become
|
|
invalidated. Inserting into the middle of the vector will
|
|
invalidate all iterators. For convenience, the function back()
|
|
returns a reference to the last element in the vector, and front()
|
|
returns a reference to the first element. If the vector is
|
|
empty(), both back() and front() have undefined behavior (your
|
|
application will crash or do unpredictable things). Use back() and
|
|
front() with caution, for example:
|
|
|
|
\code
|
|
QValueVector<int> vec( 3 );
|
|
vec.push_back( 1 );
|
|
vec.push_back( 2 );
|
|
vec.push_back( 3 );
|
|
...
|
|
if ( !vec.empty() ) {
|
|
// OK: modify the first element
|
|
int& i = vec.front();
|
|
i = 18;
|
|
}
|
|
...
|
|
QValueVector<double> dvec;
|
|
double d = dvec.back(); // undefined behavior
|
|
\endcode
|
|
|
|
Because QValueVector manages memory dynamically, it is recommended
|
|
that you contruct a vector with an initial size. Inserting and
|
|
removing elements happens fastest when:
|
|
\list
|
|
\i Inserting or removing elements happens at the end() of the
|
|
vector;
|
|
\i The vector does not need to allocate additional memory.
|
|
\endlist
|
|
|
|
By creating a QValueVector with a sufficiently large initial size,
|
|
there will be less memory allocations. Do not use an initial size
|
|
that is too big, since it will still take time to construct all
|
|
the empty entries, and the extra space will be wasted if it is
|
|
never used.
|
|
|
|
Because QValueVector is value-based there is no need to be careful
|
|
about deleting elements in the vector. The vector holds its own
|
|
copies and will free them if the corresponding member or the
|
|
vector itself is deleted. You can force the vector to free all of
|
|
its items with clear().
|
|
|
|
QValueVector is shared implicitly, which means it can be copied in
|
|
constant time. If multiple QValueVector instances share the same
|
|
data and one needs to modify its contents, this modifying instance
|
|
makes a copy and modifies its private copy; it thus does not
|
|
affect the other instances. This is often called "copy on write".
|
|
If a QValueVector is being used in a multi-threaded program, you
|
|
must protect all access to the vector. See QMutex.
|
|
|
|
There are several ways to insert elements into the vector. The
|
|
push_back() function insert elements into the end of the vector,
|
|
and is usually fastest. The insert() function can be used to add
|
|
elements at specific positions within the vector.
|
|
|
|
Items can be also be removed from the vector in several ways.
|
|
There are several variants of the erase() function which removes a
|
|
specific element, or range of elements, from the vector.
|
|
|
|
Vectors can be also sorted with various STL algorithms , or it can
|
|
be sorted using the \link ntqtl.html TQt Template Library\endlink.
|
|
For example with qHeapSort():
|
|
|
|
Example:
|
|
\code
|
|
QValueVector<int> v( 4 );
|
|
v.push_back( 5 );
|
|
v.push_back( 8 );
|
|
v.push_back( 3 );
|
|
v.push_back( 4 );
|
|
qHeapSort( v );
|
|
\endcode
|
|
|
|
QValueVector stores its elements in contiguous memory. This means
|
|
that you can use a QValueVector in any situation that requires an
|
|
array.
|
|
*/
|
|
|
|
/*! \enum QValueVector::value_type
|
|
The type of the object stored in the vector. */
|
|
/*! \enum QValueVector::ValueType
|
|
The type of the object stored in the vector. */
|
|
/*! \enum QValueVector::pointer
|
|
The pointer to T type. */
|
|
/*! \enum QValueVector::const_pointer
|
|
The const pointer to T type. */
|
|
/*! \enum QValueVector::iterator
|
|
The vector's iterator type. */
|
|
/*! \enum QValueVector::const_iterator
|
|
The vector's const iterator type. */
|
|
/*! \enum QValueVector::Iterator
|
|
The vector's iterator type. */
|
|
/*! \enum QValueVector::ConstIterator
|
|
The vector's const iterator type. */
|
|
/*! \enum QValueVector::reference
|
|
The reference to T type. */
|
|
/*! \enum QValueVector::const_reference
|
|
The const reference to T type. */
|
|
/*! \enum QValueVector::size_type
|
|
An unsigned integral type, used to represent various sizes. */
|
|
/*! \enum QValueVector::difference_type
|
|
A signed integral type used to represent the distance between two iterators. */
|
|
|
|
|
|
/*!
|
|
\fn QValueVector::QValueVector()
|
|
|
|
Constructs an empty vector without any elements. To create a
|
|
vector which reserves an initial amount of space for elements, use
|
|
\c QValueVector(size_type n).
|
|
*/
|
|
|
|
/*!
|
|
\fn QValueVector::QValueVector( const QValueVector<T>& v )
|
|
|
|
Constructs a copy of \a v.
|
|
|
|
This operation costs O(1) time because QValueVector is implicitly
|
|
shared.
|
|
|
|
The first modification to the vector does takes O(n) time, because
|
|
the elements must be copied.
|
|
*/
|
|
|
|
/*!
|
|
\fn QValueVector::QValueVector( std::vector<T>& v )
|
|
|
|
Constructs a copy of \a v.
|
|
*/
|
|
|
|
/*!
|
|
\fn QValueVector::QValueVector( const std::vector<T>& v )
|
|
|
|
This operation costs O(n) time because \a v is copied.
|
|
*/
|
|
|
|
/*!
|
|
\fn QValueVector::QValueVector( size_type n, const T& val )
|
|
|
|
Constructs a vector with an initial size of \a n elements. Each
|
|
element is initialized with the value of \a val.
|
|
*/
|
|
|
|
/*!
|
|
\fn QValueVector::~QValueVector()
|
|
|
|
Destroys the vector, destroying all elements and freeing the
|
|
allocated memory. References to the values in the vector and all
|
|
iterators of this vector become invalidated. Note that it is
|
|
impossible for an iterator to check whether or not it is valid:
|
|
QValueVector is tuned for performance, not for error checking.
|
|
*/
|
|
|
|
/*!
|
|
\fn QValueVector<T>& QValueVector::operator=( const QValueVector<T>& v )
|
|
|
|
Assigns \a v to this vector and returns a reference to this vector.
|
|
|
|
All iterators of the current vector become invalidated by this
|
|
operation. The cost of such an assignment is O(1) since
|
|
QValueVector is implicitly shared.
|
|
*/
|
|
|
|
/*!
|
|
\fn QValueVector<T>& QValueVector::operator=( const std::vector<T>& v )
|
|
|
|
\overload
|
|
|
|
Assigns \a v to this vector and returns a reference to this vector.
|
|
|
|
All iterators of the current vector become invalidated by this
|
|
operation. The cost of this assignment is O(n) since \a v is
|
|
copied.
|
|
*/
|
|
|
|
/*!
|
|
\fn size_type QValueVector::size() const
|
|
|
|
Returns the number of elements in the vector.
|
|
|
|
This function is provided for STL compatibility. It is equivalent
|
|
to count().
|
|
|
|
\sa empty()
|
|
*/
|
|
|
|
/*!
|
|
\fn size_type QValueVector::count() const
|
|
|
|
Returns the number of items in the vector.
|
|
|
|
\sa isEmpty()
|
|
*/
|
|
|
|
/*!
|
|
\fn bool QValueVector::empty() const
|
|
|
|
Returns TRUE if the vector is empty; otherwise returns FALSE.
|
|
Equivalent to size()==0, only faster.
|
|
|
|
This function is provided for STL compatibility. It is equivalent
|
|
to isEmpty().
|
|
|
|
\sa size()
|
|
*/
|
|
|
|
/*!
|
|
\fn bool QValueVector::isEmpty() const
|
|
|
|
Returns TRUE if the vector is empty; returns FALSE otherwise.
|
|
|
|
\sa count()
|
|
*/
|
|
|
|
/*!
|
|
\fn size_type QValueVector::capacity() const
|
|
|
|
Returns the maximum number of elements that can be stored in the
|
|
vector without forcing memory reallocation. If memory reallocation
|
|
takes place, some or all iterators may become invalidated.
|
|
*/
|
|
|
|
/*!
|
|
\fn iterator QValueVector::begin()
|
|
|
|
Returns an iterator pointing to the beginning of the vector. If
|
|
the vector is empty(), the returned iterator will equal end().
|
|
*/
|
|
|
|
/*!
|
|
\fn const_iterator QValueVector::begin() const
|
|
|
|
\overload
|
|
|
|
Returns a const iterator pointing to the beginning of the vector.
|
|
If the vector is empty(), the returned iterator will equal end().
|
|
*/
|
|
|
|
/*!
|
|
\fn const_iterator QValueVector::constBegin() const
|
|
|
|
Returns a const iterator pointing to the beginning of the vector.
|
|
If the vector is empty(), the returned iterator will equal end().
|
|
|
|
\sa constEnd();
|
|
*/
|
|
|
|
/*!
|
|
\fn iterator QValueVector::end()
|
|
|
|
Returns an iterator pointing behind the last element of the
|
|
vector.
|
|
*/
|
|
|
|
/*!
|
|
\fn const_iterator QValueVector::end() const
|
|
|
|
\overload
|
|
|
|
Returns a const iterator pointing behind the last element of the
|
|
vector.
|
|
*/
|
|
|
|
/*!
|
|
\fn const_iterator QValueVector::constEnd() const
|
|
|
|
Returns a const iterator pointing behind the last element of the
|
|
vector.
|
|
|
|
\sa constBegin()
|
|
*/
|
|
|
|
/*!
|
|
\fn reference QValueVector::at( size_type i , bool* ok )
|
|
|
|
Returns a reference to the element with index \a i. If \a ok is
|
|
non-null, and the index \a i is out of range, *\a ok is set to
|
|
FALSE and the returned reference is undefined. If the index \a i
|
|
is within the range of the vector, and \a ok is non-null, *\a ok
|
|
is set to TRUE and the returned reference is well defined.
|
|
*/
|
|
|
|
/*!
|
|
\fn const_reference QValueVector::at( size_type i , bool* ok ) const
|
|
|
|
\overload
|
|
|
|
Returns a const reference to the element with index \a i. If \a ok
|
|
is non-null, and the index \a i is out of range, *\a ok is set to
|
|
FALSE and the returned reference is undefined. If the index \a i
|
|
is within the range of the vector, and \a ok is non-null, *\a ok
|
|
is set to TRUE and the returned reference is well defined.
|
|
*/
|
|
|
|
/*!
|
|
\fn reference QValueVector::operator[]( size_type i )
|
|
|
|
Returns a reference to the element at index \a i. If \a i is out
|
|
of range, this function has undefined behavior.
|
|
|
|
\sa at()
|
|
*/
|
|
|
|
/*!
|
|
\fn const_reference QValueVector::operator[]( size_type i ) const
|
|
|
|
\overload
|
|
|
|
Returns a const reference to the element at index \a i. If \a i is
|
|
out of range, this function has undefined behavior.
|
|
|
|
\sa at()
|
|
*/
|
|
|
|
/*!
|
|
\fn reference QValueVector::front()
|
|
|
|
Returns a reference to the first element in the vector. If there
|
|
is no first element, this function has undefined behavior.
|
|
|
|
\sa empty() back()
|
|
*/
|
|
|
|
/*!
|
|
\fn const_reference QValueVector::front() const
|
|
|
|
\overload
|
|
|
|
Returns a const reference to the first element in the vector. If
|
|
there is no first element, this function has undefined behavior.
|
|
|
|
\sa empty() back()
|
|
*/
|
|
|
|
/*!
|
|
\fn reference QValueVector::first()
|
|
|
|
Returns a reference to the first item in the vector. If there is
|
|
no first item, this function has undefined behavior.
|
|
|
|
\sa empty() last()
|
|
*/
|
|
|
|
/*!
|
|
\fn const_reference QValueVector::first() const
|
|
|
|
\overload
|
|
*/
|
|
|
|
/*!
|
|
\fn reference QValueVector::back()
|
|
|
|
Returns a reference to the last element in the vector. If there is
|
|
no last element, this function has undefined behavior.
|
|
|
|
\sa empty() front()
|
|
*/
|
|
|
|
/*!
|
|
\fn const_reference QValueVector::back() const
|
|
|
|
\overload
|
|
|
|
Returns a const reference to the last element in the vector. If
|
|
there is no last element, this function has undefined behavior.
|
|
|
|
\sa empty() front()
|
|
*/
|
|
|
|
/*!
|
|
\fn reference QValueVector::last()
|
|
|
|
Returns a reference to the last item in the vector. If there is no
|
|
last item, this function has undefined behavior.
|
|
|
|
\sa empty() first()
|
|
*/
|
|
|
|
/*!
|
|
\fn const_reference QValueVector::last() const
|
|
|
|
\overload
|
|
*/
|
|
|
|
/*!
|
|
\fn void QValueVector::push_back( const T& x )
|
|
|
|
Appends a copy of \a x to the end of the vector. This is the
|
|
fastest way to add new elements.
|
|
|
|
This function is provided for STL compatibility. It is equivalent
|
|
to append().
|
|
|
|
\sa insert()
|
|
*/
|
|
|
|
/*!
|
|
\fn void QValueVector::append( const T& x )
|
|
|
|
Appends a copy of \a x to the end of the vector.
|
|
|
|
\sa push_back() insert()
|
|
*/
|
|
|
|
/*!
|
|
\fn void QValueVector::pop_back()
|
|
|
|
Removes the last item from the vector.
|
|
|
|
This function is provided for STL compatibility.
|
|
*/
|
|
|
|
/*!
|
|
\fn iterator QValueVector::insert( iterator pos, const T& x )
|
|
|
|
Inserts a copy of \a x at the position immediately before \a pos.
|
|
|
|
\sa push_back()
|
|
*/
|
|
|
|
/*! \fn void QValueVector::detachInternal()
|
|
|
|
\internal
|
|
*/
|
|
|
|
/*!
|
|
\fn iterator QValueVector::insert( iterator pos, size_type n, const T& x )
|
|
|
|
\overload
|
|
|
|
Inserts \a n copies of \a x immediately before position x.
|
|
|
|
\sa push_back()
|
|
*/
|
|
|
|
/*!
|
|
\fn void QValueVector::reserve( size_type n )
|
|
|
|
Increases the vector's capacity. If \a n is less than or equal to
|
|
capacity(), nothing happens. Otherwise, additional memory is
|
|
allocated so that capacity() will be increased to a value greater
|
|
than or equal to \a n. All iterators will then become invalidated.
|
|
Note that the vector's size() and the values of existing elements
|
|
remain unchanged.
|
|
*/
|
|
|
|
/*!
|
|
\fn void QValueVector::resize( size_type n, const T& val = T() )
|
|
|
|
Changes the size of the vector to \a n. If \a n is greater than
|
|
the current size(), elements are added to the end and initialized
|
|
with the value of \a val. If \a n is less than size(), elements
|
|
are removed from the end. If \a n is equal to size() nothing
|
|
happens.
|
|
*/
|
|
|
|
/*!
|
|
\fn void QValueVector::clear()
|
|
|
|
Removes all the elements from the vector.
|
|
*/
|
|
|
|
/*!
|
|
\fn iterator QValueVector::erase( iterator pos )
|
|
|
|
Removes the element at position \a pos and returns the position of
|
|
the next element.
|
|
*/
|
|
|
|
/*!
|
|
\fn iterator QValueVector::erase( iterator first, iterator last )
|
|
|
|
\overload
|
|
|
|
Removes all elements from \a first up to but not including \a last
|
|
and returns the position of the next element.
|
|
*/
|
|
|
|
/*!
|
|
\fn bool QValueVector::operator==( const QValueVector<T>& x ) const
|
|
|
|
Returns TRUE if each element in this vector equals each
|
|
corresponding element in \a x; otherwise returns FALSE.
|
|
*/
|
|
|
|
/*!
|
|
\fn bool QValueVector::operator==( const QValueVector<T>& x )
|
|
|
|
\overload
|
|
|
|
Returns TRUE if each element in this vector equals each
|
|
corresponding element in \a x; otherwise returns FALSE.
|
|
*/
|
|
|
|
|
|
/*!
|
|
\fn void QValueVector::detach()
|
|
|
|
\internal
|
|
|
|
If the vector does not share its data with another QValueVector
|
|
instance, nothing happens. Otherwise the function creates a new
|
|
copy of this data and detaches from the shared one. This function
|
|
is called whenever the vector is modified. The implicit sharing
|
|
mechanism is implemented this way.
|
|
*/
|