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