Circular Buffer C++

circular buffer, also known as cyclic buffer or ring buffer is a special data structure that uses a single, fixed-size buffer as if it were connected end-to-end. That is, if you reach writing to the last available slot in the buffer, the next slot to write into is the first slot of the buffer. You can find the gereric version here


The following code is a sample implementation of that structure. You can freely use them if you need to. The code standard I am trying to follow is Google's C++ Style.


The header file:
circular_buffer.hpp

#ifndef MCP_CIRCULAR_BUFFER_H_
#define MCP_CIRCULAR_BUFFER_H_

namespace base {
// This is a fixed-size, circular buffer of integer.
// The class is not thread-safe,
class CircularBuffer {
public:

  // Creates a buffer with 'slots' slots.
  explicit CircularBuffer(int slots);
  // Destructor.
  ~CircularBuffer();
  // Writes 'value' to the next available slot. It may overwrite
  // values that were not yet read out of the buffer.
  void write(int value);
  // Returns the next value available for reading, in the order they
  // were written, and marks slot as read. If the buffer is empty returns -1.
  int read();
  // Removes all the elements from the buffer.
  void clear();

private:
  //array of integers
  int* data_;
  // the size of the buffer
  int  num_of_slots_;
  //index to read the next integer from buffer
  int  read_index_;
  //index to write a new integer to buffer
  int  write_index_;

  // Non-copyable, non-assignable.
  CircularBuffer(CircularBuffer&);
  CircularBuffer& operator=(const CircularBuffer&);
};
} // namespace base
#endif  // MCP_CIRCULAR_BUFFER_H_

circular_buffer.cpp

#include "circular_buffer.hpp"

namespace base {

CircularBuffer::CircularBuffer(int slots) {
  if (slots <= 0) {
    num_of_slots_ = 10; /*pre-assigned value */
  } else {
      num_of_slots_ = slots;
  }
  clear();
}

CircularBuffer::~CircularBuffer() {
  delete[] data_;
}

void CircularBuffer::write(int value) {
  data_[write_index_] = value;
  if (read_index_ == -1) {
    //if buffer is empty, set the read index to the 
 //current write index. because that will be the first 
 //slot to be read later.
    read_index_ = write_index_; 
  }
  write_index_ = (write_index_ + 1) % num_of_slots_; 
}

int CircularBuffer::read() {
  if (read_index_ == -1) {
    // buffer empty
    return -1;
  }
  int ret_val = data_[read_index_];
  read_index_ = (read_index_ + 1) % num_of_slots_;
  if (read_index_ == write_index_) {
    /*all available data is read, now buffer is empty*/
    read_index_ = -1;
  }

  return ret_val;  
}

void CircularBuffer::clear() {
  read_index_ = -1; /* buffer empty */
  write_index_ = 0; /* first time writing to that buffer*/
  delete [] data_;
  data_ = new int[num_of_slots_]; /* allocate space for buffer */
}

}  // namespace base

Python Line Profilers using Decorator Pattern

You can use any of the following decorators to profile your functions line by line.  The first one(Profiler1) is a decorator as a class and...