1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2013 - TortoiseGit
4 // Copyright (C) 2010-2011, 2014 - TortoiseSVN
6 // This program is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU General Public License
8 // as published by the Free Software Foundation; either version 2
9 // of the License, or (at your option) any later version.
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software Foundation,
18 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 * Implements a queue like container which avoids storing duplicates.
25 * If an entry is added that's already in the queue, it gets moved to
26 * the end of the queue.
29 * UniqueQueue<CString> myQueue;
30 * myQueue.Push(CString(L"one"));
31 * myQueue.Push(CString(L"two"));
32 * myQueue.Push(CString(L"one")); // "one" already exists, so moved to the end of the queue
33 * myQueue.Push(CString(L"three"));
34 * myQueue.Push(CString(L"three"));
36 * ATLASSERT(myQueue.Pop().Compare(L"two") == 0); // because "one" got moved
37 * ATLASSERT(myQueue.Pop().Compare(L"one") == 0);
38 * ATLASSERT(myQueue.Pop().Compare(L"three") == 0);
48 size_t Push(const T
&value
);
50 size_t erase(const T
&value
);
51 size_t size() const { return m_Queue
.size(); }
52 bool empty() { return m_Queue
.empty(); }
54 typedef struct UniqueQueueStruct
59 std::map
<T
, size_t> m_QueueTMap
;
60 std::deque
<UniqueQueueStruct
> m_Queue
;
61 size_t m_highestValue
;
65 UniqueQueue
<T
>::UniqueQueue()
71 UniqueQueue
<T
>::~UniqueQueue()
77 size_t UniqueQueue
<T
>::Push(const T
&value
)
79 std::map
<T
, size_t>::iterator it
= m_QueueTMap
.find(value
);
80 if (it
!= m_QueueTMap
.end())
82 // value is already in the queue: we don't allow duplicates
83 // so just move the existing value to the end of the queue
84 for (std::deque
<UniqueQueueStruct
>::iterator qIt
= m_Queue
.begin(); qIt
!= m_Queue
.end(); ++qIt
)
86 if (qIt
->priority
== it
->second
)
92 it
->second
= m_highestValue
;
94 s
.priority
= m_highestValue
++;
100 m_QueueTMap
.insert(it
, std::map
<T
, size_t>::value_type(value
, m_highestValue
));
102 s
.priority
= m_highestValue
++;
104 m_Queue
.push_back(s
);
105 if (m_highestValue
== 0)
107 // overflow of priority value
108 // recreate the whole queue from scratch
109 std::map
<T
, size_t> tempQueue
= m_QueueTMap
;
113 for (std::map
<T
, size_t>::const_iterator tempIt
= tempQueue
.begin(); tempIt
!= tempQueue
.end(); ++tempIt
)
115 m_QueueTMap
.insert(m_QueueTMap
.end(), std::map
<T
, size_t>::value_type(tempIt
->first
, m_highestValue
));
116 UniqueQueueStruct s2
;
117 s2
.priority
= m_highestValue
++;
118 s2
.value
= tempIt
->first
;
119 m_Queue
.push_back(s2
);
124 return m_Queue
.size();
128 T UniqueQueue
<T
>::Pop()
133 T value
= m_Queue
.front().value
;
135 m_QueueTMap
.erase(value
);
144 size_t UniqueQueue
<T
>::erase(const T
&value
)
146 std::map
<T
, size_t>::iterator it
= m_QueueTMap
.find(value
);
147 if (it
!= m_QueueTMap
.end())
149 for (std::deque
<UniqueQueueStruct
>::iterator qIt
= m_Queue
.begin(); qIt
!= m_Queue
.end(); ++qIt
)
151 if (qIt
->priority
== it
->second
)
157 m_QueueTMap
.erase(it
);
160 return m_QueueTMap
.size();