I converted the C# code that @Armali posted to C++:
#include <vector>
#include <string>
#include <algorithm>
std::vector<std::string> str_split(const std::string& in, const std::string& delim=" \t\r\n") {
std::vector<std::string> out;
auto firstPos = in.find_first_not_of(delim);
auto secondPos = in.find_first_of(delim, firstPos);
out.clear();
if(firstPos != std::string::npos)
{ out.push_back( in.substr( firstPos, secondPos - firstPos ) ); }
while( secondPos != std::string::npos ) {
firstPos = in.find_first_not_of(delim, secondPos);
if(firstPos == std::string::npos)
{ break; }
secondPos = in.find_first_of( delim, firstPos );
out.push_back( in.substr( firstPos, secondPos - firstPos ) );
}
return out;
}
int str_compare_no_case(std::string a, std::string b) {
std::transform(a.begin(), a.end(), a.begin(), ::tolower);
std::transform(b.begin(), b.end(), b.begin(), ::tolower);
return a.compare(b);
}
static std::string MakeRelativePath(std::string absPath, std::string relTo) {
#ifdef _WIN32
const char directorySeparator = '\\';
#else
const char directorySeparator = '/';
#endif
std::string DirectorySeparatorChars = {directorySeparator, '\0'};
auto absParts = str_split(absPath, DirectorySeparatorChars);
auto relParts = str_split(relTo, DirectorySeparatorChars);
// Get the shortest of the two paths
size_t len = std::min(absParts.size(), relParts.size());
// Use to determine where in the loop we exited
int lastCommonRoot = -1;
int index;
// Find common root
for (size_t index = 0; index < len; index++) {
if (str_compare_no_case(absParts[index], relParts[index])==0) {
lastCommonRoot = index;
} else {
break;
}
}
// If we didn't find a common prefix "c:\xx", "D:\"
if (lastCommonRoot == -1) {
// The path of the two files doesn't have any common base.
return absPath;
}
// Build up the relative path
std::string relativePath;
// Add on the ..
for (size_t index = lastCommonRoot + 1; index < relParts.size(); index++) {
relativePath += "..";
relativePath += directorySeparator;
}
// Add on the folders
for (size_t index = lastCommonRoot + 1; index+1 < absParts.size(); index++) {
relativePath += absParts[index];
relativePath += directorySeparator;
}
if(!absParts.empty()) {
relativePath += absParts[absParts.size() - 1];
}
return relativePath;
}