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