Guest User

Untitled

a guest
Dec 18th, 2018
106
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.48 KB | None | 0 0
  1. #include <iostream>
  2. #include <exception>
  3. #include <stdexcept>
  4.  
  5. // Требования к value_type:
  6. // * Конструктор по умолчанию
  7. // * Оператор присваивания
  8.  
  9. template <typename value_type>
  10. class CircularBuffer
  11. {
  12. private:
  13.     static const int m_default_length = 27;
  14.     value_type * m_buffer;
  15.     value_type * m_first_element;
  16.     value_type * m_last_element;
  17.     unsigned int m_capacity;
  18.    
  19.     unsigned int get_real_index(unsigned int relative_index)
  20.     {
  21.                 return ((m_first_element - m_buffer + relative_index) % m_capacity);
  22.         };
  23.    
  24. public:
  25.     CircularBuffer()
  26.     {
  27.         m_capacity = m_default_length;
  28.         m_buffer = new value_type[m_default_length];
  29.         m_first_element = NULL;
  30.         m_last_element = NULL;
  31.     };
  32.    
  33.     ~CircularBuffer()
  34.     {
  35.         delete[] m_buffer;
  36.     };
  37.    
  38.     CircularBuffer(const CircularBuffer & cb)
  39.     {
  40.                 int i;
  41.                 int j;
  42.         m_capacity = cb.m_capacity;
  43.         m_buffer = new value_type[m_capacity];
  44.         if (!m_first_element)
  45.         {
  46.                         m_first_element = NULL;
  47.                         m_last_element = NULL;
  48.                         return;
  49.                 }
  50.                 m_first_element = m_buffer + cb.m_first_element - cb.m_buffer;
  51.         m_last_element = m_buffer + cb.m_last_element - cb.m_buffer;
  52.                 if (m_last_element > m_first_element)
  53.                 {
  54.                         i = m_first_element - m_buffer;
  55.                         j = m_last_element - m_buffer;
  56.                         for(; i <= j; ++i)
  57.                         {
  58.                                 m_buffer[i] = cb.m_buffer[i];
  59.                         }
  60.                         return;
  61.                 }
  62.                 if (m_last_element < m_first_element)
  63.                 {
  64.                         i = 0;
  65.                         j = m_last_element - m_buffer;
  66.                         for(; i <= j;  ++i)
  67.                         {
  68.                                 m_buffer[i] = cb.m_buffer[i];
  69.                         }
  70.                         i = m_first_element - m_buffer;
  71.                         j = m_capacity - 1;
  72.                         for(; i <= j;  ++i)
  73.                         {
  74.                                 m_buffer[i] = cb.m_buffer[i];
  75.                         }
  76.                         return;
  77.                 }
  78.                 m_buffer[m_first_element - m_buffer] = cb.m_buffer[m_first_element - m_buffer];
  79.     };
  80.  
  81. //Конструирует буфер заданной ёмкости.
  82.     explicit CircularBuffer(int capacity)
  83.     {
  84.         m_capacity = capacity;
  85.         m_buffer = new value_type[capacity];
  86.         m_first_element = NULL;
  87.         m_last_element = NULL;
  88.     };
  89.    
  90. //Конструирует буфер заданной ёмкости, целиком заполняет его элементом elem.
  91.     CircularBuffer(int capacity, const value_type & elem)
  92.     {
  93.         int i = 0;
  94.         m_capacity = capacity;
  95.         m_buffer = new value_type[m_capacity];
  96.         m_first_element = m_buffer;
  97.         for(; i < m_capacity; ++i)
  98.         {
  99.             m_buffer[i] = elem;
  100.         }
  101.         m_last_element = &(m_buffer[i-1]);
  102.     };
  103.  
  104. //Доступ по индексу. Не проверяют правильность индекса.
  105.     value_type & operator[](int i)
  106.     {
  107.                 return (m_buffer[get_real_index(i)]);
  108.     };
  109.     const value_type & operator[](int i) const
  110.     {
  111.                 return (m_buffer[get_real_index(i)]);
  112.     };
  113.  
  114. //Доступ по индексу. Методы бросают исключение в случае неверного индекса.
  115.     value_type & at(int i)
  116.     {
  117.         if (i < size())
  118.         {
  119.             return (m_buffer[get_real_index(i)]);
  120.         }
  121.         throw invalid_argument;
  122.     };
  123.     const value_type & at(int i) const
  124.     {
  125.         if (i < size())
  126.         {
  127.             return (m_buffer[get_real_index(i)]);
  128.         }
  129.         throw invalid_argument;
  130.     };
  131. //Ссылка на первый элемент.
  132.     value_type & front()
  133.     {
  134.         return *m_first_element;
  135.     };
  136.  
  137. //Ссылка на последний элемент.
  138.     value_type & back()
  139.     {
  140.         return *m_last_element;
  141.     };
  142.     const value_type & front() const
  143.     {
  144.         return *m_first_element;
  145.     };
  146.     const value_type & back() const
  147.     {
  148.         return *m_last_element;
  149.     };
  150.  
  151. //Линеаризация - сдвинуть кольцевой буфер так, что его первый элемент
  152. //переместится в начало аллоцированной памяти. Возвращает указатель
  153. //на первый элемент.
  154.     value_type * linearize()
  155.         {
  156.                 value_type tmp;
  157.                 value_type * p;
  158.                 value_type * p2;
  159.                 if (is_linearized())
  160.                 {
  161.                         return;
  162.                 }
  163.                 while (m_last_element < m_first_element)
  164.                 {
  165.                         tmp = m_buffer[0];
  166.                         p = &(m_buffer[0]);
  167.                         while (p < m_last_element)
  168.                         {
  169.                                 *(p) = *(p + 1);
  170.                                 ++p;
  171.                         }
  172.                         p = m_first_element;
  173.                         while (p < m_buffer + m_capacity - 1)
  174.                         {
  175.                                 *(p) = *(p + 1);
  176.                                 ++p;
  177.                         }
  178.                         *(p) = tmp;
  179.                 }
  180.                 p = m_buffer;
  181.                 p2 = m_first_element;
  182.                 while (m_last_element >= p2)
  183.                 {
  184.                         *p = *p2;
  185.                         ++p;
  186.                         ++p2;
  187.                 }
  188.                 return m_buffer;
  189.         };
  190. //Проверяет, является ли буфер линеаризованным.
  191.     bool is_linearized() const
  192.     {
  193.         return (m_first_element == m_buffer);
  194.     };
  195. //Сдвигает буфер так, что по нулевому индексу окажется элемент
  196. //с индексом new_begin.
  197.     void rotate(int new_begin);
  198. //Количество элементов, хранящихся в буфере.
  199.     int size() const
  200.         {
  201.                 if (m_last_element >= m_first_element)
  202.                 {
  203.                         return (m_last_element - m_first_element + 1);
  204.                 }
  205.                 return ((m_last_element - m_buffer +1) + (m_buffer + m_capacity - m_first_element));
  206.         };
  207.     bool empty() const
  208.     {
  209.         return (m_first_element == NULL);
  210.     };
  211. //true, если size() == capacity().
  212.     bool full() const
  213.     {
  214.         if (m_first_element == m_buffer)
  215.         {
  216.             return (m_last_element == m_buffer + m_capacity);
  217.         }
  218.         return (m_first_element - 1 == m_last_element);
  219.     };
  220. //Количество свободных ячеек в буфере.
  221.     int reserve() const
  222.         {
  223.                 return (m_capacity - size());
  224.         };
  225. //ёмкость буфера
  226.     int capacity() const
  227.         {
  228.                 return m_capacity;
  229.         };
  230.  
  231.     void set_capacity(int new_capacity);
  232. //Изменяет размер буфера.
  233. //В случае расширения, новые элементы заполняются элементом item.
  234.     void resize(int new_size, const value_type & item = value_type());
  235. //Оператор присваивания.
  236.     const CircularBuffer & operator=(const CircularBuffer & cb);
  237. //Обменивает содержимое буфера с буфером cb.
  238.     void swap(CircularBuffer & cb);
  239.  
  240. //Добавляет элемент в конец буфера.
  241. //Если текущий размер буфера равен его ёмкости, то переписывается
  242. //первый элемент буфера (т.е., буфер закольцован).
  243.     void push_back(const value_type & item = value_type());
  244. //Добавляет новый элемент перед первым элементом буфера.
  245. //Аналогично push_back, может переписать последний элемент буфера.
  246.     void push_front(const value_type & item = value_type());
  247. //удаляет последний элемент буфера.
  248.     void pop_back();
  249. //удаляет первый элемент буфера.
  250.     void pop_front();
  251.  
  252.     //Вставляет элемент item по индексу pos. Ёмкость буфера остается неизменной.
  253.     void insert(int pos, const value_type & item = value_type());
  254. //Удаляет элементы из буфера в интервале [first, last).
  255.     void erase(int first, int last);
  256. //Очищает буфер.
  257.     void clear()
  258.         {
  259.  
  260.         };
  261. };
  262.  
  263. bool operator==(const CircularBuffer & a, const CircularBuffer & b);
  264. bool operator!=(const CircularBuffer & a, const CircularBuffer & b);
  265.  
  266. int main()
  267. {
  268.     return 0;
  269. }
  270.  
  271.  
  272. /*
  273. template <typename value_type>
  274. class RingBuffer
  275. {
  276. value_type* _buffer;
  277. int _length;
  278.  
  279. public:
  280. RingBuffer(unsigned int length)
  281. {
  282. _buffer = new value_type[length]);
  283. _length = length;
  284. }
  285.  
  286. ~RingBuffer()
  287. {
  288. delete _buffer;
  289. }
  290. };
  291. */
  292. /*
  293. #include "stdafx.h"
  294. #include "RingBuffer.h"
  295.  
  296. int _tmain(int argc, _TCHAR* argv[])
  297. {
  298. RingBuffer<char> rb(100);
  299.  
  300. return 0;
  301. }
  302. */
Add Comment
Please, Sign In to add comment