Home | History | Annotate | Download | only in src
      1 // Copyright 2006-2009 the V8 project authors. All rights reserved.
      2 // Redistribution and use in source and binary forms, with or without
      3 // modification, are permitted provided that the following conditions are
      4 // met:
      5 //
      6 //     * Redistributions of source code must retain the above copyright
      7 //       notice, this list of conditions and the following disclaimer.
      8 //     * Redistributions in binary form must reproduce the above
      9 //       copyright notice, this list of conditions and the following
     10 //       disclaimer in the documentation and/or other materials provided
     11 //       with the distribution.
     12 //     * Neither the name of Google Inc. nor the names of its
     13 //       contributors may be used to endorse or promote products derived
     14 //       from this software without specific prior written permission.
     15 //
     16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27 
     28 #ifndef V8_LIST_INL_H_
     29 #define V8_LIST_INL_H_
     30 
     31 #include "list.h"
     32 
     33 namespace v8 {
     34 namespace internal {
     35 
     36 
     37 template<typename T, class P>
     38 void List<T, P>::Add(const T& element) {
     39   if (length_ < capacity_) {
     40     data_[length_++] = element;
     41   } else {
     42     List<T, P>::ResizeAdd(element);
     43   }
     44 }
     45 
     46 
     47 template<typename T, class P>
     48 void List<T, P>::AddAll(const List<T, P>& other) {
     49   int result_length = length_ + other.length_;
     50   if (capacity_ < result_length) Resize(result_length);
     51   for (int i = 0; i < other.length_; i++) {
     52     data_[length_ + i] = other.data_[i];
     53   }
     54   length_ = result_length;
     55 }
     56 
     57 
     58 // Use two layers of inlining so that the non-inlined function can
     59 // use the same implementation as the inlined version.
     60 template<typename T, class P>
     61 void List<T, P>::ResizeAdd(const T& element) {
     62   ResizeAddInternal(element);
     63 }
     64 
     65 
     66 template<typename T, class P>
     67 void List<T, P>::ResizeAddInternal(const T& element) {
     68   ASSERT(length_ >= capacity_);
     69   // Grow the list capacity by 50%, but make sure to let it grow
     70   // even when the capacity is zero (possible initial case).
     71   int new_capacity = 1 + capacity_ + (capacity_ >> 1);
     72   // Since the element reference could be an element of the list, copy
     73   // it out of the old backing storage before resizing.
     74   T temp = element;
     75   Resize(new_capacity);
     76   data_[length_++] = temp;
     77 }
     78 
     79 
     80 template<typename T, class P>
     81 void List<T, P>::Resize(int new_capacity) {
     82   T* new_data = List<T, P>::NewData(new_capacity);
     83   memcpy(new_data, data_, capacity_ * sizeof(T));
     84   List<T, P>::DeleteData(data_);
     85   data_ = new_data;
     86   capacity_ = new_capacity;
     87 }
     88 
     89 
     90 template<typename T, class P>
     91 Vector<T> List<T, P>::AddBlock(T value, int count) {
     92   int start = length_;
     93   for (int i = 0; i < count; i++) Add(value);
     94   return Vector<T>(&data_[start], count);
     95 }
     96 
     97 
     98 template<typename T, class P>
     99 T List<T, P>::Remove(int i) {
    100   T element = at(i);
    101   length_--;
    102   while (i < length_) {
    103     data_[i] = data_[i + 1];
    104     i++;
    105   }
    106   return element;
    107 }
    108 
    109 
    110 template<typename T, class P>
    111 void List<T, P>::Clear() {
    112   DeleteData(data_);
    113   Initialize(0);
    114 }
    115 
    116 
    117 template<typename T, class P>
    118 void List<T, P>::Rewind(int pos) {
    119   length_ = pos;
    120 }
    121 
    122 
    123 template<typename T, class P>
    124 void List<T, P>::Iterate(void (*callback)(T* x)) {
    125   for (int i = 0; i < length_; i++) callback(&data_[i]);
    126 }
    127 
    128 
    129 template<typename T, class P>
    130 bool List<T, P>::Contains(const T& elm) {
    131   for (int i = 0; i < length_; i++) {
    132     if (data_[i] == elm)
    133       return true;
    134   }
    135   return false;
    136 }
    137 
    138 
    139 template<typename T, class P>
    140 void List<T, P>::Sort(int (*cmp)(const T* x, const T* y)) {
    141   ToVector().Sort(cmp);
    142 #ifdef DEBUG
    143   for (int i = 1; i < length_; i++)
    144     ASSERT(cmp(&data_[i - 1], &data_[i]) <= 0);
    145 #endif
    146 }
    147 
    148 
    149 template<typename T, class P>
    150 void List<T, P>::Sort() {
    151   Sort(PointerValueCompare<T>);
    152 }
    153 
    154 
    155 template<typename T, class P>
    156 void List<T, P>::Initialize(int capacity) {
    157   ASSERT(capacity >= 0);
    158   data_ = (capacity > 0) ? NewData(capacity) : NULL;
    159   capacity_ = capacity;
    160   length_ = 0;
    161 }
    162 
    163 
    164 } }  // namespace v8::internal
    165 
    166 #endif  // V8_LIST_INL_H_
    167