30 #ifndef _GLIBCXX_FS_PATH_H
31 #define _GLIBCXX_FS_PATH_H 1
33 #if __cplusplus >= 201703L
46 #include <bits/shared_ptr.h>
49 #if __cplusplus > 201703L
53 #if defined(_WIN32) && !defined(__CYGWIN__)
54 # define _GLIBCXX_FILESYSTEM_IS_WINDOWS 1
58 namespace std _GLIBCXX_VISIBILITY(default)
60 _GLIBCXX_BEGIN_NAMESPACE_VERSION
64 _GLIBCXX_BEGIN_NAMESPACE_CXX11
75 template<
typename _CharT>
76 inline constexpr
bool __is_encoded_char =
false;
78 inline constexpr
bool __is_encoded_char<char> =
true;
79 #ifdef _GLIBCXX_USE_CHAR8_T
81 inline constexpr
bool __is_encoded_char<char8_t> =
true;
83 #if _GLIBCXX_USE_WCHAR_T
85 inline constexpr
bool __is_encoded_char<wchar_t> =
true;
88 inline constexpr
bool __is_encoded_char<char16_t> =
true;
90 inline constexpr
bool __is_encoded_char<char32_t> =
true;
92 #if __cpp_concepts >= 201907L
93 template<
typename _Iter>
96 template<
typename _Iter>
101 template<>
struct __safe_iterator_traits<void*> { };
102 template<>
struct __safe_iterator_traits<const void*> { };
103 template<>
struct __safe_iterator_traits<volatile void*> { };
104 template<>
struct __safe_iterator_traits<const volatile void*> { };
107 template<
typename _Iter_traits,
typename =
void>
108 struct __is_path_iter_src
112 template<
typename _Iter_traits>
113 struct __is_path_iter_src<_Iter_traits,
114 void_t<typename _Iter_traits::value_type>>
115 : bool_constant<__is_encoded_char<typename _Iter_traits::value_type>>
118 template<
typename _Source>
119 inline constexpr
bool __is_path_src
120 = __is_path_iter_src<iterator_traits<decay_t<_Source>>>::value;
123 inline constexpr
bool __is_path_src<path> =
false;
126 inline constexpr
bool __is_path_src<volatile path> =
false;
129 inline constexpr
bool __is_path_src<void*> =
false;
132 inline constexpr
bool __is_path_src<const void*> =
false;
135 inline constexpr
bool __is_path_src<volatile void*> =
false;
138 inline constexpr
bool __is_path_src<const volatile void*> =
false;
140 template<
typename _CharT,
typename _Traits,
typename _Alloc>
141 inline constexpr
bool
142 __is_path_src<basic_string<_CharT, _Traits, _Alloc>>
143 = __is_encoded_char<_CharT>;
145 template<
typename _CharT,
typename _Traits>
146 inline constexpr
bool
147 __is_path_src<basic_string_view<_CharT, _Traits>>
148 = __is_encoded_char<_CharT>;
151 template<
typename _Tp>
152 using _Path = enable_if_t<__is_path_src<_Tp>, path>;
155 template<
typename _Iter,
typename _Tr = __safe_iterator_traits<_Iter>>
156 using _Path2 = enable_if_t<__is_path_iter_src<_Tr>::value, path>;
162 template<
typename _CharT,
typename _Traits,
typename _Alloc>
163 inline basic_string_view<_CharT, _Traits>
164 __effective_range(
const basic_string<_CharT, _Traits, _Alloc>& __source)
167 template<
typename _CharT,
typename _Traits>
168 inline const basic_string_view<_CharT, _Traits>&
169 __effective_range(
const basic_string_view<_CharT, _Traits>& __source)
172 template<
typename _Source>
174 __effective_range(
const _Source& __source)
176 if constexpr (is_pointer_v<decay_t<_Source>>)
177 return basic_string_view{&*__source};
183 =
typename iterator_traits<_Source>::value_type;
184 basic_string<value_type> __str;
185 _Source __it = __source;
186 for (value_type __ch = *__it; __ch != value_type(); __ch = *++__it)
187 __str.push_back(__ch);
193 template<
typename _Tp>
195 decltype(__detail::__effective_range(std::declval<_Tp>()))>::value_type;
200 template<
typename _Tp,
typename _Val = __value_t<_Tp>>
201 using __value_type_is_char
206 template<
typename _Tp,
typename _Val = __value_t<_Tp>>
207 using __value_type_is_char_or_char8_t
209 #ifdef _GLIBCXX_USE_CHAR8_T
210 || std::is_same_v<_Val, char8_t>
215 template<
typename _InputIterator>
217 __string_from_range(_InputIterator __first, _InputIterator __last)
221 static_assert(__is_encoded_char<_EcharT>);
223 #if __cpp_lib_concepts
224 constexpr
bool __contiguous = std::contiguous_iterator<_InputIterator>;
226 constexpr
bool __contiguous
227 = is_pointer_v<decltype(std::__niter_base(__first))>;
229 if constexpr (__contiguous)
232 const auto* __f = std::__to_address(std::__niter_base(__first));
233 const auto* __l = std::__to_address(std::__niter_base(__last));
234 return basic_string_view<_EcharT>(__f, __l - __f);
238 return basic_string<_EcharT>(__first, __last);
248 #ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
249 using value_type = wchar_t;
250 static constexpr value_type preferred_separator = L
'\\';
252 # ifdef _GLIBCXX_DOXYGEN
254 using value_type = __os_dependent__;
256 using value_type = char;
258 static constexpr value_type preferred_separator =
'/';
263 enum format :
unsigned char { native_format, generic_format, auto_format };
269 path(
const path& __p) =
default;
272 #if _GLIBCXX_USE_CXX11_ABI || _GLIBCXX_FULLY_DYNAMIC_STRING == 0
275 : _M_pathname(
std::move(__p._M_pathname)),
279 path(string_type&& __source,
format = auto_format)
280 : _M_pathname(
std::
move(__source))
281 { _M_split_cmpts(); }
283 template<
typename _Source,
284 typename _Require = __detail::_Path<_Source>>
285 path(_Source
const& __source,
format = auto_format)
286 : _M_pathname(_S_convert(__detail::__effective_range(__source)))
287 { _M_split_cmpts(); }
289 template<
typename _InputIterator,
290 typename _Require = __detail::_Path2<_InputIterator>>
291 path(_InputIterator __first, _InputIterator __last,
format = auto_format)
292 : _M_pathname(_S_convert(__first, __last))
293 { _M_split_cmpts(); }
295 template<
typename _Source,
296 typename _Require = __detail::_Path<_Source>,
297 typename _Require2 = __detail::__value_type_is_char<_Source>>
298 path(_Source
const& __src,
const locale& __loc,
format = auto_format)
299 : _M_pathname(_S_convert_loc(__detail::__effective_range(__src), __loc))
300 { _M_split_cmpts(); }
302 template<
typename _InputIterator,
303 typename _Require = __detail::_Path2<_InputIterator>,
304 typename _Req2 = __detail::__value_type_is_char<_InputIterator>>
305 path(_InputIterator __first, _InputIterator __last,
const locale& __loc,
307 : _M_pathname(_S_convert_loc(__first, __last, __loc))
308 { _M_split_cmpts(); }
314 path& operator=(
const path&);
315 path& operator=(path&&) noexcept;
316 path& operator=(string_type&& __source);
317 path& assign(string_type&& __source);
319 template<typename _Source>
320 __detail::_Path<_Source>&
321 operator=(_Source const& __source)
322 {
return *
this = path(__source); }
324 template<
typename _Source>
325 __detail::_Path<_Source>&
326 assign(_Source
const& __source)
327 {
return *
this = path(__source); }
329 template<
typename _InputIterator>
330 __detail::_Path2<_InputIterator>&
331 assign(_InputIterator __first, _InputIterator __last)
332 {
return *
this = path(__first, __last); }
336 path& operator/=(
const path& __p);
338 template<
typename _Source>
339 __detail::_Path<_Source>&
340 operator/=(_Source
const& __source)
342 _M_append(_S_convert(__detail::__effective_range(__source)));
346 template<
typename _Source>
347 __detail::_Path<_Source>&
348 append(_Source
const& __source)
350 _M_append(_S_convert(__detail::__effective_range(__source)));
354 template<
typename _InputIterator>
355 __detail::_Path2<_InputIterator>&
356 append(_InputIterator __first, _InputIterator __last)
358 _M_append(_S_convert(__first, __last));
364 path& operator+=(
const path& __x);
365 path& operator+=(
const string_type& __x);
366 path& operator+=(
const value_type* __x);
367 path& operator+=(value_type __x);
368 path& operator+=(basic_string_view<value_type> __x);
370 template<
typename _Source>
371 __detail::_Path<_Source>&
372 operator+=(_Source
const& __x) {
return concat(__x); }
374 template<
typename _CharT>
375 __detail::_Path2<_CharT*>&
376 operator+=(_CharT __x);
378 template<
typename _Source>
379 __detail::_Path<_Source>&
380 concat(_Source
const& __x)
382 _M_concat(_S_convert(__detail::__effective_range(__x)));
386 template<
typename _InputIterator>
387 __detail::_Path2<_InputIterator>&
388 concat(_InputIterator __first, _InputIterator __last)
390 _M_concat(_S_convert(__first, __last));
396 void clear() noexcept { _M_pathname.
clear(); _M_split_cmpts(); }
398 path& make_preferred();
399 path& remove_filename();
400 path& replace_filename(
const path& __replacement);
401 path& replace_extension(
const path& __replacement = path());
403 void swap(path& __rhs) noexcept;
407 const string_type& native() const noexcept {
return _M_pathname; }
408 const value_type* c_str() const noexcept {
return _M_pathname.
c_str(); }
409 operator string_type()
const {
return _M_pathname; }
411 template<
typename _CharT,
typename _Traits = std::
char_traits<_CharT>,
412 typename _Allocator = std::allocator<_CharT>>
414 string(
const _Allocator& __a = _Allocator())
const;
417 #if _GLIBCXX_USE_WCHAR_T
420 #ifdef _GLIBCXX_USE_CHAR8_T
421 __attribute__((__abi_tag__(
"__u8")))
422 std::u8string u8string() const;
430 template<
typename _CharT,
typename _Traits = std::
char_traits<_CharT>,
431 typename _Allocator = std::allocator<_CharT>>
433 generic_string(
const _Allocator& __a = _Allocator())
const;
436 #if _GLIBCXX_USE_WCHAR_T
439 #ifdef _GLIBCXX_USE_CHAR8_T
440 __attribute__((__abi_tag__(
"__u8")))
441 std::u8string generic_u8string() const;
450 int compare(
const path& __p)
const noexcept;
451 int compare(
const string_type& __s)
const noexcept;
452 int compare(
const value_type* __s)
const noexcept;
453 int compare(basic_string_view<value_type> __s)
const noexcept;
457 path root_name()
const;
458 path root_directory()
const;
459 path root_path()
const;
460 path relative_path()
const;
461 path parent_path()
const;
462 path filename()
const;
464 path extension()
const;
468 [[nodiscard]]
bool empty() const noexcept {
return _M_pathname.
empty(); }
469 bool has_root_name() const noexcept;
470 bool has_root_directory() const noexcept;
471 bool has_root_path() const noexcept;
472 bool has_relative_path() const noexcept;
473 bool has_parent_path() const noexcept;
474 bool has_filename() const noexcept;
475 bool has_stem() const noexcept;
476 bool has_extension() const noexcept;
477 bool is_absolute() const noexcept;
478 bool is_relative() const noexcept {
return !is_absolute(); }
481 path lexically_normal()
const;
482 path lexically_relative(
const path& base)
const;
483 path lexically_proximate(
const path& base)
const;
487 using const_iterator = iterator;
489 iterator
begin()
const;
490 iterator
end()
const;
493 template<
typename _CharT,
typename _Traits>
497 __os <<
std::quoted(__p.string<_CharT, _Traits>());
502 template<
typename _CharT,
typename _Traits>
516 {
return __lhs.compare(__rhs) == 0; }
518 #if __cpp_lib_three_way_comparison
520 friend strong_ordering
521 operator<=>(
const path& __lhs,
const path& __rhs) noexcept
522 {
return __lhs.compare(__rhs) <=> 0; }
526 {
return !(__lhs == __rhs); }
530 {
return __lhs.compare(__rhs) < 0; }
534 {
return !(__rhs < __lhs); }
538 {
return __rhs < __lhs; }
542 {
return !(__lhs < __rhs); }
548 path __result(__lhs);
554 enum class _Type : unsigned char {
555 _Multi = 0, _Root_name, _Root_dir, _Filename
561 __glibcxx_assert(__type != _Type::_Multi);
562 _M_cmpts.type(__type);
565 enum class _Split { _Stem, _Extension };
567 void _M_append(basic_string_view<value_type>);
568 void _M_concat(basic_string_view<value_type>);
570 pair<const string_type*, size_t> _M_find_extension() const noexcept;
581 _S_convert(string_type __str)
584 template<
typename _Tp>
586 _S_convert(
const _Tp& __str)
588 if constexpr (is_same_v<_Tp, string_type>)
590 else if constexpr (is_same_v<_Tp, basic_string_view<value_type>>)
592 else if constexpr (is_same_v<typename _Tp::value_type, value_type>)
593 return basic_string_view<value_type>(__str.
data(), __str.
size());
595 return _S_convert(__str.
data(), __str.
data() + __str.
size());
598 template<typename _EcharT>
600 _S_convert(const _EcharT* __first, const _EcharT* __last);
602 template<typename _Iter>
604 _S_convert(_Iter __first, _Iter __last)
605 {
return _S_convert(__detail::__string_from_range(__first, __last)); }
608 _S_convert_loc(
const char* __first,
const char* __last,
611 template<
typename _Iter>
613 _S_convert_loc(_Iter __first, _Iter __last,
const std::locale& __loc)
615 const auto __s = __detail::__string_from_range(__first, __last);
616 return _S_convert_loc(__s.data(), __s.data() + __s.size(), __loc);
619 template<
typename _Tp>
621 _S_convert_loc(
const _Tp& __s,
const std::locale& __loc)
623 return _S_convert_loc(__s.data(), __s.data() + __s.size(), __loc);
626 template<
typename _CharT,
typename _Traits,
typename _Allocator>
627 static basic_string<_CharT, _Traits, _Allocator>
628 _S_str_convert(basic_string_view<value_type>,
const _Allocator&);
630 void _M_split_cmpts();
632 _Type _M_type() const noexcept {
return _M_cmpts.type(); }
634 string_type _M_pathname;
640 using value_type = _Cmpt;
641 using iterator = value_type*;
642 using const_iterator =
const value_type*;
646 _List(_List&&) =
default;
651 _Type type() const noexcept
652 {
return _Type(
reinterpret_cast<uintptr_t
>(_M_impl.get()) & 0x3); }
654 void type(_Type) noexcept;
656 int size() const noexcept;
657 bool empty() const noexcept;
659 void swap(_List& __l) noexcept { _M_impl.swap(__l._M_impl); }
660 int capacity() const noexcept;
661 void reserve(
int,
bool);
666 iterator begin() noexcept;
667 iterator end() noexcept;
668 const_iterator begin() const noexcept;
669 const_iterator end() const noexcept;
671 value_type& front() noexcept;
672 value_type& back() noexcept;
673 const value_type& front() const noexcept;
674 const value_type& back() const noexcept;
677 void _M_erase_from(const_iterator __pos);
682 void operator()(_Impl*)
const noexcept;
693 inline void swap(path& __lhs, path& __rhs) noexcept { __lhs.swap(__rhs); }
695 size_t hash_value(
const path& __p) noexcept;
719 const path& path1()
const noexcept;
720 const path& path2()
const noexcept;
721 const char*
what() const noexcept;
725 std::__shared_ptr<const _Impl> _M_impl;
731 [[noreturn]]
inline void
732 __throw_conversion_error()
735 "Cannot convert character sequence",
736 std::make_error_code(errc::illegal_byte_sequence)));
739 #ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
740 template<
typename _Tp>
742 __wstr_from_utf8(
const _Tp& __str)
744 static_assert(std::is_same_v<typename _Tp::value_type, char>);
747 std::codecvt_utf8_utf16<wchar_t> __wcvt;
748 const auto __p = __str.
data();
749 if (!__str_codecvt_in_all(__p, __p + __str.size(), __wstr, __wcvt))
750 __detail::__throw_conversion_error();
763 template<
typename _InputIterator,
764 typename _Require = __detail::_Path2<_InputIterator>,
766 = __detail::__value_type_is_char_or_char8_t<_InputIterator>>
768 u8path(_InputIterator __first, _InputIterator __last)
770 #ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
771 if constexpr (is_same_v<_CharT, char>)
772 return path{ __detail::__wstr_from_utf8(
773 __detail::__string_from_range(__first, __last)) };
775 return path{ __first, __last };
778 return path{ __first, __last };
786 template<
typename _Source,
787 typename _Require = __detail::_Path<_Source>,
788 typename _CharT = __detail::__value_type_is_char_or_char8_t<_Source>>
792 #ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
793 if constexpr (is_same_v<_CharT, char>)
794 return path{ __detail::__wstr_from_utf8(
795 __detail::__effective_range(__source)) };
797 return path{ __source };
800 return path{ __source };
806 struct path::_Cmpt :
path
809 :
path(__s, __t), _M_pos(__pos) { }
811 _Cmpt() : _M_pos(-1) { }
816 template<
typename _E
charT>
818 path::_S_convert(
const _EcharT* __f,
const _EcharT* __l)
820 static_assert(__detail::__is_encoded_char<_EcharT>);
822 if constexpr (is_same_v<_EcharT, value_type>)
823 return basic_string_view<value_type>(__f, __l - __f);
824 #if !defined _GLIBCXX_FILESYSTEM_IS_WINDOWS && defined _GLIBCXX_USE_CHAR8_T
825 else if constexpr (is_same_v<_EcharT, char8_t>)
827 return string_view(
reinterpret_cast<const char*
>(__f), __l - __f);
831 #ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
833 if constexpr (is_same_v<_EcharT, char>)
835 struct _UCvt :
std::codecvt<wchar_t, char, std::mbstate_t>
837 if (__str_codecvt_in_all(__f, __l, __wstr, __cvt))
840 #ifdef _GLIBCXX_USE_CHAR8_T
841 else if constexpr (is_same_v<_EcharT, char8_t>)
843 const auto __f2 =
reinterpret_cast<const char*
>(__f);
844 return __detail::__wstr_from_utf8(string_view(__f2, __l - __f));
849 struct _UCvt :
std::codecvt<_EcharT, char, std::mbstate_t>
852 if (__str_codecvt_out_all(__f, __l, __str, __cvt))
853 return __detail::__wstr_from_utf8(__str);
856 struct _UCvt :
std::codecvt<_EcharT, char, std::mbstate_t>
859 if (__str_codecvt_out_all(__f, __l, __str, __cvt))
862 __detail::__throw_conversion_error();
872 using difference_type = std::ptrdiff_t;
878 iterator() : _M_path(
nullptr), _M_cur(), _M_at_end() { }
887 iterator operator++(
int) {
auto __tmp = *
this; ++*
this;
return __tmp; }
890 iterator operator--(
int) {
auto __tmp = *
this; --*
this;
return __tmp; }
893 {
return __lhs._M_equals(__rhs); }
896 {
return !__lhs._M_equals(__rhs); }
901 bool _M_is_multi()
const {
return _M_path->_M_type() == _Type::_Multi; }
903 friend difference_type
906 __glibcxx_assert(__first._M_path !=
nullptr);
907 __glibcxx_assert(__first._M_path == __last._M_path);
908 if (__first._M_is_multi())
909 return std::distance(__first._M_cur, __last._M_cur);
910 else if (__first._M_at_end == __last._M_at_end)
913 return __first._M_at_end ? -1 : 1;
917 __path_iter_advance(
iterator& __i, difference_type __n)
925 __glibcxx_assert(__i._M_path !=
nullptr);
926 __glibcxx_assert(__i._M_is_multi());
932 iterator(
const path* __path, path::_List::const_iterator __iter)
933 : _M_path(__path), _M_cur(__iter), _M_at_end()
937 : _M_path(__path), _M_cur(), _M_at_end(__at_end)
943 path::_List::const_iterator _M_cur;
951 if (&__p ==
this) [[__unlikely__]]
954 _M_pathname =
std::move(__p._M_pathname);
965 path::assign(string_type&& __source)
966 {
return *
this = path(
std::move(__source)); }
969 path::operator+=(
const string_type& __x)
976 path::operator+=(
const value_type* __x)
983 path::operator+=(value_type __x)
985 _M_concat(basic_string_view<value_type>(&__x, 1));
990 path::operator+=(basic_string_view<value_type> __x)
996 template<
typename _CharT>
997 inline __detail::_Path2<_CharT*>&
998 path::operator+=(
const _CharT __x)
1000 _M_concat(_S_convert(&__x, &__x + 1));
1005 path::make_preferred()
1007 #ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
1008 std::replace(_M_pathname.begin(), _M_pathname.end(), L
'/',
1009 preferred_separator);
1016 _M_pathname.swap(__rhs._M_pathname);
1017 _M_cmpts.swap(__rhs._M_cmpts);
1021 template<
typename _CharT,
typename _Traits,
typename _Allocator>
1023 path::_S_str_convert(basic_string_view<value_type> __str,
1024 const _Allocator& __a)
1026 static_assert(!is_same_v<_CharT, value_type>);
1028 using _WString = basic_string<_CharT, _Traits, _Allocator>;
1030 if (__str.size() == 0)
1031 return _WString(__a);
1033 #ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
1036 std::codecvt_utf8_utf16<value_type> __cvt;
1038 using _CharAlloc = __alloc_rebind<_Allocator, char>;
1039 using _String = basic_string<char, char_traits<char>, _CharAlloc>;
1040 _String __u8str{_CharAlloc{__a}};
1041 const value_type* __wfirst = __str.data();
1042 const value_type* __wlast = __wfirst + __str.size();
1043 if (__str_codecvt_out_all(__wfirst, __wlast, __u8str, __cvt)) {
1044 if constexpr (is_same_v<_CharT, char>)
1048 const char* __first = __u8str.data();
1049 const char* __last = __first + __u8str.size();
1051 const value_type* __first = __str.data();
1052 const value_type* __last = __first + __str.size();
1056 #ifdef _GLIBCXX_USE_CHAR8_T
1057 if constexpr (is_same_v<_CharT, char8_t>)
1058 return _WString(__first, __last, __a);
1063 _WString __wstr(__a);
1064 struct _UCvt :
std::codecvt<_CharT, char, std::mbstate_t> { } __cvt;
1065 if (__str_codecvt_in_all(__first, __last, __wstr, __cvt))
1069 #ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
1072 __detail::__throw_conversion_error();
1076 template<
typename _CharT,
typename _Traits,
typename _Allocator>
1077 inline basic_string<_CharT, _Traits, _Allocator>
1078 path::string(
const _Allocator& __a)
const
1080 if constexpr (is_same_v<_CharT, value_type>)
1081 return { _M_pathname.c_str(), _M_pathname.length(), __a };
1083 return _S_str_convert<_CharT, _Traits>(_M_pathname, __a);
1087 path::string()
const {
return string<char>(); }
1089 #if _GLIBCXX_USE_WCHAR_T
1091 path::wstring()
const {
return string<wchar_t>(); }
1094 #ifdef _GLIBCXX_USE_CHAR8_T
1095 inline std::u8string
1096 path::u8string()
const {
return string<char8_t>(); }
1099 path::u8string()
const
1101 #ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
1104 std::codecvt_utf8_utf16<value_type> __cvt;
1105 const value_type* __first = _M_pathname.
data();
1106 const value_type* __last = __first + _M_pathname.size();
1107 if (__str_codecvt_out_all(__first, __last, __str, __cvt))
1109 __detail::__throw_conversion_error();
1117 path::u16string()
const {
return string<char16_t>(); }
1120 path::u32string()
const {
return string<char32_t>(); }
1122 template<
typename _CharT,
typename _Traits,
typename _Allocator>
1124 path::generic_string(
const _Allocator& __a)
const
1126 #ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
1127 const value_type __slash = L
'/';
1129 const value_type __slash =
'/';
1131 using _Alloc2 =
typename allocator_traits<_Allocator>::template
1132 rebind_alloc<value_type>;
1133 basic_string<value_type, char_traits<value_type>, _Alloc2> __str(__a);
1135 if (_M_type() == _Type::_Root_dir)
1136 __str.
assign(1, __slash);
1139 __str.
reserve(_M_pathname.size());
1140 bool __add_slash =
false;
1141 for (
auto& __elem : *
this)
1143 #ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
1144 if (__elem._M_type() == _Type::_Root_dir)
1152 __str += basic_string_view<value_type>(__elem._M_pathname);
1153 __add_slash = __elem._M_type() == _Type::_Filename;
1157 if constexpr (is_same_v<_CharT, value_type>)
1160 return _S_str_convert<_CharT, _Traits>(__str, __a);
1164 path::generic_string()
const
1165 {
return generic_string<char>(); }
1167 #if _GLIBCXX_USE_WCHAR_T
1169 path::generic_wstring()
const
1170 {
return generic_string<wchar_t>(); }
1173 #ifdef _GLIBCXX_USE_CHAR8_T
1174 inline std::u8string
1175 path::generic_u8string()
const
1176 {
return generic_string<char8_t>(); }
1179 path::generic_u8string()
const
1180 {
return generic_string(); }
1184 path::generic_u16string()
const
1185 {
return generic_string<char16_t>(); }
1188 path::generic_u32string()
const
1189 {
return generic_string<char32_t>(); }
1192 path::compare(
const string_type& __s)
const noexcept
1193 {
return compare(basic_string_view<value_type>(__s)); }
1196 path::compare(
const value_type* __s)
const noexcept
1197 {
return compare(basic_string_view<value_type>(__s)); }
1200 path::filename()
const
1204 else if (_M_type() == _Type::_Filename)
1206 else if (_M_type() == _Type::_Multi)
1208 if (_M_pathname.back() == preferred_separator)
1210 auto& __last = *--
end();
1211 if (__last._M_type() == _Type::_Filename)
1220 auto ext = _M_find_extension();
1221 if (ext.first && ext.second != 0)
1222 return path{ext.first->substr(0, ext.second)};
1227 path::extension()
const
1229 auto ext = _M_find_extension();
1231 return path{ext.first->substr(ext.second)};
1236 path::has_stem() const noexcept
1238 auto ext = _M_find_extension();
1239 return ext.first && ext.second != 0;
1243 path::has_extension() const noexcept
1245 auto ext = _M_find_extension();
1250 path::is_absolute() const noexcept
1252 #ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
1253 return has_root_name() && has_root_directory();
1255 return has_root_directory();
1259 inline path::iterator
1262 if (_M_type() == _Type::_Multi)
1263 return iterator(
this, _M_cmpts.begin());
1264 return iterator(
this,
empty());
1267 inline path::iterator
1270 if (_M_type() == _Type::_Multi)
1271 return iterator(
this, _M_cmpts.end());
1272 return iterator(
this,
true);
1275 inline path::iterator&
1276 path::iterator::operator++()
1278 __glibcxx_assert(_M_path !=
nullptr);
1279 if (_M_path->_M_type() == _Type::_Multi)
1281 __glibcxx_assert(_M_cur != _M_path->_M_cmpts.end());
1286 __glibcxx_assert(!_M_at_end);
1292 inline path::iterator&
1293 path::iterator::operator--()
1295 __glibcxx_assert(_M_path !=
nullptr);
1296 if (_M_path->_M_type() == _Type::_Multi)
1298 __glibcxx_assert(_M_cur != _M_path->_M_cmpts.begin());
1303 __glibcxx_assert(_M_at_end);
1309 inline path::iterator::reference
1310 path::iterator::operator*()
const
1312 __glibcxx_assert(_M_path !=
nullptr);
1313 if (_M_path->_M_type() == _Type::_Multi)
1315 __glibcxx_assert(_M_cur != _M_path->_M_cmpts.end());
1322 path::iterator::_M_equals(iterator __rhs)
const
1324 if (_M_path != __rhs._M_path)
1326 if (_M_path ==
nullptr)
1328 if (_M_path->_M_type() == path::_Type::_Multi)
1329 return _M_cur == __rhs._M_cur;
1330 return _M_at_end == __rhs._M_at_end;
1334 _GLIBCXX_END_NAMESPACE_CXX11
1338 distance(filesystem::path::iterator __first, filesystem::path::iterator __last)
1339 {
return __path_iter_distance(__first, __last); }
1341 template<
typename _InputIterator,
typename _Distance>
1343 advance(filesystem::path::iterator& __i, _Distance __n)
1344 { __path_iter_advance(__i,
static_cast<ptrdiff_t
>(__n)); }
1346 extern template class __shared_ptr<const filesystem::filesystem_error::_Impl>;
1348 _GLIBCXX_END_NAMESPACE_VERSION
auto_ptr & operator=(auto_ptr &__a)
auto_ptr assignment operator.
element_type * operator->() const
Smart pointer dereferencing.
constexpr complex< _Tp > operator*(const complex< _Tp > &__x, const complex< _Tp > &__y)
Return new complex value x times y.
friend bool operator!=(const path &__lhs, const path &__rhs) noexcept
Compare paths.
friend bool operator<=(const path &__lhs, const path &__rhs) noexcept
Compare paths.
path u8path(_InputIterator __first, _InputIterator __last)
friend std::basic_ostream< _CharT, _Traits > & operator<<(std::basic_ostream< _CharT, _Traits > &__os, const path &__p)
Write a path to a stream.
path u8path(const _Source &__source)
friend bool operator>(const path &__lhs, const path &__rhs) noexcept
Compare paths.
friend path operator/(const path &__lhs, const path &__rhs)
Append one path to another.
format
path::format is ignored in this implementation
friend bool operator>=(const path &__lhs, const path &__rhs) noexcept
Compare paths.
friend bool operator<(const path &__lhs, const path &__rhs) noexcept
Compare paths.
friend std::basic_istream< _CharT, _Traits > & operator>>(std::basic_istream< _CharT, _Traits > &__is, path &__p)
Read a path from a stream.
friend bool operator==(const path &__lhs, const path &__rhs) noexcept
Compare paths.
const char * what() const noexcept
typename remove_reference< _Tp >::type remove_reference_t
Alias template for remove_reference.
void void_t
A metafunction that always yields void, used for detecting valid types.
typename enable_if< _Cond, _Tp >::type enable_if_t
Alias template for enable_if.
integral_constant< bool, false > false_type
The type used as a compile-time boolean with false value.
constexpr _Tp * __addressof(_Tp &__r) noexcept
Same as C++11 std::addressof.
constexpr std::remove_reference< _Tp >::type && move(_Tp &&__t) noexcept
Convert a value to an rvalue.
void swap(any &__x, any &__y) noexcept
Exchange the states of two any objects.
_Tp * begin(valarray< _Tp > &__va)
Return an iterator pointing to the first element of the valarray.
_Tp * end(valarray< _Tp > &__va)
Return an iterator pointing to one past the last element of the valarray.
ISO C++ entities toplevel namespace is std.
constexpr auto empty(const _Container &__cont) noexcept(noexcept(__cont.empty())) -> decltype(__cont.empty())
Return whether a container is empty.
constexpr auto size(const _Container &__cont) noexcept(noexcept(__cont.size())) -> decltype(__cont.size())
Return the size of a container.
constexpr auto data(_Container &__cont) noexcept(noexcept(__cont.data())) -> decltype(__cont.data())
Return the data pointer of a container.
auto quoted(const _CharT *__string, _CharT __delim=_CharT('"'), _CharT __escape = _CharT('\\'))
Manipulator for quoted strings.
Template class basic_istream.
Template class basic_ostream.
A non-owning reference to a string.
An exception type that includes an error_code value.
const _CharT * c_str() const noexcept
Return const pointer to null-terminated contents.
void reserve(size_type __res_arg)
Attempt to preallocate enough memory for specified number of characters.
basic_string & assign(const basic_string &__str)
Set value to contents of another string.
const _CharT * data() const noexcept
Return const pointer to contents.
bool empty() const noexcept
static const size_type npos
Value returned by various member functions when they fail.
Primary class template codecvt.
Traits class for iterators.
Exception type thrown by the Filesystem library.
An iterator for the components of a path.
Container class for localization functionality.
Bidirectional iterators support a superset of forward iterator operations.