1 #ifndef UTILS_PATH_H_INCLUDED
2 #define UTILS_PATH_H_INCLUDED
14 extern std::ostream& operator<<(std::ostream& out,
const Path& path);
33 using difference_type = std::ptrdiff_t;
36 using iterator_category = std::forward_iterator_tag;
38 using node =
struct{ DIR* d;
struct dirent* e; };
40 using node =
struct{ HANDLE h; WIN32_FIND_DATA d; };
48 assert(path !=
nullptr);
51 if (m_path->is_file())
return *m_path;
53 return Path(m_node.e->d_name);
55 return Path(m_node.d.cFileName);
62 if (m_path->is_file()) {
66 m_node.e = readdir(m_node.d);
67 if (!m_node.e) closedir(m_node.d);
69 if (FindNextFile(m_node.h, &m_node.d) == 0) {
82 bool operator==(
const iterator& rhs)
const {
83 if (m_path != rhs.m_path)
return false;
84 if (!m_path || m_path->is_file())
return true;
86 return m_node.e == rhs.m_node.e;
88 return strcmp(m_node.d.cFileName, rhs.m_node.d.cFileName) == 0;
91 bool operator!=(
const iterator& rhs)
const {
92 return !operator==(rhs);
96 if (!m_path->exists()) {
98 }
else if (m_path->is_directory()) {
100 m_node.d = opendir(m_path->m_path.c_str());
101 m_node.e = readdir(m_node.d);
103 std::string pat = m_path->m_path +
"/*";
104 m_node.h = FindFirstFile(pat.c_str(), &m_node.d);
109 if (m_path->is_file() || !m_path->exists()) {
124 Path(
const std::string& path);
125 Path(
const char* p) :
Path(std::string(p)) {}
137 std::string
file_name(
bool extension =
true)
const;
140 bool empty()
const {
return is_empty(); }
141 bool is_empty()
const {
return m_path.empty(); }
142 bool is_file()
const;
143 bool is_directory()
const;
144 bool is_folder()
const {
return is_directory(); }
145 bool is_relative()
const {
return !is_absolute(); }
146 bool is_absolute()
const;
148 const std::string& to_string()
const {
return m_path; }
150 Path& operator=(
const char* p) { m_path = p;
return *
this; }
151 Path& operator=(
const std::string& p) {
return operator=(p.c_str()); }
152 bool operator==(
const char* p)
const;
153 bool operator==(
const Path& p)
const {
return *
this == p.m_path; }
154 bool operator==(
const std::string& p)
const {
return operator==(p.c_str()); }
155 bool operator!=(
const char* p)
const {
return !operator==(p); }
156 bool operator!=(
const Path& p)
const {
return !operator==(p); }
157 bool operator!=(
const std::string& p)
const {
return !operator==(p); }
159 bool operator<(
const Path& p)
const {
return resolve().to_string() < p.resolve().to_string(); }
160 bool operator<=(
const Path& p)
const {
return operator==(p) || operator<(p); }
162 Path operator+(
const char* p)
const;
163 Path& operator+=(
const char* p) {
return *
this = *
this + p; }
164 Path operator+(
const std::string& p)
const {
return operator+(p.c_str()); }
165 Path& operator+=(
const std::string& p) {
return operator+=(p.c_str()); }
166 Path operator+(
const Path& p)
const {
return operator+(p.m_path); }
167 Path& operator+=(
const Path& p) {
return operator+=(p.m_path); }
169 Path::iterator begin()
const;
170 Path::iterator end()
const;
176 struct hash<utils::Path> {
177 std::size_t operator()(
const utils::Path& path)
const {
178 return std::hash<std::string>()(path.
resolve().to_string());
183 #endif // UTILS_PATH_H_INCLUDED