VirtualBox

source: vbox/trunk/src/libs/xpcom18a4/xpcom/ds/nsDeque.cpp@ 102005

最後變更 在這個檔案從102005是 101927,由 vboxsync 提交於 14 月 前

libs/xpcom: Remove unused code in nsDeque.{cpp,h}, bugref:10545

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Author Date Id Revision
檔案大小: 8.8 KB
 
1/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2/* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 *
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
9 *
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
13 * License.
14 *
15 * The Original Code is mozilla.org code.
16 *
17 * The Initial Developer of the Original Code is
18 * Netscape Communications Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 1998
20 * the Initial Developer. All Rights Reserved.
21 *
22 * Contributor(s):
23 *
24 * Alternatively, the contents of this file may be used under the terms of
25 * either of the GNU General Public License Version 2 or later (the "GPL"),
26 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
35 *
36 * ***** END LICENSE BLOCK ***** */
37
38#include "nsDeque.h"
39#include "nsCRT.h"
40#ifdef DEBUG_rickg
41#include <stdio.h>
42#endif
43
44/**
45 * 07/02/2001 09:17p 509,104 clangref.pdf from openwatcom's site
46 * Watcom C Language Reference Edition 11.0c
47 * page 118 of 297
48 *
49 * The % symbol yields the remainder from the division of the first operand
50 * by the second operand. The operands of % must have integral type.
51 *
52 * When both operands of % are positive, the result is a positive value
53 * smaller than the second operand. When one or both operands is negative,
54 * whether the result is positive or negative is implementation-defined.
55 *
56 */
57/* Ok, so first of all, C is underspecified. joy.
58 * The following functions do not provide a correct implementation of modulus
59 * They provide functionality for x>-y.
60 * There are risks of 2*y being greater than max int, which is part of the
61 * reason no multiplication is used and other operations are avoided.
62 *
63 * modasgn
64 * @param x variable
65 * @param y expression
66 * approximately equivalent to x %= y
67 *
68 * modulus
69 * @param x expression
70 * @param y expression
71 * approximately equivalent to x % y
72 */
73#define modasgn(x,y) if (x<0) x+=y; x%=y
74#define modulus(x,y) ((x<0)?(x+y)%(y):(x)%(y))
75
76MOZ_DECL_CTOR_COUNTER(nsDeque)
77
78/**
79 * Standard constructor
80 */
81nsDeque::nsDeque() {
82 MOZ_COUNT_CTOR(nsDeque);
83 mOrigin=mSize=0;
84 mData=mBuffer; // don't allocate space until you must
85 mCapacity=sizeof(mBuffer)/sizeof(mBuffer[0]);
86 memset(mData, 0, mCapacity*sizeof(mBuffer[0]));
87}
88
89/**
90 * Destructor
91 */
92nsDeque::~nsDeque() {
93 MOZ_COUNT_DTOR(nsDeque);
94
95 Erase();
96 if (mData && (mData!=mBuffer)) {
97 delete [] mData;
98 }
99 mData=0;
100}
101
102/**
103 * Remove all items from container without destroying them.
104 *
105 * @return *this
106 */
107nsDeque& nsDeque::Empty() {
108 if (mSize && mData) {
109 memset(mData, 0, mCapacity*sizeof(*mData));
110 }
111 mSize=0;
112 mOrigin=0;
113 return *this;
114}
115
116/**
117 * Remove and delete all items from container
118 *
119 * @return *this
120 */
121nsDeque& nsDeque::Erase() {
122 return Empty();
123}
124
125/**
126 * This method quadruples the size of the deque
127 * Elements in the deque are resequenced so that elements
128 * in the deque are stored sequentially
129 *
130 * If the deque actually overflows, there's very little we can do.
131 * Perhaps this function should return PRBool/nsresult indicating success/failure.
132 *
133 * @return capacity of the deque
134 * If the deque did not grow,
135 * and you knew its capacity beforehand,
136 * then this would be a way to indicate the failure.
137 */
138PRInt32 nsDeque::GrowCapacity() {
139 PRInt32 theNewSize=mCapacity<<2;
140 NS_ASSERTION(theNewSize>mCapacity, "Overflow");
141 if (theNewSize<=mCapacity)
142 return mCapacity;
143 void** temp=new void*[theNewSize];
144
145 //Here's the interesting part: You can't just move the elements
146 //directly (in situ) from the old buffer to the new one.
147 //Since capacity has changed, the old origin doesn't make
148 //sense anymore. It's better to resequence the elements now.
149
150 if (temp) {
151 PRInt32 tempi=0;
152 PRInt32 i=0;
153 PRInt32 j=0;
154 for (i=mOrigin; i<mCapacity; i++) {
155 temp[tempi++]=mData[i]; //copy the leading elements...
156 }
157 for (j=0;j<mOrigin;j++) {
158 temp[tempi++]=mData[j]; //copy the trailing elements...
159 }
160 if (mData != mBuffer) {
161 delete [] mData;
162 }
163 mCapacity=theNewSize;
164 mOrigin=0; //now realign the origin...
165 mData=temp;
166 }
167 return mCapacity;
168}
169
170/**
171 * This method adds an item to the end of the deque.
172 * This operation has the potential to cause the
173 * underlying buffer to resize.
174 *
175 * @param aItem: new item to be added to deque
176 * @return *this
177 */
178nsDeque& nsDeque::Push(void* aItem) {
179 if (mSize==mCapacity) {
180 GrowCapacity();
181 }
182 mData[modulus(mOrigin + mSize, mCapacity)]=aItem;
183 mSize++;
184 return *this;
185}
186
187/**
188 * This method adds an item to the front of the deque.
189 * This operation has the potential to cause the
190 * underlying buffer to resize.
191 *
192 * --Commments for GrowCapacity() case
193 * We've grown and shifted which means that the old
194 * final element in the deque is now the first element
195 * in the deque. This is temporary.
196 * We haven't inserted the new element at the front.
197 *
198 * To continue with the idea of having the front at zero
199 * after a grow, we move the old final item (which through
200 * the voodoo of mOrigin-- is now the first) to its final
201 * position which is conveniently the old length.
202 *
203 * Note that this case only happens when the deque is full.
204 * [And that pieces of this magic only work if the deque is full.]
205 * picture:
206 * [ABCDEFGH] @[mOrigin:3]:D.
207 * Task: PushFront("Z")
208 * shift mOrigin so, @[mOrigin:2]:C
209 * stretch and rearrange: (mOrigin:0)
210 * [CDEFGHAB ________ ________ ________]
211 * copy: (The second C is currently out of bounds)
212 * [CDEFGHAB C_______ ________ ________]
213 * later we will insert Z:
214 * [ZDEFGHAB C_______ ________ ________]
215 * and increment size: 9. (C is no longer out of bounds)
216 * --
217 * @param aItem: new item to be added to deque
218 * @return *this
219 */
220nsDeque& nsDeque::PushFront(void* aItem) {
221 mOrigin--;
222 modasgn(mOrigin,mCapacity);
223 if (mSize==mCapacity) {
224 GrowCapacity();
225 /* Comments explaining this are above*/
226 mData[mSize]=mData[mOrigin];
227 }
228 mData[mOrigin]=aItem;
229 mSize++;
230 return *this;
231}
232
233/**
234 * Remove and return the last item in the container.
235 *
236 * @return ptr to last item in container
237 */
238void* nsDeque::Pop() {
239 void* result=0;
240 if (mSize>0) {
241 --mSize;
242 PRInt32 offset=modulus(mSize + mOrigin, mCapacity);
243 result=mData[offset];
244 mData[offset]=0;
245 if (!mSize) {
246 mOrigin=0;
247 }
248 }
249 return result;
250}
251
252/**
253 * This method gets called you want to remove and return
254 * the first member in the container.
255 *
256 * @return last item in container
257 */
258void* nsDeque::PopFront() {
259 void* result=0;
260 if (mSize>0) {
261 NS_ASSERTION(mOrigin < mCapacity, "Error: Bad origin");
262 result=mData[mOrigin];
263 mData[mOrigin++]=0; //zero it out for debugging purposes.
264 mSize--;
265 // Cycle around if we pop off the end
266 // and reset origin if when we pop the last element
267 if (mCapacity==mOrigin || !mSize) {
268 mOrigin=0;
269 }
270 }
271 return result;
272}
273
274/**
275 * This method gets called you want to peek at the bottom
276 * member without removing it.
277 *
278 * @return last item in container
279 */
280void* nsDeque::Peek() {
281 void* result=0;
282 if (mSize>0) {
283 result = mData[modulus(mSize - 1 + mOrigin, mCapacity)];
284 }
285 return result;
286}
287
288/**
289 * This method gets called you want to peek at the topmost
290 * member without removing it.
291 *
292 * @return last item in container
293 */
294void* nsDeque::PeekFront() {
295 void* result=0;
296 if (mSize>0) {
297 result=mData[mOrigin];
298 }
299 return result;
300}
301
302/**
303 * Call this to retrieve the ith element from this container.
304 * Keep in mind that accessing the underlying elements is
305 * done in a relative fashion. Object 0 is not necessarily
306 * the first element (the first element is at mOrigin).
307 *
308 * @param aIndex : 0 relative offset of item you want
309 * @return void* or null
310 */
311void* nsDeque::ObjectAt(PRInt32 aIndex) const {
312 void* result=0;
313 if ((aIndex>=0) && (aIndex<mSize)) {
314 result=mData[modulus(mOrigin + aIndex, mCapacity)];
315 }
316 return result;
317}
318
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette