Home | History | Annotate | Download | only in wtf
      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 
      9 namespace WTF {
     10 
     11 template<typename T, template <typename> class ArrayType = TerminatedArray>
     12 class TerminatedArrayBuilder {
     13     DISALLOW_ALLOCATION();
     14     WTF_MAKE_NONCOPYABLE(TerminatedArrayBuilder);
     15 public:
     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 
     57 private:
     58 #ifndef NDEBUG
     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 
     77 using WTF::TerminatedArrayBuilder;
     78 
     79 #endif // TerminatedArrayBuilder_h
     80