Merge "Fix build break by removing TIZEN_RECORDING_SURFACE_SET" into tizen_2.1
[framework/web/webkit-efl.git] / Source / WTF / wtf / BoundsCheckedPointer.h
1 /*
2  * Copyright (C) 2011 Apple 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
6  * are met:
7  *
8  * 1.  Redistributions of source code must retain the above copyright
9  *     notice, this list of conditions and the following disclaimer. 
10  * 2.  Redistributions in binary form must reproduce the above copyright
11  *     notice, this list of conditions and the following disclaimer in the
12  *     documentation and/or other materials provided with the distribution. 
13  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
14  *     its contributors may be used to endorse or promote products derived
15  *     from this software without specific prior written permission. 
16  *
17  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28
29 #ifndef WTF_BoundsCheckedPointer_h
30 #define WTF_BoundsCheckedPointer_h
31
32 #include <wtf/Assertions.h>
33 #include <wtf/UnusedParam.h>
34
35 namespace WTF {
36
37 // Useful for when you'd like to do pointer arithmetic on a buffer, but
38 // you'd also like to get some ASSERT()'s that prevent you from overflowing.
39 // This should be performance-neutral in release builds, while providing
40 // you with strong assertions in debug builds. Note that all of the
41 // asserting happens when you actually access the pointer. You are allowed
42 // to overflow or underflow with arithmetic so long as no accesses are
43 // performed.
44
45 template<typename T>
46 class BoundsCheckedPointer {
47 public:
48     BoundsCheckedPointer()
49         : m_pointer(0)
50 #if !ASSERT_DISABLED
51         , m_begin(0)
52         , m_end(0)
53 #endif
54     {
55     }
56
57     BoundsCheckedPointer(T* pointer, size_t numElements)
58         : m_pointer(pointer)
59 #if !ASSERT_DISABLED
60         , m_begin(pointer)
61         , m_end(pointer + numElements)
62 #endif
63     {
64         UNUSED_PARAM(numElements);
65     }
66     
67     BoundsCheckedPointer(T* pointer, T* end)
68         : m_pointer(pointer)
69 #if !ASSERT_DISABLED
70         , m_begin(pointer)
71         , m_end(end)
72 #endif
73     {
74         UNUSED_PARAM(end);
75     }
76
77     BoundsCheckedPointer(T* pointer, T* begin, size_t numElements)
78         : m_pointer(pointer)
79 #if !ASSERT_DISABLED
80         , m_begin(begin)
81         , m_end(begin + numElements)
82 #endif
83     {
84         UNUSED_PARAM(begin);
85         UNUSED_PARAM(numElements);
86     }
87     
88     BoundsCheckedPointer(T* pointer, T* begin, T* end)
89         : m_pointer(pointer)
90 #if !ASSERT_DISABLED
91         , m_begin(begin)
92         , m_end(end)
93 #endif
94     {
95         UNUSED_PARAM(begin);
96         UNUSED_PARAM(end);
97     }
98     
99     BoundsCheckedPointer& operator=(T* value)
100     {
101         m_pointer = value;
102         return *this;
103     }
104     
105     BoundsCheckedPointer& operator+=(ptrdiff_t amount)
106     {
107         m_pointer += amount;
108         return *this;
109     }
110
111     BoundsCheckedPointer& operator-=(ptrdiff_t amount)
112     {
113         m_pointer -= amount;
114         return *this;
115     }
116     
117     BoundsCheckedPointer operator+(ptrdiff_t amount) const
118     {
119         BoundsCheckedPointer result = *this;
120         result.m_pointer += amount;
121         return result;
122     }
123
124     BoundsCheckedPointer operator-(ptrdiff_t amount) const
125     {
126         BoundsCheckedPointer result = *this;
127         result.m_pointer -= amount;
128         return result;
129     }
130     
131     BoundsCheckedPointer operator++() // prefix
132     {
133         m_pointer++;
134         return *this;
135     }
136
137     BoundsCheckedPointer operator--() // prefix
138     {
139         m_pointer--;
140         return *this;
141     }
142
143     BoundsCheckedPointer operator++(int) // postfix
144     {
145         BoundsCheckedPointer result = *this;
146         m_pointer++;
147         return result;
148     }
149
150     BoundsCheckedPointer operator--(int) // postfix
151     {
152         BoundsCheckedPointer result = *this;
153         m_pointer--;
154         return result;
155     }
156     
157     bool operator<(T* other) const
158     {
159         return m_pointer < other;
160     }
161
162     bool operator<=(T* other) const
163     {
164         return m_pointer <= other;
165     }
166
167     bool operator>(T* other) const
168     {
169         return m_pointer > other;
170     }
171
172     bool operator>=(T* other) const
173     {
174         return m_pointer >= other;
175     }
176
177     bool operator==(T* other) const
178     {
179         return m_pointer == other;
180     }
181
182     bool operator!=(T* other) const
183     {
184         return m_pointer != other;
185     }
186
187     bool operator<(BoundsCheckedPointer other) const
188     {
189         return m_pointer < other.m_pointer;
190     }
191
192     bool operator<=(BoundsCheckedPointer other) const
193     {
194         return m_pointer <= other.m_pointer;
195     }
196
197     bool operator>(BoundsCheckedPointer other) const
198     {
199         return m_pointer > other.m_pointer;
200     }
201
202     bool operator>=(BoundsCheckedPointer other) const
203     {
204         return m_pointer >= other.m_pointer;
205     }
206
207     bool operator==(BoundsCheckedPointer other) const
208     {
209         return m_pointer == other.m_pointer;
210     }
211
212     bool operator!=(BoundsCheckedPointer other) const
213     {
214         return m_pointer != other.m_pointer;
215     }
216
217     BoundsCheckedPointer operator!()
218     {
219         return !m_pointer;
220     }
221     
222     T* get()
223     {
224         return m_pointer;
225     }
226     
227     T& operator*()
228     {
229         validate();
230         return *m_pointer;
231     }
232
233     const T& operator*() const
234     {
235         validate();
236         return *m_pointer;
237     }
238
239     T& operator[](ptrdiff_t index)
240     {
241         validate(m_pointer + index);
242         return m_pointer[index];
243     }
244
245     const T& operator[](ptrdiff_t index) const
246     {
247         validate(m_pointer + index);
248         return m_pointer[index];
249     }
250     
251     // The only thing this has in common with strcat() is that it
252     // keeps appending from the given pointer until reaching 0.
253     BoundsCheckedPointer& strcat(const T* source)
254     {
255         while (*source)
256             *(*this)++ = *source++;
257         return *this;
258     }
259
260 private:
261     void validate(T* pointer) const
262     {
263         ASSERT_UNUSED(pointer, pointer >= m_begin);
264         
265         // This guard is designed to protect against the misaligned case.
266         // A simple pointer < m_end would miss the case if, for example,
267         // T = int16_t and pointer is 1 byte less than m_end.
268         ASSERT_UNUSED(pointer, pointer + 1 <= m_end);
269     }
270     
271     void validate() const
272     {
273         validate(m_pointer);
274     }
275     
276     T* m_pointer;
277 #if !ASSERT_DISABLED
278     T* m_begin;
279     T* m_end;
280 #endif
281 };
282
283 } // namespace WTF
284
285 using WTF::BoundsCheckedPointer;
286
287 #endif // WTF_BoundsCheckedPointer_h