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 self = 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 self )
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 self )
95 if ( self->count == self->size )
97 self->list = realloc( self->list, sizeof( deque_entry ) * ( self->size + 20 ) );
100 return self->list == NULL;
103 /** Push an item to the end.
105 * \public \memberof mlt_deque_s
106 * \param self a deque
107 * \param item an opaque pointer
108 * \return true if there was an error
111 int mlt_deque_push_back( mlt_deque self, void *item )
113 int error = mlt_deque_allocate( self );
116 self->list[ self->count ++ ].addr = item;
123 * \public \memberof mlt_deque_s
124 * \param self a pointer
125 * \return an opaque pointer
128 void *mlt_deque_pop_back( mlt_deque self )
130 return self->count > 0 ? self->list[ -- self->count ].addr : NULL;
133 /** Queue an item at the start.
135 * \public \memberof mlt_deque_s
136 * \param self a deque
137 * \param item an opaque pointer
138 * \return true if there was an error
141 int mlt_deque_push_front( mlt_deque self, void *item )
143 int error = mlt_deque_allocate( self );
147 memmove( &self->list[ 1 ], self->list, ( self->count ++ ) * sizeof( deque_entry ) );
148 self->list[ 0 ].addr = item;
154 /** Remove an item from the start.
156 * \public \memberof mlt_deque_s
157 * \param self a pointer
158 * \return an opaque pointer
161 void *mlt_deque_pop_front( mlt_deque self )
165 if ( self->count > 0 )
167 item = self->list[ 0 ].addr;
168 memmove( self->list, &self->list[ 1 ], ( -- self->count ) * sizeof( deque_entry ) );
174 /** Inquire on item at back of deque but don't remove.
176 * \public \memberof mlt_deque_s
177 * \param self a deque
178 * \return an opaque pointer
181 void *mlt_deque_peek_back( mlt_deque self )
183 return self->count > 0 ? self->list[ self->count - 1 ].addr : NULL;
186 /** Inquire on item at front of deque but don't remove.
188 * \public \memberof mlt_deque_s
189 * \param self a deque
190 * \return an opaque pointer
193 void *mlt_deque_peek_front( mlt_deque self )
195 return self->count > 0 ? self->list[ 0 ].addr : NULL;
198 /** Inquire on item in deque but don't remove.
200 * \public \memberof mlt_deque_s
201 * \param self a deque
202 * \param index the position in the deque
203 * \return an opaque pointer
206 void *mlt_deque_peek( mlt_deque self, int index )
208 return self->count > index ? self->list[ index ].addr : NULL;
211 /** Insert an item in a sorted fashion.
213 * Optimized for the equivalent of \p mlt_deque_push_back.
215 * \public \memberof mlt_deque_s
216 * \param self a deque
217 * \param item an opaque pointer
218 * \param cmp a function pointer to the comparison function
219 * \return true if there was an error
222 int mlt_deque_insert( mlt_deque self, void *item, mlt_deque_compare cmp )
224 int error = mlt_deque_allocate( self );
228 int n = self->count + 1;
230 if ( cmp( item, self->list[ n - 1 ].addr ) >= 0 )
232 memmove( &self->list[ n + 1 ], &self->list[ n ], ( self->count - n ) * sizeof( deque_entry ) );
233 self->list[ n ].addr = item;
239 /** Push an integer to the end.
241 * \public \memberof mlt_deque_s
242 * \param self a deque
243 * \param item an integer
244 * \return true if there was an error
247 int mlt_deque_push_back_int( mlt_deque self, int item )
249 int error = mlt_deque_allocate( self );
252 self->list[ self->count ++ ].value = item;
259 * \public \memberof mlt_deque_s
260 * \param self a deque
264 int mlt_deque_pop_back_int( mlt_deque self )
266 return self->count > 0 ? self->list[ -- self->count ].value : 0;
269 /** Queue an integer at the start.
271 * \public \memberof mlt_deque_s
272 * \param self a deque
273 * \param item an integer
274 * \return true if there was an error
277 int mlt_deque_push_front_int( mlt_deque self, int item )
279 int error = mlt_deque_allocate( self );
283 memmove( &self->list[ 1 ], self->list, ( self->count ++ ) * sizeof( deque_entry ) );
284 self->list[ 0 ].value = item;
290 /** Remove an integer from the start.
292 * \public \memberof mlt_deque_s
293 * \param self a deque
297 int mlt_deque_pop_front_int( mlt_deque self )
301 if ( self->count > 0 )
303 item = self->list[ 0 ].value;
304 memmove( self->list, &self->list[ 1 ], ( -- self->count ) * sizeof( deque_entry ) );
310 /** Inquire on an integer at back of deque but don't remove.
312 * \public \memberof mlt_deque_s
313 * \param self a deque
317 int mlt_deque_peek_back_int( mlt_deque self )
319 return self->count > 0 ? self->list[ self->count - 1 ].value : 0;
322 /** Inquire on an integer at front of deque but don't remove.
324 * \public \memberof mlt_deque_s
325 * \param self a deque
329 int mlt_deque_peek_front_int( mlt_deque self )
331 return self->count > 0 ? self->list[ 0 ].value : 0;
334 /** Push a double float to the end.
336 * \public \memberof mlt_deque_s
337 * \param self a deque
338 * \param item a double float
339 * \return true if there was an error
342 int mlt_deque_push_back_double( mlt_deque self, double item )
344 int error = mlt_deque_allocate( self );
347 self->list[ self->count ++ ].floating = item;
352 /** Pop a double float.
354 * \public \memberof mlt_deque_s
355 * \param self a deque
356 * \return a double float
359 double mlt_deque_pop_back_double( mlt_deque self )
361 return self->count > 0 ? self->list[ -- self->count ].floating : 0;
364 /** Queue a double float at the start.
366 * \public \memberof mlt_deque_s
367 * \param self a deque
368 * \param item a double float
369 * \return true if there was an error
372 int mlt_deque_push_front_double( mlt_deque self, double item )
374 int error = mlt_deque_allocate( self );
378 memmove( &self->list[ 1 ], self->list, ( self->count ++ ) * sizeof( deque_entry ) );
379 self->list[ 0 ].floating = item;
385 /** Remove a double float from the start.
387 * \public \memberof mlt_deque_s
388 * \param self a deque
389 * \return a double float
392 double mlt_deque_pop_front_double( mlt_deque self )
396 if ( self->count > 0 )
398 item = self->list[ 0 ].floating;
399 memmove( self->list, &self->list[ 1 ], ( -- self->count ) * sizeof( deque_entry ) );
405 /** Inquire on a double float at back of deque but don't remove.
407 * \public \memberof mlt_deque_s
408 * \param self a deque
409 * \return a double float
412 double mlt_deque_peek_back_double( mlt_deque self )
414 return self->count > 0 ? self->list[ self->count - 1 ].floating : 0;
417 /** Inquire on a double float at front of deque but don't remove.
419 * \public \memberof mlt_deque_s
420 * \param self a deque
421 * \return a double float
424 double mlt_deque_peek_front_double( mlt_deque self )
426 return self->count > 0 ? self->list[ 0 ].floating : 0;
429 /** Destroy the queue.
431 * \public \memberof mlt_deque_s
432 * \param self a deque
435 void mlt_deque_close( mlt_deque self )