mirror of
https://github.com/facebook/sapling.git
synced 2024-10-06 06:47:41 +03:00
Introduce AbsolutePath.relativize().
Reviewed By: simpkins Differential Revision: D3842037 fbshipit-source-id: 1e1fa8be7883f88bf5819533db7b2359640fd525
This commit is contained in:
parent
9c79b74456
commit
28a6867d46
@ -8,9 +8,9 @@
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
#include <boost/operators.hpp>
|
||||
#include <folly/Hash.h>
|
||||
#include <folly/String.h>
|
||||
#include <boost/operators.hpp>
|
||||
#include <type_traits>
|
||||
|
||||
namespace facebook {
|
||||
@ -472,6 +472,13 @@ class ComposedPathIterator
|
||||
return piece();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a RelativePathPiece that corresponds to the characters in the path
|
||||
* "to the right of" the current iterator position. Note that this is true
|
||||
* whether this is a forward or reverse iterator.
|
||||
*/
|
||||
RelativePathPiece remainder() const;
|
||||
|
||||
/*
|
||||
* TODO: operator->() is not implemented
|
||||
*
|
||||
@ -849,6 +856,44 @@ class AbsolutePathBase : public ComposedPathBase<
|
||||
reverse_iterator{p, nullptr});
|
||||
}
|
||||
|
||||
/**
|
||||
* This must be equal to or an ancestor of the specified path.
|
||||
* If `this` is "/foo" and `child` is "/foo/bar/baz", then this returns
|
||||
* `RelativePathPiece("bar/baz")`. If `this` and `child` are equal, then this
|
||||
* returns `RelativePathPiece()`.
|
||||
*/
|
||||
RelativePathPiece relativize(AbsolutePath child) const {
|
||||
auto myPaths = this->paths();
|
||||
auto childPaths = child.paths();
|
||||
auto myIter = myPaths.begin();
|
||||
auto childIter = childPaths.begin();
|
||||
while (true) {
|
||||
if (childIter == childPaths.end()) {
|
||||
throw std::runtime_error(folly::to<std::string>(
|
||||
child.c_str(), " should be under ", this->stringPiece()));
|
||||
}
|
||||
|
||||
// Note that a RelativePath cannot contain "../" path elements.
|
||||
if (myIter.piece() != childIter.piece()) {
|
||||
throw std::runtime_error(folly::to<std::string>(
|
||||
this->stringPiece(),
|
||||
" does not seem to be a prefix of ",
|
||||
child.c_str()));
|
||||
}
|
||||
|
||||
myIter++;
|
||||
if (myIter != myPaths.end()) {
|
||||
childIter++;
|
||||
} else {
|
||||
// We do not want to increment childIter here or else we will be missing
|
||||
// a path component when we call remainder() after the while loop.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return childIter.remainder();
|
||||
}
|
||||
|
||||
/** Compose an AbsolutePath with a RelativePath */
|
||||
template <typename B>
|
||||
AbsolutePath operator+(const detail::RelativePathBase<B>& b) const {
|
||||
@ -994,8 +1039,21 @@ RelativePath operator+(
|
||||
return a + RelativePathPiece(b);
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
template <typename Piece, bool IsReverse>
|
||||
RelativePathPiece ComposedPathIterator<Piece, IsReverse>::remainder() const {
|
||||
CHECK_NOTNULL(pos_);
|
||||
if (pos_ < path_.end()) {
|
||||
return RelativePathPiece(
|
||||
folly::StringPiece(pos_ + 1, path_.end()),
|
||||
detail::SkipPathSanityCheck());
|
||||
} else {
|
||||
return RelativePathPiece();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} // facebook::eden
|
||||
|
||||
namespace std {
|
||||
/* Allow std::hash to operate on these types */
|
||||
|
@ -7,8 +7,8 @@
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*
|
||||
*/
|
||||
#include <gtest/gtest.h>
|
||||
#include <boost/functional/hash.hpp>
|
||||
#include <gtest/gtest.h>
|
||||
#include <sstream>
|
||||
#include "PathFuncs.h"
|
||||
|
||||
@ -289,6 +289,16 @@ TEST(PathFuncs, AbsolutePath) {
|
||||
auto comp4 = AbsolutePathPiece() + RelativePathPiece("foo");
|
||||
EXPECT_EQ("/foo", comp4.stringPiece());
|
||||
|
||||
AbsolutePath root("/");
|
||||
EXPECT_EQ(RelativePathPiece(), root.relativize(root));
|
||||
EXPECT_EQ(RelativePathPiece(), abs.relativize(abs));
|
||||
|
||||
EXPECT_EQ(
|
||||
RelativePathPiece("foo"), abs.relativize(abs + RelativePathPiece("foo")));
|
||||
EXPECT_EQ(
|
||||
RelativePathPiece("foo/bar"),
|
||||
abs.relativize(abs + RelativePathPiece("foo/bar")));
|
||||
|
||||
// auto bad = rel + abs; doesn't compile; invalid for ABS to be on RHS
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user