summaryrefslogtreecommitdiffstats
path: root/libcxx/include/experimental
diff options
context:
space:
mode:
authorEric Fiselier <eric@efcs.ca>2018-04-02 23:03:41 +0000
committerEric Fiselier <eric@efcs.ca>2018-04-02 23:03:41 +0000
commitd7fae181c3954886257fb33d0a57b954b26da745 (patch)
tree841df55a810bc7446cf7afdd6811b3f1d79a3fc8 /libcxx/include/experimental
parent298ffc609bf5c67079dbeb77e3f75e5bc18fde7a (diff)
downloadbcm5719-llvm-d7fae181c3954886257fb33d0a57b954b26da745.tar.gz
bcm5719-llvm-d7fae181c3954886257fb33d0a57b954b26da745.zip
Implement filesystem NB comments, relative paths, and related issues.
This is a fairly large patch that implements all of the filesystem NB comments and the relative paths changes (ex. adding weakly_canonical). These issues and papers are all interrelated so their implementation couldn't be split up nicely. This patch upgrades <experimental/filesystem> to match the C++17 spec and not the published experimental TS spec. Some of the changes in this patch are both API and ABI breaking, however libc++ makes no guarantee about stability for experimental implementations. The major changes in this patch are: * Implement NB comments for filesystem (P0492R2), including: * Implement `perm_options` enum as part of NB comments, and update the `permissions` function to match. * Implement changes to `remove_filename` and `replace_filename` * Implement changes to `path::stem()` and `path::extension()` which support splitting examples like `.profile`. * Change path iteration to return an empty path instead of '.' for trailing separators. * Change `operator/=` to handle absolute paths on the RHS. * Change `absolute` to no longer accept a current path argument. * Implement relative paths according to NB comments (P0219r1) * Combine `path.cpp` and `operations.cpp` since some path functions require access to the operations internals, and some fs operations require access to the path parser. llvm-svn: 329028
Diffstat (limited to 'libcxx/include/experimental')
-rw-r--r--libcxx/include/experimental/filesystem168
1 files changed, 122 insertions, 46 deletions
diff --git a/libcxx/include/experimental/filesystem b/libcxx/include/experimental/filesystem
index 47cc0c5aa70..411b98121f0 100644
--- a/libcxx/include/experimental/filesystem
+++ b/libcxx/include/experimental/filesystem
@@ -76,11 +76,11 @@
// operational functions
- path absolute(const path& p, const path& base=current_path());
+ path absolute(const path& p);
+ path absolute(const path& p, error_code &ec);
- path canonical(const path& p, const path& base = current_path());
+ path canonical(const path& p);
path canonical(const path& p, error_code& ec);
- path canonical(const path& p, const path& base, error_code& ec);
void copy(const path& from, const path& to);
void copy(const path& from, const path& to, error_code& ec);
@@ -185,9 +185,17 @@
void permissions(const path& p, perms prms, perm_options opts,
error_code& ec);
+ path proximate(const path& p, error_code& ec);
+ path proximate(const path& p, const path& base = current_path());
+ path proximate(const path& p, const path& base, error_code &ec);
+
path read_symlink(const path& p);
path read_symlink(const path& p, error_code& ec);
+ path relative(const path& p, error_code& ec);
+ path relative(const path& p, const path& base=current_path());
+ path relative(const path& p, const path& base, error_code& ec);
+
bool remove(const path& p);
bool remove(const path& p, error_code& ec) _NOEXCEPT;
@@ -211,12 +219,13 @@
file_status symlink_status(const path& p);
file_status symlink_status(const path& p, error_code& ec) _NOEXCEPT;
- path system_complete(const path& p);
- path system_complete(const path& p, error_code& ec);
-
path temp_directory_path();
path temp_directory_path(error_code& ec);
+ path weakly_canonical(path const& p);
+ path weakly_canonical(path const& p, error_code& ec);
+
+
} } } } // namespaces std::experimental::filesystem::v1
*/
@@ -796,26 +805,26 @@ public:
private:
template <class _ECharT>
- void __append_sep_if_needed(_ECharT __first_or_null) {
- const _ECharT __null_val = {};
- bool __append_sep = !empty() &&
- !__is_separator(__pn_.back()) &&
- __first_or_null != __null_val && // non-empty
- !__is_separator(__first_or_null);
- if (__append_sep)
- __pn_ += preferred_separator;
+ static bool __source_is_absolute(_ECharT __first_or_null) {
+ return __is_separator(__first_or_null);
}
public:
// appends
path& operator/=(const path& __p) {
- _LIBCPP_ASSERT(!__p.has_root_name(),
- "cannot append to a path with a root name");
- __append_sep_if_needed(__p.empty() ? char{} : __p.__pn_[0]);
+ if (__p.is_absolute()) {
+ __pn_ = __p.__pn_;
+ return *this;
+ }
+ if (has_filename())
+ __pn_ += preferred_separator;
__pn_ += __p.native();
return *this;
}
+ // FIXME: Use _LIBCPP_DIAGNOSE_WARNING to produce a diagnostic when __src
+ // is known at compile time to be "/' since the user almost certainly intended
+ // to append a separator instead of overwriting the path with "/"
template <class _Source>
_LIBCPP_INLINE_VISIBILITY
_EnableIfPathable<_Source>
@@ -828,7 +837,10 @@ public:
append(const _Source& __src) {
using _Traits = __is_pathable<_Source>;
using _CVT = _PathCVT<_SourceChar<_Source>>;
- __append_sep_if_needed(_Traits::__first_or_null(__src));
+ if (__source_is_absolute(_Traits::__first_or_null(__src)))
+ __pn_.clear();
+ else if (has_filename())
+ __pn_ += preferred_separator;
_CVT::__append_source(__pn_, __src);
return *this;
}
@@ -838,10 +850,11 @@ public:
typedef typename iterator_traits<_InputIt>::value_type _ItVal;
static_assert(__can_convert_char<_ItVal>::value, "Must convertible");
using _CVT = _PathCVT<_ItVal>;
- if (__first != __last) {
- __append_sep_if_needed(*__first);
- _CVT::__append_range(__pn_, __first, __last);
- }
+ if (__first != __last && __source_is_absolute(*__first))
+ __pn_.clear();
+ else if (has_filename())
+ __pn_ += preferred_separator;
+ _CVT::__append_range(__pn_, __first, __last);
return *this;
}
@@ -916,10 +929,9 @@ public:
_LIBCPP_INLINE_VISIBILITY
path& remove_filename() {
- if (__pn_.size() == __root_path_raw().size())
- clear();
- else
- __pn_ = __parent_path();
+ auto __fname = __filename();
+ if (!__fname.empty())
+ __pn_.erase(__fname.data() - __pn_.data());
return *this;
}
@@ -935,6 +947,10 @@ public:
__pn_.swap(__rhs.__pn_);
}
+ // private helper to allow reserving memory in the path
+ _LIBCPP_INLINE_VISIBILITY
+ void __reserve(size_t __s) { __pn_.reserve(__s); }
+
// native format observers
_LIBCPP_INLINE_VISIBILITY
const string_type& native() const _NOEXCEPT {
@@ -1023,6 +1039,17 @@ public:
_LIBCPP_INLINE_VISIBILITY bool is_absolute() const { return has_root_directory(); }
_LIBCPP_INLINE_VISIBILITY bool is_relative() const { return !is_absolute(); }
+ // relative paths
+ path lexically_normal() const;
+ path lexically_relative(const path& __base) const;
+
+ _LIBCPP_INLINE_VISIBILITY path lexically_proximate(const path& __base) const {
+ path __result = this->lexically_relative(__base);
+ if (__result.native().empty())
+ return *this;
+ return __result;
+ }
+
// iterators
class _LIBCPP_TYPE_VIS iterator;
typedef iterator const_iterator;
@@ -1277,7 +1304,9 @@ void __throw_filesystem_error(_Args&&...)
// operational functions
_LIBCPP_FUNC_VIS
-path __canonical(const path&, const path&, error_code *__ec=nullptr);
+path __absolute(const path&, error_code *__ec=nullptr);
+_LIBCPP_FUNC_VIS
+path __canonical(const path&, error_code *__ec=nullptr);
_LIBCPP_FUNC_VIS
void __copy(const path& __from, const path& __to, copy_options __opt,
error_code *__ec=nullptr);
@@ -1342,6 +1371,8 @@ _LIBCPP_FUNC_VIS
path __system_complete(const path&, error_code *__ec=nullptr);
_LIBCPP_FUNC_VIS
path __temp_directory_path(error_code *__ec=nullptr);
+_LIBCPP_FUNC_VIS
+path __weakly_canonical(path const& __p, error_code *__ec=nullptr);
inline _LIBCPP_INLINE_VISIBILITY
path current_path() {
@@ -1363,24 +1394,24 @@ void current_path(const path& __p, error_code& __ec) _NOEXCEPT {
__current_path(__p, &__ec);
}
-_LIBCPP_FUNC_VIS
-path absolute(const path&, const path& __p2 = current_path());
+inline _LIBCPP_INLINE_VISIBILITY
+path absolute(const path& __p) {
+ return __absolute(__p);
+}
inline _LIBCPP_INLINE_VISIBILITY
-path canonical(const path& __p, const path& __base = current_path()) {
- return __canonical(__p, __base);
+path absolute(const path& __p, error_code &__ec) {
+ return __absolute(__p, &__ec);
}
inline _LIBCPP_INLINE_VISIBILITY
-path canonical(const path& __p, error_code& __ec) {
- path __base = __current_path(&__ec);
- if (__ec) return {};
- return __canonical(__p, __base, &__ec);
+path canonical(const path& __p) {
+ return __canonical(__p);
}
inline _LIBCPP_INLINE_VISIBILITY
-path canonical(const path& __p, const path& __base, error_code& __ec) {
- return __canonical(__p, __base, &__ec);
+path canonical(const path& __p, error_code& __ec) {
+ return __canonical(__p, &__ec);
}
inline _LIBCPP_INLINE_VISIBILITY
@@ -1492,7 +1523,8 @@ void create_symlink(const path& __to, const path& __new) {
}
inline _LIBCPP_INLINE_VISIBILITY
-void create_symlink(const path& __to, const path& __new, error_code& __ec) _NOEXCEPT {
+void create_symlink(const path& __to, const path& __new,
+ error_code& __ec) _NOEXCEPT {
return __create_symlink(__to, __new, &__ec);
}
@@ -1716,6 +1748,27 @@ void permissions(const path& __p, perms __prms, perm_options __opts,
}
inline _LIBCPP_INLINE_VISIBILITY
+path proximate(const path& __p, const path& __base, error_code& __ec) {
+ path __tmp = __weakly_canonical(__p, &__ec);
+ if (__ec)
+ return {};
+ path __tmp_base = __weakly_canonical(__base, &__ec);
+ if (__ec)
+ return {};
+ return __tmp.lexically_proximate(__tmp_base);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+path proximate(const path& __p, error_code& __ec) {
+ return proximate(__p, current_path(), __ec);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+path proximate(const path& __p, const path& __base = current_path()) {
+ return __weakly_canonical(__p).lexically_proximate(__weakly_canonical(__base));
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
path read_symlink(const path& __p) {
return __read_symlink(__p);
}
@@ -1725,6 +1778,29 @@ path read_symlink(const path& __p, error_code& __ec) {
return __read_symlink(__p, &__ec);
}
+
+inline _LIBCPP_INLINE_VISIBILITY
+path relative(const path& __p, const path& __base, error_code& __ec) {
+ path __tmp = __weakly_canonical(__p, &__ec);
+ if (__ec)
+ return path();
+ path __tmpbase = __weakly_canonical(__base, &__ec);
+ if (__ec)
+ return path();
+ return __tmp.lexically_relative(__tmpbase);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+path relative(const path& __p, error_code& __ec) {
+ return relative(__p, current_path(), __ec);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+path relative(const path& __p, const path& __base=current_path()) {
+ return __weakly_canonical(__p).lexically_relative(__weakly_canonical(__base));
+}
+
+
inline _LIBCPP_INLINE_VISIBILITY
bool remove(const path& __p) {
return __remove(__p);
@@ -1796,23 +1872,23 @@ file_status symlink_status(const path& __p, error_code& __ec) _NOEXCEPT {
}
inline _LIBCPP_INLINE_VISIBILITY
-path system_complete(const path& __p) {
- return __system_complete(__p);
+path temp_directory_path() {
+ return __temp_directory_path();
}
inline _LIBCPP_INLINE_VISIBILITY
-path system_complete(const path& __p, error_code& __ec) {
- return __system_complete(__p, &__ec);
+path temp_directory_path(error_code& __ec) {
+ return __temp_directory_path(&__ec);
}
inline _LIBCPP_INLINE_VISIBILITY
-path temp_directory_path() {
- return __temp_directory_path();
+path weakly_canonical(path const& __p) {
+ return __weakly_canonical(__p);
}
inline _LIBCPP_INLINE_VISIBILITY
-path temp_directory_path(error_code& __ec) {
- return __temp_directory_path(&__ec);
+path weakly_canonical(path const& __p, error_code& __ec) {
+ return __weakly_canonical(__p, &__ec);
}
OpenPOWER on IntegriCloud