30 #ifndef _GLIBCXX_EXPERIMENTAL_FS_PATH_H
31 #define _GLIBCXX_EXPERIMENTAL_FS_PATH_H 1
33 #if __cplusplus < 201103L
47 #if __cplusplus == 201402L
51 #if defined(_WIN32) && !defined(__CYGWIN__)
52 # define _GLIBCXX_FILESYSTEM_IS_WINDOWS 1
56 namespace std _GLIBCXX_VISIBILITY(default)
58 _GLIBCXX_BEGIN_NAMESPACE_VERSION
60 namespace experimental
66 _GLIBCXX_BEGIN_NAMESPACE_CXX11
68 #if __cplusplus == 201402L
70 #elif __cplusplus > 201402L
81 template<
typename _CharT,
82 typename _Ch =
typename remove_const<_CharT>::type>
83 using __is_encoded_char
84 = __or_<is_same<_Ch, char>,
85 is_same<_Ch, wchar_t>,
86 #ifdef _GLIBCXX_USE_CHAR8_T
87 is_same<_Ch, char8_t>,
89 is_same<_Ch, char16_t>,
90 is_same<_Ch, char32_t>>;
92 template<
typename _Iter,
94 using __is_path_iter_src
95 = __and_<__is_encoded_char<typename _Iter_traits::value_type>,
97 typename _Iter_traits::iterator_category>>;
99 template<
typename _Iter>
100 static __is_path_iter_src<_Iter>
101 __is_path_src(_Iter,
int);
103 template<
typename _CharT,
typename _Traits,
typename _Alloc>
104 static __is_encoded_char<_CharT>
105 __is_path_src(
const basic_string<_CharT, _Traits, _Alloc>&,
int);
107 #if __cplusplus >= 201402L
108 template<
typename _CharT,
typename _Traits>
109 static __is_encoded_char<_CharT>
110 __is_path_src(
const basic_string_view<_CharT, _Traits>&,
int);
113 template<
typename _Unknown>
115 __is_path_src(
const _Unknown&, ...);
117 template<
typename _Tp1,
typename _Tp2>
118 struct __constructible_from;
120 template<
typename _Iter>
121 struct __constructible_from<_Iter, _Iter>
122 : __is_path_iter_src<_Iter>
125 template<
typename _Source>
126 struct __constructible_from<_Source, void>
127 : decltype(__is_path_src(std::declval<const _Source&>(), 0))
130 template<
typename _Tp1,
typename _Tp2 = void,
131 typename _Tp1_nocv =
typename remove_cv<_Tp1>::type,
132 typename _Tp1_noptr =
typename remove_pointer<_Tp1>::type>
133 using _Path =
typename
135 __not_<is_void<_Tp1_noptr>>,
136 __constructible_from<_Tp1, _Tp2>>::value,
139 template<
typename _Source>
141 _S_range_begin(_Source __begin) {
return __begin; }
143 struct __nul_terminated { };
145 template<
typename _Source>
146 inline __nul_terminated
147 _S_range_end(_Source) {
return {}; }
149 template<
typename _CharT,
typename _Traits,
typename _Alloc>
151 _S_range_begin(
const basic_string<_CharT, _Traits, _Alloc>& __str)
152 {
return __str.data(); }
154 template<
typename _CharT,
typename _Traits,
typename _Alloc>
156 _S_range_end(
const basic_string<_CharT, _Traits, _Alloc>& __str)
157 {
return __str.data() + __str.size(); }
159 #if __cplusplus >= 201402L
160 template<
typename _CharT,
typename _Traits>
162 _S_range_begin(
const basic_string_view<_CharT, _Traits>& __str)
163 {
return __str.data(); }
165 template<
typename _CharT,
typename _Traits>
167 _S_range_end(
const basic_string_view<_CharT, _Traits>& __str)
168 {
return __str.data() + __str.size(); }
171 template<
typename _Tp,
172 typename _Iter = decltype(_S_range_begin(std::declval<_Tp>())),
174 typename _UnqualVal =
typename std::remove_const<_Val>::type>
179 template<
typename _Tp,
180 typename _Iter = decltype(_S_range_begin(std::declval<_Tp>())),
182 typename _UnqualVal =
typename std::remove_const<_Val>::type>
186 #ifdef _GLIBCXX_USE_CHAR8_T
189 >::value, _UnqualVal>::type;
204 #ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
205 typedef wchar_t value_type;
206 static constexpr value_type preferred_separator = L
'\\';
208 typedef char value_type;
209 static constexpr value_type preferred_separator =
'/';
220 : _M_pathname(
std::move(__p._M_pathname)), _M_type(__p._M_type)
222 if (_M_type == _Type::_Multi)
227 path(string_type&& __source)
229 { _M_split_cmpts(); }
231 template<
typename _Source,
232 typename _Require = __detail::_Path<_Source>>
233 path(_Source
const& __source)
234 : _M_pathname(_S_convert(__detail::_S_range_begin(__source),
235 __detail::_S_range_end(__source)))
236 { _M_split_cmpts(); }
238 template<
typename _InputIterator,
239 typename _Require = __detail::_Path<_InputIterator, _InputIterator>>
240 path(_InputIterator __first, _InputIterator __last)
241 : _M_pathname(_S_convert(__first, __last))
242 { _M_split_cmpts(); }
244 template<
typename _Source,
245 typename _Require = __detail::_Path<_Source>,
246 typename _Require2 = __detail::__value_type_is_char<_Source>>
247 path(_Source
const& __source,
const locale& __loc)
248 : _M_pathname(_S_convert_loc(__detail::_S_range_begin(__source),
249 __detail::_S_range_end(__source), __loc))
250 { _M_split_cmpts(); }
252 template<
typename _InputIterator,
253 typename _Require = __detail::_Path<_InputIterator, _InputIterator>,
254 typename _Require2 = __detail::__value_type_is_char<_InputIterator>>
255 path(_InputIterator __first, _InputIterator __last,
const locale& __loc)
256 : _M_pathname(_S_convert_loc(__first, __last, __loc))
257 { _M_split_cmpts(); }
263 path& operator=(
const path& __p) =
default;
264 path& operator=(
path&& __p) noexcept;
265 path& operator=(string_type&& __source);
266 path& assign(string_type&& __source);
268 template<
typename _Source>
269 __detail::_Path<_Source>&
270 operator=(_Source
const& __source)
271 {
return *
this =
path(__source); }
273 template<
typename _Source>
274 __detail::_Path<_Source>&
275 assign(_Source
const& __source)
276 {
return *
this =
path(__source); }
278 template<
typename _InputIterator>
279 __detail::_Path<_InputIterator, _InputIterator>&
280 assign(_InputIterator __first, _InputIterator __last)
281 {
return *
this =
path(__first, __last); }
285 path& operator/=(
const path& __p) {
return _M_append(__p._M_pathname); }
287 template<
typename _Source>
288 __detail::_Path<_Source>&
289 operator/=(_Source
const& __source)
290 {
return append(__source); }
292 template<
typename _Source>
293 __detail::_Path<_Source>&
294 append(_Source
const& __source)
296 return _M_append(_S_convert(__detail::_S_range_begin(__source),
297 __detail::_S_range_end(__source)));
300 template<
typename _InputIterator>
301 __detail::_Path<_InputIterator, _InputIterator>&
302 append(_InputIterator __first, _InputIterator __last)
303 {
return _M_append(_S_convert(__first, __last)); }
308 path& operator+=(
const string_type& __x);
309 path& operator+=(
const value_type* __x);
310 path& operator+=(value_type __x);
311 #if __cplusplus >= 201402L
315 template<
typename _Source>
316 __detail::_Path<_Source>&
317 operator+=(_Source
const& __x) {
return concat(__x); }
319 template<
typename _CharT>
320 __detail::_Path<_CharT*, _CharT*>&
321 operator+=(_CharT __x);
323 template<
typename _Source>
324 __detail::_Path<_Source>&
325 concat(_Source
const& __x)
327 return *
this += _S_convert(__detail::_S_range_begin(__x),
328 __detail::_S_range_end(__x));
331 template<
typename _InputIterator>
332 __detail::_Path<_InputIterator, _InputIterator>&
333 concat(_InputIterator __first, _InputIterator __last)
334 {
return *
this += _S_convert(__first, __last); }
338 void clear() noexcept { _M_pathname.
clear(); _M_split_cmpts(); }
340 path& make_preferred();
341 path& remove_filename();
342 path& replace_filename(
const path& __replacement);
343 path& replace_extension(
const path& __replacement =
path());
345 void swap(
path& __rhs) noexcept;
349 const string_type& native()
const noexcept {
return _M_pathname; }
350 const value_type* c_str()
const noexcept {
return _M_pathname.
c_str(); }
351 operator string_type()
const {
return _M_pathname; }
353 template<
typename _CharT,
typename _Traits = std::
char_traits<_CharT>,
354 typename _Allocator = std::allocator<_CharT>>
356 string(
const _Allocator& __a = _Allocator())
const;
359 #if _GLIBCXX_USE_WCHAR_T
362 #ifdef _GLIBCXX_USE_CHAR8_T
363 __attribute__((__abi_tag__(
"__u8")))
364 std::u8string u8string()
const;
372 template<
typename _CharT,
typename _Traits = std::
char_traits<_CharT>,
373 typename _Allocator = std::allocator<_CharT>>
375 generic_string(
const _Allocator& __a = _Allocator())
const;
378 #if _GLIBCXX_USE_WCHAR_T
381 #ifdef _GLIBCXX_USE_CHAR8_T
382 __attribute__((__abi_tag__(
"__u8")))
383 std::u8string generic_u8string()
const;
392 int compare(
const path& __p)
const noexcept;
393 int compare(
const string_type& __s)
const;
394 int compare(
const value_type* __s)
const;
395 #if __cplusplus >= 201402L
401 path root_name()
const;
402 path root_directory()
const;
403 path root_path()
const;
404 path relative_path()
const;
405 path parent_path()
const;
406 path filename()
const;
408 path extension()
const;
412 _GLIBCXX_NODISCARD
bool empty()
const noexcept {
return _M_pathname.
empty(); }
413 bool has_root_name()
const;
414 bool has_root_directory()
const;
415 bool has_root_path()
const;
416 bool has_relative_path()
const;
417 bool has_parent_path()
const;
418 bool has_filename()
const;
419 bool has_stem()
const;
420 bool has_extension()
const;
421 bool is_absolute()
const;
422 bool is_relative()
const {
return !is_absolute(); }
433 template<
typename _InputIterator,
436 =
typename std::remove_cv<typename _Traits::value_type>::type>
438 _S_string_from_iter(_InputIterator __source)
441 for (_CharT __ch = *__source; __ch != _CharT(); __ch = *++__source)
448 enum class _Type : unsigned char {
449 _Multi, _Root_name, _Root_dir, _Filename
452 path(string_type __str, _Type __type) : _M_pathname(__str), _M_type(__type)
454 __glibcxx_assert(!empty());
455 __glibcxx_assert(_M_type != _Type::_Multi);
458 enum class _Split { _Stem, _Extension };
460 path& _M_append(
const string_type& __str)
462 if (!_M_pathname.
empty() && !_S_is_dir_sep(_M_pathname.
back())
463 && !__str.empty() && !_S_is_dir_sep(__str.front()))
464 _M_pathname += preferred_separator;
465 _M_pathname += __str;
472 template<
typename _CharT>
476 _S_convert(value_type* __src, __detail::__nul_terminated)
477 {
return string_type(__src); }
480 _S_convert(
const value_type* __src, __detail::__nul_terminated)
481 {
return string_type(__src); }
483 template<
typename _Iter>
485 _S_convert(_Iter __first, _Iter __last)
488 return _Cvt<typename remove_cv<__value_type>::type>::
489 _S_convert(__first, __last);
492 template<
typename _InputIterator>
494 _S_convert(_InputIterator __src, __detail::__nul_terminated)
496 auto __s = _S_string_from_iter(__src);
497 return _S_convert(__s.c_str(), __s.c_str() + __s.size());
501 _S_convert_loc(
const char* __first,
const char* __last,
505 _S_convert_loc(
char* __first,
char* __last,
const std::locale& __loc)
507 return _S_convert_loc(
const_cast<const char*
>(__first),
508 const_cast<const char*
>(__last), __loc);
511 template<
typename _Iter>
513 _S_convert_loc(_Iter __first, _Iter __last,
const std::locale& __loc)
516 return _S_convert_loc(__str.
data(), __str.
data()+__str.
size(), __loc);
519 template<
typename _InputIterator>
521 _S_convert_loc(_InputIterator __src, __detail::__nul_terminated,
524 const std::string __s = _S_string_from_iter(__src);
525 return _S_convert_loc(__s.
data(), __s.
data() + __s.
size(), __loc);
528 static bool _S_is_dir_sep(value_type __ch)
530 #ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
531 return __ch == L
'/' || __ch == preferred_separator;
537 void _M_split_cmpts();
539 void _M_add_root_name(
size_t __n);
540 void _M_add_root_dir(
size_t __pos);
541 void _M_add_filename(
size_t __pos,
size_t __n);
543 string_type _M_pathname;
546 using _List = _GLIBCXX_STD_C::vector<_Cmpt>;
548 _Type _M_type = _Type::_Multi;
554 inline void swap(
path& __lhs,
path& __rhs) noexcept { __lhs.swap(__rhs); }
557 size_t hash_value(
const path& __p) noexcept;
560 inline bool operator<(
const path& __lhs,
const path& __rhs) noexcept;
563 inline bool operator<=(
const path& __lhs,
const path& __rhs) noexcept
564 {
return !(__rhs < __lhs); }
567 inline bool operator>(
const path& __lhs,
const path& __rhs) noexcept
568 {
return __rhs < __lhs; }
571 inline bool operator>=(
const path& __lhs,
const path& __rhs) noexcept
572 {
return !(__lhs < __rhs); }
575 inline bool operator==(
const path& __lhs,
const path& __rhs) noexcept;
578 inline bool operator!=(
const path& __lhs,
const path& __rhs) noexcept
579 {
return !(__lhs == __rhs); }
582 inline path
operator/(
const path& __lhs,
const path& __rhs)
584 path __result(__lhs);
590 template<
typename _CharT,
typename _Traits>
591 basic_ostream<_CharT, _Traits>&
592 operator<<(basic_ostream<_CharT, _Traits>& __os,
const path& __p)
594 auto __tmp = __p.string<_CharT, _Traits>();
595 using __quoted_string
597 __os << __quoted_string{__tmp, _CharT(
'"'), _CharT(
'\\')};
602 template<
typename _CharT,
typename _Traits>
603 basic_istream<_CharT, _Traits>&
604 operator>>(basic_istream<_CharT, _Traits>& __is, path& __p)
606 basic_string<_CharT, _Traits> __tmp;
607 using __quoted_string
609 if (__is >> __quoted_string{ __tmp, _CharT(
'"'), _CharT(
'\\') })
615 #ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
616 template<
typename _InputIterator>
618 __u8path(_InputIterator __first, _InputIterator __last,
char)
621 std::codecvt_utf8_utf16<path::value_type> __cvt;
622 path::string_type __tmp;
624 const char*
const __ptr = __u8str.
data();
625 if (__str_codecvt_in_all(__ptr, __ptr + __u8str.size(), __tmp, __cvt))
626 return path{ __tmp };
627 _GLIBCXX_THROW_OR_ABORT(filesystem_error(
628 "Cannot convert character sequence",
629 std::make_error_code(errc::illegal_byte_sequence)));
632 #ifdef _GLIBCXX_USE_CHAR8_T
633 template<
typename _InputIterator>
635 __u8path(_InputIterator __first, _InputIterator __last, char8_t)
637 return path{ __first, __last };
642 template<
typename _InputIterator,
643 typename _Require = __detail::_Path<_InputIterator, _InputIterator>,
645 __detail::__value_type_is_char_or_char8_t<_InputIterator>>
647 u8path(_InputIterator __first, _InputIterator __last)
649 #ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
650 return __u8path(__first, __last, _CharT{});
652 return path{ __first, __last };
657 #ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
659 __u8path(
const string& __s,
char)
661 return filesystem::u8path(__s.data(), __s.data() + __s.size());
664 template<
typename _Source>
665 inline __enable_if_t<is_convertible<const _Source&, string>::value, path>
666 __u8path(
const _Source& __source,
char)
669 return filesystem::u8path(__s.
data(), __s.
data() + __s.
size());
672 template<
typename _Source>
673 inline __enable_if_t<!is_convertible<const _Source&, string>::value, path>
674 __u8path(
const _Source& __source,
char)
676 std::string __s = path::_S_string_from_iter(__source);
677 return filesystem::u8path(__s.
data(), __s.
data() + __s.
size());
680 #ifdef _GLIBCXX_USE_CHAR8_T
681 template<
typename _Source>
683 __u8path(
const _Source& __source, char8_t)
685 return path{ __source };
690 template<
typename _Source,
691 typename _Require = __detail::_Path<_Source>,
693 __detail::__value_type_is_char_or_char8_t<_Source>>
695 u8path(
const _Source& __source)
697 #ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
698 return __u8path(__source, _CharT{});
700 return path{ __source };
719 :
system_error(__ec, __what_arg), _M_path1(__p1), _M_path2(__p2)
724 const path& path1()
const noexcept {
return _M_path1; }
725 const path& path2()
const noexcept {
return _M_path2; }
726 const char*
what() const noexcept {
return _M_what.
c_str(); }
737 struct path::_Cmpt :
path
739 _Cmpt(string_type __s, _Type __t,
size_t __pos)
742 _Cmpt() : _M_pos(-1) { }
749 struct path::_Cvt<path::value_type>
754 using __codecvt_utf8_to_wide = _Cvt;
756 template<
typename _WStr>
758 __str_codecvt_in_all(
const char*,
const char*,
759 _WStr&, __codecvt_utf8_to_wide&) noexcept
762 template<
typename _Iter>
764 _S_convert(_Iter __first, _Iter __last)
765 {
return string_type{__first, __last}; }
769 template<
typename _CharT>
775 using __codecvt_utf8_to_wchar
776 =
typename conditional<
sizeof(wchar_t) ==
sizeof(char32_t),
777 std::codecvt_utf8<wchar_t>,
778 std::codecvt_utf8_utf16<wchar_t>
783 struct __codecvt_utf8_to_utfNN :
std::codecvt<_CharT, char, mbstate_t>
788 using __codecvt_utf8_to_wide
789 =
typename conditional<is_same<_CharT, wchar_t>::value,
790 __codecvt_utf8_to_wchar,
791 __codecvt_utf8_to_utfNN>::type;
793 #ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
794 #ifdef _GLIBCXX_USE_CHAR8_T
796 _S_wconvert(
const char8_t* __f,
const char8_t* __l,
const char8_t*)
798 const char* __f2 = (
const char*)__f;
799 const char* __l2 = (
const char*)__l;
801 std::codecvt_utf8_utf16<wchar_t> __wcvt;
802 if (__str_codecvt_in_all(__f2, __l2, __wstr, __wcvt))
808 _S_wconvert(
const char* __f,
const char* __l,
const char*)
810 std::codecvt_utf8_utf16<wchar_t> __cvt;
812 if (__str_codecvt_in_all(__f, __l, __wstr, __cvt))
814 _GLIBCXX_THROW_OR_ABORT(filesystem_error(
815 "Cannot convert character sequence",
816 std::make_error_code(errc::illegal_byte_sequence)));
820 _S_wconvert(
const _CharT* __f,
const _CharT* __l,
const void*)
822 __codecvt_utf8_to_wide __cvt;
824 if (__str_codecvt_out_all(__f, __l, __str, __cvt))
826 const char* __f2 = __str.
data();
827 const char* __l2 = __f2 + __str.
size();
828 std::codecvt_utf8_utf16<wchar_t> __wcvt;
830 if (__str_codecvt_in_all(__f2, __l2, __wstr, __wcvt))
833 _GLIBCXX_THROW_OR_ABORT(filesystem_error(
834 "Cannot convert character sequence",
835 std::make_error_code(errc::illegal_byte_sequence)));
839 _S_convert(
const _CharT* __f,
const _CharT* __l)
841 return _S_wconvert(__f, __l, (
const _CharT*)
nullptr);
845 _S_convert(
const _CharT* __f,
const _CharT* __l)
847 #ifdef _GLIBCXX_USE_CHAR8_T
848 if constexpr (is_same<_CharT, char8_t>::value)
849 return string_type(__f, __l);
853 __codecvt_utf8_to_wide __cvt;
855 if (__str_codecvt_out_all(__f, __l, __str, __cvt))
857 _GLIBCXX_THROW_OR_ABORT(filesystem_error(
858 "Cannot convert character sequence",
859 std::make_error_code(errc::illegal_byte_sequence)));
865 _S_convert(_CharT* __f, _CharT* __l)
867 return _S_convert(
const_cast<const _CharT*
>(__f),
868 const_cast<const _CharT*
>(__l));
871 template<
typename _Iter>
873 _S_convert(_Iter __first, _Iter __last)
876 return _S_convert(__str.
data(), __str.
data() + __str.
size());
879 template<
typename _Iter,
typename _Cont>
881 _S_convert(__gnu_cxx::__normal_iterator<_Iter, _Cont> __first,
882 __gnu_cxx::__normal_iterator<_Iter, _Cont> __last)
883 {
return _S_convert(__first.base(), __last.base()); }
891 using difference_type = std::ptrdiff_t;
897 iterator() : _M_path(
nullptr), _M_cur(), _M_at_end() { }
906 iterator operator++(
int) {
auto __tmp = *
this; ++*
this;
return __tmp; }
909 iterator operator--(
int) {
auto __tmp = *
this; --*
this;
return __tmp; }
912 {
return __lhs._M_equals(__rhs); }
915 {
return !__lhs._M_equals(__rhs); }
920 iterator(
const path* __path, path::_List::const_iterator __iter)
921 : _M_path(__path), _M_cur(__iter), _M_at_end()
925 : _M_path(__path), _M_cur(), _M_at_end(__at_end)
931 path::_List::const_iterator _M_cur;
937 path::operator=(
path&& __p) noexcept
939 _M_pathname =
std::move(__p._M_pathname);
941 _M_type = __p._M_type;
947 path::operator=(string_type&& __source)
951 path::assign(string_type&& __source)
955 path::operator+=(
const path& __p)
957 return operator+=(__p.native());
961 path::operator+=(
const string_type& __x)
969 path::operator+=(
const value_type* __x)
977 path::operator+=(value_type __x)
984 #if __cplusplus >= 201402L
986 path::operator+=(basic_string_view<value_type> __x)
988 _M_pathname.
append(__x.data(), __x.size());
994 template<
typename _CharT>
995 inline __detail::_Path<_CharT*, _CharT*>&
996 path::operator+=(_CharT __x)
999 return concat(__addr, __addr + 1);
1003 path::make_preferred()
1005 #ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
1006 std::replace(_M_pathname.
begin(), _M_pathname.
end(), L
'/',
1007 preferred_separator);
1014 _M_pathname.swap(__rhs._M_pathname);
1015 _M_cmpts.swap(__rhs._M_cmpts);
1019 template<
typename _CharT,
typename _Traits,
typename _Allocator>
1023 if _GLIBCXX17_CONSTEXPR (is_same<_CharT, value_type>::value)
1024 return { _M_pathname.
begin(), _M_pathname.
end(), __a };
1026 using _WString = basic_string<_CharT, _Traits, _Allocator>;
1028 const value_type* __first = _M_pathname.
data();
1029 const value_type* __last = __first + _M_pathname.
size();
1031 #ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
1032 using _CharAlloc = __alloc_rebind<_Allocator, char>;
1033 using _String = basic_string<char, char_traits<char>, _CharAlloc>;
1037 codecvt_utf8_utf16<value_type> __cvt;
1038 _String __u8str{_CharAlloc{__a}};
1039 if (__str_codecvt_out_all(__first, __last, __u8str, __cvt))
1044 operator()(
const _String& __from, _String&,
true_type)
1048 operator()(
const _String& __from, _WString& __to,
false_type)
1050 #ifdef _GLIBCXX_USE_CHAR8_T
1051 if constexpr (is_same<_CharT, char8_t>::value)
1053 __to.assign(__from.begin(), __from.end());
1060 typename path::_Cvt<_CharT>::__codecvt_utf8_to_wide __cvt;
1061 const char* __f = __from.data();
1062 const char* __l = __f + __from.size();
1063 if (__str_codecvt_in_all(__f, __l, __to, __cvt))
1069 _WString __wstr(__a);
1070 if (
auto* __p = __dispatch(__u8str, __wstr, is_same<_CharT, char>{}))
1074 #ifdef _GLIBCXX_USE_CHAR8_T
1075 if constexpr (is_same<_CharT, char8_t>::value)
1076 return _WString(__first, __last, __a);
1080 typename path::_Cvt<_CharT>::__codecvt_utf8_to_wide __cvt;
1081 _WString __wstr(__a);
1082 if (__str_codecvt_in_all(__first, __last, __wstr, __cvt))
1086 _GLIBCXX_THROW_OR_ABORT(filesystem_error(
1087 "Cannot convert character sequence",
1088 std::make_error_code(errc::illegal_byte_sequence)));
1094 #if _GLIBCXX_USE_WCHAR_T
1099 #ifdef _GLIBCXX_USE_CHAR8_T
1100 inline std::u8string
1101 path::u8string()
const {
return string<char8_t>(); }
1104 path::u8string()
const
1106 #ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
1109 std::codecvt_utf8_utf16<value_type> __cvt;
1110 const value_type* __first = _M_pathname.
data();
1111 const value_type* __last = __first + _M_pathname.
size();
1112 if (__str_codecvt_out_all(__first, __last, __str, __cvt))
1114 _GLIBCXX_THROW_OR_ABORT(filesystem_error(
1115 "Cannot convert character sequence",
1116 std::make_error_code(errc::illegal_byte_sequence)));
1129 template<
typename _CharT,
typename _Traits,
typename _Allocator>
1131 path::generic_string(
const _Allocator& __a)
const
1133 #ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
1134 const _CharT __slash = is_same<_CharT, wchar_t>::value
1138 const _CharT __slash = _CharT(
'/');
1140 basic_string<_CharT, _Traits, _Allocator> __str(__a);
1142 bool __add_slash =
false;
1143 for (
auto& __elem : *
this)
1145 if (__elem._M_type == _Type::_Root_dir)
1152 __str += __elem.string<_CharT, _Traits, _Allocator>(__a);
1153 __add_slash = __elem._M_type == _Type::_Filename;
1159 path::generic_string()
const {
return generic_string<char>(); }
1161 #if _GLIBCXX_USE_WCHAR_T
1163 path::generic_wstring()
const {
return generic_string<wchar_t>(); }
1166 #ifdef _GLIBCXX_USE_CHAR8_T
1167 inline std::u8string
1168 path::generic_u8string()
const {
return generic_string<char8_t>(); }
1171 path::generic_u8string()
const {
return generic_string<char>(); }
1175 path::generic_u16string()
const {
return generic_string<char16_t>(); }
1178 path::generic_u32string()
const {
return generic_string<char32_t>(); }
1181 path::compare(
const string_type& __s)
const {
return compare(path(__s)); }
1184 path::compare(
const value_type* __s)
const {
return compare(path(__s)); }
1186 #if __cplusplus >= 201402L
1188 path::compare(basic_string_view<value_type> __s)
const
1189 {
return compare(path(__s)); }
1193 path::filename()
const {
return empty() ? path() : *--
end(); }
1198 auto ext = _M_find_extension();
1199 if (ext.first && ext.second != 0)
1200 return path{ext.first->substr(0, ext.second)};
1205 path::extension()
const
1207 auto ext = _M_find_extension();
1209 return path{ext.first->substr(ext.second)};
1214 path::has_stem()
const
1216 auto ext = _M_find_extension();
1217 return ext.first && ext.second != 0;
1221 path::has_extension()
const
1223 auto ext = _M_find_extension();
1228 path::is_absolute()
const
1230 #ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
1231 return has_root_name() && has_root_directory();
1233 return has_root_directory();
1237 inline path::iterator
1240 if (_M_type == _Type::_Multi)
1241 return iterator(
this, _M_cmpts.
begin());
1242 return iterator(
this,
false);
1245 inline path::iterator
1248 if (_M_type == _Type::_Multi)
1249 return iterator(
this, _M_cmpts.
end());
1250 return iterator(
this,
true);
1253 inline path::iterator&
1254 path::iterator::operator++()
1256 __glibcxx_assert(_M_path !=
nullptr);
1257 if (_M_path->_M_type == _Type::_Multi)
1259 __glibcxx_assert(_M_cur != _M_path->_M_cmpts.
end());
1264 __glibcxx_assert(!_M_at_end);
1270 inline path::iterator&
1271 path::iterator::operator--()
1273 __glibcxx_assert(_M_path !=
nullptr);
1274 if (_M_path->_M_type == _Type::_Multi)
1276 __glibcxx_assert(_M_cur != _M_path->_M_cmpts.begin());
1281 __glibcxx_assert(_M_at_end);
1287 inline path::iterator::reference
1290 __glibcxx_assert(_M_path !=
nullptr);
1291 if (_M_path->_M_type == _Type::_Multi)
1293 __glibcxx_assert(_M_cur != _M_path->_M_cmpts.end());
1300 path::iterator::_M_equals(iterator __rhs)
const
1302 if (_M_path != __rhs._M_path)
1304 if (_M_path ==
nullptr)
1306 if (_M_path->_M_type == path::_Type::_Multi)
1307 return _M_cur == __rhs._M_cur;
1308 return _M_at_end == __rhs._M_at_end;
1315 inline bool operator<(
const path& __lhs,
const path& __rhs) noexcept
1316 {
return __lhs.compare(__rhs) < 0; }
1318 inline bool operator==(
const path& __lhs,
const path& __rhs) noexcept
1319 {
return __lhs.compare(__rhs) == 0; }
1322 _GLIBCXX_END_NAMESPACE_CXX11
1327 _GLIBCXX_END_NAMESPACE_VERSION
constexpr duration< __common_rep_t< _Rep2, _Rep1 >, _Period > operator*(const _Rep1 &__s, const duration< _Rep2, _Period > &__d)
constexpr complex< _Tp > operator/(const complex< _Tp > &__x, const complex< _Tp > &__y)
Return new complex value x divided by y.
integral_constant< bool, true > true_type
The type used as a compile-time boolean with true value.
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 * end(valarray< _Tp > &__va) noexcept
Return an iterator pointing to one past the last element of the valarray.
_Tp * begin(valarray< _Tp > &__va) noexcept
Return an iterator pointing to the first element of the valarray.
basic_string< char > string
A string of char.
basic_string< char32_t > u32string
A string of char32_t.
basic_string< char16_t > u16string
A string of char16_t.
basic_string< wchar_t > wstring
A string of wchar_t.
ISO C++ entities toplevel namespace is std.
std::basic_istream< _CharT, _Traits > & operator>>(std::basic_istream< _CharT, _Traits > &__is, bitset< _Nb > &__x)
Global I/O operators for bitsets.
std::basic_ostream< _CharT, _Traits > & operator<<(std::basic_ostream< _CharT, _Traits > &__os, const bitset< _Nb > &__x)
Global I/O operators for bitsets.
constexpr auto empty(const _Container &__cont) noexcept(noexcept(__cont.empty())) -> decltype(__cont.empty())
Return whether a container is empty.
A non-owning reference to a string.
An exception type that includes an error_code value.
Define a member typedef type only if a boolean constant is true.
void push_back(_CharT __c)
Append a single character.
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.
size_type size() const noexcept
Returns the number of characters in the string, not including any null-termination.
const _CharT * data() const noexcept
Return const pointer to contents.
basic_string & append(const basic_string &__str)
Append a string to this string.
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.
Container class for localization functionality.
Struct for delimited strings.
Bidirectional iterators support a superset of forward iterator operations.
Struct holding two objects of arbitrary type.
iterator begin() noexcept
Exception type thrown by the Filesystem TS library.
const char * what() const noexcept
An iterator for the components of a path.
A non-owning reference to a string.