1// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4#ifndef TerminatedArrayBuilder_h
5#define TerminatedArrayBuilder_h
6
7#include "wtf/OwnPtr.h"
8
9namespace WTF {
10
11template<typename T, template <typename> class ArrayType = TerminatedArray>
12class TerminatedArrayBuilder {
13    DISALLOW_ALLOCATION();
14    WTF_MAKE_NONCOPYABLE(TerminatedArrayBuilder);
15public:
16    explicit TerminatedArrayBuilder(typename ArrayType<T>::Allocator::PassPtr array)
17        : m_array(array)
18        , m_count(0)
19        , m_capacity(0)
20    {
21        if (!m_array)
22            return;
23        m_capacity = m_count = m_array->size();
24    }
25
26    void grow(size_t count)
27    {
28        ASSERT(count);
29        if (!m_array) {
30            ASSERT(!m_count);
31            ASSERT(!m_capacity);
32            m_capacity = count;
33            m_array = ArrayType<T>::Allocator::create(m_capacity);
34            return;
35        }
36        m_capacity += count;
37        m_array = ArrayType<T>::Allocator::resize(m_array.release(), m_capacity);
38        m_array->at(m_count - 1).setLastInArray(false);
39    }
40
41    void append(const T& item)
42    {
43        RELEASE_ASSERT(m_count < m_capacity);
44        ASSERT(!item.isLastInArray());
45        m_array->at(m_count++) = item;
46    }
47
48    typename ArrayType<T>::Allocator::PassPtr release()
49    {
50        RELEASE_ASSERT(m_count == m_capacity);
51        if (m_array)
52            m_array->at(m_count - 1).setLastInArray(true);
53        assertValid();
54        return m_array.release();
55    }
56
57private:
58#if ENABLE(ASSERT)
59    void assertValid()
60    {
61        for (size_t i = 0; i < m_count; ++i) {
62            bool isLastInArray = (i + 1 == m_count);
63            ASSERT(m_array->at(i).isLastInArray() == isLastInArray);
64        }
65    }
66#else
67    void assertValid() { }
68#endif
69
70    typename ArrayType<T>::Allocator::Ptr m_array;
71    size_t m_count;
72    size_t m_capacity;
73};
74
75} // namespace WTF
76
77using WTF::TerminatedArrayBuilder;
78
79#endif // TerminatedArrayBuilder_h
80