尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
C++自定义可对称双向迭代器
#include cassert #include memory #include vector #include iostream class Range { public: using Index uint64_t; using SignedIndex int64_t; using Offset int64_t; using Size uint64_t; Range() default; template typename T Range(T start, T end) { if (!isValidRange(start, end)) { assert(false); return; } m_start start; m_end end; } Range(const Range other) default; bool isEmpty() const { return 0 size(); } bool isValid() const { return isValidRange(m_start, m_end); } bool isEqual(const Range other) const { return m_start other.m_start m_end other.m_end; } bool contains(SignedIndex pos) const { return pos 0 contains((Index)pos); } bool contains(Index pos) const { return m_start pos pos m_end; } bool contains(const Range other) const { return !other.isEmpty() m_start other.m_start other.m_end m_end; } Size size() const { return isValid() ? m_end - m_start : 0; } Index begin() const { return m_start; } Index start() const { return m_start; } Index end() const { return m_end; } Index last() const { return isEmpty() ? m_start : m_end - 1; } void setSize(Size newSize) { m_end m_start newSize; } bool operator(const Range other) const { return isEqual(other); } bool operator!(const Range other) const { return !isEqual(other); } friend std::ostream operator(std::ostream os, const Range range) { os [ range.m_start , range.m_end ); return os; } protected: template typename T static bool isValidRange(T start, T end) { return start 0 end start; } private: Index m_start 0; Index m_end 0; }; class BidiRange : public Range { public: BidiRange::BidiRange(const Range range, bool bForward) : Range(range), m_bForward(bForward) {} [[nodiscard]] bool BidiRange::isForward() const { return m_bForward; } private: bool m_bForward; }; template typename T class VisualIterator { public: using self T; using reference self; using pointer self*; constexpr explicit VisualIterator(T* ptr, size_t size) : m_node(ptr), m_size(size) {} constexpr reference operator*() const { return *m_node; } constexpr pointer operator-() const { return m_node; } constexpr virtual reference operator() 0; constexpr virtual pointer operator(int size) 0; constexpr virtual reference operator--() 0; constexpr virtual pointer operator--(int size) 0; [[nodiscard]] constexpr size_t size() const { return m_size; } constexpr size_t operator-(const VisualIteratorT other) const { return m_node - other.operator-(); } protected: pointer m_node; size_t m_size; }; template typename T using VisualIteratorSp typename std::shared_ptrVisualIteratorT; template typename T class ForwardVisualIterator : public VisualIteratorT { public: using reference typename VisualIteratorT::reference; using pointer typename VisualIteratorT::pointer; constexpr explicit ForwardVisualIterator(T* ptr, size_t size) : VisualIteratorT(ptr, size) {} constexpr reference operator() override { VisualIteratorT::m_node; return *VisualIteratorT::m_node; } constexpr pointer operator(int size) override { pointer tmp VisualIteratorT::m_node; tmp size; return tmp; } constexpr reference operator--() override { --VisualIteratorT::m_node; return *VisualIteratorT::m_node; } constexpr pointer operator--(int size) override { pointer tmp VisualIteratorT::m_node; tmp - size; return tmp; } }; template typename T class ReverseVisualIterator : public VisualIteratorT { public: using reference typename VisualIteratorT::reference; using pointer typename VisualIteratorT::pointer; constexpr explicit ReverseVisualIterator(T* ptr, size_t size) : VisualIteratorT(ptr, size) {} constexpr reference operator() override { --VisualIteratorT::m_node; return *VisualIteratorT::m_node; } constexpr pointer operator(int size) override { pointer tmp VisualIteratorT::m_node; tmp - size; return tmp; } constexpr reference operator--() override { VisualIteratorT::m_node; return *VisualIteratorT::m_node; } constexpr pointer operator--(int size) override { pointer tmp VisualIteratorT::m_node; tmp size; return tmp; } }; /* template typename T, template typename class VT VisualIteratorSpT makeVisualIterator(T *ptr, size_t size, bool bBegin) { assert(false); } */ template typename T VisualIteratorSpT makeVisualIteratorForward(T* ptr, size_t size, bool bBegin) { return std::make_sharedForwardVisualIteratorT((bBegin ? ptr : ptr size), size); } template typename T VisualIteratorSpT makeVisualIteratorBack(T* ptr, size_t size, bool bBegin) { return std::make_sharedReverseVisualIteratorT((bBegin ? ptr size - 1 : ptr - 1), size); } template typename T class BidiVisualIterator { public: using self T; using reference self; using pointer self*; using BaseVisualIter VisualIteratorSpT; constexpr explicit BidiVisualIterator(T* ptr, size_t size, bool dir, bool bBegin) : m_ltr(dir) , m_iter(dir ? makeVisualIteratorForwardT(ptr, size, bBegin) : makeVisualIteratorBackT(ptr, size, bBegin)) { } constexpr reference operator*() const { return m_iter-operator*(); } constexpr pointer operator-() const { return m_iter-operator-(); } constexpr reference operator() { return m_iter-operator(); } constexpr pointer operator(int size) { return m_iter-operator(size); } constexpr reference operator--() { return m_iter-operator--(); } constexpr pointer operator--(int size) { return m_iter-operator--(size); } constexpr bool operator(const BidiVisualIteratorT other) const { return m_ltr other.m_ltr operator-() other.operator-(); } constexpr bool operator!(const BidiVisualIteratorT other) const { return !operator(other); } constexpr size_t operator-(const BidiVisualIteratorT other) const { return (*m_iter).operator-() - other.operator-(); } [[nodiscard]] constexpr bool isForward() const { return m_ltr; } private: bool m_ltr; BaseVisualIter m_iter; }; /* 支持内部双向迭代器rbegin,begin,rend,end */ template typename T class BidiVisualSpan : public VisualIteratorT { public: using reference typename VisualIteratorT::reference; using pointer typename VisualIteratorT::pointer; using cpointer const typename VisualIteratorT::self*; using pointerRef typename VisualIteratorT::self*; constexpr explicit BidiVisualSpan(const T* ptr, const BidiRange range) : VisualIteratorT(const_castT*(ptr), range.size()) , m_bidiRange(range) { } constexpr BidiVisualIteratorT begin() const { return BidiVisualIteratorT(VisualIteratorT::operator-(), VisualIteratorT::size(), isForward(), true); } constexpr BidiVisualIteratorT end() const { return BidiVisualIteratorT(VisualIteratorT::operator-(), VisualIteratorT::size(), isForward(), false); } constexpr BidiVisualIteratorT rbegin() const { return BidiVisualIteratorT(VisualIteratorT::operator-(), VisualIteratorT::size(), !isForward(), true); } constexpr BidiVisualIteratorT rend() const { return BidiVisualIteratorT(VisualIteratorT::operator-(), VisualIteratorT::size(), !isForward(), false); } constexpr BidiVisualIteratorT last() const { BidiVisualIteratorT tmp this-end(); --tmp; return tmp; } constexpr pointer operator[](int i) const { BidiVisualIteratorT tmp this-begin(); auto newNode tmp.operator(i); return newNode; } constexpr reference operator() { VisualIteratorT* base this; return base- operator*(); } constexpr pointer operator(int) { VisualIteratorT* base this; return base- operator-(); } constexpr reference operator--() { VisualIteratorT* base this; return base- operator*(); } constexpr pointer operator--(int) { VisualIteratorT* base this; return base- operator-(); } [[nodiscard]] constexpr bool isForward() const { return m_bidiRange.isForward(); } [[nodiscard]] constexpr const BidiRange getBidiRange() const { return m_bidiRange; } constexpr cpointer inc(pointerRef data) const { return const_castT*(isForward() ? data : --data); } constexpr cpointer dec(pointerRef data) const { return const_castT*(isForward() ? --data : data); } constexpr BidiVisualIteratorT inc(const BidiVisualIteratorT data) const { auto tmp data; tmp; return tmp; } constexpr BidiVisualIteratorT dec(const BidiVisualIteratorT data) const { auto tmp data; --tmp; return tmp; } private: BidiRange m_bidiRange; }; /** * brief 双向迭代器测试 * return 支持正反序迭代 */ bool testVisualSpan() { std::vectorint vcts{ 0, 1, 2, 3, 4, 5 }; std::vectorint expectVct; // int * start vcts[0]; BidiVisualSpanint spanVisual(vcts[0], BidiRange(Range(0, 6), true)); for (auto item spanVisual.begin(); item ! spanVisual.end(); item) { // printf(%d\n, *item); expectVct.emplace_back(*item); } if (expectVct ! vcts) return false; expectVct.clear(); for (auto item : spanVisual) { // printf(%d\n, item); expectVct.emplace_back(item); } if (expectVct ! vcts) return false; expectVct.clear(); for (auto item spanVisual.rbegin(); item ! spanVisual.rend(); item) { // printf(%d\n, *item); expectVct.emplace_back(*item); } std::reverse(expectVct.begin(), expectVct.end()); if (expectVct ! vcts) return false; //////////////////////////////////////////////////////////////////// expectVct.clear(); BidiVisualSpanint spanRVisual(vcts[0], BidiRange(Range(0, 6), false)); if (spanRVisual.rend() ! spanVisual.end()) return false; // 支持双向同源迭代器 if (spanRVisual.rbegin() ! spanVisual.begin()) return false; // 支持双向同源迭代器 for (auto item spanRVisual.begin(); item ! spanRVisual.end(); item) { // printf(%d\n, *item); expectVct.emplace_back(*item); } std::reverse(expectVct.begin(), expectVct.end()); if (expectVct ! vcts) return false; expectVct.clear(); for (auto item : spanRVisual) { // printf(%d\n, item); expectVct.emplace_back(item); } std::reverse(expectVct.begin(), expectVct.end()); if (expectVct ! vcts) return false; expectVct.clear(); for (auto item spanRVisual.rbegin(); item ! spanRVisual.rend(); item) { // printf(%d\n, *item); expectVct.emplace_back(*item); } if (expectVct ! vcts) return false; return true; } void test() { std::cout (testVisualSpan() ? Test OK ! : Test Failed !) std::endl; // Test OK ! }对比参考std::bidirectional_iterator - cppreference.com创作不易小小的支持一下吧
RELATED

