#pragma once #include "Iterator.Base.tlh" //----------------------------------------------------------------------------- // Distinct_Iterator_Base // // 2019-3-13 : // 计算 m_Count 是对的. // 但是如果修改了 m_Count, 在 Satisfy () 函数执行过程中, 很容易出错. // 因为 Iter 的迭代是基于原始迭代器 - std::iterator 的, // m_Index 的变更是基于原始迭代器的, // 因此要求 m_Count 与 原始迭代器的数量相符 // 如果修改了 m_Count, 在迭代未结束时, m_Count 将小于 m_Index // 导致迭代提前结束了 //----------------------------------------------------------------------------- namespace Iterator { template class Distinct_Iterator_Base : public ForIterator { typedef ForIterator inherited; public: using value_type = typename ForIterator::value_type; using data_type = typename ForIterator::data_type; using deref_type = value_type; public: Distinct_Iterator_Base () = delete; Distinct_Iterator_Base (inherited & Iter) : inherited (Iter) { } Distinct_Iterator_Base (const Distinct_Iterator_Base & from) : inherited (from) { m_arDup = from.m_arDup; m_BeginOfDup = m_arDup.cbegin (); m_EndOfDup = m_arDup.cend (); } Distinct_Iterator_Base (Distinct_Iterator_Base && from) : inherited (from) { m_arDup.swap (from.m_arDup); m_BeginOfDup = m_arDup.cbegin (); m_EndOfDup = m_arDup.cend (); } public: inline virtual void Next () override { if (! IsEmpty ()) { inherited::Next (); Satisfy (); } } protected: virtual void FindDup () = 0; protected: void Satisfy () { if (inherited::IsEmpty ()) return; if (m_arDup.empty ()) return; for (;! IsEmpty (); inherited::Next ()) { auto it = std::find (m_BeginOfDup, m_EndOfDup, inherited::stdCurrent ()); if (it == m_EndOfDup) return; } } protected: using dup_type = std::vector ; typename dup_type m_arDup; typename dup_type::const_iterator m_BeginOfDup; typename dup_type::const_iterator m_EndOfDup; }; }; //----------------------------------------------------------------------------- // Distinct_Iterator //----------------------------------------------------------------------------- namespace Iterator { template class Distinct_Iterator : public Distinct_Iterator_Base { typedef Distinct_Iterator_Base inherited; // typedef ForIterator inherited; public: Distinct_Iterator () = delete; Distinct_Iterator (ForIterator & Iter) : inherited (Iter) { FindDup (); } Distinct_Iterator (const Distinct_Iterator & from) : inherited (from) { } Distinct_Iterator (Distinct_Iterator && from) : inherited (from) { } protected: virtual void FindDup () override { if (IsEmpty ()) return; ForIterator findIter = *this; typename dup_type arDup; for (; ! findIter.IsEmpty (); findIter.Next ()) { auto & v0 = findIter.Current (); auto tmpIter = findIter; tmpIter ++; for (; ! tmpIter.IsEmpty (); tmpIter++) { if (v0 != tmpIter.Current ()) continue; auto it = std::find (arDup.cbegin (), arDup.cend (), tmpIter.stdCurrent ()); if (it != arDup.cend ()) continue; TRACE ("\r\nfindIter.Index : %3d, tmpIter.Index : %3d ", findIter.Index (), tmpIter.Index ()); arDup.push_back (tmpIter.stdCurrent ()); } } TRACE ("\r\n------ END --------"); m_arDup.swap (arDup); m_BeginOfDup = m_arDup.cbegin (); m_EndOfDup = m_arDup.cend (); // m_Count -= (int) m_arDup.size (); } }; }; //----------------------------------------------------------------------------- // Distinct_Iterator //----------------------------------------------------------------------------- namespace Iterator { template class Distinct_Iterator2 : public Distinct_Iterator_Base { typedef Distinct_Iterator_Base inherited; // typedef ForIterator inherited; public: Distinct_Iterator2 () = delete; Distinct_Iterator2 (const Predicate & f, ForIterator & Iter) : m_predicate (f), inherited (Iter) { FindDup (); } Distinct_Iterator2 (const Distinct_Iterator2 & from) : m_predicate (from.m_predicate), inherited (from) { } Distinct_Iterator2 (Distinct_Iterator2 && from) : m_predicate (from.m_predicate), inherited (from) { } protected: virtual void FindDup () override { if (IsEmpty ()) return; ForIterator findIter = *this; typename dup_type arDup; for (; ! findIter.IsEmpty (); findIter.Next ()) { auto & v0 = findIter.Current (); auto tmpIter = findIter; tmpIter ++; for (; ! tmpIter.IsEmpty (); tmpIter++) { // if (v0 != value) if (! m_predicate (v0, tmpIter.Current ())) continue; auto it = std::find (arDup.cbegin (), arDup.cend (), tmpIter.stdCurrent ()); if (it != arDup.cend ()) continue; TRACE ("\r\nfindIter.Index : %3d, tmpIter.Index : %3d ", findIter.Index (), tmpIter.Index ()); arDup.push_back (tmpIter.stdCurrent ()); } } TRACE ("\r\n------ END --------"); m_arDup.swap (arDup); m_BeginOfDup = m_arDup.cbegin (); m_EndOfDup = m_arDup.cend (); // m_Count -= (int) m_arDup.size (); } private: Predicate m_predicate; }; };