9namespace pixelbullet::filesystem
11[[nodiscard]]
inline std::filesystem::path normalized_path(
const std::filesystem::path& path)
13 std::filesystem::path normalized = path.lexically_normal();
14 while (!normalized.empty() && !normalized.has_filename())
16 const std::filesystem::path parent = normalized.parent_path();
17 if (parent.empty() || parent == normalized)
26[[nodiscard]]
inline std::string normalized_path_key(
const std::filesystem::path& path)
28 std::string key = normalized_path(path).generic_string();
30 for (
char& value : key)
32 value =
static_cast<char>(std::tolower(
static_cast<unsigned char>(value)));
38[[nodiscard]]
inline bool paths_equal(
const std::filesystem::path& lhs,
const std::filesystem::path& rhs)
40 return normalized_path_key(lhs) == normalized_path_key(rhs);
43[[nodiscard]]
inline bool path_is_within(
const std::filesystem::path& path,
const std::filesystem::path& directory)
45 if (path.empty() || directory.empty())
50 const std::filesystem::path normalized_target = normalized_path(path);
51 const std::filesystem::path normalized_directory = normalized_path(directory);
52 auto target_it = normalized_target.begin();
53 for (
auto directory_it = normalized_directory.begin(); directory_it != normalized_directory.end(); ++directory_it, ++target_it)
55 if (target_it == normalized_target.end() || normalized_path_key(*target_it) != normalized_path_key(*directory_it))
64inline void normalize_sort_unique_paths(std::vector<std::filesystem::path>& paths)
66 for (std::filesystem::path& path : paths)
68 path = normalized_path(path);
71 std::sort(paths.begin(), paths.end(),
72 [](
const std::filesystem::path& lhs,
const std::filesystem::path& rhs)
74 const std::string lhs_key = normalized_path_key(lhs);
75 const std::string rhs_key = normalized_path_key(rhs);
76 if (lhs_key != rhs_key)
78 return lhs_key < rhs_key;
80 return lhs.generic_string() < rhs.generic_string();
82 paths.erase(std::unique(paths.begin(), paths.end(),
83 [](
const std::filesystem::path& lhs,
const std::filesystem::path& rhs) { return paths_equal(lhs, rhs); }),