|
95 | 95 | #define GHC_EXPAND_IMPL |
96 | 96 | #define GHC_INLINE |
97 | 97 | #ifdef GHC_OS_WINDOWS |
| 98 | +#ifndef GHC_FS_API |
98 | 99 | #define GHC_FS_API |
| 100 | +#endif |
| 101 | +#ifndef GHC_FS_API_CLASS |
99 | 102 | #define GHC_FS_API_CLASS |
| 103 | +#endif |
100 | 104 | #else |
| 105 | +#ifndef GHC_FS_API |
101 | 106 | #define GHC_FS_API __attribute__((visibility("default"))) |
| 107 | +#endif |
| 108 | +#ifndef GHC_FS_API_CLASS |
102 | 109 | #define GHC_FS_API_CLASS __attribute__((visibility("default"))) |
103 | 110 | #endif |
| 111 | +#endif |
104 | 112 | #elif defined(GHC_FILESYSTEM_FWD) |
105 | 113 | #define GHC_INLINE |
106 | 114 | #ifdef GHC_OS_WINDOWS |
| 115 | +#ifndef GHC_FS_API |
107 | 116 | #define GHC_FS_API extern |
| 117 | +#endif |
| 118 | +#ifndef GHC_FS_API_CLASS |
108 | 119 | #define GHC_FS_API_CLASS |
| 120 | +#endif |
109 | 121 | #else |
| 122 | +#ifndef GHC_FS_API |
110 | 123 | #define GHC_FS_API extern |
| 124 | +#endif |
| 125 | +#ifndef GHC_FS_API_CLASS |
111 | 126 | #define GHC_FS_API_CLASS |
112 | 127 | #endif |
| 128 | +#endif |
113 | 129 | #else |
114 | 130 | #define GHC_EXPAND_IMPL |
115 | 131 | #define GHC_INLINE inline |
| 132 | +#ifndef GHC_FS_API |
116 | 133 | #define GHC_FS_API |
| 134 | +#endif |
| 135 | +#ifndef GHC_FS_API_CLASS |
117 | 136 | #define GHC_FS_API_CLASS |
118 | 137 | #endif |
| 138 | +#endif |
119 | 139 |
|
120 | 140 | #ifdef GHC_EXPAND_IMPL |
121 | 141 |
|
|
198 | 218 | #endif |
199 | 219 | #endif // GHC_EXPAND_IMPL |
200 | 220 |
|
| 221 | +// After standard library includes. |
| 222 | +// Standard library support for std::string_view. |
| 223 | +#if defined(__cpp_lib_string_view) |
| 224 | +#define GHC_HAS_STD_STRING_VIEW |
| 225 | +#elif defined(_LIBCPP_VERSION) && (_LIBCPP_VERSION >= 4000) && (__cplusplus >= 201402) |
| 226 | +#define GHC_HAS_STD_STRING_VIEW |
| 227 | +#elif defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE >= 7) && (__cplusplus >= 201703) |
| 228 | +#define GHC_HAS_STD_STRING_VIEW |
| 229 | +#elif defined(_MSC_VER) && (_MSC_VER >= 1910 && _MSVC_LANG >= 201703) |
| 230 | +#define GHC_HAS_STD_STRING_VIEW |
| 231 | +#endif |
| 232 | + |
| 233 | +// Standard library support for std::experimental::string_view. |
| 234 | +#if defined(_LIBCPP_VERSION) && (_LIBCPP_VERSION >= 3700 && _LIBCPP_VERSION < 7000) && (__cplusplus >= 201402) |
| 235 | +#define GHC_HAS_STD_EXPERIMENTAL_STRING_VIEW |
| 236 | +#elif defined(__GNUC__) && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 9)) || (__GNUC__ > 4)) && (__cplusplus >= 201402) |
| 237 | +#define GHC_HAS_STD_EXPERIMENTAL_STRING_VIEW |
| 238 | +#endif |
| 239 | + |
| 240 | +#if defined(GHC_HAS_STD_STRING_VIEW) |
| 241 | +#include <string_view> |
| 242 | +#elif defined(GHC_HAS_STD_EXPERIMENTAL_STRING_VIEW) |
| 243 | +#include <experimental/string_view> |
| 244 | +#endif |
| 245 | + |
201 | 246 | //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
202 | 247 | // Behaviour Switches (see README.md, should match the config in test/filesystem_test.cpp): |
203 | 248 | //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
|
245 | 290 | //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
246 | 291 |
|
247 | 292 | // ghc::filesystem version in decimal (major * 10000 + minor * 100 + patch) |
248 | | -#define GHC_FILESYSTEM_VERSION 10500L |
| 293 | +#define GHC_FILESYSTEM_VERSION 10502L |
249 | 294 |
|
250 | 295 | #if !defined(GHC_WITH_EXCEPTIONS) && (defined(__EXCEPTIONS) || defined(__cpp_exceptions) || defined(_CPPUNWIND)) |
251 | 296 | #define GHC_WITH_EXCEPTIONS |
|
257 | 302 | namespace ghc { |
258 | 303 | namespace filesystem { |
259 | 304 |
|
| 305 | +#if defined(GHC_HAS_CUSTOM_STRING_VIEW) |
| 306 | +#define GHC_WITH_STRING_VIEW |
| 307 | +#elif defined(GHC_HAS_STD_STRING_VIEW) |
| 308 | +#define GHC_WITH_STRING_VIEW |
| 309 | +using std::basic_string_view; |
| 310 | +#elif defined(GHC_HAS_STD_EXPERIMENTAL_STRING_VIEW) |
| 311 | +#define GHC_WITH_STRING_VIEW |
| 312 | +using std::experimental::basic_string_view; |
| 313 | +#endif |
| 314 | + |
260 | 315 | // temporary existing exception type for yet unimplemented parts |
261 | 316 | class GHC_FS_API_CLASS not_implemented_exception : public std::logic_error |
262 | 317 | { |
@@ -334,28 +389,25 @@ class GHC_FS_API_CLASS path |
334 | 389 | struct _is_basic_string<std::basic_string<CharT, std::char_traits<CharT>, std::allocator<CharT>>> : std::true_type |
335 | 390 | { |
336 | 391 | }; |
337 | | -#ifdef __cpp_lib_string_view |
| 392 | +#ifdef GHC_WITH_STRING_VIEW |
| 393 | + template <class CharT, class Traits> |
| 394 | + struct _is_basic_string<basic_string_view<CharT, Traits>> : std::true_type |
| 395 | + { |
| 396 | + }; |
338 | 397 | template <class CharT> |
339 | | - struct _is_basic_string<std::basic_string_view<CharT>> : std::true_type |
| 398 | + struct _is_basic_string<basic_string_view<CharT, std::char_traits<CharT>>> : std::true_type |
340 | 399 | { |
341 | 400 | }; |
342 | 401 | #endif |
343 | 402 |
|
344 | 403 | template <typename T1, typename T2 = void> |
345 | 404 | using path_type = typename std::enable_if<!std::is_same<path, T1>::value, path>::type; |
346 | | -#ifdef GHC_USE_WCHAR_T |
347 | 405 | template <typename T> |
348 | 406 | using path_from_string = typename std::enable_if<_is_basic_string<T>::value || std::is_same<char const*, typename std::decay<T>::type>::value || std::is_same<char*, typename std::decay<T>::type>::value || |
349 | 407 | std::is_same<wchar_t const*, typename std::decay<T>::type>::value || std::is_same<wchar_t*, typename std::decay<T>::type>::value, |
350 | 408 | path>::type; |
351 | 409 | template <typename T> |
352 | | - using path_type_EcharT = typename std::enable_if<std::is_same<T, char>::value || std::is_same<T, char16_t>::value || std::is_same<T, char32_t>::value, path>::type; |
353 | | -#else |
354 | | - template <typename T> |
355 | | - using path_from_string = typename std::enable_if<_is_basic_string<T>::value || std::is_same<char const*, typename std::decay<T>::type>::value || std::is_same<char*, typename std::decay<T>::type>::value, path>::type; |
356 | | - template <typename T> |
357 | 410 | using path_type_EcharT = typename std::enable_if<std::is_same<T, char>::value || std::is_same<T, char16_t>::value || std::is_same<T, char32_t>::value || std::is_same<T, wchar_t>::value, path>::type; |
358 | | -#endif |
359 | 411 | // 30.10.8.4.1 constructors and destructor |
360 | 412 | path() noexcept; |
361 | 413 | path(const path& p); |
@@ -397,8 +449,8 @@ class GHC_FS_API_CLASS path |
397 | 449 | // 30.10.8.4.4 concatenation |
398 | 450 | path& operator+=(const path& x); |
399 | 451 | path& operator+=(const string_type& x); |
400 | | -#ifdef __cpp_lib_string_view |
401 | | - path& operator+=(std::basic_string_view<value_type> x); |
| 452 | +#ifdef GHC_WITH_STRING_VIEW |
| 453 | + path& operator+=(basic_string_view<value_type> x); |
402 | 454 | #endif |
403 | 455 | path& operator+=(const value_type* x); |
404 | 456 | path& operator+=(value_type x); |
@@ -451,8 +503,8 @@ class GHC_FS_API_CLASS path |
451 | 503 | // 30.10.8.4.8 compare |
452 | 504 | int compare(const path& p) const noexcept; |
453 | 505 | int compare(const string_type& s) const; |
454 | | -#ifdef __cpp_lib_string_view |
455 | | - int compare(std::basic_string_view<value_type> s) const; |
| 506 | +#ifdef GHC_WITH_STRING_VIEW |
| 507 | + int compare(basic_string_view<value_type> s) const; |
456 | 508 | #endif |
457 | 509 | int compare(const value_type* s) const; |
458 | 510 |
|
@@ -1501,8 +1553,8 @@ inline StringType fromUtf8(const Utf8String& utf8String, const typename StringTy |
1501 | 1553 | template <class StringType, typename charT, std::size_t N> |
1502 | 1554 | inline StringType fromUtf8(const charT (&utf8String)[N]) |
1503 | 1555 | { |
1504 | | -#ifdef __cpp_lib_string_view |
1505 | | - return fromUtf8<StringType>(std::basic_string_view<charT>(utf8String, N - 1)); |
| 1556 | +#ifdef GHC_WITH_STRING_VIEW |
| 1557 | + return fromUtf8<StringType>(basic_string_view<charT>(utf8String, N - 1)); |
1506 | 1558 | #else |
1507 | 1559 | return fromUtf8<StringType>(std::basic_string<charT>(utf8String, N - 1)); |
1508 | 1560 | #endif |
@@ -1556,7 +1608,11 @@ inline std::string toUtf8(const strT& unicodeString) |
1556 | 1608 | template <typename charT> |
1557 | 1609 | inline std::string toUtf8(const charT* unicodeString) |
1558 | 1610 | { |
| 1611 | +#ifdef GHC_WITH_STRING_VIEW |
| 1612 | + return toUtf8(basic_string_view<charT, std::char_traits<charT>>(unicodeString)); |
| 1613 | +#else |
1559 | 1614 | return toUtf8(std::basic_string<charT, std::char_traits<charT>>(unicodeString)); |
| 1615 | +#endif |
1560 | 1616 | } |
1561 | 1617 |
|
1562 | 1618 | #ifdef GHC_USE_WCHAR_T |
@@ -1602,7 +1658,11 @@ inline std::wstring toWChar(const strT& unicodeString) |
1602 | 1658 | template <typename charT> |
1603 | 1659 | inline std::wstring toWChar(const charT* unicodeString) |
1604 | 1660 | { |
| 1661 | +#ifdef GHC_WITH_STRING_VIEW |
| 1662 | + return toWChar(basic_string_view<charT, std::char_traits<charT>>(unicodeString)); |
| 1663 | +#else |
1605 | 1664 | return toWChar(std::basic_string<charT, std::char_traits<charT>>(unicodeString)); |
| 1665 | +#endif |
1606 | 1666 | } |
1607 | 1667 | #endif // GHC_USE_WCHAR_T |
1608 | 1668 |
|
@@ -2159,12 +2219,12 @@ GHC_INLINE file_status status_ex(const path& p, std::error_code& ec, file_status |
2159 | 2219 | if (result == 0) { |
2160 | 2220 | ec.clear(); |
2161 | 2221 | file_status fs = detail::file_status_from_st_mode(st.st_mode); |
| 2222 | + if (sls) { |
| 2223 | + *sls = fs; |
| 2224 | + } |
2162 | 2225 | if (fs.type() == file_type::symlink) { |
2163 | 2226 | result = ::stat(p.c_str(), &st); |
2164 | 2227 | if (result == 0) { |
2165 | | - if (sls) { |
2166 | | - *sls = fs; |
2167 | | - } |
2168 | 2228 | fs = detail::file_status_from_st_mode(st.st_mode); |
2169 | 2229 | } |
2170 | 2230 | } |
@@ -2413,7 +2473,7 @@ inline path& path::operator/=(const Source& source) |
2413 | 2473 | template <class Source> |
2414 | 2474 | inline path& path::append(const Source& source) |
2415 | 2475 | { |
2416 | | - return this->operator/=(path(detail::toUtf8(source))); |
| 2476 | + return this->operator/=(path(source)); |
2417 | 2477 | } |
2418 | 2478 |
|
2419 | 2479 | template <> |
@@ -2444,16 +2504,21 @@ GHC_INLINE path& path::operator+=(const string_type& x) |
2444 | 2504 | return concat(x); |
2445 | 2505 | } |
2446 | 2506 |
|
2447 | | -#ifdef __cpp_lib_string_view |
2448 | | -GHC_INLINE path& path::operator+=(std::basic_string_view<value_type> x) |
| 2507 | +#ifdef GHC_WITH_STRING_VIEW |
| 2508 | +GHC_INLINE path& path::operator+=(basic_string_view<value_type> x) |
2449 | 2509 | { |
2450 | 2510 | return concat(x); |
2451 | 2511 | } |
2452 | 2512 | #endif |
2453 | 2513 |
|
2454 | 2514 | GHC_INLINE path& path::operator+=(const value_type* x) |
2455 | 2515 | { |
2456 | | - return concat(string_type(x)); |
| 2516 | +#ifdef GHC_WITH_STRING_VIEW |
| 2517 | + basic_string_view<value_type> part(x); |
| 2518 | +#else |
| 2519 | + string_type part(x); |
| 2520 | +#endif |
| 2521 | + return concat(part); |
2457 | 2522 | } |
2458 | 2523 |
|
2459 | 2524 | GHC_INLINE path& path::operator+=(value_type x) |
@@ -2481,8 +2546,12 @@ inline path::path_from_string<Source>& path::operator+=(const Source& x) |
2481 | 2546 | template <class EcharT> |
2482 | 2547 | inline path::path_type_EcharT<EcharT>& path::operator+=(EcharT x) |
2483 | 2548 | { |
| 2549 | +#ifdef GHC_WITH_STRING_VIEW |
| 2550 | + basic_string_view<EcharT> part(&x, 1); |
| 2551 | +#else |
2484 | 2552 | std::basic_string<EcharT> part(1, x); |
2485 | | - concat(detail::toUtf8(part)); |
| 2553 | +#endif |
| 2554 | + concat(part); |
2486 | 2555 | return *this; |
2487 | 2556 | } |
2488 | 2557 |
|
@@ -2779,8 +2848,8 @@ GHC_INLINE int path::compare(const string_type& s) const |
2779 | 2848 | return compare(path(s)); |
2780 | 2849 | } |
2781 | 2850 |
|
2782 | | -#ifdef __cpp_lib_string_view |
2783 | | -GHC_INLINE int path::compare(std::basic_string_view<value_type> s) const |
| 2851 | +#ifdef GHC_WITH_STRING_VIEW |
| 2852 | +GHC_INLINE int path::compare(basic_string_view<value_type> s) const |
2784 | 2853 | { |
2785 | 2854 | return compare(path(s)); |
2786 | 2855 | } |
@@ -5411,7 +5480,7 @@ class directory_iterator::impl |
5411 | 5480 | if (_entry) { |
5412 | 5481 | _current = _base; |
5413 | 5482 | _current.append_name(_entry->d_name); |
5414 | | - _dir_entry = directory_entry(_current, ec); |
| 5483 | + _dir_entry.assign(_current, ec); |
5415 | 5484 | if (ec && (ec.value() == EACCES || ec.value() == EPERM) && (_options & directory_options::skip_permission_denied) == directory_options::skip_permission_denied) { |
5416 | 5485 | ec.clear(); |
5417 | 5486 | skip = true; |
@@ -5654,28 +5723,26 @@ GHC_INLINE recursive_directory_iterator& recursive_directory_iterator::operator+ |
5654 | 5723 |
|
5655 | 5724 | GHC_INLINE recursive_directory_iterator& recursive_directory_iterator::increment(std::error_code& ec) noexcept |
5656 | 5725 | { |
5657 | | - auto status = (*this)->status(ec); |
5658 | | - if (ec) |
5659 | | - return *this; |
5660 | | - auto symlink_status = (*this)->symlink_status(ec); |
5661 | | - if (ec) |
5662 | | - return *this; |
5663 | | - if (recursion_pending() && is_directory(status) && (!is_symlink(symlink_status) || (options() & directory_options::follow_directory_symlink) != directory_options::none)) { |
5664 | | - _impl->_dir_iter_stack.push(directory_iterator((*this)->path(), _impl->_options, ec)); |
5665 | | - } |
5666 | | - else { |
5667 | | - _impl->_dir_iter_stack.top().increment(ec); |
5668 | | - } |
5669 | | - if (!ec) { |
5670 | | - while (depth() && _impl->_dir_iter_stack.top() == directory_iterator()) { |
5671 | | - _impl->_dir_iter_stack.pop(); |
| 5726 | + bool isDir = (*this)->is_directory(ec); |
| 5727 | + bool isSymLink = !ec && (*this)->is_symlink(ec); |
| 5728 | + if(!ec) { |
| 5729 | + if (recursion_pending() && isDir && (!isSymLink || (options() & directory_options::follow_directory_symlink) != directory_options::none)) { |
| 5730 | + _impl->_dir_iter_stack.push(directory_iterator((*this)->path(), _impl->_options, ec)); |
| 5731 | + } |
| 5732 | + else { |
5672 | 5733 | _impl->_dir_iter_stack.top().increment(ec); |
5673 | 5734 | } |
| 5735 | + if (!ec) { |
| 5736 | + while (depth() && _impl->_dir_iter_stack.top() == directory_iterator()) { |
| 5737 | + _impl->_dir_iter_stack.pop(); |
| 5738 | + _impl->_dir_iter_stack.top().increment(ec); |
| 5739 | + } |
| 5740 | + } |
| 5741 | + else if (!_impl->_dir_iter_stack.empty()) { |
| 5742 | + _impl->_dir_iter_stack.pop(); |
| 5743 | + } |
| 5744 | + _impl->_recursion_pending = true; |
5674 | 5745 | } |
5675 | | - else if (!_impl->_dir_iter_stack.empty()) { |
5676 | | - _impl->_dir_iter_stack.pop(); |
5677 | | - } |
5678 | | - _impl->_recursion_pending = true; |
5679 | 5746 | return *this; |
5680 | 5747 | } |
5681 | 5748 |
|
|
0 commit comments