# concurrent_vector

`A concurrent_vector<T>` is a dynamically growable array of `T`. It is safe to grow a `concurrent_vector` while other threads are also operating on elements of it, or even growing it themselves. For safe concurrent growing, `concurrent_vector` has three methods that support common uses of dynamic arrays: `push_back`, `grow_by`, and `grow_to_at_least`.

Method `push_back(x)` safely appends x to the array. Method `grow_by(n)` safely appends `n` consecutive elements initialized with `T()`. Both methods return an iterator pointing to the first appended element. Each element is initialized with `T()`. So for example, the following routine safely appends a C string to a shared vector:

    void Append( concurrent_vector<char>& vector, const char* string ) {
        size_t n = strlen(string)+1;
        std::copy( string, string+n, vector.grow_by(n) );
    }

The related method `grow_to_at_least(n)`grows a vector to size `n` if it is shorter. Concurrent calls to the growth methods do not necessarily return in the order that elements are appended to the vector.

Method `size()` returns the number of elements in the vector, which may include elements that are still undergoing concurrent construction by methods `push_back`, `grow_by,` or `grow_to_at_least`. The example uses std::copy and iterators, not `strcpy and pointers`, because elements in a `concurrent_vector` might not be at consecutive addresses. It is safe to use the iterators while the `concurrent_vector` is being grown, as long as the iterators never go past the current value of `end()`. However, the iterator may reference an element undergoing concurrent construction. You must synchronize construction and access.

A `concurrent_vector<T>` never moves an element until the array is cleared, which can be an advantage over the STL std::vector even for single-threaded code. However, `concurrent_vector` does have more overhead than std::vector. Use `concurrent_vector` only if you really need the ability to dynamically resize it while other accesses are (or might be) in flight, or require that an element never move.

Caution

Operations on `concurrent_vector` are concurrency safe with respect to growing, not for clearing or destroying a vector. Never invoke method `clear()` if there are other operations in flight on the `concurrent_vector`.