1 /* 2 * Copyright (C) 2009 Google Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above 11 * copyright notice, this list of conditions and the following disclaimer 12 * in the documentation and/or other materials provided with the 13 * distribution. 14 * * Neither the name of Google Inc. nor the names of its 15 * contributors may be used to endorse or promote products derived from 16 * this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 #ifndef WebVector_h 32 #define WebVector_h 33 34 #include "WebCommon.h" 35 36 #include <algorithm> 37 #include <limits> 38 #include <stdlib.h> 39 40 namespace blink { 41 42 // A simple vector class. 43 // 44 // Sample usage: 45 // 46 // void Foo(WebVector<int>& result) 47 // { 48 // WebVector<int> data(10); 49 // for (size_t i = 0; i < data.size(); ++i) 50 // data[i] = ... 51 // result.swap(data); 52 // } 53 // 54 // It is also possible to assign from other types of random access 55 // containers: 56 // 57 // void Foo(const std::vector<std::string>& input) 58 // { 59 // WebVector<WebCString> cstrings = input; 60 // ... 61 // } 62 // 63 template <typename T> 64 class WebVector { 65 public: 66 typedef T ValueType; 67 ~WebVector()68 ~WebVector() 69 { 70 destroy(); 71 } 72 73 explicit WebVector(size_t size = 0) 74 { 75 initialize(size); 76 } 77 78 template <typename U> WebVector(const U * values,size_t size)79 WebVector(const U* values, size_t size) 80 { 81 initializeFrom(values, size); 82 } 83 WebVector(const WebVector<T> & other)84 WebVector(const WebVector<T>& other) 85 { 86 initializeFrom(other.m_ptr, other.m_size); 87 } 88 89 template <typename C> WebVector(const C & other)90 WebVector(const C& other) 91 { 92 initializeFrom(other.size() ? &other[0] : 0, other.size()); 93 } 94 95 WebVector& operator=(const WebVector& other) 96 { 97 if (this != &other) 98 assign(other); 99 return *this; 100 } 101 102 template <typename C> 103 WebVector<T>& operator=(const C& other) 104 { 105 if (this != reinterpret_cast<const WebVector<T>*>(&other)) 106 assign(other); 107 return *this; 108 } 109 110 template <typename C> assign(const C & other)111 void assign(const C& other) 112 { 113 assign(other.size() ? &other[0] : 0, other.size()); 114 } 115 116 template <typename U> assign(const U * values,size_t size)117 void assign(const U* values, size_t size) 118 { 119 destroy(); 120 initializeFrom(values, size); 121 } 122 size()123 size_t size() const { return m_size; } isEmpty()124 bool isEmpty() const { return !m_size; } 125 126 T& operator[](size_t i) 127 { 128 BLINK_ASSERT(i < m_size); 129 return m_ptr[i]; 130 } 131 const T& operator[](size_t i) const 132 { 133 BLINK_ASSERT(i < m_size); 134 return m_ptr[i]; 135 } 136 contains(const T & value)137 bool contains(const T& value) const 138 { 139 for (size_t i = 0; i < m_size; i++) { 140 if (m_ptr[i] == value) 141 return true; 142 } 143 return false; 144 } 145 data()146 T* data() { return m_ptr; } data()147 const T* data() const { return m_ptr; } 148 swap(WebVector<T> & other)149 void swap(WebVector<T>& other) 150 { 151 std::swap(m_ptr, other.m_ptr); 152 std::swap(m_size, other.m_size); 153 } 154 155 private: initialize(size_t size)156 void initialize(size_t size) 157 { 158 validateSize(size); 159 m_size = size; 160 if (!m_size) 161 m_ptr = 0; 162 else { 163 m_ptr = static_cast<T*>(::operator new(sizeof(T) * m_size)); 164 for (size_t i = 0; i < m_size; ++i) 165 new (&m_ptr[i]) T(); 166 } 167 } 168 169 template <typename U> initializeFrom(const U * values,size_t size)170 void initializeFrom(const U* values, size_t size) 171 { 172 validateSize(size); 173 m_size = size; 174 if (!m_size) 175 m_ptr = 0; 176 else { 177 m_ptr = static_cast<T*>(::operator new(sizeof(T) * m_size)); 178 for (size_t i = 0; i < m_size; ++i) 179 new (&m_ptr[i]) T(values[i]); 180 } 181 } 182 validateSize(size_t size)183 void validateSize(size_t size) 184 { 185 if (std::numeric_limits<size_t>::max() / sizeof(T) < size) 186 abort(); 187 } 188 destroy()189 void destroy() 190 { 191 for (size_t i = 0; i < m_size; ++i) 192 m_ptr[i].~T(); 193 ::operator delete(m_ptr); 194 } 195 196 T* m_ptr; 197 size_t m_size; 198 }; 199 200 } // namespace blink 201 202 #endif 203