• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* ------------------------------------------------------------------
2  * Copyright (C) 1998-2009 PacketVideo
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13  * express or implied.
14  * See the License for the specific language governing permissions
15  * and limitations under the License.
16  * -------------------------------------------------------------------
17  */
18 // -*- c++ -*-
19 
20 
21 
22 // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
23 
24 //                     O S C L _ Q U E U E
25 // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
26 
27 /*! \addtogroup osclbase OSCL Base
28  * Additional osclbase comment
29  * @{
30  */
31 
32 /*! \file oscl_queue.h
33     \brief The file oscl_queue.h defines the template class Oscl_Queue.  It is
34     similar to the STL::queue class, with some differences:
35      - less complete
36      - based on array rather than a deque
37      - some interfaces modeled on oscl_vector, for ease of transition
38     Memory allocation is abstracted through the use of an allocator template parameter.
39 */
40 
41 #ifndef OSCL_QUEUE_H_INCLUDED
42 #define OSCL_QUEUE_H_INCLUDED
43 
44 #ifndef OSCL_BASE_H_INCLUDED
45 #include "oscl_base.h"
46 #endif
47 
48 #ifndef OSCL_MEM_BASIC_FUNCTIONS_H_INCLUDED
49 #include "oscl_mem_basic_functions.h"
50 #endif
51 
52 #ifndef OSCL_ASSERT_H_INCLUDED
53 #include "oscl_assert.h"
54 #endif
55 
56 #ifndef OSCL_OPAQUE_TYPE_H_INCLUDED
57 #include "oscl_opaque_type.h"
58 #endif
59 
60 /**
61  * Oscl_Queue_Base is a non-templatized base class for Oscl_Queue.
62  * The purpose of this base class is to avoid large inline routines
63  * in the Oscl_Queue implementation.
64  * This class is not intended for direct instantiation except by
65  * Oscl_Queue.
66  */
67 class Oscl_Queue_Base
68 {
69     public:
70 
71         /**
72          * Returns the size of the queue.
73          */
size()74         uint32 size() const
75         {
76             return numelems;
77         }
78 
79         /**
80          * Returns the allocated memory of the queue.
81          */
capacity()82         uint32 capacity() const
83         {
84             return bufsize;
85         }
86 
87         /**
88          * True if there are no elements in the queue
89          */
empty()90         bool empty() const
91         {
92             return numelems == 0;
93         }
94 
95         /**
96          * Reallocates memory if necessary to a capacity of n elements.
97          * The main reason for reserve is efficiency.  If you know the capacity to
98          * which your vector must grow, then it is more efficient to allocate the
99          * vector all at once rather than rely on the automatic reallocation scheme.
100          * This also helps cotrol the invalidation of iterators.
101          * @param n size of vector
102          */
103         OSCL_IMPORT_REF void reserve(uint32 n) ;
104 
105     protected:
106 
107         //for use in default constructor.  vtable is needed so this is a subroutine.
108         OSCL_IMPORT_REF void construct(Oscl_Opaque_Type_Alloc* aType);
109 
110         //for use in constructor with pre-allocation for "n" elements.
111         OSCL_IMPORT_REF void construct(Oscl_Opaque_Type_Alloc* aType, uint32 n) ;
112 
113         /**
114          * The destructor.
115          */
~Oscl_Queue_Base()116         virtual ~Oscl_Queue_Base()
117         {}
118 
119         /**
120          * Like an explicit destructor call.
121          */
122         OSCL_IMPORT_REF void destroy();
123 
124         /**
125          * Inserts a new element at the end.
126          *  Queue will be grown if necessary.  If allocation fails, an OSCL_LEAVE will occur
127          * @param x new element
128          */
129         OSCL_IMPORT_REF void push(const OsclAny* x) ;
130 
131         /**
132          * Removes the first element
133          */
134         OSCL_IMPORT_REF void pop() ;
135 
136         /**
137          * Removes all elements.
138          */
139         OSCL_IMPORT_REF void clear() ;
140 
141         uint32 numelems;  // number of valid entries in queue
142         uint32 bufsize;   // size of elems
143         OsclAny* elems;   // array holding the elements
144         uint32 sizeof_T;
145 
146         uint32 ifront;    // front of queue: removal point
147         uint32 irear;     // just before back of queue: increment=>insertion point
148 
149     private:
150 
151         /**
152          * return a T* incremented by n.
153          */
increment_T(OsclAny * p_T,int32 n)154         OsclAny* increment_T(OsclAny* p_T, int32 n) const
155         {
156             return (OsclAny*)((int32)p_T + n*sizeof_T);
157         }
158 
159         /**
160          * Returns the first element.
161          */
front()162         OsclAny* front()
163         {
164             return increment_T(elems, ifront);
165         }
166 
167         Oscl_Opaque_Type_Alloc* pOpaqueType;
168 };
169 
170 /**
171  * Oscl_Queue Class.  A subset of STL::Queue methods.
172  * Oscl_Queue supports constant time insertion (at the end) and removal of
173  * elements at the front of the queue.  It does not support
174  * insertion or removal of elements at the other ends or middle of the
175  * queue, nor random access to elements.
176  *  * No iteration capability is [currently] supplied.
177  *  * No assignment or copy  capability is [currently] supplied.
178  *  The number of elements in a queue can vary dynamically, and
179  * memory management is performed automatically.
180  */
181 
182 template<class T, class Alloc>
183 class Oscl_Queue
184         : public Oscl_Queue_Base
185         , public Oscl_Opaque_Type_Alloc
186 {
187 
188     public:
189         typedef T value_type;
190         typedef T* pointer;
191         typedef T& reference;
192         typedef const T& const_reference;
193         typedef uint32 size_type;
194 
195         /**
196          * Creates an empty queue.
197          */
Oscl_Queue()198         Oscl_Queue() : Oscl_Queue_Base(), Oscl_Opaque_Type_Alloc()
199         {
200             sizeof_T = sizeof(T);
201             Oscl_Queue_Base::construct(this);
202         }
203 
204         /**
205          * Creates an empty queue with capacity n.
206          * @param n creates a queue with n elements.  The main reason for specifying n
207          * is efficiency.  If you know the capacity to which your queue must grow, then
208          * it is more efficient to allocate the queue all at once rather than rely on
209          * the automatic reallocation scheme.
210          */
Oscl_Queue(uint32 n)211         Oscl_Queue(uint32 n) : Oscl_Queue_Base(), Oscl_Opaque_Type_Alloc()
212         {
213             sizeof_T = sizeof(T);
214             Oscl_Queue_Base::construct(this, n);
215         }
216 
217         /**
218          * The destructor.
219          */
~Oscl_Queue()220         virtual ~Oscl_Queue()
221         {
222             Oscl_Queue_Base::destroy();
223         }
224 
225         /**
226          * Inserts a new element at the end.
227          *  Queue will be grown if necessary.  If allocation fails, an OSCL_LEAVE will occur
228          * @param x new element
229          */
push(const T & x)230         void push(const T& x)
231         {
232             Oscl_Queue_Base::push(&x);
233         }
234 
235         /**
236          * Returns the first element.
237          */
front()238         reference front()
239         {
240             OSCL_ASSERT(! empty());
241             return (reference)((pointer)elems)[ifront];
242         }
243 
244         /**
245          * Returns the first element (const)
246          */
front()247         const_reference front() const
248         {
249             OSCL_ASSERT(! empty());
250             return (const_reference)((pointer)elems)[ifront];
251         }
252 
253 
254         /**
255          * Removes the first element
256          */
pop()257         void pop()
258         {
259             Oscl_Queue_Base::pop();
260         }
261 
262         /**
263          * Returns the last element:  "back"
264          *  (generally not too useful, but some debugging aids might
265          *   want to find out what was just added)
266          */
back()267         reference back()
268         {
269             OSCL_ASSERT(! empty());
270             return (reference)((pointer)elems)[irear];
271         }
272 
273         /**
274          * Returns the last element (const)
275          */
back()276         const_reference back() const
277         {
278             OSCL_ASSERT(! empty());
279             return (const_reference)((pointer)elems)[irear];
280         }
281 
282         /**
283          * Removes all elements.
284          */
clear()285         void clear()
286         {
287             Oscl_Queue_Base::clear();
288         }
289 
290         /**
291          * Return various iterators
292          *  : not provided for queues.  Paradigm is FIFO
293          */
294 
295         /**
296          * Erases the element pointed to by iterator pos.
297          *  : not provided for queues.  Paradigm is QUEUE.
298          */
299 
300     private:
301         Alloc defAlloc;
302 
303         //from Oscl_Opaque_Type_Alloc
allocate(const uint32 size)304         OsclAny* allocate(const uint32 size)
305         {
306             return defAlloc.allocate(size);
307         }
308 
309         //from Oscl_Opaque_Type_Alloc
deallocate(OsclAny * p)310         void deallocate(OsclAny* p)
311         {
312             defAlloc.deallocate(p);
313         }
314 
315         //from Oscl_Opaque_Type_Alloc
construct(OsclAny * p,const OsclAny * x)316         void construct(OsclAny* p, const OsclAny* x)
317         {
318             OSCL_ASSERT(x);
319             new(p) value_type(*((T*)x));
320         }
321 
322         //from Oscl_Opaque_Type_Alloc
destroy(OsclAny * first)323         void destroy(OsclAny* first)
324         {
325             OSCL_ASSERT(first);
326             OSCL_UNUSED_ARG(first);
327             //must use "pointer" instead of "T*" here to avoid ADS 1.2 compile error.
328             ((pointer)first)->~T();
329         }
330 
331 
332         /***************************
333          * things we don't believe are needed
334          * -- private definitions to block implicit ones --
335          */
336 
337         /**
338          * The assignment operator --
339          *  - private, to block use of implicit assignment
340          *  - not actually implemented, don't believe it's needed
341          */
342         Oscl_Queue<T, Alloc>& operator=(const Oscl_Queue<T, Alloc>& x)
343         {
344             // Do we need to copy a queue?  Why...?
345             //  .. unless there's a need, let's not bother with the
346             //  complexity here..
347             // (need something here, we don't want implicit assignment either
348             OSCL_UNUSED_ARG(x);
349             OSCL_ASSERT(false);
350             return *this;
351         }
352 
353         /**
354          * Copy Constructor.
355          * @param x queue class to copy, also for value passage as argument
356          * (but: why do we want to copy a queue??)
357          */
Oscl_Queue(const Oscl_Queue<T,Alloc> & x)358         Oscl_Queue(const Oscl_Queue<T, Alloc>& x)
359                 : Oscl_Queue_Base(sizeof(T), this, this)
360         {
361             OSCL_UNUSED_ARG(x);
362             OSCL_ASSERT(false);
363         }
364 };  // end class oscl_queue
365 
366 /*! @} */
367 
368 
369 #endif
370 
371 
372