1.. _concurrent_vector_ug:
2
3concurrent_vector
4=================
5
6
7``A concurrent_vector<T>`` is a dynamically growable array of ``T``. It
8is safe to grow a ``concurrent_vector`` while other threads are also
9operating on elements of it, or even growing it themselves. For safe
10concurrent growing, ``concurrent_vector`` has three methods that support
11common uses of dynamic arrays: ``push_back``, ``grow_by``, and
12``grow_to_at_least``.
13
14
15Method ``push_back(x)`` safely appends x to the array. Method
16``grow_by(n)`` safely appends ``n`` consecutive elements initialized
17with ``T()``. Both methods return an iterator pointing to the first
18appended element. Each element is initialized with ``T()``. So for
19example, the following routine safely appends a C string to a shared
20vector:
21
22
23::
24
25
26   void Append( concurrent_vector<char>& vector, const char* string ) {
27       size_t n = strlen(string)+1;
28       std::copy( string, string+n, vector.grow_by(n) );
29   }
30
31
32The related method ``grow_to_at_least(n)``\ grows a vector to size ``n``
33if it is shorter. Concurrent calls to the growth methods do not
34necessarily return in the order that elements are appended to the
35vector.
36
37
38Method ``size()`` returns the number of elements in the vector, which
39may include elements that are still undergoing concurrent construction
40by methods ``push_back``, ``grow_by,`` or ``grow_to_at_least``. The
41example uses std::copy and iterators, not ``strcpy and pointers``,
42because elements in a ``concurrent_vector`` might not be at consecutive
43addresses. It is safe to use the iterators while the
44``concurrent_vector`` is being grown, as long as the iterators never go
45past the current value of ``end()``. However, the iterator may reference
46an element undergoing concurrent construction. You must synchronize
47construction and access.
48
49
50A ``concurrent_vector<T>`` never moves an element until the array is
51cleared, which can be an advantage over the STL std::vector even for
52single-threaded code. However, ``concurrent_vector`` does have more
53overhead than std::vector. Use ``concurrent_vector`` only if you really
54need the ability to dynamically resize it while other accesses are (or
55might be) in flight, or require that an element never move.
56
57
58.. CAUTION::
59   Operations on ``concurrent_vector`` are concurrency safe with respect
60   to *growing*, not for clearing or destroying a vector. Never invoke
61   method ``clear()`` if there are other operations in flight on the
62   ``concurrent_vector``.
63