• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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