03 | 写一个能产生斐波那契数列的range——惰性求值
1.首先为了满足 range 概念的要求我们需要提供 begin() 和 end()
2.begin() 和 end() 返回的应该是迭代器,注意这个地方两种可以返回两种不同类型(c++17后即可)
3.为了满足迭代器 概念的要求我们提供5个 typedef,并根据 std::input_iterator_tag 类型决定我们要实现的“解引用函数”,“前后置++”,“比较函数”等。
本篇文章是使用 range 来实现序列生成,后面再使用协程来实现简单的序列生成器。
#include <stddef.h>
#include <iostream>
#include <ranges>
#include <stdint.h>
#include <concepts>
class fibonacci {
public:
class sentinel;
class iterator;
iterator begin() noexcept;
sentinel end() noexcept;
};
class fibonacci::sentinel {};
class fibonacci::iterator {
public:
// Required to satisfy iterator
// concept
typedef ptrdiff_t difference_type;
typedef uint64_t value_type;
typedef const uint64_t* pointer;
typedef const uint64_t& reference;
typedef std::input_iterator_tag iterator_category;
value_type operator*() const
{
return b_;
}
pointer operator->() const
{
return &b_;
}
iterator& operator++()
{
auto tmp = a_;
a_ = b_;
b_ += tmp;
return *this;
}
iterator operator++(int)
{
auto tmp = *this;
++*this;
return tmp;
}
bool operator==(const sentinel&) const
{
return false;
}
bool operator!=(const sentinel&) const
{
return true;
}
private:
uint64_t a_{0};
uint64_t b_{1};
};
// sentinel needs to be
// equality_comparable_with iterator
bool operator==(const fibonacci::sentinel& lhs,
const fibonacci::iterator& rhs)
{
return rhs == lhs;
}
bool operator!=(const fibonacci::sentinel& lhs,
const fibonacci::iterator& rhs)
{
return rhs != lhs;
}
inline fibonacci::iterator fibonacci::begin() noexcept
{
return iterator();
}
inline fibonacci::sentinel fibonacci::end() noexcept
{
return sentinel();
}
int main(){
// 打印头20项
for(auto i:fibonacci()|std::ranges::views::take(20)){
std::cout<<i<<std::endl;
}
// 打印小于 10000 的数列项
for(auto i:fibonacci()|
std::ranges::views::take_while([](uint64_t x){
return x<1000;
})){
std::cout<<i<<std::endl;
}
}