diff options
-rw-r--r-- | libbutl/path.mxx | 6 | ||||
-rw-r--r-- | libbutl/path.txx | 16 |
2 files changed, 19 insertions, 3 deletions
diff --git a/libbutl/path.mxx b/libbutl/path.mxx index 12479ce..5a41ddc 100644 --- a/libbutl/path.mxx +++ b/libbutl/path.mxx @@ -952,6 +952,12 @@ LIBBUTL_MODEXPORT namespace butl basic_path relative (basic_path) const; + // As above but return nullopt rather than throw if a relative path cannot + // be derived. + // + optional<basic_path> + try_relative (basic_path) const; + // Iteration over path components. // // Note that for an absolute POSIX path the first component is empty, diff --git a/libbutl/path.txx b/libbutl/path.txx index 45b62bd..84fc038 100644 --- a/libbutl/path.txx +++ b/libbutl/path.txx @@ -103,8 +103,8 @@ LIBBUTL_MODEXPORT namespace butl //@@ MOD Clang needs this for some reason. #endif template <typename C, typename K> - basic_path<C, K> basic_path<C, K>:: - relative (basic_path<C, K> d) const + optional<basic_path<C, K>> basic_path<C, K>:: + try_relative (basic_path<C, K> d) const { dir_type r; @@ -118,12 +118,22 @@ LIBBUTL_MODEXPORT namespace butl //@@ MOD Clang needs this for some reason. // Roots of the paths do not match. // if (d.root ()) - throw invalid_basic_path<C> (this->path_); + return nullopt; } return r / leaf (d); } + template <typename C, typename K> + basic_path<C, K> basic_path<C, K>:: + relative (basic_path<C, K> d) const + { + if (optional<basic_path<C, K>> r = try_relative (std::move (d))) + return std::move (*r); + + throw invalid_basic_path<C> (this->path_); + } + #ifdef _WIN32 // Find the actual spelling of a name in the specified dir. If the name is // found, append it to the result and return true. Otherwise, return false. |