Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <exception>
- #include <stdexcept>
- // Требования к value_type:
- // * Конструктор по умолчанию
- // * Оператор присваивания
- template <typename value_type>
- class CircularBuffer
- {
- private:
- static const int m_default_length = 27;
- value_type * m_buffer;
- value_type * m_first_element;
- value_type * m_last_element;
- unsigned int m_capacity;
- unsigned int get_real_index(unsigned int relative_index)
- {
- return ((m_first_element - m_buffer + relative_index) % m_capacity);
- };
- public:
- CircularBuffer()
- {
- m_capacity = m_default_length;
- m_buffer = new value_type[m_default_length];
- m_first_element = NULL;
- m_last_element = NULL;
- };
- ~CircularBuffer()
- {
- delete[] m_buffer;
- };
- CircularBuffer(const CircularBuffer & cb)
- {
- int i;
- int j;
- m_capacity = cb.m_capacity;
- m_buffer = new value_type[m_capacity];
- if (!m_first_element)
- {
- m_first_element = NULL;
- m_last_element = NULL;
- return;
- }
- m_first_element = m_buffer + cb.m_first_element - cb.m_buffer;
- m_last_element = m_buffer + cb.m_last_element - cb.m_buffer;
- if (m_last_element > m_first_element)
- {
- i = m_first_element - m_buffer;
- j = m_last_element - m_buffer;
- for(; i <= j; ++i)
- {
- m_buffer[i] = cb.m_buffer[i];
- }
- return;
- }
- if (m_last_element < m_first_element)
- {
- i = 0;
- j = m_last_element - m_buffer;
- for(; i <= j; ++i)
- {
- m_buffer[i] = cb.m_buffer[i];
- }
- i = m_first_element - m_buffer;
- j = m_capacity - 1;
- for(; i <= j; ++i)
- {
- m_buffer[i] = cb.m_buffer[i];
- }
- return;
- }
- m_buffer[m_first_element - m_buffer] = cb.m_buffer[m_first_element - m_buffer];
- };
- //Конструирует буфер заданной ёмкости.
- explicit CircularBuffer(int capacity)
- {
- m_capacity = capacity;
- m_buffer = new value_type[capacity];
- m_first_element = NULL;
- m_last_element = NULL;
- };
- //Конструирует буфер заданной ёмкости, целиком заполняет его элементом elem.
- CircularBuffer(int capacity, const value_type & elem)
- {
- int i = 0;
- m_capacity = capacity;
- m_buffer = new value_type[m_capacity];
- m_first_element = m_buffer;
- for(; i < m_capacity; ++i)
- {
- m_buffer[i] = elem;
- }
- m_last_element = &(m_buffer[i-1]);
- };
- //Доступ по индексу. Не проверяют правильность индекса.
- value_type & operator[](int i)
- {
- return (m_buffer[get_real_index(i)]);
- };
- const value_type & operator[](int i) const
- {
- return (m_buffer[get_real_index(i)]);
- };
- //Доступ по индексу. Методы бросают исключение в случае неверного индекса.
- value_type & at(int i)
- {
- if (i < size())
- {
- return (m_buffer[get_real_index(i)]);
- }
- throw invalid_argument;
- };
- const value_type & at(int i) const
- {
- if (i < size())
- {
- return (m_buffer[get_real_index(i)]);
- }
- throw invalid_argument;
- };
- //Ссылка на первый элемент.
- value_type & front()
- {
- return *m_first_element;
- };
- //Ссылка на последний элемент.
- value_type & back()
- {
- return *m_last_element;
- };
- const value_type & front() const
- {
- return *m_first_element;
- };
- const value_type & back() const
- {
- return *m_last_element;
- };
- //Линеаризация - сдвинуть кольцевой буфер так, что его первый элемент
- //переместится в начало аллоцированной памяти. Возвращает указатель
- //на первый элемент.
- value_type * linearize()
- {
- value_type tmp;
- value_type * p;
- value_type * p2;
- if (is_linearized())
- {
- return;
- }
- while (m_last_element < m_first_element)
- {
- tmp = m_buffer[0];
- p = &(m_buffer[0]);
- while (p < m_last_element)
- {
- *(p) = *(p + 1);
- ++p;
- }
- p = m_first_element;
- while (p < m_buffer + m_capacity - 1)
- {
- *(p) = *(p + 1);
- ++p;
- }
- *(p) = tmp;
- }
- p = m_buffer;
- p2 = m_first_element;
- while (m_last_element >= p2)
- {
- *p = *p2;
- ++p;
- ++p2;
- }
- return m_buffer;
- };
- //Проверяет, является ли буфер линеаризованным.
- bool is_linearized() const
- {
- return (m_first_element == m_buffer);
- };
- //Сдвигает буфер так, что по нулевому индексу окажется элемент
- //с индексом new_begin.
- void rotate(int new_begin);
- //Количество элементов, хранящихся в буфере.
- int size() const
- {
- if (m_last_element >= m_first_element)
- {
- return (m_last_element - m_first_element + 1);
- }
- return ((m_last_element - m_buffer +1) + (m_buffer + m_capacity - m_first_element));
- };
- bool empty() const
- {
- return (m_first_element == NULL);
- };
- //true, если size() == capacity().
- bool full() const
- {
- if (m_first_element == m_buffer)
- {
- return (m_last_element == m_buffer + m_capacity);
- }
- return (m_first_element - 1 == m_last_element);
- };
- //Количество свободных ячеек в буфере.
- int reserve() const
- {
- return (m_capacity - size());
- };
- //ёмкость буфера
- int capacity() const
- {
- return m_capacity;
- };
- void set_capacity(int new_capacity);
- //Изменяет размер буфера.
- //В случае расширения, новые элементы заполняются элементом item.
- void resize(int new_size, const value_type & item = value_type());
- //Оператор присваивания.
- const CircularBuffer & operator=(const CircularBuffer & cb);
- //Обменивает содержимое буфера с буфером cb.
- void swap(CircularBuffer & cb);
- //Добавляет элемент в конец буфера.
- //Если текущий размер буфера равен его ёмкости, то переписывается
- //первый элемент буфера (т.е., буфер закольцован).
- void push_back(const value_type & item = value_type());
- //Добавляет новый элемент перед первым элементом буфера.
- //Аналогично push_back, может переписать последний элемент буфера.
- void push_front(const value_type & item = value_type());
- //удаляет последний элемент буфера.
- void pop_back();
- //удаляет первый элемент буфера.
- void pop_front();
- //Вставляет элемент item по индексу pos. Ёмкость буфера остается неизменной.
- void insert(int pos, const value_type & item = value_type());
- //Удаляет элементы из буфера в интервале [first, last).
- void erase(int first, int last);
- //Очищает буфер.
- void clear()
- {
- };
- };
- bool operator==(const CircularBuffer & a, const CircularBuffer & b);
- bool operator!=(const CircularBuffer & a, const CircularBuffer & b);
- int main()
- {
- return 0;
- }
- /*
- template <typename value_type>
- class RingBuffer
- {
- value_type* _buffer;
- int _length;
- public:
- RingBuffer(unsigned int length)
- {
- _buffer = new value_type[length]);
- _length = length;
- }
- ~RingBuffer()
- {
- delete _buffer;
- }
- };
- */
- /*
- #include "stdafx.h"
- #include "RingBuffer.h"
- int _tmain(int argc, _TCHAR* argv[])
- {
- RingBuffer<char> rb(100);
- return 0;
- }
- */
Add Comment
Please, Sign In to add comment