OSDN Git Service

refactor
[winmerge-jp/winmerge-jp.git] / Src / DirItemIterator.h
1 /**
2  *  @file DirItemIterator.h
3  *
4  *  @brief Declaration DirItemIterator classes.
5  */ 
6
7 #pragma once
8
9 #include <iterator>
10 #include <utility>
11 #include "IListCtrl.h"
12
13 class DIFFITEM;
14
15 class DirItemWithIndexIterator : public std::iterator<std::forward_iterator_tag, std::pair<int, DIFFITEM *> >
16 {
17 public:
18         explicit DirItemWithIndexIterator(IListCtrl *pList, int sel = -1, bool selected = false, bool reverse = false) :
19           m_pList(pList), m_sel(sel), m_selected(selected), m_reverse(reverse)
20         {
21                 if (m_sel == -1)
22                 {
23                         if (m_reverse)
24                         {
25                                 int last = m_pList->GetRowCount() - 1;
26                                 if (!m_selected || m_pList->IsSelectedItem(last))
27                                         m_sel = last;
28                                 else
29                                         m_sel = m_pList->GetNextItem(last, m_selected, m_reverse);
30                         }
31                         else
32                                 m_sel = m_pList->GetNextItem(-1, m_selected, m_reverse);
33                 }
34                 if (m_sel != -1)
35                 {
36                         if (m_pList->GetItemData(m_sel) == reinterpret_cast<void *>((uintptr_t)-1L))
37                         {
38                                 if (m_reverse && m_sel == 0)
39                                         m_sel = -1;
40                                 else
41                                         m_sel = m_pList->GetNextItem(m_sel, m_selected, m_reverse);
42                         }
43                 }
44         }
45
46         DirItemWithIndexIterator() : m_pList(NULL), m_sel(-1), m_selected(false), m_reverse(false)
47         {
48         }
49
50         ~DirItemWithIndexIterator() = default;
51
52         DirItemWithIndexIterator& operator=(const DirItemWithIndexIterator& it)
53         {
54                 m_sel = it.m_sel;
55                 m_pList = it.m_pList;
56                 m_selected = it.m_selected;
57                 m_reverse = it.m_reverse;
58                 return *this;
59         }
60
61         DirItemWithIndexIterator& operator++()
62         {
63                 m_sel = m_pList->GetNextItem(m_sel, m_selected, m_reverse);
64                 return *this;
65         }
66
67         std::pair<int, DIFFITEM *> operator*()
68         {
69                 return std::make_pair(m_sel, reinterpret_cast<DIFFITEM *>(m_pList->GetItemData(m_sel)));
70         }
71
72         bool operator==(const DirItemWithIndexIterator& it) const
73         {
74                 return m_sel == it.m_sel;
75         }
76
77         bool operator!=(const DirItemWithIndexIterator& it) const
78         {
79                 return m_sel != it.m_sel;
80         }
81
82         bool m_selected;
83         bool m_reverse;
84         int m_sel;
85
86 private:
87         IListCtrl *m_pList;
88 };
89
90 class DirItemIterator : public std::iterator<std::forward_iterator_tag, DIFFITEM*>
91 {
92 public:
93         explicit DirItemIterator(IListCtrl *pList, int sel = -1, bool selected = false, bool reverse = false) : 
94           m_pList(pList), m_sel(sel), m_selected(selected), m_reverse(reverse), m_pdi(nullptr)
95         {
96                 if (m_sel == -1)
97                 {
98                         if (m_reverse)
99                         {
100                                 int last = m_pList->GetRowCount() - 1;
101                                 if (!m_selected || m_pList->IsSelectedItem(last))
102                                         m_sel = last;
103                                 else
104                                         m_sel = m_pList->GetNextItem(last, m_selected, m_reverse);
105                         }
106                         else
107                                 m_sel = m_pList->GetNextItem(-1, m_selected, m_reverse);
108                 }
109                 if (m_sel != -1)
110                 {
111                         m_pdi = reinterpret_cast<const DIFFITEM *>(m_pList->GetItemData(m_sel));
112                         if (m_pdi == reinterpret_cast<const DIFFITEM *>(-1L))
113                         {
114                                 if (m_reverse && m_sel == 0)
115                                         m_sel = -1;
116                                 else
117                                 {
118                                         m_sel = m_pList->GetNextItem(m_sel, m_selected, m_reverse);
119                                         m_pdi = reinterpret_cast<const DIFFITEM *>(m_pList->GetItemData(m_sel));
120                                 }
121                         }
122                         else if (m_pdi == nullptr)
123                         {
124                                 m_sel = -1;
125                         }
126                 }
127         }
128
129         DirItemIterator() : m_pList(nullptr), m_sel(-1), m_selected(false), m_reverse(false), m_pdi(nullptr)
130         {
131         }
132
133         ~DirItemIterator() = default;
134
135         DirItemIterator::DirItemIterator(const DirItemIterator& it)
136         {
137                 m_sel = it.m_sel;
138                 m_pList = it.m_pList;
139                 m_pdi = it.m_pdi;
140                 m_selected = it.m_selected;
141                 m_reverse = it.m_reverse;
142         }
143
144         DirItemIterator& operator=(const DirItemIterator& it)
145         {
146                 m_sel = it.m_sel;
147                 m_pList = it.m_pList;
148                 m_pdi = it.m_pdi;
149                 m_selected = it.m_selected;
150                 m_reverse = it.m_reverse;
151                 return *this;
152         }
153
154         DirItemIterator& operator++()
155         {
156                 if (m_reverse && m_sel <= 0)
157                 {
158                         m_sel = -1;
159                         m_pdi = reinterpret_cast<const DIFFITEM *>(-1L);
160                 }
161                 else
162                 {
163                         m_sel = m_pList->GetNextItem(m_sel, m_selected, m_reverse);
164                         m_pdi = reinterpret_cast<const DIFFITEM *>(m_pList->GetItemData(m_sel));
165                         if (m_pdi == reinterpret_cast<const DIFFITEM *>(-1L))
166                                 m_sel = -1;
167                 }
168                 return *this;
169         }
170
171         DIFFITEM& operator*()
172         {
173                 return *const_cast<DIFFITEM *>(m_pdi);
174         }
175
176         const DIFFITEM& operator*() const
177         {
178                 return *m_pdi;
179         }
180
181         bool operator==(const DirItemIterator& it) const
182         {
183                 return m_sel == it.m_sel;
184         }
185
186         bool operator!=(const DirItemIterator& it) const
187         {
188                 return m_sel != it.m_sel;
189         }
190
191         bool m_selected;
192         bool m_reverse;
193         int m_sel;
194         const DIFFITEM *m_pdi;
195
196 private:
197         IListCtrl *m_pList;
198 };