Click here to Skip to main content
15,895,799 members
Articles / Desktop Programming / MFC

Another Enum Viewer

Rate me:
Please Sign up or sign in to vote.
4.50/5 (2 votes)
22 Oct 20015 min read 83K   1.3K   19  
An article on the usage and design of another Enum Viewer
// JLCircBuffer.h:  Implementation of circular buffer template.
// The "JL" is the author's initials
//
// T must have:
//    T::T() or equivalent
//    T::operator=() or equivalent

#ifndef INCL_JLCIRCBUFFER_H
#define INCL_JLCIRCBUFFER_H

template <class T> class JLCircBuffer 
{
public:
   // ctor/dtor
   JLCircBuffer(int minSize = DefaultSize);
   JLCircBuffer(const JLCircBuffer& rhs);
   ~JLCircBuffer();

   // assignment
   const JLCircBuffer& operator=(const JLCircBuffer& rhs);

   //
   // operations
   //

   // Note: does not delete elements in buffer
   void clear() { nbrEntries = 0; nextOffset = 0; }

   // status of buffer
   int entries() const { return nbrEntries; }
   int isEmpty() const { return nbrEntries == 0; }

   // Index w.r.t. front of queue -- modifyable until next operation
   T& operator[](int idx) { 
      #ifndef NDEBUG
         assert(idx >= 0 && idx < nbrEntries);
      #endif
      return buffer[(nextOffset + idx) & sizeLessOne]; 
   }

   // Index w.r.t. front of queue -- const value
   const T& operator[](int idx) const { 
      #ifndef NDEBUG
         assert(idx >= 0 && idx < nbrEntries);
      #endif
      return buffer[(nextOffset + idx) & sizeLessOne]; 
   }

   // Remove item from front of queue
   void removeFirst() { 
      #ifndef NDEBUG
         assert(!isEmpty());
      #endif
      nextOffset = (nextOffset+1) & sizeLessOne;
      nbrEntries--;
   }

   // Get and remove item from front of queue
   T next() { 
      #ifndef NDEBUG
         assert(!isEmpty());
      #endif
      T* elt = &buffer[nextOffset];
      removeFirst();
      return *elt;
   }

   // Add item to end of queue
   void append(const T& elt)
   {
      if (nbrEntries == size)
      {
         expand();
      }
      buffer[(nextOffset + nbrEntries) & sizeLessOne] = elt;
      nbrEntries++;
   }

   // constants
   enum { DefaultSize = 32 };

private:
   void init();
   // double the current buffer size -- this changes the offsets!
   void expand();

   // data
   T* buffer;
   int size;            // number of allocated entries
   int sizeLessOne;     // number of allocated entries - 1
   T* bufEnd;           // == buffer + size
   int nextOffset;      // index of next entry in queue
   int nbrEntries;
};

//////////////////////////////////////////////////////////////////////////
//                  Out-of-line template functions                      //
//////////////////////////////////////////////////////////////////////////
template <class T>
JLCircBuffer<T>::JLCircBuffer(int minSize)
{
   // Find first power of 2 >= to requested size
   for (size = 2; size < minSize; size *= 2) {;}
   init();
}

template <class T>
JLCircBuffer<T>::JLCircBuffer(const JLCircBuffer& rhs)
{
   for (size = DefaultSize; size < rhs.entries(); size *= 2) {;}
   init();
}

template <class T>
void
JLCircBuffer<T>::init()
{
   // Allocate buffer
   buffer = new T[size];

   // Other initialization
   sizeLessOne = size - 1;
   bufEnd = buffer + size;
   nextOffset = 0;
   nbrEntries = 0;
}

template <class T>
JLCircBuffer<T>::~JLCircBuffer()
{
   delete [] buffer;
}

template <class T>
const JLCircBuffer<T>& 
JLCircBuffer<T>::operator=(
   const JLCircBuffer& rhs
)
{
   if (this != &rhs)
   {
      clear();
      for (int i = 0; i < rhs.entries(); i++)
      {
         append(rhs[i]);
      }
   }
   return *this;
}

template <class T>
void 
JLCircBuffer<T>::expand()
{
   // allocate a buffer that is double the current size
   T* newBuffer = new T[size*2];

   // Copy the contents to the new buffer
   // Note that this will store the first logical item in the 
   // first physical array element.
   for (int i = 0; i < entries(); i++)
   {
      newBuffer[i] = (*this)[i];
   }

   // delete old buffer
   delete [] buffer;

   // Re-initialize with new contents, keep old nbrEntries
   buffer = newBuffer;
   bufEnd = buffer + size;
   size = size * 2;
   sizeLessOne = size - 1;
   nextOffset = 0;
}

#endif

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions