让基于范围的for循环支持自定义类型

点击查看代码
namespace detail_range
{
	template<typename T>
	class iterator
	{
	public:
		using value_type = T;
		using size_type = size_t;
		iterator(size_type cursor,value_type value,value_type step)
			:m_cursor{ cursor }, m_value{ value }, m_step{ step }
		{
			m_value += cursor * step;
		}
		value_type operator*()const
		{
			return m_value;
		}
		iterator& operator++()
		{
			m_value += m_step;
			m_cursor++;
			return *this;
		}
		bool operator!=(const iterator&other)
		{
			return this->m_cursor != other.m_cursor;
		}

	private:
		size_type m_cursor;
		value_type m_value;
		value_type m_step;
	};

	template<typename T>
	class impl
	{
	public:
		using value_type = T;
		using size_type = typename iterator<value_type>::size_type;
		using reference = const value_type&;
		using const_reference = const value_type&;
		using iterator = const detail_range::iterator<value_type>;
		using const_iterator = const detail_range::iterator<value_type>;
		impl(value_type begin,value_type end,value_type step)
			:m_beginValue{begin},m_endValue{end},m_step{step},m_maxCount{getMaxCount()}
		{

		}
		size_type getMaxCount()
		{
			if (m_step > 0 && m_beginValue >= m_endValue)
			{
				std::logic_error("beginValue must smaller than endValue!");
			}
			if (m_step < 0 && m_beginValue <= m_endValue)
			{
				std::logic_error("beginValue must bigger than endValue");
			}
			size_type count = static_cast<size_type>((m_endValue - m_beginValue) / m_step);
			if (m_beginValue + count * m_step != m_endValue)
			{
				count++;
			}
			return count;
		}
		size_type size()
		{
			return m_maxCount;
		}
		const_iterator begin()
		{
			return { 0,m_beginValue,m_step };
		}
		const_iterator end()
		{
			return { m_maxCount,m_beginValue,m_step };
		}

	private:
		value_type m_beginValue;
		value_type m_endValue;
		value_type m_step;
		size_type m_maxCount;
	};

	template<typename T>
	impl<T> range(T end)
	{
		return { {},end,1 };
	}

	template<typename T>
	impl<T> range(T begin, T end)
	{
		return { begin,end,1 };
	}

	template<typename T,typename U>
	auto range(T begin, T end, U step)
	{
// 		using impl_t = impl<decltype(begin + step)>;
// 		return impl_t( begin,end,step );
		return impl<decltype(begin + step)>(begin, end, step);
	}
}

用法示例:

点击查看代码
	for (auto i : detail_range::range(10,0,-0.5))
	{
		cout << i << "\t";
	}

输出结果:

posted @ 2021-09-09 14:39  youlj  阅读(56)  评论(0)    收藏  举报