16 return !name.
empty() && name.path[0] ==
'.';
20 return !path.empty() && path[0] == SEPARATOR;
28 return path.size() == 1 && path[0] ==
'/';
36 std::size_t n = path.rfind(SEPARATOR);
37 if (n == std::string::npos) {
40 if (n == path.size() - 1) {
42 return Path(path.substr(0, n)).parentPath();
44 return Path(path.substr(0, n + 1));
48 std::size_t n = path.rfind(SEPARATOR);
49 if (n == std::string::npos) {
52 }
else if (n == path.size() - 1) {
54 return Path(path.substr(0, path.size() - 1)).fileName();
56 return Path(path.substr(n + 1));
61 if (name.path.size() <= 1) {
64 const std::size_t n = name.path.find_last_of(
'.');
65 if (n == 0 || n == std::string::npos) {
68 return Path(name.path.substr(n + 1));
78 if (name.
empty() || name.path ==
"." || name.path ==
"..") {
82 const std::size_t n = name.path.find_last_of(
'.');
83 if (n == 0 || n == std::string::npos) {
85 if (!newExtension.empty()) {
86 path +=
"." + newExtension;
90 const std::size_t indexInPath = path.size() - name.path.size() + n;
91 if (!newExtension.empty()) {
92 path.replace(indexInPath + 1, std::string::npos, newExtension);
94 path = path.substr(0, indexInPath);
102 if (name.
empty() || name.path ==
"." || name.path ==
"..") {
105 const std::size_t n = name.path.find_last_of(
'.');
106 if (n == 0 || n == std::string::npos) {
110 path = path.substr(0, path.size() - name.path.size() + n);
117 while ((n = this->findFolder(
"..")) != std::string::npos) {
120 *
this = parent / tail;
122 while ((n = this->findFolder(
".")) != std::string::npos) {
123 Path parent =
Path(path.substr(0, n));
125 *
this = parent / tail;
147 const std::size_t m = wd.path.find(SEPARATOR, n);
148 if (m == std::string::npos || wd.path.substr(0, m) != path.substr(0, m)) {
154 const Path sharedPath(path.substr(0, n));
157 while (wd.path.substr(0, n + 1) != sharedPath.path) {
159 newPath /=
Path(
"..");
162 newPath /=
Path(path.substr(n));
163 return *
this = std::move(newPath);
167 constexpr
Size bufferCnt = 1024;
168 char buffer[bufferCnt];
169 if (getcwd(buffer,
sizeof(buffer))) {
170 std::string path(buffer);
171 return Path(path + SEPARATOR);
179 return Path(other.path);
180 }
else if (other.path.empty()) {
183 return Path(path +
"/" + other.path);
188 *
this = *
this / other;
193 return path == other.path;
197 return path != other.path;
201 return path < other.path;
209 void Path::convert() {
210 for (
char& c : path) {
211 if (c ==
'\\' || c ==
'/') {
215 std::string duplicates = { SEPARATOR, SEPARATOR };
217 while ((n = path.find(duplicates)) != std::string::npos) {
218 path.replace(n, 2, 1, SEPARATOR);
222 std::size_t Path::findFolder(
const std::string& folder) {
223 if (path == folder || path.substr(0,
std::min(path.size(), folder.size() + 1)) == folder + SEPARATOR) {
226 const size_t n = path.find(SEPARATOR + folder + SEPARATOR);
227 if (n != std::string::npos) {
230 if (path.substr(
std::max(0,
int(path.size()) -
int(folder.size()) - 1)) == SEPARATOR + folder) {
231 return path.size() - folder.size();
233 return std::string::npos;
236 Path operator"" _path(
const char* nativePath,
const std::size_t size) {
238 return Path(nativePath);
#define SPH_ASSERT(x,...)
uint32_t Size
Integral type used to index arrays (by default).
constexpr INLINE T max(const T &f1, const T &f2)
NAMESPACE_SPH_BEGIN constexpr INLINE T min(const T &f1, const T &f2)
Minimum & Maximum value.
#define NAMESPACE_SPH_END
std::ostream & operator<<(std::ostream &stream, const Path &path)
Object representing a path on a filesystem, similar to std::filesystem::path in c++17.
Object representing a path on a filesystem.
bool isRelative() const
Checks if the path is relative. Empty path is not considered relative.
Path operator/(const Path &other) const
Appends two paths together.
static Path currentPath()
Returns the current working directory, or empty path if the function failed.
Path & replaceExtension(const std::string &newExtension)
Changes the extension of the file.
Path & removeExtension()
Removes the extension from the path.
std::string native() const
Returns the native version of the path.
bool operator<(const Path &other) const
Does lexicographical comparison of two paths.
bool isRoot() const
Checks if the object holds root path.
Path & makeAbsolute()
Turns the path into an absolute path.
Path()=default
Constructs an empty path.
Path & removeSpecialDirs()
Removes . and .. directories from the path.
bool isHidden() const
Checks if the file is hidden, i.e. starts with a dot (makes only sense on Unit based systems).
bool empty() const
Checks if the path is empty.
Path & operator/=(const Path &other)
Appends another path to this one.
Path fileName() const
Returns the filename of the path.
Path parentPath() const
Returns the parent directory. If the path is empty or root, return empty path.
Path extension() const
Returns the extension of the filename.
bool operator==(const Path &other) const
Checks if two objects represent the same path.
bool hasExtension() const
Checks if the file has an extension.
bool operator!=(const Path &other) const
Checks if two objects represent different paths.
Path & makeRelative()
Turns the path into a relative path.