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 TerminatedArray_h
5d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#define TerminatedArray_h
6d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
7d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#include "wtf/FastAllocBase.h"
8d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#include "wtf/OwnPtr.h"
9d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
10d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)namespace WTF {
11d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
12d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)// TerminatedArray<T> represents a sequence of elements of type T in which each
13d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)// element knows whether it is the last element in the sequence or not. For this
14d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)// check type T must provide isLastInArray method.
15d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)// TerminatedArray<T> can only be constructed by TerminatedArrayBuilder<T>.
16d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)template<typename T>
17d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)class TerminatedArray {
18d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    WTF_MAKE_NONCOPYABLE(TerminatedArray);
19d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)public:
20d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    T& at(size_t index) { return reinterpret_cast<T*>(this)[index]; }
21d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    const T& at(size_t index) const { return reinterpret_cast<const T*>(this)[index]; }
22d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
23d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    template<typename U>
24d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    class iterator_base {
25d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    public:
26d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        iterator_base& operator++()
27d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        {
28d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            if (m_val->isLastInArray()) {
29d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                m_val = 0;
30d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            } else {
31d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                ++m_val;
32d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            }
33d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            return *this;
34d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        }
35d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
36d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        U& operator*() const { return *m_val; }
37d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
38d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        bool operator==(const iterator_base& other) const { return m_val == other.m_val; }
39d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        bool operator!=(const iterator_base& other) const { return !(*this == other); }
40d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
41d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    private:
42d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        iterator_base(U* val) : m_val(val) { }
43d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
44d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        U* m_val;
45d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
46d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        friend class TerminatedArray;
47d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    };
48d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
49d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    typedef iterator_base<T> iterator;
50d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    typedef iterator_base<const T> const_iterator;
51d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
52d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    iterator begin() { return iterator(reinterpret_cast<T*>(this)); }
53d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    const_iterator begin() const { return const_iterator(reinterpret_cast<const T*>(this)); }
54d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
55d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    iterator end() { return iterator(0); }
56d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    const_iterator end() const { return const_iterator(0); }
57d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
58d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    size_t size() const
59d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    {
60d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        size_t count = 0;
61d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        for (const_iterator it = begin(); it != end(); ++it)
62d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            count++;
63d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return count;
64d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    }
65d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
66d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    // Match Allocator semantics to be able to use OwnPtr<TerminatedArray>.
67d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    void operator delete(void* p) { ::WTF::fastFree(p); }
68d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
69d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)private:
70d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    // Allocator describes how TerminatedArrayBuilder should create new instances
71d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    // of TerminateArray and manage their lifetimes.
72d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    struct Allocator {
73d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        typedef PassOwnPtr<TerminatedArray> PassPtr;
74d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        typedef OwnPtr<TerminatedArray> Ptr;
75d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
76d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        static PassPtr create(size_t capacity)
77d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        {
78d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            return adoptPtr(static_cast<TerminatedArray*>(fastMalloc(capacity * sizeof(T))));
79d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        }
80d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
81d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        static PassPtr resize(PassPtr ptr, size_t capacity)
82d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        {
83d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            return adoptPtr(static_cast<TerminatedArray*>(fastRealloc(ptr.leakPtr(), capacity * sizeof(T))));
84d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        }
85d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    };
86d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
87d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    // Prohibit construction. Allocator makes TerminatedArray instances for
88d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    // TerminatedArrayBuilder by pointer casting.
89d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    TerminatedArray();
90d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
91d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    template<typename, template <typename> class> friend class TerminatedArrayBuilder;
92d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)};
93d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
94d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)} // namespace WTF
95d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
96d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)using WTF::TerminatedArray;
97d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
98d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#endif // TerminatedArray_h
99