Circular Buffer 2

1.overwrite old element
2.not thread-safe
3.bitwise instead of modulo operation

#ifndef _CIRCULAR_BUFFER_H_2022_10_02
#define _CIRCULAR_BUFFER_H_2022_10_02
#include <vector>
#include<climits>
#include <iostream>

inline bool is_power_of_2(unsigned int v)
	{
		return v && (!(v & (v - 1)));
	}
	inline unsigned int roundup_pow_of_2(unsigned int v)
	{
		if (v == 0)
			return 0;
		unsigned int tmp = 1U;
		while (v >>= 1)
		{
			tmp <<= 1;
		}
		return tmp <<= 1;
	}
	template <typename Ty_>
	class CircularBuffer
	{
	public:
		explicit CircularBuffer(unsigned int max_size = 255)
		{
			//static_assert(!std::is_pointer<Ty_>::value, "not support pointers");
			if (max_size <= 0 || max_size >= (1U << (sizeof(max_size) * CHAR_BIT - 1)))
				max_size = 255;
			++max_size;  //one room for flagging full
			if (!is_power_of_2(max_size))
			{
				m_capacity = roundup_pow_of_2(max_size);
			}
			else
			{
				m_capacity = max_size;
			}
			m_buffer.resize(m_capacity);
		}

		bool empty() const
		{
			return m_read_index == m_write_index;
		}

		bool full() const
		{
			return ((m_write_index + 1) & (m_capacity - 1)) == (m_read_index & (m_capacity - 1));
		}

		void push_back(const Ty_& e)
		{
			m_buffer[m_write_index & (m_capacity - 1)] = e;
			if (full())
			{
				++m_read_index;
			}
			m_write_index++;
		}

		void push_back(Ty_&& e)
		{
			m_buffer[m_write_index & (m_capacity - 1)] = std::move(e);
			if (full())
			{
				++m_read_index;
			}
			m_write_index++;
		}

		void pop_front()
		{
			if (!empty()) ++m_read_index;
		}

		//UB if empty
		Ty_& front()
		{
			return at(0);
		}
		const Ty_& front() const
		{
			return at(0);
		}

		Ty_& at(unsigned int index)
		{
			if (index >= size()) throw std::invalid_argument("at out of range");

			index += m_read_index;
			index &= (m_capacity - 1);
			return m_buffer[index];
		}

		const Ty_& at(unsigned int index) const
		{
			if (index >= size()) throw std::invalid_argument("at out of range");

			index += m_read_index;
			index &= (m_capacity - 1);
			return m_buffer[index];
		}

		//std::shared_ptr<Ty_> front(unsigned int index) const
		//{
		//	return at(0);
		//}

		//std::shared_ptr<Ty_> at(unsigned int index) const
		//{
		//	if (index >= size()) return std::shared_ptr<Ty_>();

		//	index += m_read_index;
		//	index &= (m_capacity - 1);

		//	std::shared_ptr<Ty_> res(std::make_shared<Ty_>(m_buffer[index]));
		//	return res;
		//}

		unsigned int size() const
		{
			return m_write_index - m_read_index;
		}

		unsigned int capacity() const
		{
			return m_capacity;
		}

	private:
		std::vector<Ty_> m_buffer;
		unsigned int m_read_index{ 0 };
		unsigned int m_write_index{ 0 };
		unsigned int m_capacity{ 0 };
	};

	//test case

	template<typename Ty_>
	std::ostream& operator<<(std::ostream& out, CircularBuffer<Ty_>& cb)
	{
		unsigned int size = cb.size();
		if (0 == size)
		{
			out << "empty" << std::endl;
			return out;
		}

		unsigned int index = 0;
		while (index < size)
		{
			out << cb.at(index) << "  ";
			index++;
		}
		out << std::endl;
		return out;
	}

	void test_circular_buffer()
	{
		constexpr int max_size = 4;
		//not support, fail when compile
		//CircularBuffer<int*> cb_pointer;
		CircularBuffer<int> cb(max_size);
		std::cout << cb;
		cb.push_back(1);
		cb.push_back(2);
		cb.push_back(3);
		cb.push_back(4);
		std::cout << cb;
		cb.front() = 9;
		std::cout << cb;
		cb.push_back(5);
		cb.push_back(6);
		std::cout << cb;
		std::cout << cb;

		cb.pop_front();
		std::cout << cb;
		cb.pop_front();
		cb.pop_front();
		cb.pop_front();
		cb.pop_front();
		std::cout << cb;
		cb.pop_front();
		std::cout << cb;
	}
#endif
	
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值