//////////////////////////////////////////////////////////////////////////////////////// // RAVEN STANDARD TEMPLATE LIBRARY // (c) 2002 Activision // // // Queue Template // -------------- // The queue is a circular buffer of objects which supports a push at the "front" and a // pop at the "back". Therefore it is: // // First In, First Out // // As the pointers to the push and pop locations are changed it wrapps around the end // of the array and back to the front. There are asserts to make sure it never goes // beyond the capacity of the object. // // // // NOTES: // // // //////////////////////////////////////////////////////////////////////////////////////// #if !defined(RATL_QUEUE_VS_INC) #define RATL_QUEUE_VS_INC //////////////////////////////////////////////////////////////////////////////////////// // Includes //////////////////////////////////////////////////////////////////////////////////////// #if !defined(RATL_COMMON_INC) #include "ratl_common.h" #endif namespace ratl { //////////////////////////////////////////////////////////////////////////////////////// // The Queue Class //////////////////////////////////////////////////////////////////////////////////////// template class queue_base : public ratl_base { public: typedef typename T TStorageTraits; typedef typename T::TValue TTValue; //////////////////////////////////////////////////////////////////////////////////// // Capacity Enum //////////////////////////////////////////////////////////////////////////////////// enum { CAPACITY = T::CAPACITY }; private: //////////////////////////////////////////////////////////////////////////////////// // Data //////////////////////////////////////////////////////////////////////////////////// array_base mData; // The Memory int mPush; // Address Of Next Add Location int mPop; // Address Of Next Remove Location int mSize; int push_low() { assert(size()=CAPACITY) { mPush=0; return CAPACITY-1; } return mPush-1; } public: typedef T TStorageTraits; //////////////////////////////////////////////////////////////////////////////////// // Constructor //////////////////////////////////////////////////////////////////////////////////// queue_base() : mPush(0), mPop(0), mSize(0) { } //////////////////////////////////////////////////////////////////////////////////// // Get The Size (The Difference Between The Push And Pop "Pointers") //////////////////////////////////////////////////////////////////////////////////// int size() const { return mSize; } //////////////////////////////////////////////////////////////////////////////////// // Check To See If The Size Is Zero //////////////////////////////////////////////////////////////////////////////////// bool empty() const { return !mSize; } //////////////////////////////////////////////////////////////////////////////////// // Check To See If The Size Is Full //////////////////////////////////////////////////////////////////////////////////// bool full() const { return mSize>=CAPACITY; } //////////////////////////////////////////////////////////////////////////////////// // Empty Out The Entire Queue //////////////////////////////////////////////////////////////////////////////////// void clear() { mPush = 0; mPop = 0; mSize = 0; mData.clear(); } //////////////////////////////////////////////////////////////////////////////////// // Add A Value, returns a reference to the value in place //////////////////////////////////////////////////////////////////////////////////// TTValue & push() { int idx=push_low(); mData.construct(idx); return mData[idx]; } //////////////////////////////////////////////////////////////////////////////////// // Add A Value to the Queue //////////////////////////////////////////////////////////////////////////////////// void push(const TTValue& v) { mData.construct(push_low(),v); } //////////////////////////////////////////////////////////////////////////////////// // Add A Value to the Queue, returning a void * to the memory //////////////////////////////////////////////////////////////////////////////////// TRatlNew *push_raw() { return mData.alloc_raw(push_low()); } //////////////////////////////////////////////////////////////////////////////////// // Remove A Value From The Queue //////////////////////////////////////////////////////////////////////////////////// void pop() { assert(size()>0); mData.destruct(mPop); // Update Pop Location //--------------------- mPop++; if (mPop>=CAPACITY) { mPop=0; } mSize--; } TTValue & top() { assert(size()>0); return mData[mPop]; } const TTValue & top() const { assert(size()>0); return mData[mPop]; } template CAST_TO *verify_alloc(CAST_TO *p) const { return mData.verify_alloc(p); } }; template class queue_vs : public queue_base > { public: typedef typename storage::value_semantics TStorageTraits; typedef typename TStorageTraits::TValue TTValue; enum { CAPACITY = ARG_CAPACITY }; queue_vs() {} }; template class queue_os : public queue_base > { public: typedef typename storage::object_semantics TStorageTraits; typedef typename TStorageTraits::TValue TTValue; enum { CAPACITY = ARG_CAPACITY }; queue_os() {} }; template class queue_is : public queue_base > { public: typedef typename storage::virtual_semantics TStorageTraits; typedef typename TStorageTraits::TValue TTValue; enum { CAPACITY = ARG_CAPACITY, MAX_CLASS_SIZE = ARG_MAX_CLASS_SIZE }; queue_is() {} }; } #endif