相关推荐

C++ 列式内存布局数据存储格式 Arrow

C++ 列式内存布局数据存储格式 Arrow

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📅 2026/11/2 1:12:16
C++ OPENGL 贝塞尔曲线绘制

C++ OPENGL 贝塞尔曲线绘制

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📅 2026/11/2 1:12:16
基于FPGA与STM32的LFM脉冲压缩雷达系统设计与实现

基于FPGA与STM32的LFM脉冲压缩雷达系统设计与实现

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📅 2026/11/2 1:07:16
MORE NEWS

更多资讯

📰

从数字化到数智化:关键技术栈与应用实践

1. 从数字化到数智化的时代跨越2003年我在某大型国企第一次接触ERP系统实施时,财务部的老会计盯着屏幕上的电子凭证直摇头:"这玩意儿能比我的账本靠谱?"二十年后的今天,当看到超市收银员用AI摄像头自动识别商品时&#…

📰

技术副业变现:从运维到云计算专家的转型之路

1. 副业转型的契机与背景2019年我还在某二线城市做着月薪5000的运维工作,每天重复着服务器监控和故障处理。直到某次在CSDN分享了一个Linux排查脚本,意外获得200收藏,评论区有人询问"能否有偿定制?"这个契机让我意识到&…

📰

从重复造轮子到搭积木式开发:活动系统架构演进实践

