12bool is_parent_path(
const path& parent,
const path& child)
14 return child.parent_path() == parent;
17bool is_indirect_parent_path(
const path& parent,
const path& child)
19 path rel = child.lexically_relative(parent);
20 return !rel.empty() && rel.begin()->string() !=
"." && rel.begin()->string() !=
"..";
23bool begins_with(
const std::string& str,
const std::string& value)
26 if(str.length() < value.length())
30 if(str.empty() || value.empty())
36 auto s1 = str.substr(0, value.length());
38 return s1.compare(value) == 0;
40static std::string replace_seq(
const std::string& str,
const std::string& old_sequence,
const std::string& new_sequence)
43 std::string::size_type location = 0;
44 std::string::size_type old_length = old_sequence.length();
45 std::string::size_type new_length = new_sequence.length();
50 while(std::string::npos != (location = s.find(old_sequence, location)))
52 s.replace(location, old_length, new_sequence);
53 location += new_length;
56 if(location >= s.length())
68std::string to_lower(
const std::string& str)
71 std::transform(s.begin(), s.end(), s.begin(), tolower);
75template<
typename Container = std::
string,
typename CharT =
char,
typename Traits = std::
char_traits<
char>>
76auto read_stream_into_container(std::basic_istream<CharT, Traits>& in, Container& container) ->
bool
79 std::is_same<Container, std::basic_string<CharT, Traits, typename Container::allocator_type>>::value ||
80 std::is_same<Container, std::vector<CharT, typename Container::allocator_type>>::value ||
81 std::is_same<Container,
82 std::vector<std::make_unsigned_t<CharT>,
typename Container::allocator_type>>::value ||
83 std::is_same<Container, std::vector<std::make_signed_t<CharT>,
typename Container::allocator_type>>::value,
84 "only strings and vectors of ((un)signed) CharT allowed");
86 auto const start_pos = in.tellg();
87 if(std::streamsize(-1) == start_pos || !in.good())
92 if(!in.seekg(0, std::ios_base::end) || !in.good())
97 auto const end_pos = in.tellg();
99 if(std::streamsize(-1) == end_pos || !in.good())
104 auto const char_count = end_pos - start_pos;
106 if(!in.seekg(start_pos) || !in.good())
111 container.resize(
static_cast<std::size_t
>(char_count));
113 if(!container.empty())
115 in.read(
reinterpret_cast<CharT*
>(&container[0]), char_count);
116 container.resize(in.gcount());
119 return in.good() || in.eof();
127 static bool is_insensitive = []()
129 auto timestamp = fs::file_time_type::clock::now();
130 auto temp_path = fs::temp_directory_path();
132 auto salt = std::to_string(int64_t(timestamp.time_since_epoch().count())) + std::to_string(std::rand());
133 std::string temp_name_lower =
"_case_sensitivity_test_" + salt +
".txt";
134 std::string temp_name_upper =
"_CASE_SENSITIVITY_TEST_" + salt +
".txt";
136 auto file_lower = temp_path / temp_name_lower;
137 auto file_upper = temp_path / temp_name_upper;
144 bool result = fs::equivalent(file_upper, file_lower, ec);
145 fs::remove(file_lower, ec);
150 return is_insensitive;
217 static const std::string separator =
":/";
218 const auto string_path = _path.generic_string();
219 auto pos = string_path.find(separator, 0);
220 if(pos == std::string::npos)
225 const auto root = string_path.substr(0, pos);
227 fs::path relative_path = string_path.substr(pos + separator.size());
231 auto it = protocols.find(root);
233 if(it == std::end(protocols))
238 auto result = path(it->second);
239 if(!relative_path.empty())
241 result = result / relative_path.make_preferred();
248 static const std::string separator =
":/";
250 const auto string_path = _path.generic_string();
251 auto pos = string_path.find(separator, 0);
252 if(pos == std::string::npos)
257 const auto root = string_path.substr(0, pos);
262 return (protocols.find(root) != std::end(protocols));
267 const auto string_path = fs::path(_path).make_preferred().string();
271 const protocols_t::value_type* best_protocol{};
272 for(
const auto& protocol_pair : protocols)
275 const auto& resolved_protocol = protocol_pair.second;
277 if(detail::begins_with(string_path, resolved_protocol))
281 if(best_protocol->second.size() < resolved_protocol.size())
283 best_protocol = &protocol_pair;
288 best_protocol = &protocol_pair;
294 const auto& protocol = best_protocol->first;
295 const auto& resolved_protocol = best_protocol->second;
297 auto arg1 = path(string_path).generic_string();
298 auto arg2 = path(resolved_protocol).generic_string();
300 return replace(arg1, arg2, protocol +
":").generic_string();
path replace(const path &_path, const path &_sequence, const path &_new_sequence)
Replacing any occurences of the specified path sequence with another.