3 * \brief double ended queue
6 * Copyright (C) 2003-2009 Ushodaya Enterprises Limited
7 * \author Charles Yates <charles.yates@pandora.be>
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 #include "mlt_deque.h"
27 // System header files
31 /** \brief Deque entry class
43 /** \brief Double-Ended Queue (deque) class
45 * The double-ended queue is a very versatile data structure. MLT uses it as
46 * list, stack, and circular queue.
58 * \public \memberof mlt_deque_s
62 mlt_deque mlt_deque_init( )
64 mlt_deque this = malloc( sizeof( struct mlt_deque_s ) );
74 /** Return the number of items in the deque.
76 * \public \memberof mlt_deque_s
78 * \return the number of items
81 int mlt_deque_count( mlt_deque this )
86 /** Allocate space on the deque.
88 * \private \memberof mlt_deque_s
90 * \return true if there was an error
93 static int mlt_deque_allocate( mlt_deque this )
95 if ( this->count == this->size )
97 this->list = realloc( this->list, sizeof( deque_entry ) * ( this->size + 20 ) );
100 return this->list == NULL;
103 /** Push an item to the end.
105 * \public \memberof mlt_deque_s
106 * \param this a deque
107 * \param item an opaque pointer
108 * \return true if there was an error
111 int mlt_deque_push_back( mlt_deque this, void *item )
113 int error = mlt_deque_allocate( this );
116 this->list[ this->count ++ ].addr = item;
123 * \public \memberof mlt_deque_s
124 * \param this a pointer
125 * \return an opaque pointer
128 void *mlt_deque_pop_back( mlt_deque this )
130 return this->count > 0 ? this->list[ -- this->count ].addr : NULL;
133 /** Queue an item at the start.
135 * \public \memberof mlt_deque_s
136 * \param this a deque
137 * \param item an opaque pointer
138 * \return true if there was an error
141 int mlt_deque_push_front( mlt_deque this, void *item )
143 int error = mlt_deque_allocate( this );
147 memmove( &this->list[ 1 ], this->list, ( this->count ++ ) * sizeof( deque_entry ) );
148 this->list[ 0 ].addr = item;
154 /** Remove an item from the start.
156 * \public \memberof mlt_deque_s
157 * \param this a pointer
158 * \return an opaque pointer
161 void *mlt_deque_pop_front( mlt_deque this )
165 if ( this->count > 0 )
167 item = this->list[ 0 ].addr;
168 memmove( this->list, &this->list[ 1 ], ( -- this->count ) * sizeof( deque_entry ) );
174 /** Inquire on item at back of deque but don't remove.
176 * \public \memberof mlt_deque_s
177 * \param this a deque
178 * \return an opaque pointer
181 void *mlt_deque_peek_back( mlt_deque this )
183 return this->count > 0 ? this->list[ this->count - 1 ].addr : NULL;
186 /** Inquire on item at front of deque but don't remove.
188 * \public \memberof mlt_deque_s
189 * \param this a deque
190 * \return an opaque pointer
193 void *mlt_deque_peek_front( mlt_deque this )
195 return this->count > 0 ? this->list[ 0 ].addr : NULL;
198 /** Insert an item in a sorted fashion.
200 * Optimized for the equivalent of \p mlt_deque_push_back.
202 * \public \memberof mlt_deque_s
203 * \param this a deque
204 * \param item an opaque pointer
205 * \param cmp a function pointer to the comparison function
206 * \return true if there was an error
209 int mlt_deque_insert( mlt_deque this, void *item, mlt_deque_compare cmp )
211 int error = mlt_deque_allocate( this );
215 int n = this->count + 1;
217 if ( cmp( item, this->list[ n - 1 ].addr ) >= 0 )
219 memmove( &this->list[ n + 1 ], &this->list[ n ], ( this->count - n ) * sizeof( deque_entry ) );
220 this->list[ n ].addr = item;
226 /** Push an integer to the end.
228 * \public \memberof mlt_deque_s
229 * \param this a deque
230 * \param item an integer
231 * \return true if there was an error
234 int mlt_deque_push_back_int( mlt_deque this, int item )
236 int error = mlt_deque_allocate( this );
239 this->list[ this->count ++ ].value = item;
246 * \public \memberof mlt_deque_s
247 * \param this a deque
251 int mlt_deque_pop_back_int( mlt_deque this )
253 return this->count > 0 ? this->list[ -- this->count ].value : 0;
256 /** Queue an integer at the start.
258 * \public \memberof mlt_deque_s
259 * \param this a deque
260 * \param item an integer
261 * \return true if there was an error
264 int mlt_deque_push_front_int( mlt_deque this, int item )
266 int error = mlt_deque_allocate( this );
270 memmove( &this->list[ 1 ], this->list, ( this->count ++ ) * sizeof( deque_entry ) );
271 this->list[ 0 ].value = item;
277 /** Remove an integer from the start.
279 * \public \memberof mlt_deque_s
280 * \param this a deque
284 int mlt_deque_pop_front_int( mlt_deque this )
288 if ( this->count > 0 )
290 item = this->list[ 0 ].value;
291 memmove( this->list, &this->list[ 1 ], ( -- this->count ) * sizeof( deque_entry ) );
297 /** Inquire on an integer at back of deque but don't remove.
299 * \public \memberof mlt_deque_s
300 * \param this a deque
304 int mlt_deque_peek_back_int( mlt_deque this )
306 return this->count > 0 ? this->list[ this->count - 1 ].value : 0;
309 /** Inquire on an integer at front of deque but don't remove.
311 * \public \memberof mlt_deque_s
312 * \param this a deque
316 int mlt_deque_peek_front_int( mlt_deque this )
318 return this->count > 0 ? this->list[ 0 ].value : 0;
321 /** Push a double float to the end.
323 * \public \memberof mlt_deque_s
324 * \param this a deque
325 * \param item a double float
326 * \return true if there was an error
329 int mlt_deque_push_back_double( mlt_deque this, double item )
331 int error = mlt_deque_allocate( this );
334 this->list[ this->count ++ ].floating = item;
339 /** Pop a double float.
341 * \public \memberof mlt_deque_s
342 * \param this a deque
343 * \return a double float
346 double mlt_deque_pop_back_double( mlt_deque this )
348 return this->count > 0 ? this->list[ -- this->count ].floating : 0;
351 /** Queue a double float at the start.
353 * \public \memberof mlt_deque_s
354 * \param this a deque
355 * \param item a double float
356 * \return true if there was an error
359 int mlt_deque_push_front_double( mlt_deque this, double item )
361 int error = mlt_deque_allocate( this );
365 memmove( &this->list[ 1 ], this->list, ( this->count ++ ) * sizeof( deque_entry ) );
366 this->list[ 0 ].floating = item;
372 /** Remove a double float from the start.
374 * \public \memberof mlt_deque_s
375 * \param this a deque
376 * \return a double float
379 double mlt_deque_pop_front_double( mlt_deque this )
383 if ( this->count > 0 )
385 item = this->list[ 0 ].floating;
386 memmove( this->list, &this->list[ 1 ], ( -- this->count ) * sizeof( deque_entry ) );
392 /** Inquire on a double float at back of deque but don't remove.
394 * \public \memberof mlt_deque_s
395 * \param this a deque
396 * \return a double float
399 double mlt_deque_peek_back_double( mlt_deque this )
401 return this->count > 0 ? this->list[ this->count - 1 ].floating : 0;
404 /** Inquire on a double float at front of deque but don't remove.
406 * \public \memberof mlt_deque_s
407 * \param this a deque
408 * \return a double float
411 double mlt_deque_peek_front_double( mlt_deque this )
413 return this->count > 0 ? this->list[ 0 ].floating : 0;
416 /** Destroy the queue.
418 * \public \memberof mlt_deque_s
419 * \param this a deque
422 void mlt_deque_close( mlt_deque this )