1. 从重复造轮子到搭积木式开发的演进历程十年前我刚入行时,参与的第一个项目就是活动系统开发。当时团队接到一个春节促销活动的需求,从数据库设计、接口开发到前端页面,全部从零开始搭建。整整三周时间,我们都在重复实现那些基础…

📰

表情包制作与使用全指南:从资源获取到版权防范

1. 表情包文化现象解析当代网络社交中,表情包已成为不可或缺的沟通元素。从早期的颜文字到如今的动态GIF,表情包经历了从简单符号到多元文化载体的演变过程。根据我的观察,2023年表情包使用量同比增长了37%,平均每个用户每天发送表…

📰

消息队列核心技术解析与性能优化实践

1. 消息队列的本质与核心价值消息队列(Message Queue)本质上是一种异步通信机制,它像是一条虚拟的传送带,连接着系统中不同的组件。我在2013年第一次接触ActiveMQ时,就被这种解耦思想深深吸引——生产者只管往队列里扔…

📰

c++实现的常见缓存算法和LRU

前言 缓存的核心矛盾是容量有限而数据无限:当新的键值对要进来而缓存已满时,必须挑一个旧条目淘汰。挑谁,就是缓存淘汰算法要回答的问题。FIFO 按进入时间淘汰,LRU 按最近使用时间淘汰,LFU 按使用频率淘汰,…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