-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdirectory_iterator.h
188 lines (150 loc) · 4.47 KB
/
directory_iterator.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
// directory_iterator.h standart header - by jannik voss
/*
HEADER FILE INFORMATION:
source: no source file needed
class:
directory_iterator
*/
#pragma once
#include <string>
#include <memory>
#include <Windows.h>
namespace filesys{
/*
TEMPLATE CLASS directory_iterator
PLATFORM: Windows (filesystem: wchar_t)
iterate through all files in a directory
-> notice: the current version of the directory_iterator does not support backward iteration
-> usage: for(auto it=directory_iterator(L"C:/"); it != directory_iterator(); ++it)
std::wcout << it->c_str() << std::endl;
-> TODO: functions: 'equals()' and 'swap()'; optimize the comparison operator
*/
// TEMPLATE CLASS Basic_directory_iterator
template<class T>
class Basic_directory_iterator
{
public:
typedef std::input_iterator_tag iterator_category;
typedef T value_type;
typedef std::ptrdiff_t difference_type;
typedef value_type* pointer;
typedef value_type& reference;
typedef const value_type* const_pointer;
typedef const value_type& const_reference;
typedef typename value_type::size_type size_type;
//static Basic_directory_iterator end()
// { // get end-iterator
// return Basic_directory_iterator();
// }
~Basic_directory_iterator()
{ // destruct
Clear();
}
Basic_directory_iterator()
: MyFind_data()
, MyHfile()
, MyCurrent()
{ // end-iterator
}
Basic_directory_iterator(const Basic_directory_iterator& o)
: MyFind_data(o.MyFind_data)
, MyHfile(o.MyHfile)
, MyCurrent(o.MyCurrent)
{
}
Basic_directory_iterator(Basic_directory_iterator&& o)
: MyFind_data(o.MyFind_data)
, MyHfile(o.MyHfile)
, MyCurrent(o.MyCurrent)
{
o.clear();
}
Basic_directory_iterator(const value_type& p)
: MyFind_data()
, MyHfile( FindFirstFile( (p+L"*").c_str() , &MyFind_data ), &FindClose )
, MyCurrent(value_type(MyHfile.get() != INVALID_HANDLE_VALUE? MyFind_data.cFileName: TEXT("") ))
{ // construct from specified value
}
Basic_directory_iterator& operator ++ ()
{ // pre-increment
Forward();
return (*this);
}
Basic_directory_iterator operator ++(int)
{ // increment
Basic_directory_iterator tmp = *this;
Forward();
return tmp;
}
Basic_directory_iterator& operator += (/*int*/ size_type num)
{ // step Forward
std::advance(*this, num);
return (*this);
}
Basic_directory_iterator operator + (int num) const
{ // step Forward
Basic_directory_iterator tmp = *this;
return (tmp += num);
}
#if defined (_MSC_VER) && (_MSC_VER < 1300)
#pragma warning(disable:4284) // infix notation problem when using iterator operator ->
#endif
const value_type& operator * () const
{ // reference to the current filepath
return (MyCurrent);
}
const value_type* operator ->() const
{ // pointer to the current filepath
return (&MyCurrent);
}
value_type get() const
{ // copy the current filepath
return (MyCurrent);
}
void swap(Basic_directory_iterator& o)
{ // exchange internals
std::swap(MyFind_data, o.MyFind_data);
std::swap(MyHfile, o.MyHfile);
std::swap(MyCurrent, o.MyCurrent);
}
bool equals(const Basic_directory_iterator& o) const
{ // test for equality
return (MyCurrent == o.MyCurrent); // unsafe (two different iterators pointing to one file)
}
private:
void Forward()
{ // step Forward to the next file
if(FindNextFile(MyHfile.get(), &MyFind_data))
MyCurrent.assign(value_type(MyFind_data.cFileName));
else
MyCurrent.clear();
}
void Clear()
{ // make end-iterator
MyFind_data = WIN32_FIND_DATA();
MyHfile = shared_handle();
MyCurrent.clear();
}
typedef std::shared_ptr< std::remove_pointer< HANDLE >::type > shared_handle;
WIN32_FIND_DATA MyFind_data;
shared_handle MyHfile;
value_type MyCurrent; // MyCurrent filepath
};
template<class T>
bool operator == (const Basic_directory_iterator<T>& l, const Basic_directory_iterator<T>& r)
{ // test for equality
return (l.equals(r));
}
template<class T>
bool operator != (const Basic_directory_iterator<T>& l, const Basic_directory_iterator<T>& r)
{ // test for inequality
return !(l == r);
}
template<class T>
void swap(Basic_directory_iterator<T>& l, Basic_directory_iterator<T>& r)
{ // exchange internals
l.swap(r);
}
typedef Basic_directory_iterator<std::basic_string<wchar_t>>
directory_iterator;
};//end: namespace